Skip to content

Commit 7faf8dd

Browse files
authored
Merge pull request #727 from mgxd/fix/trace
ENH: Support for Philips DICOMs w/ derived volume
2 parents 9430224 + 5181407 commit 7faf8dd

File tree

4 files changed

+48
-4
lines changed

4 files changed

+48
-4
lines changed

nibabel/nicom/dicomwrappers.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
from __future__ import division
1515

1616
import operator
17+
import warnings
1718

1819
import numpy as np
1920

2021
from . import csareader as csar
2122
from .dwiparams import B2q, nearest_pos_semi_def, q2bg
2223
from ..openers import ImageOpener
2324
from ..onetime import setattr_on_read as one_time
24-
from ..pydicom_compat import tag_for_keyword
25+
from ..pydicom_compat import tag_for_keyword, Sequence
2526

2627

2728
class WrapperError(Exception):
@@ -502,8 +503,32 @@ def image_shape(self):
502503
rows, cols = self.get('Rows'), self.get('Columns')
503504
if None in (rows, cols):
504505
raise WrapperError("Rows and/or Columns are empty.")
506+
505507
# Check number of frames
508+
first_frame = self.frames[0]
506509
n_frames = self.get('NumberOfFrames')
510+
# some Philips may have derived images appended
511+
has_derived = False
512+
if hasattr(first_frame, 'get') and first_frame.get([0x18, 0x9117]):
513+
# DWI image may include derived isotropic, ADC or trace volume
514+
try:
515+
self.frames = Sequence(
516+
frame for frame in self.frames if
517+
frame.MRDiffusionSequence[0].DiffusionDirectionality
518+
!= 'ISOTROPIC'
519+
)
520+
except IndexError:
521+
# Sequence tag is found but missing items!
522+
raise WrapperError("Diffusion file missing information")
523+
except AttributeError:
524+
# DiffusionDirectionality tag is not required
525+
pass
526+
else:
527+
if n_frames != len(self.frames):
528+
warnings.warn("Derived images found and removed")
529+
n_frames = len(self.frames)
530+
has_derived = True
531+
507532
assert len(self.frames) == n_frames
508533
frame_indices = np.array(
509534
[frame.FrameContentSequence[0].DimensionIndexValues
@@ -522,6 +547,15 @@ def image_shape(self):
522547
if stackid_tag in dim_seq:
523548
stackid_dim_idx = dim_seq.index(stackid_tag)
524549
frame_indices = np.delete(frame_indices, stackid_dim_idx, axis=1)
550+
dim_seq.pop(stackid_dim_idx)
551+
if has_derived:
552+
# derived volume is included
553+
derived_tag = tag_for_keyword("DiffusionBValue")
554+
if derived_tag not in dim_seq:
555+
raise WrapperError("Missing information, cannot remove indices "
556+
"with confidence.")
557+
derived_dim_idx = dim_seq.index(derived_tag)
558+
frame_indices = np.delete(frame_indices, derived_dim_idx, axis=1)
525559
# account for the 2 additional dimensions (row and column) not included
526560
# in the indices
527561
n_dim = frame_indices.shape[1] + 2
Binary file not shown.

nibabel/nicom/tests/test_dicomwrappers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
DATA_FILE_SLC_NORM = pjoin(IO_DATA_PATH, 'csa_slice_norm.dcm')
3636
DATA_FILE_DEC_RSCL = pjoin(IO_DATA_PATH, 'decimal_rescale.dcm')
3737
DATA_FILE_4D = pjoin(IO_DATA_PATH, '4d_multiframe_test.dcm')
38+
DATA_FILE_4D_DERIVED = pjoin(IO_DATA_PATH, '4d_multiframe_with_derived.dcm')
3839

3940
# This affine from our converted image was shown to match our image spatially
4041
# with an image from SPM DICOM conversion. We checked the matching with SPM
@@ -616,6 +617,13 @@ def test_data_real(self):
616617
assert_equal(sha1(dat_str).hexdigest(),
617618
'149323269b0af92baa7508e19ca315240f77fa8c')
618619

620+
@dicom_test
621+
def test_data_derived_shape(self):
622+
# Test 4D diffusion data with an additional trace volume included
623+
# Excludes the trace volume and generates the correct shape
624+
dw = didw.wrapper_from_file(DATA_FILE_4D_DERIVED)
625+
assert_equal(dw.image_shape, (96, 96, 60, 33))
626+
619627
@dicom_test
620628
def test_data_fake(self):
621629
# Test algorithm for get_data

nibabel/pydicom_compat.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,24 @@
2121
import numpy as np
2222

2323
have_dicom = True
24-
pydicom = read_file = tag_for_keyword = None
24+
pydicom = read_file = tag_for_keyword = Sequence = None
2525

2626
try:
2727
import dicom as pydicom
28-
# Values not imported by default
29-
import dicom.values
3028
except ImportError:
3129
try:
3230
import pydicom
3331
except ImportError:
3432
have_dicom = False
3533
else: # pydicom module available
3634
from pydicom.dicomio import read_file
35+
from pydicom.sequence import Sequence
3736
# Values not imported by default
3837
import pydicom.values
3938
else: # dicom module available
39+
# Values not imported by default
40+
import dicom.values
41+
from dicom.sequence import Sequence
4042
read_file = pydicom.read_file
4143

4244
if have_dicom:

0 commit comments

Comments
 (0)