Add massive neutrino support and improve CSV/CLI output

- Add neutrino mass parameter to SpectrumConfig and CLI interface
- Update PhaseSpace component to handle neutrino mass effects properly
- Update CSV headers to show basic endpoint and all transition types
- Add --csv-verbosity option to CLI with 'full' and 'concise' options
- Fix comparison plots to properly show linear scale variations
- Add comprehensive tests for neutrino mass functionality
This commit is contained in:
2026-07-02 10:33:28 +03:00
parent 406fd57bcd
commit 876e1e3ab8
48 changed files with 5213 additions and 97 deletions
+22 -1
View File
@@ -50,10 +50,26 @@ class PhaseSpace(SpectrumComponent):
w_e = W
p_e = momentum(W, self.m_e)
w_nu = self.W0 - W
p_nu = momentum(w_nu, self.m_nu)
# Calculate p_nu, handling the case where w_nu < self.m_nu
# In this case, the neutrino energy is less than its mass, which is unphysical
# The phase space should be 0 in this region
if self.m_nu > 0:
# Check where w_nu < self.m_nu
below_threshold = w_nu < self.m_nu
# Calculate p_nu only where it's physically valid
p_nu = np.zeros_like(w_nu)
valid_mask = ~below_threshold
if np.any(valid_mask):
p_nu[valid_mask] = momentum(w_nu[valid_mask], self.m_nu)
else:
below_threshold = np.zeros_like(w_nu, dtype=bool)
p_nu = momentum(w_nu, self.m_nu)
# Calculate phase space factor
phase_space = p_e * w_e * p_nu * w_nu
# Calculate forbid factor
if self.tr_type in ["A", "F1"]:
forbid_factor: float | np.ndarray = 1
elif self.tr_type in ["F1U", "F2"]:
@@ -66,6 +82,11 @@ class PhaseSpace(SpectrumComponent):
)
result = np.asarray(phase_space * forbid_factor, dtype=np.float64)
# For regions below the neutrino mass threshold, the phase space should be 0
if self.m_nu > 0:
result[below_threshold] = 0.0
if self._logger:
self._logger.debug(
"PhaseSpace: output range=[%.6e, %.6e]",