4D DICOM concatenates volumes along Z

Hello,

I feel like this question has come up before, so feel free to direct me to a mailing-list post but I couldn’t find one that fixed my issue. I also apologise in advance if any of my terminology is wrong, my DICOM knowledge isn’t great.

I am trying to read a multi-volume, multi-echo, multi-series (magnitude, real & imaginary images) DICOM and save it as multiple 4D NIFTIs. I am following the example code from https://itk.org/ITKExamples/src/IO/GDCM/ReadDICOMSeriesAndWrite3DImage/Documentation.html. I have added the tags for Echo Number and Image Type to AddSeriesRestriction(), and changed the dimension of the Reader and Writer to 4. However, while this correctly splits the echos/image types, instead of getting a 4D NIFTI out, all the volumes are concatenated along Z and I get massive 3D NIFTIs instead.

Is there something extra I have to add to read a 4D NIFTI? One thing I have noticed is that in the DICOM tags there does not appear to be any tag for volume/timepoint, is this messing things up?

The DICOMs were acquired on a GE MRI scanner. I am using ITK from master (is that also an issue)? If it would help to upload the DICOMs somewhere I can do that.

Thanks,
Toby

Getting 3D time points from a 4D DICOM series is very difficult, as it is different for each imaging modality, acquisition type, and vendor implementation. In the last couple of years, we implemented in 3D Slicer 5 basic strategies to group/sort images (see multi-volume importer plugin source in 3D Slicer) that covers most cases, but still we have to keep adding new variants as we come across more images. Also, there are multiple valid grouping options for a data set: e.g., you can group image slices according to their absolute acquisition time, or based on their acquisition time with the heart cycle. We use some consistency checks to make loading more robust, but it causes some of the valid datasets fail to load (for example, slice positions or number of slices are not always equal in each time point).

Probably interpretation of a few commonly used image types could be implemented in ITK, but I don’t think it is realistic to implement a solution in ITK that would read all 4D data sets. Maybe a solution could be to implement a plugin infrastructure in ITK similarly to 3D Slicer’s DICOM plugins: DICOM loader passes the data to each registered DICOM plugin for examination, each plugin examines the data and returns what information it can load from it, finally the DICOM loader chooses most likely valid interpretation (if there are multiple possible interpretations then the user may be offered to choose one). A few plugins could be maintained in ITK proper and users could add their own rules that would cover image types in their field of use.

1 Like

DICOMs also have image date and time, e.g.

(0008,0023)	Image Date    VR: DA	Length: 8	 Value: 20090306
(0008,0030)	Study Time    VR: TM	Length: 6	 Value: 092725

I suppose that what gets written into the time is not standardized. With a single 3D volume the times of individual slices are mostly irrelevant. But for a 4D series they are not. If all slices within a time-point have the same time, it is easy. But for different slices mostly having different times (a single 3D “time-point” takes several seconds to acquire), it is harder to group slices into time-points.

@lassoan has more experience with this, and managed to answer quicker :smiley:

Thanks for the input. This looks like it will be harder than I hoped.

Sadly, the timing tags appear to be useless in this case. The Study Time tag is the same for all the files. There is a (0018,1060) TriggerTime which does change, but in what appears to be an inconsistent fashion that I can’t work out.

What I am surprised by is that there doesn’t appear to be a DICOM tag for the number of “slices” acquired? There is (0020,9057) InStackPositionNumber, but the actual numbers don’t make much sense (the very first DICOM file has this set to 3, for instance). If the number of slices could be extracted from the tags, then the number of volumes is the number of DICOMs in the series / number of slices. However, that’s so obvious I’m sure it’s already been thought of?

Sorry for replying to myself - I have just found tag (0025,1011) NumberOfAcquisitions, which in this case is the number of volumes. So the opposite strategy of dividing the number of DICOMs by the number of acquisitions by the number of volumes would give the correct number of slices.

(I’m having some trouble getting dcmdump from dcmtk to read my GE tag dictionary correctly, which is why I had missed this. The GE tag dictionary does have multiple tags that could be used to set the number of slices, but none of them are present in these DICOMs!)

EDIT: I’ve had another look at this, and sadly the 0025,1011 tag does not seem to make it into the meta-data I can read with ITK. The DICOM tags only seem to be available through the GDCMImageIO object - the meta-data dictionaries for the ImageSeriesReader and GDCMSeriesFileNames are both empty. But the 0025,1011 tag is not listed in the available keys.

If I can get access to that tag somehow, then I can use the various splitter/tiling classes to manipulate the image into the correct dimensions.

1 Like

(I think my edit to the above post might have been missed as I made it too long after the original post)

To summarise my current issue - not all the DICOM tags appear to make it through into the MetaDataDictionary that can be accessed from the GDCMImageIO object. In particular, I think I can solve my problems if I can get the tag 0025,1011. Am I missing something easy to read in every tag in a DICOM header?

Have you tried to enable loading of private tags?

2 Likes

I totally missed that, sorry! Thanks @dzenanz, I can read the tag now.

1 Like

Check out Slicer’s DICOM importer plugin for common strategies for determining which slice belongs to which volume: https://github.com/fedorov/MultiVolumeImporter/blob/a85d4566f0b292773b3f28e06305e2e4d2cf3ca2/MultiVolumeImporterPlugin.py

Usually you have to go through all slices, sort them by spatial position and at least one more sorting tag - see commonly used sorting tags here:

Many of them are in private fields and you may need to parse them or interpret in some combination.

By they way, have you tested if Slicer’s DICOM importer can interpret your data correctly?

1 Like