docs: update documentation files and fix linting issues

This commit is contained in:
2026-07-07 13:32:48 +03:00
parent 9bf1e1333e
commit be3e288e0d
27 changed files with 423 additions and 250 deletions
+3 -1
View File
@@ -13,7 +13,9 @@ except ImportError:
DetectorResponse = None # type: ignore[misc, assignment]
@pytest.mark.skipif(DetectorResponse is None, reason="DetectorResponse not yet implemented")
@pytest.mark.skipif(
DetectorResponse is None, reason="DetectorResponse not yet implemented"
)
class TestAnalyticalGaussianResponse:
"""Test pure Gaussian detector response."""
+9 -3
View File
@@ -22,7 +22,9 @@ class TestExchangePhysics:
ex = ExchangeCorrection(Z=80)
low_W = np.array([1.1])
result = ex(low_W)
assert result[0] > 1.0, f"Exchange must enhance spectrum at low energy for heavy Z: {result[0]}"
assert (
result[0] > 1.0
), f"Exchange must enhance spectrum at low energy for heavy Z: {result[0]}"
@pytest.mark.physics
def test_grows_as_energy_decreases(self):
@@ -35,7 +37,9 @@ class TestExchangePhysics:
s_low = ex(low_W)[0]
s_lower = ex(lower_W)[0]
assert s_lower > s_low, f"Exchange must increase at lower energy: {s_low} → {s_lower}"
assert (
s_lower > s_low
), f"Exchange must increase at lower energy: {s_low} → {s_lower}"
@pytest.mark.physics
def test_vanishes_at_high_energy(self):
@@ -43,7 +47,9 @@ class TestExchangePhysics:
ex = ExchangeCorrection(Z=40)
high_W = np.array([3.0, 5.0])
result = ex(high_W)
assert abs(result[0] - 1.0) < 0.5, f"Exchange must approach unity at high energy: {result}"
assert (
abs(result[0] - 1.0) < 0.5
), f"Exchange must approach unity at high energy: {result}"
class TestExchangeErrorHandling:
+2 -2
View File
@@ -75,8 +75,8 @@ class TestFermiPhysicalBehavior:
"""
ff = FermiFunction(Z=92, A=238)
W_low = np.array([1.01]) # Near threshold
W_mid = np.array([3.0]) # Mid-range
W_low = np.array([1.01]) # Near threshold
W_mid = np.array([3.0]) # Mid-range
f_low = ff(W_low)[0]
f_mid = ff(W_mid)[0]
+9 -9
View File
@@ -660,9 +660,9 @@ class TestMultiBranchEdgeCases:
W, _ = spectrum.get_energy_grid(config)
values = spectrum(W)
assert np.all(np.isfinite(values)), (
"High-Z multi-branch must not produce NaN/inf"
)
assert np.all(
np.isfinite(values)
), "High-Z multi-branch must not produce NaN/inf"
def test_no_branches_defaults_to_single(self):
"""No branches list should default to single-branch mode."""
@@ -727,9 +727,9 @@ class TestMultiBranchEdgeCases:
contrib = universal_product * branch.intensity * bs[i]
# Branch contribution should not exceed total
assert np.all(contrib <= total + 1e-10), (
f"Branch {i} contribution exceeds total at some points"
)
assert np.all(
contrib <= total + 1e-10
), f"Branch {i} contribution exceeds total at some points"
# Branch contribution should be non-negative
assert np.all(contrib >= 0), f"Branch {i} contribution has negative values"
@@ -779,6 +779,6 @@ class TestMultiBranchEdgeCases:
assert integral > 0, f"Branch {i} has zero integral"
# Sum of branch integrals should equal total
assert np.isclose(sum(integrals), total_integral, rtol=1e-6), (
"Sum of branch integrals should equal total integral"
)
assert np.isclose(
sum(integrals), total_integral, rtol=1e-6
), "Sum of branch integrals should equal total integral"
+27 -27
View File
@@ -20,12 +20,12 @@ class TestNeutrinoMassPhaseSpaceEffects:
result = ps(W_test)
# Should not produce NaN values
assert not np.any(np.isnan(result)), (
"Phase space with m_nu=0 should not produce NaN values"
)
assert np.all(result > 0), (
"Phase space with m_nu=0 should be positive in physical range"
)
assert not np.any(
np.isnan(result)
), "Phase space with m_nu=0 should not produce NaN values"
assert np.all(
result > 0
), "Phase space with m_nu=0 should be positive in physical range"
def test_phase_space_with_nonzero_neutrino_mass(self):
"""Test that phase space calculation works with non-zero neutrino mass."""
@@ -34,12 +34,12 @@ class TestNeutrinoMassPhaseSpaceEffects:
result = ps(W_test)
# Should not produce NaN values for energies above threshold
assert not np.any(np.isnan(result)), (
"Phase space with m_nu>0 should not produce NaN values above threshold"
)
assert np.all(result > 0), (
"Phase space with m_nu>0 should be positive above threshold"
)
assert not np.any(
np.isnan(result)
), "Phase space with m_nu>0 should not produce NaN values above threshold"
assert np.all(
result > 0
), "Phase space with m_nu>0 should be positive above threshold"
def test_phase_space_with_neutrino_mass_near_endpoint(self):
"""Test that phase space calculation handles energies near endpoint with neutrino mass."""
@@ -48,18 +48,18 @@ class TestNeutrinoMassPhaseSpaceEffects:
# Test energies where W0-W > m_nu (should be finite)
W_above_threshold = np.array([4.8]) # W0-W = 0.2 > m_nu=0.1
result_above = ps(W_above_threshold)
assert not np.any(np.isnan(result_above)), (
"Should produce finite value above threshold"
)
assert not np.any(
np.isnan(result_above)
), "Should produce finite value above threshold"
# Test energies where W0-W < m_nu (should be handled properly)
# With our fix, this should return 0 instead of NaN
W_below_threshold = np.array([4.95]) # W0-W = 0.05 < m_nu=0.1
result_below = ps(W_below_threshold)
# After our fix, NaN values should be replaced with 0
assert np.all(result_below == 0.0) or np.all(np.isnan(result_below)), (
"Should handle below-threshold energies properly (either 0 or NaN)"
)
assert np.all(result_below == 0.0) or np.all(
np.isnan(result_below)
), "Should handle below-threshold energies properly (either 0 or NaN)"
def test_spectrum_config_with_neutrino_mass(self):
"""Test that SpectrumConfig accepts and stores neutrino mass parameter."""
@@ -72,9 +72,9 @@ class TestNeutrinoMassPhaseSpaceEffects:
e_step_MeV=0.001,
neutrino_mass_MeV=0.01,
)
assert config.neutrino_mass_MeV == 0.01, (
"SpectrumConfig should store neutrino mass parameter"
)
assert (
config.neutrino_mass_MeV == 0.01
), "SpectrumConfig should store neutrino mass parameter"
def test_beta_spectrum_with_neutrino_mass(self):
"""Test that BetaSpectrum works with neutrino mass in configuration."""
@@ -96,12 +96,12 @@ class TestNeutrinoMassPhaseSpaceEffects:
result = spectrum(W)
# Should not produce NaN values
assert not np.any(np.isnan(result)), (
"BetaSpectrum with neutrino mass should not produce NaN values"
)
assert np.all(result >= 0), (
"BetaSpectrum with neutrino mass should be non-negative"
)
assert not np.any(
np.isnan(result)
), "BetaSpectrum with neutrino mass should not produce NaN values"
assert np.all(
result >= 0
), "BetaSpectrum with neutrino mass should be non-negative"
class TestNeutrinoMassCLIIntegration:
+3 -3
View File
@@ -74,9 +74,9 @@ class TestPhaseSpaceNeutrinoMass:
val_massive = ps_massive(W_near_endpoint)[0]
assert not np.isnan(val_massive), "Should produce finite value"
assert val_massive < val_zero, (
"Massive neutrino must suppress spectrum near endpoint"
)
assert (
val_massive < val_zero
), "Massive neutrino must suppress spectrum near endpoint"
@pytest.mark.physics
def test_massive_neutrino_below_threshold(self):
+31 -13
View File
@@ -21,20 +21,24 @@ class TestRadiativeEndpointHandling:
result = rc(W_near_end)
assert not np.isnan(result[0]), "Resummed correction must be finite at endpoint"
assert not np.isinf(result[0]), "Resummed correction must not diverge at endpoint"
assert not np.isinf(
result[0]
), "Resummed correction must not diverge at endpoint"
@pytest.mark.physics
def test_standard_mode_diverges(self):
"""Without resummation, δᵣ → −∞ as W → W₀ (logarithmic divergence)."""
rc = RadiativeCorrection(W0=5.0, use_endpoint_resummation=False)
W_far = np.array([4.9]) # ΔW = 0.1
W_far = np.array([4.9]) # ΔW = 0.1
W_close = np.array([4.99]) # ΔW = 0.01
val_far = rc(W_far)[0]
val_close = rc(W_close)[0]
assert val_close < val_far, "Standard mode must show divergent behavior near endpoint"
assert (
val_close < val_far
), "Standard mode must show divergent behavior near endpoint"
class TestRadiativeEnergyDependence:
@@ -51,7 +55,9 @@ class TestRadiativeEnergyDependence:
r_mid = rc(mid_W)[0]
r_near = rc(near_end_W)[0]
assert r_near <= r_mid, f"Correction factor should decrease near endpoint: {r_mid} → {r_near}"
assert (
r_near <= r_mid
), f"Correction factor should decrease near endpoint: {r_mid} → {r_near}"
class TestRadiativeResummationSwitch:
@@ -73,8 +79,12 @@ class TestRadiativeResummationSwitch:
r_standard = rc_standard(W_near)[0]
assert not np.isnan(r_resummed), "Resummed mode must be finite"
assert not np.isnan(r_standard), "Standard mode must be finite (mask protects endpoint)"
assert r_resummed > r_standard, f"Near endpoint: resummed={r_resummed} > standard={r_standard}"
assert not np.isnan(
r_standard
), "Standard mode must be finite (mask protects endpoint)"
assert (
r_resummed > r_standard
), f"Near endpoint: resummed={r_resummed} > standard={r_standard}"
@pytest.mark.physics
def test_resummation_only_near_endpoint(self):
@@ -87,9 +97,9 @@ class TestRadiativeResummationSwitch:
r_resummed_far = rc_resummed(W_far)[0]
r_standard_far = rc_standard(W_far)[0]
assert np.isclose(r_resummed_far, r_standard_far, rtol=1e-10), (
f"Far from endpoint: resummed={r_resummed_far}, standard={r_standard_far}"
)
assert np.isclose(
r_resummed_far, r_standard_far, rtol=1e-10
), f"Far from endpoint: resummed={r_resummed_far}, standard={r_standard_far}"
# Very near endpoint (delta_W < delta_cut): resummed is finite and larger
W_near = np.array([4.9995])
@@ -121,7 +131,9 @@ class TestRadiativeZDependence:
W_test = np.linspace(1.5, 4.5, 10)
diff = np.abs(rc_z50(W_test) - rc_z1(W_test))
assert np.max(diff) > 1e-4, f"Z=1 and Z=50 should differ: max diff = {np.max(diff)}"
assert (
np.max(diff) > 1e-4
), f"Z=1 and Z=50 should differ: max diff = {np.max(diff)}"
@pytest.mark.physics
def test_z_correction_magnitude_reasonable(self):
@@ -129,7 +141,9 @@ class TestRadiativeZDependence:
rc = RadiativeCorrection(W0=5.0, Z=92, use_endpoint_resummation=True)
W_test = np.array([3.0])
result = rc(W_test)
assert 0.9 < result[0] < 3.0, f"Z=92 correction should be reasonable: {result[0]}"
assert (
0.9 < result[0] < 3.0
), f"Z=92 correction should be reasonable: {result[0]}"
class TestRadiativeAParameter:
@@ -138,8 +152,12 @@ class TestRadiativeAParameter:
@pytest.mark.physics
def test_a_affects_nuclear_model_correction(self):
"""A parameter affects the nuclear-structure-dependent part of O(Z*alpha^2)."""
rc_a100 = RadiativeCorrection(W0=5.0, Z=50, A=100, use_endpoint_resummation=True)
rc_a140 = RadiativeCorrection(W0=5.0, Z=50, A=140, use_endpoint_resummation=True)
rc_a100 = RadiativeCorrection(
W0=5.0, Z=50, A=100, use_endpoint_resummation=True
)
rc_a140 = RadiativeCorrection(
W0=5.0, Z=50, A=140, use_endpoint_resummation=True
)
W_test = np.array([3.0])
assert rc_a100(W_test)[0] != rc_a140(W_test)[0], (