1 from __future__
import print_function
5 from pprint
import pprint
6 from FWCore.Utilities.Enumerate
import Enumerate
7 from FWCore.Utilities.FileUtils
import sectionNofTotal
11 """Infrastructure to parse variable definitions passed to cmsRun
12 configuration scripts"""
15 multiplicity = Enumerate (
"singleton list",
"multiplicity")
16 varType = Enumerate (
"bool int float string tagString")
17 commaRE = re.compile (
r',')
18 trueRE = re.compile (
r'^true$', re.IGNORECASE)
19 falseRE = re.compile (
r'^false$', re.IGNORECASE)
23 """Class initializer"""
44 VarParsing.multiplicity.singleton,
45 VarParsing.varType.string,
46 "Prepend location of files starting "
50 if lower ==
'analysis' or lower ==
'python':
54 VarParsing.multiplicity.singleton,
55 VarParsing.varType.int,
56 "Number of events to process (-1 for all)")
59 VarParsing.multiplicity.singleton,
60 VarParsing.varType.int,
61 "Total number of sections")
64 VarParsing.multiplicity.singleton,
65 VarParsing.varType.int,
66 "This section (from 1..totalSections inclusive)")
69 VarParsing.multiplicity.list,
70 VarParsing.varType.string,
72 self.
register (
'secondaryInputFiles',
74 VarParsing.multiplicity.list,
75 VarParsing.varType.string,
76 "Second group of files to process (if needed)")
79 VarParsing.multiplicity.singleton,
80 VarParsing.varType.string,
81 "String to prepend location of all files")
84 VarParsing.multiplicity.singleton,
85 VarParsing.varType.tagString,
86 "Name of output file (if needed)")
87 self.
register (
'secondaryOutputFile',
89 VarParsing.multiplicity.singleton,
90 VarParsing.varType.tagString,
91 "Name of second output file (if needed)")
94 VarParsing.multiplicity.singleton,
95 VarParsing.varType.string,
96 "tag to add to output filename")
98 ifCond =
'maxEvents > 0',
105 if lower ==
"standard":
109 VarParsing.multiplicity.singleton,
110 VarParsing.varType.int,
111 "Number of events to process (-1 for all)")
114 VarParsing.multiplicity.list,
115 VarParsing.varType.string,
119 VarParsing.multiplicity.list,
120 VarParsing.varType.string,
121 "Second group of files to process (if needed)")
124 VarParsing.multiplicity.singleton,
125 VarParsing.varType.tagString,
126 "Name of output file (if needed)")
129 VarParsing.multiplicity.singleton,
130 VarParsing.varType.tagString,
131 "Name of second output file (if needed)")
133 ifCond =
'maxEvents > 0',
134 tagArg =
'maxEvents')
137 print(
"Error: VarParsing.__init__ doesn't understand '%s'" \
139 raise RuntimeError(
"Failed to create VarParsing object")
143 """Sets up information for tags for output names"""
144 necessaryKeys = set ([
'ifCond',
'tag'])
145 allowedKeys = set ([
'tagArg'])
146 for key
in kwargs.keys():
147 if key
in allowedKeys:
149 if key
in necessaryKeys:
150 necessaryKeys.remove (key)
153 print(
"Unknown option '%s'" % key)
154 raise RuntimeError(
"Unknown option")
158 print(
"Missing keys: %s" % necessaryKeys)
159 raise runtimeError(
"Missing keys")
160 tag = kwargs.get(
'tag')
162 self.
_tags[tag] = kwargs
167 """Parses command line arguments. Parsing starts just after
168 the name of the configuration script. Parsing will fail if
169 there is not 'xxxx.py'"""
176 if not foundPy
and arg.endswith (
'.py'):
185 name, value = arg.split (
'=', 1)
188 name, command = name.split (
'_', 1)
189 command = command.lower()
190 if command ==
'load':
193 if command ==
'clear':
197 print(
"Unknown command '%s' in '%s_%s" % \
198 (command, name, command))
199 raise RuntimeError(
"Illegal parsing command")
203 print(
"Error: '%s' not registered." \
205 raise RuntimeError(
"Unknown variable")
206 if VarParsing.multiplicity.singleton == \
209 if self.
_beenSet.get (name)
and singleAssign:
210 print(
"Variable '%s' assigned multiple times. Use" \
211 ,
"'multipleAssign' command to avoid")
212 raise RuntimeError(
"Multiple assignment")
222 name, command = arg.split (
'_', 1)
223 command = command.lower()
225 print(
"Error: '%s' not registered." \
227 raise RuntimeError(
"Unknown variable")
228 if command ==
'clear':
233 print(
"Do not understand '%s' in '%s'" % (command, arg))
234 raise RuntimeError(
"Unknown command")
237 command = arg.lower()
238 if command ==
'help' or command ==
'--help':
240 elif command ==
'print' or command ==
'--print':
242 elif command ==
'noprint' or command ==
'--noprint':
246 print(
"Do not understand command '%s'" % (arg))
247 raise RuntimeError(
"Unknown command")
253 if 'totalSections' in self.
_register and \
256 self.totalSections
and self.section:
266 if 'storePrepend' in self.
_register and \
269 storeRE = re.compile (
r'^/store/')
272 if storeRE.match (filename):
273 filename = self.storePrepend + filename
274 newFileList.append (filename)
285 filename = self.filePrepend + filename
286 newFileList.append (filename)
293 print(
"VarParsing.parseArguments() Failure: No configuration " + \
294 "file found ending in .py.")
295 raise RuntimeError(
"Invalid configuration ending")
304 """Empties all entries from list"""
306 print(
"Error: '%s' not registered." \
308 raise RuntimeError(
"Unknown variable")
309 if self.
_register[name] != VarParsing.multiplicity.list:
310 print(
"Error: '%s' is not a list" % name)
311 raise RuntimeError(
"Faulty 'clear' command")
317 """Tells lists to not clear default list values when set from
320 print(
"Error: '%s' not registered." \
322 raise RuntimeError(
"Unknown variable")
323 if self.
_register[name] != VarParsing.multiplicity.list:
324 print(
"Error: '%s' is not a list" % name)
325 raise RuntimeError(
"Faulty 'setNoDefaultClear' command")
330 """Tells lists to not split up values by commas."""
332 print(
"Error: '%s' not registered." \
334 raise RuntimeError(
"Unknown variable")
335 if self.
_register[name] != VarParsing.multiplicity.list:
336 print(
"Error: '%s' is not a list" % name)
337 raise RuntimeError(
"Faulty 'setNoCommaSplit' command")
342 """Loads a list from file"""
344 print(
"Error: '%s' not registered." \
346 raise RuntimeError(
"Unknown variable")
347 if self.
_register[name] != VarParsing.multiplicity.list:
348 print(
"Error: '%s' is not a list" % name)
349 raise RuntimeError(
"'load' only works for lists")
350 filename = os.path.expanduser (filename)
351 if not os.path.exists (filename):
352 print(
"Error: '%s' file does not exist.")
353 raise RuntimeError(
"Bad filename")
354 source = open (filename,
'r')
355 for line
in source.readlines():
356 line = re.sub (
r'#.+$',
'', line)
364 """Prints out help information and exits"""
368 multipleAssign : Allows singletons to have multiple assigments
369 print : Prints out current values
370 XXX_clear : Clears list named 'XXX'
377 mult = multiplicity.singleton,
378 mytype = varType.int,
381 """Register a variable"""
383 if not VarParsing.multiplicity.isValidValue (mult):
384 print(
"Error: VarParsing.register() must use ",\
385 "VarParsing.multiplicity.")
386 raise RuntimeError(
"Improper 'mult' value")
387 if not VarParsing.varType.isValidValue (mytype):
388 print(
"Error: VarParsing.register() must use ",\
389 "VarParsing.varType.")
390 raise RuntimeError(
"Improper 'type' value %s" % mytype)
391 if VarParsing.multiplicity.list == mult
and \
392 VarParsing.varType.tagString == mytype:
393 print(
"Error: 'tagString' can only be used with 'singleton'")
394 raise RuntimeError(
"Improper registration")
397 print(
"Error: Name can not contain '_': %s" % name)
398 raise RuntimeError(
"Improper 'name'")
402 print(
"Error: You can not register a name twice, '%s'" \
404 raise RuntimeError(
"Attempt to re-register variable")
407 self.
_info[name] = info
408 self.
_types[name] = mytype
411 if VarParsing.multiplicity.singleton == mult:
418 self.
_lists[name].append (default)
424 if kwargs.get (
'noCommaSplit'):
426 del kwargs[
'noCommaSplit']
427 if kwargs.get (
'noDefaultClear'):
429 del kwargs[
'noDefaultClear']
431 raise RuntimeError(
"register() Unknown arguments %s" % kwargs)
435 """Returns true if a key is registered"""
440 """Change the type of 'name' to 'mytype'"""
441 if not VarParsing.varType.isValidValue (mytype):
442 print(
"Error: VarParsing.setType() must use ",\
443 "VarParsing.varType.")
444 raise RuntimeError(
"Improper 'type' value")
446 self.
_types[name] = mytype
451 """Used to set or change the default of an already registered
455 print(
"Error: VarParsing.setDefault '%s' not already registered." \
457 raise RuntimeError(
"setDefault without registration")
458 if VarParsing.multiplicity.singleton == self.
_register[name]:
461 print(
"Error: VarParsing.setDefault needs exactly 1 ",\
462 "value for '%s'" % name)
463 raise RuntimeError(
"setDefault args problem")
485 if isinstance (args, tuple)
and len (args) == 1:
488 if isinstance (args, tuple):
490 elif isinstance (args, list):
499 mylist.extend( VarParsing.commaRE.split( item ) )
505 """Converts inputVal to the type required by name"""
506 inputVal = str (inputVal)
507 if self.
_types[name] == VarParsing.varType.bool:
508 if VarParsing.trueRE.match (inputVal)
or '1' == inputVal:
510 elif VarParsing.falseRE.match (inputVal)
or '0' == inputVal:
513 raise RuntimeError(
"Unknown bool value '%s'. Must be 'true' or 'false'" % inputVal)
514 if self.
_types[name] == VarParsing.varType.string
or \
515 self.
_types[name] == VarParsing.varType.tagString:
517 elif self.
_types[name] == VarParsing.varType.int:
518 return int (inputVal, 0)
519 elif self.
_types[name] == VarParsing.varType.float:
520 return float (inputVal)
522 raise RuntimeError(
"Unknown varType")
527 print(
"Error: '%s' not registered." \
529 raise RuntimeError(
"Unknown variable")
530 if self.
_register[name] == VarParsing.multiplicity.list:
531 print(
"Error: '%s' is a list" % name)
532 raise RuntimeError(
"withTags() only works on singletons")
534 if retval.endswith (
'.root'):
535 retval, garbage = os.path.splitext (retval)
537 reverseOrder.reverse()
538 for tag
in reverseOrder:
539 tagDict = self.
_tags[tag]
540 ifCond = tagDict[
'ifCond']
541 if ifCond.count(
'%'):
544 ifCond =
"self." + ifCond
545 boolValue = eval (ifCond)
546 tagArg = tagDict.get (
'tagArg')
548 evalString =
"'%s' %% self.%s" % (tag, tagArg)
549 tag = eval (evalString)
551 retval = retval +
"_" + tag
552 return retval +
".root"
556 """String form of self"""
558 form =
" %%-%ds: %%s" % maxLen
559 formInfo =
" %%%ds - %%s" % (maxLen - 2)
560 formItem =
" %%%ds %%s" % (maxLen - 1)
563 retval = retval +
"Singletons:\n"
564 for varName, value
in sorted (six.iteritems(self.
_singletons)):
565 retval = retval + form % (varName, value) +
"\n";
566 if self.
_info.get(varName):
567 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n"
569 retval = retval +
"Lists:\n"
570 for varName, value
in sorted (six.iteritems(self.
_lists)):
571 stringValue =
"%s" % value
572 if len (stringValue) < 76 - maxLen:
573 retval = retval + form % (varName, value) +
"\n"
575 varLength = len (value)
576 for index, item
in enumerate (value):
578 retval = retval + form % (varName,
"['" + item)
580 retval = retval + formItem % (
'',
"'" + item)
581 if index == varLength - 1:
582 retval = retval +
"' ]\n"
584 retval = retval +
"',\n"
585 if self.
_info.get(varName):
586 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n"
591 """Lets me set internal values, or uses setDefault"""
592 if not name.startswith (
"_"):
593 mylist = list (extras)
594 mylist.insert (0, value)
597 object.__setattr__ (self, name, value)
601 """Lets user get the info they want with obj.name"""
602 if name.startswith (
"_"):
604 return object.__getattribute__ (self, name)
608 print(
"Error: '%s' not already registered." \
610 raise RuntimeError(
"Unknown variable")
611 if VarParsing.multiplicity.singleton == self.
_register[name]:
612 if VarParsing.varType.tagString == self.
_types[name] \
628 if __name__ ==
"__main__":
635 historyPath = os.path.expanduser(
"~/.pyhistory")
640 readline.write_history_file(historyPath)
641 if os.path.exists(historyPath):
642 readline.read_history_file(historyPath)
645 atexit.register(save_history)
646 readline.parse_and_bind(
"set show-all-if-ambiguous on")
647 readline.parse_and_bind(
"tab: complete")
648 if os.path.exists (historyPath) :
649 readline.read_history_file(historyPath)
650 readline.set_history_length(-1)
657 obj = VarParsing (
'standard')
658 obj.register (
'someVar',
659 mult=VarParsing.multiplicity.singleton,
661 obj.setupTags (tag =
"someCondition",