{ "cells": [ { "cell_type": "markdown", "id": "0216d282", "metadata": {}, "source": [ "# Crystal Generation\n", "\n", "The first step in the ASSYST workflow is the generation of random, periodic\n", "crystal structures. These will form the seeds from which the rest of the\n", "training set is grown by relaxation and random perturbation.\n", "\n", "This notebook shows how to:\n", "\n", "1. specify the **chemical compositions** to sample with `Formulas`,\n", "2. **generate** symmetric crystal structures with `sample`, and\n", "3. inspect the result by **plotting** the resulting distribution of\n", " compositions and bond distances." ] }, { "cell_type": "markdown", "id": "716e571b", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 1, "id": "e8163865", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:57.274809Z", "iopub.status.busy": "2026-05-05T00:21:57.274603Z", "iopub.status.idle": "2026-05-05T00:21:59.136599Z", "shell.execute_reply": "2026-05-05T00:21:59.135079Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": "/root/.local/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\nfrom .autonotebook import tqdm as notebook_tqdm\n" } ], "source": [ "from assyst.crystals import Formulas, sample\n", "from assyst.plot import concentration_histogram, distance_histogram" ] }, { "cell_type": "markdown", "id": "ee80b2d3", "metadata": {}, "source": [ "## Formulas\n", "\n", "The smallest unit ASSYST samples is a *formula unit*, i.e. a dictionary that\n", "specifies how many atoms of each species are in one structure. Examples are\n", "\n", "- Mg$_2$Ca\n", "- Mg$_4$Ca$_2$\n", "- and so on.\n", "\n", "For each formula ASSYST tries to generate as many different space groups as\n", "possible, giving a structurally diverse set of seeds for the same composition.\n", "\n", "`Formulas` is a thin wrapper around a tuple of these dictionaries that adds a\n", "few convenient operators for building such collections." ] }, { "cell_type": "markdown", "id": "dc1e147e", "metadata": {}, "source": [ "### Manual construction\n", "\n", "Formulas can be constructed by hand," ] }, { "cell_type": "code", "execution_count": 2, "id": "b8e72ada", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.139314Z", "iopub.status.busy": "2026-05-05T00:21:59.138852Z", "iopub.status.idle": "2026-05-05T00:21:59.146032Z", "shell.execute_reply": "2026-05-05T00:21:59.145016Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 1}, {'Mg': 2}, {'Mg': 3}, {'Mg': 4}))" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mg = Formulas(\n", " ({'Mg': 1}, {'Mg': 2}, {'Mg': 3}, {'Mg': 4})\n", ")\n", "mg" ] }, { "cell_type": "code", "execution_count": 3, "id": "34316c6b", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.147989Z", "iopub.status.busy": "2026-05-05T00:21:59.147795Z", "iopub.status.idle": "2026-05-05T00:21:59.152635Z", "shell.execute_reply": "2026-05-05T00:21:59.151351Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 2, 'Ca': 1}, {'Mg': 4, 'Ca': 2}))" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mgca = Formulas(\n", " ({'Mg': 2, 'Ca': 1}, {'Mg': 4, 'Ca': 2})\n", ")\n", "mgca" ] }, { "cell_type": "markdown", "id": "33fda7fb", "metadata": {}, "source": [ "### Helpers\n", "\n", "or with the `range` helper, which mimics the builtin `range` for a single element." ] }, { "cell_type": "code", "execution_count": 4, "id": "cd5d5b50", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.154572Z", "iopub.status.busy": "2026-05-05T00:21:59.154385Z", "iopub.status.idle": "2026-05-05T00:21:59.158992Z", "shell.execute_reply": "2026-05-05T00:21:59.157779Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 1}, {'Mg': 2}, {'Mg': 3}, {'Mg': 4}))" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Formulas.range('Mg', 1, 5)" ] }, { "cell_type": "markdown", "id": "68d10219", "metadata": {}, "source": [ "### Algebra\n", "\n", "`Formulas` overloads `+`, `|` and `*` so that larger sets can be built from\n", "smaller ones.\n", "\n", "`+` simply concatenates the formula tuples," ] }, { "cell_type": "code", "execution_count": 5, "id": "f4d7adb8", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.160829Z", "iopub.status.busy": "2026-05-05T00:21:59.160653Z", "iopub.status.idle": "2026-05-05T00:21:59.165671Z", "shell.execute_reply": "2026-05-05T00:21:59.164354Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 1}, {'Mg': 2}, {'Mg': 3}, {'Mg': 4}, {'Ca': 1}, {'Ca': 2}))" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Formulas.range('Mg', 1, 5) + Formulas.range('Ca', 1, 3)" ] }, { "cell_type": "markdown", "id": "ecfd97bd", "metadata": {}, "source": [ "`|` does an *element-wise* combination, like an inner product (truncates to the shorter sequence)," ] }, { "cell_type": "code", "execution_count": 6, "id": "0b0d3ab8", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.167575Z", "iopub.status.busy": "2026-05-05T00:21:59.167350Z", "iopub.status.idle": "2026-05-05T00:21:59.171744Z", "shell.execute_reply": "2026-05-05T00:21:59.170767Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 1, 'Ca': 1}, {'Mg': 2, 'Ca': 2}))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Formulas.range('Mg', 1, 5) | Formulas.range('Ca', 1, 3)" ] }, { "cell_type": "markdown", "id": "e6881186", "metadata": {}, "source": [ "and `*` produces the *outer product*, all combinations of two element ranges." ] }, { "cell_type": "code", "execution_count": 7, "id": "a3f9e85f", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.173519Z", "iopub.status.busy": "2026-05-05T00:21:59.173307Z", "iopub.status.idle": "2026-05-05T00:21:59.177877Z", "shell.execute_reply": "2026-05-05T00:21:59.176725Z" } }, "outputs": [ { "data": { "text/plain": [ "Formulas(atoms=({'Mg': 1, 'Ca': 1}, {'Mg': 1, 'Ca': 2}, {'Mg': 2, 'Ca': 1}, {'Mg': 2, 'Ca': 2}, {'Mg': 3, 'Ca': 1}, {'Mg': 3, 'Ca': 2}, {'Mg': 4, 'Ca': 1}, {'Mg': 4, 'Ca': 2}))" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Formulas.range('Mg', 1, 5) * Formulas.range('Ca', 1, 3)" ] }, { "cell_type": "markdown", "id": "9882bef5", "metadata": {}, "source": [ "## Sampling\n", "\n", "Once we have the formulas we can ask ASSYST to generate symmetric structures\n", "for them. `sample` is a generator: it yields one `ase.Atoms` at a time so we\n", "materialize the result with `list`." ] }, { "cell_type": "code", "execution_count": 8, "id": "f1f3ff6f", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:21:59.179726Z", "iopub.status.busy": "2026-05-05T00:21:59.179543Z", "iopub.status.idle": "2026-05-05T00:22:19.445445Z", "shell.execute_reply": "2026-05-05T00:22:19.444361Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": "Spacegroups: 100%|██████████| 230/230 [00:03<00:00, 63.20it/s]\nSpacegroups: 100%|██████████| 230/230 [00:16<00:00, 13.85it/s]\nMg4Ca2: 100%|██████████| 2/2 [00:20<00:00, 11.27s/it]\nMg4Ca2: 100%|██████████| 2/2 [00:20<00:00, 10.13s/it]\nGenerated 154 structures\n" } ], "source": [ "structures = list(sample(\n", " formulas=mgca,\n", "))\n", "print(f\"Generated {len(structures)} structures\")" ] }, { "cell_type": "markdown", "id": "306b723c", "metadata": {}, "source": [ "Each entry is a regular `ase.Atoms` object enriched with provenance information in `info` (see the *Lineage* notebook for details)." ] }, { "cell_type": "code", "execution_count": 9, "id": "1db8d50a", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:22:19.447669Z", "iopub.status.busy": "2026-05-05T00:22:19.447457Z", "iopub.status.idle": "2026-05-05T00:22:19.452370Z", "shell.execute_reply": "2026-05-05T00:22:19.451313Z" } }, "outputs": [ { "data": { "text/plain": [ "Atoms(symbols='Mg2Ca', pbc=True, cell=[[5.479671805958892, -1.7139494480728563, -0.10455948903220216], [0.0, 2.6195168936402604, -0.19173510821008755], [0.0, 0.0, 4.396734373534593]])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "structures[0]" ] }, { "cell_type": "markdown", "id": "282be466", "metadata": {}, "source": [ "## Visualization\n", "\n", "`assyst.plot` provides a number of helpers to inspect a set of structures at\n", "a glance. Two useful ones for the very first sampling step are the bond\n", "distance histogram and the concentration histogram." ] }, { "cell_type": "code", "execution_count": 10, "id": "16e0e4d3", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:22:19.454511Z", "iopub.status.busy": "2026-05-05T00:22:19.454160Z", "iopub.status.idle": "2026-05-05T00:22:39.568408Z", "shell.execute_reply": "2026-05-05T00:22:39.567270Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAG1CAYAAAAfhDVuAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAALNpJREFUeJzt3Xt0FFW+9vGnQ5ImkJtBclMu4aKAxIAgmAGVMZGbcERwRjgwJzAsXDqAQkQEFQS8RFiDAopEGIk6yjDqETzgkRGDgChG5DICchCcKAhJYEDSJEgTkn7/wPRLkwS6k266s/l+1qq16L2rq35d1aSfVVW7yuJwOBwCAAAwVJC/CwAAAPAlwg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGjB/i4gEFRUVOjw4cOKiIiQxWLxdzkAAMANDodDJ0+eVGJiooKCaj5+Q9iRdPjwYTVr1szfZQAAgFo4ePCgrr322hr7CTuSIiIiJJ3bWJGRkX6uBgAAuMNms6lZs2bO3/GaEHYk56mryMhIwg4AAPXMpS5B4QJlAABgNMIOAAAwGmEHAAAYjbADAACMRtgBAABGI+wAAACjEXYAAIDRCDsAAMBohB0AAGA0wg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0Qg7AADAaIQdAABgNMIOAAAwGmEHAAAYjbADAACMRtgBAABGI+wAAACjEXYAAIDRCDsAAMBohB0AAGA0wg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0Qg7AADAaH4NO1lZWbr55psVERGh2NhYDRo0SHv37nWZ5/Tp0xo7dqyaNGmi8PBwDRkyREVFRS7zHDhwQHfddZcaNWqk2NhYPfroozp79uzl/CgAACBA+TXsbNiwQWPHjtWXX36ptWvXqqysTL1791ZpaalznokTJ2rVqlV69913tWHDBh0+fFiDBw929peXl+uuu+7SmTNn9MUXX+iNN97Q66+/runTp/vjIwEAgABjcTgcDn8XUeno0aOKjY3Vhg0bdNttt6m4uFhNmzbVsmXLdO+990qS/u///k/t27fX5s2bdcstt+ijjz7SgAEDdPjwYcXFxUmSsrOz9dhjj+no0aMKDQ295HptNpuioqJUXFysyMhIn35GAADgHe7+fgfUNTvFxcWSpJiYGEnS1q1bVVZWpvT0dOc87dq1U/PmzbV582ZJ0ubNm5WcnOwMOpLUp08f2Ww27d69u9r12O122Ww2lwkAAJgpYMJORUWFJkyYoB49eqhjx46SpMLCQoWGhio6Otpl3ri4OBUWFjrnOT/oVPZX9lUnKytLUVFRzqlZs2Ze/jQAACBQBEzYGTt2rHbt2qXly5f7fF1Tp05VcXGxczp48KDP1wkAAPwj2N8FSNK4ceO0evVqbdy4Uddee62zPT4+XmfOnNGJEydcju4UFRUpPj7eOc9XX33lsrzK0VqV81zIarXKarV6+VMAAIBA5NcjOw6HQ+PGjdOKFSu0bt06JSUlufR36dJFISEhys3Ndbbt3btXBw4cUGpqqiQpNTVVO3fu1JEjR5zzrF27VpGRkerQocPl+SAAACBg+fXIztixY7Vs2TJ98MEHioiIcF5jExUVpbCwMEVFRWn06NHKzMxUTEyMIiMjNX78eKWmpuqWW26RJPXu3VsdOnTQH/7wB82ZM0eFhYV68sknNXbsWI7eAAAA/w49t1gs1bbn5ORo5MiRks7dVPCRRx7R3/72N9ntdvXp00evvPKKyymqH3/8UQ8++KDWr1+vxo0bKyMjQ88//7yCg93Lcgw9BwCg/nH39zug7rPjL4QdAADqn3p5nx0AAABvI+wAAACjEXYAAIDRCDsAAMBohB0AAGA0wg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0Qg7AADAaIQdAABgNMIOAAAwGmEHAAAYjbADAACMRtgBAABGI+wAAACjEXYAAIDRCDsAAMBohB0AAGA0wg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0Qg7AADAaIQdAABgNMIOAAAwGmEHAAAYjbADAACMRtgBAABGI+wAAACjEXYAAIDRCDsAAMBohB0AAGA0wg4AADAaYQcAABiNsAMAAIxG2AEAAEYj7AAAAKMRdgAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0fwadjZu3KiBAwcqMTFRFotFK1eudOkfOXKkLBaLy9S3b1+XeY4fP67hw4crMjJS0dHRGj16tEpKSi7jpwAAAIHMr2GntLRUKSkpWrhwYY3z9O3bVwUFBc7pb3/7m0v/8OHDtXv3bq1du1arV6/Wxo0bdf/99/u6dAAAUE8E+3Pl/fr1U79+/S46j9VqVXx8fLV9e/bs0Zo1a7RlyxZ17dpVkvTSSy+pf//++vOf/6zExESv1wwAAOqXgL9mZ/369YqNjdX111+vBx98UMeOHXP2bd68WdHR0c6gI0np6ekKCgpSXl6eP8oFAAABxq9Hdi6lb9++Gjx4sJKSkvT999/r8ccfV79+/bR582Y1aNBAhYWFio2NdXlPcHCwYmJiVFhYWONy7Xa77Ha787XNZvPZZwAAAP4V0GFn6NChzn8nJyfrxhtvVOvWrbV+/XqlpaXVerlZWVmaOXOmN0oEAAABLuBPY52vVatWuvrqq7V//35JUnx8vI4cOeIyz9mzZ3X8+PEar/ORpKlTp6q4uNg5HTx40Kd1AwAA/6lXYeenn37SsWPHlJCQIElKTU3ViRMntHXrVuc869atU0VFhbp3717jcqxWqyIjI10mAABgJr+exiopKXEepZGk/Px87dixQzExMYqJidHMmTM1ZMgQxcfH6/vvv9fkyZPVpk0b9enTR5LUvn179e3bV2PGjFF2drbKyso0btw4DR06lJFYAABAkmRxOBwOf618/fr1+u1vf1ulPSMjQ4sWLdKgQYO0fft2nThxQomJierdu7eefvppxcXFOec9fvy4xo0bp1WrVikoKEhDhgzRggULFB4e7nYdNptNUVFRKi4u5igPAAD1hLu/334NO4GCsAMAQP3j7u93vbpmBwAAwFOEHQAAYDTCDgAAMJrHYeeXX37RqVOnnK9//PFHzZs3Tx9//LFXCwMAAPVPyykf+ruEKjwOO3fffbfefPNNSdKJEyfUvXt3zZ07V3fffbcWLVrk9QIBAADqwuOws23bNt16662SpPfee09xcXH68ccf9eabb2rBggVeLxAAAKAuPA47p06dUkREhCTp448/1uDBgxUUFKRbbrlFP/74o9cLBAAAqAuPw06bNm20cuVKHTx4UP/4xz/Uu3dvSdKRI0e4Rw0AAAg4Hoed6dOna9KkSWrZsqW6deum1NRUSeeO8nTu3NnrBQIAANSFx8/Guvfee9WzZ08VFBSoU6dOzva0tDTdc8893qwNAACgzmp1n519+/Zp7ty56tGjhw4dOiRJ2rt3r/797397tTgAAIC68jjs/Pd//7f69OmjsLAwbdu2TXa7XZJUXFys5557zusFAgAA1IXHYeeZZ55Rdna2lixZopCQEGd7jx49tG3bNq8WBwAAUFceh529e/fqtttuq9IeFRWlEydOeKMmAAAAr/E47MTHx2v//v1V2jdt2qRWrVp5pSgAAABv8TjsjBkzRg8//LDy8vJksVh0+PBhvf3225o0aZIefPBBX9QIAABQax4PPZ8yZYoqKiqUlpamU6dO6bbbbpPVatWkSZM0fvx4X9QIAABQax6HHYvFoieeeEKPPvqo9u/fr5KSEnXo0EHh4eG+qA8AAKBOPDqNVVZWprS0NO3bt0+hoaHq0KGDunXrRtABAAABy6OwExISom+++cZXtQAAAHidxxcojxgxQq+99povagEAAPA6j6/ZOXv2rJYuXapPPvlEXbp0UePGjV36X3jhBa8VBwAAUFceh51du3bppptukiR99913Ln0Wi8U7VQEAAHiJx2Hn008/9UUdAAAAPlGrp54DAADUFx4f2Zk1a9ZF+6dPn17rYgAAALzN47CzYsUKl9dlZWXKz89XcHCwWrduTdgBAAABxeOws3379iptNptNI0eO1D333OOVogAAALzFK9fsREZGaubMmZo2bZo3FgcAAOA1XrtAubi4WMXFxd5aHAAAgFd4fBprwYIFLq8dDocKCgr017/+Vf369fNaYQAAAN7gcdh58cUXXV4HBQWpadOmysjI0NSpU71WGAAAgDd4HHbWr1+vZs2aKSjI9QyYw+HQwYMHFRER4bXiAAAA6srja3ZatWqlf//731Xajx8/rqSkJK8UBQAA4C0ehx2Hw1Fte0lJiRo2bFjnggAAALzJ7dNYmZmZks497HP69Olq1KiRs6+8vFx5eXnq1KmT1wsEAACoC7fDTuXNBB0Oh3bu3KnQ0FBnX2hoqFJSUjRp0iTvVwgAAFAHboedyqedjxo1SvPnz1dkZKTPigIAAPAWj0dj5eTk+KIOAAAAn/D4AuWsrCwtXbq0SvvSpUs1e/ZsrxQFAADgLR6HnVdffVXt2rWr0n7DDTcoOzvbK0UBAAB4i8dhp7CwUAkJCVXamzZtqoKCAq8UBQAA4C0eh51mzZrp888/r9L++eefKzEx0StFAQAAeIvHFyiPGTNGEyZMUFlZme644w5JUm5uriZPnqxHHnnE6wUCAADUhcdh59FHH9WxY8f0pz/9SWfOnJEkNWzYUI899hgPAgUAAAHH47BjsVg0e/ZsTZs2TXv27FFYWJjatm0rq9Xqi/oAAADqxOOwUyk8PFw333yzN2sBAADwOo/DzqxZsy7aP3369FoXAwAA4G0eh50VK1a4vC4rK1N+fr6Cg4PVunVrwg4AAAgoHoedygeCns9ms2nkyJG65557vFIUAACAt3h8n53qREZGaubMmZo2bZo3FgcAAOA1Xgk7klRcXKzi4mJvLQ4AAMArPD6NtWDBApfXDodDBQUF+utf/6p+/fp5rTAAAABv8DjsvPjiiy6vg4KC1LRpU2VkZHBTQQAAAkzyG8nambHT32X4lUdhp6ysTElJScrOztZ1113nq5oAAAC8xqNrdkJCQrRz504FBXntUh8AAACf8ji1jBgxQn/5y198UQsAAIDXeXzNztmzZ7V06VJ98skn6tKlixo3buzS/8ILL3itOAAAgLryOOzs2rVLN910kyTpu+++c+mzWCzeqQoAAMBLPA47n376qS/qAAAA8AmPr9k5cOCAHA5HjX0AAACBxOOwk5SUpKNHj1ZpP3bsmJKSkrxSFAAAgLd4HHYcDke11+aUlJSoYcOGXikKAADAW9y+ZiczM1PSuYuQp02bpkaNGjn7ysvLlZeXp06dOnm9QAAAgLpwO+xs375d0rkjOzt37lRoaKizLzQ0VCkpKZo0aZL3KwQAAKgDt8NO5SisUaNGaf78+YqMjPRZUQAAAN7i8TU7OTk5BB0AAOBi4QPr/F1CjdwOO5s3b9bq1atd2t58800lJSUpNjZW999/v+x2u9cLBAAAqAu3w86sWbO0e/du5+udO3dq9OjRSk9P15QpU7Rq1SplZWV5tPKNGzdq4MCBSkxMlMVi0cqVK136HQ6Hpk+froSEBIWFhSk9PV379u1zmef48eMaPny4IiMjFR0drdGjR6ukpMSjOgAAgLncDjs7duxQWlqa8/Xy5cvVvXt3LVmyRJmZmVqwYIHeeecdj1ZeWlqqlJQULVy4sNr+OXPmaMGCBcrOzlZeXp4aN26sPn366PTp0855hg8frt27d2vt2rVavXq1Nm7cqPvvv9+jOgAAgLncvkD5559/VlxcnPP1hg0b1K9fP+frm2++WQcPHvRo5f369XNZxvkcDofmzZunJ598Unfffbekc6fN4uLitHLlSg0dOlR79uzRmjVrtGXLFnXt2lWS9NJLL6l///7685//rMTERI/qAQAA5nH7yE5cXJzy8/MlSWfOnNG2bdt0yy23OPtPnjypkJAQrxWWn5+vwsJCpaenO9uioqLUvXt3bd68WdK564iio6OdQUeS0tPTFRQUpLy8vBqXbbfbZbPZXCYAAGAmt8NO//79NWXKFH322WeaOnWqGjVqpFtvvdXZ/80336h169ZeK6ywsFCSXI4mVb6u7CssLFRsbKxLf3BwsGJiYpzzVCcrK0tRUVHOqVmzZl6rGwAABBa3w87TTz+t4OBg3X777VqyZImWLFnicmPBpUuXqnfv3j4p0tumTp2q4uJi5+Tp6TcAAFB/uH3NztVXX62NGzequLhY4eHhatCggUv/u+++q/DwcK8VFh8fL0kqKipSQkKCs72oqMj5WIr4+HgdOXLE5X1nz57V8ePHne+vjtVqldVq9VqtAAAgcHl8U8GoqKgqQUeSYmJiXI701FVSUpLi4+OVm5vrbLPZbMrLy1NqaqokKTU1VSdOnNDWrVud86xbt04VFRXq3r2712oBAAD1l9tHdnyhpKRE+/fvd77Oz8/Xjh07FBMTo+bNm2vChAl65pln1LZtWyUlJWnatGlKTEzUoEGDJEnt27dX3759NWbMGGVnZ6usrEzjxo3T0KFDGYkFAAAk1eLIjiSNGzdOx48fr/PKv/76a3Xu3FmdO3eWdO7J6p07d9b06dMlSZMnT9b48eN1//336+abb1ZJSYnWrFmjhg0bOpfx9ttvq127dkpLS1P//v3Vs2dPLV68uM61AQAAM7h9ZOenn37StddeK0latmyZJk+erJiYGCUnJ+t///d/azWiqVevXnI4HDX2WywWzZo1S7NmzapxnpiYGC1btszjdQMAgCuD20d22rVrpxYtWug///M/dfr0aecIph9++EFlZWU+KxAAgEqB/LBJBC63w86JEyf07rvvqkuXLqqoqFD/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44/10ksv6YknnlBeXl6181caOHCgWrRooSVLligxMVEVFRXq2LGjzpw545wnJCTE5T0Wi8V5missLOyi9ZaUlEiSPvzwQ11zzTUufVar9eIf9gI5OTkqLy9XYmKis83hcKhBgwY6evSomjZt6tHyANQeR3YA+MS6deu0c+fOKqeeKlksFvXo0UMzZ87U9u3bFRoaqhUrVkg6dxqrvLzcZf5jx45p7969evLJJ5WWlqb27du7dTTofG3btlVYWJhyc3Or7e/QoYOsVqsOHDigNm3auEyV1w25w263a9myZZo7d6527NjhnP75z38qKSlJb731lkd1A6gbjuwAqDO73a7CwkKVl5erqKhIa9asUVZWlgYMGKD/+q//qjJ/Xl6ecnNz1bt3b8XGxiovL09Hjx5V+/btJUktW7ZUXl6efvjhB4WHhysmJkZXXXWVmjRposWLFyshIUEHDhzQlClTPKqzYcOGeuyxxzR58mSFhoaqR48eOnr0qHbv3q3Ro0crIiJCkyZN0sSJE1VRUaGePXuquLhYn3/+uSIjI53X+VzKBx98oNLSUo0ePVpRUVEufffee69ycnI0ceJEj2oHUHuEHQB1tmbNGiUkJCg4OFhXXXWVUlJStGDBAmVkZCgoqOoB5MjISG3cuFHz5s2TzWZTixYtNHfuXPXr10+SNGnSJGVkZKhDhw765ZdflJ+fr5YtW2r58uV66KGH1LFjR11//fVasGCBevXq5VGt06ZNU3BwsKZPn67Dhw8rISFBDzzwgLP/6aefVtOmTZWVlaV//etfio6Odg6nd1dOTo7S09OrBB3p3EXWzz33nLZu3aouXbp4VDuA2uHZWABQR7169VKnTp00b968Wr3fYrFoxYoVGjRokFfrAnAO1+wAgBe88sorCg8P186dO91+zwMPPKDw8HAfVgVA4sgOANTZoUOH9Msvv0iSmjdvrtDQULfed+TIEdlsNknnhsg3btzYZzUCVzLCDgAAMBqnsQAAgNEIOwAAwGiEHQAAYDTCDgAAMBphBwAAGI2wAwAAjEbYAQAARiPsAAAAoxF2AACA0Qg7AADAaP8PpmdmfuEiA+IAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "distance_histogram(structures, rmax=10, reduce=lambda x: x);" ] }, { "cell_type": "code", "execution_count": 11, "id": "e43f3c37", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:22:39.570696Z", "iopub.status.busy": "2026-05-05T00:22:39.570457Z", "iopub.status.idle": "2026-05-05T00:22:39.750287Z", "shell.execute_reply": "2026-05-05T00:22:39.749136Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAGyCAYAAAACgQXWAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAP55JREFUeJzt3XtUVXX+//HX4Y5yOaFya1CxvGfeJbKLJhNqGWYXnSFTc+mUaKOoJd9JTbqQpWY2pJPlpX6a1aRWNl/MyFsOXsIsUyM1VDLB0gDRBIT9+6OvZ+aEGgcPnMP2+Vhrr8X+fPb57Pf5uJWX++x9tsUwDEMAAAAm5eHqAgAAAGoTYQcAAJgaYQcAAJgaYQcAAJgaYQcAAJgaYQcAAJgaYQcAAJgaYQcAAJgaYQcAAJial6sLcAeVlZX64YcfFBgYKIvF4upyAABANRiGoVOnTikyMlIeHpc4f2O40MaNG40777zTiIiIMCQZq1atqrLN3r17jQEDBhhBQUFGgwYNjG7duhmHDx+29f/yyy/GmDFjjJCQEKNhw4bGoEGDjPz8fIfqyMvLMySxsLCwsLCw1MMlLy/vkr/nXXpm5/Tp0+rYsaMeeughDRo0qEr/wYMHddNNN2nkyJGaMWOGgoKCtGfPHvn5+dm2mTBhgj766CO9++67Cg4O1tixYzVo0CBt2bKl2nUEBgZKkvLy8hQUFHT5bwwAANS64uJiRUVF2X6PX4zFMNzjQaAWi0WrVq3SwIEDbW1DhgyRt7e33nzzzQu+pqioSE2aNNHy5ct17733SpK++eYbtW3bVllZWbrhhhuqte/i4mIFBwerqKiIsAMAQD1R3d/fbnuBcmVlpT766CO1atVK8fHxCg0NVUxMjFavXm3bJjs7W+Xl5YqLi7O1tWnTRk2bNlVWVtZFxy4tLVVxcbHdAgAAzMltw87x48dVUlKi5557Tn379tXHH3+su+++W4MGDdLGjRslSfn5+fLx8ZHVarV7bVhYmPLz8y86dlpamoKDg21LVFRUbb4VAADgQm4bdiorKyVJCQkJmjBhgjp16qQpU6bozjvv1IIFCy5r7JSUFBUVFdmWvLw8Z5QMAADckNveet64cWN5eXmpXbt2du1t27bVZ599JkkKDw9XWVmZCgsL7c7uFBQUKDw8/KJj+/r6ytfXt1bqBgAA7sVtz+z4+Pioe/fuysnJsWv/9ttv1axZM0lS165d5e3trczMTFt/Tk6Ojhw5otjY2DqtFwAAuCeXntkpKSnRgQMHbOu5ubnatWuXQkJC1LRpU02ePFmDBw/WLbfcot69eysjI0MffvihNmzYIEkKDg7WyJEjlZycrJCQEAUFBWncuHGKjY2t9p1YAADA3Fx66/mGDRvUu3fvKu3Dhg3TkiVLJEmLFi1SWlqavv/+e7Vu3VozZsxQQkKCbduzZ89q4sSJeuutt1RaWqr4+Hi98sorl/wY67e49RwAgPqnur+/3eZ7dlyJsAMAQP1T779nBwAAwBkIOwAAwNQIOwAAwNQIOwAAwNQIOwAAwNQIOwAAwNTc9nERpnHioFR6ytVVOMY3UGp0jaurAABcQO5Pp3W69Jyry3BIQ18vRTdu6LL9E3Zq04mD0stdXF1FzYzbSeABADeT+9Np9Z61wdVl1Mj6Sb1cFngIO7Xp/BmdmydKwVGuraW6ivKkzbPr39koALgCnD+jk9T7Wl1t9XdxNdVztPAXpa8/4NKzUYSduhAcJTW61tVVAABM4mqrv0s/FqpvuEAZAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYGmEHAACYmkvDzqZNmzRgwABFRkbKYrFo9erVF9324YcflsVi0dy5c+3aT548qcTERAUFBclqtWrkyJEqKSmp3cIBAEC94dKwc/r0aXXs2FHp6emX3G7VqlXaunWrIiMjq/QlJiZqz549WrdundasWaNNmzZp9OjRtVUyAACoZ7xcufN+/fqpX79+l9zm6NGjGjdunNauXas77rjDrm/fvn3KyMjQjh071K1bN0nSyy+/rP79+2vWrFkXDEcAAODK4tbX7FRWVmro0KGaPHmy2rdvX6U/KytLVqvVFnQkKS4uTh4eHtq2bdtFxy0tLVVxcbHdAgAAzMmtw87MmTPl5eWlRx999IL9+fn5Cg0NtWvz8vJSSEiI8vPzLzpuWlqagoODbUtUVJRT6wYAAO7DbcNOdna2XnrpJS1ZskQWi8WpY6ekpKioqMi25OXlOXV8AADgPtw27GzevFnHjx9X06ZN5eXlJS8vLx0+fFgTJ05U8+bNJUnh4eE6fvy43evOnTunkydPKjw8/KJj+/r6KigoyG4BAADm5NILlC9l6NChiouLs2uLj4/X0KFDNWLECElSbGysCgsLlZ2dra5du0qSPv30U1VWViomJqbOawYAAO7HpWGnpKREBw4csK3n5uZq165dCgkJUdOmTdWoUSO77b29vRUeHq7WrVtLktq2bau+fftq1KhRWrBggcrLyzV27FgNGTKEO7EAAIAkF3+M9fnnn6tz587q3LmzJCk5OVmdO3fWtGnTqj3GsmXL1KZNG/Xp00f9+/fXTTfdpFdffbW2SgYAAPWMS8/s9OrVS4ZhVHv7Q4cOVWkLCQnR8uXLnVgVAAAwE7e9QBkAAMAZCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUCDsAAMDUXBp2Nm3apAEDBigyMlIWi0WrV6+29ZWXl+vxxx9Xhw4d1LBhQ0VGRurBBx/UDz/8YDfGyZMnlZiYqKCgIFmtVo0cOVIlJSV1/E4AAIC7cmnYOX36tDp27Kj09PQqfWfOnNHOnTs1depU7dy5UytXrlROTo7uuusuu+0SExO1Z88erVu3TmvWrNGmTZs0evTounoLAADAzXm5cuf9+vVTv379LtgXHBysdevW2bX9/e9/V48ePXTkyBE1bdpU+/btU0ZGhnbs2KFu3bpJkl5++WX1799fs2bNUmRkZK2/BwAA4N7q1TU7RUVFslgsslqtkqSsrCxZrVZb0JGkuLg4eXh4aNu2bRcdp7S0VMXFxXYLAAAwp3oTds6ePavHH39cf/rTnxQUFCRJys/PV2hoqN12Xl5eCgkJUX5+/kXHSktLU3BwsG2Jioqq1doBAIDr1IuwU15ervvvv1+GYWj+/PmXPV5KSoqKiopsS15enhOqBAAA7sil1+xUx/mgc/jwYX366ae2szqSFB4eruPHj9ttf+7cOZ08eVLh4eEXHdPX11e+vr61VjMAAHAfbn1m53zQ2b9/vz755BM1atTIrj82NlaFhYXKzs62tX366aeqrKxUTExMXZcLAADckEvP7JSUlOjAgQO29dzcXO3atUshISGKiIjQvffeq507d2rNmjWqqKiwXYcTEhIiHx8ftW3bVn379tWoUaO0YMEClZeXa+zYsRoyZAh3YgEAAEkuDjuff/65evfubVtPTk6WJA0bNkxPPvmkPvjgA0lSp06d7F63fv169erVS5K0bNkyjR07Vn369JGHh4fuuecezZs3r07qBwAA7s+lYadXr14yDOOi/ZfqOy8kJETLly93ZlkAAMBE3PqaHQAAgMtF2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKZG2AEAAKbm0rCzadMmDRgwQJGRkbJYLFq9erVdv2EYmjZtmiIiIuTv76+4uDjt37/fbpuTJ08qMTFRQUFBslqtGjlypEpKSurwXQAAAHfm0rBz+vRpdezYUenp6Rfsf/755zVv3jwtWLBA27ZtU8OGDRUfH6+zZ8/atklMTNSePXu0bt06rVmzRps2bdLo0aPr6i0AAAA35+XKnffr10/9+vW7YJ9hGJo7d66eeOIJJSQkSJLeeOMNhYWFafXq1RoyZIj27dunjIwM7dixQ926dZMkvfzyy+rfv79mzZqlyMjIOnsvAADAPbntNTu5ubnKz89XXFycrS04OFgxMTHKysqSJGVlZclqtdqCjiTFxcXJw8ND27Ztu+jYpaWlKi4utlsAAIA5uW3Yyc/PlySFhYXZtYeFhdn68vPzFRoaatfv5eWlkJAQ2zYXkpaWpuDgYNsSFRXl5OoBAIC7cNuwU5tSUlJUVFRkW/Ly8lxdEgAAqCVuG3bCw8MlSQUFBXbtBQUFtr7w8HAdP37crv/cuXM6efKkbZsL8fX1VVBQkN0CAADMyeGw88svv+jMmTO29cOHD2vu3Ln6+OOPnVpYdHS0wsPDlZmZaWsrLi7Wtm3bFBsbK0mKjY1VYWGhsrOzbdt8+umnqqysVExMjFPrAQAA9ZPDd2MlJCRo0KBBevjhh1VYWKiYmBh5e3vrp59+0pw5c/TII49Ue6ySkhIdOHDAtp6bm6tdu3YpJCRETZs21fjx4/X000+rZcuWio6O1tSpUxUZGamBAwdKktq2bau+fftq1KhRWrBggcrLyzV27FgNGTKEO7EAAICkGpzZ2blzp26++WZJ0j//+U+FhYXp8OHDeuONNzRv3jyHxvr888/VuXNnde7cWZKUnJyszp07a9q0aZKkxx57TOPGjdPo0aPVvXt3lZSUKCMjQ35+frYxli1bpjZt2qhPnz7q37+/brrpJr366quOvi0AAGBSDp/ZOXPmjAIDAyVJH3/8sQYNGiQPDw/dcMMNOnz4sENj9erVS4ZhXLTfYrEoNTVVqampF90mJCREy5cvd2i/AADgyuHwmZ1rr71Wq1evVl5entauXavbb79dknT8+HEu9AUAAG7H4bAzbdo0TZo0Sc2bN1ePHj1sFwt//PHHto+jAAAA3IXDH2Pde++9uummm3Ts2DF16tTJ1t6nTx/dfffdzqwNAADgstXoe3b279+v2bNnq2fPnjp69KgkKScnRz/99JNTiwMAALhcDoed9957T/Hx8fL399fOnTtVWloqSSoqKtKzzz7r9AIBAAAuh8Nh5+mnn9aCBQu0cOFCeXt729p79uypnTt3OrU4AACAy+Vw2MnJydEtt9xSpT04OFiFhYXOqAkAAMBpHA474eHhdt96fN5nn32mFi1aOKUoAAAAZ3E47IwaNUp//etftW3bNlksFv3www9atmyZJk2a5NCjIgAAAOqCw7eeT5kyRZWVlerTp4/OnDmjW265Rb6+vpo0aZLGjRtXGzUCAADUmMNhx2Kx6G9/+5smT56sAwcOqKSkRO3atVNAQEBt1AcAAHBZHPoYq7y8XH369NH+/fvl4+Ojdu3aqUePHgQdAADgthwKO97e3vrqq69qqxYAAACnc/gC5QceeECvv/56bdQCAADgdA5fs3Pu3DktWrRIn3zyibp27aqGDRva9c+ZM8dpxQEAAFwuh8PO119/rS5dukiSvv32W7s+i8XinKoAAACcxOGws379+tqoAwAAoFbU6KnnAAAA9YXDZ3ZSU1Mv2T9t2rQaFwMAAOBsDoedVatW2a2Xl5crNzdXXl5euuaaawg7AADArTgcdr744osqbcXFxRo+fLjuvvtupxQFAADgLE65ZicoKEgzZszQ1KlTnTEcAACA0zjtAuWioiIVFRU5azgAAACncPhjrHnz5tmtG4ahY8eO6c0331S/fv2cVhgAAIAzOBx2XnzxRbt1Dw8PNWnSRMOGDVNKSorTCgMAAHAGh8POhg0bFBUVJQ8P+0/ADMNQXl6eAgMDnVYcAADA5XL4mp0WLVrop59+qtJ+8uRJRUdHO6UoAAAAZ3E47BiGccH2kpIS+fn5XXZBAAAAzlTtj7GSk5Ml/fqwz2nTpqlBgwa2voqKCm3btk2dOnVyeoEAAACXo9ph5/yXCRqGod27d8vHx8fW5+Pjo44dO2rSpEnOrxAAAOAyVDvsnH/a+YgRI/TSSy8pKCio1ooCAABwFofvxlq8eHFt1AEAAFArHL5AOS0tTYsWLarSvmjRIs2cOdMpRQEAADiLw2HnH//4h9q0aVOlvX379lqwYIFTigIAAHAWh8NOfn6+IiIiqrQ3adJEx44dc0pRAAAAzuJw2ImKitKWLVuqtG/ZskWRkZFOKeq8iooKTZ06VdHR0fL399c111yjp556yu67fgzD0LRp0xQRESF/f3/FxcVp//79Tq0DAADUXw5foDxq1CiNHz9e5eXluu222yRJmZmZeuyxxzRx4kSnFjdz5kzNnz9fS5cuVfv27fX5559rxIgRCg4O1qOPPipJev755zVv3jwtXbpU0dHRmjp1quLj47V3716+5BAAADgediZPnqwTJ05ozJgxKisrkyT5+fnp8ccfd/qDQP/9738rISFBd9xxhySpefPmeuutt7R9+3ZJv57VmTt3rp544gklJCRIkt544w2FhYVp9erVGjJkiFPrAQAA9Y/DH2NZLBbNnDlTP/74o7Zu3aovv/xSJ0+e1LRp05xe3I033qjMzEx9++23kqQvv/xSn332mfr16ydJys3NVX5+vuLi4myvCQ4OVkxMjLKysi46bmlpqYqLi+0WAABgTg6f2TkvICBA3bt3d2YtVUyZMkXFxcVq06aNPD09VVFRoWeeeUaJiYmSfr1YWpLCwsLsXhcWFmbru5C0tDTNmDGj9goHAABuw+Gwk5qaesl+Z57heeedd7Rs2TItX75c7du3165duzR+/HhFRkZq2LBhNR43JSXF9qwvSSouLlZUVJQzSgYAAG7G4bCzatUqu/Xy8nLl5ubKy8tL11xzjVPDzuTJkzVlyhTbtTcdOnTQ4cOHlZaWpmHDhik8PFySVFBQYHc7fEFBwSUfSurr6ytfX1+n1QkAANyXw2Hn/ANB/1txcbGGDx+uu+++2ylFnXfmzBl5eNhfVuTp6anKykpJUnR0tMLDw5WZmWkLN8XFxdq2bZseeeQRp9YCAADqpxpfs/PfgoKCNGPGDA0YMEBDhw51xpCSpAEDBuiZZ55R06ZN1b59e33xxReaM2eOHnroIUm/Xiw9fvx4Pf3002rZsqXt1vPIyEgNHDjQaXUAAID6yylhR5KKiopUVFTkrOEkSS+//LKmTp2qMWPG6Pjx44qMjNRf/vIXu4/KHnvsMZ0+fVqjR49WYWGhbrrpJmVkZPAdOwAAQFINws68efPs1g3D0LFjx/Tmm2/abgl3lsDAQM2dO1dz58696DYWi0Wpqam/e+E0AAC4Mjkcdl588UW7dQ8PDzVp0kTDhg1z+pcKAgAAXC6Hwk55ebmio6O1YMECtWrVqrZqAgAAcBqHvkHZ29tbu3fvrnKHFAAAgLtyOLU88MADeu2112qjFgAAAKdz+Jqdc+fOadGiRfrkk0/UtWtXNWzY0K5/zpw5TisOAADgcjkcdr7++mt16dJFkmwP6DzPYrE4pyoAAAAncTjsrF+/vjbqAAAAqBUOX7Nz5MgRGYZx0T4AAAB34nDYiY6O1o8//lil/cSJE4qOjnZKUQAAAM7icNgxDOOC1+aUlJTwiAYAAOB2qn3NTnJysqRfL0KeOnWqGjRoYOurqKjQtm3bbE8eBwAAcBfVDjtffPGFpF/P7OzevVs+Pj62Ph8fH3Xs2FGTJk1yfoUAAACXodph5/xdWCNGjNBLL72koKCgWisKAADAWRy+9Xzx4sW1UQcAAECtqPYFyllZWVqzZo1d2xtvvKHo6GiFhoZq9OjRKi0tdXqBAAAAl6PaYSc1NVV79uyxre/evVsjR45UXFycpkyZog8//FBpaWm1UiQAAEBNVTvs7Nq1S3369LGtr1ixQjExMVq4cKGSk5M1b948vfPOO7VSJAAAQE1VO+z8/PPPCgsLs61v3LhR/fr1s613795deXl5zq0OAADgMlU77ISFhSk3N1eSVFZWpp07d+qGG26w9Z86dUre3t7OrxAAAOAyVDvs9O/fX1OmTNHmzZuVkpKiBg0a6Oabb7b1f/XVV7rmmmtqpUgAAICaqvat50899ZQGDRqkW2+9VQEBAVq6dKndFwsuWrRIt99+e60UCQAAUFPVDjuNGzfWpk2bVFRUpICAAHl6etr1v/vuuwoICHB6gQAAAJfD4S8VDA4OvmB7SEjIZRcDAADgbA4/9RwAAKA+qVHYGTt2rE6ePOnsWgAAAJyu2mHn+++/t/28fPlylZSUSJI6dOjA9+sAAAC3Ve1rdtq0aaNGjRqpZ8+eOnv2rPLy8tS0aVMdOnRI5eXltVkjAABAjVX7zE5hYaHeffddde3aVZWVlerfv79atWql0tJSrV27VgUFBbVZJwAAQI1UO+yUl5erR48emjhxovz9/fXFF19o8eLF8vT01KJFixQdHa3WrVvXZq0AAAAOq/bHWFarVZ06dVLPnj1VVlamX375RT179pSXl5fefvttXX311dqxY0dt1goAAOCwap/ZOXr0qJ544gn5+vrq3Llz6tq1q26++Wbbc7IsFotuuumm2qwVAADAYdUOO40bN9aAAQOUlpamBg0aaMeOHRo3bpwsFosmTZqk4OBg3XrrrbVZKwAAgMNq/KWCwcHBuv/+++Xt7a1PP/1Uubm5GjNmjDNrAwAAuGwOPy5C+vUJ51dffbUkqVmzZvL29lZ4eLgGDx7s1OIAAAAuV43CTlRUlO3nr7/+2mnFAAAAOJvbPxvr6NGjeuCBB9SoUSP5+/urQ4cO+vzzz239hmFo2rRpioiIkL+/v+Li4rR//34XVgwAANyJW4edn3/+WT179pS3t7f+93//V3v37tXs2bN11VVX2bZ5/vnnNW/ePC1YsEDbtm1Tw4YNFR8fr7Nnz7qwcgAA4C5q9DFWXZk5c6aioqK0ePFiW1t0dLTtZ8MwNHfuXD3xxBNKSEiQJL3xxhsKCwvT6tWrNWTIkDqvGQAAuBe3PrPzwQcfqFu3brrvvvsUGhqqzp07a+HChbb+3Nxc5efnKy4uztYWHBysmJgYZWVlXXTc0tJSFRcX2y0AAMCc3DrsfPfdd5o/f75atmyptWvX6pFHHtGjjz6qpUuXSpLy8/MlSWFhYXavCwsLs/VdSFpamoKDg23Lf19wDQAAzMWtw05lZaW6dOmiZ599Vp07d9bo0aM1atQoLViw4LLGTUlJUVFRkW3Jy8tzUsUAAMDduHXYiYiIULt27eza2rZtqyNHjkiSwsPDJanKE9cLCgpsfRfi6+uroKAguwUAAJiTW4ednj17Kicnx67t22+/VbNmzST9erFyeHi4MjMzbf3FxcXatm2bYmNj67RWAADgntz6bqwJEyboxhtv1LPPPqv7779f27dv16uvvqpXX31VkmSxWDR+/Hg9/fTTatmypaKjozV16lRFRkZq4MCBri0eAAC4BbcOO927d9eqVauUkpKi1NRURUdHa+7cuUpMTLRt89hjj+n06dMaPXq0CgsLddNNNykjI0N+fn4urBwAALgLtw47knTnnXfqzjvvvGi/xWJRamqqUlNT67AqAABQX7j1NTsAAACXi7ADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMjbADAABMrV6Fneeee04Wi0Xjx4+3tZ09e1ZJSUlq1KiRAgICdM8996igoMB1RQIAALdSb8LOjh079I9//EPXX3+9XfuECRP04Ycf6t1339XGjRv1ww8/aNCgQS6qEgAAuJt6EXZKSkqUmJiohQsX6qqrrrK1FxUV6fXXX9ecOXN02223qWvXrlq8eLH+/e9/a+vWrS6sGAAAuIt6EXaSkpJ0xx13KC4uzq49Oztb5eXldu1t2rRR06ZNlZWVddHxSktLVVxcbLcAAABz8nJ1Ab9nxYoV2rlzp3bs2FGlLz8/Xz4+PrJarXbtYWFhys/Pv+iYaWlpmjFjhrNLBQAAbsitz+zk5eXpr3/9q5YtWyY/Pz+njZuSkqKioiLbkpeX57SxAQCAe3HrsJOdna3jx4+rS5cu8vLykpeXlzZu3Kh58+bJy8tLYWFhKisrU2Fhod3rCgoKFB4eftFxfX19FRQUZLcAAABzcuuPsfr06aPdu3fbtY0YMUJt2rTR448/rqioKHl7eyszM1P33HOPJCknJ0dHjhxRbGys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rtGGDRvUp08fF1XtfKdOndLQoUO1cOFCNW7c2NXluFx15+NKOT5iY2PtHgh84403qm3btvrHP/6hp556yoWVuUZ15uNKOTakXx8aHRoaqldffVWenp7q2rWrjh49qhdeeEHTp093dXl1qjpz0a9fP9v2119/vWJiYtSsWTO98847lzyL7A4IOy7WuHFjeXp6qqCgwK69oKBA4eHhF32dh4eHrr32WklSp06dtG/fPqWlpdnCzm+1aNFCjRs31oEDB9z6HyxH5+PgwYM6dOiQBgwYYGurrKyUJHl5eSknJ8f2uoKCAkVERNiN2alTp1p4F85TG/NxzTXXVHldfTg+avp35b95e3urc+fOOnDggCRdUcfGhfx2Pi6kPhwbUs3mIyIiQt7e3vL09LS1tW3bVvn5+SorK3PKHLtCbcyFj49PlddYrVa1atXqksePu+BjLBfz8fFR165dlZmZaWurrKxUZmam3f/Afk9lZaVKS0sv2v/999/rxIkTdv+guyNH56NNmzbavXu3du3aZVvuuusu9e7dW7t27VJUVJSio6MVHh5uN2ZxcbG2bdvm0By7Qm3Mx4XUh+PDGX9XKioqtHv3btv7vJKOjQv57XxcSH04NqSazUfPnj114MAB238IJOnbb79VRESEfHx8nPbvc12rjbm4kJKSEh08eNDtjw1J3HruDlasWGH4+voaS5YsMfbu3WuMHj3asFqttltChw4dakyZMsW2/bPPPmt8/PHHxsGDB429e/cas2bNMry8vIyFCxcahmEYp06dMiZNmmRkZWUZubm5xieffGJ06dLFaNmypXH27FmXvEdHODofv3Whu0mee+45w2q1Gu+//77x1VdfGQkJCfXq9mJnzkd9Pj4cnYsZM2YYa9euNQ4ePGhkZ2cbQ4YMMfz8/Iw9e/bYtrmSjo3fm4/6fGwYhuPzceTIESMwMNAYO3askZOTY6xZs8YIDQ01nn766WqP6a5qYy4mTpxobNiwwcjNzTW2bNlixMXFGY0bNzaOHz9e5+/PUYQdN/Hyyy8bTZs2NXx8fIwePXoYW7dutfXdeuutxrBhw2zrf/vb34xrr73W8PPzM6666iojNjbWWLFiha3/zJkzxu233240adLE8Pb2Npo1a2aMGjXK7f9y/jdH5uO3LhR2KisrjalTpxphYWGGr6+v0adPHyMnJ6eWqnc+Z85H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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "concentration_histogram(structures);" ] }, { "cell_type": "markdown", "id": "757d0dff", "metadata": {}, "source": [ "## Advanced sampling\n", "\n", "`sample` accepts several options for restricting which space groups are\n", "generated, putting bounds on the structure size, capping the total number of\n", "structures, and so on. The full signature is:" ] }, { "cell_type": "code", "execution_count": 12, "id": "933a8784", "metadata": { "execution": { "iopub.execute_input": "2026-05-05T00:22:39.752446Z", "iopub.status.busy": "2026-05-05T00:22:39.752232Z", "iopub.status.idle": "2026-05-05T00:22:39.756588Z", "shell.execute_reply": "2026-05-05T00:22:39.755620Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": "Help on function sample in module assyst.crystals:\nsample(formulas: Union[assyst.crystals.Formulas, Iterable[dict[str, int]]], spacegroups: Union[list[int], tuple[int, ...], Iterable[int], NoneType] = None, min_atoms: int = 1, max_atoms: int = 10, max_structures: int | None = None, dim: Literal[0, 1, 2, 3] = 3, tolerance: Union[Literal['metallic', 'atomic', 'molecular', 'vdW'], assyst.filters.DistanceFilter, dict] = 'metallic', rng: Union[int, numpy.random._generator.Generator, NoneType] = None) -> Iterator[ase.atoms.Atoms]\nCreate symmetric random structures.\nArgs:\nformulas (:class:`.Formulas` or :class:`collections.abc.Iterable` of :class:`dict` from :class:`str` to :class:`int`): :class:`list` of chemical formulas\nspacegroups (list of int): which space groups to generate\nmin_atoms (int): do not generate structures smaller than this\nmax_atoms (int): do not generate structures larger than this\nmax_structures (int): generate at most this many structures\ndim (one of 0, 1, 2, or 3): the dimensionality of the structures to generate; if lower than 3 the code generates\nsamples no longer from space groups, but from the subperiodic layer, rod, or point groups.\ntolerance (str, dict of elements to radii):\nspecifies minimum allowed distances between atoms in generated structures;\nif str then it should be one values understood by :class:`pyxtal.tolerance.Tol_matrix`;\nif dict each value gives the minimum *radius* allowed for an atom, whether a given distance is allowed then\ndepends on the sum of the radii of the respective elements\nrng (:class:`int`, :class:`numpy.random.Generator`): seed or random number generator\nYields:\n:class:`ase.Atoms`: random symmetric crystal structures\n" } ], "source": [ "help(sample)" ] }, { "cell_type": "markdown", "id": "b3539b53", "metadata": {}, "source": [ "Some useful non-default options:\n", "\n", "- **`spacegroups`** — restrict to a subset of space groups, e.g. cubic ones (195–230):\n", " ```python\n", " sample(formulas, spacegroups=range(195, 231))\n", " ```\n", "- **`max_structures`** — cap the total yield; handy for a quick sanity check:\n", " ```python\n", " sample(formulas, max_structures=20)\n", " ```\n", "- **`min_atoms` / `max_atoms`** — enforce a size window so the supercell stays tractable:\n", " ```python\n", " sample(formulas, min_atoms=2, max_atoms=6)\n", " ```\n", "- **`dim=2`** — generate 2-D layer structures instead of bulk crystals (layer groups instead of space groups):\n", " ```python\n", " sample(formulas, dim=2)\n", " ```\n", "- **`tolerance`** — override the default metallic radii with custom minimum distances (in Å per element radius):\n", " ```python\n", " sample(formulas, tolerance={'Mg': 1.0, 'Ca': 1.2})\n", " ```" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.15" } }, "nbformat": 4, "nbformat_minor": 5 }