From d9463a274c83c420f203a24261dbf8871a6efd3f Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 23 Aug 2019 13:26:18 -0400 Subject: [PATCH 01/12] ENH: deprecate Wrapper.get_affine - use affine property To stay inline with the regular interfaces --- nibabel/nicom/dicomwrappers.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nibabel/nicom/dicomwrappers.py b/nibabel/nicom/dicomwrappers.py index 14a92e1c5f..367a846dcb 100755 --- a/nibabel/nicom/dicomwrappers.py +++ b/nibabel/nicom/dicomwrappers.py @@ -23,6 +23,7 @@ from ..openers import ImageOpener from ..onetime import setattr_on_read as one_time from ..pydicom_compat import tag_for_keyword, Sequence +from ..deprecated import deprecate_with_version class WrapperError(Exception): @@ -286,12 +287,16 @@ def get(self, key, default=None): """ Get values from underlying dicom data """ return self.dcm_data.get(key, default) + @deprecate_with_version('get_affine method is deprecated.\n' + 'Please use the ``img.affine`` property ' + 'instead.', + '2.5.1', '4.0') def get_affine(self): - """ Return mapping between voxel and DICOM coordinate system + return self.affine - Parameters - ---------- - None + @property + def affine(self): + """ Mapping between voxel and DICOM coordinate system Returns ------- From 0932c6d118e89f97a6327d61724e79bcae5c934b Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Tue, 10 Sep 2019 21:20:41 -0400 Subject: [PATCH 02/12] DOC: Update docstrings to describe affine property --- nibabel/nicom/dicomwrappers.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/nibabel/nicom/dicomwrappers.py b/nibabel/nicom/dicomwrappers.py index 367a846dcb..bd44e958ae 100755 --- a/nibabel/nicom/dicomwrappers.py +++ b/nibabel/nicom/dicomwrappers.py @@ -96,7 +96,7 @@ class Wrapper(object): Methods: - * get_affine() + * get_affine() (deprecated, use affine property instead) * get_data() * get_pixel_array() * is_same_series(other) @@ -105,6 +105,7 @@ class Wrapper(object): Attributes and things that look like attributes: + * affine : (4, 4) array * dcm_data : object * image_shape : tuple * image_orient_patient : (3,2) array @@ -298,11 +299,8 @@ def get_affine(self): def affine(self): """ Mapping between voxel and DICOM coordinate system - Returns - ------- - aff : (4,4) affine - Affine giving transformation between voxels in data array and - mm in the DICOM patient coordinate system. + (4, 4) affine matrix giving transformation between voxels in data array + and mm in the DICOM patient coordinate system. """ # rotation matrix already accounts for the ij transpose in the # DICOM image orientation patient transform. So. column 0 is From b021b2dffa5b65b013f94c103c5ff5f671830614 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Tue, 10 Sep 2019 21:55:38 -0400 Subject: [PATCH 03/12] TEST: Check for failing GIFTI encodings --- nibabel/gifti/tests/test_gifti.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index f1285d441d..60f7a539ec 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -21,6 +21,7 @@ from nibabel.testing import clear_and_catch_warnings from .test_parse_gifti_fast import (DATA_FILE1, DATA_FILE2, DATA_FILE3, DATA_FILE4, DATA_FILE5, DATA_FILE6) +import itertools def test_gifti_image(): @@ -400,3 +401,20 @@ def test_data_array_round_trip(): gio = GiftiImage.from_file_map(fmap) vertices = gio.darrays[0].data assert_array_equal(vertices, verts) + + +def test_type_coercion(): + dtypes = (np.uint8, np.int32, np.int64, np.float32, np.float64) + encodings = ('ASCII', 'B64BIN', 'B64GZ') + for data_dtype, darray_dtype, encoding in itertools.product(dtypes, + dtypes, + encodings): + da = GiftiDataArray(np.arange(10).astype(data_dtype), + encoding=encoding, + intent='NIFTI_INTENT_NODE_INDEX', + datatype=darray_dtype) + gii = GiftiImage(darrays=[da]) + gii_copy = GiftiImage.from_bytes(gii.to_bytes()) + da_copy = gii_copy.darrays[0] + assert_equal(np.dtype(da_copy.data.dtype), np.dtype(darray_dtype)) + assert_array_equal(da_copy.data, da.data) From 2838c49ddf84981fa1b2a43646ac423340c03861 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Tue, 10 Sep 2019 22:47:01 -0400 Subject: [PATCH 04/12] FIX: Coerce data types on writing GIFTI DataArrays Includes a hack to keep the old data_tag API functional --- nibabel/gifti/gifti.py | 16 ++++++++++------ nibabel/gifti/tests/test_gifti.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index 22d6449e9a..5a69644f8e 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -270,16 +270,21 @@ def _to_xml_element(self): return DataTag(dataarray, encoding, datatype, ordering).to_xml() -def _data_tag_element(dataarray, encoding, datatype, ordering): +def _data_tag_element(dataarray, encoding, dtype, ordering): """ Creates data tag with given `encoding`, returns as XML element """ import zlib - ord = array_index_order_codes.npcode[ordering] + order = array_index_order_codes.npcode[ordering] enclabel = gifti_encoding_codes.label[encoding] if enclabel == 'ASCII': - da = _arr2txt(dataarray, datatype) + # XXX Accommodating data_tag API + # On removal (nibabel 4.0) drop str case + da = _arr2txt(dataarray, dtype if isinstance(dtype, str) else KIND2FMT[dtype.kind]) elif enclabel in ('B64BIN', 'B64GZ'): - out = dataarray.tostring(ord) + # XXX Accommodating data_tag API - don't try to fix dtype + if isinstance(dtype, str): + dtype = dataarray.dtype + out = np.asanyarray(dataarray, dtype).tostring(order) if enclabel == 'B64GZ': out = zlib.compress(out) da = base64.b64encode(out).decode() @@ -462,11 +467,10 @@ def _to_xml_element(self): if self.coordsys is not None: data_array.append(self.coordsys._to_xml_element()) # write data array depending on the encoding - dt_kind = data_type_codes.dtype[self.datatype].kind data_array.append( _data_tag_element(self.data, gifti_encoding_codes.specs[self.encoding], - KIND2FMT[dt_kind], + data_type_codes.dtype[self.datatype], self.ind_ord)) return data_array diff --git a/nibabel/gifti/tests/test_gifti.py b/nibabel/gifti/tests/test_gifti.py index 60f7a539ec..8ef7846f51 100644 --- a/nibabel/gifti/tests/test_gifti.py +++ b/nibabel/gifti/tests/test_gifti.py @@ -403,7 +403,7 @@ def test_data_array_round_trip(): assert_array_equal(vertices, verts) -def test_type_coercion(): +def test_darray_dtype_coercion_failures(): dtypes = (np.uint8, np.int32, np.int64, np.float32, np.float64) encodings = ('ASCII', 'B64BIN', 'B64GZ') for data_dtype, darray_dtype, encoding in itertools.product(dtypes, From 5b4d03afef8cbfa4e90b451a1074fc41081c0c1b Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Fri, 13 Sep 2019 13:50:07 -0400 Subject: [PATCH 05/12] MAINT: Check nightly builds on 3.7 --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e6111e8790..9a98028c2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,7 @@ dist: xenial sudo: true language: python -cache: - directories: - - $HOME/.cache/pip +cache: pip env: global: - DEPENDS="six numpy scipy matplotlib h5py pillow pydicom" @@ -59,8 +57,8 @@ matrix: - python: 2.7 env: - EXTRA_PIP_FLAGS="$PRE_PIP_FLAGS" - # test 3.5 against pre-release builds of everything - - python: 3.5 + # test 3.7 against pre-release builds of everything + - python: 3.7 env: - EXTRA_PIP_FLAGS="$PRE_PIP_FLAGS" - python: 2.7 From 08b5f0f8c4970e70b16354a550336d424900c2ca Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 19 Sep 2019 16:29:29 -0400 Subject: [PATCH 06/12] DOC: Update changelog for upcoming 2.5.1 release --- Changelog | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Changelog b/Changelog index 832e7d0843..fb004c93e3 100644 --- a/Changelog +++ b/Changelog @@ -25,6 +25,33 @@ Eric Larson (EL), Demian Wassermann, and Stephan Gerhard. References like "pr/298" refer to github pull request numbers. +2.5.1 (Monday 23 September 2019) +================================ + +Enhancements +------------ +* Ignore endianness in ``nib-diff`` if values match (pr/799) (YOH, reviewed + by CM) + +Bug fixes +--------- +* Correctly handle Philips DICOMs w/ derived volume (pr/795) (Mathias + Goncalves, reviewed by CM) +* Raise CSA tag limit to 1000, parametrize for future relaxing (pr/798, + backported to 2.5.x in pr/800) (Henry Braun, reviewed by CM, MB) +* Coerce data types to match NIfTI intent codes when writing GIFTI data + arrays (pr/806) (CM, reported by Tom Holroyd) + +Maintenance +----------- +* Require h5py 2.10 for Windows + Python < 3.6 to resolve unexpected dtypes + in Minc2 data (pr/804) (CM, reviewed by YOH) + +API changes and deprecations +---------------------------- +* Deprecate ``nicom.dicomwrappers.Wrapper.get_affine()`` in favor of ``affine`` + property; final removal in nibabel 4.0 (pr/796) (YOH, reviewed by CM) + 2.5.0 (Sunday 4 August 2019) ============================ From d8941fc3b1f6057f67aecd6355844f7bda182e94 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 15 Sep 2019 10:26:37 -0400 Subject: [PATCH 07/12] MAINT: Version 2.5.1 --- nibabel/info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nibabel/info.py b/nibabel/info.py index 12d0dc9d7e..c45e36c8e6 100644 --- a/nibabel/info.py +++ b/nibabel/info.py @@ -19,8 +19,8 @@ _version_major = 2 _version_minor = 5 _version_micro = 1 -_version_extra = 'dev' -# _version_extra = '' +# _version_extra = 'dev' +_version_extra = '' # Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" __version__ = "%s.%s.%s%s" % (_version_major, From bcb4dcc618db5dc0f632e04d71034dc4a281ddc9 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 15 Sep 2019 10:28:05 -0400 Subject: [PATCH 08/12] MAINT: Update zenodo.json --- .zenodo.json | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 16555380a4..a5ce5075aa 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -87,6 +87,11 @@ { "name": "Moloney, Brendan" }, + { + "affiliation": "MIT", + "name": "Goncalves, Mathias", + "orcid": "0000-0002-7252-7771" + }, { "name": "Burns, Christopher" }, @@ -130,11 +135,6 @@ { "name": "Baker, Eric M." }, - { - "affiliation": "MIT", - "name": "Goncalves, Mathias", - "orcid": "0000-0002-7252-7771" - }, { "name": "Hayashi, Soichi" }, @@ -244,6 +244,9 @@ "name": "P\u00e9rez-Garc\u00eda, Fernando", "orcid": "0000-0001-9090-3024" }, + { + "name": "Braun, Henry" + }, { "name": "Solovey, Igor" }, From 28d460ea61560d0f20b3014e1fe03e5e688d80f6 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 15 Sep 2019 10:36:20 -0400 Subject: [PATCH 09/12] DOC: Add Henry Braun to contributor list --- doc/source/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/index.rst b/doc/source/index.rst index ce1db32b86..09f09d4883 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -98,6 +98,7 @@ contributed code and discussion (in rough order of appearance): * Matt Cieslak * Egor Pafilov * Jath Palasubramaniam +* Henry Braun License reprise =============== From 1ab44e7298282fcd718007321439725034100131 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sun, 15 Sep 2019 10:55:59 -0400 Subject: [PATCH 10/12] MAINT: Update setup.cfg nose version to match installation instructions --- setup.cfg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 69bd84afe7..08e8727424 100644 --- a/setup.cfg +++ b/setup.cfg @@ -34,7 +34,8 @@ install_requires = numpy >=1.8 six >=1.3 bz2file ; python_version < "3.0" -tests_require = nose +tests_require = + nose >=0.11 test_suite = nose.collector zip_safe = False packages = find: @@ -46,7 +47,7 @@ dicom = doc = sphinx >=0.3 test = - nose >=0.10.1 + nose >=0.11 all = %(dicom)s %(doc)s From 248b946b5d956b4b80f84006b26630620084d1cc Mon Sep 17 00:00:00 2001 From: Henry Braun Date: Thu, 19 Sep 2019 16:23:03 -0500 Subject: [PATCH 11/12] add @hbraunDSP affiliation and ORCID --- .zenodo.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.zenodo.json b/.zenodo.json index a5ce5075aa..9b4621464f 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -245,7 +245,9 @@ "orcid": "0000-0001-9090-3024" }, { - "name": "Braun, Henry" + "affiliation": "Center for Magnetic Resonance Research, University of Minnesota", + "name": "Braun, Henry", + "orcid": "0000-0001-7003-9822" }, { "name": "Solovey, Igor" From 38342e3acf3c9134bc6eae707af77d931c66bd52 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Mon, 23 Sep 2019 12:02:49 -0400 Subject: [PATCH 12/12] MAINT: 2.5.2-dev --- nibabel/info.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nibabel/info.py b/nibabel/info.py index c45e36c8e6..686baeae01 100644 --- a/nibabel/info.py +++ b/nibabel/info.py @@ -18,9 +18,9 @@ # (pre-release) version. _version_major = 2 _version_minor = 5 -_version_micro = 1 -# _version_extra = 'dev' -_version_extra = '' +_version_micro = 2 +_version_extra = 'dev' +# _version_extra = '' # Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" __version__ = "%s.%s.%s%s" % (_version_major,