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

Source Code for Module mvpa.misc.cmdline

  1  # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  # vi: set ft=python 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 if __debug__: 101 debug("CMDLINE", "Setting verbose.level to %s" % str(value)) 102 verbose.level = value 103 optstr = optstr # pylint shut up 104 setattr(parser.values, option.dest, value)
105 106 opt.help = \ 107 Option("-h", "--help", "--sos", 108 action="help", 109 help="Show this help message and exit") 110 111 opt.verbose = \ 112 Option("-v", "--verbose", "--verbosity", 113 action="callback", callback=_verboseCallback, nargs=1, 114 type="int", dest="verbose", default=0, 115 help="Verbosity level of output") 116 """Pre-cooked `optparse`'s option to specify verbose level""" 117 118 commonopts_list = [opt.verbose, opt.help] 119 120 if __debug__: 121 from mvpa.base import debug 122
123 - def _debugCallback(option, optstr, value, parser):
124 """Callback for -d|--debug cmdline option 125 """ 126 if value == "list": 127 print "Registered debug IDs:" 128 keys = debug.registered.keys() 129 keys.sort() 130 for k in keys: 131 print "%-7s: %s" % (k, debug.registered[k]) 132 print "Use ALL: to enable all of the debug IDs listed above." 133 print "Use python regular expressions to select group. CLF.* will" \ 134 " enable all debug entries starting with CLF (e.g. CLFBIN, CLFMC)" 135 raise SystemExit, 0 136 137 optstr = optstr # pylint shut up 138 debug.setActiveFromString(value) 139 140 setattr(parser.values, option.dest, value)
141 142 143 optDebug = Option("-d", "--debug", 144 action="callback", callback=_debugCallback, 145 nargs=1, 146 type="string", dest="debug", default="", 147 help="Debug entries to report. " + 148 "Run with '-d list' to get a list of " + 149 "registered entries") 150 151 commonopts_list.append(optDebug) 152 153 opts.add("common", commonopts_list, "Common generic options") 154 155 # 156 # Classifiers options 157 # 158 opt.clf = \ 159 Option("--clf", 160 type="choice", dest="clf", 161 choices=['knn', 'svm', 'ridge', 'gpr', 'smlr'], default='svm', 162 help="Type of classifier to be used. Default: svm") 163 164 opt.radius = \ 165 Option("-r", "--radius", 166 action="store", type="float", dest="radius", 167 default=5.0, 168 help="Radius to be used (eg for the searchlight). Default: 5.0") 169 170 171 opt.knearestdegree = \ 172 Option("-k", "--k-nearest", 173 action="store", type="int", dest="knearestdegree", default=3, 174 help="Degree of k-nearest classifier. Default: 3") 175 176 opts.add('KNN', [opt.radius, opt.knearestdegree], "Specification of kNN") 177 178 179 opt.svm_C = \ 180 Option("-C", "--svm-C", 181 action="store", type="float", dest="svm_C", default=1.0, 182 help="C parameter for soft-margin C-SVM classification. " \ 183 "Default: 1.0") 184 185 opt.svm_nu = \ 186 Option("--nu", "--svm-nu", 187 action="store", type="float", dest="svm_nu", default=0.1, 188 help="nu parameter for soft-margin nu-SVM classification. " \ 189 "Default: 0.1") 190 191 opt.svm_gamma = \ 192 Option("--gamma", "--svm-gamma", 193 action="store", type="float", dest="svm_gamma", default=1.0, 194 help="gamma parameter for Gaussian kernel of RBF SVM. " \ 195 "Default: 1.0") 196 197 opts.add('SVM', [opt.svm_nu, opt.svm_C, opt.svm_gamma], "SVM specification") 198 199 opt.do_sweep = \ 200 Option("--sweep", 201 action="store_true", dest="do_sweep", 202 default=False, 203 help="Sweep through various classifiers") 204 205 # Crossvalidation options 206 207 opt.crossfolddegree = \ 208 Option("-c", "--crossfold", 209 action="store", type="int", dest="crossfolddegree", default=1, 210 help="Degree of N-fold crossfold. Default: 1") 211 212 opts.add('general', [opt.crossfolddegree], "Generalization estimates") 213 214 215 # preprocess options 216 217 opt.zscore = \ 218 Option("--zscore", 219 action="store_true", dest="zscore", default=0, 220 help="Enable zscoring of dataset samples. Default: Off") 221 222 opt.tr = \ 223 Option("--tr", 224 action="store", dest="tr", default=2.0, type='float', 225 help="fMRI volume repetition time. Default: 2.0") 226 227 opt.detrend = \ 228 Option("--detrend", 229 action="store_true", dest="detrend", default=0, 230 help="Do linear detrending. Default: Off") 231 232 opts.add('preproc', [opt.zscore, opt.tr, opt.detrend], "Preprocessing options") 233 234 235 # Wavelets options 236 if externals.exists('pywt'): 237 import pywt
238 - def _waveletFamilyCallback(option, optstr, value, parser):
239 """Callback for -w|--wavelet-family cmdline option 240 """ 241 wl_list = pywt.wavelist() 242 wl_list_str = ", ".join( 243 ['-1: None'] + ['%d:%s' % w for w in enumerate(wl_list)]) 244 if value == "list": 245 print "Available wavelet families: " + wl_list_str 246 raise SystemExit, 0 247 248 wl_family = value 249 try: 250 # may be int? ;-) 251 wl_family_index = int(value) 252 if wl_family_index >= 0: 253 try: 254 wl_family = wl_list[wl_family_index] 255 except IndexError: 256 print "Index is out of range. " + \ 257 "Following indexes with names are known: " + \ 258 wl_list_str 259 raise SystemExit, -1 260 else: 261 wl_family = 'None' 262 except ValueError: 263 pass 264 # Check the value 265 wl_family = wl_family.lower() 266 if wl_family == 'none': 267 wl_family = None 268 elif not wl_family in wl_list: 269 print "Uknown family '%s'. Known are %s" % (wl_family, ', '.join(wl_list)) 270 raise SystemExit, -1 271 # Store it in the parser 272 setattr(parser.values, option.dest, wl_family)
273 274 275 opt.wavelet_family = \ 276 Option("-w", "--wavelet-family", callback=_waveletFamilyCallback, 277 action="callback", type="string", dest="wavelet_family", 278 default='-1', 279 help="Wavelet family: string or index among the available. " + 280 "Run with '-w list' to see available families") 281 282 opt.wavelet_decomposition = \ 283 Option("-W", "--wavelet-decomposition", 284 action="store", type="choice", dest="wavelet_decomposition", 285 default='dwt', choices=['dwt', 'dwp'], 286 help="Wavelet decomposition: discrete wavelet transform "+ 287 "(dwt) or packet (dwp)") 288 289 opts.add('wavelet', [opt.wavelet_family, opt.wavelet_decomposition], 290 "Wavelets mappers") 291 292 293 # Box options 294 295 opt.boxlength = \ 296 Option("--boxlength", 297 action="store", dest="boxlength", default=1, type='int', 298 help="Length of the box in volumes (integer). Default: 1") 299 300 opt.boxoffset = \ 301 Option("--boxoffset", 302 action="store", dest="boxoffset", default=0, type='int', 303 help="Offset of the box from the event onset in volumes. Default: 0") 304 305 opts.add('box', [opt.boxlength, opt.boxoffset], "Box options") 306 307 308 # sample attributes 309 310 opt.chunk = \ 311 Option("--chunk", 312 action="store", dest="chunk", default='0', 313 help="Id of the data chunk. Default: 0") 314 315 opt.chunkLimits = \ 316 Option("--chunklimits", 317 action="store", dest="chunklimits", default=None, 318 help="Limit processing to a certain chunk of data given by start " \ 319 "and end volume number (including lower, excluding upper " \ 320 "limit). Numbering starts with zero.") 321 322 opts.add('chunk', [opt.chunk, opt.chunkLimits], "Chunk options AKA Sample attributes XXX") 323