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
1919The matrix list is an array with one row per frame in the data.
2020
2121Columns 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
3131There 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
3938XMedcon can read and write ECAT 6 format, and read ECAT 7 format: see
4039http://xmedcon.sourceforge.net and the ECAT files in the source of XMedCon,
5554from .wrapstruct import WrapStruct
5655from .fileslice import canonical_slicers , predict_shape , slice2outax
5756
58- RECORD_BYTES = 512
57+ BLOCK_SIZE = 512
5958
60- MAINHDRSZ = 502
6159main_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