mDOS JSON description
All sensor data collected by the Medusa gamma-ray spectrometers are stored and streamed in JSON format (more information on the open-source JSON format can be found here). Most programming languages can easily parse a JSON string, and online converters can be used to view data by pasting single JSON strings (For example, http://json.parser.online.fr/).
A Medusa gamma-ray spectrometer will produce JSON strings that describe the system, along with JSON strings that contain the measurement data for each of the sensors on board of the spectrometer. A description of these measurements is provided in separate meta JSON strings.
Syntax info
In the code block sections on this page, the JSON strings have been modified to clarify the documentation. Text embedded in <> brackets explain a concept and some parts of the JSON strings have been appended with comments preceded by double .slashes (//).
Example output file
The file above has been acquired from a Medusa Sensor. A project zip has been downloaded from the projects page on the mDOS interface, and the file has been extracted. This zip file includes one or more .json files, as shown above. These files can be imported for analysis in Gamman, or they can be inspected by using a text editor. Each data JSON file contains a header containing meta-information about the system and the calibration files. The meta files describe the sensors and what each measurement represents. The sensor-specific JSON strings are described below, and the calibration and system JSON strings are described in the code blocks below.
Streaming Data
In addition to the on-board storage, the data present in these JSON files can be recorded by an external logging program. Information on how to integrate this datastream to an external logging program can be found on the mDOS interface/data page.
System JSON strings
The system JSON strings describe the system and the calibration used to process the recorded data.
System JSON
[
{
"Hostname":"MS350-00xx",
"MedusaID":"MS-350.00xx",
"objectVersion":"1.0",
"CarrierVersion":"2.0",
"PSUVersion":"2.0",
}
]
Calibration JSON
[
{
"mcf_name":"ms350-00xx_3x3csi_xx-xx-20xx_kuthcs.a2320",
"encrypted_mcf_string":"<Encrypted_JSON_STRING>"
}
]
Sensor JSON strings
JSON strings containing measurement data from a sensor all have the following format:
General sensor JSON structure
[
{
"eID":"<sensorType>_<SensorSerial>", // A string which is always an
// aggregation of a sensor type
// identifier and a serial number,
// separated by an underscore
"v":{}, // An object under the 'v' key
// contains the measurements,
// which is unique for each sensor.
"vT":<timestamp> // A unix system timestamp: the
// number of milliseconds since
// Jan 1st 1970
// (https://www.unixtimestamp.com/)
}
]
Each sensor has an accompanying meta file. The meta files describe the sensors and what each measurement represents. The block below describes the general structure of a meta JSON object.
General sensor meta structure
[
{
"objectVersion":"1.0",
"eID":"<eID>", // eID of the sensor
"classID":"<name>", // Class of sensor
"sensorConfig":{<Sensor configuration>}, // The full configuration of
// the sensor
"sensorMeasures":[
{
"measureLabel":"<label>", // The name of the label
// in under the vT object
"measureDescriptor":"<description>", // A description of the label
"measureType":"<array/number/string>",
"measureUnit":"<units>", // Units of the number
"measureUnitEx":"<alt_units>", // Alternative units
"measureLow":0, // Minimum value
"measureHigh":4294967295, // Maximum value
"measureResolution":1, // Step size of measurement
"measureAccuracy":1, // Accuracy of the measurement
"array_size":<size>, // Length description in the
// case the measurement is
// an array
"synchronisation_method":<0,1,2> // Synchronization method ID
// (average, mean, sum)
}
]
}
]
Spectrometer data
Raw spectrum data
Raw spectrum data is measured by the onboard Multi-Channel Analyser (MCA) connected to the scintillating crystal. This measurement contains a spectrum with integer counts for each measurement channel. The collapsable code block directly below the measurement JSON string contains the meta string that describes what each key present in the "v" block represents.
Raw spectrum
{
"eID":"SPECTRO_xxxx", // SPECTRO identifies a spectrometer, and the four number represent a MCA serial
"vT":1623330081307,
"v":{
"Realtime":1.001,
"Livetime":0.999,
"Spectrum":[<array>], // Array with a length equal to the set number of channels.
"Total":108,
"Countrate": 108,
"Cosmics":0,
}
}
]
Raw meta JSON
[
{
"objectVersion":"1.0",
"eID":"SPECTRO_xxxx",
"classID":"Spectrometer",
"sensorConfig":{
"Serial":xxxx,
"Firmware":"19.03",
"Hardware":"14.00",
"Highvoltage":0,
"Channels":512,
"Polarity":"poNegative",
"Gain":"41.0000",
"Shapingtime":"1.0",
"Flattoptime":"1.2"
},
"sensorMeasures":[
{
"measureLabel":"Spectrum",
"measureDescriptor":"A raw gamma-ray spectrum",
"measureType":"array",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"array_size":512,
"synchronisation_method":0
},
{
"measureLabel":"Livetime",
"measureDescriptor":"Time the sensor actually measured",
"measureType":"number",
"measureUnit":"s",
"measureUnitEx":"second(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Realtime",
"measureDescriptor":"Time the measurement took",
"measureType":"number",
"measureUnit":"s",
"measureUnitEx":"second(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Total",
"measureDescriptor":"Total counts inside the spectrum",
"measureType":"number",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
},
{
"measureLabel":"Countrate",
"measureDescriptor":"Counts per second inside the spectrum (rounded)",
"measureType":"number",
"measureUnit":"cps",
"measureUnitEx":"counts per second (cps)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
},
{
"measureLabel":"Cosmics",
"measureDescriptor":"Detected counts above the last channel",
"measureType":"number",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
}
]
}
]
Stabilized spectrum data
A stabilized spectrum is a raw spectrum converted to an energy scale. This spectrum usually consists of 300 channels and can contain fractional counts. The stabilized spectrum was created using the selected calibration file. The collapsable code block directly below the measurement JSON string is the meta string that describes what each key present in the "v" block represents.
Calibration
Not all raw spectra are translated into stabilized spectra. Once the spectrometer has been turned on, it needs to collect at least 10,000 counts in the energy range of 400-3,000 KeV before it can calculate a valid stabilization. Depending on the size of the scintillation crystal, this may take up to a few minutes. After a stabilization has been determined, it is continuously updated until the system is powered down.
Stabilized JSON
[
{
"eID":"STABSPECTRO_xxxx",
"v":{
"K40":158.039154052734,
"Realtime":0.999,
"sTh232":30.5838088989258,
"Q":0.409785896539688,
"sCs137":21.3017673492432,
"Livetime":0.997,
"A1":0.659999668598175,
"Countrate":121,
"Cosmics":0,
"Total":121,
"Th232":17.5619468688965,
"sU238":36.8515777587891,
"sK40":226.527160644531,
"U238":7.76706838607788,
"Cs137":-3.49871563911438,
"StabSpectrum":[<300_channel_spectrum>]
},
"vT":1623330083308
}
]
Stabilized meta JSON
[
{
"objectVersion":"1.1",
"eID":"STABSPECTRO_xxxx",
"classID":"Gamman",
"sensorConfig":{
"MCAconfig":{
"Serial":xxxx,
"Firmware":"19.03",
"Hardware":"14.00",
"Highvoltage":0,
"Channels":512,
"Polarity":"poNegative",
"Gain":"14.0000",
"Shapingtime":"1.0",
"Flattoptime":"1.2"
},
"GammanConfig":{
"Showhints":false,
"MCFfolder":"/config/MCF/",
"MCFfile":"default",
"Fitmode":1,
"IncludeOriginalSpectrum":false
},
"SpectrumParserconfig":{
"Serial":xxxx,
"Firmware":"19.03",
"Hardware":"14.00",
"Highvoltage":0,
"Channels":512,
"Polarity":"poNegative",
"Gain":"14.0000",
"Shapingtime":"1.0",
"Flattoptime":"1.2"
}
},
"sensorMeasures":[
{
"measureLabel":"Livetime",
"measureDescriptor":"Time the sensor actually measured",
"measureType":"number",
"measureUnit":"s",
"measureUnitEx":"second(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Realtime",
"measureDescriptor":"Time the measurement took",
"measureType":"number",
"measureUnit":"s",
"measureUnitEx":"second(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Total",
"measureDescriptor":"Total counts inside the spectrum",
"measureType":"number",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
},
{
"measureLabel":"Countrate",
"measureDescriptor":"Counts per second inside the spectrum (rounded)",
"measureType":"number",
"measureUnit":"cps",
"measureUnitEx":"counts per second (cps)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
},
{
"measureLabel":"Cosmics",
"measureDescriptor":"Detected counts above the last channel",
"measureType":"number",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":1,
"measureAccuracy":1,
"synchronisation_method":0
},
{
"measureLabel":"K40",
"measureDescriptor":"Activity concentrations for potassium-40",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"sK40",
"measureDescriptor":"Uncertainty of activity concentrations for potassium-40",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"U238",
"measureDescriptor":"Activity concentrations for uranium-238",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"sU238",
"measureDescriptor":"Uncertainty of activity concentrations for uranium-238",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Th232",
"measureDescriptor":"Activity concentrations for thorium-232",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"sTh232",
"measureDescriptor":"Uncertainty of activity concentrations for thorium-232",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"Cs137",
"measureDescriptor":"Activity concentrations for cesium-137",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"sCs137",
"measureDescriptor":"Uncertainty of activity concentrations for cesium-137",
"measureType":"array",
"measureUnit":"Bq/kg",
"measureUnitEx":"Bequerel per kilogram",
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"A1",
"measureDescriptor":"A1 stabilization parameter",
"measureType":"number",
"measureUnit":"",
"measureUnitEx":"",
"measureResolution":0.01,
"measureAccuracy":0.01,
"synchronisation_method":0
},
{
"measureLabel":"Q",
"measureDescriptor":"Quality of fit indication",
"measureType":"number",
"measureUnit":"",
"measureUnitEx":"",
"measureLow":0,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0
},
{
"measureLabel":"StabSpectrum",
"measureDescriptor":"A stabilized gamma-ray spectrum",
"measureType":"array",
"measureUnit":"cnts",
"measureUnitEx":"count(s)",
"measureLow":0,
"measureHigh":4294967295,
"measureResolution":0.001,
"measureAccuracy":0.001,
"synchronisation_method":0,
"spectrum":1,
"array_size":300
}
]
}
]
GPS data
The code block below shows a typical JSON measurement string to store data from a GPS. The collapsable code block directly below the measurement JSON string contains the meta string that describes what each key present in the "v" block represents.
GPS json
[
{
"eID":"GPS_0006",
"v":{
"Date":1623330083000,
"Heading":0.0,
"Height":58.983,
"HeightMSL":13.299,
"Lat":53.0107648,
"Lon":7.0139993,
"cAcc":5.9975,
"gSpeed":8.36,
"gpsFix":3,
"hAcc":0.519,
"noSat":30,
"pDOP":0.92,
"rtkFix":0,
"sAcc":1.55,
"vAcc":0.851
},
"vT":1623330083893
}
]
GPS meta JSON
[
{
"classID":"GPS",
"eID":"GPS_0006",
"objectVersion":2,
"sensorConfig":{
"Enabled":true,
"ID":"GPS",
"UDPmetaPort":null,
"UDPsendIP":null,
"UDPsendPort":null,
"address":"0x42",
"debugMode":null,
"eID":"GPS_0006",
"interval":1000,
"port":"/dev/i2c-2",
"type":"uBlox ZED-F9P"
},
"sensorMeasures":[
{
"measureDescriptor":"Date from the GPS",
"measureLabel":"Date",
"measureType":"number",
"measureUnit":"UTM",
"measureUnitEx":"Milliseconds since 1970"
},
{
"measureAccuracy":1e-07,
"measureDescriptor":"Latitude = Geographic coordinate that specifies the north-south position seen from the equator",
"measureLabel":"Lat",
"measureResolution":1e-07,
"measureType":"number",
"measureUnit":"degree",
"measureUnitEx":"degree as seen from the equator"
},
{
"measureAccuracy":1e-07,
"measureDescriptor":"Longitude = Geographic coordinate that specifies the east-west position seen from the Royal Observatory, Greenwich, England",
"measureLabel":"Lon",
"measureResolution":1e-07,
"measureType":"number",
"measureUnit":"degree",
"measureUnitEx":"degree as seen from the Greenwich"
},
{
"measureAccuracy":0.001,
"measureDescriptor":"Altitude above the ground",
"measureLabel":"Height",
"measureResolution":0.001,
"measureType":"number",
"measureUnit":"meter",
"measureUnitEx":"Meter above the ground"
},
{
"measureAccuracy":0.001,
"measureDescriptor":"Height above mean sea level",
"measureLabel":"HeightMSL",
"measureResolution":0.001,
"measureType":"number",
"measureUnit":"meter",
"measureUnitEx":"Meter above mean sea level"
},
{
"measureAccuracy":1,
"measureDescriptor":"Horizontal Accuracy Estimate",
"measureLabel":"hAcc",
"measureResolution":0.001,
"measureType":"number",
"measureUnit":"meter"
},
{
"measureAccuracy":1,
"measureDescriptor":"Vertical Accuracy Estimate",
"measureLabel":"vAcc",
"measureResolution":0.001,
"measureType":"number",
"measureUnit":"meter"
},
{
"measureAccuracy":1,
"measureDescriptor":"GPSfix Type 0=no fix, 1=dead reckoning only, 2=2D-fix, 3=3D-fix, 4=GPS + dead reckoning combined, 5=Time only fix, 6..ff=Reserved valus",
"measureLabel":"gpsFix",
"measureResolution":1,
"measureType":"number",
"measureUnit":""
},
{
"measureAccuracy":1,
"measureDescriptor":"RTK solution: 0=no, 1=float solution, 2=fixed solution",
"measureLabel":"rtkFix",
"measureResolution":1,
"measureType":"number",
"measureUnit":""
},
{
"measureAccuracy":1,
"measureDescriptor":"Number of sats used in fix",
"measureLabel":"noSat",
"measureResolution":1,
"measureType":"number",
"measureUnit":""
},
{
"measureAccuracy":0.01,
"measureDescriptor":"positional dillution of precision",
"measureLabel":"pDOP",
"measureResolution":0.01,
"measureType":"number",
"measureUnit":""
},
{
"measureAccuracy":0.01,
"measureDescriptor":"Ground speed (2-D)",
"measureLabel":"gSpeed",
"measureResolution":0.01,
"measureType":"number",
"measureUnit":"m/s",
"measureUnitEx":"Meter per second"
},
{
"measureAccuracy":1,
"measureDescriptor":"Speed accuracy estimation",
"measureLabel":"sAcc",
"measureResolution":0.01,
"measureType":"number",
"measureUnit":"m/s",
"measureUnitEx":"Meter per second"
},
{
"measureAccuracy":1e-05,
"measureDescriptor":"Heading of motion(2-D)",
"measureLabel":"Heading",
"measureResolution":1e-05,
"measureType":"number",
"measureUnit":"deg",
"measureUnitEx":"degree"
},
{
"measureAccuracy":1e-05,
"measureDescriptor":"Heading accuracy estimation",
"measureLabel":"cAcc",
"measureResolution":1e-05,
"measureType":"number",
"measureUnit":"deg",
"measureUnitEx":"degree"
}
]
}
]
PTH data
The code block below shows a typical measurement JSON string to store data from a PTH sensor. A PTH sensor monitors the environmental properties of air pressure, temperature and humidity. The collapsable code block directly below the measurement JSON string contains the meta string that describes what each key present in the "v" block represents.
PTH json
[
{
"eID":"PTH_0006",
"v":{
"Hum":27.75,
"Press":1017.2866,
"Temp":30.71
},
"vT":1623330083950
}
]
PTH meta JSON
[
{
"classID":"PTH",
"eID":"PTH_0006",
"objectVersion":1,
"sensorConfig":{
"Address":"0x76",
"DebugMode":null,
"Enabled":true,
"ID":"PTH",
"Interval":1000,
"Port":"/dev/i2c-3",
"UDPsendIP":null,
"UDPsendPort":null,
"eID":"PTH-0006",
"type":"Bosch BME280"
},
"sensorMeasures":[
{
"measureAccuracy":0.2,
"measureDescriptor":"Pressure in hectopascals",
"measureLabel":"Press",
"measureResolution":0.0001,
"measureType":"number",
"measureUnit":"hectoPascal",
"measureUnitEx":"Kilogram / (meter * second^2)",
"synchronisation_method":1
},
{
"measureAccuracy":1.0,
"measureDescriptor":"Temperature in celcius",
"measureLabel":"Temp",
"measureResolution":0.01,
"measureType":"number",
"measureUnit":"Celcius",
"synchronisation_method":1
},
{
"measureAccuracy":3,
"measureDescriptor":"Percentage relative humidity",
"measureHigh":100,
"measureLabel":"Hum",
"measureLow":0,
"measureResolution":0.01,
"measureType":"number",
"measureUnit":"Precentage",
"measureUnitEx":"Percentage of total humidity",
"synchronisation_method":1
}
]
}
]
Synchronized data
The detector synchronizes the sensor data coming in. Synchronization combines the data from multiple sensors to a single JSON. The stabilized spectrum is used as the basis for this synchronized JSON. Based on their timestamp, other sensor readings are interpolated to the stabilized spectrum. The detector's settings describe which sensor readings are interpolated and are not user adjustable. The generated synced JSON can be used to directly use the georeferenced spectrometer data and allows to skip the post-processing step altogether.
SYNC json
[
{
"eID":"SYNC_xxxx",
"v":{
"K40":1237.255,
"Realtime":3.003,
"sTh232":19.725,
"Q":0.505,
"sCs137":18.605,
"Livetime":2.991,
"A1":0.647,
"Countrate":724,
"Cosmics":2,
"Total":2210,
"Th232":129.369,
"sU238":27.237,
"sK40":175.886,
"U238":76.274,
"Cs137":0.246,
"StabSpectrum":[<300_channel_spectrum>],
"Dose":0.116,
"Lat":53.0107648,
"Lon":7.0139993,
"Date":1584835625503.1572,
"Height":58.983
},
"vT":1675441175625
}
]
External TXT data
The code block below shows a typical measurement JSON string to store text data streamed over the RS-232 port. This function can be used to store readings from any auxiliary sensor. See the data out page for more information about the configuration.
TXT json
[
{
"eID":"TXT_external",
"v":{ <A text line streamed through the external RS-232 port>
},
"vT":1623330083950
}
]
Multi crystal systems
When the system contains multiple crystals the JSON contains an array of multiple raw spectrum data JSONS (see section above)
Optionally one of the raw spectra has the key "type" : "upward"
, indicating an upward-looking detector.
In multi-crystal systems, all the spectra not tagged with the upward type will be stabilized and summed. The summed spectrum will be analyzed, resulting in a stabilized spectrum data json (see section above).
Raw multi-crystal JSON
{
"eID":"SPECTRO_sum", // SPECTRO_SUM identifies a multi crystal JSON
"vT":1623330081307,
"v":{
[<array of raw spectra>] // Array with a length equal to the number
// of crystals
}
}
]