Skip to content

Auxiliary tools for working with radiacode devices

License

Notifications You must be signed in to change notification settings

ckuethe/radiacode-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

97 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Radiacode Tools

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.

Quick start

$ 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.

calibrate.py / rccalibrate

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

n42convert.py / n42convert

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.

n42validate.py / n42validate

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.

n42www.py / n42www

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 POSTed 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.

radiacode_poll.py / radiacode-poll

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.

sanitize_track.py / rcsanitize

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.

rcmultispg.py

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.