Metadata-Version: 2.4
Name: TDCRPy
Version: 2.20.12
Summary: TDCR model — Monte Carlo efficiency estimation for liquid scintillation counting
Home-page: https://github.com/RomainCoulon/TDCRPy
Author: Romain Coulon
Author-email: romain.coulon@bipm.org
Project-URL: Documentation, https://github.com/RomainCoulon/TDCRPy/
Project-URL: Bug Tracker, https://github.com/RomainCoulon/TDCRPy/issues
Keywords: TDCR,Monte-Carlo,radionuclide,liquid scintillation,counting
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Natural Language :: French
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENCE.md
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: matplotlib
Requires-Dist: tqdm
Requires-Dist: numba
Requires-Dist: setuptools
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: sphinx; extra == "dev"
Requires-Dist: sphinx-rtd-theme; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# TDCRPy

<div align="center">

<img src="docs/logo1.png" alt="TDCRPy Logo" width="200"/>

**A Photo-Physical Stochastic Model for Liquid Scintillation Counting**

![License](https://img.shields.io/badge/license-MIT-blue.svg)
![Python](https://img.shields.io/badge/python-3.11%2B-blue)
![Version](https://img.shields.io/badge/version-2.20.11-green)
![Status](https://img.shields.io/badge/status-stable-green)
![BIPM](https://img.shields.io/badge/maintained%20by-BIPM-005696)

</div>

---

## 📖 Overview

**TDCRPy** is a Python package developed and maintained by the **BIPM** (Bureau International des Poids et Mesures). It estimates detection efficiencies of liquid scintillation counters using the **TDCR** (Triple to Double Coincidence Ratio) or **CIEMAT/NIST** methods.

The calculation is based on a photo-physical stochastic Monte Carlo model, allowing users to address:

* Complex decay schemes (beta spectra via BetaShape, gamma interactions via MCNP matrices).
* Radionuclide mixtures with arbitrary activity fractions.
* Ionisation quenching via the Birks model (electrons and alpha particles).
* Reverse micelle effects in cocktails used for aqueous samples.
* Asymmetric PMT configurations (per-channel free parameters).
* Dynamic efficiency evolution over time (with `radioactivedecay`).
* Full optical Monte Carlo transport (`opticalTransport=True`).

Technical details are described in:

* [Coulon et al., *Applied Radiation and Isotopes* (2024)](https://doi.org/10.1016/j.apradiso.2024.111518)
* [Coulon et al., BIPM Technical Report](http://dx.doi.org/10.13140/RG.2.2.15682.80321)

---

## 📦 Installation

TDCRPy requires Python ≥ 3.11 and a standard scientific environment.

```shell
pip install TDCRPy
```

To upgrade to the latest version:

```shell
pip install TDCRPy --upgrade
```

### Run Tests

Verify the installation by running the unit tests:

```shell
python -m unittest tdcrpy.test.test_tdcrpy
```

---

## ⚡ Quick Start

Estimate detection efficiencies for **Co-60** using the full stochastic model.

```python
import tdcrpy

L    = 1.2      # free parameter (photons keV⁻¹)
Rad  = "Co-60"  # radionuclide
pmf  = "1"      # activity fraction (100 %)
N    = 10000    # Monte Carlo trials (≥ 10 000 recommended)
kB   = 1.0e-5   # Birks constant (cm keV⁻¹)
V    = 10       # scintillator volume (mL)

result = tdcrpy.TDCRPy.TDCRPy(L, Rad, pmf, N, kB, V)

print(f"eff_S = {result[0]:.4f} ± {result[1]:.4f}")   # single events
print(f"eff_D = {result[2]:.4f} ± {result[3]:.4f}")   # double coincidences
print(f"eff_T = {result[4]:.4f} ± {result[5]:.4f}")   # triple coincidences
```

### Find L from a Measured TDCR Ratio

```python
TD = 0.9776   # measured T/D ratio
result = tdcrpy.TDCRPy.eff(TD, Rad, pmf, kB, V)

print(f"L = {result[0]:.4f} photons/keV")
print(f"eff_T = {result[6]:.4f} ± {result[7]:.4f}")
```

---

## 🛠 Advanced Features

### Asymmetric PMT Configuration

Pass a 3-tuple for the free parameter to model per-channel asymmetry:

```python
L = (1.1, 1.3, 1.2)   # (L_A, L_B, L_C) in photons keV⁻¹
result = tdcrpy.TDCRPy.TDCRPy(L, "Co-60", "1", N, kB, V)

print(f"eff_AB = {result[6]:.4f}")   # A–B double coincidences
print(f"eff_BC = {result[8]:.4f}")
print(f"eff_AC = {result[10]:.4f}")
```

### Radionuclide Mixtures

Provide comma-separated nuclides and their relative activity fractions:

```python
result = tdcrpy.TDCRPy.TDCRPy(L, "Co-60, H-3", "0.8, 0.2", N, kB, V)
```

### Analytical Model (Pure Beta Emitters)

A faster, deterministic alternative for pure β⁻ nuclides:

```python
# Returns (L0, L_opt, eff_S, eff_D, eff_T)
result = tdcrpy.TDCRPy.effA(TD, "H-3", "1", kB, V)

print(f"L0 = {result[0]:.4f} photons/keV")
print(f"eff_T = {result[4]:.4f}")
```

### Full Optical Monte Carlo Transport

Enable stochastic photon-transport for each event: photons are sampled
from a Poisson distribution, distributed equally among PMTs, and converted
to photoelectrons via Binomial draws (quantum efficiency):

```python
result = tdcrpy.TDCRPy.TDCRPy(L, Rad, pmf, N, kB, V, opticalTransport=True)
```

### Dynamic Decay

Combine with `radioactivedecay` to track efficiency as a sample decays:

```python
import radioactivedecay as rd
import tdcrpy as td

inv0 = rd.Inventory({'Mo-99': 1.0}, 'Bq')
inv1 = inv0.decay(30.0, 'h')          # decay 30 h

acts  = inv1.activities('Bq')
total = sum(acts.values())
nucs  = ", ".join(k for k, v in acts.items() if v > 0)
fracs = ", ".join(str(v / total) for k, v in acts.items() if v > 0)

result = td.TDCRPy.TDCRPy(1.0, nucs, fracs, N, kB, V)
```

---

## ⚙️ Configuration & Physics

Display the current physics settings:

```python
import tdcrpy as td
td.TDCR_model_lib.readParameters(disp=True)
```

### Configuration Reference

| Parameter | Setter | Default | Unit | Description |
| :--- | :--- | :---: | :---: | :--- |
| Electron bins | `modifynE_electron(n)` | 1000 | — | Integration bins for electron quenching |
| Alpha bins | `modifynE_alpha(n)` | 1000 | — | Integration bins for alpha quenching |
| Stopping power | `modifysp_model(m)` | `tan_xia` | — | Low-energy model (`tan_xia`, `joy_luo`, …) |
| Birks parameter | `modifyChou_param(k)` | 0 | cm²/MeV² | Chou bimolecular quenching constant |
| Density | `modifyDensity(ρ)` | 0.98 | g/cm³ | Scintillator density (Ultima Gold) |
| Mean Z / A | `modifyZ(z)`, `modifyA(a)` | 3.25 / 5.94 | — | Effective atomic/mass number |
| Cocktail | `modifyLScocktail(name, fAq)` | `Ultima Gold` | — | LS cocktail + aqueous fraction |
| Micelle correction | `modifyMicCorr(b)` | False | — | Activate reverse-micelle correction |
| Micelle diameter | `modifyDiam_micelle(d)` | 2 | nm | Mean micelle diameter |
| Quantum efficiency | `modifyEffQ(q)` | `0.25,0.25,0.25` | — | PMT quantum efficiencies (A, B, C) |
| Optical transport | `modifyOpticalTransport(b)` | False | — | Enable full optical MC transport |
| Resolving time | `modifyTau(τ)` | 50 | ns | Coincidence resolving time |
| Dead time | `modifyDeadTime(t)` | 30 | µs | Extended dead time |
| Measurement time | `modifyMeasTime(T)` | 60 | min | Measurement duration |

---

## 📓 Notebooks

### Getting started

| Notebook | Description |
| :--- | :--- |
| [tuturial.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/tuturial.ipynb) | **End-to-end tutorial**: fixed-L efficiencies, TDCR fitting (symmetric and asymmetric), radionuclide mixtures, full optical MC transport |
| [changeParameters.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/changeParameters.ipynb) | **Configuration**: how to modify every physics parameter (quenching bins, stopping power model, cocktail, PMT efficiencies, dead time…) |

### Detection models

| Notebook | Description |
| :--- | :--- |
| [analyticalModel.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/analyticalModel.ipynb) | **Analytical model** (`effA`): fast beta-spectrum-based efficiency for pure β emitters; symmetric and asymmetric PMT configurations |
| [CNmethod.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/CNmethod.ipynb) | **CIEMAT/NIST (C/N) method**: 2-PMT coincidence system efficiency using `modelAnalyticalCN` |
| [cerenkovModel.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/cerenkovModel.ipynb) | **Čerenkov counting model**: Frank-Tamm-based efficiency for high-energy beta emitters |
| [opticalTransport.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/opticalTransport.ipynb) | **Optical MC transport**: comparison of semi-analytical vs full photon-transport model (`opticalTransport=True`) for H-3, Fe-55, Co-60 |

### Nuclide case studies

| Notebook | Description |
| :--- | :--- |
| [H-3.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/H-3.ipynb) | **Tritium (H-3)**: low-energy pure β; analytical and stochastic efficiency, micelle correction effect |
| [Co-60.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/Co-60.ipynb) | **Co-60**: γ-emitter with complex decay; analytical approximation vs full stochastic model |
| [Fe-55.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/Fe-55.ipynb) | **Fe-55**: electron-capture nuclide producing Mn K-α X-rays and Auger electrons |
| [Sr-90_Y-90.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/Sr-90_Y-90.ipynb) | **Sr-90/Y-90 mixture**: secular equilibrium of two pure β emitters (0.546 and 2.28 MeV endpoints) |
| [Zr-93.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/Zr-93.ipynb) | **Zr-93**: β/EC branching ratio nuclide with X-ray emission |

### Physics sub-models

| Notebook | Description |
| :--- | :--- |
| [quenchingModel.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/quenchingModel.ipynb) | **Birks quenching**: quenched energy vs initial energy for electrons and α particles as a function of kB |
| [stoppingPower.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/stoppingPower.ipynb) | **Stopping power models**: comparison of tan_xia, joy_luo, ashley and other models for electrons |
| [readBetaSpectrum.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/readBetaSpectrum.ipynb) | **Beta spectra**: reading and visualising deposited-energy spectra from BetaShape + MCNP calculations |
| [interaction.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/interaction.ipynb) | **Radiation–matter interactions**: photon and electron energy deposition via MCNP response matrices |

### Advanced / experimental

| Notebook | Description |
| :--- | :--- |
| [mixture.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/mixture.ipynb) | **Radionuclide mixtures**: efficiency of arbitrary multi-component samples with `pmf_1` fractions |
| [efficiencyCuve.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/efficiencyCuve.ipynb) | **Efficiency curve (quench curve)**: eff_D and eff_T vs light yield L for a series of kB values |
| [distrubutionTDCR.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/distrubutionTDCR.ipynb) | **TDCR distribution**: histogram of per-event efficiency values over MC trials; statistical characterisation |
| [dynamicDecay.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/dynamicDecay.ipynb) | **Dynamic efficiency**: time-dependent efficiency during daughter-nuclide ingrowth (requires `radioactivedecay`) |

### Validation

| Notebook | Description |
| :--- | :--- |
| [functional_validation.ipynb](https://github.com/RomainCoulon/TDCRPy/blob/main/notebooks/functional_validation.ipynb) | **Cross-version validation**: compare two TDCRPy versions side-by-side for H-3, Fe-55, Co-60, Sr-90, Cd-109 across analytical and stochastic models; configurable `VERSION_REF` / `VERSION_NEW` |

---

## 📚 Citation

If you use **TDCRPy** in your work, please cite:

> R. Coulon, J. Hu — **TDCRPy: A Python package for TDCR measurements**  
> *Applied Radiation and Isotopes* (2024)  
> DOI: [10.1016/j.apradiso.2024.111518](https://doi.org/10.1016/j.apradiso.2024.111518)

---

## ⚖️ License

This project is licensed under the **MIT License**.  
Copyright © BIPM (Bureau International des Poids et Mesures).
