Files
beta_shape_pnpi/README.md
T

255 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Beta Spectrum Calculation Toolkit
A modular Python package for calculating high-precision **beta decay energy spectra**. It models the spectral shape of nuclear transitions by combining well-established physical corrections into a coherent, configurable pipeline.
**Features:**
- Numerical evaluation from near-zero kinetic energies up to the endpoint
- Selective inclusion of higher-order corrections via `SpectrumConfig` toggles
- Clean, composable component architecture
- Built-in visualization and CSV export via `BetaSpectrumAnalyzer`
- Comprehensive scientific reference in [`docs/`](docs/)
______________________________________________________________________
## Core Concept
The beta spectrum is constructed as a product of independent correction factors:
$$N(W) \\propto p W (W_0 - W)^2 \\times \\prod_i C_i(W)$$
Each $C_i(W)$ is an independently implemented and toggleable component.
______________________________________________________________________
## Project Structure
```
beta_shape_pnpi/
├── pyproject.toml
├── docs/ # Obsidian knowledge base (physics theory & references)
│ ├── README.md # Vault overview + navigation index
│ ├── Hayen2017_summary.md # Full paper summary backbone
│ ├── 00-beta-spectrum-overview.md # Master equation, all corrections table
│ ├── 01-fermi-function.md # Fermi function F₀(Z,W)
│ ├── 02-phase-space.md # Phase space p·W·(W₀−W)²
│ ├── 03-finite-size.md # L₀, U, DFS corrections
│ ├── 04-screening-correction.md # Atomic screening S(Z,W)
│ ├── 05-exchange-correction.md # Electron exchange X(Z,W)
│ ├── 06-radiative-corrections.md # Outer radiative δᵣ(W,W₀)
│ ├── 07-recoil-effects.md # Weak magnetism, recoil kinematics
│ ├── 10-nuclear-structure.md # Shape factor C(Z,W), BB vs HS formalisms
│ ├── 12-atomic-overlap.md # Bahcall correction r(Z,W)
│ ├── 13-chemical-effects.md # Molecular environment effects
│ └── refs-hayen2017.md # Key equations reference table, citations
├── beta_spectrum/
│ ├── __init__.py # Public API: constants, utilities, classes
│ ├── base.py # Abstract SpectrumComponent base class
│ ├── constants.py # Physical constants (natural units, m_e = 1)
│ ├── utils.py # Helpers: T<->W conversion, momentum, nuclear radius
│ ├── spectrum.py # BetaSpectrum + BetaSpectrumAnalyzer classes
│ └── components/
│ │ ├── phase_space.py ✓ Phase space shape (p·W·(W₀−W)²)
│ │ ├── fermi.py ✓ Coulomb correction (loggamma for stability)
│ │ ├── finite_size.py ✓ L0 expansion + charge distribution U term
│ │ ├── screening.py ✓ Atomic electron screening (ratio method)
│ │ ├── exchange.py ✓ Hayen-2018 empirical fit coefficients
│ │ ├── radiative.py ✓ Outer radiative corrections, soft-photon resummation
│ │ └── recoil.py ✗ Not yet implemented
├── tests/
│ ├── test_radiative.py # Radiative correction tests (24 tests)
│ ├── test_exchange.py # Exchange correction tests
│ ├── test_fermi.py # Fermi function tests
│ ├── test_finite_size.py # Finite size correction tests
│ ├── test_phase_space.py # Phase space tests
│ ├── test_screening.py # Screening correction tests
│ └── test_spectrum.py # Integration tests
└── data/
└── exchange_coeff.csv # Tabulated coefficients for X(Z,W), Z=2..120
```
______________________________________________________________________
## Architecture
### `SpectrumComponent` (base class)
Defined in `beta_spectrum/base.py`. All physics corrections inherit from this abstract base and implement:
```python
def __call__(self, W: np.ndarray) -> np.ndarray
```
This makes every component stateless (or minimally stateful), vectorized, and composable.
### `BetaSpectrum`
Defined in `beta_spectrum/spectrum.py`. Orchestrates the calculation:
- Combines components multiplicatively via `__call__(W)`
- Factory method `from_config(config)` for declarative setup
- Generates energy grids with `get_energy_grid(config)`
- Returns individual component values via `calculate_components(W)`
### `BetaSpectrumAnalyzer`
Also in `spectrum.py`. Provides debugging and visualization tools:
- `total_spectrum(normalize=True/False)` — computed spectrum array
- `plot_analysis(save_path=None)` — 4-panel matplotlib figure (spectrum, components, cumulative effect, deviations from unity)
- `export_to_csv(filename)` — export via pandas DataFrame
- `get_data()` — return all numerical data for custom analysis
______________________________________________________________________
## Quick Start
```python
from beta_spectrum import SpectrumConfig, BetaSpectrum, BetaSpectrumAnalyzer
config = SpectrumConfig(
Z_parent=90, # Thorium-232 (example)
Z_daughter=91,
A_number=232,
endpoint_MeV=4.8, # Q-value
transition_type="A", # Allowed transition (default)
)
spectrum = BetaSpectrum.from_config(config)
W, E_MeV = spectrum.get_energy_grid(config)
values = spectrum(W)
analyzer = BetaSpectrumAnalyzer(spectrum, config)
analyzer.plot_analysis() # Show/ save 4-panel figure
analyzer.export_to_csv("output.csv") # Export data to CSV
```
______________________________________________________________________
## Components
| Component | Module | Status | Description |
| --------------------- | ---------------- | -----: | -------------------------------------------------------------------------------------------------------------- |
| Phase Space | `phase_space.py` | ✓ | Baseline $p W (W_0 - W)^2$ with transition-type-dependent forbidden factors and optional neutrino mass support |
| Fermi Function | `fermi.py` | ✓ | Relativistic Coulomb correction via `scipy.special.loggamma` |
| Finite Size L0 | `finite_size.py` | ✓ | Low-Z expansion from Hayen et al. with prefactor |
| Charge Distribution U | `finite_size.py` | ✓ | Second-order $(1/5)(\\alpha Z W R)^2$ correction |
| Screening | `screening.py` | ✓ | Ratio method with logistic switching, energy shift $V_0$ |
| Exchange | `exchange.py` | ✓ | Hayen-2018 Table X empirical fit (CSV data for Z=2..120) |
| Radiative | `radiative.py` | ✓ | Outer radiative corrections (Hayen Eq. 47–53), soft-photon resummation at endpoint |
| Recoil | `recoil.py` | ✗ | Stub only, not yet implemented |
______________________________________________________________________
## Configuration
Use `SpectrumConfig` to selectively enable/disable each correction:
```python
config = SpectrumConfig(
Z_parent=20, Z_daughter=21, A_number=40, endpoint_MeV=5.0,
transition_type="F1", # first forbidden non-unique
use_fermi=True,
use_screening=False, # disable atomic screening
use_exchange=True,
use_radiative=True,
)
```
______________________________________________________________________
## Transition Types
The `transition_type` parameter in `SpectrumConfig` determines the **forbidden factor** applied to the phase space calculation. This encodes the angular momentum and parity selection rules for the nuclear transition:
| Type | Name | Forbidden Order | $\\Delta J^\\pi$ | Forbidden Factor |
| ----- | ----------------------------- | --------------- | ------------------------------------- | --------------------------------------------------------- |
| `A` | Allowed | 0 | $0^+, 1^+$ | $1$ |
| `F1` | First forbidden (non-unique) | 1 | $0^-, 1^-, 2^\\pm$ | $p\_\\nu^2 + p_e^2$ |
| `F1U` | First forbidden (unique) | 1 | $2^-$ | $p\_\\nu^2 + p_e^2$ |
| `F2` | Second forbidden (non-unique) | 2 | $1^\\pm, 2^+, 3^\\pm$ | $p\_\\nu^4 + \\frac{3}{10}p\_\\nu^2 p_e^2 + p_e^4$ |
| `F2U` | Second forbidden (unique) | 2 | $3^-$ | $p\_\\nu^4 + \\frac{3}{10}p\_\\nu^2 p_e^2 + p_e^4$ |
| `F3` | Third forbidden (non-unique) | 3 | $0^\\pm, 1^\\pm, 2^\\pm, 3^+, 4^\\pm$ | $p\_\\nu^6 + 7p\_\\nu^4 p_e^2 + 7p\_\\nu^2 p_e^4 + p_e^6$ |
| `F3U` | Third forbidden (unique) | 3 | $4^-$ | $p\_\\nu^6 + 7p\_\\nu^4 p_e^2 + 7p\_\\nu^2 p_e^4 + p_e^6$ |
| `F4` | Fourth forbidden (unique) | 4 | $5^-$ | $p\_\\nu^6 + 7p\_\\nu^4 p_e^2 + 7p\_\\nu^2 p_e^4 + p_e^6$ |
The forbidden factor multiplies the baseline phase space $p_e W_e p\_\\nu W\_\\nu$, modifying the spectral shape at higher energies. The even/odd suffix (`U`) distinguishes **unique** transitions (single contributing nuclear matrix element) from **non-unique** ones (multiple contributing matrix elements).
> [!note] Shape factor
> For a complete treatment of forbidden transitions, the nuclear **shape factor** $C(Z,W)$ from `[[10-nuclear-structure]]` should also be included. This is not yet implemented in the calculator.
## Dependencies
**Runtime:** numpy, scipy (for `loggamma`, `spence`), matplotlib (plotting), pandas (CSV export)\
**Dev:** pytest, black, ruff, mypy (strict mode configured in `pyproject.toml`)
______________________________________________________________________
## Design Principles
### 1. Modularity
Each physical effect is isolated in its own component under `beta_spectrum/components/`.
### 2. Numerical Stability
Care near $W \\to 1$ (threshold) and $W \\to W_0$ (endpoint):
- `np.clip` / epsilon floors for regularization
- Safe logarithms via `scipy.special.loggamma` and dilogarithm
- Masking invalid regions
### 3. Vectorization
All components operate on NumPy arrays — no Python loops in hot paths.
### 4. Extensibility
New corrections are added by subclassing:
```python
class NewCorrection(SpectrumComponent):
def __call__(self, W):
return ...
```
______________________________________________________________________
## Development Status
**Version:** 0.2.0\
**Status:** Active development — core physics engine is functional with comprehensive test coverage.
### Remaining Work
- Implement nuclear recoil correction in `recoil.py` (see \[[07-recoil-effects]\])
- Declare pandas as a runtime dependency in `pyproject.toml`
- Satisfy mypy strict type-checking requirements
- CLI entry point and multiple decay branch support
- Implement nuclear shape factors C(Z,W) for forbidden transitions
- Implement neutrino radiative corrections (Sirlin 2011)
______________________________________________________________________
## Knowledge Base
The [`docs/`](docs/) directory contains the complete scientific reference for beta spectrum shape corrections, organized as an Obsidian vault. It is structured around Hayen et al., *Rev. Mod. Phys.* **90**, 015008 (2017) and maps directly to calculator components:
| # | Note | Calculator Module | Status |
| --- | ------------------------------ | --------------------------- | --------------------- |
| 1 | \[[01-fermi-function]\] | `components/fermi.py` | ✓ implemented |
| 2 | \[[03-finite-size]\] | `components/finite_size.py` | ✓ implemented |
| 3 | \[[04-screening-correction]\] | `components/screening.py` | ✓ implemented |
| 4 | \[[05-exchange-correction]\] | `components/exchange.py` | ✓ implemented |
| 5 | \[[06-radiative-corrections]\] | `components/radiative.py` | ✓ implemented |
| 6 | \[[07-recoil-effects]\] | `components/recoil.py` | ✗ not yet implemented |
Notes prefixed with `10-`, `12-`, `13-` cover nuclear structure, atomic overlap, and chemical effects — important for future extensions but outside the current calculator scope.
______________________________________________________________________
## Notes
- Physical constants are defined in natural units ($m_e = 1$); energies can be converted from MeV via utilities in `utils.py`
- The framework assumes familiarity with beta decay theory