From 61b198deea75854c3c0206f8bf59ede1ef0fe1d3 Mon Sep 17 00:00:00 2001 From: Brendan Moloney Date: Thu, 17 Dec 2015 16:23:40 -0800 Subject: [PATCH 1/3] BF+TST: Skip over missing CSA header elem instead of raising. Allows us to load data where the PrivateCreator is present but the element containing the header info is not. Ran into this with anonymized data. --- nibabel/nicom/csareader.py | 6 ++++-- nibabel/nicom/tests/test_csareader.py | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/nibabel/nicom/csareader.py b/nibabel/nicom/csareader.py index c42e37fb2a..f19bc0c7f0 100644 --- a/nibabel/nicom/csareader.py +++ b/nibabel/nicom/csareader.py @@ -63,8 +63,10 @@ def get_csa_header(dcm_data, csa_type='image'): if section_start is None: return None element_no = section_start + element_offset - # Assume tag exists - tag = dcm_data[(0x29, element_no)] + try: + tag = dcm_data[(0x29, element_no)] + except KeyError: + return None return read(tag.value) diff --git a/nibabel/nicom/tests/test_csareader.py b/nibabel/nicom/tests/test_csareader.py index ffef46ae44..04e26a2395 100644 --- a/nibabel/nicom/tests/test_csareader.py +++ b/nibabel/nicom/tests/test_csareader.py @@ -1,6 +1,7 @@ """ Testing Siemens CSA header reader """ from os.path import join as pjoin +from copy import deepcopy import gzip import numpy as np @@ -13,6 +14,8 @@ from .test_dicomwrappers import (have_dicom, dicom_test, IO_DATA_PATH, DATA, DATA_FILE) +if have_dicom: + from .test_dicomwrappers import pydicom CSA2_B0 = open(pjoin(IO_DATA_PATH, 'csa2_b0.bin'), 'rb').read() CSA2_B1000 = open(pjoin(IO_DATA_PATH, 'csa2_b1000.bin'), 'rb').read() @@ -128,3 +131,15 @@ def test_ice_dims(): assert_equal(csa.get_ice_dims(csa_info), ex_dims) assert_equal(csa.get_ice_dims({}), None) + + +@dicom_test +def test_missing_csa_elem(): + # Test that we get None instead of raising an Exception when the file has + # the PrivateCreator element for the CSA dict but not the element with the + # actual CSA header (perhaps due to anonymization) + dcm = deepcopy(DATA) + csa_tag = pydicom.tag.Tag(0x29, 0x1010) + del dcm[csa_tag] + hdr = csa.get_csa_header(dcm, 'image') + assert_equal(hdr, None) From 854b817a7134f9c4fb504c135fcb4479391f0ad1 Mon Sep 17 00:00:00 2001 From: Brendan Moloney Date: Wed, 2 Mar 2016 18:10:05 -0800 Subject: [PATCH 2/3] RF: Move dicom import into test function Include a comment about why the tag might be missing. --- nibabel/nicom/csareader.py | 1 + nibabel/nicom/tests/test_csareader.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nibabel/nicom/csareader.py b/nibabel/nicom/csareader.py index f19bc0c7f0..cba9e39e34 100644 --- a/nibabel/nicom/csareader.py +++ b/nibabel/nicom/csareader.py @@ -66,6 +66,7 @@ def get_csa_header(dcm_data, csa_type='image'): try: tag = dcm_data[(0x29, element_no)] except KeyError: + # The element could be missing due to anonymization return None return read(tag.value) diff --git a/nibabel/nicom/tests/test_csareader.py b/nibabel/nicom/tests/test_csareader.py index 04e26a2395..a95e49ad3a 100644 --- a/nibabel/nicom/tests/test_csareader.py +++ b/nibabel/nicom/tests/test_csareader.py @@ -14,8 +14,6 @@ from .test_dicomwrappers import (have_dicom, dicom_test, IO_DATA_PATH, DATA, DATA_FILE) -if have_dicom: - from .test_dicomwrappers import pydicom CSA2_B0 = open(pjoin(IO_DATA_PATH, 'csa2_b0.bin'), 'rb').read() CSA2_B1000 = open(pjoin(IO_DATA_PATH, 'csa2_b1000.bin'), 'rb').read() @@ -138,8 +136,12 @@ def test_missing_csa_elem(): # Test that we get None instead of raising an Exception when the file has # the PrivateCreator element for the CSA dict but not the element with the # actual CSA header (perhaps due to anonymization) + try: + from dicom.tag import Tag + except ImportError: + from pydicom.tag import Tag dcm = deepcopy(DATA) - csa_tag = pydicom.tag.Tag(0x29, 0x1010) + csa_tag = Tag(0x29, 0x1010) del dcm[csa_tag] hdr = csa.get_csa_header(dcm, 'image') assert_equal(hdr, None) From 1faade29a74155b6709f5a12c486c558e521516f Mon Sep 17 00:00:00 2001 From: Brendan Moloney Date: Wed, 2 Mar 2016 18:34:17 -0800 Subject: [PATCH 3/3] RF: Skip test for python < 2.6 and pydicom < 1.0 Move pydicom import back to top level of module since we need its version info for skipping the test, plus this removes duplicate logic for importing 'pydicom' vs 'dicom'. Updated test_csa_header_read to use the top level import as well. --- nibabel/nicom/tests/test_csareader.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/nibabel/nicom/tests/test_csareader.py b/nibabel/nicom/tests/test_csareader.py index a95e49ad3a..d9066bff6c 100644 --- a/nibabel/nicom/tests/test_csareader.py +++ b/nibabel/nicom/tests/test_csareader.py @@ -1,5 +1,6 @@ """ Testing Siemens CSA header reader """ +import sys from os.path import join as pjoin from copy import deepcopy import gzip @@ -11,9 +12,12 @@ from nose.tools import (assert_true, assert_false, assert_equal, assert_raises) +from numpy.testing.decorators import skipif from .test_dicomwrappers import (have_dicom, dicom_test, IO_DATA_PATH, DATA, DATA_FILE) +if have_dicom: + from .test_dicomwrappers import pydicom CSA2_B0 = open(pjoin(IO_DATA_PATH, 'csa2_b0.bin'), 'rb').read() CSA2_B1000 = open(pjoin(IO_DATA_PATH, 'csa2_b1000.bin'), 'rb').read() @@ -31,11 +35,7 @@ def test_csa_header_read(): assert_true(csa.is_mosaic(hdr)) # Get a shallow copy of the data, lacking the CSA marker # Need to do it this way because del appears broken in pydicom 0.9.7 - try: - from dicom.dataset import Dataset - except ImportError: - from pydicom.dataset import Dataset - data2 = Dataset() + data2 = pydicom.dataset.Dataset() for element in DATA: if (element.tag.group, element.tag.elem) != (0x29, 0x10): data2.add(element) @@ -132,16 +132,14 @@ def test_ice_dims(): @dicom_test +@skipif(sys.version_info < (2,7) and pydicom.__version__ < '1.0', + 'Known issue for python 2.6 and pydicom < 1.0') def test_missing_csa_elem(): # Test that we get None instead of raising an Exception when the file has # the PrivateCreator element for the CSA dict but not the element with the # actual CSA header (perhaps due to anonymization) - try: - from dicom.tag import Tag - except ImportError: - from pydicom.tag import Tag dcm = deepcopy(DATA) - csa_tag = Tag(0x29, 0x1010) + csa_tag = pydicom.dataset.Tag(0x29, 0x1010) del dcm[csa_tag] hdr = csa.get_csa_header(dcm, 'image') assert_equal(hdr, None)