Skip to content

Commit 40a9c17

Browse files
author
Félix C. Morency
committed
BF: Fixed ECAT7 dictionary writing and byte endianness
1 parent d13e172 commit 40a9c17

File tree

1 file changed

+72
-17
lines changed

1 file changed

+72
-17
lines changed

nibabel/ecat.py

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -863,16 +863,43 @@ def from_file_map(klass, file_map):
863863
img = klass(data, aff, header, subheaders, mlist, extra=None, file_map = file_map)
864864
return img
865865

866+
def _get_empty_dir(self):
867+
'''
868+
Get empty directory entry of the form
869+
[numAvail, nextDir, previousDir, numUsed]
870+
'''
871+
return np.array([31, 2, 0, 0], dtype=np.uint32)
872+
873+
def _write_data(self, data, stream, pos, dtype=None, endianness=None):
874+
'''
875+
Write data to ``stream`` using an array_writer
876+
877+
:param data: Numpy array containing the dat
878+
:param stream: The file-like object to write the data to
879+
:param pos: The position in the stream to write the data to
880+
:param endianness: Endianness code of the data to write
881+
'''
882+
if dtype is None:
883+
dtype = data.dtype
884+
885+
if endianness is None:
886+
endianness = native_code
887+
888+
stream.seek(pos)
889+
writer = make_array_writer(
890+
data.newbyteorder(endianness),
891+
dtype).to_fileobj(stream)
892+
866893
def to_file_map(self, file_map=None):
867894
''' Write ECAT7 image to `file_map` or contained ``self.file_map``
868895
869896
The format consist of:
870897
871-
- A main header (512L)
898+
- A main header (512L) with dictionary entries in the form
899+
[numAvail, nextDir, previousDir, numUsed]
872900
- For every frame (3D volume in 4D data)
873901
- A subheader (size = frame_offset)
874902
- Frame data (3D volume)
875-
- Directory entry (16L)
876903
'''
877904
if file_map is None:
878905
file_map = self.file_map
@@ -881,7 +908,9 @@ def to_file_map(self, file_map=None):
881908
hdr = self.get_header()
882909
mlist = self.get_mlist()._mlist
883910
subheaders = self.get_subheaders()
884-
entry_pos = 528L #512L + 16L
911+
dir_pos = 512L
912+
entry_pos = dir_pos + 16L #528L
913+
current_dir = self._get_empty_dir()
885914

886915
hdr_fh, img_fh = self._get_fileholders(file_map)
887916
hdrf = hdr_fh.get_prepare_fileobj(mode='wb')
@@ -900,25 +929,51 @@ def to_file_map(self, file_map=None):
900929
subhdr = subheaders.subheaders[index]
901930
imgf.write(subhdr.tostring())
902931

932+
#Seek to the next image block
933+
pos = imgf.tell()
934+
imgf.seek(pos + 2)
935+
903936
#Get frame and its data type
904-
dtype = self.get_data_dtype(index)
905937
image = self.get_frame(index)
938+
dtype = image.dtype
906939

907-
#Rescale data to original value
908-
#(see EcatSubHeader.data_from_fileobj)
909-
image = image / subhdr['scale_factor']
910-
image = image / hdr['ecat_calibration_factor']
911-
912-
#Write image
913-
arr_writer = make_array_writer(
914-
np.cast[dtype](image),
915-
dtype)
916-
arr_writer.to_fileobj(imgf)
940+
#Write frame images
941+
self._write_data(image, imgf, pos+2, endianness=swapped_code)
917942

918943
#Move to dictionnary offset and write dictionnary entry
919-
imgf.seek(entry_pos)
920-
imgf.write(mlist[index].tostring())
921-
entrypos = entry_pos + 16L
944+
self._write_data(mlist[index], imgf, entry_pos,
945+
np.uint32, endianness=swapped_code)
946+
947+
entry_pos = entry_pos + 16L
948+
949+
current_dir[0] = current_dir[0] - 1
950+
current_dir[3] = current_dir[3] + 1
951+
952+
#Create a new directory is previous one is full
953+
if current_dir[0] == 0:
954+
#self._write_dir(current_dir, imgf, dir_pos)
955+
self._write_data(current_dir, imgf, dir_pos)
956+
current_dir = self._get_empty_dir()
957+
current_dir[3] = dir_pos / 512L
958+
dir_pos = mlist[index][2] + 1
959+
entry_pos = dir_pos + 16L
960+
961+
tmp_avail = current_dir[0]
962+
tmp_used = current_dir[3]
963+
964+
#Fill directory with empty data until directory is full
965+
while current_dir[0] > 0:
966+
entry_pos = dir_pos + 16L + (16L * current_dir[3])
967+
self._write_data(np.array([0,0,0,0]), imgf, entry_pos, np.uint32)
968+
current_dir[0] = current_dir[0] - 1
969+
current_dir[3] = current_dir[3] + 1
970+
971+
current_dir[0] = tmp_avail
972+
current_dir[3] = tmp_used
973+
974+
#Write directory index
975+
self._write_data(current_dir, imgf, dir_pos, endianness='>')
976+
922977

923978
@classmethod
924979
def from_image(klass, img):

0 commit comments

Comments
 (0)