Read ECAT format images
An ECAT format image consists of:
ECAT thinks of memory locations in terms of blocks. One block is 512 bytes. Thus block 1 starts at 0 bytes, block 2 at 512 bytes, and so on.
The matrix list is an array with one row per frame in the data.
Columns in the matrix list are:
0 - Matrix identifier (frame number)
1 - matrix data start block number (subheader followed by image data)
2 - Last block number of matrix (image) data
There is one sub-header for each image frame (or matrix in the terminology above). A sub-header can also be called an image header. The sub-header is one block (512 bytes), and the frame (image) data follows.
There is very little documentation of the ECAT format, and many of the comments in this code come from a combination of trial and error and wild speculation.
XMedcon can read and write ECAT 6 format, and read ECAT 7 format: see http://xmedcon.sourceforge.net and the ECAT files in the source of XMedCon, currently libs/tpc/*ecat* and source/m-ecat*. Unfortunately XMedCon is GPL and some of the header files are adapted from CTI files (called CTI code below). It’s not clear what the licenses are for these files.
EcatHeader([binaryblock, endianness, check]) | Class for basic Ecat PET header |
EcatImage(dataobj, affine, header, ...[, ...]) | Class returns a list of Ecat images, with one image(hdr/data) per frame |
EcatImageArrayProxy(subheader) | Ecat implemention of array proxy protocol |
EcatSubHeader(hdr, mlist, fileobj) | parses the subheaders in the ecat (.v) file |
get_frame_order(mlist) | Returns the order of the frames stored in the file |
get_series_framenumbers(mlist) | Returns framenumber of data as it was collected, |
load | |
read_mlist(fileobj, endianness) | read (nframes, 4) matrix list array from fileobj |
read_subheaders(fileobj, mlist, endianness) | Retrieve all subheaders and return list of subheader recarrays |
Bases: nibabel.wrapstruct.WrapStruct
Class for basic Ecat PET header
Sub-parts of standard Ecat File
This just reads the main Ecat Header, it does not load the data or read the mlist or any sub headers
Initialize Ecat header from bytes object
Parameters: | binaryblock : {None, bytes} optional
endianness : {None, ‘<’, ‘>’, other endian code}, optional
check : {True, False}, optional
|
---|
Initialize Ecat header from bytes object
Parameters: | binaryblock : {None, bytes} optional
endianness : {None, ‘<’, ‘>’, other endian code}, optional
check : {True, False}, optional
|
---|
Return header data for empty header with given endianness
Get numpy dtype for data from header
Type of ECAT Matrix File from code stored in header
gets orientation of patient based on code stored in header, not always reliable
Guess endian from MAGIC NUMBER value of header data
Bases: nibabel.spatialimages.SpatialImage
Class returns a list of Ecat images, with one image(hdr/data) per frame
Initialize Image
The image is a combination of (array, affine matrix, header, subheader, mlist) with optional meta data in extra, and filename / file-like objects contained in the file_map.
Parameters: | dataabj : array-like
affine : None or (4,4) array-like
header : None or header instance
subheader : None or subheader instance
mlist : None or array
extra : None or mapping, optional
file_map : mapping, optional
|
---|
Examples
>>> import os
>>> import nibabel as nib
>>> nibabel_dir = os.path.dirname(nib.__file__)
>>> from nibabel import ecat
>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
>>> img = ecat.load(ecat_file)
>>> frame0 = img.get_frame(0)
>>> frame0.shape == (10, 10, 3)
True
>>> data4d = img.get_data()
>>> data4d.shape == (10, 10, 3, 1)
True
Initialize Image
The image is a combination of (array, affine matrix, header, subheader, mlist) with optional meta data in extra, and filename / file-like objects contained in the file_map.
Parameters: | dataabj : array-like
affine : None or (4,4) array-like
header : None or header instance
subheader : None or subheader instance
mlist : None or array
extra : None or mapping, optional
file_map : mapping, optional
|
---|
Examples
>>> import os
>>> import nibabel as nib
>>> nibabel_dir = os.path.dirname(nib.__file__)
>>> from nibabel import ecat
>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
>>> img = ecat.load(ecat_file)
>>> frame0 = img.get_frame(0)
>>> frame0.shape == (10, 10, 3)
True
>>> data4d = img.get_data()
>>> data4d.shape == (10, 10, 3, 1)
True
alias of EcatImageArrayProxy
class method to create image from mapping specified in file_map
Get full volume for a time frame
Parameters: |
|
---|---|
Return type: | Numpy array containing (possibly oriented) raw data |
returns 4X4 affine
get access to the mlist
get access to subheaders
alias of EcatHeader
Write ECAT7 image to file_map or contained self.file_map
The format consist of:
[numAvail, nextDir, previousDir, numUsed]
For every frame (3D volume in 4D data) - A subheader (size = frame_offset) - Frame data (3D volume)
Bases: object
parses the subheaders in the ecat (.v) file there is one subheader for each frame in the ecat file
Parameters: | hdr : EcatHeader
mlist : array shape (N, 4)
fileobj : ECAT file <filename>.v fileholder or file object
|
---|
parses the subheaders in the ecat (.v) file there is one subheader for each frame in the ecat file
Parameters: | hdr : EcatHeader
mlist : array shape (N, 4)
fileobj : ECAT file <filename>.v fileholder or file object
|
---|
Read scaled data from file for a given frame
Parameters: |
|
---|---|
Return type: | Numpy array containing (possibly oriented) raw data |
See also
raw_data_from_fileobj
returns best affine for given frame of data
returns number of frames
returns shape of given frame
returns zooms ...pixdims
Get raw data from file object.
Parameters: |
|
---|---|
Return type: | Numpy array containing (possibly oriented) raw data |
See also
data_from_fileobj
Returns the order of the frames stored in the file Sometimes Frames are not stored in the file in chronological order, this can be used to extract frames in correct order
Returns: | id_dict: dict mapping frame number -> [mlist_row, mlist_id] : (where mlist id is value in the first column of the mlist matrix ) : |
---|
Examples
>>> import os
>>> import nibabel as nib
>>> nibabel_dir = os.path.dirname(nib.__file__)
>>> from nibabel import ecat
>>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
>>> img = ecat.load(ecat_file)
>>> mlist = img.get_mlist()
>>> get_frame_order(mlist)
{0: [0, 16842758]}
read (nframes, 4) matrix list array from fileobj
Parameters: | fileobj : file-like
|
---|---|
Returns: | mlist : (nframes, 4) ndarray
|
Notes
A block is 512 bytes.
block_no in the code below is 1-based. block 1 is the main header, and the mlist blocks start at block number 2.
The 512 bytes in an mlist block contain 32 rows of the int32 (nframes, 4) mlist matrix.
The first row of these 32 looks like a special row. The 4 values appear to be (respectively):
Retrieve all subheaders and return list of subheader recarrays
Parameters: | fileobj : file-like
mlist : (nframes, 4) ndarray
endianness : {‘<’, ‘>’}
|
---|---|
Returns: | subheaders : list
|