Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release NPESv2 #3

Merged
merged 9 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,53 @@
# NPES-JSON

![GitHub release (latest by date)](https://img.shields.io/github/v/release/OpenGammaProject/NPES-JSON?style=flat-square) ![GitHub](https://img.shields.io/github/license/OpenGammaProject/NPES-JSON?style=flat-square) ![GitHub deployments](https://img.shields.io/github/deployments/OpenGammaProject/NPES-JSON/github-pages?label=web%20docs&style=flat-square)

Novel JSON Schema targeted at storing **N**uclear **P**hysics **E**nergy **S**pectra and meta data in a single data object to be parsed by an API or stored in files. Mainly used in gamma spectrometry for energy and background energy spectra, but it can be used for any kind of application where pulse height diagrams (i.e. histogram data) are used. This was originally inspired by the XML files used in the program [BecqMoni (Japanese MCA)](https://www.gammaspectacular.com/blue/software-downloads/becqmoni) and strives to be an open, well-documented, smaller-in-size and easier-to-parse file standard for universal use. Based on JSON Schema Draft-07, therefore it can also be used to transfer data in an API context.
Novel JSON Schema targeted at storing **N**uclear **P**hysics **E**nergy **S**pectra and meta data in a single data object to be parsed by an API or stored in files. Mainly used in gamma spectrometry for energy and background energy spectra, but it can be used for any kind of application where pulse height diagrams (i.e., histogram data) are used. This was originally inspired by the XML files used in the program [BecqMoni (Japanese MCA)](https://www.gammaspectacular.com/blue/software-downloads/becqmoni) and strives to be an open, well-documented, smaller-in-size and easier-to-parse file standard for universal use. Based on JSON Schema Draft-07, therefore it can also be used to transfer data in an API context.

## Why

Other than very simple CSV files there is no real widespread file format in gamma spectrometry, especially one that also allows saving other meta data on top of the spectrum. Few programs use the XML files proposed by BecqMoni, but this is not a standardized format, but more of an informal aggreement on some parts of that format. On top of that, due to the nature of XML, files can quickly get unreasonably big. To solve these issues, IMHO the best solution is to use JSON with a JSON Schema, which is much smaller, partly even simpler to parse and can be validated.
Other than very simple CSV files there is no real widespread and universal file format in gamma spectrometry, especially one that also allows saving other meta data on top of the spectrum. Few programs use the XML files proposed by BecqMoni, but this is not a standardized format, but more of an informal aggreement on some parts of that format. On top of that, due to the nature of XML, files can quickly get unreasonably large in size. To solve these issues, IMHO the best solution is to use JSON with a JSON Schema, which is much smaller, partly even simpler to parse due to its widespread nature and can be validated too.

NPES JSON can also be used in web APIs to transfer spectra data between clients and/or servers. Due to it being JSON, parsing is trivial in JavaScript and very easy in any other web-related programming language. With this you can obviously also validate API requests, which makes data handling a breeze.
NPES JSON can also be used in web APIs to transfer spectra data between clients and/or servers. Due to it being JSON, parsing is trivial in JavaScript and very easy in any other web-related programming language. In this context you can also validate API requests, which makes data handling a breeze and is overall extremely helpful. It's also straight-forward to implement in Python, which is used a lot in data science and pretty much copies the entire data structure of JSON with its dictionary data types.

### Benefits for developers

- Complete and open documentation on the data structure.
- Files can be validated before exporting or importing/loading.
- Can be used to transfer data in an API or similar use cases.
- JSON can be parsed easily in every major programming language and it is absolutely trivial to serialize/deserialize in JavaScript or Python.
- Complete file compatability with every other program adhering to this standard.
- Can be used to transfer data in an API context or similar use cases.
- JSON can be parsed easily in every major programming language and it is trivial to serialize/deserialize in JavaScript and Python.
- Complete file compatibility with every other program adhering to this standard.

### Benefits for end users

- Much smaller file size compared to XML files containing the same information (around 10%).
- Immediate interoperability between different programs - if it imports in one program you can be sure it will import in any other piece of software that supports this file type.
- Immediate interoperability between different programs - if it imports in one program you can be sure it will correctly import in any other piece of software that supports the standard.
- If something goes wrong, you can validate files to see exactly what issues there are.
- You can easily manipulate the data in 3rd party software or your own scripts (especially in Python for example) due to it's simple structure.
- You can easily manipulate the data in 3rd party software or your own scripts (especially in Python for example) due to its simple structure.

## Documentation

The Schema(s) can be found in `schema`.

Example files that validate can be found in `examples`.

For a full, human-readable documentation please head to https://opengammaproject.github.io/NPES-JSON/.
For a full, human-readable documentation please head to [https://opengammaproject.github.io/NPES-JSON/](https://opengammaproject.github.io/NPES-JSON/).

JSON Schema implementation docs can be found here: http://json-schema.org/implementations.html
JSON Schema implementation docs can be found here: [http://json-schema.org/implementations.html](http://json-schema.org/implementations.html)

The documentation has been generated using [JSON Schema for Humans](https://github.com/coveooss/json-schema-for-humans) using the command `generate-schema-doc .\schema\ index.html --config-file .\jsfh-conf.yaml`.

## Changes upon v1

- It is now possible to store multiple spectra in one file in an array structure. There is basically no limit on the number of spectra, so you can for example use it to combine files or to store spectra in a data logger context as discussed in [#2](https://github.com/OpenGammaProject/NPES-JSON/discussions/2). This basically takes the v1 of the standard, puts a bracket around all instances except for `schemaVersion` and allows you to have multiple entries in that array.

## Future Improvements

- Making it possible to store multiple spectra in one file. At the moment this is only possible by appending multiple NPES JSON entries one after another in a single file. That works and it is valid JSON formatting, but it's neither officially supported nor documented.
- None at the moment :)

## Supported Software

This is not a fully comprehensive list, but if you are using this data format, please feel free to add your program and create a PR.

* Gamma MCA: [OpenGammaProject/Gamma-MCA](https://github.com/OpenGammaProject/Gamma-MCA)
* Impulse by Gammaspectacular: [ssesselmann/impulse](https://github.com/ssesselmann/impulse)
- Gamma MCA: [OpenGammaProject/Gamma-MCA](https://github.com/OpenGammaProject/Gamma-MCA)
- Impulse by Gammaspectacular: [ssesselmann/impulse](https://github.com/ssesselmann/impulse) (only supports [NPESv1](https://github.com/OpenGammaProject/NPES-JSON/tree/NPESv1) at the moment)
14 changes: 7 additions & 7 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# Examples

Both of these are gamma spectra of different samples with different saved parameters.
Some example files to have a look at the structure, make yourself familiar with the formatting and test your validation.

## Example 1

Converted from a BecqMoni XML. Reduced size from 18 kB to 2 kB (almost 90% saved).
Converted from a BecqMoni XML, just a single data package containing a single spectrum. Also minimized the JSON, this in total reduced the size from 18 kB to 2 kB (almost 90% saved).

Only 256 channels, reduced size is exponentially larger for larger datasets.

**-->** In [Gamma MCA](https://spectrum.nuclearphoenix.xyz), the JSON files also load significantly faster than the XML files, despite there being an additional file validation step. Sometimes by a good factor of 2. More software tests have to be done to confirm the speed advantage, though.

## Example 2

Energy spectrum and background energy spectrum imported from standard CSV files; added additional sample info and calibration.
Two data packages containing the same data and prettified JSON, just as a demonstration of the array nature of the standard. Energy spectrum and background energy spectrum imported from standard CSV files; added additional sample info and calibration.

Size of both original CSVs: 18 kB
Size of original CSVs in total: 18 kB

Size of NPES JSON: 19 kB
Size of NPES JSON containing the same data: 19 kB

**-->** Only 6% increase despite added calibration for both spectra and sample information.
**-->** Only 6% increase despite added calibration for both spectra and sample information. So it's not even much larger than just a bare CSV!

## Minimal

Absolute minimum example with a single energy spectrum and a 256-bin histogram.
Absolute minimum example with a single data package that includes a single energy spectrum and a 256-bin histogram.
2 changes: 1 addition & 1 deletion examples/example1.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"schemaVersion":"NPESv1","deviceData":{"softwareName":"Gamma MCA, 2023-01-14","deviceName":"RadiaCode-101"},"sampleInfo":{"name":"Mushrooms","location":"The local town","note":"Hello World!","weight":1000,"volume":1000,"time":"2023-01-10T16:14:00+01:00"},"resultData":{"startTime":"2023-01-19T17:14:50+01:00","endTime":"2023-01-19T16:14:50+01:00","energySpectrum":{"numberOfChannels":256,"validPulseCount":60800,"measurementTime":86843,"spectrum":[0,0,659,2134,2388,1529,1351,1523,2050,2042,1737,1344,1151,1001,934,928,923,945,1004,1038,989,1025,1067,1047,932,887,838,833,728,675,657,673,617,604,588,595,549,551,563,571,525,555,514,569,498,468,475,416,361,333,272,306,275,234,234,215,217,236,257,300,383,417,522,580,622,629,611,518,410,331,279,219,166,151,144,136,141,108,131,130,121,133,115,113,81,131,90,101,105,94,93,92,91,104,103,84,88,71,88,98,91,74,98,82,68,71,80,65,79,69,89,75,74,73,63,59,54,45,55,53,38,49,48,37,44,34,44,52,42,33,51,48,44,49,47,50,52,42,44,45,31,35,33,39,31,35,24,27,31,23,19,18,15,25,20,18,18,15,14,15,21,18,16,19,15,20,18,17,17,13,15,17,19,18,9,12,13,15,8,7,20,13,13,16,11,17,10,10,15,12,15,13,9,11,7,8,11,13,16,5,10,6,10,13,8,9,13,10,15,13,6,10,9,7,6,8,11,4,5,3,10,13,6,11,9,11,9,10,15,7,10,8,7,16,8,9,12,12,4,11,7,11,12,12,10,12,8,13,9,14,11,9,17,7,15,1357]},"backgroundEnergySpectrum":{"numberOfChannels":256,"validPulseCount":30266,"measurementTime":86516,"spectrum":[0,0,60,195,361,503,515,701,943,1133,1035,678,551,563,509,488,466,473,441,420,394,447,437,377,428,431,385,374,358,336,322,312,305,277,270,266,234,256,237,235,218,228,219,244,234,171,209,235,205,215,199,228,201,190,200,212,177,146,169,153,159,143,150,160,142,149,134,126,138,145,140,142,105,135,124,111,110,111,103,111,99,100,114,106,94,100,93,96,111,91,90,81,106,107,92,71,91,68,81,71,82,70,83,67,75,67,62,77,53,74,77,63,57,53,53,50,49,50,51,47,36,42,37,39,26,37,30,40,37,33,44,55,48,55,40,39,53,42,31,39,30,40,29,25,26,24,25,26,31,27,26,19,20,21,19,26,23,18,21,14,30,19,19,17,20,12,19,10,14,21,17,18,15,10,14,21,17,12,15,13,20,14,7,17,8,8,8,10,10,17,15,18,13,22,15,10,7,6,15,10,16,12,16,9,5,9,4,6,11,7,6,6,7,10,2,9,10,7,8,6,11,12,12,7,12,7,7,5,6,6,3,9,14,10,9,10,4,11,10,5,12,6,13,13,11,9,10,10,10,14,10,10,12,17,14,1354]}}}
{"schemaVersion":"NPESv2","data":[{"deviceData":{"softwareName":"Gamma MCA, 2023-01-14","deviceName":"RadiaCode-101"},"sampleInfo":{"name":"Mushrooms","location":"The local town","note":"Hello World!","weight":1000,"volume":1000,"time":"2023-01-10T16:14:00+01:00"},"resultData":{"startTime":"2023-01-19T17:14:50+01:00","endTime":"2023-01-19T16:14:50+01:00","energySpectrum":{"numberOfChannels":256,"validPulseCount":60800,"measurementTime":86843,"spectrum":[0,0,659,2134,2388,1529,1351,1523,2050,2042,1737,1344,1151,1001,934,928,923,945,1004,1038,989,1025,1067,1047,932,887,838,833,728,675,657,673,617,604,588,595,549,551,563,571,525,555,514,569,498,468,475,416,361,333,272,306,275,234,234,215,217,236,257,300,383,417,522,580,622,629,611,518,410,331,279,219,166,151,144,136,141,108,131,130,121,133,115,113,81,131,90,101,105,94,93,92,91,104,103,84,88,71,88,98,91,74,98,82,68,71,80,65,79,69,89,75,74,73,63,59,54,45,55,53,38,49,48,37,44,34,44,52,42,33,51,48,44,49,47,50,52,42,44,45,31,35,33,39,31,35,24,27,31,23,19,18,15,25,20,18,18,15,14,15,21,18,16,19,15,20,18,17,17,13,15,17,19,18,9,12,13,15,8,7,20,13,13,16,11,17,10,10,15,12,15,13,9,11,7,8,11,13,16,5,10,6,10,13,8,9,13,10,15,13,6,10,9,7,6,8,11,4,5,3,10,13,6,11,9,11,9,10,15,7,10,8,7,16,8,9,12,12,4,11,7,11,12,12,10,12,8,13,9,14,11,9,17,7,15,1357]},"backgroundEnergySpectrum":{"numberOfChannels":256,"validPulseCount":30266,"measurementTime":86516,"spectrum":[0,0,60,195,361,503,515,701,943,1133,1035,678,551,563,509,488,466,473,441,420,394,447,437,377,428,431,385,374,358,336,322,312,305,277,270,266,234,256,237,235,218,228,219,244,234,171,209,235,205,215,199,228,201,190,200,212,177,146,169,153,159,143,150,160,142,149,134,126,138,145,140,142,105,135,124,111,110,111,103,111,99,100,114,106,94,100,93,96,111,91,90,81,106,107,92,71,91,68,81,71,82,70,83,67,75,67,62,77,53,74,77,63,57,53,53,50,49,50,51,47,36,42,37,39,26,37,30,40,37,33,44,55,48,55,40,39,53,42,31,39,30,40,29,25,26,24,25,26,31,27,26,19,20,21,19,26,23,18,21,14,30,19,19,17,20,12,19,10,14,21,17,18,15,10,14,21,17,12,15,13,20,14,7,17,8,8,8,10,10,17,15,18,13,22,15,10,7,6,15,10,16,12,16,9,5,9,4,6,11,7,6,6,7,10,2,9,10,7,8,6,11,12,12,7,12,7,7,5,6,6,3,9,14,10,9,10,4,11,10,5,12,6,13,13,11,9,10,10,10,14,10,10,12,17,14,1354]}}}]}
16,482 changes: 16,481 additions & 1 deletion examples/example2.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/minimal.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"schemaVersion":"NPESv1","resultData":{"energySpectrum":{"numberOfChannels":256,"spectrum":[0,0,659,2134,2388,1529,1351,1523,2050,2042,1737,1344,1151,1001,934,928,923,945,1004,1038,989,1025,1067,1047,932,887,838,833,728,675,657,673,617,604,588,595,549,551,563,571,525,555,514,569,498,468,475,416,361,333,272,306,275,234,234,215,217,236,257,300,383,417,522,580,622,629,611,518,410,331,279,219,166,151,144,136,141,108,131,130,121,133,115,113,81,131,90,101,105,94,93,92,91,104,103,84,88,71,88,98,91,74,98,82,68,71,80,65,79,69,89,75,74,73,63,59,54,45,55,53,38,49,48,37,44,34,44,52,42,33,51,48,44,49,47,50,52,42,44,45,31,35,33,39,31,35,24,27,31,23,19,18,15,25,20,18,18,15,14,15,21,18,16,19,15,20,18,17,17,13,15,17,19,18,9,12,13,15,8,7,20,13,13,16,11,17,10,10,15,12,15,13,9,11,7,8,11,13,16,5,10,6,10,13,8,9,13,10,15,13,6,10,9,7,6,8,11,4,5,3,10,13,6,11,9,11,9,10,15,7,10,8,7,16,8,9,12,12,4,11,7,11,12,12,10,12,8,13,9,14,11,9,17,7,15,1357]}}}
{"schemaVersion":"NPESv2","data":[{"resultData":{"energySpectrum":{"numberOfChannels":256,"spectrum":[0,0,659,2134,2388,1529,1351,1523,2050,2042,1737,1344,1151,1001,934,928,923,945,1004,1038,989,1025,1067,1047,932,887,838,833,728,675,657,673,617,604,588,595,549,551,563,571,525,555,514,569,498,468,475,416,361,333,272,306,275,234,234,215,217,236,257,300,383,417,522,580,622,629,611,518,410,331,279,219,166,151,144,136,141,108,131,130,121,133,115,113,81,131,90,101,105,94,93,92,91,104,103,84,88,71,88,98,91,74,98,82,68,71,80,65,79,69,89,75,74,73,63,59,54,45,55,53,38,49,48,37,44,34,44,52,42,33,51,48,44,49,47,50,52,42,44,45,31,35,33,39,31,35,24,27,31,23,19,18,15,25,20,18,18,15,14,15,21,18,16,19,15,20,18,17,17,13,15,17,19,18,9,12,13,15,8,7,20,13,13,16,11,17,10,10,15,12,15,13,9,11,7,8,11,13,16,5,10,6,10,13,8,9,13,10,15,13,6,10,9,7,6,8,11,4,5,3,10,13,6,11,9,11,9,10,15,7,10,8,7,16,8,9,12,12,4,11,7,11,12,12,10,12,8,13,9,14,11,9,17,7,15,1357]}}}]}
Loading