httk.atomistic.io.cif.cif_parser

Classes

CifMeta

What a CIF number claims about its own precision, beyond its value.

AsuCell

Hold the parsed cell, atom sites, exact tokens, and precision claims.

Functions

parse_cif_float(…)

Parse a CIF numeric field.

parse_cif_fraction(token)

Parse a CIF numeric token exactly, preserving finite decimals and fractions.

parse_cif_int(token, *[, strict, allow_round])

Convert a CIF numeric token to an integer using its central value.

cif_exact_token(token)

The numeric part of a CIF value, as text, with any uncertainty estimate removed.

parse_asu_cell(cifblock)

Parse a CIF block into its asymmetric-unit cell data.

parse_structural_modulation(cifblock)

Extract structural superspace modulation information from a standard CIF.

cifblock_to_asu(cifblock)

Convert one normalized CIF block to a neutral asymmetric-unit payload.

read_cif_asus(source, *[, autocorrect])

Read a CIF and return its asymmetric units as a neutral, tagged payload.

single_asu_from_cif_file(source)

Return the first structural CIF block from read_cif_asus().

Module Contents

class httk.atomistic.io.cif.cif_parser.CifMeta[source]

Bases: TypedDict

What a CIF number claims about its own precision, beyond its value.

Both are exact rationals, or None when the token makes no such claim. None is not the same as claiming exactness: a value written 1/3 states an exact number and reports None for both, while ? states nothing at all and also reports None.

precision is implied by the digits written (0.3333 is good to 1/10000); esd is the standard uncertainty a file states explicitly, so 0.3333(7) reports a precision of 1/10000 and an esd of 7/10000. They measure different things and the coarser of the two is the honest claim.

Parameters:
  • esd – Standard uncertainty explicitly stated by the CIF token.

  • precision – Precision implied by the digits written in the CIF token.

esd: fractions.Fraction | None[source]
precision: fractions.Fraction | None[source]
httk.atomistic.io.cif.cif_parser.parse_cif_float(token: str, *, meta: Literal[False] = ..., pragmatic: bool = ...) float | None[source]
httk.atomistic.io.cif.cif_parser.parse_cif_float(token: str, *, meta: Literal[True], pragmatic: bool = ...) tuple[float | None, CifMeta]

Parse a CIF numeric field.

If meta=False:

return float_value or None.

If meta=True:

return (float_value_or_None, CifMeta) — the value plus what the token claims about its own precision. See CifMeta; both of its fields are exact rationals or None.

Parameters:
  • token – Numeric text to parse, including CIF uncertainty notation when present.

  • meta – Include the value’s claimed precision and standard uncertainty.

  • pragmatic – Salvage selected non-standard numeric spellings instead of rejecting them.

Returns:

The parsed value, optionally paired with its precision metadata.

Raises:

ValueError – If the token is missing or cannot be interpreted as a CIF number.

httk.atomistic.io.cif.cif_parser.parse_cif_fraction(token)[source]

Parse a CIF numeric token exactly, preserving finite decimals and fractions.

Parameters:

token (str) – Numeric text whose exact central value should be preserved.

Returns:

The exact value, or None for an unknown CIF value.

Raises:

ValueError – If the token does not contain a valid exact numeric value.

Return type:

fractions.Fraction | None

httk.atomistic.io.cif.cif_parser.parse_cif_int(token, *, strict=True, allow_round=False)[source]

Convert a CIF numeric token to an integer using its central value.

The accepted forms include '123(4)', '3E2', and '1.0E3'. - strict=True: require the value to be exactly integral; otherwise raise ValueError. - allow_round=True (only if strict=False): round half-even to the nearest int.

Parameters:
  • token (str) – Numeric text to convert.

  • strict (bool) – Require the central value to be integral.

  • allow_round (bool) – Permit half-even rounding when strict is false.

Returns:

The converted integer.

Raises:
  • ValueError – If the token is missing or its central value cannot be converted under the selected rules.

  • decimal.InvalidOperation – If an unmatched token has malformed decimal syntax.

Return type:

int

httk.atomistic.io.cif.cif_parser.cif_exact_token(token)[source]

The numeric part of a CIF value, as text, with any uncertainty estimate removed.

"0.3333(5)" becomes "0.3333" and "3(1)e-1" becomes "3e-1"; "?" and "." become None. The point of keeping the text rather than a float is fidelity: a consumer that wants an exact value can read 0.3333 as the rational 3333/10000, which is what the file says, whereas float("0.3333") is a binary approximation whose exact rational value is 6004199023210345/18014398509481984 and says something the file did not.

Parameters:

token (str) – CIF value text whose uncertainty estimate should be removed.

Returns:

The central numeric text, or None for an unknown value.

Return type:

str | None

class httk.atomistic.io.cif.cif_parser.AsuCell[source]

Bases: NamedTuple

Hold the parsed cell, atom sites, exact tokens, and precision claims.

Parameters:
  • basis – Conventional Cartesian basis vectors for the unit cell.

  • positions – Fractional atom positions.

  • positions_exact – Original central coordinate tokens for each atom.

  • occupancies – Parsed atom occupancies, when supplied.

  • occupancies_exact – Original central occupancy tokens, when supplied.

  • occupancy_precisions – Coarsest claimed precision for each occupancy, when supplied.

  • coordinate_precision – Coarsest claimed precision across the coordinates.

  • basis_precision – Coarsest claimed precision across the cell lengths.

  • symbols – Atom-site symbols in input order.

  • labels – Atom-site labels in input order.

  • equivalent_atoms – One-based identifiers grouping equal atom-site labels.

basis: list[list[float]][source]
positions: list[tuple[float | None, float | None, float | None]][source]
positions_exact: list[tuple[str | None, str | None, str | None]][source]
occupancies: list[float | None] | None[source]
occupancies_exact: list[str | None] | None[source]
occupancy_precisions: list[fractions.Fraction | None] | None[source]
coordinate_precision: fractions.Fraction | None[source]
basis_precision: fractions.Fraction | None[source]
symbols: list[str][source]
labels: list[str][source]
equivalent_atoms: list[int][source]
httk.atomistic.io.cif.cif_parser.parse_asu_cell(cifblock)[source]

Parse a CIF block into its asymmetric-unit cell data.

Parameters:

cifblock (collections.abc.Mapping[str, Any]) – Normalized CIF data for one data block.

Returns:

The parsed unit cell and atom-site data.

Raises:

ValueError – If required cell or atom-site data is missing or invalid.

Return type:

AsuCell

httk.atomistic.io.cif.cif_parser.parse_structural_modulation(cifblock)[source]

Extract structural superspace modulation information from a standard CIF.

Returns a tuple (structural_q, mod_dim, has_struct_mod, struct_mod_atoms) where

structural_q is a list of q-vectors or None, mod_dim is the modulation dimension (0 if absent), has_struct_mod is a bool, and struct_mod_atoms is a sorted list of atom-site labels.

Parameters:

cifblock (collections.abc.Mapping[str, Any]) – Normalized CIF data for one data block.

Returns:

Structural q-vectors, modulation dimension, presence flag, and affected labels.

Raises:

ValueError – If a structural wave vector contains an unknown component.

Return type:

tuple[list[list[fractions.Fraction]] | None, int, bool, list[str]]

httk.atomistic.io.cif.cif_parser.cifblock_to_asu(cifblock)[source]

Convert one normalized CIF block to a neutral asymmetric-unit payload.

The payload keeps cell_parameters_exact and positions_exact as the central numeric text written by the file, and keeps symops_xyz as the raw operation strings. The dual numeric channel gives _httk_*_exact companion tags precedence over standard numeric tags on read, preserving central text after a lossy display write.

Parameters:

cifblock (collections.abc.Mapping[str, Any]) – Normalized CIF data for one data block.

Returns:

A neutral mapping containing cell, atom, symmetry, and metadata channels.

Raises:

ValueError – If the block lacks required cell, atom-site, or symmetry data.

Return type:

dict[str, Any]

httk.atomistic.io.cif.cif_parser.read_cif_asus(source, *, autocorrect=False)[source]

Read a CIF and return its asymmetric units as a neutral, tagged payload.

This is what httk.core.load returns for a .cif file: a mapping with format set to "cif", blocks holding one asymmetric-unit mapping per data block that describes a structure, and header the file’s leading comment. The tag lets a consumer dispatch on the file type without knowing which reader produced the payload. When autocorrect=True, the top-level payload also contains autocorrect=True so downstream adapters can apply compatible repairs.

Loading never fails on account of a block that is not a structure. CIF is a general-purpose format and a file may hold bibliographic entries, powder patterns, or an incomplete draft alongside — or instead of — anything crystallographic. Blocks without atom sites are simply not structures and are passed over; blocks that have atom sites but cannot be interpreted are collected in unparsed, each with the reason, so that nothing is dropped silently and the failure surfaces when a structure is actually asked for.

The mapping stays neutral — plain lists, strings, exact numeric text channels, and raw symmetry-operation strings, with no domain objects — so this reader layer need not know about the httk-atomistic structure model. Turning it into a structure is httk.core.load (which returns an ASUStructure when atomistic support is installed).

Parameters:
Returns:

A neutral CIF payload containing structural blocks, unparsed block reasons, and the header.

Raises:

ValueError – If the CIF stream contains malformed data that prevents parsing.

Return type:

dict[str, Any]

httk.atomistic.io.cif.cif_parser.single_asu_from_cif_file(source)[source]

Return the first structural CIF block from read_cif_asus().

Parameters:

source (str | os.PathLike[str] | collections.abc.Iterable[str]) – A filename, open text stream, or iterable of CIF lines.

Returns:

The first parsed asymmetric-unit mapping.

Raises:

ValueError – If no structural block is available.

Return type:

dict[str, Any]