mDOS JSON description
All sensor data collected by the Medusa gamma-ray spectrometers is both stored and streamed in JSON format (more information on the open-source JSON format can be found here). A JSON string can easily be parsed by most programming languages 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. The contents of this zip file include 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 consists of a header containing meta information of the system and the calibration files. The meta files contain a description of 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 contain a description of 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 what is measured by the onboard Multi Channel Analyser (MCA) that is 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,
"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":"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 that is 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,
"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":"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 is used to monitor the environmental properties 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
}
]
}
]
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 auxillary 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 that are not tagged with the upward type will be stabilized and summed. The summed spectrum will be analyzed and will result 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
}
}
]