nipy / nibabel

Python package to access a cacophony of neuro-imaging file formats

Home Page:http://nipy.org/nibabel/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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....