Skip to main content

Secular equilibrium calculator for radioactive decay chains

Project description

Secular Equilibrium Calculator

Radioactive Decay Chain Secular Equilibrium Calculation Tool

📦 Features

  • Calculate parent nuclide activity and mass based on measured daughter nuclide activity
  • Supports any radioactive decay chain, including natural series (U-238, Th-232, U-235) and artificial chains
  • Automatic cumulative branching ratio calculation across decay chains
  • Supports all decay types (α, β-, β+, EC, SF, IT, p, n, etc.)
  • Decay type specification with shorthand support (a for α, b for β-, e for EC)
  • Provide command-line interface (CLI) and Python API
  • Detailed error handling and input validation
  • Flexible output modes including quiet and mass-only outputs
  • Measurement uncertainty propagation for activity and mass outputs
  • Batch CSV processing mode for multi-sample calculations
  • Full decay-path explanation with per-path branching contributions

🔧 Installation

Install via pip (recommended)

pip install secular-equilibrium

Install from source

# Clone repository
git clone https://github.com/Josiah1/secular-eq.git
cd secular-eq

# Install dependencies
pip install -r requirements.txt

# Install in development mode
pip install -e .

🚀 Quick Start

Method 1: Python library usage

from secular_equilibrium import calculate_secular_equilibrium

# Calculate U-238 content from Pb-214 activity
results = calculate_secular_equilibrium(
    measured_nuclide='Pb-214',
    measured_activity=100.0,  # Bq
    parent_nuclides=['U-238', 'Ra-226'],
    verbose=True
)

print(f"U-238 activity: {results['U-238']['activity_Bq']:.4e} Bq")
print(f"U-238 mass: {results['U-238']['mass_g']:.4e} g")

Method 2: Command-line usage

# Basic usage
secular-eq --measured Pb-214 --activity 100 --parents U-238 Ra-226

# Short form
secular-eq -m Pb-214 -a 100 -p U-238

# Multiple parent nuclides
secular-eq -m Bi-214 -a 50 -p U-238 U-234 Ra-226 Rn-222

# Quiet mode (only output key results)
secular-eq -m Pb-214 -a 100 -p U-238 -q

# Specify decay type (e.g., alpha decay)
secular-eq -m Pb-214 -a 100 -p U-238 -d α

# Using shorthand for decay type (a for alpha, b for beta, e for EC)
secular-eq -m Pb-214 -a 100 -p U-238 -d a

# Mass-only output (only masses in grams, one per line)
secular-eq -m Pb-214 -a 100 -p U-238 Ra-226 --mass-only

# Include measured activity uncertainty (Bq)
secular-eq -m Pb-214 -a 100 -p U-238 --activity-unc 5

# Explain all parent-to-measured decay paths and path contributions
secular-eq -m Ra-223 -a 100 -p Ac-227 --explain-paths

# Batch mode from CSV (output to stdout)
secular-eq --input-csv batch_inputs.csv

# Batch mode with output file
secular-eq --input-csv batch_inputs.csv --output-csv batch_outputs.csv

📊 Practical Application Examples

Example 1: U-238 content determination in environmental samples

from secular_equilibrium import calculate_secular_equilibrium

# Measured Pb-214 activity in soil sample is 85 Bq/kg
results = calculate_secular_equilibrium(
    measured_nuclide='Pb-214',
    measured_activity=85.0,  # Bq/kg
    parent_nuclides=['U-238'],
    verbose=True
)

# Get U-238 content
u238_mass_per_kg = results['U-238']['mass_g']
u238_ppm = u238_mass_per_kg * 1e6  # Convert to ppm
print(f"\nU-238 concentration in soil: {u238_ppm:.2f} ppm")

Example 2: Th-232 series analysis

# Measured Bi-212 activity
results = calculate_secular_equilibrium(
    measured_nuclide='Bi-212',
    measured_activity=120.0,
    parent_nuclides=['Th-232', 'Ra-228', 'Th-228'],
    verbose=False  # Don't print detailed information
)

# Extract key information
for parent, data in results.items():
    print(f"{parent}:")
    print(f"  Activity: {data['activity_Bq']:.2e} Bq")
    print(f"  Mass: {data['mass_g']:.2e} g")
    print(f"  Branching ratio: {data['branching_ratio']:.4f}")

📚 API Documentation

SecularEquilibriumCalculator class

Initialization parameters

  • measured_nuclide (str): Measured nuclide name (e.g., 'Pb-214', 'Bi-214')
  • measured_activity (float): Measured activity (Bq)
  • parent_nuclides (List[str]): List of parent nuclides (e.g., ['U-238', 'Ra-226'])
  • decay_type (str, optional): Decay type to consider (e.g., 'α', 'β-', 'β+', 'EC'). If None, considers all decay types (default).

Methods

  • calculate(): Perform calculation, return result dictionary
  • print_results(results): Print formatted results

calculate_secular_equilibrium() function

Convenience function that automatically creates calculator and returns results.

def calculate_secular_equilibrium(
    measured_nuclide: str,
    measured_activity: float,
    parent_nuclides: List[str],
    decay_type: Optional[str] = None,
    verbose: bool = True,
    measured_activity_uncertainty: Optional[float] = None,
    include_paths: bool = False,
) -> Dict[str, Dict[str, float]]

Example with decay type specification

# Calculate U-238 activity from measured Pb-214 alpha decay activity
results = calculate_secular_equilibrium(
    measured_nuclide='Pb-214',
    measured_activity=50.0,  # Alpha decay activity (Bq)
    parent_nuclides=['U-238'],
    decay_type='α',  # or use shorthand 'a'
    verbose=True
)

# Using shorthand for decay type
results = calculate_secular_equilibrium(
    measured_nuclide='Pb-214',
    measured_activity=50.0,
    parent_nuclides=['U-238'],
    decay_type='a',  # shorthand for alpha
    verbose=True
)

Return value format

{
    'U-238': {
        'activity_Bq': 100.0,           # Activity (Bq)
        'mass_g': 8.04e-6,              # Mass (g)
        'branching_ratio': 1.0,         # Branching ratio
        'halflife_yr': 4.468e9,         # Half-life (years)
        'atomic_mass': 238.05078826,    # Atomic mass (u)
        'activity_uncertainty_Bq': 5.0, # Optional uncertainty field
        'mass_uncertainty_g': 4.02e-7,  # Optional uncertainty field
        'relative_uncertainty': 0.05,   # Optional uncertainty field
        'paths': [...]                  # Optional when include_paths=True
    }
}

🧾 Batch CSV Input/Output

Input CSV columns

Required:

  • measured_nuclide
  • measured_activity
  • parent_nuclides (semicolon-separated, e.g., U-238;Ra-226)

Optional:

  • decay_type
  • measured_activity_uncertainty

Output CSV columns

Always includes input columns plus:

  • parent
  • activity_Bq, mass_g, branching_ratio, halflife_yr, atomic_mass
  • activity_uncertainty_Bq, mass_uncertainty_g, relative_uncertainty (when available)
  • paths_json (when --explain-paths is enabled)
  • error (row-level or parent-level errors)

Batch mode continues processing on errors and returns non-zero exit code if any row fails.

🔬 Supported Decay Chains

The calculator supports any radioactive decay chain based on the nuclear decay database. While commonly used for natural radioactive series, it works equally well for artificial decay chains and custom nuclide combinations.

Major natural radioactive series (common examples)

  1. U-238 series (Uranium series)

    • U-238 → Th-234 → Pa-234m → U-234 → Th-230 → Ra-226 → Rn-222 → Po-218 → Pb-214 → Bi-214 → Po-214 → Pb-210
  2. Th-232 series (Thorium series)

    • Th-232 → Ra-228 → Ac-228 → Th-228 → Ra-224 → Rn-220 → Po-216 → Pb-212 → Bi-212 → Po-212/Tl-208
  3. U-235 series (Actinium series)

    • U-235 → Th-231 → Pa-231 → Ac-227 → Th-227 → Ra-223 → Rn-219 → Po-215 → Pb-211 → Bi-211

⚠️ Important Notes

  1. Closed system: Assumes closed system with no external nuclide addition or loss
  2. Equilibrium time: Requires waiting about 7-10 daughter half-lives to reach equilibrium
  3. Branching decay: Automatically considers branching ratios, but ensure correct decay chain
  4. Measurement uncertainty: Result accuracy depends on input activity measurement precision

🧪 Running Tests

# Run all tests
python -m pytest tests/

# Run specific test
python -m pytest tests/test_calculator.py::TestSecularEquilibrium::test_u238_chain

# Use unittest
python -m unittest tests/test_calculator.py

📄 License

MIT License - See LICENSE file for details

🤝 Contributing

Welcome to submit Issues and Pull Requests!

  1. Fork the project
  2. Create feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add some AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open Pull Request

📧 Contact

For questions, please submit an Issue on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

secular_equilibrium-1.1.1.tar.gz (22.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

secular_equilibrium-1.1.1-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file secular_equilibrium-1.1.1.tar.gz.

File metadata

  • Download URL: secular_equilibrium-1.1.1.tar.gz
  • Upload date:
  • Size: 22.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for secular_equilibrium-1.1.1.tar.gz
Algorithm Hash digest
SHA256 51b7c2a43c28e5178bf59340ca60c4f73346947d0581fdd2dd5fb45b53d2bfaf
MD5 d353e09363c03096b8bc05d82e0a7211
BLAKE2b-256 24052bfa2ed1a1b29cd49db047756320a960c11a03de8a407fe23adcb9beb51c

See more details on using hashes here.

File details

Details for the file secular_equilibrium-1.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for secular_equilibrium-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e9faa229974ae8dca0a778b1864614d829fbad33d6470484bf4c89f46d749193
MD5 eb4552c87d06b2734685793ff5d83d1a
BLAKE2b-256 762c967303e4275b1c7d46ff628957a150f6de0bdb8c6dd3914e0d7a86420678

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page