feat: make phase space and Fermi function unconditional core components
This commit is contained in:
+56
-48
@@ -73,9 +73,9 @@ class SpectrumConfig:
|
|||||||
e_step_MeV: float = 0.001
|
e_step_MeV: float = 0.001
|
||||||
neutrino_mass_MeV: float = 0.0
|
neutrino_mass_MeV: float = 0.0
|
||||||
|
|
||||||
# Toggle components and corrections
|
# Higher-order corrections. The core spectrum components (phase space
|
||||||
use_phase_space: bool = True
|
# and the Fermi function, both 0-order) are unconditional: there are
|
||||||
use_fermi: bool = True
|
# deliberately no toggles for them.
|
||||||
use_screening: bool = True
|
use_screening: bool = True
|
||||||
use_finite_size: bool = True
|
use_finite_size: bool = True
|
||||||
use_charge_dist: bool = True
|
use_charge_dist: bool = True
|
||||||
@@ -252,26 +252,29 @@ class BetaSpectrum:
|
|||||||
def _from_config_single(
|
def _from_config_single(
|
||||||
cls, config: SpectrumConfig, logger: Optional[logging.Logger] = None
|
cls, config: SpectrumConfig, logger: Optional[logging.Logger] = None
|
||||||
) -> BetaSpectrum:
|
) -> BetaSpectrum:
|
||||||
"""Create single-branch spectrum calculator."""
|
"""Create single-branch spectrum calculator.
|
||||||
|
|
||||||
|
The core spectrum components (phase space x Fermi function, both
|
||||||
|
0-order) are always built; only higher-order corrections are
|
||||||
|
conditional.
|
||||||
|
"""
|
||||||
components: List[SpectrumComponent] = []
|
components: List[SpectrumComponent] = []
|
||||||
W0 = float(T_to_W(config.endpoint_MeV))
|
W0 = float(T_to_W(config.endpoint_MeV))
|
||||||
|
|
||||||
if config.use_phase_space:
|
# Core spectrum components (0-order): always included.
|
||||||
# Convert neutrino mass from MeV to natural units
|
# Convert neutrino mass from MeV to natural units
|
||||||
m_nu_natural = config.neutrino_mass_MeV / ME_MEV
|
m_nu_natural = config.neutrino_mass_MeV / ME_MEV
|
||||||
components.append(
|
components.append(
|
||||||
PhaseSpace(
|
PhaseSpace(
|
||||||
W0=W0,
|
W0=W0,
|
||||||
transition_type=config.transition_type,
|
transition_type=config.transition_type,
|
||||||
m_nu=m_nu_natural,
|
m_nu=m_nu_natural,
|
||||||
logger=logger,
|
logger=logger,
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if config.use_fermi:
|
|
||||||
components.append(
|
|
||||||
FermiFunction(Z=config.Z_daughter, A=config.A_number, logger=logger)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
components.append(
|
||||||
|
FermiFunction(Z=config.Z_daughter, A=config.A_number, logger=logger)
|
||||||
|
)
|
||||||
|
|
||||||
if config.use_finite_size:
|
if config.use_finite_size:
|
||||||
components.append(
|
components.append(
|
||||||
@@ -322,13 +325,13 @@ class BetaSpectrum:
|
|||||||
Note: Radiative correction is branch-dependent (depends on W0), so it goes
|
Note: Radiative correction is branch-dependent (depends on W0), so it goes
|
||||||
into each branch's calculator, not the universal components.
|
into each branch's calculator, not the universal components.
|
||||||
"""
|
"""
|
||||||
|
if config.branches is None:
|
||||||
|
raise ValueError("branches must be provided for multi-branch mode")
|
||||||
if logger:
|
if logger:
|
||||||
logger.info("Multi-branch mode: %d branches", len(config.branches))
|
logger.info("Multi-branch mode: %d branches", len(config.branches))
|
||||||
|
|
||||||
# Create per-branch calculators
|
# Create per-branch calculators
|
||||||
branch_spectra: List[BetaSpectrum] = []
|
branch_spectra: List[BetaSpectrum] = []
|
||||||
if config.branches is None:
|
|
||||||
raise ValueError("branches must be provided for multi-branch mode")
|
|
||||||
for i, branch in enumerate(config.branches):
|
for i, branch in enumerate(config.branches):
|
||||||
if logger:
|
if logger:
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -339,37 +342,42 @@ class BetaSpectrum:
|
|||||||
branch.intensity,
|
branch.intensity,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a per-branch config with the branch's endpoint and transition type
|
# Per-branch calculator: the per-branch core phase space
|
||||||
branch_config = SpectrumConfig(
|
# (unconditional) plus optional per-branch radiative
|
||||||
Z_parent=config.Z_parent,
|
# corrections. The universal Fermi function and universal
|
||||||
Z_daughter=config.Z_daughter,
|
# higher-order corrections are applied outside, so they must
|
||||||
A_number=config.A_number,
|
# NOT be built here (a Fermi function per branch would
|
||||||
endpoint_MeV=branch.endpoint_MeV,
|
# double-apply it).
|
||||||
transition_type=branch.transition_type,
|
W0_branch = float(T_to_W(branch.endpoint_MeV))
|
||||||
e_step_MeV=config.e_step_MeV,
|
m_nu_natural = config.neutrino_mass_MeV / ME_MEV
|
||||||
neutrino_mass_MeV=config.neutrino_mass_MeV,
|
branch_components: List[SpectrumComponent] = [
|
||||||
# Branch-dependent components
|
PhaseSpace(
|
||||||
use_phase_space=config.use_phase_space,
|
W0=W0_branch,
|
||||||
use_radiative=config.use_radiative,
|
transition_type=branch.transition_type,
|
||||||
# Universal components disabled (handled separately)
|
m_nu=m_nu_natural,
|
||||||
use_fermi=False,
|
logger=logger,
|
||||||
use_screening=False,
|
)
|
||||||
use_finite_size=False,
|
]
|
||||||
use_charge_dist=False,
|
if config.use_radiative:
|
||||||
use_exchange=False,
|
branch_components.append(
|
||||||
)
|
RadiativeCorrection(
|
||||||
|
W0=W0_branch,
|
||||||
|
Z=config.Z_daughter,
|
||||||
|
A=config.A_number,
|
||||||
|
use_endpoint_resummation=True,
|
||||||
|
logger=logger,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
branch_spectrum = cls._from_config_single(branch_config, logger)
|
branch_spectra.append(cls(branch_components, logger=logger))
|
||||||
branch_spectra.append(branch_spectrum)
|
|
||||||
|
|
||||||
# Create universal components (shared across all branches)
|
# Create universal components (shared across all branches)
|
||||||
# Note: Radiative is NOT included here because it depends on W0
|
# Note: Radiative is NOT included here because it depends on W0
|
||||||
universal_components: List[SpectrumComponent] = []
|
# The Fermi function is a core spectrum component (0-order Coulomb
|
||||||
|
# correction): always included, not a higher-order correction.
|
||||||
if config.use_fermi:
|
universal_components: List[SpectrumComponent] = [
|
||||||
universal_components.append(
|
FermiFunction(Z=config.Z_daughter, A=config.A_number, logger=logger)
|
||||||
FermiFunction(Z=config.Z_daughter, A=config.A_number, logger=logger)
|
]
|
||||||
)
|
|
||||||
|
|
||||||
if config.use_finite_size:
|
if config.use_finite_size:
|
||||||
universal_components.append(
|
universal_components.append(
|
||||||
|
|||||||
Reference in New Issue
Block a user