Unable to get attribute from Philips DICOM: Calculated shape does not match number of frames.
yarikoptic opened this issue · comments
Originally brought to try on these DICOMs in the context of nipy/heudiconv#575 (comment) and trying on Philips DICOMs within http://github.com/neurolabusc/dcm_qa_enh by @neurolabusc for enhanced Philips dicoms for sw 5.3.0:
where attempt to run heudiconv crashed
❯ heudiconv -f convertall -c dcm2niix --bids -o out-heudiconv -s unknown --files Philips
INFO: Running heudiconv version 0.11.6 latest 0.12.0
INFO: Analyzing 3 dicoms
Traceback (most recent call last):
File "/usr/bin/heudiconv", line 33, in <module>
sys.exit(load_entry_point('heudiconv==0.11.6', 'console_scripts', 'heudiconv')())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/heudiconv/cli/run.py", line 24, in main
workflow(**kwargs)
File "/usr/lib/python3/dist-packages/heudiconv/main.py", line 327, in workflow
study_sessions = get_study_sessions(dicom_dir_template, files,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/heudiconv/parser.py", line 178, in get_study_sessions
seqinfo_dict = group_dicoms_into_seqinfos(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/heudiconv/dicoms.py", line 202, in group_dicoms_into_seqinfos
mwinfo = validate_dicom(filename, dcmfilter)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/heudiconv/dicoms.py", line 106, in validate_dicom
del mw.series_signature[sig]
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/nibabel/onetime.py", line 142, in __get__
val = self.getter(obj)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/nibabel/nicom/dicomwrappers.py", line 625, in series_signature
signature['image_shape'] = (self.image_shape, eq)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/nibabel/onetime.py", line 142, in __get__
val = self.getter(obj)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/nibabel/nicom/dicomwrappers.py", line 566, in image_shape
raise WrapperError('Calculated shape does not match number of frames.')
nibabel.nicom.dicomwrappers.WrapperError: Calculated shape does not match number of frames.
I found an oldish fixed issue #693 relating to the same "Effect", and then reproduced with similar minimalish reproducer on a sample file from that repo with master version of nibabel:
❯ python -c 'import nibabel, pydicom, sys; from nibabel.nicom.dicomwrappers import wrapper_from_file; print(nibabel.__version__); mw = wrapper_from_file(sys.argv[1], force=True); print(mw.series_signature)' Philips/IM_0027_fMAP.dcm
<string>:1: UserWarning: The DICOM readers are highly experimental, unstable, and only work for Siemens time-series at the moment
Please use with caution. We would be grateful for your help in improving them
5.1.0.dev90+g3a4cc5e3
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/yoh/proj/nipy/nipy-suite/nibabel-upstream/nibabel/onetime.py", line 156, in __get__
val = self.getter(obj)
^^^^^^^^^^^^^^^^
File "/home/yoh/proj/nipy/nipy-suite/nibabel-upstream/nibabel/nicom/dicomwrappers.py", line 625, in series_signature
signature['image_shape'] = (self.image_shape, eq)
^^^^^^^^^^^^^^^^
File "/home/yoh/proj/nipy/nipy-suite/nibabel-upstream/nibabel/onetime.py", line 156, in __get__
val = self.getter(obj)
^^^^^^^^^^^^^^^^
File "/home/yoh/proj/nipy/nipy-suite/nibabel-upstream/nibabel/nicom/dicomwrappers.py", line 566, in image_shape
raise WrapperError('Calculated shape does not match number of frames.')
nibabel.nicom.dicomwrappers.WrapperError: Calculated shape does not match number of frames.
Yarik, is this something that you can debug and propose a fix for? Do we need to call in Brendan or someone else?
forgot about this one... I will try to do. Relates to #1245 and also not reported here nipy/heudiconv#633 as all are triggered by del mw.series_signature[sig]
more info as instigated from #1296 (comment)
Some DICOM guru might be needed for that ;) FWIW it is the http://github.com/neurolabusc/dcm_qa_fmap repo and we get
❯ dcm2niix -o . IM_0027_fMAP.dcm
Chris Rorden's dcm2niiX version v1.0.20220720 (JP2:OpenJPEG) GCC13.2.0 x86-64 (64-bit Linux)
Found 1 DICOM file(s)
Warning: Philips enhanced DICOMs (hint: export as classic DICOM)
Philips Scaling Values RS:RI:SS = 1.27985:0:8.44864e-06 (see PMC3998685)
Convert 1 DICOM as ./fmap_WIP_B0_NS_20180526150245_801_e1 (64x64x32x1)
Philips Scaling Values RS:RI:SS = 0.2442:-500:4.095 (see PMC3998685)
Convert 1 DICOM as ./fmap_WIP_B0_NS_20180526150245_801_e2_fieldmaphz (64x64x32x1)
Conversion required 0.004854 seconds (0.004851 for core code).
❯ nib-ls *nii
fmap_WIP_B0_NS_20180526150245_801_e1.nii int16 [ 64, 64, 32] 4.00x4.00x4.00 sform
fmap_WIP_B0_NS_20180526150245_801_e2_fieldmaphz.nii int16 [ 64, 64, 32] 4.00x4.00x4.00 sform
(Pdb) l
564 # More than 3 dimensions
565 ns_unique = [len(np.unique(row)) for row in self._frame_indices.T]
566 shape = (rows, cols) + tuple(ns_unique)
567 n_vols = np.prod(shape[3:])
568 if n_frames != n_vols * shape[2]:
569 -> raise WrapperError('Calculated shape does not match number of frames.')
570 return tuple(shape)
571
572 @one_time
573 def image_orient_patient(self):
574 """
(Pdb) p n_frames, n_vols * shape[2]
('64', 128)
*(Pdb) p n_frames, n_vols, shape[2]
('64', 4, 32)
given this crummy script
import sys;
from nibabel.nicom import dicomwrappers as didw;
f=sys.argv[1];
print(f);
shape = didw.wrapper_from_file(f).image_shape
print(shape)
so we clearly could improve code there to at least not compare banas to oranges and make exception more informative....