@@ -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
@@ -467,17 +467,50 @@ def get_frame_order(self):
467
467
468
468
"""
469
469
mlist = self ._mlist
470
- ind = mlist [:,0 ] > 0
471
- nframes = ind .shape [0 ]
472
- tmp = mlist [ind ,0 ]
473
- tmp .sort ()
474
- frame_dict = {}
470
+ ids = mlist [:, 0 ].copy ()
471
+ n_valid = np .sum (ids > 0 )
472
+ ids [ids <= 0 ] = ids .max () + 1 # put invalid frames at end after sort
473
+ valid_order = np .argsort (ids )
474
+ if not all (valid_order == sorted (valid_order )):
475
+ #raise UserWarning if Frames stored out of order
476
+ warnings .warn_explicit ('Frames stored out of order;' \
477
+ 'true order = %s\n ' \
478
+ 'frames will be accessed in order ' \
479
+ 'STORED, NOT true order' % (valid_order ),
480
+ UserWarning ,'ecat' , 0 )
475
481
id_dict = {}
476
- for fn , id in enumerate (mlist [ind ,0 ]):
477
- mlist_n = np .where (tmp == id )[0 ][0 ]
478
- id_dict .update ({fn :[mlist_n ,id ]})
479
-
482
+ for i in range (n_valid ):
483
+ id_dict [i ] = [valid_order [i ], ids [valid_order [i ]]]
484
+
480
485
return id_dict
486
+
487
+ def get_series_framenumbers (self ):
488
+ """ Returns framenumber of data as it was collected,
489
+ as part of a series; not just the order of how it was
490
+ stored in this or across other files
491
+
492
+ For example, if the data is split between multiple files
493
+ this should give you the true location of this frame as
494
+ collected in the series
495
+ (Frames are numbered starting at ONE (1) not Zero)
496
+
497
+ Returns
498
+ -------
499
+ frame_dict: dict mapping order_stored -> frame in series
500
+ where frame in series counts from 1; [1,2,3,4...]
501
+
502
+
503
+
504
+ """
505
+ frames_order = self .get_frame_order ()
506
+ nframes = self .hdr ['num_frames' ]
507
+ mlist_nframes = len (frames_order )
508
+ trueframenumbers = np .arange (nframes - mlist_nframes , nframes )
509
+ frame_dict = {}
510
+ for frame_stored , (true_order , _ ) in frames_order .items ():
511
+ #frame as stored in file -> true number in series
512
+ frame_dict [frame_stored ] = trueframenumbers [true_order ]+ 1
513
+ return frame_dict
481
514
482
515
class EcatSubHeader (object ):
483
516
@@ -625,7 +658,8 @@ def data_from_fileobj(self, frame=0):
625
658
626
659
627
660
class EcatImage (SpatialImage ):
628
- """This class returns a list of Ecat images, with one image(hdr/data) per frame
661
+ """This class returns a list of Ecat images,
662
+ with one image(hdr/data) per frame
629
663
"""
630
664
_header = EcatHeader
631
665
header_class = _header
@@ -650,7 +684,8 @@ def __init__(self, subheader):
650
684
def __array__ (self ):
651
685
''' Cached read of data from file
652
686
This reads ALL FRAMES into one array, can be memory expensive
653
- use subheader.data_from_fileobj(frame) for less memeory intensive reads
687
+ use subheader.data_from_fileobj(frame) for less memory intensive
688
+ reads
654
689
'''
655
690
if self ._data is None :
656
691
self ._data = np .empty (self .shape )
@@ -664,8 +699,9 @@ def __init__(self, data, affine, header,
664
699
extra = None , file_map = None ):
665
700
""" Initialize Image
666
701
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
702
+ The image is a combination of
703
+ (array, affine matrix, header, subheader, mlist)
704
+ with optional meta data in `extra`, and filename / file-like objects
669
705
contained in the `file_map`.
670
706
671
707
Parameters
0 commit comments