Source code for nook

"""nook: nuclear level schemes from ENSDF.

Two backends behind one data model -- the IAEA Livechart API for adopted
levels, the NNDC flat files for every evaluated dataset. See ``docs/usage.md``.
"""

from . import compare
from .cache import Cache, default_cache_dir
from .decay import DecayScheme, Feeding, Normalization, Parent
from .groundstate import EVALUATIONS, UNITS, GroundState
from .model import Gamma, Level, LevelScheme
from .nuclide import Nuclide
from .quantities import (
    HalfLife,
    JPi,
    SpinParity,
    Uncertain,
    parse_half_life,
    parse_spin_parity,
    parse_value_with_uncertainty,
)
from .repair import Repair, repair
from .sources import (
    ENSDFFileSource,
    LivechartError,
    LivechartSource,
    Ripl3Source,
    default_ripl_path,
    parse_references,
    place_gammas,
)
from .sources.ensdf_file import default_ensdf_path
from .survey import NuclideSummary, survey

__version__ = "0.1.0"

#: Accepted spelling -> canonical source name.  Every dispatcher that takes a
#: ``source`` string (here, ``compare``) resolves through this one map.
SOURCE_ALIASES = {
    "iaea": "livechart",
    "api": "livechart",
    "ensdf": "file",
    "flat": "file",
    "ripl": "ripl3",
}

__all__ = [
    "EVALUATIONS",
    "UNITS",
    "Cache",
    "DecayScheme",
    "ENSDFFileSource",
    "Feeding",
    "Gamma",
    "HalfLife",
    "JPi",
    "Level",
    "LevelScheme",
    "LivechartError",
    "LivechartSource",
    "Normalization",
    "Nuclide",
    "NuclideSummary",
    "Parent",
    "Repair",
    "SpinParity",
    "Uncertain",
    "__version__",
    "decay_schemes",
    "default_cache_dir",
    "ground_state",
    "level_scheme",
    "parse_half_life",
    "parse_references",
    "repair",
    "survey",
    "compare",
    "default_ensdf_path",
    "default_ripl_path",
    "Ripl3Source",
    "GroundState",
    "parse_spin_parity",
    "parse_value_with_uncertainty",
    "place_gammas",
]


[docs] def level_scheme( nuclide, source: str = "livechart", dataset: str | None = None, with_gammas: bool = True, cache=None, path=None, ) -> LevelScheme: """Fetch a level scheme for ``nuclide`` (``"24Mg"``, ``"Mg-24"``, ``(12, 24)``). ``source`` is ``"livechart"`` for the IAEA API, which serves adopted levels only; ``"file"`` for local flat files, where ``dataset`` picks one evaluation by DSID substring; or ``"ripl3"`` for the committed RIPL-3 mirror (levels cut 2021, derived from ENSDF). """ nuc = Nuclide.parse(nuclide) source = SOURCE_ALIASES.get(source, source) if source == "livechart": if dataset is not None: raise ValueError( "the Livechart API only serves adopted levels; " "use source='file' to select a specific dataset" ) return LivechartSource(cache=cache).fetch(nuc, with_gammas=with_gammas) if source == "file": return ENSDFFileSource(path=path).fetch(nuc, dataset=dataset) if source == "ripl3": if dataset is not None: raise ValueError( "RIPL-3 carries one levels dataset per nuclide; " "use source='file' to select a specific ENSDF evaluation" ) return Ripl3Source(path=path).fetch(nuc) raise ValueError(f"unknown source {source!r}")
[docs] def decay_schemes(nuclide, path=None) -> "list[DecayScheme]": """Every decay dataset populating ``nuclide``, from local ENSDF files. Decay data is only available from the flat files; the Livechart API serves adopted levels alone. """ return ENSDFFileSource(path=path).decay_schemes(Nuclide.parse(nuclide))
[docs] def ground_state( nuclide, source: str = "livechart", cache=None, path=None ) -> "GroundState": """Mass, abundance, charge radius and moments for ``nuclide``. ``source="livechart"`` aggregates AME, NUBASE, charge radii and moment compilations (see :data:`nook.EVALUATIONS` for attribution and :data:`nook.UNITS` for units -- ``atomic_mass`` is in micro-u, not u). ``source="ripl3"`` serves the sparser RIPL-3 mass tables: mass excess and abundance, with FRDM95/HFB-14 theory values in ``metadata``. The ENSDF flat files carry none of this. """ source = SOURCE_ALIASES.get(source, source) if source == "livechart": return LivechartSource(cache=cache).ground_state(Nuclide.parse(nuclide)) if source == "ripl3": return Ripl3Source(path=path).ground_state(Nuclide.parse(nuclide)) raise ValueError(f"unknown ground-state source {source!r}")