nook.compare

Cross-source comparison: levels and masses where the backends overlap.

Two questions this module answers:

  • levels() – RIPL’s discrete levels derive from ENSDF, so matching a RIPL scheme against an ENSDF one (or Livechart’s adopted levels) checks a parsing chain end to end, and the disagreements that remain are real: levels RIPL dropped, spins RIPL invented, and the two completeness cutoffs – RIPL’s evaluated Nmax against the heuristic complete_up_to().

  • masses() – the same nuclide’s mass excess across evaluations: AME via Livechart, Audi-as-shipped via RIPL, and the FRDM95/HFB-14 theory values. sigma_between says whether two experimental values actually disagree; theory-minus-experiment is a model residual, not a discrepancy.

Level matching is energy-sorted greedy nearest-neighbour, one-to-one, within max(tolerance_kev, 3 * combined sigma). Ground states always match each other.

class nook.compare.LevelMatch(a, b, delta_kev, combined_sigma_kev, jpi_agree)[source]

Bases: object

One matched pair of levels.

a: Level
b: Level
delta_kev: float
combined_sigma_kev: float | None
jpi_agree: bool | None

True/False when both sides have candidates; None when either is unknown.

property significant: bool

The energies disagree beyond 3 combined sigma.

class nook.compare.LevelComparison(nuclide: 'Nuclide', source_a: 'str', source_b: 'str', matched: 'tuple[LevelMatch, ...]', only_a: 'tuple[Level, ...]', only_b: 'tuple[Level, ...]', cutoff_a: 'int | None' = None, cutoff_b: 'int | None' = None)[source]

Bases: object

nuclide: Nuclide
source_a: str
source_b: str
matched: tuple[LevelMatch, ...]
only_a: tuple[Level, ...]
only_b: tuple[Level, ...]
cutoff_a: int | None = None

Levels in the heuristically complete part of scheme a.

cutoff_b: int | None = None

RIPL’s own Nmax for scheme b, when b is RIPL.

property n_matched: int
property rms_delta_kev: float | None
property max_delta_kev: float | None
property jpi_agreement_fraction: float | None
to_records()[source]
nook.compare.levels(nuclide, sources=('file', 'ripl3'), below=None, tolerance_kev=2.0, path=None, ripl_path=None, cache=None)[source]

Match one nuclide’s level scheme across two sources.

sources names any two of "file", "ripl3", "livechart". below truncates both schemes first; floating (offset) levels are dropped because their absolute position is undefined.

class nook.compare.MassComparison(nuclide, entries=<factory>)[source]

Bases: object

One nuclide’s mass excess across evaluations, keV.

entries keys: "ame-livechart", "ripl-exp" (experimental) and "frdm95", "hfb14" (theory).

nuclide: Nuclide
entries: dict[str, Uncertain]
property experimental: dict[str, Uncertain]
property spread_kev: float | None

Max minus min over every evaluation that has a value.

sigma_between(key_a, key_b)[source]

Absolute difference over combined sigma between two entries.

residual_kev(theory='frdm95')[source]

Theory minus experiment (RIPL experimental value).

nook.compare.masses(nuclide, cache=None, ripl_path=None, with_livechart=True)[source]

One nuclide’s mass excess across every evaluation we can reach.

with_livechart=False skips the network/API entry and compares the local RIPL tables only.

nook.compare.mass_table(nuclides, cache=None, ripl_path=None, with_livechart=False)[source]

masses over many nuclides, keyed (z, a) like a survey table.