Source code for openquake.hazardlib.correlation_models.registry

# The Hazard Library
# Copyright (C) 2026 GEM Foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Registry for ground-motion correlation models."""

from dataclasses import dataclass

from openquake.baselib.general import import_all
from openquake.hazardlib.correlation_models.base import (
    CorrelationModel, CrossIMTCorrelationModel, SpatialCorrelationModel,
    SpatialCrossIMTCorrelationModel)


[docs]@dataclass(frozen=True) class ModelSpec: """Registration metadata for a correlation model.""" name: str cls: type[CorrelationModel] aliases: tuple[str, ...] model_type: str description: str @property def residual_component(self): return self.cls.DEFINED_FOR_RESIDUAL_COMPONENT @property def supported_imts(self): return self.cls.DEFINED_FOR_INTENSITY_MEASURE_TYPES @property def calibrated_imts(self): return self.cls._calibrated_imts() @property def intensity_measure_type_approximations(self): return dict(self.cls.INTENSITY_MEASURE_TYPE_APPROXIMATIONS) @property def imc(self): return self.cls.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT @property def sa_damping(self): return self.cls.DEFINED_FOR_SA_DAMPING @property def sa_period_range(self): return self.cls.DEFINED_FOR_SA_PERIOD_RANGE @property def region(self): return self.cls.DEFINED_FOR_REGION
registry = {} _specs = {} _models_loaded = False def _load_models(): """Import model modules the first time the registry is queried.""" global _models_loaded if _models_loaded: return root = 'openquake.hazardlib.correlation_models' for model_type in ('spatial', 'cross_imt', 'spatial_cross_imt'): import_all(f'{root}.{model_type}') _models_loaded = True def _model_type(cls): if issubclass(cls, SpatialCorrelationModel): return 'spatial' if issubclass(cls, CrossIMTCorrelationModel): return 'cross_imt' if issubclass(cls, SpatialCrossIMTCorrelationModel): return 'spatial_cross_imt' raise TypeError(f'{cls.__name__} is not a correlation model')
[docs]def register_model(*aliases, description=''): """Register a model class under its canonical name and aliases.""" def decorator(cls): if not issubclass(cls, CorrelationModel): raise TypeError(f'{cls.__name__} is not a correlation model') name = cls.__name__ keys = (name,) + tuple(aliases) duplicates = sorted(key for key in keys if key in registry) if duplicates: raise KeyError( f'Correlation model names already registered: {duplicates}') spec = ModelSpec( name, cls, tuple(aliases), _model_type(cls), description) _specs[name] = spec for key in keys: registry[key] = cls return cls return decorator
[docs]def get_model_class(name, model_type=None): """Return the class registered under ``name``.""" _load_models() try: cls = registry[name] except KeyError as exc: available = ', '.join(sorted(registry)) raise KeyError( f'Unknown correlation model {name!r}; available: {available}' ) from exc if model_type is not None and _model_type(cls) != model_type: raise TypeError( f'{name} is {_model_type(cls)}, not {model_type}') return cls
[docs]def get_model(name, model_type=None, **parameters): """Instantiate and validate the model registered under ``name``.""" model = get_model_class(name, model_type)(**parameters) model.validate() return model
[docs]def get_model_specs(model_type=None): """Return canonical model specifications, optionally by model type.""" _load_models() if model_type is None: return dict(_specs) return {name: spec for name, spec in _specs.items() if spec.model_type == model_type}