fix(spectrum): lone branch defines endpoint in single-branch mode

When config.branches carries exactly one branch (e.g. after
--intensity-cutoff filtering), the branch endpoint/transition define
the spectrum, energy grid, analyzer unified branch view and CSV
header. The stale top-level endpoint inherited from the parent decay
no longer leaks into physics (proven wrong on Cs137: spectrum
extended to 1176 keV while the lone survivor ends at 514 keV).
This commit is contained in:
2026-10-01 22:04:17 +03:00
parent 6bb7b950c7
commit ee7aedc80a
6 changed files with 179 additions and 10 deletions
+13 -1
View File
@@ -81,6 +81,18 @@ class CSVEmitter:
if config.use_exchange:
enabled.append("exchange")
# The header endpoint must describe the spectrum that is actually
# computed. Single mode with exactly one configured branch follows
# the branch (the top-level endpoint may be stale from the parent
# decay, e.g. after intensity-cutoff filtering).
basic_endpoint_MeV = config.endpoint_MeV
if (
not analyzer._is_multi
and config.branches is not None
and len(config.branches) == 1
):
basic_endpoint_MeV = analyzer._unified_branches[0].endpoint_MeV
parent_symbol = analyzer._element_symbol(config.Z_parent)
daughter_symbol = analyzer._element_symbol(config.Z_daughter)
@@ -99,7 +111,7 @@ class CSVEmitter:
f"# nuclide: {parent_symbol}{config.A_number} "
f"-> {daughter_symbol}{config.A_number} "
f"(Z={config.Z_parent}->{config.Z_daughter})",
f"# basic_endpoint: {config.endpoint_MeV * 1000:.1f} keV",
f"# basic_endpoint: {basic_endpoint_MeV * 1000:.1f} keV",
]
if config.neutrino_mass_MeV > 0: