Just some things for working with my RadiaCode devices from Scan-Electronics.
If you're planning on generating gps-tagged logs with a headless sensor, you might also want to look at my web console for gpsd.
$ git clone https://github.com/ckuethe/radiacode-tools
$ cd radiacode-tools
$ python -m venv venv
$ . venv/bin/activate
$ pip install -e .
Some convenience scripts will be installed along with the python code,
eg. rccalibrate
to go along with calibrate.py
.
This tool computes calibration factors for mapping the channel to detected photon energy.
Use calibrate.py -W
to generate a example calibration file, then use your
detector to measure a range of photon energies.
usage: calibrate.py [-h] [-z] [-f FILE] [-o N] [-p N] [-W]
options:
-h, --help show this help message and exit
-z, --zero-start Add a synthetic (0,0) calibration data point
-f FILE, --cal-file FILE Calibration data file [radiacode.json]
-o N, --order N Calibration polynomial order [2]
-p N, --precision N Number of decimal places in calibration factors [8]
-W, --write-template Generate a template calibration file
Calibration can be performed with a single sample (Th-232, Ra-226), though better results may be obtained using more isotopes with a broader range of energies.
# data derived from americium, barium, europium, potassium, radium, sodium, and thorium.
$ ./calibrate.py
data range: (9, 26) - (941, 2614)
x^0 .. x^2: [-7.26773237, 2.44338618, 0.00037684]
R^2: 0.99988
# Same data as above, but with a synthetic (0,0) data point
$ ./calibrate.py -z
data range: (0, 0) - (941, 2614)
x^0 .. x^2: [-6.28323127, 2.43830549, 0.00038176]
R^2: 0.99988
# Single source calibration using thoriated tungsten welding electrodes
$ ./calibrate.py -f thorium.json
data range: (138, 338) - (941, 2614)
x^0 .. x^2: [-15.63118352, 2.47761651, 0.00033984]
R^2: 0.99988
# Single source calibration using a luminous radium paint
$ ./calibrate.py -f radium.json
data range: (122, 295) - (802, 2204)
x^0 .. x^2: [-2.45705927, 2.39432185, 0.00044401]
R^2: 0.99998
This tool converts a RadiaCode ("RC") spectrum XML file into ANSI N42 format for analysis with other tools such as InterSpec. For my main use case - InterSpec interoperability - this tool has been somewhat superseded by [sandialabs/SpecUtils#15], but not everyone will be able to update their copy of InterSpec, and there are other tools for gamma spectroscopy so it's not completely useless.
usage: n42convert.py [-h] -i NAME [-b NAME] [-o NAME | -r] [--overwrite] [-u UUID]
options:
-h, --help show this help message and exit
-i NAME, --input NAME primary source data file
-b NAME, --background NAME Retrieve background from this file, using the background series if it exists or the main series otherwise.
-o NAME, --output NAME [<foreground>.n42]
-r, --recursive if given, treat the input path as a directory to process recursively with autogenerated output names
--overwrite allow existing file to be overwritten
-u UUID, --uuid UUID specify a UUID for the generated document. [<random>]
Only a single -i
or --input
argument is required. This will convert the
contents of an RC spectrum file into an N42 file named similarly to the source file.
If the RC file contains an included background spectrum it will be included in the
output.
If the -r
or --recursive
argument is given, the input argument is treated as a
directory to traverse looking for RC files to be converted. This argument causes
the background argument to be ignored, and is mutually exclusive with the output
argument; output file name will be generated from each input filename.
In cases where two separate spectra have been recorded, they can be combined to form a recording with included background. Consider a basement lab with a smoke detector; the background radiation may be influenced by the concrete foundation made with an aggregate containing a relatively large amount of thorium and uranium, there may be elevated levels of radon due to poor ventilation, and the smoke detector contains an americium source.
A recording of this ambient radiation can be saved as lab.xml
.
When a new sample arrives, perhaps a container of sodium-free salt substitute (KCl
)
or a crate of bananas for scale, it is measured in the same location as the lab
reference measurement, and the recording may be saved as k40.xml
. These two files
may be merged by running n42convert.py -f k40.xml -b lab.xml -o banana.n42
.
If the background RC file has both foreground and background spectra, the background spectrum will be copied into the output N42 file. If no background spectrum exists, the foreground data from the background file will be copied into the output N42 file.
usage: n42validate.py [-h] [-r] [-q] [-v] [-V] [-s XSD] [-u URL] [-x EXT] FILE [FILE ...]
positional arguments:
FILE source data file
options:
-h, --help show this help message and exit
-r, --recursive treat the input path as a directory to process recursively [False]
-q, --quiet don't display the invalid XML element
-v, --verbose display valid files too, by default only invalid files are reported
-V, --valid-only only display valid files
-s XSD, --schema-file XSD Default: ~/.cache/n42.xsd
-u URL, --schema-url URL Default: https://www.nist.gov/document/n42xsd
-x EXT, --extension EXT Default: .n42
Some programs are more tolerant than others when processing potentially invalid N42 inputs. This utility can be used to check data file compliance with the N42 specification. Output can be constrained to valid or invalid files only, with optional detailed information about which elements of the file are incorrect.
usage: n42www.py [-h] [-b IP] [-m NUM] [-p PORT] [-v]
options:
-h, --help show this help message and exit
-b IP, --bind-addr IP IP address on which to listen [127.0.0.1]
-m NUM, --max-size NUM Maximum upload file size in bytes [131072]
-p PORT, --port PORT Port on which to listen [6853]
-v, --verbose increase verbosity for debugging
This program is a simple web server which allows an RC XML file to be POST
ed
to its /convert
endpoint, returning an N42 file. This enables radiation analysis
to be conducted using just an RC detector, and a phone or tablet running the
RadiaCode
and
InterSpec
apps.
Configuring a reverse proxy and WSGI
server for safe deployment of this server
is beyond the scope of this document.
usage: radiacode_poll.py [-h] [-b MAC] [--accumulate | --accumulate-time TIME | --accumulate-dose DOSE] [--bgsub] [--reset-spectrum] [--reset-dose] [outfile]
options:
-h, --help show this help message and exit
-b MAC, --btaddr MAC Bluetooth address of device; leave blank to use USB
--accumulate Measure until interrupted with ^C
--accumulate-time TIME Measure for a given amount of time (hh:mm:ss)
--accumulate-dose DOSE Measure until a certain dose has been accumulated (uSv)
-B, --bgsub Produce a single spectrum measurement file containing only
the difference between the initial spectrum and the final
spectrum. The start time will be thetime the intial spectrum
was captured. If not specified, the output file will contain
the intial and final spectra, which can be subtracted in other
tools.
--reset-spectrum Reset accumulated spectrum. Dangerous.
--reset-dose Reset accumulated spectrum. Very Dangerous.
Poll a spectrum from a RadiaCode device. This script depends on the radiacode python module, but should work with both bluetooth and USB connections. I've only tested this over USB though.
When run without accumulation, the current, in-memory, spectrum will be downloaded.
If any of the accumulation options are given, an initial spectrum will be captured
and the script will delay. After the delay, another spectrum will be captured. If
the --bgsub
flag is given, the initial spectrum will be subtracted from the final
spectrum and the result will be saved as Foreground; if not, the initial spectrum is
included as a Background measurement, with the final spectrum as a Foreground.
Two options are given to reset the in-memory spectrum and the total accumulated dose. I'm calling them dangerous since they will delete data from device memory.
usage: rcsanitize [-h] [-p PREFIX] [-s STR] [-t TIME] [-x LON] [-y LAT] [-c STR] [-C] [-I] [-N] [-O] [-d] FILE [FILE ...]
Sanitize a Radiacode track by rebasing it (to the notional setting of Hunt for Red October)
positional arguments:
FILE
options:
-h, --help show this help message and exit
-p PREFIX, --prefix PREFIX [sanitized_]
-s STR, --serial-number STR [RC-100-314159]
-t TIME, --start-time TIME [1984-12-05T00:00:00]
-x LON, --base-longitude LON [-55.926966]
-y LAT, --base-latitude LAT [43.583332]
-c STR, --comment STR [And I ... was never here.]
-C, --allow-unsanitized-comment Preserve original comment [False]
-I, --force-input Allow processing of files that begin with the chosen prefix [False]
-N, --allow-unsanitized-name Preserve original track name [False]
-O, --force-overwrite Overwrite existing files [False]
-d, --dry-run Do not emit any output files [False]
Sanitize tracks by teleporting and time traveling them. This can be useful if you don't necessarily want to reveal exactly when or where you were wandering around a nuclear site or potential uranium mine, but want to share the general shape of the area... or if you want to bait your GEOINT friends.
usage: rcmultispg [-h] [-d STR] [-a] [-i FLOAT] [-p STR] [-g URL] [--reset-dose] [--reset-spectrum] [--stdout]
Poll all connected RadiaCode PSRDs and produce spectrograms
options:
-h, --help show this help message and exit
-d STR, --dev STR USB ID of target device. May be repeated for multiple devices. Leave blank to use all connected devices
-a, --require-all abort if not all specified devices can be attached
-i FLOAT, --interval FLOAT Polling interval in seconds [5.0s]
-p STR, --prefix STR prefix for generated filename [rcmulti_]
-g URL, --gpsd URL Connect to specified device, eg. gpsd://localhost:2947/dev/ttyACM0
--reset-dose reset the internal dose meter
--reset-spectrum reset the currently displayed spectrum
--stdout log to stdout instead of to a file
This tool emits a merged log of realtime and spectrum data from a number of sensors, optionally enriched with GPS data from gpsd. This can be used to produce radiacode-compatible spectrograms, spectra, and tracks; as well as 3D tracks for use with other tools. Additionally, near synchronous polling of multiple connected devices is done in case measurements inside and outside of shielding (for example) is desired.
Logs are emitted as ndjson
(newline-delimited JSON, one record per line), typically
to distinct logfiles but optionally to stdout
.
To assist in runtime monitoring, a pollable metrics server runs on port 6853 (on a
phone keypad it spells NUKE
) which emits some performance figures as a JSON object.