Metadata-Version: 2.4
Name: taustar
Version: 0.2.0
Summary: Allan deviation toolkit for nuclear and radioactive counting measurements
Author: Assaf Alassaf
License: MIT
Project-URL: Homepage, https://github.com/assafalassaf/taustar
Project-URL: Documentation, https://github.com/assafalassaf/taustar#readme
Project-URL: Repository, https://github.com/assafalassaf/taustar
Project-URL: Issues, https://github.com/assafalassaf/taustar/issues
Keywords: allan-deviation,allan-variance,OADEV,ADEV,MDEV,HDEV,nuclear-measurements,radioactive-counting,metrology,frequency-stability,noise-analysis,radionuclide,time-frequency,Poisson-noise,detector-characterisation,IEEE-1139,EDF,IAEA
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.22
Provides-Extra: plot
Requires-Dist: matplotlib>=3.5; extra == "plot"
Provides-Extra: all
Requires-Dist: matplotlib>=3.5; extra == "all"
Requires-Dist: scipy>=1.7; extra == "all"
Requires-Dist: pandas>=1.4; extra == "all"
Provides-Extra: dev
Requires-Dist: matplotlib>=3.5; extra == "dev"
Requires-Dist: scipy>=1.7; extra == "dev"
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Dynamic: license-file

# taustar

**Allan deviation toolkit for nuclear and radioactive counting measurements.**

A Python library implementing the overlapping Allan deviation (OADEV) framework for radioactive counting, with all standard Allan deviation variants, a built-in radionuclide database, closed-form theoretical predictions, noise identification, and publication-quality figure generation.

## Installation

```bash
pip install taustar
```

Or install from source:

```bash
git clone https://github.com/assafalassaf/taustar.git
cd taustar
pip install -e .
```

## Quick Start

```python
import taustar as on

# Theoretical prediction: what's the best stability you can get
# from Tc-99m at 10,000 detected counts per second?
pred = on.predict(activity=10_000, halflife="6.01h")
print(pred)
# NuclearPrediction(
#   activity    = 10000.0 cps,
#   half-life   = 6.01 h,
#   τ*          = 46.38 s,
#   σ_y,min     = 1.47e-03
# )
```

## Features

### All Allan Deviation Variants

```python
import numpy as np
import taustar as on

# Generate fractional deviations from counting data
y = on.counts_to_fractional(my_counts)

# Standard Allan deviation
taus, ad, lo, hi = on.adev(y, tau0=1.0)

# Overlapping Allan deviation (recommended)
taus, ad, lo, hi = on.oadev(y, tau0=1.0)

# Modified Allan deviation (distinguishes WPM from WFM)
taus, md, lo, hi = on.mdev(y, tau0=1.0)

# Hadamard deviation (drift-insensitive)
taus, hd, lo, hi = on.hdev(y, tau0=1.0)

# Overlapping Hadamard deviation
taus, ohd, lo, hi = on.ohdev(y, tau0=1.0)

# Time deviation
taus, td, lo, hi = on.tdev(y, tau0=1.0)

# Total deviation (extended overlap for short datasets)
taus, td, lo, hi = on.totdev(y, tau0=1.0)

# Théo1 deviation (maximum information from finite data)
taus, th, lo, hi = on.theo1(y, tau0=1.0)
```

All variants return 68% confidence intervals.

### Theoretical Equations

```python
import taustar as on

# Optimal averaging time (Eq. 6)
tau_star = on.optimal_tau(activity=10_000, halflife="6.01h")

# Minimum achievable instability (Eq. 7)
s_min = on.sigma_min(activity=10_000, halflife="6.01h")

# Individual contributions
var_poisson = on.poisson_variance(activity=10_000, tau=100)
var_drift = on.drift_variance(halflife="6.01h", tau=100)

# Full theoretical curve
taus, sigma = on.theoretical_oadev(activity=10_000, halflife="6.01h")
```

### Built-in Isotope Database

22 radionuclides with half-lives, typical activities, decay modes, detector types, and application context.

```python
import taustar as on

# Look up an isotope
iso = on.get_isotope("Co-60")
print(iso.halflife_display)    # "5.271 yr"
print(iso.typical_activity)    # 10000
print(iso.decay_mode)          # "β-"

# List all isotopes
for iso in on.list_isotopes(sort_by="halflife"):
    print(f"{iso.name:<12} {iso.halflife_display}")

# Search by property
alpha_emitters = on.search_isotopes(decay_mode="α")
long_lived = on.search_isotopes(halflife_min=365.25*86400*100)  # >100 yr
```

### Noise Identification

```python
import taustar as on

# From OADEV data, identify noise types
segments = on.identify_noise(taus, sigma, piecewise=True)
for seg in segments:
    print(seg)
    # NoiseSegment(τ=1.0–100.0 s, μ=-0.48, White Frequency, R²=0.998)
    # NoiseSegment(τ=100.0–10000.0 s, μ=+0.95, Linear Frequency Drift, R²=0.997)

# Fit slope in a specific tau range
slope, intercept, r2 = on.fit_slope(taus, sigma, tau_min=10, tau_max=1000)
```

### Full Analysis Pipeline

```python
import taustar as on

# Load data
data = on.load_counts("detector_data.csv", gate_time=1800)

# Run analysis with theoretical comparison
result = on.analyze(data, activity=10_000, halflife="5.271y")
print(result.summary())

# Apply decay correction
corrected = on.decay_correct(data, halflife="5.271y")
result_corr = on.analyze(corrected, activity=10_000, halflife="5.271y")
```

### Publication Figures (CPEM Style)

```python
import taustar as on

# Theoretical prediction plot
fig, ax = on.plot_theoretical(activity=10_000, halflife="6.01h")

# Measured vs theoretical comparison
fig, ax = on.plot_comparison(result, show_corrected=result_corr)

# Multi-isotope comparison
fig, ax = on.plot_multi_isotope([
    {"name": "Tc-99m", "activity": 100_000, "halflife": "6.01h"},
    {"name": "I-131",  "activity": 50_000,  "halflife": "8.025d"},
    {"name": "Co-60",  "activity": 10_000,  "halflife": "5.271y"},
    {"name": "Cs-137", "activity": 5_000,   "halflife": "30.08y"},
    {"name": "Am-241", "activity": 5_000,   "halflife": "432.2y"},
    {"name": "Ra-226", "activity": 1_000,   "halflife": "1600y"},
])

# Save in multiple formats
on.save_figure(fig, "figure_2", formats=["png", "pdf"])
```

## Command-Line Interface

```bash
# Theoretical prediction
taustar predict --activity 10000 --halflife 6.01h --plot

# Browse isotope database
taustar library list
taustar library predict Tc-99m --plot

# Compare isotopes
taustar library compare Tc-99m Co-60 Ra-226 Am-241 --plot

# Analyze real data
taustar analyze data.csv --gate-time 1800 --halflife 5.271y --correct --plot
```

## Noise Type Reference

| Slope μ | Noise Type | OADEV Behaviour | Nuclear Origin |
|---------|-----------|-----------------|----------------|
| −1 | White Phase | τ⁻¹ | Timing jitter, digitiser quantisation |
| −1/2 | White Frequency | τ⁻¹/² | Poisson counting statistics |
| 0 | Flicker Frequency | τ⁰ | PMT gain aging, discriminator drift |
| +1/2 | Random Walk | τ⁺¹/² | Temperature-coupled gain fluctuations |
| +1 | Linear Drift | τ⁺¹ | Radioactive decay or instrumental drift |

## Theory

The library implements the closed-form OADEV framework where:

- **Poisson noise** decreases as σ(τ) = 1/√(A₀τ) — set by the detected count rate
- **Decay drift** increases as σ(τ) = ln(2)·τ / (√2·t½) — set by the half-life
- **Optimal averaging time** τ* = (t½² / (A₀·ln²2))^(1/3) — where these balance
- **Minimum instability** σ_min = √(3/2) · (ln²2 / (A₀²·t½²))^(1/6) — the theoretical floor

## Citation

If you use this library in your research, please cite:

```bibtex
@article{alassaf2026oadev,
  title={Overlapping Allan deviation framework for nuclear counting measurements},
  author={Alassaf, Assaf and Hamid, Ramiz},
  year={2026},
}
```

## License

MIT License. See [LICENSE](LICENSE) for details.
