Calibration

class curie.Calibration(filename=None)[source]

Calibration for HPGe spectra

Provides methods for calculating and fitting energy, efficiency and resolution calibrations for HPGe spectra. Each Spectrum class contains a Calibration, which can be loaded from a file, or fit to calibration spectra from known sources.

Parameters:
filenamestr, optional

Path to a .json file storing calibration data. The .json file can be produced by calling cb.saveas('example_calib.json') after performing a calibration fit with the cb.calibrate() function. This allows past calibrations to be recalled without needing to re-perform the calibration fits.

Attributes:
engcalnp.ndarray

Energy calibration parameters. length 2, 3 or 4 array, depending on whether the calibration is linear, quadratic or cubic.

effcalnp.ndarray

Efficiency calibration parameters, for the semi-empirical efficiency model (see the eff method). Length 5 array, or length 7 if the two low-energy attenuation terms (detector window and dead layer) are included; for the ‘loglog’ model, the polynomial coefficients of ln(eff) in powers of ln(E).

unc_effcalnp.ndarray

Efficiency calibration covariance matrix, of the same dimension as effcal (5x5 or 7x7 for the Vidmar models).

rescalnp.ndarray

Resolution calibration parameters. length 2 array if resolution calibration is of the form R = a + b*chan (default), length 1 if R = a*sqrt(chan), or length 3 if R = sqrt(a + b*chan + c*chan^2).

fit_configdict

Calibration-fit configuration (see the class Attributes and calibrate)

Methods

calibrate(spectra, sources[, eff_points])

Generate calibration parameters from spectra

eff(energy[, effcal, model])

Efficiency calibration function

eng(channel[, engcal, model])

Energy calibration function

map_channel(energy[, engcal])

Energy to channel calibration

plot(**kwargs)

Plots energy, resolution and efficiency calibrations

plot_effcal(**kwargs)

Plot the efficiency calibration

plot_engcal(**kwargs)

Plot the energy calibration

plot_rescal(**kwargs)

Plot the resolution calibration

res(channel[, rescal, model])

Resolution calibration

saveas(filename)

Save the calibration as a .json file

unc_eff(energy[, effcal, unc_effcal, model])

Uncertainty in the efficiency

Examples

>>> cb = Calibration()
>>> print(cb.engcal)
[0.  0.3]
>>> cb.engcal = [0.1, 0.2, 0.003]
>>> print(cb.engcal)
[0.1   0.2   0.003]
>>> cb.saveas('test_calib.json')
>>> cb = Calibration('test_calib.json')
>>> print(cb.engcal)
[0.1   0.2   0.003]
calibrate(spectra, sources, eff_points=None, **kwargs)[source]

Generate calibration parameters from spectra

Performs an energy, resolution and efficiency calibration on peak fits to a given list of spectra. Reference activities must be given for the efficiency calibration. Spectra are allowed to have isotopes that are not in sources, but these will not be included in the efficiency calibration.

Keyword arguments other than eff_points are fit_config keys: they merge into cb.fit_config and persist for subsequent calibrations.

Parameters:
spectralist of sp.Spectrum

List of calibration spectra. Must have sp.isotopes defined, and matching the isotopes given in sources.

sourcesstr, list, dict or pd.DataFrame

Datatype or (if str) file that can be converted into a pandas DataFrame. Required keys are ‘isotope’, ‘A0’ (reference activity), and ‘ref_date’ (reference date).

eff_pointspd.DataFrame, optional

User-supplied efficiency points appended to the measured points before the efficiency fit: columns energy (keV), efficiency, unc_efficiency, and optionally isotope. The public form of efficiency-extrapolation and multi-geometry merges. Their uncertainties are treated as independent.

engcal_modelstr, optional

‘linear’, ‘quadratic’ or ‘cubic’. Default None: the model is inferred from the current calibration’s parameter length.

rescal_modelstr, optional

‘sqrt’ (a*sqrt(ch)), ‘linear’ (a + b*ch) or ‘sqrt_quad’ (sqrt(a + b*ch + c*ch^2)). Default None: inferred by length.

effcal_modelstr, optional

‘vidmar’ (the 5/7-parameter automatic choice, the default behavior), ‘vidmar-5’, ‘vidmar-7’, or a polynomial of ln(eff) in ln(E): ‘loglog’ (order 4) or ‘loglog-2’ through ‘loglog-8’ for an explicit order. Default None = ‘vidmar’.

engcal_max_errorfloat, optional

Pre-fit cut: drop energy-calibration points whose relative uncertainty exceeds this. Default 0.25.

rescal_max_errorfloat, optional

As above, for resolution points. Default 0.33.

effcal_max_errorfloat, optional

As above, for efficiency points. Default 0.33.

outlier_sigmafloat, optional

Post-fit residual threshold, in sigma, above which a point is clipped from the stored calibration points (it stays visible in the *_data tables and plots). Default sqrt(10), about 3.16.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.7E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> print(cb.effcal)
[4.78771190e-02 9.99910335e+01 2.10108097e+00 1.90374157e+00
 3.95525964e-01]
>>> cb.plot()
property diagnostics

Fit diagnostics from the most recent calibration

Read-only pd.DataFrame with one row per calibration sub-fit (fit is ‘engcal’, ‘rescal’ or ‘effcal’) and columns chi2 (reduced, over all n_points that entered the fit - flagged outliers included), dof, n_points (points the fit used), n_dropped (pre-fit drops plus post-fit outlier clips; clipping affects the stored points, not the fit), converged, model, scale_factor (uncertainty inflation applied; 1.0 = none), flags (comma-joined, e.g. ‘chi2_high’, ‘at_bound:l’) and message (the associated summary text). Empty (with the full schema) before any calibration has been performed; rebuilt on each calibrate() call. Accessing it never triggers a fit.

eff(energy, effcal=None, model=None)[source]

Efficiency calibration function

Returns the calculated (absolute) efficiency given an input array of energies. The effcal can be supplied, or if effcal=None, the calibration object’s internal efficiency calibration (cb.effcal) is used.

The functional form of the efficiency used is a modified version of the semi-empirical formula proposed by Vidmar (2001): eff(E) = c[0]*(1.0-exp(-mu(eng)*c[1]))*(tau(eng)+sigma(eng)*(1.0-exp(-(mu(eng)*c[3])**c[2]))*c[4])/mu(eng) if the effcal is length 5 or eff(E) = c[0]*exp(-mu_w(eng)*c[5])*exp(-mu(eng)*c[6])*(1.0-exp(-mu(eng)*c[1]))*(tau(eng)+sigma(eng)*(1.0-exp(-(mu(eng)*c[3])**c[2]))*c[4])/mu(eng) if the effcal is length 7.

Parameters:
energyarray_like

Peak energy in keV.

effcalarray_like, optional

Efficiency calibration parameters. length 5 or 7 array, depending on whether the efficiency fit includes the low-energy components; for the ‘loglog’ model, the polynomial coefficients of ln(eff) in powers of ln(E).

modelstr, optional

Efficiency model: ‘vidmar-5’, ‘vidmar-7’ or ‘loglog’. Default None: the calibration’s own model tag if effcal is not given, else inferred from the parameter length (5 or 7 = Vidmar). A loglog parameter array can be the same length as a Vidmar one, so explicitly supplied loglog parameters require model='loglog'.

Returns:
efficiencynp.ndarray

Absolute efficiency at the given energies.

Examples

>>> cb = ci.Calibration()
>>> print(cb.effcal)
[1.87867638e-02 8.82671055e+01 2.09673703e+00 1.66193806e+00
 3.90089610e-01 3.79361265e+00 1.24058591e-02]
>>> print(cb.eff(50*np.arange(1,10)))
[0.00469671 0.00553412 0.00502548 0.00436836 0.00369016 0.00315241
 0.002754   0.00245546 0.00222482]
property effcal_data

Efficiency-calibration points from the most recent calibration

Read-only pd.DataFrame with one row per measured point, including the points the fit rejected: columns energy, efficiency, unc_efficiency, isotope (source provenance - which isotope the point came from, derived from the stored line label; ‘’ for calibrations saved before it was recorded), used (False for rejected points - outlier rows entered the fit but are clipped from the stored calibration points), reason (’’ when used, else ‘unc>33%’ or ‘outlier >3.16 sigma’) and residual (measured minus fitted efficiency). Empty (with the full schema) if no calibration data is present.

eng(channel, engcal=None, model=None)[source]

Energy calibration function

Returns the calculated energy given an input array of channel numbers. The engcal can be supplied, or if engcal=None the Calibration object’s energy calibration is used (cb.engcal).

Parameters:
channelarray_like

Spectrum channel number. The maximum channel number should be the length of the spectrum.

engcalarray_like, optional

Optional energy calibration. If a length 2 array, calibration will be engcal[0] + engcal[1]*channel. If length 3, then engcal[0] + engcal[1]*channel + engcal[2]*channel**2, and if length 4 the cubic polynomial continues the same pattern.

modelstr, optional

Energy calibration model: ‘linear’, ‘quadratic’ or ‘cubic’. Default None: the calibration’s own model tag if engcal is not given, else inferred from the parameter length.

Returns:
energy: np.ndarray

Calibrated energy corresponding to the given channels.

Examples

>>> cb = ci.Calibration()
>>> print(cb.engcal)
[0.  0.3]
>>> print(cb.eng(np.arange(10)))
[0.  0.3 0.6 0.9 1.2 1.5 1.8 2.1 2.4 2.7]
>>> cb.engcal = [0.1, 0.2, 0.003]
>>> print(cb.eng(np.arange(10)))
[0.1   0.303 0.512 0.727 0.948 1.175 1.408 1.647 1.892 2.143]
property engcal_data

Energy-calibration points from the most recent calibration

Read-only pd.DataFrame with one row per measured point, including the points the fit rejected: columns channel, energy, unc_channel, used (False for rejected points), reason (’’ when used, else e.g. ‘unc>25%’) and residual (measured minus fitted energy, keV). Empty (with the full schema) if no calibration data is present.

property fit_config

Calibration-fit configuration (see the class Attributes and calibrate)

map_channel(energy, engcal=None)[source]

Energy to channel calibration

Calculates the spectrum channel number corresponding to a given energy array. This should return the inverse of the energy calibration, but as an integer-type channel number.

Parameters:
energyarray_like

Peak energy in keV

engcalarray_like, optional

Energy calibration parameters. length 2, 3 or 4 array, depending on whether the calibration is linear, quadratic or cubic (the cubic is inverted numerically).

Returns:
channelnp.ndarray

Calculated channel number given the input energy array

Examples

>>> cb = ci.Calibration()
>>> print(cb.engcal)
[0.  0.3]
>>> print(cb.map_channel(300))
1000
>>> print(cb.eng(cb.map_channel(300)))
300.0
plot(**kwargs)[source]

Plots energy, resolution and efficiency calibrations

Draws all three of energy, resolution and efficiency calibrations on a single figure, and shows measured values from peak data, if available.

Other Parameters:
**kwargs

Optional keyword arguments for plotting. See the plotting section of the curie API for a complete list of kwargs.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.5E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> cb.plot()
plot_effcal(**kwargs)[source]

Plot the efficiency calibration

Draws the efficiency calibration, with measurements from peak fit data if available.

Other Parameters:
**kwargs

Optional keyword arguments for plotting. See the plotting section of the curie API for a complete list of kwargs.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.5E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> cb.plot_effcal()
plot_engcal(**kwargs)[source]

Plot the energy calibration

Draws the energy calibration, with measurements from peak fit data if available.

Other Parameters:
**kwargs

Optional keyword arguments for plotting. See the plotting section of the curie API for a complete list of kwargs.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.5E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> cb.plot_engcal()
plot_rescal(**kwargs)[source]

Plot the resolution calibration

Draws the resolution calibration, with measurements from peak fit data if available.

Other Parameters:
**kwargs

Optional keyword arguments for plotting. See the plotting section of the curie API for a complete list of kwargs.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.5E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> cb.plot_rescal()
res(channel, rescal=None, model=None)[source]

Resolution calibration

Calculates the expected 1-sigma peak widths for a given input array of channel numbers. If rescal is given, it is used instead of the calibration object’s internal value (cb.rescal).

Parameters:
channelarray_like

Spectrum channel number. The maximum channel number should be the length of the spectrum.

rescalarray_like, optional

Resolution calibration parameters. length 2 array if resolution calibration is of the form R = a + b*chan (default), length 1 if R = a*sqrt(chan), or length 3 if R = sqrt(a + b*chan + c*chan^2) (the ‘sqrt_quad’ model).

modelstr, optional

Resolution model: ‘sqrt’, ‘linear’ or ‘sqrt_quad’. Default None: the calibration’s own model tag if rescal is not given, else inferred from the parameter length.

Returns:
resolutionnp.ndarray

Calculated 1-sigma width of the peaks given the input channel numbers.

Examples

>>> cb = ci.Calibration()
>>> print(cb.rescal)
[2.e+00 4.e-04]
>>> print(cb.res(100*np.arange(1,10)))
[2.04 2.08 2.12 2.16 2.2  2.24 2.28 2.32 2.36]
property rescal_data

Resolution-calibration points from the most recent calibration

Read-only pd.DataFrame with one row per measured point, including the points the fit rejected: columns channel, width, unc_width, used (False for rejected points - outlier rows entered the fit but are clipped from the stored calibration points), reason (’’ when used, else ‘unc>33%’ or ‘outlier >3.16 sigma’) and residual (measured minus fitted width, channels). Empty (with the full schema) if no calibration data is present.

saveas(filename)[source]

Save the calibration as a .json file

Saves the energy, resolution and efficiency calibration to a .json file, which can be recalled by a new calibration object by passing the ‘filename’ keyword to Calibration() upon construction.

Parameters:
filenamestr

Complete filename to save the calibration. Must end in ‘.json’.

Examples

>>> sp = ci.Spectrum('eu_calib_7cm.Spe')
>>> sp.isotopes = ['152EU']
>>> cb = ci.Calibration()
>>> cb.calibrate([sp], sources=[{'isotope':'152EU', 'A0':3.7E4, 'ref_date':'01/01/2009 12:00:00'}])
>>> print(cb.effcal)
[4.78771190e-02 9.99910335e+01 2.10108097e+00 1.90374157e+00
 3.95525964e-01]
>>> cb.saveas('example_calib.json')
>>> cb = ci.Calibration('example_calib.json')
>>> print(cb.effcal)
[4.78771190e-02 9.99910335e+01 2.10108097e+00 1.90374157e+00
 3.95525964e-01]
unc_eff(energy, effcal=None, unc_effcal=None, model=None)[source]

Uncertainty in the efficiency

Returns the calculated uncertainty in efficiency for an input array of energies. If effcal or unc_effcal are not none, they are used instead of the calibration object’s internal values. (cb.unc_effcal) unc_effcal must be a covariance matrix of the same dimension as effcal.

Parameters:
energyarray_like

Peak energy in keV.

effcalarray_like, optional

Efficiency calibration parameters. length 5 or 7 array, depending on whether the efficiency fit includes the low-energy components; for the ‘loglog’ model, the polynomial coefficients of ln(eff) in powers of ln(E).

unc_effcalarray_like, optional

Efficiency calibration covariance matrix, of the same dimension as effcal (5x5 or 7x7 for the Vidmar models).

modelstr, optional

Efficiency model, as in eff (needed when explicitly supplied parameters are for the ‘loglog’ model).

Returns:
unc_efficiencynp.ndarray

Absolute uncertainty in efficiency for the given energies.

Examples

>>> cb = ci.Calibration()
>>> print(cb.eff(50*np.arange(1,10)))
[0.00469671 0.00553412 0.00502548 0.00436836 0.00369016 0.00315241
 0.002754   0.00245546 0.00222482]
>>> print(cb.unc_eff(50*np.arange(1,10)))
[1.84927072e-05 2.06720560e-05 4.00073148e-05 3.34061820e-05
 1.49979136e-05 1.05818602e-05 9.72833934e-06 8.95311822e-06
 8.10774373e-06]