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.14.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.14-py3-none-any.whl (23.5 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: tdcrpy-2.20.14.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.14.tar.gz
Algorithm Hash digest
SHA256 90e6b3a73e2eafac2700662322f6c1b2f5147e19e272b7c34a30d8dc8cb02e2b
MD5 513a1919e0d1771b4130b0efd8248ac8
BLAKE2b-256 ef49986fdbf3ce16342debdec37b22eb981128a5128f36f1a2bde4d8049c87b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for tdcrpy-2.20.14.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.14-py3-none-any.whl.

File metadata

  • Download URL: tdcrpy-2.20.14-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.14-py3-none-any.whl
Algorithm Hash digest
SHA256 64d513746fc1b2844adac2aae8eda1ac360f9020048ea7f16039dfaf7c01c0a5
MD5 ef45a7a4dd56e56e2599d76e8d671d95
BLAKE2b-256 6a30b9259fbfdaa082e6923d26706e1ab42ff2b13a136fb944a68197a6e9d096

See more details on using hashes here.

Provenance

The following attestation bundles were made for tdcrpy-2.20.14-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

2.20.15

2 files

This release

2.20.14 This release

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