27
27
('isotope_name' , '8S' ),
28
28
('isotope_halflife' , np .float32 ),
29
29
('radiopharmaceutical' ,'32S' ),
30
- ('gantry_tilt' , np .float32 ),
30
+ ('gantry_tilt' , np .float32 ),
31
31
('gantry_rotation' ,np .float32 ),
32
32
('bed_elevation' ,np .float32 ),
33
33
('intrinsic_tilt' , np .float32 ),
34
- ('wobble_speed' ,np .uint16 ),
34
+ ('wobble_speed' ,np .uint16 ),
35
35
('transm_source_type' ,np .uint16 ),
36
- ('distance_scanned' ,np .float32 ),
36
+ ('distance_scanned' ,np .float32 ),
37
37
('transaxial_fov' ,np .float32 ),
38
38
('angular_compression' , np .uint16 ),
39
39
('coin_samp_mode' ,np .uint16 ),
40
40
('axial_samp_mode' ,np .uint16 ),
41
- ('ecat_calibration_factor' ,np .float32 ),
41
+ ('ecat_calibration_factor' ,np .float32 ),
42
42
('calibration_unitS' , np .uint16 ),
43
43
('calibration_units_type' ,np .uint16 ),
44
44
('compression_code' ,np .uint16 ),
76
76
('well_counter_corr_factor' , np .float32 ),
77
77
('data_units' , '32S' ),
78
78
('septa_state' ,np .uint16 ),
79
- ('fill' ,np .uint16 )
79
+ ('fill' , np .uint16 )
80
80
]
81
81
hdr_dtype = np .dtype (main_header_dtd )
82
82
@@ -191,23 +191,23 @@ class EcatHeader(object):
191
191
"""Class for basic Ecat PET header
192
192
Sub-parts of standard Ecat File
193
193
main header
194
- matrix list
195
- which lists the information for each
194
+ matrix list
195
+ which lists the information for each
196
196
frame collected (can have 1 to many frames)
197
- subheaders specific to each frame
197
+ subheaders specific to each frame
198
198
with possibly-variable sized data blocks
199
-
200
- This just reads the main Ecat Header,
201
- it does not load the data
199
+
200
+ This just reads the main Ecat Header,
201
+ it does not load the data
202
202
or read the mlist or any sub headers
203
203
204
204
"""
205
205
206
206
_dtype = hdr_dtype
207
207
_ft_defs = ft_defs
208
208
_patient_orient_defs = patient_orient_defs
209
-
210
- def __init__ (self ,
209
+
210
+ def __init__ (self ,
211
211
fileobj = None ,
212
212
endianness = None ):
213
213
"""Initialize Ecat header from file object
@@ -224,20 +224,20 @@ def __init__(self,
224
224
if fileobj is None :
225
225
self ._header_data = self ._empty_headerdata (endianness )
226
226
return
227
-
227
+
228
228
hdr = np .ndarray (shape = (),
229
229
dtype = self ._dtype ,
230
230
buffer = fileobj )
231
231
if endianness is None :
232
232
endianness = self ._guess_endian (hdr )
233
-
233
+
234
234
if endianness != native_code :
235
235
dt = self ._dtype .newbyteorder (endianness )
236
236
hdr = np .ndarray (shape = (),
237
237
dtype = dt ,
238
238
buffer = fileobj )
239
239
self ._header_data = hdr .copy ()
240
-
240
+
241
241
return
242
242
243
243
def get_header (self ):
@@ -271,7 +271,7 @@ def from_fileobj(klass, fileobj, endianness=None):
271
271
----------
272
272
fileobj : file-like object
273
273
Needs to implement ``read`` method
274
- endianness : None or endian code, optional
274
+ endianness : None or endian code, optional
275
275
Code specifying endianness of data to be read
276
276
277
277
Returns
@@ -281,7 +281,7 @@ def from_fileobj(klass, fileobj, endianness=None):
281
281
282
282
Examples
283
283
--------
284
-
284
+
285
285
286
286
"""
287
287
raw_str = fileobj .read (klass ._dtype .itemsize )
@@ -296,7 +296,7 @@ def _empty_headerdata(self,endianness=None):
296
296
hdr_data = np .zeros ((), dtype = dt )
297
297
hdr_data ['magic_number' ] = 'MATRIX72'
298
298
hdr_data ['sw_version' ] = 74
299
- hdr_data ['num_frames' ]= 0
299
+ hdr_data ['num_frames' ]= 0
300
300
hdr_data ['file_type' ] = 0 # Unknown
301
301
hdr_data ['ecat_calibration_factor' ] = 1.0 # scale factor
302
302
return hdr_data
@@ -305,7 +305,7 @@ def _empty_headerdata(self,endianness=None):
305
305
def get_data_dtype (self ):
306
306
""" Get numpy dtype for data from header"""
307
307
raise NotImplementedError ("dtype is only valid from subheaders" )
308
-
308
+
309
309
310
310
def copy (self ):
311
311
return self .__class__ (
@@ -321,7 +321,7 @@ def __eq__(self, other):
321
321
return self_bb == other .binaryblock
322
322
other_bb = other ._header_data .byteswap ().tostring ()
323
323
return self_bb == other_bb
324
-
324
+
325
325
def __ne__ (self , other ):
326
326
''' equality between two headers defined by ``header_data``
327
327
@@ -369,14 +369,14 @@ def get_filetype(self):
369
369
if not ft_codes .has_key (code ):
370
370
raise KeyError ('Ecat Filetype CODE %d not recognized' % code )
371
371
return ft_codes [code ]
372
-
372
+
373
373
def __iter__ (self ):
374
374
return iter (self .keys ())
375
-
375
+
376
376
def keys (self ):
377
377
''' Return keys from header data'''
378
378
return list (self ._dtype .names )
379
-
379
+
380
380
def values (self ):
381
381
''' Return values from header data'''
382
382
data = self ._header_data
@@ -385,9 +385,9 @@ def values(self):
385
385
def items (self ):
386
386
''' Return items from header data'''
387
387
return zip (self .keys (), self .values ())
388
-
388
+
389
389
class EcatMlist (object ):
390
-
390
+
391
391
def __init__ (self ,fileobj , hdr ):
392
392
""" gets list of frames and subheaders in pet file
393
393
@@ -413,21 +413,22 @@ def __init__(self,fileobj, hdr):
413
413
def get_mlist (self , fileobj ):
414
414
fileobj .seek (512 )
415
415
dat = fileobj .read (128 * 32 )
416
-
416
+
417
417
dt = np .dtype ([('matlist' ,np .int32 )])
418
418
if not self .hdr .endianness is native_code :
419
419
dt = dt .newbyteorder (self .hdr .endianness )
420
420
nframes = self .hdr ['num_frames' ]
421
421
mlist = np .zeros ((nframes ,4 ))
422
422
record_count = 0
423
423
done = False
424
+
424
425
while not done : #mats['matlist'][0,1] == 2:
425
-
426
+
426
427
mats = np .recarray (shape = (32 ,4 ), dtype = dt , buf = dat )
427
428
if not (mats ['matlist' ][0 ,0 ] + mats ['matlist' ][0 ,3 ]) == 31 :
428
429
mlist = []
429
430
return mlist
430
-
431
+
431
432
nrecords = mats ['matlist' ][0 ,3 ]
432
433
mlist [record_count :nrecords + record_count ,:] = mats ['matlist' ][1 :nrecords + 1 ,:]
433
434
record_count += nrecords
@@ -439,6 +440,7 @@ def get_mlist(self, fileobj):
439
440
fileobj .seek (0 )
440
441
fileobj .seek (tmp * 512 )
441
442
dat = fileobj .read (128 * 32 )
443
+
442
444
return mlist
443
445
444
446
def get_frame_order (self ):
@@ -465,7 +467,7 @@ def get_frame_order(self):
465
467
>>> mlist.get_frame_order()
466
468
{0: [0, 16842758.0]}
467
469
468
-
470
+
469
471
"""
470
472
mlist = self ._mlist
471
473
ids = mlist [:, 0 ].copy ()
@@ -482,7 +484,7 @@ def get_frame_order(self):
482
484
id_dict = {}
483
485
for i in range (n_valid ):
484
486
id_dict [i ] = [valid_order [i ], ids [valid_order [i ]]]
485
-
487
+
486
488
return id_dict
487
489
488
490
def get_series_framenumbers (self ):
@@ -512,8 +514,8 @@ def get_series_framenumbers(self):
512
514
>>> mlist.get_series_framenumbers()
513
515
{0: 1}
514
516
515
-
516
-
517
+
518
+
517
519
"""
518
520
frames_order = self .get_frame_order ()
519
521
nframes = self .hdr ['num_frames' ]
@@ -527,12 +529,12 @@ def get_series_framenumbers(self):
527
529
return frame_dict
528
530
except :
529
531
raise IOError ('Error in header or mlist order unknown' )
530
-
532
+
531
533
class EcatSubHeader (object ):
532
534
533
535
_subhdrdtype = subhdr_dtype
534
536
_data_type_codes = data_type_codes
535
-
537
+
536
538
def __init__ (self , hdr , mlist , fileobj ):
537
539
"""parses the subheaders in the ecat (.v) file
538
540
there is one subheader for each frame in the ecat file
@@ -542,7 +544,7 @@ def __init__(self, hdr, mlist, fileobj):
542
544
hdr : EcatHeader
543
545
544
546
mlist : EcatMlist
545
-
547
+
546
548
fileobj : ECAT file <filename>.v fileholder or file object
547
549
with read, seek methods
548
550
@@ -583,7 +585,7 @@ def _get_subheaders(self):
583
585
buf = tmpdat ))
584
586
subheaders .append (sh )
585
587
return subheaders
586
-
588
+
587
589
def get_shape (self , frame = 0 ):
588
590
""" returns shape of given frame"""
589
591
subhdr = self .subheaders [frame ]
@@ -611,24 +613,24 @@ def _check_affines(self):
611
613
for item in i :
612
614
if not np .all (first == item ):
613
615
return False
614
- return True
615
-
616
+ return True
617
+
616
618
def get_frame_affine (self ,frame = 0 ):
617
619
"""returns best affine for given frame of data"""
618
620
subhdr = self .subheaders [frame ]
619
621
x_off = subhdr ['x_offset' ]
620
622
y_off = subhdr ['y_offset' ]
621
623
z_off = subhdr ['z_offset' ]
622
-
624
+
623
625
zooms = self .get_zooms (frame = frame )
624
-
626
+
625
627
dims = self .get_shape (frame )
626
628
# get translations from center of image
627
- origin_offset = (np .array (dims )- 1 ) / 2.0
629
+ origin_offset = (np .array (dims )- 1 ) / 2.0
628
630
aff = np .diag (zooms )
629
631
aff [:3 ,- 1 ] = - origin_offset * zooms [:- 1 ] + np .array ([x_off ,y_off ,z_off ])
630
632
return aff
631
-
633
+
632
634
def get_zooms (self ,frame = 0 ):
633
635
"""returns zooms ...pixdims"""
634
636
subhdr = self .subheaders [frame ]
@@ -669,7 +671,7 @@ def data_from_fileobj(self, frame=0):
669
671
data = raw_data * header ['ecat_calibration_factor' ]
670
672
data = data * subhdr ['scale_factor' ]
671
673
return data
672
-
674
+
673
675
674
676
675
677
0 commit comments