Skip to content

Detector Calibration

Chris Kuethe edited this page Aug 20, 2023 · 3 revisions

Calibration establishes a relationship between analog-to-digital converter readings and real-world quantities. There are a number of factors that influence the measurment: photon energy, photon trajectory, scintillator efficiency, optical path inside the scintillation medium, photomultipler efficiency at the scintillation wavelength, photomultiplier dark current, photomultiplier gain, ADC resolution, temperature ... By measuring a variety of sources it is possible to compute a model that can reasonably accurately convert a large number of 526 into "potassium-40!" (for example)

Create the calibration file

calibrate.py -W will create an example calibration file. It contains some suggested elements and easily detected emission peaks. There is an intentional error ("unobtanium") in the template to prevent it from being used without at least a cursory look

{
  "unobtainium": "Remove this line after filling in actual calibration measurements. The channel mapping below is a rough (aka. wrong) linear model...",
  "americium": [
    { "energy": 26, "channel": 9 },
    { "energy": 60, "channel": 21 }
  ],
  "barium": [
    { "energy": 80, "channel": 28 },
    { "energy": 166, "channel": 59 },
    { "energy": 303, "channel": 109 },
    { "energy": 356, "channel": 128 }
  ],
  "europium": [
    { "energy": 40, "channel": 14 },
    { "energy": 122, "channel": 44 },
    { "energy": 245, "channel": 88 },
    { "energy": 344, "channel": 124 },
    { "energy": 1098, "channel": 395 },
    { "energy": 1408, "channel": 507 }
  ],
  "potassium": [
    { "energy": 1461, "channel": 526 }
  ],
  "radium": [
    { "energy": 295, "channel": 106 },
    { "energy": 352, "channel": 126 },
    { "energy": 609, "channel": 219 },
    { "energy": 1120, "channel": 403 },
    { "energy": 1765, "channel": 635 },
    { "energy": 2204, "channel": 793 }
  ],
  "sodium": [
    { "energy": 511, "channel": 184 },
    { "energy": 1275, "channel": 459 }
  ],
  "thorium": [
    { "energy": 338, "channel": 121 },
    { "energy": 583, "channel": 210 },
    { "energy": 911, "channel": 328 },
    { "energy": 1588, "channel": 572 },
    { "energy": 2614, "channel": 941 }
  ]
}

Edit the calibration

Remove the unobtainium, save the file, and compute the initial calibration factors

{
  "americium": [
    { "energy": 26, "channel": 9 },
    { "energy": 60, "channel": 21 }
  ],
  "barium": [
    { "energy": 80, "channel": 28 },
    { "energy": 166, "channel": 59 },
    { "energy": 303, "channel": 109 },
    { "energy": 356, "channel": 128 }
  ],
  "europium": [
    { "energy": 40, "channel": 14 },
    { "energy": 122, "channel": 44 },
    { "energy": 245, "channel": 88 },
    { "energy": 344, "channel": 124 },
    { "energy": 1098, "channel": 395 },
    { "energy": 1408, "channel": 507 }
  ],
  "potassium": [
    { "energy": 1461, "channel": 526 }
  ],
  "radium": [
    { "energy": 295, "channel": 106 },
    { "energy": 352, "channel": 126 },
    { "energy": 609, "channel": 219 },
    { "energy": 1120, "channel": 403 },
    { "energy": 1765, "channel": 635 },
    { "energy": 2204, "channel": 793 }
  ],
  "sodium": [
    { "energy": 511, "channel": 184 },
    { "energy": 1275, "channel": 459 }
  ],
  "thorium": [
    { "energy": 338, "channel": 121 },
    { "energy": 583, "channel": 210 },
    { "energy": 911, "channel": 328 },
    { "energy": 1588, "channel": 572 },
    { "energy": 2614, "channel": 941 }
  ]
}

This produces an incorrect, but nice looking set of calibration factors.

$ ./calibrate.py
data range: (9, 26) - (941, 2614)
x^0 .. x^2: [1.26860787, 2.77308657, 4.45e-06]
R^2: 1.00000

Gather some data

Below are some spectra from a few easily obtained sources, along with one industrial source. Simply record enough data to get a clean peak, then measure the channel with the highest energy near the expected energy.

From the calibration sources, the following measurements were made:

Isotope Energy (keV) channel
Am-241 26 10
Am-241 60 28
K-40 1461 551
Th-232 338 138
Th-232 583 234
Th-232 911 362
Th-232 1588 597
Th-232 2614 936
Na-22 511 207
Na-22 1275 488

These measurements are translated into the following calibration file:

{
  "americium": [
    { "energy": 26, "channel": 10 },
    { "energy": 60, "channel": 28 }
  ],
  "potassium": [
    { "energy": 1461, "channel": 526 }
  ],
  "sodium": [
    { "energy": 511, "channel": 184 },
    { "energy": 1275, "channel": 459 }
  ],
  "thorium": [
    { "energy": 338, "channel": 121 },
    { "energy": 583, "channel": 210 },
    { "energy": 911, "channel": 328 },
    { "energy": 1588, "channel": 572 },
    { "energy": 2614, "channel": 941 }
  ]
}

Generate a calibration

$ ./calibrate.py
data range: (10, 26) - (941, 2614)
x^0 .. x^2: [-6.84097897, 2.80495935, -2.238e-05]
R^2: 0.99996

And apply this calibration to the detector with Device Settings > Calibration coefficients in the app.

calibrate

The detector is now calibrated.

Clone this wiki locally