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:
@@ -95,6 +95,21 @@ class SpectrumConfig:
|
||||
)
|
||||
|
||||
|
||||
def _effective_single_fields(config: SpectrumConfig) -> Tuple[float, str]:
|
||||
"""Resolve (endpoint_MeV, transition_type) for single-branch mode.
|
||||
|
||||
When config.branches carries exactly one branch (e.g. after intensity
|
||||
cutoff filtering removed all but one), that branch defines the spectrum:
|
||||
its endpoint and transition type win over the (possibly stale) top-level
|
||||
fields inherited from the parent decay. With branches=None the top-level
|
||||
fields are used as before.
|
||||
"""
|
||||
if config.branches is not None and len(config.branches) == 1:
|
||||
lone = config.branches[0]
|
||||
return float(lone.endpoint_MeV), str(lone.transition_type)
|
||||
return float(config.endpoint_MeV), str(config.transition_type)
|
||||
|
||||
|
||||
class BetaSpectrum:
|
||||
"""
|
||||
Precise beta spectrum calculator.
|
||||
@@ -259,7 +274,8 @@ class BetaSpectrum:
|
||||
conditional.
|
||||
"""
|
||||
components: List[SpectrumComponent] = []
|
||||
W0 = float(T_to_W(config.endpoint_MeV))
|
||||
eff_endpoint, eff_transition = _effective_single_fields(config)
|
||||
W0 = float(T_to_W(eff_endpoint))
|
||||
|
||||
# Core spectrum components (0-order): always included.
|
||||
# Convert neutrino mass from MeV to natural units
|
||||
@@ -267,7 +283,7 @@ class BetaSpectrum:
|
||||
components.append(
|
||||
PhaseSpace(
|
||||
W0=W0,
|
||||
transition_type=config.transition_type,
|
||||
transition_type=eff_transition,
|
||||
m_nu=m_nu_natural,
|
||||
logger=logger,
|
||||
)
|
||||
@@ -419,6 +435,11 @@ class BetaSpectrum:
|
||||
"""
|
||||
if self._is_multi and self.branches:
|
||||
max_endpoint = max(b.endpoint_MeV for b in self.branches)
|
||||
elif config.branches is not None and len(config.branches) == 1:
|
||||
# Single-mode with exactly one configured branch: the branch
|
||||
# endpoint defines the grid, not the (possibly stale) top-level
|
||||
# endpoint from the parent decay.
|
||||
max_endpoint = float(config.branches[0].endpoint_MeV)
|
||||
else:
|
||||
max_endpoint = config.endpoint_MeV
|
||||
|
||||
|
||||
Reference in New Issue
Block a user