3.1. Reaction How-to Guide
This page is a task-by-task reference for the Reaction and Library
classes. All examples assume import curie as ci. The library
descriptions and integration conventions are detailed in
Nuclear Reaction Data.
Getting a reaction
Reactions are written TARGET(incident,outgoing)PRODUCT. The target
and product take the same isotope names as everywhere in Curie (see
Isotope & Decay Chain How-to Guide), the incident particle is n, p or d
(plus a alpha, h helion — a 3He nucleus — and g
photon in the IAEA library), and the outgoing particle
is a shorthand like g, 2n, p, a, inl (inelastic),
f (fission) — or x, meaning “anything”: only the product is
specified:
rx = ci.Reaction('115IN(n,g)') # radiative capture
rx = ci.Reaction('Ra-226(n,2n)Ra-225')
rx = ci.Reaction('natTI(p,x)48V') # any route from natTi to 48V
A natural-abundance elemental target is written with the nat prefix
(natTI, natCU); this notation is specific to reaction targets —
it is not a valid Isotope name.
The product can be omitted when the outgoing particle determines it
('115IN(n,g)' is '115IN(n,g)116IN'), but is needed to select an
isomer — a longer-lived excited state of the product nucleus, written
with an m suffix ('115IN(n,inl)115INm1'). The data are attributes: rx.eng
(MeV), rx.xs (mb), rx.unc_xs (mb; zeros if the library provides
no uncertainties), and rx.TeX for plot labels.
How Curie picks the library
With the default library='best', Curie tries the libraries in a fixed
priority order and keeps the first one that carries the reaction:
Incident particle |
Priority order |
|---|---|
neutron |
IRDFF-II -> ENDF/B-VIII.1 -> IAEA -> TENDL-2025 -> TENDL-2025 (residual product) |
proton, deuteron, |
IAEA -> TENDL-2025 (residual product) |
alpha |
|
helion, photon |
IAEA |
The order reflects evaluation care: dosimetry and monitor standards first, general-purpose evaluations next, all-encompassing theoretical libraries last. Check which library was selected, and pin it explicitly when reproducibility matters (in a publication, name the library — ‘best’ can resolve differently as libraries are added or updated):
rx = ci.Reaction('90ZR(n,2n)')
print(rx.library.name) # IRDFF-II
rx = ci.Reaction('90ZR(n,2n)', 'endf')
Exclusive vs. residual-product libraries
The neutron libraries (ENDF, TENDL, IRDFF) are organized by exclusive
reaction channel — the outgoing particles are specified, as in
(n,2n). The residual-product libraries (the IAEA library, and the
TENDL tendl_n/tendl_p/tendl_d variants) are instead
organized by what nucleus is produced: the reaction is written (p,x)
and only the product matters, summing over every route to it (the full
library taxonomy is in Nuclear Reaction Data). This is why
proton reactions are written 'natTI(p,x)48V' rather than
'48TI(p,n)48V'.
In the TENDL residual-product libraries every product state is a
separate entry: 86SR(p,x)86Yg and 86SR(p,x)86Ym1 are different
reactions. If you give no isomer suffix, the ground state is
assumed (a warning prints, once per library instance).
Searching a library
When you don’t know the exact reaction name, search with any combination of target, incident/outgoing particle, and product:
>>> lb = ci.Library('tendl_p')
>>> print(lb.search(target='Sr-86', product='Y-86g'))
['86SR(p,x)86Yg']
>>> lb = ci.Library('endf')
>>> print(lb.search(target='226RA', outgoing='2n'))
['226RA(n,2n)225RA']
Searching by target alone lists everything the library evaluates for that nucleus — for ENDF that includes totals, elastic scattering and level-by-level inelastic channels, not just activation products.
Library names are 'endf', 'tendl', 'irdff', 'iaea', and
'tendl_n'/'tendl_p'/'tendl_d'/'tendl_a' for the
residual-product libraries. search returns reaction names ready to pass to
Reaction.
Values on your energy grid
rx.interpolate(energy) evaluates the cross section wherever you need
it, and rx.interpolate_unc(energy) its uncertainty:
rx = ci.Reaction('115IN(n,g)', 'irdff')
print(rx.interpolate([0.5, 1.0, 5.0])) # mb, at 0.5, 1 and 5 MeV
Interpolation is linear for the pointwise-linearized libraries and monotone PCHIP in sqrt(E)-sqrt(sigma) space for the smooth TENDL curves (exact through the evaluated points, no overshoot at thresholds); either scheme can be selected per reaction:
rx.interpolate(energy, interpolation='linear') # kept for later calls
rx.interp_config = {'interpolation': 'pchip-sqrt'}
One
convention to know: outside the library’s evaluated energy range the
interpolated cross section is zero — Curie never extrapolates. Check
rx.eng.min() and rx.eng.max() when working near the edges of a
library’s grid; the consequences for flux averages are shown in the
Reactions Worked Examples.
Flux averages and integrals
For an activation measurement, the effective cross section is the
flux-weighted average over the particle spectrum. Give average()
your energy grid and the flux on that grid:
import numpy as np
rx = ci.Reaction('90ZR(n,2n)', 'irdff') # a threshold reaction
eng = np.linspace(10, 30, 50)
phi = np.exp(-0.5*((eng - 20)/3.5)**2) # any relative shape
print(rx.average(eng, phi))
print(rx.average(eng, phi, unc=True)) # (value, uncertainty)
The flux needs no normalization — only its shape matters for the
average. rx.integrate(eng, phi) returns the flux integral
\(\int \sigma(E)\,\phi(E)\,dE\) instead, for which the flux’s
absolute normalization does matter (which to use when, and how each
becomes a production rate, is laid out on the Reactions overview
page). Cross-section uncertainties are treated as fully correlated
between energies — see Nuclear Reaction Data for the exact
conventions.
Plotting
rx.plot() shows the cross section over its full grid, with an
uncertainty band when the library provides one. Overlay reactions or
libraries by passing figure and axes through:
rx = ci.Reaction('90ZR(n,2n)', 'irdff')
f, ax = rx.plot(return_plot=True, label='library')
rx = ci.Reaction('90ZR(n,2n)', 'endf')
rx.plot(f=f, ax=ax, label='library')
label can be 'reaction', 'library' or 'both'; pass
energy= to plot on your own grid; scale='loglog' sets the axes
(the full list of scale options is on the Plotting page).