From c33d0510532909a8c2ae82c7303c2d2872590773 Mon Sep 17 00:00:00 2001 From: John Travers Date: Sat, 24 Oct 2026 14:22:43 +0100 Subject: [PATCH] Read one gas's fit where only its fit is needed electronic_static_polarizability (and so ionisation_parameters and the ionisation rates) and the compact models looked a parent fit up in fitted_models(), which builds all fifteen fits with their Kramers-Kronig absorption terms. They now use fitted_model(name). The entry-point test also checks that the full set of fits is never built. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 6 ++++++ src/optmat/gas/ionisation.py | 4 ++-- src/optmat/gas/models/compact.py | 14 +++++++------- tests/test_catalogue.py | 8 ++++++-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 429aa81d..aecc567e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ All notable changes are recorded here, in the style of ## Unreleased +### Changed + +- `gas.ionisation.ionisation_parameters` and the compact models read their gas's own + fitted model, not all fifteen with their absorption terms (no value changed): + `ionisation_parameters("He")` takes half the time it did. + ## 0.9.0 (2026-10-24) Models read only the data they need, so start-up is seconds to tens of seconds faster diff --git a/src/optmat/gas/ionisation.py b/src/optmat/gas/ionisation.py index 0432dd7a..701da2fe 100644 --- a/src/optmat/gas/ionisation.py +++ b/src/optmat/gas/ionisation.py @@ -328,9 +328,9 @@ def electronic_static_polarizability(gas: Gas | str) -> tuple[float, float, str] the model's name. """ # Loaded here: the fitted models bring the whole dispersion chain. - from optmat.gas.models.fitted import FittedModel, fitted_models # noqa: PLC0415 + from optmat.gas.models.fitted import FittedModel, fitted_model # noqa: PLC0415 - model: FittedModel = fitted_models()[f"fit/{as_gas(gas).value}"] + model: FittedModel = fitted_model(f"fit/{as_gas(gas).value}") n_fitted = len(model.strengths) - model.n_fixed strengths = np.asarray(model.strengths[:n_fitted]) energies = np.asarray(model.energies[:n_fitted]) diff --git a/src/optmat/gas/models/compact.py b/src/optmat/gas/models/compact.py index d1c09476..22c1a496 100644 --- a/src/optmat/gas/models/compact.py +++ b/src/optmat/gas/models/compact.py @@ -51,7 +51,7 @@ from optmat.gas.gases import Gas, as_gas from optmat.gas.infrared import gauss_rule from optmat.gas.models._defaults import defaults -from optmat.gas.models.fitted import FittedModel, fitted_models +from optmat.gas.models.fitted import FittedModel, fitted_model from optmat.identity import FrozenMapping __all__ = [ @@ -1179,7 +1179,7 @@ def _gap_note(self, wavelength: Float[np.ndarray, "*shape"]) -> str: """ note = super()._gap_note(wavelength) values = np.ravel(np.asarray(wavelength, dtype=float)) - parent = fitted_models()[self.parent] + parent = fitted_model(self.parent) theirs = ~_validity.outside(values, parent.intervals) if np.any(theirs & _validity.outside(values, self.intervals)): note += f"; {self.parent} is qualified there" @@ -1193,7 +1193,7 @@ def _sources(self) -> tuple[str, ...]: tuple of str Sorted source ids. """ - return fitted_models()[self.parent]._sources() + return fitted_model(self.parent)._sources() @functools.cache @@ -1208,7 +1208,7 @@ def compact_models() -> dict[str, CompactModel]: models = {} for path in sorted(COMPACT_MODEL_DIRECTORY.glob("*.json")): record = json.loads(path.read_text(encoding="utf-8")) - parent = fitted_models()[record["parent"]] + parent = fitted_model(record["parent"]) n_terms = len(parent.strengths) - parent.n_fixed + parent.n_rotational labels = [ "compact (the parent's)" if kept else "compact" for kept in record["kept"] @@ -1291,7 +1291,7 @@ def reproduction(model: CompactModel) -> dict[str, dict[str, float]]: # Imported here: the fitting code loads every dataset. from optmat.gas import fitting # noqa: PLC0415 - parent = fitted_models()[model.parent] + parent = fitted_model(model.parent) config = fitting.load_config(str(parent.record["name"])) start = len(model.strengths) - model.n_fixed + model.n_rotational compact = dataclasses.replace( @@ -1569,7 +1569,7 @@ def _stated_error( largest difference in ``beta_2`` over the largest ``|beta_2|``, on the check grid over every interval. """ - parent = fitted_models()[model.parent] + parent = fitted_model(model.parent) def sellmeier(x: Float[np.ndarray, " n"]) -> Float[np.ndarray, " n"]: """Return the Sellmeier form's ``n - 1``. @@ -1696,7 +1696,7 @@ def coefficients( model=name, parent=model.parent, model_digest=model.identity.digest, - parent_digest=fitted_models()[model.parent].identity.digest, + parent_digest=fitted_model(model.parent).identity.digest, form=form, labels=tuple(model.labels[k] for k in order), kinds=tuple(str(x) for x in kinds), diff --git a/tests/test_catalogue.py b/tests/test_catalogue.py index f224dd64..53a60d09 100644 --- a/tests/test_catalogue.py +++ b/tests/test_catalogue.py @@ -108,12 +108,16 @@ def test_solprops_entry_points_never_load_the_catalogue(): ionisation_parameters("Ar") raman_response("N2", 293.15) transport_model("Ar") -print(optmat.datasets.sources.cache_info().currsize) +from optmat.gas.molecular_ionisation_rates import molecular_rate_model +molecular_rate_model("N2", 800e-9) +from optmat.gas.models.fitted import fitted_models as fits +print(optmat.datasets.sources.cache_info().currsize, fits.cache_info().currsize) """ result = subprocess.run( [sys.executable, "-c", code], capture_output=True, text=True, check=True ) - assert result.stdout.strip() == "0" + # Neither the catalogue nor every gas's fit (each with its absorption term). + assert result.stdout.split() == ["0", "0"] @pytest.mark.parametrize(