From b974b68ce70393bc43fb30c769068e8b658d3418 Mon Sep 17 00:00:00 2001 From: Evgeniy Unzhakov Date: Fri, 1 May 2026 19:17:41 +0300 Subject: [PATCH] docs: update README structure and DEVELOPMENT.md setup instructions --- DEVELOPMENT.md | 3 + README.md | 153 +++++++++++++++++++++++++++---------------------- 2 files changed, 88 insertions(+), 68 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index eec89a9..5b752fc 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,6 +2,9 @@ ## 1. Setup +Do not attempt system wide pip installations. Use virtual environment 'sci'. +Default venv location: `~/.pyenv/`. + ```bash source ~/.pyenv/sci/bin/activate pip install -e ".[dev]" diff --git a/README.md b/README.md index 29241e7..34f3209 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,24 @@ 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/) ---- +- 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)$$ +$$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 @@ -55,11 +56,19 @@ beta_shape_pnpi/ │ │ ├── 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 @@ -76,20 +85,22 @@ This makes every component stateless (or minimally stateful), vectorized, and co ### `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)` + +- 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 ---- +- `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 @@ -113,22 +124,22 @@ 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 | +| 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 @@ -145,50 +156,55 @@ config = SpectrumConfig( ) ``` ---- +______________________________________________________________________ ## 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$ | +| 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). +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) +**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 + +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 @@ -197,41 +213,42 @@ class NewCorrection(SpectrumComponent): return ... ``` ---- +______________________________________________________________________ ## Development Status -**Version:** 0.1.2 -**Status:** Active development — core physics engine is functional; recoil correction and tests remain incomplete. +**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]]) -* Add unit / integration tests (pytest configured but no test files) -* 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 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 | +| # | 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 +- 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