hmf.core.model¶
The Model base class and the per-kind model registry (issue #388).
A model is one interchangeable implementation of a piece of physics: a fitting
function, a transfer function, a filter, a mass definition, … Models are frozen,
keyword-only attrs classes whose fields are the model’s parameters. They have no
cosmology of their own: their methods take every physical input as an explicit
argument (issue #389).
Kinds and registration¶
A kind is an abstract base class declared with kind=True. It owns a registry of
its models:
@attrs.frozen(kw_only=True)
class FittingFunction(Model, kind=True):
@abc.abstractmethod
def fsigma(self, sigma): ...
@attrs.frozen(kw_only=True)
class Tinker08(FittingFunction, alias="Tinker08"):
A: float = field(default=0.186, doc="Amplitude.")
def fsigma(self, sigma): ...
Every concrete subclass of a kind is registered in that kind (and in any enclosing
kind) under its qualified name, package.module:Class, and, if it gives one,
under a short alias. An alias is unique within a kind: registering a second class
under the same alias is an error, unless the new class passes override=True. A
class defined in user code therefore never silently replaces a built-in model.
Intermediate base classes that should not be registered pass abstract=True.
Re-defining a class with the same qualified name (re-running a notebook cell, or
importlib.reload()) replaces the old registration.
Lookup¶
Lookup is per kind only; there is no global lookup by name.
FittingFunction.get(name) accepts an alias, a qualified name, an import path
("pkg.mod:Cls" or "pkg.mod.Cls") of a class not yet imported, or a class. If
that fails, it loads the plugins advertised in the hmf.models entry-point group
(once each) and tries again, and finally raises ModelNotFoundError with
suggestions. A plugin package advertises its models in its pyproject.toml:
[project.entry-points."hmf.models"]
my_models = "my_package.models"
The entry point may name a module (whose import registers its models) or a class.
Subclasses must be decorated with @attrs.frozen(kw_only=True)¶
Slotted attrs classes are built twice: once by the class statement, and again
by the decorator, which calls __init_subclass__ a second time without the class
keywords. Model handles this (it stores its own class keywords on the class,
and re-registers the final class), and generates the “Parameters” section of the
class docstring from the fields at that point. Mixins with their own
__init_subclass__ should likewise tolerate being called a second time without
their keywords.
Classes
|
Base class of every v4 model. |
Functions
|
Return the qualified name of a class: |
Exceptions
|
A model was registered under an alias already taken within its kind. |
|
No model of the requested kind is registered or importable under a name. |