Skip to content

Commit ee40bbb

Browse files
committed
RF+DOC: rewording of ECAT docstrings / variable naming
Use 'block' instead of 'record' for 512 byte chunks. Rename variables accordingly.
1 parent 27fb8de commit ee40bbb

File tree

1 file changed

+38
-41
lines changed

1 file changed

+38
-41
lines changed

nibabel/ecat.py

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,27 @@
1313
* a *main header*;
1414
* at least one *matrix list* (mlist);
1515
16-
ECAT thinks of memory locations in terms of *records*. One record is 512
17-
bytes. Thus record 1 is at 0 bytes, record 2 at 512 bytes, and so on.
16+
ECAT thinks of memory locations in terms of *blocks*. One block is 512
17+
bytes. Thus block 1 starts at 0 bytes, block 2 at 512 bytes, and so on.
1818
1919
The matrix list is an array with one row per frame in the data.
2020
2121
Columns in the matrix list are:
2222
2323
* 0 - Matrix identifier (frame number)
24-
* 1 - matrix data start record number (subheader stored here)
25-
* 2 - Last record number of matrix data block.
24+
* 1 - matrix data start block number (subheader followed by image data)
25+
* 2 - Last block number of matrix (image) data
2626
* 3 - Matrix status:
2727
* 1 - exists - rw
2828
* 2 - exists - ro
2929
* 3 - matrix deleted
3030
3131
There is one sub-header for each image frame (or matrix in the terminology
32-
above).
32+
above). A sub-header can also be called an *image header*. The sub-header is
33+
one block (512 bytes), and the frame (image) data follows.
3334
34-
A sub-header can also be called an *image header*.
35-
36-
There is very little documentation of this format, and many of the comments in
37-
this code come from a combination of trial and error and wild speculation.
35+
There is very little documentation of the ECAT format, and many of the comments
36+
in this code come from a combination of trial and error and wild speculation.
3837
3938
XMedcon can read and write ECAT 6 format, and read ECAT 7 format: see
4039
http://xmedcon.sourceforge.net and the ECAT files in the source of XMedCon,
@@ -55,9 +54,8 @@
5554
from .wrapstruct import WrapStruct
5655
from .fileslice import canonical_slicers, predict_shape, slice2outax
5756

58-
RECORD_BYTES = 512
57+
BLOCK_SIZE = 512
5958

60-
MAINHDRSZ = 502
6159
main_header_dtd = [
6260
('magic_number', '14S'),
6361
('original_filename', '32S'),
@@ -332,57 +330,56 @@ def read_mlist(fileobj, endianness):
332330
mlist : (nframes, 4) ndarray
333331
matrix list is an array with ``nframes`` rows and columns:
334332
335-
* 0 - Matrix identifier.
336-
* 1 - subheader record number
337-
* 2 - Last record number of matrix data block.
333+
* 0 - Matrix identifier (frame number)
334+
* 1 - matrix data start block number (subheader followed by image data)
335+
* 2 - Last block number of matrix (image) data
338336
* 3 - Matrix status:
339-
340-
* 1 - exists - rw
341-
* 2 - exists - ro
342-
* 3 - matrix deleted
337+
* 1 - exists - rw
338+
* 2 - exists - ro
339+
* 3 - matrix deleted
343340
344341
Notes
345342
-----
346-
A 'record' or 'block' is 512 bytes.
343+
A block is 512 bytes.
347344
348-
``record_no`` in the code below is 1-based. Record 1 is the main header,
349-
and the mlist records start at record number 2.
345+
``block_no`` in the code below is 1-based. block 1 is the main header,
346+
and the mlist blocks start at block number 2.
350347
351-
The 512 bytes in an mlist record represents 32 rows of the int32 (nframes,
348+
The 512 bytes in an mlist block contain 32 rows of the int32 (nframes,
352349
4) mlist matrix.
353350
354351
The first row of these 32 looks like a special row. The 4 values appear
355352
to be (respectively):
356353
357354
* not sure - maybe negative number of mlist rows (out of 31) that are
358-
blank and not used in this record. Called `nfree` but unused in CTI
355+
blank and not used in this block. Called `nfree` but unused in CTI
359356
code;
360-
* record_no - of next set of mlist entries or 2 if no more entries. We also
357+
* block_no - of next set of mlist entries or 2 if no more entries. We also
361358
allow 1 or 0 to signal no more entries;
362-
* <no idea>. Called `prvblk` in CTI code, so maybe previous record no;
363-
* n_rows - number of mlist rows in this record (between ?0 and 31) (called
359+
* <no idea>. Called `prvblk` in CTI code, so maybe previous block no;
360+
* n_rows - number of mlist rows in this block (between ?0 and 31) (called
364361
`nused` in CTI code).
365362
"""
366363
dt = np.dtype(np.int32) # should this be uint32 given mlist dtype?
367364
if not endianness is native_code:
368365
dt = dt.newbyteorder(endianness)
369366
mlists = []
370367
mlist_index = 0
371-
mlist_record_no = 2 # 1-based indexing, record with first mlist
368+
mlist_block_no = 2 # 1-based indexing, block with first mlist
372369
while True:
373-
# Read record containing mlist entries
374-
fileobj.seek((mlist_record_no - 1) * RECORD_BYTES) # fix 1-based indexing
370+
# Read block containing mlist entries
371+
fileobj.seek((mlist_block_no - 1) * BLOCK_SIZE) # fix 1-based indexing
375372
dat = fileobj.read(128 * 32) # isn't this too long? Should be 512?
376373
rows = np.ndarray(shape=(32, 4), dtype=dt, buffer=dat)
377374
# First row special, points to next mlist entries if present
378-
n_unused, mlist_record_no, _, n_rows = rows[0]
375+
n_unused, mlist_block_no, _, n_rows = rows[0]
379376
if not (n_unused + n_rows) == 31: # Some error condition here?
380377
mlist = []
381378
return mlist
382379
# Use all but first housekeeping row
383380
mlists.append(rows[1:n_rows+1])
384381
mlist_index += n_rows
385-
if mlist_record_no <= 2: # should record_no in (1, 2) be an error?
382+
if mlist_block_no <= 2: # should block_no in (1, 2) be an error?
386383
break
387384
# Code in ``get_frame_order`` seems to imply ids can be < 0; is that
388385
# true? Should the dtype be uint32 or int32?
@@ -481,8 +478,8 @@ def read_subheaders(fileobj, mlist, endianness):
481478
mlist : (nframes, 4) ndarray
482479
Columns are:
483480
* 0 - Matrix identifier.
484-
* 1 - subheader record number
485-
* 2 - Last record number of matrix data block.
481+
* 1 - subheader block number
482+
* 2 - Last block number of matrix data block.
486483
* 3 - Matrix status:
487484
endianness : {'<', '>'}
488485
little / big endian code
@@ -496,12 +493,12 @@ def read_subheaders(fileobj, mlist, endianness):
496493
dt = subhdr_dtype
497494
if not endianness is native_code:
498495
dt = dt.newbyteorder(endianness)
499-
for mat_id, sh_recno, sh_last_recno, mat_stat in mlist:
500-
if sh_recno == 0:
496+
for mat_id, sh_blkno, sh_last_blkno, mat_stat in mlist:
497+
if sh_blkno == 0:
501498
break
502-
offset = (sh_recno - 1) * 512
499+
offset = (sh_blkno - 1) * BLOCK_SIZE
503500
fileobj.seek(offset)
504-
tmpdat = fileobj.read(512)
501+
tmpdat = fileobj.read(BLOCK_SIZE)
505502
sh = np.ndarray(shape=(), dtype=dt, buffer=tmpdat)
506503
subheaders.append(sh)
507504
return subheaders
@@ -520,14 +517,14 @@ def __init__(self,fileobj, hdr):
520517
Columns are:
521518
522519
* 0 - Matrix identifier.
523-
* 1 - subheader record number
524-
* 2 - Last record number of matrix data block.
520+
* 1 - subheader block number
521+
* 2 - Last block number of matrix data block.
525522
* 3 - Matrix status:
526523
* 1 - exists - rw
527524
* 2 - exists - ro
528525
* 3 - matrix deleted
529526
530-
A record above is 512 bytes in the image data file
527+
A block above is 512 bytes in the image data file
531528
532529
Parameters
533530
-----------
@@ -631,7 +628,7 @@ def _get_data_dtype(self, frame):
631628

632629
def _get_frame_offset(self, frame=0):
633630
mlist = self._mlist._mlist
634-
offset = (mlist[frame][1]) * 512
631+
offset = (mlist[frame][1]) * BLOCK_SIZE
635632
return int(offset)
636633

637634
def _get_oriented_data(self, raw_data, orientation=None):

0 commit comments

Comments
 (0)