test: adapt existing suites to unconditional core, drop dead detector tests
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user