Ingesting source data

Before you can run anything you need to read source files — CIFs from a database, POSCARs from an earlier project, outputs from a finished run. In httk v1 loading dispatched to a patchwork of format backends, some of them external command-line tools configured in httk.cfg. In httk₂ there is one entry point, the readers are pure Python, and dispatch is by filename.

One entry point

httk.core.load(path) returns the file’s native representation: a CIF loads as an asymmetric-unit structure, a POSCAR as a unit-cell structure. Compressed files decompress transparently, and dispatch is on the extension or exact basename, case-insensitively.

from httk.core import load

structure = load("example.cif")        # CIF -> ASUStructure
# POSCAR, CONTCAR, and "CONTCAR.bz2" work too; POSCAR -> UnitcellStructure.

print("Formula:", structure.formula)
print("Volume:", float(structure.cell.volume))

To expand an asymmetric unit to a full unit cell, or to get the lazy view form, construct the view explicitly:

from httk.atomistic import UnitcellStructureView

unitcell = UnitcellStructureView(load("example.cif"))
unitcell = UnitcellStructureView("example.cif")   # equivalent, lazy

For a remote source, httk.core.fetch(url) takes a plain URL string and is itself the explicit network consent. The lazy view/loader path instead gates remote access with a DatastreamURL token — for example UnitcellStructureView(DatastreamURL(url)). New formats are added by modules through register_reader; httk-atomistic registers the CIF/mCIF, POSCAR, OUTCAR, and WAVECAR readers among others. The ASE bridge works both directions (UnitcellStructureView(atoms) and ASEAtomsView(structure)), and a pymatgen bridge lives in httk.atomistic.

In httk v1

httk.load() existed, but it dispatched to per-format backends — httk.atomistic.atomisticio.cif_to_struct(filename, backends=['internal', 'cif2cell', 'ase', 'platon']) for CIFs, httk.iface.vasp_if.poscar_to_structure() for POSCARs. The pure-Python internal backend came first; the external tools (cif2cell, ase, platon) were optional fallbacks, used only if installed and configured in httk.cfg under [paths]. httk₂ readers are pure Python, registered, and chosen by filename with no external-tool configuration.

In httk v1

You may have loaded through the class method Structure.io.load("example.cif"). The httk₂ equivalent is UnitcellStructureView(load(path)) (or passing the path straight to the view). See Structures and file formats for the current structure vocabulary — views, asymmetric units, and where exact geometry becomes a float.

Into a database

The same source directory can become a queryable DuckDB httk-store database. UnitcellStructureView normalizes each CIF-native asymmetric unit to the unit-cell representation declared for the structures entry family:

from pathlib import Path

from httk.atomistic import StructureEntry, UnitcellStructureRecord, UnitcellStructureView
from httk.core import load
from httk.store import Backend, EntryIdScheme, SqlStore

db = Backend.duckdb("source.duckdb")
store = SqlStore(
    db,
    entry_records={StructureEntry: UnitcellStructureRecord},
    entry_ids=EntryIdScheme("httk.source", "1"),
)

count = 0
with store.transaction():
    for path in sorted(Path("structures").glob("*.cif")):
        structure = UnitcellStructureView(load(path))
        store.save(structure)
        count += 1

print(f"Stored {count} structures")

Records are content-addressed and deduplicated, so re-running the ingest is idempotent. The same store can later receive calculation results; see Storing data in a database.

In httk v1

The comparable habit was store.save(struct) on httk.db.store.SqlStore; httk₂ keeps the save operation but declares the durable structure representation when the store is first opened.