1# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- 2# vi: set ft=python sts=4 ts=4 sw=4 et: 3### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 4# 5# See COPYING file distributed along with the NiBabel package for the 6# copyright and license terms. 7# 8### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 9# module imports 10from .py3k import asbytes 11from .filename_parser import types_filenames, splitext_addext 12from . import volumeutils as vu 13from . import spm2analyze as spm2 14from . import nifti1 15from .freesurfer import MGHImage 16from .fileholders import FileHolderError 17from .spatialimages import ImageFileError 18from .imageclasses import class_map, ext_map 19 20 21def load(filename): 22 ''' Load file given filename, guessing at file type 23 24 Parameters 25 ---------- 26 filename : string 27 specification of file to load 28 29 Returns 30 ------- 31 img : ``SpatialImage`` 32 Image of guessed type 33 ''' 34 froot, ext, trailing = splitext_addext(filename, ('.gz', '.bz2')) 35 try: 36 img_type = ext_map[ext] 37 except KeyError: 38 raise ImageFileError('Cannot work out file type of "%s"' % 39 filename) 40 if ext in ('.nii', '.mnc', '.mgh', '.mgz'): 41 klass = class_map[img_type]['class'] 42 else: 43 # might be nifti pair or analyze of some sort 44 files_types = (('image','.img'), ('header','.hdr')) 45 filenames = types_filenames(filename, files_types) 46 hdr = nifti1.Nifti1Header.from_fileobj( 47 vu.allopen(filenames['header']), 48 check=False) 49 if hdr['magic'] in (asbytes('ni1'), asbytes('n+1')): 50 # allow goofy nifti single magic for pair 51 klass = nifti1.Nifti1Pair 52 else: 53 klass = spm2.Spm2AnalyzeImage 54 return klass.from_filename(filename) 55 56 57def save(img, filename): 58 ''' Save an image to file adapting format to `filename` 59 60 Parameters 61 ---------- 62 img : ``SpatialImage`` 63 image to save 64 filename : str 65 filename (often implying filenames) to which to save `img`. 66 67 Returns 68 ------- 69 None 70 ''' 71 try: 72 img.to_filename(filename) 73 except ImageFileError: 74 pass 75 else: 76 return 77 froot, ext, trailing = splitext_addext(filename, ('.gz', '.bz2')) 78 img_type = ext_map[ext] 79 klass = class_map[img_type]['class'] 80 converted = klass.from_image(img) 81 converted.to_filename(filename) 82 83 84def read_img_data(img, prefer='scaled'): 85 """ Read data from image associated with files 86 87 Parameters 88 ---------- 89 img : ``SpatialImage`` 90 Image with valid image file in ``img.file_map``. Unlike the 91 ``img.get_data()`` method, this function returns the data read 92 from the image file, as specified by the *current* image header 93 and *current* image files. 94 prefer : str, optional 95 Can be 'scaled' - in which case we return the data with the 96 scaling suggested by the format, or 'unscaled', in which case we 97 return, if we can, the raw data from the image file, without the 98 scaling applied. 99 100 Returns 101 ------- 102 arr : ndarray 103 array as read from file, given parameters in header 104 105 Notes 106 ----- 107 Summary: please use the ``get_data`` method of `img` instead of this 108 function unless you are sure what you are doing. 109 110 In general, you will probably prefer ``prefer='scaled'``, because 111 this gives the data as the image format expects to return it. 112 113 Use `prefer` == 'unscaled' with care; the modified Analyze-type 114 formats such as SPM formats, and nifti1, specify that the image data 115 array is given by the raw data on disk, multiplied by a scalefactor 116 and maybe with the addition of a constant. This function, with 117 ``unscaled`` returns the data on the disk, without these 118 format-specific scalings applied. Please use this funciton only if 119 you absolutely need the unscaled data, and the magnitude of the 120 data, as given by the scalefactor, is not relevant to your 121 application. The Analyze-type formats have a single scalefactor +/- 122 offset per image on disk. If you do not care about the absolute 123 values, and will be removing the mean from the data, then the 124 unscaled values will have preserved intensity ratios compared to the 125 mean-centered scaled data. However, this is not necessarily true of 126 other formats with more complicated scaling - such as MINC. 127 """ 128 image_fileholder = img.file_map['image'] 129 try: 130 fileobj = image_fileholder.get_prepare_fileobj() 131 except FileHolderError: 132 raise ImageFileError('No image file specified for this image') 133 if prefer not in ('scaled', 'unscaled'): 134 raise ValueError('Invalid string "%s" for "prefer"' % prefer) 135 hdr = img.get_header() 136 if prefer == 'unscaled': 137 try: 138 return hdr.raw_data_from_fileobj(fileobj) 139 except AttributeError: 140 pass 141 return hdr.data_from_fileobj(fileobj) 142