Skip to content

Commit f20392f

Browse files
author
Félix C. Morency
committed
NF: Added ECAT7 write support
1 parent 719aee7 commit f20392f

File tree

1 file changed

+60
-4
lines changed

1 file changed

+60
-4
lines changed

nibabel/ecat.py

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from .volumeutils import (native_code, swapped_code, make_dt_codes,
1414
array_from_file)
1515
from .spatialimages import SpatialImage, ImageDataError
16+
from .arraywriters import make_array_writer
1617

1718

1819
MAINHDRSZ = 502
@@ -287,6 +288,9 @@ def from_fileobj(klass, fileobj, endianness=None):
287288
raw_str = fileobj.read(klass._dtype.itemsize)
288289
return klass(raw_str, endianness)
289290

291+
def write_to(self, fileobj):
292+
fileobj.write(self.binaryblock)
293+
290294
def _empty_headerdata(self,endianness=None):
291295
"""Return header data for empty header with given endianness"""
292296
#hdr_data = super(EcatHeader, self)._empty_headerdata(endianness)
@@ -861,10 +865,62 @@ def from_file_map(klass, file_map):
861865
img = klass(data, aff, header, subheaders, mlist, extra=None, file_map = file_map)
862866
return img
863867

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
868924

869925
@classmethod
870926
def from_image(klass, img):

0 commit comments

Comments
 (0)