def test_scaling(): # Test integer scaling from float # Analyze headers cannot do float-integer scaling ''' hdr = AnalyzeHeader() yield assert_true, hdr.default_x_flip shape = (1,2,3) hdr.set_data_shape(shape) hdr.set_data_dtype(np.float32) data = np.ones(shape, dtype=np.float64) S = StringIO() # Writing to float datatype doesn't need scaling write_scaled_data(hdr, data, S) rdata = read_data(hdr, S) yield assert_true, np.allclose(data, rdata) # Writing to integer datatype does, and raises an error hdr.set_data_dtype(np.int32) yield (assert_raises, HeaderTypeError, write_scaled_data, hdr, data, StringIO()) # unless we aren't scaling, in which case we convert the floats to # integers and write write_data(hdr, data, S) rdata = read_data(hdr, S) yield assert_true, np.allclose(data, rdata) # This won't work for floats that aren't close to integers data_p5 = data + 0.5 write_data(hdr, data_p5, S) rdata = read_data(hdr, S) yield assert_false, np.allclose(data_p5, rdata)
def test_read_write_data(self): # Check reading and writing of data hdr = self.header_class() hdr.set_data_shape((1,2,3)) hdr.set_data_dtype(np.float32) S = StringIO() data = np.arange(6, dtype=np.float64) # data have to be the right shape yield (assert_raises, HeaderDataError, write_scaled_data, hdr, data, S) data = data.reshape((1,2,3)) # and size yield (assert_raises, HeaderDataError, write_scaled_data, hdr, data[:,:,:-1], S) yield (assert_raises, HeaderDataError, write_scaled_data, hdr, data[:,:-1,:], S) # OK if so write_scaled_data(hdr, data, S) # Read it back data_back = read_data(hdr, S) # Should be about the same yield assert_array_almost_equal, data, data_back # but with the header dtype, not the data dtype yield assert_equal, hdr.get_data_dtype(), data_back.dtype # this is with native endian, not so for swapped S2 = StringIO() hdr2 = hdr.as_byteswapped() hdr2.set_data_dtype(np.float32) hdr2.set_data_shape((1,2,3)) write_scaled_data(hdr2, data, S) data_back2 = read_data(hdr2, S) # Compares the same yield assert_array_almost_equal, data_back, data_back2 # Same dtype names yield assert_equal, data_back.dtype.name, data_back2.dtype.name # But not the same endianness yield (assert_not_equal, data.dtype.byteorder, data_back2.dtype.byteorder) # Try scaling down to integer hdr.set_data_dtype(np.uint8) S3 = StringIO() # Analyze header cannot do scaling, but, if not scaling, # AnalyzeHeader is OK write_data(hdr, data, S3) data_back = read_data(hdr, S3) yield assert_array_almost_equal, data, data_back # But, the data won't always be same as input if not scaling data = np.arange(6, dtype=np.float64).reshape((1,2,3)) + 0.5 write_data(hdr, data, S3) data_back = read_data(hdr, S3) yield assert_false, np.allclose(data, data_back)
def test_scaling(self): hdr = self.header_class() hdr.set_data_shape((1,2,3)) hdr.set_data_dtype(np.int16) S3 = StringIO() data = np.arange(6, dtype=np.float64).reshape((1,2,3)) # This uses scaling write_scaled_data(hdr, data, S3) data_back = read_data(hdr, S3) yield assert_array_almost_equal, data, data_back, 4 # This is exactly the same call, just testing it works twice data_back2 = read_data(hdr, S3) yield assert_array_equal, data_back, data_back2, 4
def test_general_init(self): hdr = self.header_class() # binaryblock has length given by header data dtype binblock = hdr.binaryblock yield assert_equal, len(binblock), hdr.structarr.dtype.itemsize # an empty header has shape (0,) - like an empty array (np.array([])) yield assert_equal, hdr.get_data_shape(), (0,) # The affine is always homogenous 3D regardless of shape. The # default affine will have -1 as the X zoom iff default_x_flip # is True (which it is by default). We have to be careful of # the translations though - these arise from SPM's use of the # origin field, and the center of the image. yield assert_array_equal, np.diag(hdr.get_base_affine()), [-1,1,1,1] # But zooms only go with number of dimensions yield assert_equal, hdr.get_zooms(), () # Endianness will be native by default for empty header yield assert_equal, hdr.endianness, native_code # But you can change this if you want hdr = self.header_class(endianness='swapped') yield assert_equal, hdr.endianness, swapped_code # Trying to read data from an empty header gives no data yield assert_equal, len(read_data(hdr, StringIO())), 0 # Setting no data into an empty header results in - no data sfobj = StringIO() write_scaled_data(hdr, [], sfobj) yield assert_equal, sfobj.getvalue(), '' # Setting more data then there should be gives an error yield (assert_raises, HeaderDataError, write_scaled_data, hdr, np.zeros(3), sfobj) # You can also pass in a check flag, without data this has no effect hdr = self.header_class(check=False)
def get_data(self): ''' Lazy load of data ''' if not self._data is None: return self._data if not self._files: return None try: fname = self._files['image'] except KeyError: return None self._data = read_data(self._header, allopen(fname)) return self._data