Mrs_tool can not read a nifti file generated from osprey

Hi,

I have both philips spar/sdat and data/list files acquired from a subject.

In the former dataset, nifti files were generated with both spec2nii and osprey gui. However, mrs_tool can get information from the nifti file from spec2nii, but not from osprey gui.

In the latter dataset of .data/.list, I saved it as nifti format with io_writeniimrs.m. The nifti file can be processed with osprey. Unfortunately, however, mrs_tool info also generated error messages like below.

Similar, but opposite case, topic existed.
(Errors when processing NIfTI-MRS files in Osprey - #4 by Chris_Davies-Jenkins)

Any suggestion would be greatly appreciated.

Bumseok

in case of “with osprey gui”

main.py", line 91, in read_FID
return fsl_nmrs.NIFTI_MRS(filename, validate_on_creation=False)
…
hdr_ext.py", line 106, in from_header_ext
raise ValueError(f’User-defined key {key} must contain a “Description” field"')
ValueError: User-defined key ProcessingSoftwareVersion must contain a “Description” field"

in case of “with io_writeniimrs.m”

validator.py", line 166, in validate_hdr_ext
raise headerExtensionError(f’{key} must be a {standard_defined[key][0]}. ’
nifti_mrs.validator.headerExtensionError: RepetitionTime must be a <class ‘float’>. RepetitionTime is a <class ‘int’>, with value 2.

Thanks - this is really useful feedback. I think this means that we’ll need to modify io_writeniimrs to comply a little more strictly with the requirements. Here, specifically, we stored TR as an integer rather than a float and didn’t store a description of some additional header documentation. This should be easily fixable on our end.

@wclarke might also find this useful to edit his code to be a little more forgiving if the incoming NIfTI-MRS file is not perfectly compliant.

Thanks @drshrink, this is useful to know, and it should be fixed.

@admin, I could do that. Or do you fancy implementing a validator like nifti_mrs_tools/src/nifti_mrs/validator.py at master ¡ wtclarke/nifti_mrs_tools ¡ GitHub? (<300 lines of code).

I could then move nifti_mrs_tools/src/nifti_mrs/definitions.py at master ¡ wtclarke/nifti_mrs_tools ¡ GitHub to be a e.g. json file in GitHub - wtclarke/mrs_nifti_standard: The NIfTI-MRS data standard: specification, code, and example data., and we could both use that to make sure we abide by the standard.

Hi @admin and @wclarke,

Thanks
I wonder something is progressing.
validator.py did not produce any output for nifiti file generated with io_writeniimrs.m

Sorry, I have not gotten to this yet.

Hi,
I have the same problem.
Did you find a solution?

Hanna

Hi both,

you can always use spec2nii extract and spec2nii insert to extract the JSON formatted header, touch it up, and reinsert it into the NIfTI file.

The TR would just need to be a floating point number i.e. have a decimal value, even of .0.

The ProcessingSoftwareVersion should have a format like:

“ProcessingSoftwareVersion”:
    { “Value” : "foo",
      “Description” : “bar”}

Hi @wclarke and @admin

Thanks for responses.

In the case of the nifti file generated with Osprey gui, spec2nii generate following errors:

File “fsl_mrs/lib/pypy3.9/site-packages/nifti_mrs/nifti_mrs.py”, line 125, in init
self._hdr_ext = Hdr_Ext.from_header_ext(
File “fsl_mrs/lib/pypy3.9/site-packages/nifti_mrs/hdr_ext.py”, line 106, in from_header_ext
raise ValueError(f’User-defined key {key} must contain a “Description” field"')
ValueError: User-defined key ProcessingSoftwareVersion must contain a “Description” field"

Is this when you use spec2nii extract? I’m pretty sure I made that able to handle non-compliant files. What version of spec2nii are you using?

Thanks for the response.

I get a similar error message with spec2nii version 0.7.3.

Hanna

Hi
I think I found a (temporary) solution in …/site-packages/nifti_mrs/hdr_ext.py:

I tested spec2nii and fsl_mrs with one un-edited nifti file (preprocessed with Osprey) and it worked
:slight_smile: :grinning: without any error

the extracted json-file is very short in comparison to the json-files extracted from other files, which I preprocessed with fsl-mrs:

{
“SpectrometerFrequency”: [
123.223413
],
“ResonantNucleus”: [
“1H”
],
“dim_5”: “DIM_COIL”,
“dim_6”: “DIM_DYN”

@wclarke, it is v0.7.2 in my case

Bumseok

Do you get this error if you run spec2nii extract path/to/your/file.nii.gz?

yes (with the unmodified Python script)

Huh, any chance you could share an example bit of data?

Hey,
I have asked the PI, but he is on vacation at the moment; it may take a little longer.

Hanna

I’m 90% there with the validator, then onto fixing the Osprey outputs. It would be great if you could convert definitions.py into a JSON file that we both can use! Right now I’ve cloned the definitions with a couple rather clunky structs.

1 Like

Hi all,I have just pushed this commit to the Osprey develop branch that should hopefully fix this.

Fix issues when loading Osprey-processed NIfTI-MRS into FSL:

  • Add a validator function (op_validateniimrs)
  • Custom key ‘ProcessingSoftwareVersion’ now has ‘Value’ and ‘Description’ fields
  • Attempt to force saving TR/TE/TxOffset as double/float, although that may just be a problem of the dcm2nii writing tool!
    (see discussion at Mrs_tool can not read a nifti file generated from osprey)

The validator worked perfectly on all test data in the nifti-mrs-tools test data repo, and also on a bunch of Osprey-processed NIfTI-MRS files that I just generated from our own example data.

@wclarke One tricky issue that might be out of reach for me to fix is forcing to write TR, TE and the transmitter offset as floats when they are in fact integer numbers. This is taken care of by a MATLAB JSON writer in the dcm2nii package we use. It looks like, in my example data, TR is still written out as 2. Upon reading in again, the MATLAB JSON reader still parses the 2 as double/float, so when my validator checks for float/double-ness, it thinks everything is correct. Do you think you can relax the requirements to include integers (which, technically, should be allowable for TR/TE/TxOffset)?

Also note that Osprey is only writing out the standard defined parameters that we currently parse, which doesn’t, by default, include things like PatientWeight. If that’s important to people, I can further work on the headers.

1 Like

Great. I’ll a) translate the python definitions to a generic one and b) make the python interpretation match that of the standard which only specifies ‘number’ (so int/float are allowable where appropriate). I have a bit of time to start this tomorrow.

@Hanna Thanks for the data. I found the issue, and I’ll also fix that tomorrow in nifti-mrs-tools as a more immediate solution.

3 Likes

Fabulous, thanks Will!