Package mvpa :: Package misc :: Module cmdline
[hide private]
[frames] | no frames]

Source Code for Module mvpa.misc.cmdline

  1  #emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  #ex: set sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  7  # 
  8  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  9  """Common functions and options definitions for command line 
 10   
 11  __docformat__ = 'restructuredtext' 
 12   
 13  Conventions: 
 14  Every option (instance of optparse.Option) has prefix "opt". Lists of options 
 15  has prefix opts (e.g. `opts.common`). 
 16   
 17  Option name should be camelbacked version of .dest for the option. 
 18  """ 
 19   
 20  import mvpa 
 21   
 22  # TODO? all options (opt*) might migrate to respective module? discuss 
 23  from optparse import OptionParser, Option, OptionGroup, OptionConflictError 
 24   
 25  # needed for verboseCallback 
 26  from mvpa.base import verbose, externals 
 27   
 28  # we need to make copies of the options if we place them into the 
 29  # groups, since otherwise it is impossible to use them without using 
 30  # the whole group. May be we should make some late creation of the 
 31  # groups -- ie only if user requests a group, options are added to it. 
 32  from mvpa.support import copy 
 33   
34 -class Options(object):
35 """Just a convinience placeholder for all available options 36 """ 37 pass
38
39 -class OptionGroups(object):
40 """Group creation is delayed until instance is requested. 41 42 This allows to overcome the problem of poluting handled cmdline options 43 """ 44
45 - def __init__(self, parser):
46 self._d = {} 47 self._parser = parser
48
49 - def add(self, name, l, doc):
50 self._d[name] = (doc, l)
51
52 - def _getGroup(self, name):
53 try: 54 doc, l = self._d[name] 55 except KeyError: 56 raise ValueError, "No group with name %s" % name 57 opts = OptionGroup(self._parser, doc) 58 #opts.add_options(copy.deepcopy(l)) # may be copy? 59 try: 60 opts.add_options(l) 61 except OptionConflictError: 62 print "Problem addition options to the group '%s'. Most probably" \ 63 " the option was independently added already." % name 64 raise 65 return opts
66
67 - def __getattribute__(self, index):
68 if index[0] == '_': 69 return object.__getattribute__(self, index) 70 if self._d.has_key(index): 71 return self._getGroup(index) 72 return object.__getattribute__(self, index)
73 74 75 # TODO: try to make groups definition somewhat lazy, since now 76 # whenever a group is created, those parameters are already known by 77 # parser, although might not be listed in the list of used and not by 78 # --help. But their specification on cmdline doesn't lead to 79 # error/help msg. 80 # 81 # Conflict hanlder to resolve situation that we have the same option added 82 # to some group and also available 'freely' 83 # 84 # set default version string, otherwise '--version' option is not enabled 85 # can be overwritten later on by assigning to `parser.version` 86 parser = OptionParser(version="%prog", 87 add_help_option=False, 88 conflict_handler="error") 89 90 91 opt = Options() 92 opts = OptionGroups(parser) 93 94 # 95 # Verbosity options 96 #
97 -def _verboseCallback(option, optstr, value, parser):
98 """Callback for -v|--verbose cmdline option 99 """ 100 verbose.level = value 101 optstr = optstr # pylint shut up 102 setattr(parser.values, option.dest, value)
103 104 opt.help = \ 105 Option("-h", "--help", "--sos", 106 action="help", 107 help="Show this help message and exit") 108 109 opt.verbose = \ 110 Option("-v", "--verbose", "--verbosity", 111 action="callback", callback=_verboseCallback, nargs=1, 112 type="int", dest="verbose", default=0, 113 help="Verbosity level of output") 114 """Pre-cooked `optparse`'s option to specify verbose level""" 115 116 commonopts_list = [opt.verbose, opt.help] 117 118 if __debug__: 119 from mvpa.base import debug 120
121 - def _debugCallback(option, optstr, value, parser):
122 """Callback for -d|--debug cmdline option 123 """ 124 if value == "list": 125 print "Registered debug IDs:" 126 keys = debug.registered.keys() 127 keys.sort() 128 for k in keys: 129 print "%-7s: %s" % (k, debug.registered[k]) 130 print "Use ALL: to enable all of the debug IDs listed above." 131 print "Use python regular expressions to select group. CLF.* will" \ 132 " enable all debug entries starting with CLF (e.g. CLFBIN, CLFMC)" 133 raise SystemExit, 0 134 135 optstr = optstr # pylint shut up 136 debug.setActiveFromString(value) 137 138 setattr(parser.values, option.dest, value)
139 140 141 optDebug = Option("-d", "--debug", 142 action="callback", callback=_debugCallback, 143 nargs=1, 144 type="string", dest="debug", default="", 145 help="Debug entries to report. " + 146 "Run with '-d list' to get a list of " + 147 "registered entries") 148 149 commonopts_list.append(optDebug) 150 151 opts.add("common", commonopts_list, "Common generic options") 152 153 # 154 # Classifiers options 155 # 156 opt.clf = \ 157 Option("--clf", 158 type="choice", dest="clf", 159 choices=['knn', 'svm', 'ridge', 'gpr', 'smlr'], default='svm', 160 help="Type of classifier to be used. Default: svm") 161 162 opt.radius = \ 163 Option("-r", "--radius", 164 action="store", type="float", dest="radius", 165 default=5.0, 166 help="Radius to be used (eg for the searchlight). Default: 5.0") 167 168 169 opt.knearestdegree = \ 170 Option("-k", "--k-nearest", 171 action="store", type="int", dest="knearestdegree", default=3, 172 help="Degree of k-nearest classifier. Default: 3") 173 174 opts.add('KNN', [opt.radius, opt.knearestdegree], "Specification of kNN") 175 176 177 opt.svm_C = \ 178 Option("-C", "--svm-C", 179 action="store", type="float", dest="svm_C", default=1.0, 180 help="C parameter for soft-margin C-SVM classification. " \ 181 "Default: 1.0") 182 183 opt.svm_nu = \ 184 Option("--nu", "--svm-nu", 185 action="store", type="float", dest="svm_nu", default=0.1, 186 help="nu parameter for soft-margin nu-SVM classification. " \ 187 "Default: 0.1") 188 189 opt.svm_gamma = \ 190 Option("--gamma", "--svm-gamma", 191 action="store", type="float", dest="svm_gamma", default=1.0, 192 help="gamma parameter for Gaussian kernel of RBF SVM. " \ 193 "Default: 1.0") 194 195 opts.add('SVM', [opt.svm_nu, opt.svm_C, opt.svm_gamma], "SVM specification") 196 197 opt.do_sweep = \ 198 Option("--sweep", 199 action="store_true", dest="do_sweep", 200 default=False, 201 help="Sweep through various classifiers") 202 203 # Crossvalidation options 204 205 opt.crossfolddegree = \ 206 Option("-c", "--crossfold", 207 action="store", type="int", dest="crossfolddegree", default=1, 208 help="Degree of N-fold crossfold. Default: 1") 209 210 opts.add('general', [opt.crossfolddegree], "Generalization estimates") 211 212 213 # preprocess options 214 215 opt.zscore = \ 216 Option("--zscore", 217 action="store_true", dest="zscore", default=0, 218 help="Enable zscoring of dataset samples. Default: Off") 219 220 opt.tr = \ 221 Option("--tr", 222 action="store", dest="tr", default=2.0, type='float', 223 help="fMRI volume repetition time. Default: 2.0") 224 225 opt.detrend = \ 226 Option("--detrend", 227 action="store_true", dest="detrend", default=0, 228 help="Do linear detrending. Default: Off") 229 230 opts.add('preproc', [opt.zscore, opt.tr, opt.detrend], "Preprocessing options") 231 232 233 # Wavelets options 234 if externals.exists('pywt'): 235 import pywt
236 - def _waveletFamilyCallback(option, optstr, value, parser):
237 """Callback for -w|--wavelet-family cmdline option 238 """ 239 wl_list = pywt.wavelist() 240 wl_list_str = ", ".join( 241 ['-1: None'] + ['%d:%s' % w for w in enumerate(wl_list)]) 242 if value == "list": 243 print "Available wavelet families: " + wl_list_str 244 raise SystemExit, 0 245 246 wl_family = value 247 try: 248 # may be int? ;-) 249 wl_family_index = int(value) 250 if wl_family_index >= 0: 251 try: 252 wl_family = wl_list[wl_family_index] 253 except IndexError: 254 print "Index is out of range. " + \ 255 "Following indexes with names are known: " + \ 256 wl_list_str 257 raise SystemExit, -1 258 else: 259 wl_family = 'None' 260 except ValueError: 261 pass 262 # Check the value 263 wl_family = wl_family.lower() 264 if wl_family == 'none': 265 wl_family = None 266 elif not wl_family in wl_list: 267 print "Uknown family '%s'. Known are %s" % (wl_family, ', '.join(wl_list)) 268 raise SystemExit, -1 269 # Store it in the parser 270 setattr(parser.values, option.dest, wl_family)
271 272 273 opt.wavelet_family = \ 274 Option("-w", "--wavelet-family", callback=_waveletFamilyCallback, 275 action="callback", type="string", dest="wavelet_family", 276 default='-1', 277 help="Wavelet family: string or index among the available. " + 278 "Run with '-w list' to see available families") 279 280 opt.wavelet_decomposition = \ 281 Option("-W", "--wavelet-decomposition", 282 action="store", type="choice", dest="wavelet_decomposition", 283 default='dwt', choices=['dwt', 'dwp'], 284 help="Wavelet decomposition: discrete wavelet transform "+ 285 "(dwt) or packet (dwp)") 286 287 opts.add('wavelet', [opt.wavelet_family, opt.wavelet_decomposition], 288 "Wavelets mappers") 289 290 291 # Box options 292 293 opt.boxlength = \ 294 Option("--boxlength", 295 action="store", dest="boxlength", default=1, type='int', 296 help="Length of the box in volumes (integer). Default: 1") 297 298 opt.boxoffset = \ 299 Option("--boxoffset", 300 action="store", dest="boxoffset", default=0, type='int', 301 help="Offset of the box from the event onset in volumes. Default: 0") 302 303 opts.add('box', [opt.boxlength, opt.boxoffset], "Box options") 304 305 306 # sample attributes 307 308 opt.chunk = \ 309 Option("--chunk", 310 action="store", dest="chunk", default='0', 311 help="Id of the data chunk. Default: 0") 312 313 opt.chunkLimits = \ 314 Option("--chunklimits", 315 action="store", dest="chunklimits", default=None, 316 help="Limit processing to a certain chunk of data given by start " \ 317 "and end volume number (including lower, excluding upper " \ 318 "limit). Numbering starts with zero.") 319 320 opts.add('chunk', [opt.chunk, opt.chunkLimits], "Chunk options AKA Sample attributes XXX") 321