{"id":23935173,"url":"https://github.com/ckuethe/radiacode-tools","last_synced_at":"2025-04-12T09:22:59.278Z","repository":{"id":189266933,"uuid":"676726842","full_name":"ckuethe/radiacode-tools","owner":"ckuethe","description":"Auxiliary tools for working with radiacode devices ","archived":false,"fork":false,"pushed_at":"2025-04-05T00:28:39.000Z","size":928,"stargazers_count":20,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-05T01:24:21.747Z","etag":null,"topics":["dosimeter-calibration","gamma-ray-spectrometry","gamma-spectra","gamma-spectrometry","n42","radiacode","radiation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckuethe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-09T21:43:21.000Z","updated_at":"2025-04-05T00:28:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"94300d0e-7da8-4ca0-b65e-d8f5e5476007","html_url":"https://github.com/ckuethe/radiacode-tools","commit_stats":{"total_commits":54,"total_committers":2,"mean_commits":27.0,"dds":0.05555555555555558,"last_synced_commit":"631b17c20da3d2fa58ee6e5234c0cd36ae242420"},"previous_names":["ckuethe/radiacode-tools"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckuethe%2Fradiacode-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckuethe%2Fradiacode-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckuethe%2Fradiacode-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckuethe%2Fradiacode-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckuethe","download_url":"https://codeload.github.com/ckuethe/radiacode-tools/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248544373,"owners_count":21121940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dosimeter-calibration","gamma-ray-spectrometry","gamma-spectra","gamma-spectrometry","n42","radiacode","radiation"],"created_at":"2025-01-06T00:44:49.133Z","updated_at":"2025-04-12T09:22:59.259Z","avatar_url":"https://github.com/ckuethe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Github Tests Workflow](https://github.com/ckuethe/radiacode-tools/actions/workflows/tests.yml/badge.svg)](https://github.com/ckuethe/radiacode-tools/actions/workflows/tests.yml)\n![Codecov Workflow](https://github.com/ckuethe/radiacode-tools/actions/workflows/codecov.yml/badge.svg)\n[![Codecov Status](https://codecov.io/gh/ckuethe/radiacode-tools/graph/badge.svg?token=IJIWGVDKTY)![Codecov](https://img.shields.io/codecov/c/github/ckuethe/radiacode-tools)](https://app.codecov.io/gh/ckuethe/radiacode-tools/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n# Radiacode Tools\n\nJust some things for working with my RadiaCode devices from Scan-Electronics.\n\nIf you're planning on generating gps-tagged logs with a headless sensor, you\nmight also want to look at my [web console for gpsd](https://github.com/ckuethe/webcpgs/).\n\n## Quick start\n\n```\n$ git clone https://github.com/ckuethe/radiacode-tools\n$ cd radiacode-tools\n$ python -m venv venv\n$ . venv/bin/activate\n$ pip install -e .\n\n# or this if you want to plot tracks and spectrograms\n$ pip install -e .[graphical]\n```\n\nSome convenience scripts will be installed along with the python code,\neg. `rccalibrate` to go along with `calibrate.py`.\n\n### calibrate.py / rccalibrate\nThis tool computes calibration factors for mapping the channel to detected\nphoton energy. \n\nUse `calibrate.py -W` to generate a example calibration file, then use your\ndetector to measure a range of photon energies.\n\n```\nusage: calibrate.py [-h] [-z] [-f FILE] [-o N] [-p N] [-W]\n\noptions:\n  -h, --help                   show this help message and exit\n  -z, --zero-start             Add a synthetic (0,0) calibration data point\n  -f FILE, --cal-file FILE     Calibration data file [radiacode.json]\n  -o N, --order N              Calibration polynomial order [2]\n  -p N, --precision N          Number of decimal places in calibration factors [8]\n  -W, --write-template         Generate a template calibration file\n\n```\n\nCalibration can be performed with a single sample (Th-232, Ra-226), though better\nresults may be obtained using more isotopes with a broader range of energies.\n\n```\n# data derived from americium, barium, europium, potassium, radium, sodium, and thorium.\n$ ./calibrate.py \ndata range: (9, 26) - (941, 2614)\nx^0 .. x^2: [-7.26773237, 2.44338618, 0.00037684]\nR^2: 0.99988\n\n# Same data as above, but with a synthetic (0,0) data point\n$ ./calibrate.py -z\ndata range: (0, 0) - (941, 2614)\nx^0 .. x^2: [-6.28323127, 2.43830549, 0.00038176]\nR^2: 0.99988\n\n# Single source calibration using thoriated tungsten welding electrodes\n$ ./calibrate.py -f thorium.json \ndata range: (138, 338) - (941, 2614)\nx^0 .. x^2: [-15.63118352, 2.47761651, 0.00033984]\nR^2: 0.99988\n\n# Single source calibration using a luminous radium paint \n$ ./calibrate.py -f radium.json \ndata range: (122, 295) - (802, 2204)\nx^0 .. x^2: [-2.45705927, 2.39432185, 0.00044401]\nR^2: 0.99998\n```\n\n### n42convert.py / n42convert\nThis tool converts a RadiaCode (\"RC\") spectrum XML file into\n[ANSI N42](https://www.nist.gov/pml/radiation-physics/ansiieee-n4242-2020-version)\nformat for analysis with other tools such as\n[InterSpec](https://github.com/sandialabs/InterSpec).\nFor my main use case - InterSpec interoperability - this tool has been\nmostly superseded by [sandialabs/SpecUtils#15], but not everyone will\nbe able to update their copy of InterSpec, and there are other tools for\ngamma spectroscopy so it's not completely useless.\n\n```\nusage: n42convert.py [-h] -i NAME [-b NAME] [-o NAME | -r] [--overwrite] [-u UUID]\n\noptions:\n  -h, --help                    show this help message and exit\n  -i NAME, --input NAME         primary source data file\n  -b NAME, --background NAME    Retrieve background from this file, using the background series if it exists or the main series otherwise.\n  -o NAME, --output NAME        [\u003cforeground\u003e.n42]\n  -r, --recursive               if given, treat the input path as a directory to process recursively with autogenerated output names\n  --overwrite                   allow existing file to be overwritten\n  -u UUID, --uuid UUID          specify a UUID for the generated document. [\u003crandom\u003e]\n\n```\n\nOnly a single `-i` or `--input` argument is required. This will convert the\ncontents of an RC spectrum file into an N42 file named similarly to the source file.\nIf the RC file contains an included background spectrum it will be included in the\noutput.\n\nIf the `-r` or `--recursive` argument is given, the input argument is treated as a\ndirectory to traverse looking for RC files to be converted. This argument causes\nthe background argument to be ignored, and is mutually exclusive with the output\nargument; output file name will be generated from each input filename.\n\nIn cases where two separate spectra have been recorded, they can be combined to form\na recording with included background. Consider a basement lab with a smoke detector;\nthe background radiation may be influenced by the concrete foundation made with an\naggregate containing a relatively large amount of thorium and uranium, there may be\nelevated levels of radon due to poor ventilation, and the smoke detector contains an\namericium source.\n\nA recording of this ambient radiation can be saved as `lab.xml`.\nWhen a new sample arrives, perhaps a container of sodium-free salt substitute (`KCl`)\nor a crate of bananas for scale, it is measured in the same location as the lab\nreference measurement, and the recording may be saved as `k40.xml`. These two files\nmay be merged by running `n42convert.py -f k40.xml -b lab.xml -o banana.n42`.\n\nIf the background RC file has both foreground and background spectra, the background\nspectrum will be copied into the output N42 file. If no background spectrum exists,\nthe foreground data from the background file will be copied into the output N42 file.\n\n### n42validate.py / n42validate\n```\nusage: n42validate.py [-h] [-r] [-q] [-v] [-V] [-s XSD] [-u URL] [-x EXT] FILE [FILE ...]\n\npositional arguments:\n  FILE                  source data file\n\noptions:\n  -h, --help                  show this help message and exit\n  -r, --recursive             treat the input path as a directory to process recursively [False]\n  -q, --quiet                 don't display the invalid XML element\n  -v, --verbose               display valid files too, by default only invalid files are reported\n  -V, --valid-only            only display valid files\n  -s XSD, --schema-file XSD   Default: ~/.cache/n42.xsd\n  -u URL, --schema-url URL    Default: https://www.nist.gov/document/n42xsd\n  -x EXT, --extension EXT     Default: .n42\n```\n\nSome programs are more tolerant than others when processing potentially invalid\nN42 inputs. This utility can be used to check data file compliance with the N42\nspecification. Output can be constrained to valid or invalid files only, with\noptional detailed information about which elements of the file are incorrect.\n\n### n42www.py / n42www\n```\nusage: n42www.py [-h] [-b IP] [-m NUM] [-p PORT] [-v]\n\noptions:\n  -h, --help                show this help message and exit\n  -b IP, --bind-addr IP     IP address on which to listen [127.0.0.1]\n  -m NUM, --max-size NUM    Maximum upload file size in bytes [131072]\n  -p PORT, --port PORT      Port on which to listen [6853]\n  -v, --verbose             increase verbosity for debugging\n```\n\nThis program is a simple web server which allows an RC XML file to be `POST`ed\nto its `/convert` endpoint, returning an N42 file. This enables radiation analysis\nto be conducted using just an RC detector, and a phone or tablet running the\n[RadiaCode](https://play.google.com/store/apps/details?id=com.almacode.radiacode)\nand\n[InterSpec](https://play.google.com/store/apps/details?id=gov.sandia.interspec)\napps. This too is mostly irrelevant now that InterSpec can read RadiaCode files.\n\nConfiguring a reverse proxy and `WSGI` server for safe deployment of this server\nis beyond the scope of this document.\n\n### radiacode_poll.py / radiacode-poll\n```\nusage: radiacode_poll.py [-h] [-b MAC] [--accumulate | --accumulate-time TIME | --accumulate-dose DOSE] [--bgsub]  [--reset-spectrum] [--reset-dose] [outfile]\n\noptions:\n  -h, --help              show this help message and exit\n  -b MAC, --btaddr MAC    Bluetooth address of device; leave blank to use USB\n  --accumulate            Measure until interrupted with ^C\n  --accumulate-time TIME  Measure for a given amount of time (hh:mm:ss)\n  --accumulate-dose DOSE  Measure until a certain dose has been accumulated (uSv)\n  -B, --bgsub             Produce a single spectrum measurement file containing only\n                          the difference between the initial spectrum and the final\n                          spectrum. The start time will be thetime the intial spectrum\n                          was captured. If not specified, the output file will contain\n                          the intial and final spectra, which can be subtracted in other\n                          tools.\n  --reset-spectrum        Reset accumulated spectrum. Dangerous.\n  --reset-dose            Reset accumulated spectrum. Very Dangerous.\n```\n\nPoll a spectrum from a RadiaCode device. This script depends on the\n[radiacode](https://github.com/cdump/radiacode) python module, but should work with\nboth bluetooth and USB connections. I've only tested this over USB though.\n\nWhen run without accumulation, the current, in-memory, spectrum will be downloaded.\nIf any of the accumulation options are given, an initial spectrum will be captured\nand the script will delay. After the delay, another spectrum will be captured. If\nthe `--bgsub` flag is given, the initial spectrum will be subtracted from the final\nspectrum and the result will be saved as Foreground; if not, the initial spectrum is\nincluded as a Background measurement, with the final spectrum as a Foreground.\n\nTwo options are given to reset the in-memory spectrum and the total accumulated dose.\nI'm calling them dangerous since they will delete data from device memory.\n\n### sanitize_track.py / rcsanitize\n```\nusage: rcsanitize [-h] [-p PREFIX] [-s STR] [-t TIME] [-x LON] [-y LAT] [-c STR] [-C] [-I] [-N] [-O] [-d] FILE [FILE ...]\n\nSanitize a Radiacode track by rebasing it (to the notional setting of Hunt for Red October)\n\npositional arguments:\n  FILE\n\noptions:\n  -h, --help                         show this help message and exit\n  -p PREFIX, --prefix PREFIX         [sanitized_]\n  -s STR, --serial-number STR        [RC-100-314159]\n  -t TIME, --start-time TIME         [1984-12-05T00:00:00]\n  -x LON, --base-longitude LON       [-55.926966]\n  -y LAT, --base-latitude LAT        [43.583332]\n  -c STR, --comment STR              [And I ... was never here.]\n  -C, --allow-unsanitized-comment    Preserve original comment [False]\n  -I, --force-input                  Allow processing of files that begin with the chosen prefix [False]\n  -N, --allow-unsanitized-name       Preserve original track name [False]\n  -O, --force-overwrite              Overwrite existing files [False]\n  -d, --dry-run                      Do not emit any output files [False]\n```\n\nSanitize tracks by teleporting and time traveling them. This can be useful if\nyou don't necessarily want to reveal exactly when or where you were wandering\naround a nuclear site or potential uranium mine, but want to share the general\nshape of the area... or if you want to bait your GEOINT friends.\n\n### rcmultispg.py\n```\nusage: rcmultispg [-h] [-d STR] [-a] [-i FLOAT] [-p STR] [-g URL] [--reset-dose] [--reset-spectrum] [--stdout]\n\nPoll all connected RadiaCode PSRDs and produce spectrograms\n\noptions:\n  -h, --help                  show this help message and exit\n  -d STR, --dev STR           USB ID of target device. May be repeated for multiple devices. Leave blank to use all connected devices\n  -a, --require-all           abort if not all specified devices can be attached\n  -i FLOAT, --interval FLOAT  Polling interval in seconds [5.0s]\n  -p STR, --prefix STR        prefix for generated filename [rcmulti_]\n  -g URL, --gpsd URL          Connect to specified device, eg. gpsd://localhost:2947/dev/ttyACM0\n  --reset-dose                reset the internal dose meter\n  --reset-spectrum            reset the currently displayed spectrum\n  --stdout                    log to stdout instead of to a file\n\n```\n\nThis tool emits a merged log of realtime and spectrum data from a number of sensors,\noptionally enriched with GPS data from [gpsd](https://gpsd.io). This can be used to\nproduce radiacode-compatible spectrograms, spectra, and tracks; as well as 3D tracks\nfor use with other tools. Additionally, near synchronous polling of multiple connected\ndevices is done in case measurements inside and outside of shielding (for example) is\ndesired.\n\nLogs are emitted as `ndjson` (newline-delimited JSON, one record per line), typically\nto distinct logfiles but optionally to `stdout`.\n\nTo assist in runtime monitoring, a pollable metrics server runs on port 6853 (on a\nphone keypad it spells `NUKE`) which emits some performance figures as a JSON object.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckuethe%2Fradiacode-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckuethe%2Fradiacode-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckuethe%2Fradiacode-tools/lists"}