{ "cells": [ { "cell_type": "markdown", "id": "c1f5da2b8", "metadata": {}, "source": [ "# Structures: httk-core and httk-atomistic together\n", "\n", "This notebook shows two *httk₂* modules composing over the shared `httk.*` namespace: `httk-atomistic` provides the crystal-structure domain, while `httk-core` provides the `DataLoader` used to read a structure from JSON. Their versioned module documentation is listed in the site module directory. It is executed during the docs build, so its outputs reflect the current API." ] }, { "cell_type": "markdown", "id": "c1ccae8b0", "metadata": {}, "source": [ "## Building a structure\n", "\n", "A `Structure` is defined by a `cell` (3×3 matrix), `sites` (reduced coordinates), a list of `species`, and `species_at_sites` naming the species on each site. Species follow the OPTIMADE `species` object: a `name`, a list of `chemical_symbols`, and matching `concentration` values. Here we build zinc-blende GaAs." ] }, { "cell_type": "code", "execution_count": 1, "id": "cf827e94a", "metadata": { "execution": { "iopub.execute_input": "2026-07-22T22:39:52.749682Z", "iopub.status.busy": "2026-07-22T22:39:52.749302Z", "iopub.status.idle": "2026-07-22T22:39:52.816665Z", "shell.execute_reply": "2026-07-22T22:39:52.815018Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "species : ['Ga', 'As']\n", "species_at_sites: ('Ga', 'As')\n" ] } ], "source": [ "from httk.atomistic import Structure\n", "\n", "species = [\n", " {\"name\": \"Ga\", \"chemical_symbols\": [\"Ga\"], \"concentration\": [1.0]},\n", " {\"name\": \"As\", \"chemical_symbols\": [\"As\"], \"concentration\": [1.0]},\n", "]\n", "cell = [[0.0, 2.825, 2.825], [2.825, 0.0, 2.825], [2.825, 2.825, 0.0]]\n", "sites = [[0.0, 0.0, 0.0], [0.25, 0.25, 0.25]]\n", "species_at_sites = [\"Ga\", \"As\"]\n", "\n", "structure = Structure(cell, sites, species, species_at_sites)\n", "print(\"species :\", [s.name for s in structure.species])\n", "print(\"species_at_sites:\", structure.species_at_sites)" ] }, { "cell_type": "markdown", "id": "c3572f485", "metadata": {}, "source": [ "## Round-tripping through the primitive view\n", "\n", "`StructurePrimitiveView` presents any structure backend as an spglib-like `(lattice, positions, numbers)` tuple — bare atomic numbers instead of named species. `UnitcellStructureView` presents it back as a full `Structure`." ] }, { "cell_type": "code", "execution_count": 2, "id": "ce02ea9a6", "metadata": { "execution": { "iopub.execute_input": "2026-07-22T22:39:52.820465Z", "iopub.status.busy": "2026-07-22T22:39:52.820116Z", "iopub.status.idle": "2026-07-22T22:39:52.828305Z", "shell.execute_reply": "2026-07-22T22:39:52.826549Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "atomic numbers: (31, 33)\n", "cell preserved : True\n", "species_at_sites preserved: True\n" ] } ], "source": [ "from httk.atomistic import StructurePrimitiveView, UnitcellStructureView\n", "\n", "lattice, positions, numbers = StructurePrimitiveView(structure)\n", "print(\"atomic numbers:\", numbers)\n", "\n", "roundtrip = UnitcellStructureView(StructurePrimitiveView(structure))\n", "print(\"cell preserved :\", roundtrip.cell == structure.cell)\n", "print(\"species_at_sites preserved:\", roundtrip.species_at_sites == structure.species_at_sites)" ] }, { "cell_type": "markdown", "id": "c6e827583", "metadata": {}, "source": [ "## When the primitive view does not apply\n", "\n", "The primitive representation carries only bare atomic numbers, so every site must be a single, unattached chemical element. A structure with a `vacancy` species cannot become a primitive triple — building the view raises `TypeError`." ] }, { "cell_type": "code", "execution_count": 3, "id": "ccc4547cb", "metadata": { "execution": { "iopub.execute_input": "2026-07-22T22:39:52.832074Z", "iopub.status.busy": "2026-07-22T22:39:52.831677Z", "iopub.status.idle": "2026-07-22T22:39:52.840278Z", "shell.execute_reply": "2026-07-22T22:39:52.838590Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TypeError: This structure cannot be represented as a primitive structure (species 'Vac' is not a single, unattached chemical element)\n" ] } ], "source": [ "vacancy_species = [\n", " {\"name\": \"Ga\", \"chemical_symbols\": [\"Ga\"], \"concentration\": [1.0]},\n", " {\"name\": \"Vac\", \"chemical_symbols\": [\"vacancy\"], \"concentration\": [1.0]},\n", "]\n", "with_vacancy = Structure(cell, sites, vacancy_species, [\"Ga\", \"Vac\"])\n", "\n", "try:\n", " StructurePrimitiveView(with_vacancy)\n", "except TypeError as error:\n", " print(\"TypeError:\", error)" ] }, { "cell_type": "markdown", "id": "cb4a63ca6", "metadata": {}, "source": [ "## Loading a structure from JSON via httk-core\n", "\n", "The quartet can just as well come from data. Here httk-core's `DataLoader` parses a structure-shaped JSON document (passed inline with `kind=\"content\"`), and httk-atomistic constructs the `Structure` from it — the two modules composing over the shared namespace." ] }, { "cell_type": "code", "execution_count": 4, "id": "cb39255a4", "metadata": { "execution": { "iopub.execute_input": "2026-07-22T22:39:52.844693Z", "iopub.status.busy": "2026-07-22T22:39:52.844330Z", "iopub.status.idle": "2026-07-22T22:39:52.853439Z", "shell.execute_reply": "2026-07-22T22:39:52.851907Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "equal to the hand-built structure: True\n" ] } ], "source": [ "import json\n", "\n", "from httk.core import DataLoader\n", "\n", "document = json.dumps(\n", " {\n", " \"cell\": cell,\n", " \"sites\": sites,\n", " \"species\": species,\n", " \"species_at_sites\": species_at_sites,\n", " }\n", ")\n", "\n", "record = DataLoader(\"gaas-structure\", document, kind=\"content\").data\n", "from_json = Structure(\n", " record[\"cell\"], record[\"sites\"], record[\"species\"], record[\"species_at_sites\"]\n", ")\n", "print(\"equal to the hand-built structure:\", from_json == structure)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }