rordenlab / dcm2niix

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

Question: sample of public DICOMs with incomplete acquisition #733

Closed yarikoptic closed 1 year ago

yarikoptic commented 1 year ago

which would lead dcm2niix to exit with exit code 1, not 2. E.g. dicom files per slice for bold but having 1 complete volume and one partial, or alike leading to smth like

❯ cd /tmp/ttt
MR.1.3.12.2.1107.5.2.43.167017.2020012914293355999131660  MR.1.3.12.2.1107.5.2.43.167017.2020012914301930881739443  MR.1.3.12.2.1107.5.2.43.167017.2020012914320550634554326
❯ dcm2niix -z y .
Chris Rorden's dcm2niiX version v1.0.20220720  (JP2:OpenJPEG) GCC12.1.0 x86-64 (64-bit Linux)
Found 3 DICOM file(s)
Slices stacked despite coil variation 'H1' vs 'H7' (use '-m o' to turn off merging)
Warning: Interslice distance varies in this volume (incompatible with NIfTI format).
Warning: Missing images? Expected 3 images, but instance number (0020,0013) ranges from 23 to 136
Convert 3 DICOM as ./_swi_acq-QSMX3echos_20200129132019_26_cH11_ph (264x288x3x1)
Warning: Unable to rotate 3D volume: slices not equidistant: 40 != 73
Compress: "/usr/bin/pigz" -n -f -6 "./_swi_acq-QSMX3echos_20200129132019_26_cH11_ph.nii"
❯ echo $?
1

needed for testing https://github.com/nipy/heudiconv/pull/695 which came up due to https://github.com/nipy/nipype/issues/3592

neurolabusc commented 1 year ago

Exit code 0 is for success, exit code 1 is the undefined error. Other exit codes are for clearly defined errors. Your problem is that the DICOM standard does not require instance number to be sequential or even unique. Therefore, while the sparse ordering of the instance numbers might give the user a clue, this could also be a completely valid DICOM. This also explains why the text outputs are warning not errors: they are unexpected and might provide the user with a clue for diagnosis, but are not clear violations of the standard.

//EXIT_SUCCESS 0
//EXIT_FAILURE 1
#define kEXIT_NO_VALID_FILES_FOUND  2
#define kEXIT_REPORT_VERSION  3
#define kEXIT_CORRUPT_FILE_FOUND  4
#define kEXIT_INPUT_FOLDER_INVALID  5
#define kEXIT_OUTPUT_FOLDER_INVALID  6
#define kEXIT_OUTPUT_FOLDER_READ_ONLY  7
#define kEXIT_SOME_OK_SOME_BAD  8
#define kEXIT_RENAME_ERROR  9
#define kEXIT_INCOMPLETE_VOLUMES_FOUND  10 //issue 515
#define kEXIT_NOMINAL  11 //did not expect to convert files

Likewise, while the NIfTI standard requires all 2D slices in a 3D volume are equidistant, this is not a constraint for DICOM. Indeed, it is common for DICOM CT scans of the head to have fine slicing near the life-critical brain stem and coarse slicing for the cortex.

In brief, since the DICOM images do not report the total number of images in a series and allow variable gaps between slices, it is hard to determine if files are missing or if a sparse volume was intended. This issue should vanish as we move to enhanced DICOM where an entire series is saved in a single file (or for Siemens an entire 3D volume) which prevents problems with copying some but not all files.

yarikoptic commented 1 year ago

Thank you @neurolabusc for the detailed description. FWIW, I have submitted a fix to nipype to reflect the fact that exit 1 is also an error: https://github.com/yarikoptic/nipype/commit/be5b9088492b655f9cd6d007f131688026c12682 . The question/issue was primarily to just find some dicoms which would make dcm2niix exit with exit code 1. What would be the lightweightest repo/use case for that?

neurolabusc commented 1 year ago

Since EXIT_FAILURE is the generic, undefined error there are many ways to elicit it. Perhaps the easiest way with an existing validation DICOM dataset is two run dcm2niix twice, the first time forcing it to overwrite existing data (-w 1) and the second time forcing it to skip the existing files. The second run will generate warnings that it is skipping files to avoid name conflicts and it generates the generic EXIT_FAILURE.

./dcm2niix -b y -w 1 /path/to/dicoms
./dcm2niix -b y -w 0 /path/to/dicoms
neurolabusc commented 1 year ago

As an aside, all errors except EXIT_FAILURE are specific and suggest hard failures. The generic EXIT_FAILURE may be in the eye of the beholder: the software may be unaware if this was the intended behavior.

yarikoptic commented 1 year ago

thanks for the example @neurolabusc , I will see if I could use it.

The generic EXIT_FAILURE may be in the eye of the beholder: the software may be unaware if this was the intended behavior.

not sure if I follow really. What matters to me is that it is a failure - non-0 code means that execution did not succeed normally, even if potentially produced some files, and we should not just blindly ignore that.