optmat.identity#

The identity of a model: a digest of what it evaluates, and its status.

A propagation code that records which model produced its numbers needs a name that changes whenever the numbers can. Every model, response and bundle of the public surface therefore has an identity, a ModelIdentity whose digest is the SHA-256 of a canonical record of the model (OEP 1, section 4.8):

  • the class’s qualified name;

  • the EVALUATION_VERSION of the class and of every class it inherits evaluation from, and of each shared evaluator module it evaluates through, raised whenever that code changes its output;

  • every field: the constructor’s parameters, including those that fix a state, and the values evaluation reads (a fit’s terms, a spectrum’s grid), not the files that produced them;

  • extras a class declares: its validity where it is not a field, values it resolves once from another component, and the digests of the components it is bound to.

The converse is not promised: an edit that leaves every number unchanged may still change the digest. The package version is recorded beside the digest, not in it, so a digest survives a release that did not touch the model.

The record is serialised as JSON with sorted keys and no insignificant whitespace, UTF-8, floats in Python’s shortest round-trip form, non-finite floats as the strings "inf", "-inf" and "nan", arrays as lists, a complex number as [re, im] and an enumeration by its value.

Overrides (OEP 1, section 6.3). model.with_parameters(**changes) rebuilds a model with some of its inputs changed: the class declares the inputs an override may name (INPUTS) and refuses the fields derived from them (DERIVED). The result has the status user, records the changes in its identity’s modified and the curated model’s digest in base, and drops the base’s stated uncertainty.

A model owns its storage: its arrays are copied at construction and made read-only, and its mappings are copied into read-only mappings, so the digest stays true for the object’s life. That guards against accidents; it is not a security boundary.

This module is part of the core and imports no medium.

Module Attributes

Status

How far a model is to be trusted.

Functions

canonical(value)

Return a value as the plain JSON types of the canonical record.

canonical_json(value)

Return the canonical JSON of a value, UTF-8.

describe(value)

Return a short description of an override's value, for modified.

frozen(value)

Return a read-only copy of a value a model is to own.

parse_status(entry, where, *, default)

Return the status and reason a curated data entry declares.

sha256_digest(value)

Return the SHA-256 of a value's canonical JSON.

source_ids(*texts)

Return the source records named by dataset keys in some texts.

Classes

FrozenMapping([items])

A read-only mapping that owns a copy of its items.

Identified(*[, status, status_reason, ...])

A model that owns its storage and has an identity.

ModelIdentity(name, kind, material, digest, ...)

The identity of a model: what it is, a digest of its numbers, and its status.

class optmat.identity.FrozenMapping(items=())[source]#

Bases: Mapping, Generic

A read-only mapping that owns a copy of its items.

Unlike types.MappingProxyType it can be pickled, so a model that holds one can be sent to another process.

Parameters:
itemsMapping or iterable of pairs, optional

The items, copied.

Examples

>>> m = FrozenMapping({"a": 1})
>>> m["a"], len(m), dict(m)
(1, 1, {'a': 1})
class optmat.identity.Identified(*, status='user', status_reason='', modified=(), base='')[source]#

Bases: ABC

A model that owns its storage and has an identity.

A subclass is a frozen dataclass. It declares IDENTITY_KIND, its own EVALUATION_VERSION (raised whenever its output changes), and in EVALUATES_THROUGH the shared evaluator modules whose module-level EVALUATION_VERSION also governs its output. It implements _identity_label, and _identity_extras where its record needs more than its fields. A subclass that defines __post_init__ calls this class’s.

Attributes:
statusstr

One of STATUSES; "user" unless a curated builder says otherwise.

status_reasonstr

Why, where that needs saying.

modifiedtuple of tuple of str

The overrides applied, (name, value) sorted by name.

basestr

The digest of the curated model the overrides started from, or empty.

DERIVED: ClassVar[tuple[str, ...]] = ()#

Fields derived from the inputs, which an override may not name.

EVALUATES_THROUGH: ClassVar[tuple[str, ...]] = ()#
IDENTITY_KIND: ClassVar[str]#
INPUTS: ClassVar[tuple[str, ...]] = ()#

The parameters with_parameters() may change.

base: str = ''#
property identity: ModelIdentity[source]#

The model’s identity, computed once.

Returns:
ModelIdentity

Its name, kind, material, digest, sources and status.

identity_record()[source]#

Return the canonical record the digest is taken of.

Returns:
dict

{class, versions, fields, extras} in plain JSON types. The status is not in it.

modified: tuple[tuple[str, str], ...] = ()#
status: Status = 'user'#
status_reason: str = ''#
with_parameters(**changes)[source]#

Return the model rebuilt with some of its inputs changed (OEP 1, 6.3).

Parameters:
**changes

New values of inputs the class declares in INPUTS.

Returns:
Identified

The rebuilt model: status user, the changes in identity.modified, the curated model’s digest in identity.base, and no stated uncertainty unless the changes give one.

Raises:
OptmatError

With no change, or a name that is derived or not an input.

class optmat.identity.ModelIdentity(name, kind, material, digest, optmat_version, sources, status, status_reason, modified=(), base='', reference_temperature=None, infrared_temperature=None)[source]#

Bases: object

The identity of a model: what it is, a digest of its numbers, and its status.

Attributes:
namestr

The model’s name, such as "fit/Ar" or "rate/default/Ar@800nm".

kindstr

The quantity the model gives: "gas_refractive", "gas_hyperpolarizability", "ionisation_rate", "raman_response", "solid" or "kerr". It is not the model’s own kind, which on a dispersion model names its provenance (published, fitted, …).

materialstr

The material: a gas, a solid, a mixture such as "dry air", or a custom species’ name.

digeststr

The SHA-256 of the model’s canonical record, 64 hexadecimal digits.

optmat_versionstr

The package version that built the model; informational, not in the digest.

sourcestuple of str

The source records the model rests on.

statusstr

One of STATUSES.

status_reasonstr

Why the status is what it is, where that needs saying.

modifiedtuple of tuple of str

The overrides applied, (name, value) sorted by name; empty for a curated model.

basestr

The digest of the curated model an override started from, or empty.

reference_temperaturefloat or None

The temperature a gas polarizability refers to, K, where its source declares one.

infrared_temperaturefloat or None

The temperature of a molecular fit’s fixed infrared terms, K.

base: str = ''#
digest: str#
infrared_temperature: float | None = None#
kind: str#
material: str#
modified: tuple[tuple[str, str], ...] = ()#
name: str#
optmat_version: str#
reference_temperature: float | None = None#
sources: tuple[str, ...]#
status: str#
status_reason: str#
type optmat.identity.Status = Literal['validated', 'provisional', 'untested', 'comparison', 'user']#

How far a model is to be trusted.

  • validated: a default, with a stated uncertainty;

  • provisional: a known stopgap;

  • untested: no reference to test it against;

  • comparison: a literature form kept for comparison;

  • user: built from parameters a caller supplied, or changed by an override; a curated model’s stated uncertainty does not carry over to it.

optmat.identity.canonical(value)[source]#

Return a value as the plain JSON types of the canonical record.

Parameters:
valueobject

A field’s value.

Returns:
object

None, a bool, an int, a str, a finite float, or lists and dicts of them.

Raises:
TypeError

For a value with no canonical form.

Notes

A model with an identity enters as its type and digest, which is how a model records the components it is bound to. Any other dataclass enters as its type, the EVALUATION_VERSION its class declares, and its fields.

Examples

>>> canonical((1.5, float("inf"), 2 + 1j))
[1.5, 'inf', [2.0, 1.0]]
optmat.identity.canonical_json(value)[source]#

Return the canonical JSON of a value, UTF-8.

Parameters:
valueobject

Anything canonical() accepts.

Returns:
bytes

The JSON, keys sorted, with no insignificant whitespace.

Examples

>>> canonical_json({"b": 1, "a": [0.1, float("nan")]})
b'{"a":[0.1,"nan"],"b":1}'
optmat.identity.describe(value)[source]#

Return a short description of an override’s value, for modified.

Parameters:
valueAny

The value.

Returns:
str

Its canonical JSON if that is short, else its SHA-256 prefixed sha256:.

Examples

>>> describe(2.4)
'2.4'
>>> describe(list(range(100)))[:7]
'sha256:'
optmat.identity.frozen(value)[source]#

Return a read-only copy of a value a model is to own.

Parameters:
valueobject

A field’s value.

Returns:
object

An array copied and marked read-only; a mapping copied into a FrozenMapping of frozen values; a list or tuple as a tuple of frozen values (a named tuple keeps its type); anything else unchanged.

Examples

>>> a = np.zeros(2)
>>> b = frozen(a)
>>> b.flags.writeable, b is a
(False, False)
>>> frozen({"x": [1, 2]})
FrozenMapping({'x': (1, 2)})
optmat.identity.parse_status(entry, where, *, default)[source]#

Return the status and reason a curated data entry declares.

Parameters:
entryMapping

The entry, with optional keys status and status_reason.

wherestr

The entry’s location, for error messages.

defaultstr

The status of an entry that declares none.

Returns:
tuple of str

The status and its reason (empty where none is given).

Raises:
DataError

If the status is unknown, is user (which only a caller’s own parameters earn), or is provisional or untested without a reason.

Examples

>>> parse_status({"status": "untested", "status_reason": "no data"}, "x",
...              default="validated")
('untested', 'no data')
optmat.identity.sha256_digest(value)[source]#

Return the SHA-256 of a value’s canonical JSON.

Parameters:
valueobject

Anything canonical() accepts.

Returns:
str

64 hexadecimal digits.

Examples

>>> sha256_digest([])[:12]
'4f53cda18c2b'
optmat.identity.source_ids(*texts)[source]#

Return the source records named by dataset keys in some texts.

Parameters:
*textsstr

Texts that may contain dataset keys, <source>/<dataset>.

Returns:
tuple of str

The sources, sorted, each once.

Examples

>>> source_ids("nist_asd_2026/ie_Ar_I + nist_asd_2026/level", "tong_2002/cl_Ar")
('nist_asd_2026', 'tong_2002')