test: adapt existing suites to unconditional core, drop dead detector tests

This commit is contained in:
2026-09-30 03:08:13 +03:00
parent 7dc2ec79d1
commit 8172ba2541
6 changed files with 103 additions and 320 deletions
+31 -51
View File
@@ -21,8 +21,7 @@ We test:
6. **Component extraction**: universal + per-branch components correctly separated.
7. **CSV export**: multi-branch CSV has correct column structure.
8. **Energy grid**: uses max endpoint across all branches.
9. **Detector response**: multi-branch spectra are convolvable.
10. **BranchConfig dataclass**: basic construction and validation.
9. **BranchConfig dataclass**: basic construction and validation.
"""
import numpy as np
@@ -249,8 +248,8 @@ class TestMultiBranchSpectrum:
Z_daughter=44,
A_number=99,
endpoint_MeV=0.350,
# Disable universal components to simplify
use_fermi=False,
# Disable higher-order universal corrections to simplify:
# the universal factor reduces to the core Fermi function.
use_screening=False,
use_finite_size=False,
use_charge_dist=False,
@@ -266,8 +265,11 @@ class TestMultiBranchSpectrum:
weighted = spectrum.get_branch_normalized_spectra(W)
assert len(weighted) == 2
# With no universal components, total = sum of weighted branch spectra
total_from_branches = weighted[0] + weighted[1]
# Universal factor is the core Fermi function only (corrections off):
# total = fermi × sum(weighted branch spectra)
components = spectrum.calculate_components(W)
fermi = components["Fermi"]
total_from_branches = fermi * (weighted[0] + weighted[1])
total = spectrum(W)
assert np.allclose(total, total_from_branches, rtol=1e-10)
@@ -278,8 +280,6 @@ class TestMultiBranchSpectrum:
Z_daughter=44,
A_number=99,
endpoint_MeV=0.350,
use_phase_space=True,
use_fermi=False,
use_screening=False,
use_finite_size=False,
use_charge_dist=False,
@@ -293,13 +293,16 @@ class TestMultiBranchSpectrum:
spectrum = BetaSpectrum.from_config(config)
W, _ = spectrum.get_energy_grid(config)
# Both branches have same endpoint and transition type,
# so phase space should be identical. Total = 0.8*PS + 0.2*PS = PS
# Both branches have same endpoint and transition type, so their
# per-branch cores are identical: sum = 0.8*core + 0.2*core = core.
# Total = universal (Fermi) × sum.
total = spectrum(W)
branch0 = spectrum.branch_spectra[0](W)
branch1 = spectrum.branch_spectra[1](W)
components = spectrum.calculate_components(W)
fermi = components["Fermi"]
expected = 0.8 * branch0 + 0.2 * branch1
expected = fermi * (0.8 * branch0 + 0.2 * branch1)
assert np.allclose(total, expected, rtol=1e-10)
@@ -371,8 +374,8 @@ class TestMultiBranchComponents:
assert "Fermi" in components
assert "branch_0.PhaseSpace" in components
def test_analyzer_branch_spectra_property(self):
"""Analyzer should expose branch spectra property."""
def test_analyzer_physical_branch_spectra(self):
"""Analyzer physical branch spectra are core × corrections arrays."""
config = SpectrumConfig(
Z_parent=43,
Z_daughter=44,
@@ -386,8 +389,11 @@ class TestMultiBranchComponents:
spectrum = BetaSpectrum.from_config(config)
analyzer = BetaSpectrumAnalyzer(spectrum, config)
branch_spectra = analyzer.branch_spectra
assert len(branch_spectra) == 2
physical = [
analyzer.physical_branch_spectrum(i) for i in range(analyzer._n_branches)
]
assert len(physical) == 2
assert physical[0].shape == analyzer.W.shape
def test_total_equals_universal_times_branch_sum(self):
"""Total = universal_components * sum(intensity * branch_spectra)."""
@@ -481,6 +487,13 @@ class TestMultiBranchCSVExport:
# Should have universal columns
assert "Fermi" in df.columns
# Branch columns are physical spectra: their sum equals total_spectrum
total = df["total_spectrum"].to_numpy()
branch_sum = (
df["branch_1_spectrum"].to_numpy() + df["branch_2_spectrum"].to_numpy()
)
assert np.allclose(branch_sum, total, rtol=1e-3)
def test_single_branch_csv_columns(self, tmp_path):
"""Single-branch CSV should have standard columns."""
config = SpectrumConfig(
@@ -582,42 +595,6 @@ class TestMultiBranchTransitionTypes:
assert np.all(values >= 0)
# ---------------------------------------------------------------------------
# Multi-branch with detector response
# ---------------------------------------------------------------------------
class TestMultiBranchDetectorResponse:
"""Test multi-branch with detector response convolution."""
def test_multi_branch_with_detector(self):
"""Multi-branch spectrum should be convolvable with detector response."""
config = SpectrumConfig(
Z_parent=43,
Z_daughter=44,
A_number=99,
endpoint_MeV=0.350,
use_detector_response=True,
detector_model="gaussian",
detector_sigma_a_keV=1.0,
detector_n_channels=256,
detector_fano_factor=0.0,
branches=[
BranchConfig(endpoint_MeV=0.294, transition_type="F2", intensity=0.7),
BranchConfig(endpoint_MeV=0.150, transition_type="A", intensity=0.3),
],
)
spectrum = BetaSpectrum.from_config(config)
W, _ = spectrum.get_energy_grid(config)
detector = BetaSpectrum.create_detector_from_config(config)
convolved = spectrum.convolve_with_detector(detector, W=W, config=config)
assert convolved.shape == (256,)
assert np.all(convolved >= 0), "Convolved spectrum should be non-negative"
assert np.sum(convolved) > 0, "Convolved spectrum should have non-zero area"
# ---------------------------------------------------------------------------
# Edge cases
# ---------------------------------------------------------------------------
@@ -705,6 +682,7 @@ class TestMultiBranchEdgeCases:
),
],
)
assert config.branches is not None
spectrum = BetaSpectrum.from_config(config)
W, energies = spectrum.get_energy_grid(config)
@@ -748,6 +726,7 @@ class TestMultiBranchEdgeCases:
BranchConfig(endpoint_MeV=0.3, transition_type="F1", intensity=0.2),
],
)
assert config.branches is not None
spectrum = BetaSpectrum.from_config(config)
W, energies = spectrum.get_energy_grid(config)
@@ -775,6 +754,7 @@ class TestMultiBranchEdgeCases:
# Each branch integral should be proportional to its intensity
# (within numerical tolerance, since different endpoints give different
# phase space integrals)
assert config.branches is not None
for i, (integral, intensity) in enumerate(zip(integrals, config.branches)):
assert integral > 0, f"Branch {i} has zero integral"