Skip to content

Commit 81982ca

Browse files
authored
Merge pull request #667 from nipy/rel/2.3.1
REL: 2.3.1
2 parents 15df138 + 5841806 commit 81982ca

35 files changed

+1190
-268
lines changed

.mailmap

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Basile Pinsard <[email protected]> bpinsard <[email protected]>
2929
3030
Ben Cipollini <[email protected]> Ben Cipollini <[email protected]>
3131
Chris Markiewicz <[email protected]> Christopher J. Markiewicz <[email protected]>
32+
Chris Markiewicz <[email protected]> Chris Markiewicz <[email protected]>
3233
Chris Markiewicz <[email protected]> Christopher J. Markiewicz <[email protected]>
3334
Chris Markiewicz <[email protected]> Christopher J. Markiewicz <[email protected]>
3435
Chris Markiewicz <[email protected]> Chris Johnson <[email protected]>

.travis.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
# for it to be on multiple physical lines, so long as you remember: - There
55
# can't be any leading "-"s - All newlines will be removed, so use ";"s
66

7+
dist: xenial
8+
sudo: true
79
language: python
810

9-
# Run jobs on container-based infrastructure, can be overridden per job
10-
sudo: false
11-
1211
cache:
1312
directories:
1413
- $HOME/.cache/pip
@@ -22,11 +21,14 @@ env:
2221
- EXTRA_PIP_FLAGS="--find-links=$EXTRA_WHEELS"
2322
- PRE_PIP_FLAGS="--pre $EXTRA_PIP_FLAGS --find-links $PRE_WHEELS"
2423
python:
25-
- 3.4
2624
- 3.5
2725
- 3.6
26+
- 3.7
2827
matrix:
2928
include:
29+
- python: 3.4
30+
dist: trusty
31+
sudo: false
3032
- python: 2.7
3133
env:
3234
- COVERAGE=1

COPYING

+28-24
Original file line numberDiff line numberDiff line change
@@ -121,36 +121,40 @@ Sphinx 0.6 doesn't work properly.
121121
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
122122
DAMAGE.
123123

124-
Ordereddict
124+
OrderedSet
125125
-----------
126126

127-
In ``nibabel/externals/ordereddict.py``
127+
In ``nibabel/externals/oset.py``
128128

129-
Copied from: https://pypi.python.org/packages/source/o/ordereddict/ordereddict-1.1.tar.gz#md5=a0ed854ee442051b249bfad0f638bbec
129+
Copied from: https://files.pythonhosted.org/packages/d6/b1/a49498c699a3fda5d635cc1fa222ffc686ea3b5d04b84a3166c4cab0c57b/oset-0.1.3.tar.gz
130130

131131
::
132132

133-
Copyright (c) 2009 Raymond Hettinger
134-
135-
Permission is hereby granted, free of charge, to any person
136-
obtaining a copy of this software and associated documentation files
137-
(the "Software"), to deal in the Software without restriction,
138-
including without limitation the rights to use, copy, modify, merge,
139-
publish, distribute, sublicense, and/or sell copies of the Software,
140-
and to permit persons to whom the Software is furnished to do so,
141-
subject to the following conditions:
142-
143-
The above copyright notice and this permission notice shall be
144-
included in all copies or substantial portions of the Software.
145-
146-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
147-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
148-
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
149-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
150-
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
151-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
152-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
153-
OTHER DEALINGS IN THE SOFTWARE.
133+
Copyright (c) 2009, Raymond Hettinger, and others All rights reserved.
134+
135+
Package structured based on the one developed to odict Copyright (c) 2010, BlueDynamics Alliance, Austria
136+
137+
- Redistributions of source code must retain the above copyright notice, this
138+
list of conditions and the following disclaimer.
139+
140+
- Redistributions in binary form must reproduce the above copyright notice, this
141+
list of conditions and the following disclaimer in the documentation and/or
142+
other materials provided with the distribution.
143+
144+
- Neither the name of the BlueDynamics Alliance nor the names of its
145+
contributors may be used to endorse or promote products derived from this
146+
software without specific prior written permission.
147+
148+
THIS SOFTWARE IS PROVIDED BY BlueDynamics Alliance AS IS AND ANY EXPRESS OR
149+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
150+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
151+
SHALL BlueDynamics Alliance BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
152+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
153+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
154+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
155+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
156+
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
157+
OF SUCH DAMAGE.
154158

155159
mni_icbm152_t1_tal_nlin_asym_09a
156160
--------------------------------

Changelog

+37-1
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,46 @@ Nibabel releases
2020

2121
Most work on NiBabel so far has been by Matthew Brett (MB), Michael Hanke (MH)
2222
Ben Cipollini (BC), Marc-Alexandre Côté (MC), Chris Markiewicz (CM), Stephan
23-
Gerhard (SG) and Eric Larson (EL).
23+
Gerhard (SG), Eric Larson (EL), Yaroslav Halchenko (YOH) and Chris Cheng (CC).
2424

2525
References like "pr/298" refer to github pull request numbers.
2626

27+
Upcoming release
28+
================
29+
30+
New features
31+
------------
32+
* ``nib-diff`` command line tool for comparing image files (pr/617, pr/672,
33+
pr/678) (CC, reviewed by YOH, Pradeep Raamana and CM)
34+
35+
Enhancements
36+
------------
37+
* Speed up reading of numeric arrays in CIFTI2 (pr/655) (Michiel Cottaar,
38+
reviewed by CM)
39+
* Add ``ndim`` property to ``ArrayProxy`` and ``DataobjImage`` (pr/674) (CM,
40+
reviewed by MB)
41+
42+
Bug fixes
43+
---------
44+
* Deterministic deduction of slice ordering in degenerate cases (pr/647)
45+
(YOH, reviewed by CM)
46+
* Allow 0ms TR in MGH files (pr/653) (EL, reviewed by CM)
47+
* Allow for PPC64 little-endian long doubles (pr/658) (MB, reviewed by CM)
48+
* Correct construction of FreeSurfer annotation labels (pr/666) (CM, reviewed
49+
by EL, Paul D. McCarthy)
50+
* Fix logic for persisting filehandles with indexed-gzip (pr/679) (Paul D.
51+
McCarthy, reviewed by CM)
52+
53+
Maintenance
54+
-----------
55+
* Fix semantic error in coordinate systems documentation (pr/646) (Ariel
56+
Rokem, reviewed by CM, MB)
57+
* Test on Python 3.7, minor associated fixes (pr/651) (CM, reviewed by Gregory
58+
R. Lee, MB)
59+
60+
API changes and deprecations
61+
----------------------------
62+
2763
2.3 (Tuesday 12 June 2018)
2864
==========================
2965

appveyor.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ environment:
1212
- PYTHON: C:\Python35-x64
1313
- PYTHON: C:\Python36
1414
- PYTHON: C:\Python36-x64
15+
- PYTHON: C:\Python37
16+
- PYTHON: C:\Python37-x64
1517

1618
install:
1719
# Prepend newly installed Python to the PATH of this build (this cannot be
@@ -20,8 +22,7 @@ install:
2022
- SET PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
2123

2224
# Install the dependencies of the project.
23-
- pip install numpy scipy matplotlib nose h5py mock
24-
- pip install pydicom
25+
- pip install numpy scipy matplotlib nose h5py mock pydicom
2526
- pip install .
2627
- SET NIBABEL_DATA_DIR=%CD%\nibabel-data
2728

bin/nib-diff

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!python
2+
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
5+
#
6+
# See COPYING file distributed along with the NiBabel package for the
7+
# copyright and license terms.
8+
#
9+
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
10+
"""
11+
Quick diff summary for a set of neuroimaging files
12+
"""
13+
14+
from nibabel.cmdline.diff import main
15+
16+
if __name__ == '__main__':
17+
main()

doc/source/coordinate_systems.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ axes *starts* on the right, anterior, superior of the subject, rather than
255255
*ending* on the right, anterior, superior. In other words, they would use
256256
"RAS" to refer to a coordinate system we would call "LPI". To be safe, we'll
257257
call our interpretation of the RAS convention "RAS+", meaning that Right,
258-
Anterior, Posterior are all positive values on these axes.
258+
Anterior, Superior are all positive values on these axes.
259259

260260
Some people also use "right" to mean the right hand side when an observer
261261
looks at the front of the scanner, from the foot the scanner bed.

nibabel/arrayproxy.py

+88-25
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,14 @@
4242
used for the lifetime of the ``ArrayProxy``. It should be set to one of
4343
``True``, ``False``, or ``'auto'``.
4444
45-
If ``True``, a single file handle is created and used. If ``False``, a new
46-
file handle is created every time the image is accessed. For gzip files, if
47-
``'auto'``, and the optional ``indexed_gzip`` dependency is present, a single
48-
file handle is created and persisted. If ``indexed_gzip`` is not available,
49-
behaviour is the same as if ``keep_file_open is False``.
45+
Management of file handles will be performed either by ``ArrayProxy`` objects,
46+
or by the ``indexed_gzip`` package if it is used.
47+
48+
If this flag is set to ``True``, a single file handle is created and used. If
49+
``False``, a new file handle is created every time the image is accessed. For
50+
gzip files, if ``'auto'``, and the optional ``indexed_gzip`` dependency is
51+
present, a single file handle is created and persisted. If ``indexed_gzip`` is
52+
not available, behaviour is the same as if ``keep_file_open is False``.
5053
5154
If this is set to any other value, attempts to create an ``ArrayProxy`` without
5255
specifying the ``keep_file_open`` flag will result in a ``ValueError`` being
@@ -160,8 +163,10 @@ def __init__(self, file_like, spec, mmap=True, keep_file_open=None):
160163
# Permit any specifier that can be interpreted as a numpy dtype
161164
self._dtype = np.dtype(self._dtype)
162165
self._mmap = mmap
163-
self._keep_file_open = self._should_keep_file_open(file_like,
164-
keep_file_open)
166+
# Flags to keep track of whether a single ImageOpener is created, and
167+
# whether a single underlying file handle is created.
168+
self._keep_file_open, self._persist_opener = \
169+
self._should_keep_file_open(file_like, keep_file_open)
165170
self._lock = RLock()
166171

167172
def __del__(self):
@@ -184,16 +189,64 @@ def __setstate__(self, state):
184189
self._lock = RLock()
185190

186191
def _should_keep_file_open(self, file_like, keep_file_open):
187-
"""Called by ``__init__``, and used to determine the final value of
188-
``keep_file_open``.
192+
"""Called by ``__init__``.
193+
194+
This method determines how to manage ``ImageOpener`` instances,
195+
and the underlying file handles - the behaviour depends on:
196+
197+
- whether ``file_like`` is an an open file handle, or a path to a
198+
``'.gz'`` file, or a path to a non-gzip file.
199+
- whether ``indexed_gzip`` is present (see
200+
:attr:`.openers.HAVE_INDEXED_GZIP`).
201+
202+
An ``ArrayProxy`` object uses two internal flags to manage
203+
``ImageOpener`` instances and underlying file handles.
204+
205+
- The ``_persist_opener`` flag controls whether a single
206+
``ImageOpener`` should be created and used for the lifetime of
207+
this ``ArrayProxy``, or whether separate ``ImageOpener`` instances
208+
should be created on each file access.
209+
210+
- The ``_keep_file_open`` flag controls qwhether the underlying file
211+
handle should be kept open for the lifetime of this
212+
``ArrayProxy``, or whether the file handle should be (re-)opened
213+
and closed on each file access.
214+
215+
The internal ``_keep_file_open`` flag is only relevant if
216+
``file_like`` is a ``'.gz'`` file, and the ``indexed_gzip`` library is
217+
present.
218+
219+
This method returns the values to be used for the internal
220+
``_persist_opener`` and ``_keep_file_open`` flags; these values are
221+
derived according to the following rules:
189222
190-
The return value is derived from these rules:
223+
1. If ``file_like`` is a file(-like) object, both flags are set to
224+
``False``.
191225
192-
- If ``file_like`` is a file(-like) object, ``False`` is returned.
193-
Otherwise, ``file_like`` is assumed to be a file name.
194-
- If ``keep_file_open`` is ``auto``, and ``indexed_gzip`` is
195-
not available, ``False`` is returned.
196-
- Otherwise, the value of ``keep_file_open`` is returned unchanged.
226+
2. If ``keep_file_open`` (as passed to :meth:``__init__``) is
227+
``True``, both internal flags are set to ``True``.
228+
229+
3. If ``keep_file_open`` is ``False``, but ``file_like`` is not a path
230+
to a ``.gz`` file or ``indexed_gzip`` is not present, both flags
231+
are set to ``False``.
232+
233+
4. If ``keep_file_open`` is ``False``, ``file_like`` is a path to a
234+
``.gz`` file, and ``indexed_gzip`` is present, ``_persist_opener``
235+
is set to ``True``, and ``_keep_file_open`` is set to ``False``.
236+
In this case, file handle management is delegated to the
237+
``indexed_gzip`` library.
238+
239+
5. If ``keep_file_open`` is ``'auto'``, ``file_like`` is a path to a
240+
``.gz`` file, and ``indexed_gzip`` is present, both internal flags
241+
are set to ``True``.
242+
243+
6. If ``keep_file_open`` is ``'auto'``, and ``file_like`` is not a
244+
path to a ``.gz`` file, or ``indexed_gzip`` is not present, both
245+
internal flags are set to ``False``.
246+
247+
Note that a value of ``'auto'`` for ``keep_file_open`` will become
248+
deprecated behaviour in version 2.4.0, and support for ``'auto'`` will
249+
be removed in version 3.0.0.
197250
198251
Parameters
199252
----------
@@ -206,8 +259,10 @@ def _should_keep_file_open(self, file_like, keep_file_open):
206259
Returns
207260
-------
208261
209-
The value of ``keep_file_open`` that will be used by this
210-
``ArrayProxy``, and passed through to ``ImageOpener`` instances.
262+
A tuple containing:
263+
- ``keep_file_open`` flag to control persistence of file handles
264+
- ``persist_opener`` flag to control persistence of ``ImageOpener``
265+
objects.
211266
"""
212267
if keep_file_open is None:
213268
keep_file_open = KEEP_FILE_OPEN_DEFAULT
@@ -216,12 +271,15 @@ def _should_keep_file_open(self, file_like, keep_file_open):
216271
'\'auto\', True, False}')
217272
# file_like is a handle - keep_file_open is irrelevant
218273
if hasattr(file_like, 'read') and hasattr(file_like, 'seek'):
219-
return False
220-
# don't have indexed_gzip - auto -> False
221-
if keep_file_open == 'auto' and not (openers.HAVE_INDEXED_GZIP and
222-
file_like.endswith('.gz')):
223-
return False
224-
return keep_file_open
274+
return False, False
275+
# if the file is a gzip file, and we have_indexed_gzip,
276+
have_igzip = openers.HAVE_INDEXED_GZIP and file_like.endswith('.gz')
277+
if keep_file_open == 'auto':
278+
return have_igzip, have_igzip
279+
elif keep_file_open:
280+
return True, True
281+
else:
282+
return False, have_igzip
225283

226284
@property
227285
@deprecate_with_version('ArrayProxy.header deprecated', '2.2', '3.0')
@@ -232,6 +290,10 @@ def header(self):
232290
def shape(self):
233291
return self._shape
234292

293+
@property
294+
def ndim(self):
295+
return len(self.shape)
296+
235297
@property
236298
def dtype(self):
237299
return self._dtype
@@ -265,13 +327,14 @@ def _get_fileobj(self):
265327
A newly created ``ImageOpener`` instance, or an existing one,
266328
which provides access to the file.
267329
"""
268-
if self._keep_file_open:
330+
if self._persist_opener:
269331
if not hasattr(self, '_opener'):
270332
self._opener = openers.ImageOpener(
271333
self.file_like, keep_open=self._keep_file_open)
272334
yield self._opener
273335
else:
274-
with openers.ImageOpener(self.file_like) as opener:
336+
with openers.ImageOpener(
337+
self.file_like, keep_open=False) as opener:
275338
yield opener
276339

277340
def get_unscaled(self):

nibabel/casting.py

+3
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,9 @@ def type_info(np_type):
268268
# 80) but in calculations nexp in fact appears to be 11 as for float64
269269
ret.update(dict(width=width))
270270
return ret
271+
if vals == (105, 11, 16): # correctly detected double double
272+
ret.update(dict(nmant=nmant, nexp=nexp, width=width))
273+
return ret
271274
# Oh dear, we don't recognize the type information. Try some known types
272275
# and then give up. At this stage we're expecting exotic longdouble or
273276
# their complex equivalent.

0 commit comments

Comments
 (0)