rordenlab / dcm2niix

dcm2nii DICOM to NIfTI converter: compiled versions available from NITRC
https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage
Other
864 stars 228 forks source link

Add Return Codes other than 0 #834

Closed toomanycats closed 2 months ago

toomanycats commented 2 months ago

I often wrap dcm2niix in Python programs. When I get a set of DICOMs that I expect to form a single NiFTI, but instead get 2 or move volumes, the return code is still 0.

It would be a lot easier to handle these cases with a more descriptive return code.

TIA

neurolabusc commented 2 months ago

@toomanycats does dcm2niix generate any warnings, or is this your personal preference that these series should be concatenated or not? I really do not know what your issue is. In general, dcm2niix returns 0 for nominal behavior. If you provide two DICOM series, the expected behavior is typically to create multiple images. Sometimes the BIDS/NIfTI format expects multiple images from a single series, for example scout localizer series where different slices have a different orientation (you can ignore these with -i y). Another example is 5D series like multi-echo fMRI, where each echo is saved as its own 4D time series.

toomanycats commented 2 months ago

Hi Chris. Yes, I'm getting what I interpret as a warning, to stdout that's there's two echo times. All the DICOMs have the same series number and the same seriesInstanceUID. I think this might be a case where the T2 is designed to have multiple echo times which I've never encountered before.

$ dcm2niix -o ~ -f %d .
Chris Rorden's dcm2niiX version v1.0.20240202  (JP2:OpenJPEG) (JP-LS:CharLS) GCC8.4.0 x86-64 (64-bit Linux)
Found 440 DICOM file(s)
Slices not stacked: echo varies (TE 22.35, 18.44; echo 5, 4). Use 'merge 2D slices' option to force stacking
Convert 88 DICOM as /home/Axial_3D_ME_T2_GRE_(MSV21)_e5 (384x384x88x1)
Convert 88 DICOM as /home/Axial_3D_ME_T2_GRE_(MSV21)_e4 (384x384x88x1)
Convert 88 DICOM as /home/Axial_3D_ME_T2_GRE_(MSV21)_e3 (384x384x88x1)
Convert 88 DICOM as /home/Axial_3D_ME_T2_GRE_(MSV21)_e2 (384x384x88x1)
Convert 88 DICOM as /home/Axial_3D_ME_T2_GRE_(MSV21)_e1 (384x384x88x1)
Conversion required 1.973585 seconds (0.790000 for core code).
$ find . | xargs dcmdump | grep '(0020,000e)' | sort | uniq
W: ignoring directory because option --scan-directories is not set: .
(0020,000e) UI [1.3.12.2.1107.5.2.19.45205.30000024013120302937700001448] #  56, 1 SeriesInstanceUID
 vhasfccuneod@grapenuts  /tmp/tmpvtien0v_ 
$ find . | xargs dcmdump | grep '(0020,0011)' | sort | uniq
W: ignoring directory because option --scan-directories is not set: .
(0020,0011) IS [10]   

For 90 % of my work, I don't know anything about the study, I'm told to stack DICOMs. Our lab has a formal importation process that groups DICOMs by their series number. Most series are therefore in neat directories one per image. That way it's easy to see what's the T1, T2, fMRI, etc.

Of course we have multi volume NiFITI's for fMRI or sometimes field maps.

What is difficult, is when you return a warning on stdout but return 0. I don't know anything about the images I'm working with until much later in the pipeline or never. What I do now, is parse the stdout for all possible issues which means I have to encounter every possible issue first.

To a guy stacking thousands of volumes a year, I'd like to be able to watch a return code. Greater than zero could mean something unusual occurred but it was handled and negative can be actual errors. Of course this assumes that the expectation is one NiFTI per series.

Another instance was when I had one DICOM out of 90 that was void of data. dcm2niix didn't stack that 90th DICOM and returns 0. The general expectation is that all 90 DICOMs would make it into a volume b/c they all belong to the series.

If you don't want to use return codes then consider printing warnings to stderr. Then I can assume anything from that stream is a problem I need to handle.

In my experience, there's programs that belong to services that don't really need to report much as long as they don't crash. Then there's user programs that should tell the user as much as possible.

neurolabusc commented 2 months ago

The BIDS standard demands that multi-echo data **MUST** be split into one file per echo. Therefore, returning a zero is appropriate as this is nominal behavior.

With regards to the 1 file in 90 that has void data, it is hard to provide feedback without seeing the data. If possible, send an example of these DICOMs to my institutional email. Note that DICOM series are not required to have equidistant slices (CT scans often have variable slice distances), are not required to have sequential (or even unique) instance numbers, and are not required (and rarely do) to report the total number of images in a series. Therefore, for most manufacturers, it can be impossible to discriminate a situation where 89 of 90 images have been saved versus one where all 90 images have been saved. dcm2niix has manufacturer-specific logic to detect many edge cases. However, there are valid DICOM implementations that make robust error detection difficult.

dcm2niix will use non-zero return codes for clearly defined errors. However, the heterogeneity of the DICOM implementations and users expectations mean that not all data corruptions are identifiable and for some users a poor result is a successful result for others.

toomanycats commented 2 months ago

I see thanks for the explanation. I'm not fan of BIDS in fact I hate it with a passion.