docs: update README structure and DEVELOPMENT.md setup instructions
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## 1. Setup
|
## 1. Setup
|
||||||
|
|
||||||
|
Do not attempt system wide pip installations. Use virtual environment 'sci'.
|
||||||
|
Default venv location: `~/.pyenv/`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
source ~/.pyenv/sci/bin/activate
|
source ~/.pyenv/sci/bin/activate
|
||||||
pip install -e ".[dev]"
|
pip install -e ".[dev]"
|
||||||
|
|||||||
@@ -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.
|
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:**
|
**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
|
## Core Concept
|
||||||
|
|
||||||
The beta spectrum is constructed as a product of independent correction factors:
|
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.
|
Each $C_i(W)$ is an independently implemented and toggleable component.
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
@@ -55,11 +56,19 @@ beta_shape_pnpi/
|
|||||||
│ │ ├── exchange.py ✓ Hayen-2018 empirical fit coefficients
|
│ │ ├── exchange.py ✓ Hayen-2018 empirical fit coefficients
|
||||||
│ │ ├── radiative.py ✓ Outer radiative corrections, soft-photon resummation
|
│ │ ├── radiative.py ✓ Outer radiative corrections, soft-photon resummation
|
||||||
│ │ └── recoil.py ✗ Not yet implemented
|
│ │ └── 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/
|
└── data/
|
||||||
└── exchange_coeff.csv # Tabulated coefficients for X(Z,W), Z=2..120
|
└── exchange_coeff.csv # Tabulated coefficients for X(Z,W), Z=2..120
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
@@ -76,20 +85,22 @@ This makes every component stateless (or minimally stateful), vectorized, and co
|
|||||||
### `BetaSpectrum`
|
### `BetaSpectrum`
|
||||||
|
|
||||||
Defined in `beta_spectrum/spectrum.py`. Orchestrates the calculation:
|
Defined in `beta_spectrum/spectrum.py`. Orchestrates the calculation:
|
||||||
* Combines components multiplicatively via `__call__(W)`
|
|
||||||
* Factory method `from_config(config)` for declarative setup
|
- Combines components multiplicatively via `__call__(W)`
|
||||||
* Generates energy grids with `get_energy_grid(config)`
|
- Factory method `from_config(config)` for declarative setup
|
||||||
* Returns individual component values via `calculate_components(W)`
|
- Generates energy grids with `get_energy_grid(config)`
|
||||||
|
- Returns individual component values via `calculate_components(W)`
|
||||||
|
|
||||||
### `BetaSpectrumAnalyzer`
|
### `BetaSpectrumAnalyzer`
|
||||||
|
|
||||||
Also in `spectrum.py`. Provides debugging and visualization tools:
|
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
|
## Quick Start
|
||||||
|
|
||||||
@@ -113,22 +124,22 @@ analyzer.plot_analysis() # Show/ save 4-panel figure
|
|||||||
analyzer.export_to_csv("output.csv") # Export data to CSV
|
analyzer.export_to_csv("output.csv") # Export data to CSV
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
| Component | Module | Status | Description |
|
| 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 |
|
| 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` |
|
| 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 |
|
| 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 |
|
| 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$ |
|
| 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) |
|
| 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 |
|
| Radiative | `radiative.py` | ✓ | Outer radiative corrections (Hayen Eq. 47–53), soft-photon resummation at endpoint |
|
||||||
| Recoil | `recoil.py` | ✗ | Stub only, not yet implemented |
|
| Recoil | `recoil.py` | ✗ | Stub only, not yet implemented |
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -145,50 +156,55 @@ config = SpectrumConfig(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Transition Types
|
## 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:
|
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 |
|
| Type | Name | Forbidden Order | $\\Delta J^\\pi$ | Forbidden Factor |
|
||||||
|------|------|-----------------|----------------|------------------|
|
| ----- | ----------------------------- | --------------- | ------------------------------------- | --------------------------------------------------------- |
|
||||||
| `A` | Allowed | 0 | $0^+, 1^+$ | $1$ |
|
| `A` | Allowed | 0 | $0^+, 1^+$ | $1$ |
|
||||||
| `F1` | First forbidden (non-unique) | 1 | $0^-, 1^-, 2^\pm$ | $p_\nu^2 + p_e^2$ |
|
| `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$ |
|
| `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$ |
|
| `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$ |
|
| `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$ |
|
| `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$ |
|
| `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$ |
|
| `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
|
> [!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.
|
> 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
|
## 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`)
|
**Dev:** pytest, black, ruff, mypy (strict mode configured in `pyproject.toml`)
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Design Principles
|
## Design Principles
|
||||||
|
|
||||||
### 1. Modularity
|
### 1. Modularity
|
||||||
|
|
||||||
Each physical effect is isolated in its own component under `beta_spectrum/components/`.
|
Each physical effect is isolated in its own component under `beta_spectrum/components/`.
|
||||||
|
|
||||||
### 2. Numerical Stability
|
### 2. Numerical Stability
|
||||||
Care near $W \to 1$ (threshold) and $W \to W_0$ (endpoint):
|
|
||||||
* `np.clip` / epsilon floors for regularization
|
Care near $W \\to 1$ (threshold) and $W \\to W_0$ (endpoint):
|
||||||
* Safe logarithms via `scipy.special.loggamma` and dilogarithm
|
|
||||||
* Masking invalid regions
|
- `np.clip` / epsilon floors for regularization
|
||||||
|
- Safe logarithms via `scipy.special.loggamma` and dilogarithm
|
||||||
|
- Masking invalid regions
|
||||||
|
|
||||||
### 3. Vectorization
|
### 3. Vectorization
|
||||||
|
|
||||||
All components operate on NumPy arrays — no Python loops in hot paths.
|
All components operate on NumPy arrays — no Python loops in hot paths.
|
||||||
|
|
||||||
### 4. Extensibility
|
### 4. Extensibility
|
||||||
|
|
||||||
New corrections are added by subclassing:
|
New corrections are added by subclassing:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@@ -197,41 +213,42 @@ class NewCorrection(SpectrumComponent):
|
|||||||
return ...
|
return ...
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Development Status
|
## Development Status
|
||||||
|
|
||||||
**Version:** 0.1.2
|
**Version:** 0.2.0\
|
||||||
**Status:** Active development — core physics engine is functional; recoil correction and tests remain incomplete.
|
**Status:** Active development — core physics engine is functional with comprehensive test coverage.
|
||||||
|
|
||||||
### Remaining Work
|
### Remaining Work
|
||||||
|
|
||||||
* Implement nuclear recoil correction in `recoil.py` (see [[07-recoil-effects]])
|
- 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`
|
||||||
* Declare pandas as a runtime dependency in `pyproject.toml`
|
- Satisfy mypy strict type-checking requirements
|
||||||
* Satisfy mypy strict type-checking requirements
|
- CLI entry point and multiple decay branch support
|
||||||
* 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
|
## 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:
|
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 |
|
| # | Note | Calculator Module | Status |
|
||||||
|---|------|-------------------|--------|
|
| --- | ------------------------------ | --------------------------- | --------------------- |
|
||||||
| 1 | [[01-fermi-function]] | `components/fermi.py` | ✓ implemented |
|
| 1 | \[[01-fermi-function]\] | `components/fermi.py` | ✓ implemented |
|
||||||
| 2 | [[03-finite-size]] | `components/finite_size.py` | ✓ implemented |
|
| 2 | \[[03-finite-size]\] | `components/finite_size.py` | ✓ implemented |
|
||||||
| 3 | [[04-screening-correction]] | `components/screening.py` | ✓ implemented |
|
| 3 | \[[04-screening-correction]\] | `components/screening.py` | ✓ implemented |
|
||||||
| 4 | [[05-exchange-correction]] | `components/exchange.py` | ✓ implemented |
|
| 4 | \[[05-exchange-correction]\] | `components/exchange.py` | ✓ implemented |
|
||||||
| 5 | [[06-radiative-corrections]] | `components/radiative.py` | ✓ implemented |
|
| 5 | \[[06-radiative-corrections]\] | `components/radiative.py` | ✓ implemented |
|
||||||
| 6 | [[07-recoil-effects]] | `components/recoil.py` | ✗ not yet 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 prefixed with `10-`, `12-`, `13-` cover nuclear structure, atomic overlap, and chemical effects — important for future extensions but outside the current calculator scope.
|
||||||
|
|
||||||
---
|
______________________________________________________________________
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
* Physical constants are defined in natural units ($m_e = 1$); energies can be converted from MeV via utilities in `utils.py`
|
- 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
|
- The framework assumes familiarity with beta decay theory
|
||||||
|
|||||||
Reference in New Issue
Block a user