molcryst
Documentation: https://delonecommons.github.io/molcryst/
molcryst is a Python package for representing and analyzing molecular crystals, with an emphasis on a clear crystal object model (COM) and exact, reproducible symmetry handling.
The core goals are:
- a clear crystal object model (COM) (records → entities → keys → views)
- exact, reproducible symmetry handling (deterministic integer-grid logic)
- practical building blocks for workflows around bonds, components, and contacts
Current candidate
The current candidate source reports version 0.3.0. WP1–WP4 are accepted and
merged; exact-revision qualification and publication remain pending under WP5.
Its implemented building blocks include:
- the canonical root façade
import molcryst as mc - deterministic integer-grid symmetry primitives (
FracQ,SymOp,derive_Q) - a strict structure-owned symmetry service via
Structure.symmetry - uniform orbit helpers on
Atom,Bond,Component, andContact - CIF I/O through
gemmi, including multi-block helpers - periodic covalent bonds and covalent components (molecules vs networks)
- reusable contact definitions via
Structure.contacts(...)andContactSet - declarative contact filtering via
ContactSelectionandContactSubset - line-of-sight (LoS) contact annotation on top of stored contacts
- record-level hydrogen normalization with configurable
XHScheme/ overrides - atomref-backed curated element, radii, and X-H dataset lookup through
molcryst.chem
Status
molcryst is pre-alpha and under closed, maintainer-led development. Scientific correctness comes first; architectural simplicity comes second. There are currently no external users and no external-user backward-compatibility commitment. Obsolete or unnecessary functionality, APIs, and abstractions are removed outright within approved work; internal callers, tests, examples, and documentation are updated together. See the closed-development policy.
Only the maintainer decides when development opens and what compatibility commitments follow. There is no scheduled opening date. Correct native xyz2mol functionality, a minimum useful feature set to be defined during development, and qualification on COD are the anticipated basis for considering that decision; completing them does not automatically open the project.
The current root façade is the preferred interface to teach and test:
- the root import path and the structure/view object model are the primary public surface
- symmetry partitions and representative choice are owned by
Structure.symmetry - hard dependencies (
atomref,pbcgraph) are expected to fail eagerly on normal import paths
Known limitations include restricted operation denominators, a finite-image nearest-distance search, and incomplete handling of unresolved disorder. See capabilities and limitations before relying on general CIF coverage. Recording these limitations does not implement their fixes.
Where to go next
-
Guide
- Installation and local workflows: Install
- Minimal workflow and usage patterns: Quickstart
- Supported workflows and known risks: Capabilities and limitations
- Contacts and LoS: Contacts and LoS
- The COM mental model: Mental model
-
Examples
- User-oriented notebook workflows based on the main public interface
- Advanced notebooks that show internal representations and lower-level workflows
-
API
- API reference generated from docstrings
-
Development
- Start here: Development documentation
- Current architecture, accepted/proposed decisions, plans, audit evidence, and validation
-
Project
- Scientific intent: Scope
- Longer-term direction: Roadmap
- Changelog and license information
Quickstart
A minimal end-to-end workflow looks like this:
- read a CIF,
- build a reusable contact definition,
- compute LoS annotations,
- narrow to a filtered subset,
- traverse through structure-bound views.
Load a structure
import molcryst as mc
# Load the first CIF block by default.
s = mc.Structure.from_cif_file('my_structure.cif')
# If a CIF contains multiple blocks, choose by index or block name.
# s = mc.Structure.from_cif_file('multi.cif', block=0)
# s = mc.Structure.from_cif_file('multi.cif', block='MYBLOCK')
The Structure object is the main convenience façade. It lazily builds and
caches canonical atom entities, bonds/components, contacts, and
several periodic graph views.
Build a contact definition
# Intermolecular contacts up to a cutoff (Å).
base = s.contacts(cutoff=3.5, scope='inter')
print('n selected:', len(base))
print('n store total:', len(s.contact_store))
Notes:
Structureowns a single mutableContactStore.baseis a lightweightContactSetbound to a full contact definition (ContactSettings), not just a(cutoff, scope)pair.- public contact definitions are non-covalent relative to the active bond layer, so directly bonded pairs are excluded from the store.
- Passing
cutoff=toStructure.contacts(...)is a convenience that asks for an absolute-distance contact definition.
Compute LoS annotations
# Compute LoS (line-of-sight) for this definition.
params_id = base.ensure_los(definition='chernyshov2020')
# You can also request the Taylor definition.
# params_id = base.ensure_los(definition='taylor2014')
LoS is implemented as an annotation layer on top of the selected contacts. No new contacts are enumerated; existing contacts are annotated.
Narrow to a filtered subset
los = base.select(
mc.ContactSelection(
annotation_method='los',
annotation_params_id=params_id,
annotation_where=lambda ann: bool(ann.data['los']),
)
)
print('n LoS:', len(los))
You can use the same API for distance windows, vdW-gap windows, or additional scope filtering.
Inspect one contact
k = los.keys[0]
c = los.get(k)
ann = c.annotations[('los', params_id)]
print('edge:', k)
print('distance:', c.distance)
print('los:', ann.data['los'])
print('dR:', ann.data['dR'])
print('shield atom:', ann.data['shield_atom_id'], (ann.data['shield_tx'], ann.data['shield_ty'], ann.data['shield_tz']))
print('valid:', ann.data['valid'], 'radii_complete:', ann.data['radii_complete'])
Traverse with views and build graphs
center = s.atom(0)
print('bonded neighbors:', center.bonded_neighbors())
print('LoS contact neighbors:', center.contact_neighbors(sel=los))
atom_graph = los.atom_graph()
component_graph, bundles = los.component_graph()
print('atom graph edges:', len(atom_graph.edges))
print('component graph edges:', len(component_graph.edges))
Work with symmetry orbits
All orbit partitioning is owned by Structure.symmetry.
print('unique atom ids:', s.symmetry.unique_atom_ids())
print('unique bond edges:', [b.edge for b in s.symmetry.unique_bonds()])
print('unique component ids:', s.symmetry.unique_component_ids())
unique_contacts = s.symmetry.unique_contacts(los, rep_policy='canonical')
print('unique LoS contacts:', [c.edge for c in unique_contacts])
Views expose matching convenience helpers:
atom = s.atom(0)
print('atom orbit size:', atom.orbit_size())
print('atom rep:', atom.orbit_rep().atom_id)
contact = unique_contacts[0]
print('contact orbit size in selection:', contact.orbit_size(selection=los))
print('contact rep in selection:', contact.orbit_rep(selection=los).edge)
Notes:
Atom,Bond, andComponentorbit helpers classify the underlying reference-cell object; the viewshiftdoes not change orbit identity.Contactorbit helpers are selection-scoped, so the selection must be passed explicitly.- Symmetry queries are strict: if a requested surface is unavailable or not symmetry-closed, molcryst raises instead of silently degrading.
Installation and local development
molcryst is a research-focused, pre-alpha Python package.
Requirements
- Package metadata requires Python >=3.10. The explicit v0.3 release qualification matrix is 3.10–3.13; candidate qualification remains pending. Python 3.14 is outside that matrix.
- Runtime dependencies are installed automatically:
atomref(curated element/radii/X-H datasets and transfer engine)gemmi(CIF parsing)scipy(KDTree-based neighbour candidates)pbcgraph(periodic graph utilities)
Published release
After 0.3.0 has been qualified and published, install the published release with:
python -m pip install molcryst==0.3.0
The current source is a 0.3.0 candidate; this command is not a claim that
publication has happened.
Local candidate wheel
To inspect a locally supplied candidate wheel, create a separate environment and install the exact file:
python -m venv .venv-candidate
# Activate .venv-candidate using the command appropriate for your shell.
python -m pip install /path/to/molcryst-0.3.0-py3-none-any.whl
Installing a candidate does not establish release qualification.
Contributor editable checkout
Run contributor commands from a repository checkout:
python -m venv .venv
# Activate .venv using the command appropriate for your shell.
python -m pip install -e ".[test,docs,dev]"
Respect the declared dependency ranges, including pbcgraph>=0.1.4 and
atomref>=0.1.4,<0.2; an arbitrary sibling checkout may not satisfy them. Installing
sibling HEADs or widening their ranges is a separate compatibility task, not a
prerequisite for ordinary documentation work.
This installs:
- the package itself
- test dependencies (
pytest) - docs dependencies (
mkdocs,mkdocs-material,mkdocstrings,nbconvert, ...) - development tools (
flake8, build helpers)
For a runtime-only editable checkout, omit the extras:
python -m pip install -e .
The test, documentation and notebook commands below are repository workflows.
The public sdist contains package source, build metadata, README and legal files
plus .gitignore; it does not contain tests, docs, notebooks or contributor tools.
Run repository tests
python -m pytest
Build or preview existing documentation
For a prose/navigation change, regenerate/check only the README and build the site from the committed example pages:
python tools/gen_readme.py
python tools/gen_readme.py --check
python -m mkdocs build --clean --strict
# Or preview the same pages locally:
python -m mkdocs serve
See development validation and the development entry point for checks and work plans.
Generated docs artifacts
The local docs workflow maintains two generated artifacts:
- example pages under
docs/examples/, rendered from the source notebooks innotebooks/ - the root
README.md, generated from selected docs pages so the package landing page stays aligned with the site
The current README source pages are:
docs/index.mddocs/guide/quickstart.mddocs/guide/install.md
The notebook renderer executes source notebooks in place and writes their
outputs. sync_docs.py --check-readme also executes notebooks unless paired with
--readme-only. Do not run a notebook refresh merely to validate a prose edit;
use a disposable copy when qualifying notebook execution.
For an intentional notebook/output refresh, refresh both generated artifacts and build the site:
python tools/sync_docs.py
python -m mkdocs build
After that intentional refresh, python -m mkdocs serve previews the generated
pages without another notebook execution.
Under the hood, this runs tools/render_examples.py (examples) and tools/gen_readme.py (README).
Sync only the README
python tools/sync_docs.py --readme-only
# or:
python tools/gen_readme.py
To verify that the committed README is still in sync without rewriting it:
python tools/sync_docs.py --readme-only --check-readme
# or:
python tools/gen_readme.py --check
This README is auto-generated from selected docs pages (docs/index.md, docs/guide/quickstart.md, and docs/guide/install.md).
To update it, edit those docs pages and re-run: python tools/sync_docs.py --readme-only (or python tools/gen_readme.py).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file molcryst-0.3.0.tar.gz.
File metadata
- Download URL: molcryst-0.3.0.tar.gz
- Upload date:
- Size: 153.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63987a29a9d5c8e388e5204e1ab3f063906f39e2d121c534d74b352e8147acb1
|
|
| MD5 |
fe31e8702a8aff32e75bfc8ad0c77770
|
|
| BLAKE2b-256 |
ad2e95e834c59eff36535611fca6730daf0fe50c0d099f3512ea7b436a6562fd
|
File details
Details for the file molcryst-0.3.0-py3-none-any.whl.
File metadata
- Download URL: molcryst-0.3.0-py3-none-any.whl
- Upload date:
- Size: 212.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e501632e8f164ca209f6303e36d0fbf61c2bb2d26426ba650aa7d7f451990188
|
|
| MD5 |
590e028b1150c62fd153e22dfa53a952
|
|
| BLAKE2b-256 |
6b2bd9eb65c3ccb9ab1e980a312d60f61890a66db265680ad21baa8cdc25c50e
|