@@ -47,6 +47,72 @@ def _fread3_many(fobj, n):
47
47
return (b1 << 16 ) + (b2 << 8 ) + b3
48
48
49
49
50
+ def read_aseg_stats (seg_stats_file , set = 'subcortical' , volumes_only = False ):
51
+ """
52
+ Returns the subcortical stats found in Freesurfer output: subid/stats/aseg.stats
53
+
54
+ Tries to match the outputs returned by Freesurfer's Matlab counter part: load_segstats.m
55
+
56
+ Parameters
57
+ ----------
58
+ filepath : str
59
+ Abs path to aseg.stats file.
60
+
61
+ set : str
62
+ Which set of volumes to return, among ['subcortical', 'wholebrain']. Default: 'subcortical'.
63
+ The choice 'subcortical' returns the usual subortical segmentations.
64
+ The choice 'wholebrain' returns only volumes (only stat available),
65
+ whose segmentations include [ 'BrainSegVol', 'BrainSegVolNotVent',
66
+ 'lhCortexVol', 'rhCortexVol', 'lhCorticalWhiteMatterVol', 'rhCorticalWhiteMatterVol',
67
+ 'SubCortGrayVol', 'TotalGrayVol', 'SupraTentorialVol', 'SupraTentorialVolNotVent',
68
+ 'MaskVol', 'BrainSegVol-to-eTIV', 'MaskVol-to-eTIV', 'lhSurfaceHoles', 'rhSurfaceHoles',
69
+ 'eTIV' ]
70
+
71
+ Returns
72
+ -------
73
+ seg_name : numpy array of strings
74
+ Array of segmentation names
75
+ seg_index : numpy array
76
+ Array of indices of segmentations into the Freesurfer color lookup table.
77
+ seg_stats : numpy array
78
+ Matrix of subcortical statistics, with the following 5 columns by default.
79
+ If volumes_only = True, only the volumes in mm^3 are returned.
80
+ Columns in the full output are:
81
+ 1. number of voxels
82
+ 2. volume of voxels (mm^3) -- same as number but scaled by voxvol
83
+ 3. mean intensity over space
84
+ 4. std intensity over space
85
+ 5. min intensity over space
86
+ 6. max intensity over space
87
+ 7. range intensity over space
88
+
89
+ """
90
+
91
+ acceptable_choices = ['subcortical' , 'wholebrain' , 'eTIV' ]
92
+ set = set .lower ()
93
+ if set not in acceptable_choices :
94
+ raise ValueError ('invalid choice. Choose one among: {}' .format (acceptable_choices ))
95
+
96
+ if set in 'subcortical' :
97
+ stats = np .loadtxt (seg_stats_file , dtype = "i1,i1,i4,f4,S50,f4,f4,f4,f4,f4" )
98
+ if volumes_only :
99
+ out_data = np .array ([seg [3 ] for seg in stats ])
100
+ else :
101
+ # need to ensure both two types return data correspond in seg order
102
+ out_data = stats
103
+
104
+ elif set in [ 'wholebrain' , 'eTIV' ]:
105
+ wb_regex_pattern = r'# Measure ([\w/+_\- ]+), ([\w/+_\- ]+), ([\w/+_\- ]+), ([\d\.]+), ([\w/+_\-^]+)'
106
+ datatypes = np .dtype ('U100,U100,U100,f8,U10' )
107
+ stats = np .fromregex (seg_stats_file , wb_regex_pattern , dtype = datatypes )
108
+ if set in ['eTIV' ]:
109
+ out_data = np .array ([seg [3 ] for seg in stats if seg [1 ] == 'eTIV' ])
110
+ else :
111
+ out_data = np .array ([seg [3 ] for seg in stats ])
112
+
113
+ return out_data
114
+
115
+
50
116
def _read_volume_info (fobj ):
51
117
"""Helper for reading the footer from a surface file."""
52
118
volume_info = OrderedDict ()
0 commit comments