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### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 9from __future__ import with_statement 10 11import os 12 13import numpy as np 14 15from ..py3k import asbytes 16 17from ..volumeutils import native_code, swapped_code 18from ..ecat import EcatHeader, EcatMlist, EcatSubHeader, EcatImage 19 20from unittest import TestCase 21 22from nose.tools import (assert_true, assert_false, assert_equal, 23 assert_not_equal, assert_raises) 24 25from numpy.testing import assert_array_equal, assert_array_almost_equal 26 27from ..testing import data_path 28from ..tmpdirs import InTemporaryDirectory 29 30ecat_file = os.path.join(data_path, 'tinypet.v') 31 32class TestEcatHeader(TestCase): 33 header_class = EcatHeader 34 example_file = ecat_file 35 36 def test_header_size(self): 37 assert_equal(self.header_class._dtype.itemsize, 512) 38 39 def test_empty(self): 40 hdr = self.header_class() 41 assert_true(len(hdr.binaryblock) == 512) 42 assert_true(hdr['magic_number'] == asbytes('MATRIX72')) 43 assert_true(hdr['sw_version'] == 74) 44 assert_true(hdr['num_frames'] == 0) 45 assert_true(hdr['file_type'] == 0) 46 assert_true(hdr['ecat_calibration_factor'] == 1.0) 47 48 def test_dtype(self): 49 #dtype not specified in header, only in subheaders 50 hdr = self.header_class() 51 assert_raises(NotImplementedError, 52 hdr.get_data_dtype) 53 54 def test_header_codes(self): 55 fid = open(ecat_file, 'rb') 56 hdr = self.header_class() 57 newhdr = hdr.from_fileobj(fid) 58 fid.close() 59 assert_true(newhdr.get_filetype() == 'ECAT7_VOLUME16') 60 assert_equal(newhdr.get_patient_orient(), 61 'ECAT7_Unknown_Orientation') 62 63 def test_copy(self): 64 hdr = self.header_class() 65 hdr2 = hdr.copy() 66 assert_true(hdr == hdr2) 67 assert_true(not hdr.binaryblock == hdr2._header_data.byteswap().tostring()) 68 assert_true(hdr.keys() == hdr2.keys()) 69 70 def test_update(self): 71 hdr = self.header_class() 72 assert_true(hdr['num_frames'] == 0) 73 hdr['num_frames'] = 2 74 assert_true(hdr['num_frames'] == 2) 75 76 def test_endianness(self): 77 # Default constructed header should be native 78 native_hdr = self.header_class() 79 assert_true(native_hdr.endianness == native_code) 80 # Swapped constructed header should be swapped 81 swapped_hdr = self.header_class(endianness=swapped_code) 82 assert_true(swapped_hdr.endianness == swapped_code) 83 # Example header is big-endian 84 fid = open(ecat_file, 'rb') 85 file_hdr = native_hdr.from_fileobj(fid) 86 fid.close() 87 assert_true(file_hdr.endianness == '>') 88 89 90class TestEcatMlist(TestCase): 91 header_class = EcatHeader 92 mlist_class = EcatMlist 93 example_file = ecat_file 94 95 def test_mlist(self): 96 fid = open(self.example_file, 'rb') 97 hdr = self.header_class.from_fileobj(fid) 98 mlist = self.mlist_class(fid, hdr) 99 fid.seek(0) 100 fid.seek(512) 101 dat=fid.read(128*32) 102 dt = np.dtype([('matlist',np.int32)]) 103 dt = dt.newbyteorder('>') 104 mats = np.recarray(shape=(32,4), dtype=dt, buf=dat) 105 fid.close() 106 #tests 107 assert_true(mats['matlist'][0,0] + mats['matlist'][0,3] == 31) 108 assert_true(mlist.get_frame_order()[0][0] == 0) 109 assert_true(mlist.get_frame_order()[0][1] == 16842758.0) 110 # test badly ordered mlist 111 badordermlist = mlist 112 badordermlist._mlist = np.array([[ 1.68427540e+07, 3.00000000e+00, 113 1.20350000e+04, 1.00000000e+00], 114 [ 1.68427530e+07, 1.20360000e+04, 115 2.40680000e+04, 1.00000000e+00], 116 [ 1.68427550e+07, 2.40690000e+04, 117 3.61010000e+04, 1.00000000e+00], 118 [ 1.68427560e+07, 3.61020000e+04, 119 4.81340000e+04, 1.00000000e+00], 120 [ 1.68427570e+07, 4.81350000e+04, 121 6.01670000e+04, 1.00000000e+00], 122 [ 1.68427580e+07, 6.01680000e+04, 123 7.22000000e+04, 1.00000000e+00]]) 124 assert_true(badordermlist.get_frame_order()[0][0] == 1) 125 126 def test_mlist_errors(self): 127 fid = open(self.example_file, 'rb') 128 hdr = self.header_class.from_fileobj(fid) 129 hdr['num_frames'] = 6 130 mlist = self.mlist_class(fid, hdr) 131 mlist._mlist = np.array([[ 1.68427540e+07, 3.00000000e+00, 132 1.20350000e+04, 1.00000000e+00], 133 [ 1.68427530e+07, 1.20360000e+04, 134 2.40680000e+04, 1.00000000e+00], 135 [ 1.68427550e+07, 2.40690000e+04, 136 3.61010000e+04, 1.00000000e+00], 137 [ 1.68427560e+07, 3.61020000e+04, 138 4.81340000e+04, 1.00000000e+00], 139 [ 1.68427570e+07, 4.81350000e+04, 140 6.01670000e+04, 1.00000000e+00], 141 [ 1.68427580e+07, 6.01680000e+04, 142 7.22000000e+04, 1.00000000e+00]]) 143 series_framenumbers = mlist.get_series_framenumbers() 144 # first frame stored was actually 2nd frame acquired 145 assert_true(series_framenumbers[0] == 2) 146 order = [series_framenumbers[x] for x in sorted(series_framenumbers)] 147 # true series order is [2,1,3,4,5,6], note counting starts at 1 148 assert_true(order == [2, 1, 3, 4, 5, 6]) 149 mlist._mlist[0,0] = 0 150 frames_order = mlist.get_frame_order() 151 neworder =[frames_order[x][0] for x in sorted(frames_order)] 152 assert_true(neworder == [1, 2, 3, 4, 5]) 153 assert_raises(IOError, 154 mlist.get_series_framenumbers) 155 156 157 158class TestEcatSubHeader(TestCase): 159 header_class = EcatHeader 160 mlist_class = EcatMlist 161 subhdr_class = EcatSubHeader 162 example_file = ecat_file 163 fid = open(example_file, 'rb') 164 hdr = header_class.from_fileobj(fid) 165 mlist = mlist_class(fid, hdr) 166 subhdr = subhdr_class(hdr, mlist, fid) 167 168 def test_subheader_size(self): 169 assert_equal(self.subhdr_class._subhdrdtype.itemsize, 510) 170 171 def test_subheader(self): 172 assert_equal(self.subhdr.get_shape() , (10,10,3)) 173 assert_equal(self.subhdr.get_nframes() , 1) 174 assert_equal(self.subhdr.get_nframes(), 175 len(self.subhdr.subheaders)) 176 assert_equal(self.subhdr._check_affines(), True) 177 assert_array_almost_equal(np.diag(self.subhdr.get_frame_affine()), 178 np.array([ 2.20241979, 2.20241979, 3.125, 1.])) 179 assert_equal(self.subhdr.get_zooms()[0], 2.20241978764534) 180 assert_equal(self.subhdr.get_zooms()[2], 3.125) 181 assert_equal(self.subhdr._get_data_dtype(0),np.uint16) 182 #assert_equal(self.subhdr._get_frame_offset(), 1024) 183 assert_equal(self.subhdr._get_frame_offset(), 1536) 184 dat = self.subhdr.raw_data_from_fileobj() 185 assert_equal(dat.shape, self.subhdr.get_shape()) 186 scale_factor = self.subhdr.subheaders[0]['scale_factor'] 187 assert_equal(self.subhdr.subheaders[0]['scale_factor'].item(),1.0) 188 ecat_calib_factor = self.hdr['ecat_calibration_factor'] 189 assert_equal(ecat_calib_factor, 25007614.0) 190 191class TestEcatImage(TestCase): 192 image_class = EcatImage 193 example_file = ecat_file 194 img = image_class.load(example_file) 195 196 def test_file(self): 197 assert_equal(self.img.file_map['header'].filename, 198 self.example_file) 199 assert_equal(self.img.file_map['image'].filename, 200 self.example_file) 201 202 def test_save(self): 203 tmp_file = 'tinypet_tmp.v' 204 with InTemporaryDirectory(): 205 self.img.to_filename(tmp_file) 206 other = self.image_class.load(tmp_file) 207 assert_equal(self.img.get_data().all(), other.get_data().all()) 208 # Delete object holding reference to temporary file to make Windows 209 # happier. 210 del other 211 212 def test_data(self): 213 dat = self.img.get_data() 214 assert_equal(dat.shape, self.img.shape) 215 frame = self.img.get_frame(0) 216 assert_array_equal(frame, dat[:,:,:,0]) 217 218 def test_array_proxy(self): 219 # Get the cached data copy 220 dat = self.img.get_data() 221 # Make a new one to test arrayproxy 222 img = self.image_class.load(self.example_file) 223 # Maybe we will promote _data to public, but I know this looks bad 224 secret_data = img._data 225 data2 = np.array(secret_data) 226 assert_array_equal(data2, dat) 227 # Check it rereads 228 data3 = np.array(secret_data) 229 assert_array_equal(data3, dat) 230