Skip to main content

TDCRPy

TDCRPy Logo

A Photo-Physical Stochastic Model for Liquid Scintillation Counting

License Python Version Status BIPM


📖 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).
  • Full optical Monte Carlo transport (opticalTransport=True).
  • C/N (CIEMAT/NIST) 2-PMT efficiency curves.

Technical details are described in:


📦 Installation

TDCRPy requires Python ≥ 3.11 and a standard scientific environment.

pip install TDCRPy

To upgrade to the latest version:

pip install TDCRPy --upgrade

Run Tests

Verify the installation by running the unit tests:

python -m unittest tdcrpy.test.test_tdcrpy

⚡ Quick Start

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

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

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:

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:

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:

# 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):

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

C/N Efficiency Curve

Compute the CIEMAT/NIST efficiency curve — detection efficiency as a function of the free parameter L for a 2-PMT coincidence system:

import numpy as np
import matplotlib.pyplot as plt
import tdcrpy.TDCR_model_lib as tl

rad = "H-3"
kB  = 1e-5   # Birks constant (cm keV⁻¹)
V   = 10     # volume (mL)
ne  = 1000   # quenching integration bins

L_vec = np.linspace(1, 20, 80)
eff_D = np.array([tl.modelAnalyticalCN(L, rad, kB, V, ne)[2] for L in L_vec])

plt.plot(L_vec, eff_D)
plt.xlabel("L (photons keV⁻¹)")
plt.ylabel("eff_D (double coincidence)")
plt.title(f"C/N efficiency curve — {rad}")
plt.grid(True)
plt.show()

To find L from a measured C/N counting ratio CN (counts_D / counts_S):

from scipy.optimize import brentq

CN_meas = 0.62   # measured D/S ratio

def residual(L):
    eA, eB, eD = tl.modelAnalyticalCN(L, rad, kB, V, ne)
    return eD / ((eA + eB) / 2) - CN_meas

L0 = brentq(residual, 0.5, 30)
_, _, eff_D = tl.modelAnalyticalCN(L0, rad, kB, V, ne)
print(f"L = {L0:.3f} photons/keV,  eff_D = {eff_D:.5f}")

⚙️ Configuration & Physics

Display the current physics settings:

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

Notebooks are organised in subfolders by topic under notebooks/.

Getting started — notebooks/getting_started/

Notebook Description
tuturial.ipynb End-to-end tutorial: fixed-L efficiencies, TDCR fitting (symmetric and asymmetric), radionuclide mixtures, full optical MC transport
changeParameters.ipynb Configuration: how to modify every physics parameter (quenching bins, stopping power model, cocktail, PMT efficiencies, dead time…)

Detection models — notebooks/models/

Notebook Description
analyticalModel.ipynb Analytical model (effA): fast beta-spectrum-based efficiency for pure β emitters; symmetric and asymmetric PMT configurations
CNmethod.ipynb CIEMAT/NIST (C/N) method: 2-PMT coincidence efficiency curve using modelAnalyticalCN; L-fitting from measured C/N ratio
cerenkovModel.ipynb Čerenkov counting model: Frank-Tamm-based efficiency for high-energy beta emitters
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 — notebooks/nuclides/

Notebook Description
H-3.ipynb Tritium (H-3): low-energy pure β; analytical and stochastic efficiency, micelle correction effect
Co-60.ipynb Co-60: γ-emitter with complex decay; analytical approximation vs full stochastic model
Fe-55.ipynb Fe-55: electron-capture nuclide producing Mn K-α X-rays and Auger electrons
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 Zr-93: β/EC branching ratio nuclide with X-ray emission

Physics sub-models — notebooks/physics/

Notebook Description
quenchingModel.ipynb Birks quenching: quenched energy vs initial energy for electrons and α particles as a function of kB
stoppingPower.ipynb Stopping power models: comparison of tan_xia, joy_luo, ashley and other models for electrons
readBetaSpectrum.ipynb Beta spectra: reading and visualising deposited-energy spectra from BetaShape + MCNP calculations
interaction.ipynb Radiation–matter interactions: photon and electron energy deposition via MCNP response matrices

Advanced — notebooks/advanced/

Notebook Description
mixture.ipynb Radionuclide mixtures: efficiency of arbitrary multi-component samples with activity fractions
efficiencyCuve.ipynb TDCR efficiency curve: eff_D and eff_T vs light yield L for a series of kB values
distrubutionTDCR.ipynb TDCR distribution: histogram of per-event efficiency values over MC trials; statistical characterisation
cocktailComposition.ipynb Cocktail composition: effect of aqueous fraction (H₂O / HCl) on detection efficiency for H-3 and Sr-90
cocktailResponse.ipynb Cocktail comparison: eff_D for 12 commercial LS cocktails × 6 nuclides (H-3, C-14, Fe-55, Cr-51, Co-60, Cd-109)

Sensitivity — notebooks/sensitivity/

Notebook Description
parameterSensitivity.ipynb Parameter sensitivity study: sweeps every tunable model parameter (L, kB, PMT quantum efficiency, cocktail composition, stopping-power model, quenching numerics, micelle correction, counting-chain parameters, optical transport, MC convergence) around its nominal value for H-3 and Sr-90, with a summary tornado chart

Validation — notebooks/validation/

Notebook Description
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


⚖️ License

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

Download files

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

Source Distribution

tdcrpy-2.20.15.tar.gz (22.5 MB view details)

Uploaded Source

Built Distribution

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

tdcrpy-2.20.15-py3-none-any.whl (23.5 MB view details)

Uploaded Python 3

File details

Details for the file tdcrpy-2.20.15.tar.gz.

File metadata

  • Download URL: tdcrpy-2.20.15.tar.gz
  • Upload date:
  • Size: 22.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tdcrpy-2.20.15.tar.gz
Algorithm Hash digest
SHA256 4e8d3dac1feb9d03132662ef5ae28357d75bfd591322825a1cc039c5414459d7
MD5 3bfa7b494a89b2de4ab6c6aad46a7185
BLAKE2b-256 715974748b4edc21d02d98cd6639b6b36620ebb4e4315f905f10f0b9edb4b4f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tdcrpy-2.20.15.tar.gz:

Publisher: python-publish.yml on RomainCoulon/TDCRPy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tdcrpy-2.20.15-py3-none-any.whl.

File metadata

  • Download URL: tdcrpy-2.20.15-py3-none-any.whl
  • Upload date:
  • Size: 23.5 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tdcrpy-2.20.15-py3-none-any.whl
Algorithm Hash digest
SHA256 279edfcc698ef3fed4599687567e860ea6dcc7750df21a718c81acb6c6199a3b
MD5 bc365585eabbea5ea2b1420299fd9b17
BLAKE2b-256 a6936c5f9743891839bf4521761efaf760a342782255dcd0146c1f906c3d1018

See more details on using hashes here.

Provenance

The following attestation bundles were made for tdcrpy-2.20.15-py3-none-any.whl:

Publisher: python-publish.yml on RomainCoulon/TDCRPy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

2.20.16

2 files

This release

2.20.15 This release

2 files

2.20.14

2 files

2.20.13

2 files

2.20.12

2 files

2.20.11

2 files

2.20.10

2 files

2.20.9

2 files

2.20.8

2 files

2.20.7

2 files

2.20.6

2 files

2.20.5

2 files

2.20.3

2 files

2.20.2

2 files

2.20.0

2 files

2.19.3

2 files

2.19.2

2 files

2.19.1

2 files

2.19.0

2 files

2.18.3

2 files

2.18.2

2 files

2.18.1

2 files

2.18.0

2 files

2.17.9

2 files

2.17.8

2 files

2.17.7

2 files

2.17.6

2 files

2.17.5

2 files

2.17.4

2 files

2.17.3

2 files

2.17.2

2 files

2.17.1

2 files

2.17.0

2 files

2.16.18

2 files

2.16.17

2 files

2.16.16

2 files

2.16.15

2 files

2.16.14

2 files

2.16.13

2 files

2.16.12

2 files

2.16.11

2 files

2.16.10

2 files

2.16.9

2 files

2.16.8

2 files

2.16.7

2 files

2.16.6

2 files

2.16.5

2 files

2.16.4

2 files

2.16.3

2 files

2.16.2

2 files

2.15.13

2 files

2.15.12

2 files

2.15.11

2 files

2.15.10

2 files

2.15.9

2 files

2.15.8

2 files

2.15.7

2 files

2.15.6

2 files

2.15.5

2 files

2.15.4

2 files

2.15.3

2 files

2.15.2

2 files

2.15.1

2 files

2.15.0

2 files

2.14.0

2 files

2.13.0

2 files

2.12.13

2 files

2.11.0

2 files

2.9.0

2 files

2.8.0

2 files

2.7.0

2 files

2.6.0

2 files

2.5.0

2 files

2.4.0

2 files

2.2.0

2 files

2.1.0

2 files

2.0.9

2 files

2.0.8

2 files

2.0.7

2 files

2.0.5

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.13.1

2 files

1.13.0

2 files

1.12.15

2 files

1.12.14

2 files

1.12.13

2 files

1.12.12

2 files

1.12.11

2 files

1.12.10

2 files

1.12.9

2 files

1.12.8

2 files

1.12.6

2 files

1.12.5

2 files

1.12.4

2 files

1.12.2

2 files

1.12.1

2 files

1.11.5

2 files

1.11.4

2 files

1.11.3

2 files

1.11.2

2 files

1.11.1

2 files

1.10.0

2 files

1.9.9

2 files

1.9.8

2 files

1.9.7

2 files

1.9.6

2 files

1.9.5

2 files

1.9.4

2 files

1.9.3

2 files

1.9.2

2 files

1.9.1

2 files

1.9.0

2 files

1.8.17

2 files

1.8.16

2 files

1.8.15

2 files

1.8.14

2 files

1.8.12

2 files

1.8.11

2 files

1.8.10

2 files

1.8.9

2 files

1.8.8

2 files

1.8.7

2 files

1.8.5

2 files

1.8.4

2 files

1.8.3

2 files

1.8.1

2 files

1.8.0

2 files

1.7.4

2 files

1.7.3

2 files

1.7.2

2 files

1.7.1

2 files

1.7.0

2 files

1.6.3

2 files

1.6.2

2 files

1.6.1

2 files

1.6.0

2 files

1.5.14

2 files

1.5.13

2 files

1.5.12

2 files

1.5.11

2 files

1.5.10

2 files

1.5.9

2 files

1.5.8

2 files

1.5.7

2 files

1.5.6

2 files

1.5.5

2 files

1.5.4

2 files

1.5.3

2 files

1.5.2

2 files

1.5.1

2 files

1.5.0

2 files

1.4.0

2 files

1.3.0

2 files

1.2.0

2 files

1.1.6

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.1

2 files

1.0.0

2 files

0.0.78

2 files

0.0.77

2 files

0.0.76

2 files

0.0.75

2 files

0.0.74

2 files

0.0.73

2 files

0.0.72

2 files

0.0.71

2 files

0.0.70

2 files

0.0.69

2 files

0.0.68

2 files

0.0.67

2 files

0.0.66

2 files

0.0.65

2 files

0.0.64

2 files

0.0.63

2 files

0.0.62

2 files

0.0.61

2 files

0.0.60

2 files

0.0.59

2 files

0.0.58

2 files

0.0.57

2 files

0.0.56

2 files

0.0.54

2 files

0.0.53

2 files

0.0.52

1 file

0.0.51

2 files

0.0.50

2 files

0.0.48

2 files

0.0.47

2 files

0.0.46

2 files

0.0.45

2 files

0.0.44

2 files

0.0.43

2 files

0.0.42

2 files

0.0.41

2 files

0.0.40

2 files

0.0.39

2 files

0.0.38

2 files

0.0.37

2 files

0.0.36

2 files

0.0.34

2 files

0.0.33

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

0.0.29

2 files

0.0.28

2 files

0.0.27

2 files

0.0.26

2 files

0.0.25

2 files

0.0.24

2 files

0.0.23

2 files

0.0.22

2 files

0.0.21

2 files

0.0.20

2 files

0.0.19

2 files

0.0.18

2 files

0.0.16

2 files

0.0.15

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page