Skip to content

Commit 17fdcc0

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rel/2.4.0
2 parents 570cdc1 + 14083e8 commit 17fdcc0

File tree

11 files changed

+117
-38
lines changed

11 files changed

+117
-38
lines changed

COPYING

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ documentation is covered by the MIT license.
1818

1919
The MIT License
2020

21-
Copyright (c) 2009-2014 Matthew Brett <[email protected]>
21+
Copyright (c) 2009-2019 Matthew Brett <[email protected]>
2222
Copyright (c) 2010-2013 Stephan Gerhard <[email protected]>
2323
Copyright (c) 2006-2014 Michael Hanke <[email protected]>
2424
Copyright (c) 2011 Christian Haselgrove <[email protected]>
2525
Copyright (c) 2010-2011 Jarrod Millman <[email protected]>
26-
Copyright (c) 2011-2014 Yaroslav Halchenko <[email protected]>
26+
Copyright (c) 2011-2019 Yaroslav Halchenko <[email protected]>
27+
Copyright (c) 2015-2019 Chris Markiewicz <[email protected]>
2728

2829
Permission is hereby granted, free of charge, to any person obtaining a copy
2930
of this software and associated documentation files (the "Software"), to deal

Changelog

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ The full VCS changelog is available here:
1818
Nibabel releases
1919
****************
2020

21-
Most work on NiBabel so far has been by Matthew Brett (MB), Michael Hanke (MH)
22-
Ben Cipollini (BC), Marc-Alexandre Côté (MC), Chris Markiewicz (CM), Stephan
23-
Gerhard (SG), Eric Larson (EL), Yaroslav Halchenko (YOH) and Chris Cheng (CC).
21+
Most work on NiBabel so far has been by Matthew Brett (MB), Chris Markiewicz
22+
(CM), Michael Hanke (MH), Marc-Alexandre Côté (MC), Ben Cipollini (BC), Paul
23+
McCarthy (PM), Chris Cheng (CC), Yaroslav Halchenko (YOH), Satra Ghosh (SG),
24+
Eric Larson (EL), Demien Wasserman, and Stephan Gerhard.
2425

2526
References like "pr/298" refer to github pull request numbers.
2627

@@ -134,16 +135,16 @@ Enhancements
134135
* Simplfiy MGHImage and add footer fields (pr/569) (CM, reviewed by MB)
135136
* Force sform/qform codes to be ints, rather than numpy types (pr/575) (Paul
136137
McCarthy, reviewed by MB, CM)
137-
* Auto-fill color table in FreeSurfer annotation file (pr/592) (Paul McCarthy,
138+
* Auto-fill color table in FreeSurfer annotation file (pr/592) (PM,
138139
reviewed by CM, MB)
139140
* Set default intent code for CIFTI2 images (pr/604) (Mathias Goncalves,
140-
reviewed by CM, Satra Ghosh, MB, Tim Coalson)
141+
reviewed by CM, SG, MB, Tim Coalson)
141142
* Raise informative error on empty files (pr/611) (Pradeep Raamana, reviewed
142143
by CM, MB)
143144
* Accept degenerate filenames such as ``.nii`` (pr/621) (Dimitri
144145
Papadopoulos-Orfanos, reviewed by Yaroslav Halchenko)
145146
* Take advantage of ``IndexedGzipFile`` ``drop_handles`` flag to release
146-
filehandles by default (pr/614) (Paul McCarthy, reviewed by CM, MB)
147+
filehandles by default (pr/614) (PM, reviewed by CM, MB)
147148

148149
Bug fixes
149150
---------
@@ -153,7 +154,7 @@ Bug fixes
153154
CM, MB)
154155
* Accept lower-case orientation codes in TRK files (pr/600) (Kesshi Jordan,
155156
MB, reviewed by MB, MC, CM)
156-
* Annotation file reading (pr/592) (Paul McCarthy, reviewed by CM, MB)
157+
* Annotation file reading (pr/592) (PM, reviewed by CM, MB)
157158
* Fix buffer size calculation in ArraySequence (pr/597) (Serge Koudoro,
158159
reviewed by MC, MB, Eleftherios Garyfallidis, CM)
159160
* Resolve ``UnboundLocalError`` in Python 3 (pr/607) (Jakub Kaczmarzyk,
@@ -193,14 +194,14 @@ Bug fixes
193194

194195
* Set L/R labels in orthoview correctly (pr/564) (CM)
195196
* Defer use of ufunc / memmap test - allows "freezing" (pr/572) (MB, reviewed
196-
by Satra Ghosh)
197+
by SG)
197198
* Fix doctest failures with pre-release numpy (pr/582) (MB, reviewed by CM)
198199

199200
Maintenance
200201
-----------
201202

202-
* Update documentation around NIfTI qform/sform codes (pr/576) (Paul McCarthy,
203-
reviewed by MB, CM) + (pr/580) (Bennet Fauber, reviewed by Paul McCarthy)
203+
* Update documentation around NIfTI qform/sform codes (pr/576) (PM,
204+
reviewed by MB, CM) + (pr/580) (Bennet Fauber, reviewed by PM)
204205
* Skip precision test on macOS, newer numpy (pr/583) (MB, reviewed by CM)
205206
* Simplify AppVeyor script, removing conda (pr/584) (MB, reviewed by CM)
206207

@@ -210,12 +211,11 @@ Maintenance
210211
New features
211212
------------
212213

213-
* CIFTI support (pr/249) (Satra Ghosh, Michiel Cottaar, BC, CM, Demian
214-
Wassermann, MB)
214+
* CIFTI support (pr/249) (SG, Michiel Cottaar, BC, CM, Demian Wasserman, MB)
215215
* Support for MRtrix TCK streamlines file format (pr/486) (MC, reviewed by
216216
MB, Arnaud Bore, J-Donald Tournier, Jean-Christophe Houde)
217217
* Added ``get_fdata()`` as default method to retrieve scaled floating point
218-
data from ``DataobjImage``s (pr/551) (MB, reviewed by CM, Satra Ghosh)
218+
data from ``DataobjImage``s (pr/551) (MB, reviewed by CM, SG)
219219
220220
Enhancements
221221
------------
@@ -229,19 +229,19 @@ Enhancements
229229
* Allow dtype specifiers as fileslice input (pr/485) (MB)
230230
* Support "headerless" ArrayProxy specification, enabling memory-efficient
231231
ArrayProxy reshaping (pr/521) (CM)
232-
* Allow unknown NIfTI intent codes, add FSL codes (pr/528) (Paul McCarthy)
232+
* Allow unknown NIfTI intent codes, add FSL codes (pr/528) (PM)
233233
* Improve error handling for ``img.__getitem__`` (pr/533) (Ariel Rokem)
234234
* Delegate reorientation to SpatialImage classes (pr/544) (Mark Hymers, CM,
235235
reviewed by MB)
236236
* Enable using ``indexed_gzip`` to reduce memory usage when reading from
237-
gzipped NIfTI and MGH files (pr/552) (Paul McCarthy, reviewed by MB, CM)
237+
gzipped NIfTI and MGH files (pr/552) (PM, reviewed by MB, CM)
238238

239239
Bug fixes
240240
---------
241241

242242
* Miscellaneous MINC reader fixes (pr/493) (Robert D. Vincent, reviewed by CM,
243243
MB)
244-
* Fix corner case in ``wrapstruct.get`` (pr/516) (Paul McCarthy, reviewed by
244+
* Fix corner case in ``wrapstruct.get`` (pr/516) (PM, reviewed by
245245
CM, MB)
246246

247247
Maintenance
@@ -542,7 +542,7 @@ Special thanks to Chris Burns, Jarrod Millman and Yaroslav Halchenko.
542542

543543
* New feature release
544544
* Python 3.2 support
545-
* Substantially enhanced gifti reading support (SG)
545+
* Substantially enhanced gifti reading support (Stephan Gerhard)
546546
* Refactoring of trackvis read / write to allow reading and writing of voxel
547547
points and mm points in tracks. Deprecate use of negative voxel sizes;
548548
set voxel_order field in trackvis header. Thanks to Chris Filo

doc/source/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ discussions, release procedure and more.
2727
Authors and Contributors
2828
========================
2929

30-
The main authors of NiBabel are `Matthew Brett`_, `Michael Hanke`_, `Ben
31-
Cipollini`_, `Marc-Alexandre Côté`_, Chris Markiewicz, `Stephan Gerhard`_ and
32-
`Eric Larson`_. The authors are grateful to the following people who have
30+
Most work on NiBabel so far has been by `Matthew Brett`_, Chris Markiewicz,
31+
`Michael Hanke`_, `Marc-Alexandre Côté`_, `Ben Cipollini`_, Paul McCarthy and
32+
Chris Cheng. The authors are grateful to the following people who have
3333
contributed code and discussion (in rough order of appearance):
3434

3535
* `Yaroslav O. Halchenko`_

nibabel/info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def cmp_pkg_version(version_str, pkg_version_str=__version__):
192192

193193
# Main setup parameters
194194
NAME = 'nibabel'
195-
MAINTAINER = "Matthew Brett, Michael Hanke, Eric Larson, Chris Markiewicz"
195+
MAINTAINER = "Chris Markiewicz"
196196
MAINTAINER_EMAIL = "[email protected]"
197197
DESCRIPTION = description
198198
LONG_DESCRIPTION = long_description

nibabel/nicom/dicomreaders.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def slices_to_series(wrappers):
146146
out_vol_lists = []
147147
for vol_list in volume_lists:
148148
if len(vol_list) > 1:
149-
vol_list.sort(_slice_sorter)
149+
vol_list.sort(key=_slice_sorter)
150150
zs = [s.slice_indicator for s in vol_list]
151151
if len(set(zs)) < len(zs): # not unique zs
152152
# third pass
@@ -163,12 +163,12 @@ def slices_to_series(wrappers):
163163
return out_vol_lists
164164

165165

166-
def _slice_sorter(s1, s2):
167-
return cmp(s1.slice_indicator, s2.slice_indicator)
166+
def _slice_sorter(s):
167+
return s.slice_indicator
168168

169169

170-
def _instance_sorter(s1, s2):
171-
return cmp(s1.instance_number, s2.instance_number)
170+
def _instance_sorter(s):
171+
return s.instance_number
172172

173173

174174
def _third_pass(wrappers):
@@ -182,9 +182,9 @@ def _third_pass(wrappers):
182182
'missing InstanceNumber')
183183
if len(set(inos)) < len(inos):
184184
raise DicomReadError(msg_fmt % 'some or all slices with '
185-
'the sane InstanceNumber')
185+
'the same InstanceNumber')
186186
# sort by instance number
187-
wrappers.sort(_instance_sorter)
187+
wrappers.sort(key=_instance_sorter)
188188
# start loop, in which we start a new volume, each time we see a z
189189
# we've seen already in the current volume
190190
dw = wrappers[0]

nibabel/nicom/tests/data/0.dcm

221 KB
Binary file not shown.

nibabel/nicom/tests/data/1.dcm

221 KB
Binary file not shown.

nibabel/nicom/tests/test_dicomreaders.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
"""
44

5+
from os.path import join as pjoin, abspath
6+
57
import numpy as np
68

79
from .. import dicomreaders as didr
@@ -68,3 +70,12 @@ def test_passing_kwds():
6870
IO_DATA_PATH,
6971
csa_glob,
7072
dicom_kwargs=dict(force=True))
73+
74+
@dicom_test
75+
def test_slices_to_series():
76+
dicom_files = (pjoin(IO_DATA_PATH, "%d.dcm" % i) for i in range(2))
77+
wrappers = [didr.wrapper_from_file(f) for f in dicom_files]
78+
series = didr.slices_to_series(wrappers)
79+
assert_equal(len(series), 1)
80+
assert_equal(len(series[0]), 2)
81+

nibabel/nifti1.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@
125125
(1, 'scanner', "NIFTI_XFORM_SCANNER_ANAT"),
126126
(2, 'aligned', "NIFTI_XFORM_ALIGNED_ANAT"),
127127
(3, 'talairach', "NIFTI_XFORM_TALAIRACH"),
128-
(4, 'mni', "NIFTI_XFORM_MNI_152")), fields=('code', 'label', 'niistring'))
128+
(4, 'mni', "NIFTI_XFORM_MNI_152"),
129+
(5, 'template', "NIFTI_XFORM_TEMPLATE_OTHER"),
130+
), fields=('code', 'label', 'niistring'))
129131

130132
# unit codes
131133
unit_codes = Recoder(( # code, label
@@ -2014,13 +2016,9 @@ def as_reoriented(self, ornt):
20142016
return img
20152017

20162018
# Also apply the transform to the dim_info fields
2017-
new_dim = list(img.header.get_dim_info())
2018-
for idx, value in enumerate(new_dim):
2019-
# For each value, leave as None if it was that way,
2020-
# otherwise check where we have mapped it to
2021-
if value is None:
2022-
continue
2023-
new_dim[idx] = np.where(ornt[:, 0] == idx)[0]
2019+
new_dim = [
2020+
None if orig_dim is None else int(ornt[orig_dim, 0])
2021+
for orig_dim in img.header.get_dim_info()]
20242022

20252023
img.header.set_dim_info(*new_dim)
20262024

nibabel/tests/test_nifti1.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@
2828
from nibabel.spatialimages import HeaderDataError
2929
from nibabel.tmpdirs import InTemporaryDirectory
3030
from ..freesurfer import load as mghload
31+
from ..orientations import aff2axcodes
3132

3233
from .test_arraywriters import rt_err_estimate, IUINT_TYPES
34+
from .test_orientations import ALL_ORNTS
3335
from .test_helpers import bytesio_filemap, bytesio_round_trip
3436
from .nibabel_data import get_nibabel_data, needs_nibabel_data
3537

@@ -226,6 +228,21 @@ def test_nifti_qsform_checks(self):
226228
assert_equal(message,
227229
'sform_code -1 not valid; setting to 0')
228230

231+
def test_nifti_xform_codes(self):
232+
# Verify that all xform codes can be set in both qform and sform
233+
hdr = self.header_class()
234+
affine = np.eye(4)
235+
for code in nifti1.xform_codes.keys():
236+
hdr.set_qform(affine, code)
237+
assert_equal(hdr['qform_code'], nifti1.xform_codes[code])
238+
hdr.set_sform(affine, code)
239+
assert_equal(hdr['sform_code'], nifti1.xform_codes[code])
240+
241+
# Raise KeyError on unknown code
242+
for bad_code in (-1, 6, 10):
243+
assert_raises(KeyError, hdr.set_qform, affine, bad_code)
244+
assert_raises(KeyError, hdr.set_sform, affine, bad_code)
245+
229246
def test_magic_offset_checks(self):
230247
# magic and offset
231248
HC = self.header_class
@@ -1403,6 +1420,36 @@ def test_rt_bias(self):
14031420
bias_thresh = np.max([max_miss / np.sqrt(count), eps])
14041421
assert_true(np.abs(bias) < bias_thresh)
14051422

1423+
def test_reoriented_dim_info(self):
1424+
# Check that dim_info is reoriented correctly
1425+
arr = np.arange(24).reshape((2, 3, 4))
1426+
# Start as RAS
1427+
aff = np.diag([2, 3, 4, 1])
1428+
simg = self.single_class(arr, aff)
1429+
for freq, phas, slic in ((0, 1, 2),
1430+
(0, 2, 1),
1431+
(1, 0, 2),
1432+
(2, 0, 1),
1433+
(None, None, None),
1434+
(0, 2, None),
1435+
(0, None, None),
1436+
(None, 2, 1),
1437+
(None, None, 1),
1438+
):
1439+
simg.header.set_dim_info(freq, phas, slic)
1440+
fdir = 'RAS'[freq] if freq is not None else None
1441+
pdir = 'RAS'[phas] if phas is not None else None
1442+
sdir = 'RAS'[slic] if slic is not None else None
1443+
for ornt in ALL_ORNTS:
1444+
rimg = simg.as_reoriented(np.array(ornt))
1445+
axcode = aff2axcodes(rimg.affine)
1446+
dirs = ''.join(axcode).replace('P', 'A').replace('I', 'S').replace('L', 'R')
1447+
new_freq, new_phas, new_slic = rimg.header.get_dim_info()
1448+
new_fdir = dirs[new_freq] if new_freq is not None else None
1449+
new_pdir = dirs[new_phas] if new_phas is not None else None
1450+
new_sdir = dirs[new_slic] if new_slic is not None else None
1451+
assert_equal((new_fdir, new_pdir, new_sdir), (fdir, pdir, sdir))
1452+
14061453

14071454
@runif_extra_has('slow')
14081455
def test_large_nifti1():

0 commit comments

Comments
 (0)