DICOM meta read/write issue

Update: See my last post in this series for my workaround.

I have come across an issue with Orthanc reading and presenting meta data from the DICOM headers.

Specifically, the issue is occurring for (0018,9089) DiffusionGradientOrientation fields.

Orthanc’s meta data reader appears (randomly? always?) to be prepending “0” values with a negative: “-0”.

Note that these are Siemens MR enhanced (multi-frame) DICOM. I have not tested whether this occurs with old legacy non-enhanced DICOM.

For example, DCMTK dcmdump reports:

dcmdump +P DiffusionGradientOrientation MR000004.dcm
(0018,9089) FD -0.9999992847442627\0.0012499971780925989\0 #  24, 3 DiffusionGradientOrientation

While the Orthanc browser (and RestAPI) returns:
0018,9089 (DiffusionGradientOrientation): -0.9999992847442627\0.0012499971780925989\-0

When it comes time to write this data back OUT to a modified DICOM, the Orthanc writer complains of “out-of-range” errors:

While creating a DICOM instance, tag (0018,9089) has out-of-range value: "-0.9999992847442627\0.0012499971780925989\-0"

I tried with the GDCM turned on and off with the same result.

I am assuming this is related to the “-0”, but maybe it’s a mismatch in the floating point precision between the reader/writer? Has Siemens violated the current standard with their high precision meta data? Maybe one of the other values has too many decimal places for the writer?

I am working with the latest orthancteam image from Dockerhub:

{
   "ApiVersion" : 24,
   "CheckRevisions" : false,
   ...
   "IngestTranscoding" : "",
   "IsHttpServerSecure" : true,
   ...
   "PluginsEnabled" : true,
   "StorageAreaPlugin" : null,
   "StorageCompression" : false,
   ...
   "Version" : "1.12.4"
}

If you need an example DICOM, I will see about acquiring some phantom data. All I have is research subject data at the moment and I can’t share their meta data.

John.

Update: Depending on the random order in which I process files, I am seeing the same error for other diffusion gradient orientation values (other than “-0”):

Bad file format: While creating a DICOM instance, tag (0018,9089) has out-of-range value: "0\0.0012499971780925989\0.9999992847442627"

If I am reading the standard correctly for 0018,9089, the floats have a VR of FD (double).

So maybe this is a discrepancy between the input reader (allows double) and output writer (assumes float)?

John.

I am now wondering if this is an issue of json.loads and json.dumps conversions when going back and forth between reading in the existing data, modifying it and then writing it to the new DICOM.

I could see where some of the slash escapes “\” might fall out of the process and then you end up with incorrect strings being converted by the final json argument to the rest api.

Essentially, I have an original dicom, I read in the tags with /instances/ID/simplified-tags, convert to a python dictionary with json.loads, modiffy my tag values, and then call the instances/ID/modify with json.dumps of my modified python dictionary as the input. This all happens within the Python plugin using orthanc.RestApiGet/Post calls.

I suppose there is an opportunity in there to lose proper slash escaping “\”.

However, if that were true, I should have encountered errors long ago with non-Diffusion stuff like ImageType, which also has double slash escapes as part of the string value.

John.

The problem: Modifying some (but not all) fields in nested DICOM sequences.

Upon inspection of some of my other Orthancs, I realized I had already encountered something like this problem before back in 2021 and Sebastien and the Orthanc team introduced a targeted approach to changing values in nested DICOM sequences.

Workaround: Use targeted key/value pairs in the ‘Replace’ data when running a modify

What’s Not Working:
To update some fields in a nested DICOM sequence, I was doing something like:

  1. Copy entire nested sequence into a python dictionary
  2. Modify the particular fields I wanted changed
  3. Send the whole dictionary as ‘Replace’ data in a call to the Orthanc modify API
copy_to_modify = json.loads(json.dumps(dicom_data['TopLevelSequence']))
copy_to_modify[0]['ChildSequence'][0]['FieldName'] = 'new value'
replace_data={'TopLevelField1' : 'new value1',
              'TopLevelField2' : 'new value2',
              'TopLevelSequence' : copy_to_modify}

This approach is inefficient but was working for most DICOM. The current problematic DICOM have nested DiffusionGradientOrientation vector data. I was not modifying this data, but it was not surviving the process of conversion to/from a python dictionary while I worked on it in Python. This probably means that somewhere in the conversions, the backslash character in the vector representation is not being preserved as-is but is being treated by Python as an escape character.

What Works
Rather than sending a complicated nested Python dictionary as the replace data, use a simple flat Python dictionary where the keys themselves target the nested data you want to update:

replace_data = {'TopLevelField1' : 'new value1',
                'TopLevelField2' : 'new value2',
                'TopLevelSequence[0].ChildSequence[0].FieldName' : 'new value'}

assuming I only want to modify the value of FieldName in the first dictionary of the first child of the TopLevelSequence.

1 Like