Skip to content

dcm2niix node does not error out whenever dcm2niix exits with 1 #3592

Open
@yarikoptic

Description

@yarikoptic

Summary

Originally observed by @dnkennedy while running heudiconv on what appears to be incomplete series. then reproduced on some shorter case of 3 slices dicoms picked up from 10k of them (can't share, didn't find any public ones).

Actual behavior

The point is that if we have

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

reproducing execution with nipype:

import random
from nipype import Node
from nipype.interfaces.dcm2nii import Dcm2niix
import sys
from glob import glob

folder = sys.argv[-1]
files = glob(f"{folder}/*")
print(f"Working on {folder} with {len(files)}")

fromfile = None
convertnode = Node(Dcm2niix(from_file=fromfile), name="convert")
convertnode.base_dir = "/tmp"
convertnode.inputs.source_names = files
convertnode.inputs.out_filename = "/tmp/dcm2niixout%03d" % random.randint(0, 999)
convertnode.terminal_output = "allatonce"
convertnode.inputs.bids_format = True
eg = convertnode.run()
print(f"returncode={eg.runtime.returncode}")

which produces

❯ python /tmp/nipype_convert.py /tmp/ttt; echo $?; ls -l /tmp/ttt
Working on /tmp/ttt with 3
230721-10:38:18,884 nipype.workflow INFO:
	 [Node] Setting-up "convert" in "/tmp/convert".
230721-10:38:18,886 nipype.workflow INFO:
	 [Node] Outdated cache found for "convert".
230721-10:38:18,888 nipype.workflow INFO:
	 [Node] Executing "convert" <nipype.interfaces.dcm2nii.Dcm2niix>
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Chris Rorden's dcm2niiX version v1.0.20220720  (JP2:OpenJPEG) GCC12.1.0 x86-64 (64-bit Linux)
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Found 3 DICOM file(s)
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Slices stacked despite coil variation 'H11' vs 'H7' (use '-m o' to turn off merging)
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Warning: Interslice distance varies in this volume (incompatible with NIfTI format).
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Warning: Missing images? Expected 3 images, but instance number (0020,0013) ranges from 23 to 136
230721-10:38:18,918 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.918151:Convert 3 DICOM as ./tmp/dcm2niixout658_cH11_ph (264x288x3x1)
230721-10:38:18,924 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.924369:Warning: Unable to rotate 3D volume: slices not equidistant: 40 != 73
230721-10:38:18,924 nipype.interface INFO:
	 stdout 2023-07-21T10:38:18.924369:Compress: "/usr/bin/pigz" -n -f -6 "./tmp/dcm2niixout658_cH11_ph.nii"
230721-10:38:18,930 nipype.workflow INFO:
	 [Node] Finished "convert", elapsed time 0.024807s.
returncode=1
0
total 828
-r-------- 1 yoh yoh 282446 Jul 21 10:17 MR.1.3.12.2.1107.5.2.43.167017.2020012914293355999131660
-r-------- 1 yoh yoh 282444 Jul 21 10:17 MR.1.3.12.2.1107.5.2.43.167017.2020012914301930881739443
-r-------- 1 yoh yoh 282440 Jul 21 10:17 MR.1.3.12.2.1107.5.2.43.167017.2020012914320550634554326

so -- it runs, dcm2niix exits with 1, nipype does not fail it, as it does e.g. when dcm2niix exits with 2:

❯ python /tmp/nipype_convert.py /tmp/bogus
Working on /tmp/bogus with 1
230721-10:40:31,406 nipype.workflow INFO:
	 [Node] Setting-up "convert" in "/tmp/convert".
230721-10:40:31,407 nipype.workflow INFO:
	 [Node] Outdated cache found for "convert".
230721-10:40:31,409 nipype.workflow INFO:
	 [Node] Executing "convert" <nipype.interfaces.dcm2nii.Dcm2niix>
230721-10:40:31,439 nipype.interface INFO:
	 stdout 2023-07-21T10:40:31.439841:Chris Rorden's dcm2niiX version v1.0.20220720  (JP2:OpenJPEG) GCC12.1.0 x86-64 (64-bit Linux)
230721-10:40:31,439 nipype.interface INFO:
	 stderr 2023-07-21T10:40:31.439955:Error: Unable to find any DICOM images in /tmp/convert (or subfolders 5 deep)
230721-10:40:31,446 nipype.workflow INFO:
	 [Node] Finished "convert", elapsed time 0.015616s.
230721-10:40:31,446 nipype.workflow WARNING:
	 [Node] Error on "convert" (/tmp/convert)
Traceback (most recent call last):
  File "/tmp/nipype_convert.py", line 18, in <module>
    eg = convertnode.run()
         ^^^^^^^^^^^^^^^^^
  File "/home/yoh/proj/heudiconv/heudiconv-master/venvs/dev3/lib/python3.11/site-packages/nipype/pipeline/engine/nodes.py", line 527, in run
    result = self._run_interface(execute=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yoh/proj/heudiconv/heudiconv-master/venvs/dev3/lib/python3.11/site-packages/nipype/pipeline/engine/nodes.py", line 645, in _run_interface
    return self._run_command(execute)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yoh/proj/heudiconv/heudiconv-master/venvs/dev3/lib/python3.11/site-packages/nipype/pipeline/engine/nodes.py", line 771, in _run_command
    raise NodeExecutionError(msg)
nipype.pipeline.engine.nodes.NodeExecutionError: Exception raised while executing Node convert.

Cmdline:
	dcm2niix -b y -z y -x n -t n -m n -f /tmp/dcm2niixout592 -o . -s n -v n /tmp/convert
Stdout:
	Chris Rorden's dcm2niiX version v1.0.20220720  (JP2:OpenJPEG) GCC12.1.0 x86-64 (64-bit Linux)
Stderr:
	Error: Unable to find any DICOM images in /tmp/convert (or subfolders 5 deep)
Traceback:
	RuntimeError: subprocess exited with code 2.

Expected behavior

have an exception similar to when exits with code 2

How to replicate the behavior

see above by BYOBD (bring your own broken dicom)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions