Skip to content

Commit 4ddcbd2

Browse files
committed
RF: Restore and deprecate loadsave helpers
1 parent 1971efb commit 4ddcbd2

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed

nibabel/loadsave.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
""" Utilities to load and save image objects """
1111

1212
import numpy as np
13+
import warnings
1314

1415
from .filename_parser import splitext_addext
1516
from .openers import ImageOpener
@@ -33,7 +34,6 @@ def load(filename, **kwargs):
3334
img : ``SpatialImage``
3435
Image of guessed type
3536
'''
36-
3737
sniff = None
3838
for image_klass in all_image_classes:
3939
is_valid, sniff = image_klass.path_maybe_image(filename, sniff)
@@ -44,6 +44,31 @@ def load(filename, **kwargs):
4444
filename)
4545

4646

47+
@np.deprecate
48+
def guessed_image_type(filename):
49+
""" Guess image type from file `filename`
50+
51+
Parameters
52+
----------
53+
filename : str
54+
File name containing an image
55+
56+
Returns
57+
-------
58+
image_class : class
59+
Class corresponding to guessed image type
60+
"""
61+
warnings.warn('guessed_image_type is deprecated', DeprecationWarning)
62+
sniff = None
63+
for image_klass in all_image_classes:
64+
is_valid, sniff = image_klass.path_maybe_image(filename, sniff)
65+
if is_valid:
66+
return image_klass
67+
68+
raise ImageFileError('Cannot work out file type of "%s"' %
69+
filename)
70+
71+
4772
def save(img, filename):
4873
''' Save an image to file adapting format to `filename`
4974
@@ -178,3 +203,46 @@ def read_img_data(img, prefer='scaled'):
178203
if prefer == 'scaled':
179204
return hdr.data_from_fileobj(fileobj)
180205
return hdr.raw_data_from_fileobj(fileobj)
206+
207+
208+
@np.deprecate
209+
def which_analyze_type(binaryblock):
210+
""" Is `binaryblock` from NIfTI1, NIfTI2 or Analyze header?
211+
212+
Parameters
213+
----------
214+
binaryblock : bytes
215+
The `binaryblock` is 348 bytes that might be NIfTI1, NIfTI2, Analyze,
216+
or None of the the above.
217+
218+
Returns
219+
-------
220+
hdr_type : str
221+
* a nifti1 header (pair or single) -> return 'nifti1'
222+
* a nifti2 header (pair or single) -> return 'nifti2'
223+
* an Analyze header -> return 'analyze'
224+
* None of the above -> return None
225+
226+
Notes
227+
-----
228+
Algorithm:
229+
230+
* read in the first 4 bytes from the file as 32-bit int ``sizeof_hdr``
231+
* if ``sizeof_hdr`` is 540 or byteswapped 540 -> assume nifti2
232+
* Check for 'ni1', 'n+1' magic -> assume nifti1
233+
* if ``sizeof_hdr`` is 348 or byteswapped 348 assume Analyze
234+
* Return None
235+
"""
236+
warnings.warn('which_analyze_type is deprecated', DeprecationWarning)
237+
from .nifti1 import header_dtype
238+
hdr_struct = np.ndarray(shape=(), dtype=header_dtype, buffer=binaryblock)
239+
bs_hdr_struct = hdr_struct.byteswap()
240+
sizeof_hdr = hdr_struct['sizeof_hdr']
241+
bs_sizeof_hdr = bs_hdr_struct['sizeof_hdr']
242+
if 540 in (sizeof_hdr, bs_sizeof_hdr):
243+
return 'nifti2'
244+
if hdr_struct['magic'] in (b'ni1', b'n+1'):
245+
return 'nifti1'
246+
if 348 in (sizeof_hdr, bs_sizeof_hdr):
247+
return 'analyze'
248+
return None

nibabel/tests/test_image_load_save.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,62 @@ def test_filename_save():
260260
del rt_img
261261
finally:
262262
shutil.rmtree(pth)
263+
264+
265+
def test_analyze_detection():
266+
# Test detection of Analyze, Nifti1 and Nifti2
267+
# Algorithm is as described in loadsave:which_analyze_type
268+
def wat(hdr):
269+
return nils.which_analyze_type(hdr.binaryblock)
270+
n1_hdr = Nifti1Header(b'\0' * 348, check=False)
271+
assert_equal(wat(n1_hdr), None)
272+
n1_hdr['sizeof_hdr'] = 540
273+
assert_equal(wat(n1_hdr), 'nifti2')
274+
assert_equal(wat(n1_hdr.as_byteswapped()), 'nifti2')
275+
n1_hdr['sizeof_hdr'] = 348
276+
assert_equal(wat(n1_hdr), 'analyze')
277+
assert_equal(wat(n1_hdr.as_byteswapped()), 'analyze')
278+
n1_hdr['magic'] = b'n+1'
279+
assert_equal(wat(n1_hdr), 'nifti1')
280+
assert_equal(wat(n1_hdr.as_byteswapped()), 'nifti1')
281+
n1_hdr['magic'] = b'ni1'
282+
assert_equal(wat(n1_hdr), 'nifti1')
283+
assert_equal(wat(n1_hdr.as_byteswapped()), 'nifti1')
284+
# Doesn't matter what magic is if it's not a nifti1 magic
285+
n1_hdr['magic'] = b'ni2'
286+
assert_equal(wat(n1_hdr), 'analyze')
287+
n1_hdr['sizeof_hdr'] = 0
288+
n1_hdr['magic'] = b''
289+
assert_equal(wat(n1_hdr), None)
290+
n1_hdr['magic'] = 'n+1'
291+
assert_equal(wat(n1_hdr), 'nifti1')
292+
n1_hdr['magic'] = 'ni1'
293+
assert_equal(wat(n1_hdr), 'nifti1')
294+
295+
296+
def test_guessed_image_type():
297+
# Test whether we can guess the image type from example files
298+
assert_equal(nils.guessed_image_type(
299+
pjoin(DATA_PATH, 'example4d.nii.gz')),
300+
Nifti1Image)
301+
assert_equal(nils.guessed_image_type(
302+
pjoin(DATA_PATH, 'nifti1.hdr')),
303+
Nifti1Pair)
304+
assert_equal(nils.guessed_image_type(
305+
pjoin(DATA_PATH, 'example_nifti2.nii.gz')),
306+
Nifti2Image)
307+
assert_equal(nils.guessed_image_type(
308+
pjoin(DATA_PATH, 'nifti2.hdr')),
309+
Nifti2Pair)
310+
assert_equal(nils.guessed_image_type(
311+
pjoin(DATA_PATH, 'tiny.mnc')),
312+
Minc1Image)
313+
assert_equal(nils.guessed_image_type(
314+
pjoin(DATA_PATH, 'small.mnc')),
315+
Minc2Image)
316+
assert_equal(nils.guessed_image_type(
317+
pjoin(DATA_PATH, 'test.mgz')),
318+
MGHImage)
319+
assert_equal(nils.guessed_image_type(
320+
pjoin(DATA_PATH, 'analyze.hdr')),
321+
Spm2AnalyzeImage)

0 commit comments

Comments
 (0)