|
13 | 13 | from .volumeutils import (native_code, swapped_code, make_dt_codes,
|
14 | 14 | array_from_file)
|
15 | 15 | from .spatialimages import SpatialImage, ImageDataError
|
| 16 | +from .arraywriters import make_array_writer |
16 | 17 |
|
17 | 18 |
|
18 | 19 | MAINHDRSZ = 502
|
@@ -287,6 +288,9 @@ def from_fileobj(klass, fileobj, endianness=None):
|
287 | 288 | raw_str = fileobj.read(klass._dtype.itemsize)
|
288 | 289 | return klass(raw_str, endianness)
|
289 | 290 |
|
| 291 | + def write_to(self, fileobj): |
| 292 | + fileobj.write(self.binaryblock) |
| 293 | + |
290 | 294 | def _empty_headerdata(self,endianness=None):
|
291 | 295 | """Return header data for empty header with given endianness"""
|
292 | 296 | #hdr_data = super(EcatHeader, self)._empty_headerdata(endianness)
|
@@ -861,10 +865,62 @@ def from_file_map(klass, file_map):
|
861 | 865 | img = klass(data, aff, header, subheaders, mlist, extra=None, file_map = file_map)
|
862 | 866 | return img
|
863 | 867 |
|
864 |
| - def to_filename(self, filename): |
865 |
| - """nibabel does not support writing to Ecat filetypes at this time""" |
866 |
| - raise NotImplementedError('nibabel does not allow saving to Ecat'\ |
867 |
| - ' at this time ') |
| 868 | + def to_file_map(self, file_map=None): |
| 869 | + ''' Write ECAT7 image to `file_map` or contained ``self.file_map`` |
| 870 | +
|
| 871 | + The format consist of: |
| 872 | +
|
| 873 | + - A main header (512L) |
| 874 | + - For every frame (3D volume in 4D data) |
| 875 | + - A subheader (size = frame_offset) |
| 876 | + - Frame data (3D volume) |
| 877 | + - Directory entry (16L) |
| 878 | + ''' |
| 879 | + if file_map is None: |
| 880 | + file_map = self.file_map |
| 881 | + |
| 882 | + data = self.get_data() |
| 883 | + hdr = self.get_header() |
| 884 | + mlist = self.get_mlist()._mlist |
| 885 | + subheaders = self.get_subheaders() |
| 886 | + entry_pos = 528L #512L + 16L |
| 887 | + |
| 888 | + hdr_fh, img_fh = self._get_fileholders(file_map) |
| 889 | + hdrf = hdr_fh.get_prepare_fileobj(mode='wb') |
| 890 | + imgf = hdrf |
| 891 | + |
| 892 | + #Write main header |
| 893 | + hdr.write_to(hdrf) |
| 894 | + |
| 895 | + #Write every frames |
| 896 | + for index in xrange(0, self.get_header()['num_frames']): |
| 897 | + #Move to subheader offset |
| 898 | + frame_offset = subheaders._get_frame_offset(index) |
| 899 | + imgf.seek(frame_offset) |
| 900 | + |
| 901 | + #Write subheader |
| 902 | + subhdr = subheaders.subheaders[index] |
| 903 | + imgf.write(subhdr.tostring()) |
| 904 | + |
| 905 | + #Get frame and its data type |
| 906 | + dtype = self.get_data_dtype(index) |
| 907 | + image = self.get_frame(index) |
| 908 | + |
| 909 | + #Rescale data to original value |
| 910 | + #(see EcatSubHeader.data_from_fileobj) |
| 911 | + image = image / subhdr['scale_factor'] |
| 912 | + image = image / hdr['ecat_calibration_factor'] |
| 913 | + |
| 914 | + #Write image |
| 915 | + arr_writer = make_array_writer( |
| 916 | + np.cast[dtype](image), |
| 917 | + dtype) |
| 918 | + arr_writer.to_fileobj(imgf) |
| 919 | + |
| 920 | + #Move to dictionnary offset and write dictionnary entry |
| 921 | + imgf.seek(entry_pos) |
| 922 | + imgf.write(mlist[index].tostring()) |
| 923 | + entrypos = entry_pos + 16L |
868 | 924 |
|
869 | 925 | @classmethod
|
870 | 926 | def from_image(klass, img):
|
|
0 commit comments