@@ -442,9 +442,9 @@ def get_mlist(self, fileobj):
442
442
return mlist
443
443
444
444
def get_frame_order (self ):
445
- """Returns the order of the frames in the file
446
- Useful as sometimes Frames are not stored in the file in
447
- chronological order, and can be used to extract frames
445
+ """Returns the order of the frames stored in the file
446
+ Sometimes Frames are not stored in the file in
447
+ chronological order, this can be used to extract frames
448
448
in correct order
449
449
450
450
Returns
@@ -465,20 +465,69 @@ def get_frame_order(self):
465
465
>>> mlist.get_frame_order()
466
466
{0: [0, 16842758.0]}
467
467
468
+
468
469
"""
469
470
mlist = self ._mlist
470
- ind = mlist [:,0 ] > 0
471
- nframes = ind .shape [0 ]
472
- tmp = mlist [ind ,0 ]
473
- tmp .sort ()
474
- frame_dict = {}
471
+ ids = mlist [:, 0 ].copy ()
472
+ n_valid = np .sum (ids > 0 )
473
+ ids [ids <= 0 ] = ids .max () + 1 # put invalid frames at end after sort
474
+ valid_order = np .argsort (ids )
475
+ if not all (valid_order == sorted (valid_order )):
476
+ #raise UserWarning if Frames stored out of order
477
+ warnings .warn_explicit ('Frames stored out of order;' \
478
+ 'true order = %s\n ' \
479
+ 'frames will be accessed in order ' \
480
+ 'STORED, NOT true order' % (valid_order ),
481
+ UserWarning ,'ecat' , 0 )
475
482
id_dict = {}
476
- for fn , id in enumerate (mlist [ind ,0 ]):
477
- mlist_n = np .where (mlist [:,0 ] == id )[0 ][0 ]
478
- id_dict .update ({fn :[mlist_n ,id ]})
479
-
483
+ for i in range (n_valid ):
484
+ id_dict [i ] = [valid_order [i ], ids [valid_order [i ]]]
485
+
480
486
return id_dict
481
-
487
+
488
+ def get_series_framenumbers (self ):
489
+ """ Returns framenumber of data as it was collected,
490
+ as part of a series; not just the order of how it was
491
+ stored in this or across other files
492
+
493
+ For example, if the data is split between multiple files
494
+ this should give you the true location of this frame as
495
+ collected in the series
496
+ (Frames are numbered starting at ONE (1) not Zero)
497
+
498
+ Returns
499
+ -------
500
+ frame_dict: dict mapping order_stored -> frame in series
501
+ where frame in series counts from 1; [1,2,3,4...]
502
+
503
+ Examples
504
+ --------
505
+ >>> import os
506
+ >>> import nibabel as nib
507
+ >>> nibabel_dir = os.path.dirname(nib.__file__)
508
+ >>> from nibabel import ecat
509
+ >>> ecat_file = os.path.join(nibabel_dir,'tests','data','tinypet.v')
510
+ >>> img = ecat.load(ecat_file)
511
+ >>> mlist = img.get_mlist()
512
+ >>> mlist.get_series_framenumbers()
513
+ {0: 1}
514
+
515
+
516
+
517
+ """
518
+ frames_order = self .get_frame_order ()
519
+ nframes = self .hdr ['num_frames' ]
520
+ mlist_nframes = len (frames_order )
521
+ trueframenumbers = np .arange (nframes - mlist_nframes , nframes )
522
+ frame_dict = {}
523
+ try :
524
+ for frame_stored , (true_order , _ ) in frames_order .items ():
525
+ #frame as stored in file -> true number in series
526
+ frame_dict [frame_stored ] = trueframenumbers [true_order ]+ 1
527
+ return frame_dict
528
+ except :
529
+ raise IOError ('Error in header or mlist order unknown' )
530
+
482
531
class EcatSubHeader (object ):
483
532
484
533
_subhdrdtype = subhdr_dtype
@@ -625,7 +674,8 @@ def data_from_fileobj(self, frame=0):
625
674
626
675
627
676
class EcatImage (SpatialImage ):
628
- """This class returns a list of Ecat images, with one image(hdr/data) per frame
677
+ """This class returns a list of Ecat images,
678
+ with one image(hdr/data) per frame
629
679
"""
630
680
_header = EcatHeader
631
681
header_class = _header
@@ -650,7 +700,8 @@ def __init__(self, subheader):
650
700
def __array__ (self ):
651
701
''' Cached read of data from file
652
702
This reads ALL FRAMES into one array, can be memory expensive
653
- use subheader.data_from_fileobj(frame) for less memeory intensive reads
703
+ use subheader.data_from_fileobj(frame) for less memory intensive
704
+ reads
654
705
'''
655
706
if self ._data is None :
656
707
self ._data = np .empty (self .shape )
@@ -664,8 +715,9 @@ def __init__(self, data, affine, header,
664
715
extra = None , file_map = None ):
665
716
""" Initialize Image
666
717
667
- The image is a combination of (array, affine matrix, header, subheader,
668
- mlist) with optional meta data in `extra`, and filename / file-like objects
718
+ The image is a combination of
719
+ (array, affine matrix, header, subheader, mlist)
720
+ with optional meta data in `extra`, and filename / file-like objects
669
721
contained in the `file_map`.
670
722
671
723
Parameters
@@ -739,7 +791,7 @@ def get_affine(self):
739
791
740
792
def get_frame_affine (self , frame ):
741
793
"""returns 4X4 affine"""
742
- return self ._subheader .get_affine (frame = frame )
794
+ return self ._subheader .get_frame_affine (frame = frame )
743
795
744
796
def get_frame (self ,frame ):
745
797
return self ._subheader .data_from_fileobj (frame )
0 commit comments