6
6
import numpy as np
7
7
import getpass
8
8
import time
9
+ from os .path import exists as pexists , realpath
9
10
10
11
from collections import OrderedDict
11
12
from six .moves import xrange
@@ -47,29 +48,41 @@ def _fread3_many(fobj, n):
47
48
return (b1 << 16 ) + (b2 << 8 ) + b3
48
49
49
50
50
- def read_aseg_stats (seg_stats_file , set = 'subcortical' , volumes_only = False ):
51
+ def read_aseg_stats (seg_stats_file ,
52
+ set_wanted = 'subcortical' ,
53
+ volumes_only = False ):
51
54
"""
52
55
Returns the subcortical stats found in Freesurfer output: subid/stats/aseg.stats
53
56
54
57
Tries to match the outputs returned by Freesurfer's Matlab counter part: load_segstats.m
55
58
56
59
Parameters
57
60
----------
58
- filepath : str
61
+ seg_stats_file : str
59
62
Abs path to aseg.stats file.
60
63
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' ]
64
+ set_wanted : str
65
+ Which set of volumes to return, among ['subcortical', 'wholebrain', 'etiv_only' ].
66
+ Default: 'subcortical'.
67
+ The choice 'subcortical' returns the usual subortical segmentations.
68
+ The choice 'wholebrain' returns the volumes in aseg.stats coded as :
69
+ [ 'BrainSegVol', 'BrainSegVolNotVent', 'lhCortexVol', 'rhCortexVol', 'lhCorticalWhiteMatterVol',
70
+ 'rhCorticalWhiteMatterVol', 'SubCortGrayVol', 'TotalGrayVol', 'SupraTentorialVol',
71
+ 'SupraTentorialVolNotVent', 'MaskVol', 'BrainSegVol-to-eTIV', 'MaskVol-to-eTIV',
72
+ 'lhSurfaceHoles', 'rhSurfaceHoles', 'eTIV' ]
73
+ These are noted as 'Measure' in the commented section of stats/aseg.stats file.
74
+ The choice 'etiv_only' returns the value for eTIV (estimated total intra-cranial volume) only.
75
+
76
+ volumes_only : bool
77
+ Flag to indicate only the volumes are wanted.
78
+
79
+ Default: False, returning all info available, to closely match the outputs returned by Freesurfer's Matlab counter part:
80
+ https://github.com/freesurfer/freesurfer/blob/dev/matlab/load_segstats.m
70
81
71
82
Returns
72
83
-------
84
+ By default (volumes_only=False), three arrays are returned:
85
+
73
86
seg_name : numpy array of strings
74
87
Array of segmentation names
75
88
seg_index : numpy array
@@ -86,26 +99,32 @@ def read_aseg_stats(seg_stats_file, set ='subcortical', volumes_only = False):
86
99
6. max intensity over space
87
100
7. range intensity over space
88
101
102
+ When volumes_only=True, only one array is returned containing only volumes.
103
+
89
104
"""
90
105
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 ))
106
+ seg_stats_file = realpath (seg_stats_file )
107
+ if not pexists (seg_stats_file ):
108
+ raise IOError ('given path does not exist : {}' .format (seg_stats_file ))
109
+
110
+ acceptable_choices = ['subcortical' , 'wholebrain' , 'etiv_only' ]
111
+ set_wanted = set_wanted .lower ()
112
+ if set_wanted not in acceptable_choices :
113
+ raise ValueError ('Invalid choice. Choose one among: {}' .format (acceptable_choices ))
95
114
96
- if set in 'subcortical' :
115
+ if set_wanted in 'subcortical' :
97
116
stats = np .loadtxt (seg_stats_file , dtype = "i1,i1,i4,f4,S50,f4,f4,f4,f4,f4" )
98
117
if volumes_only :
99
118
out_data = np .array ([seg [3 ] for seg in stats ])
100
119
else :
101
120
# need to ensure both two types return data correspond in seg order
102
121
out_data = stats
103
122
104
- elif set in [ 'wholebrain' , 'eTIV ' ]:
123
+ elif set_wanted in ['wholebrain' , 'etiv_only ' ]:
105
124
wb_regex_pattern = r'# Measure ([\w/+_\- ]+), ([\w/+_\- ]+), ([\w/+_\- ]+), ([\d\.]+), ([\w/+_\-^]+)'
106
125
datatypes = np .dtype ('U100,U100,U100,f8,U10' )
107
126
stats = np .fromregex (seg_stats_file , wb_regex_pattern , dtype = datatypes )
108
- if set in ['eTIV ' ]:
127
+ if set_wanted in ['etiv_only ' ]:
109
128
out_data = np .array ([seg [3 ] for seg in stats if seg [1 ] == 'eTIV' ])
110
129
else :
111
130
out_data = np .array ([seg [3 ] for seg in stats ])
0 commit comments