@@ -329,21 +329,6 @@ def _process_image_lines(image_lines, version):
329
329
return image_defs
330
330
331
331
332
- def _direction_numbers (bvecs ):
333
- """ Enumerate directions from an (N, 3) array of direction vectors.
334
- """
335
- cnt = 0
336
- bvec_dict = {}
337
- bvec_nos = np .zeros (len (bvecs ))
338
- for i , bvec in enumerate (bvecs ):
339
- bv = tuple (bvec )
340
- if bv not in bvec_dict :
341
- bvec_dict [bv ] = cnt
342
- cnt += 1
343
- bvec_nos [i ] = bvec_dict .get (bv )
344
- return bvec_nos
345
-
346
-
347
332
def vol_numbers (slice_nos ):
348
333
""" Calculate volume numbers inferred from slice numbers `slice_nos`
349
334
@@ -1024,6 +1009,11 @@ def get_rec_shape(self):
1024
1009
def _strict_sort_keys (self ):
1025
1010
""" Determine the sort order based on several image definition fields.
1026
1011
1012
+ If the sort keys are not unique for each volume, we calculate a volume
1013
+ number by looking for repeating slice numbers
1014
+ (see :func:`vol_numbers`). This may occur for diffusion scans from
1015
+ older V4 .PAR format, where diffusion direction info is not stored.
1016
+
1027
1017
Data sorting is done in two stages:
1028
1018
- run an initial sort using several keys of interest
1029
1019
- call `vol_is_full` to identify potentially missing volumes
@@ -1048,21 +1038,22 @@ def _strict_sort_keys(self):
1048
1038
bvals = self .get_def ('diffusion_b_factor' )
1049
1039
bvecs = self .get_def ('gradient orientation number' )
1050
1040
if bvecs is None :
1051
- # manually enumerate the different directions
1052
- bvecs = _direction_numbers (self .get_def ('diffusion' ))
1053
- diffusion_keys = (bvecs , bvals )
1041
+ # no b-vectors available
1042
+ diffusion_keys = (bvals , )
1043
+ else :
1044
+ diffusion_keys = (bvecs , bvals )
1054
1045
else :
1055
1046
diffusion_keys = ()
1056
1047
1057
1048
# Define the desired sort order (last key is highest precedence)
1058
- keys = (slice_nos , echos , phases ) + \
1049
+ keys = (slice_nos , vol_numbers ( slice_nos ), echos , phases ) + \
1059
1050
diffusion_keys + asl_keys + (dynamics , image_type )
1060
1051
1061
1052
initial_sort_order = np .lexsort (keys )
1062
1053
is_full = vol_is_full (slice_nos [initial_sort_order ],
1063
1054
self .general_info ['max_slices' ])
1064
1055
1065
- # have to "unsort" is_full to match the other sort keys
1056
+ # have to "unsort" is_full and volumes to match the other sort keys
1066
1057
unsort_indices = np .argsort (initial_sort_order )
1067
1058
is_full = is_full [unsort_indices ]
1068
1059
0 commit comments