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
10 """Infrastructure to parse variable definitions passed to cmsRun
11 configuration scripts"""
14 multiplicity = Enumerate (
"singleton list",
"multiplicity")
15 varType = Enumerate (
"bool int float string tagString")
16 commaRE = re.compile (
r',')
17 trueRE = re.compile (
r'^true$', re.IGNORECASE)
18 falseRE = re.compile (
r'^false$', re.IGNORECASE)
22 """Class initializer"""
43 VarParsing.multiplicity.singleton,
44 VarParsing.varType.string,
45 "Prepend location of files starting "
49 if lower ==
'analysis' or lower ==
'python':
53 VarParsing.multiplicity.singleton,
54 VarParsing.varType.int,
55 "Number of events to process (-1 for all)")
58 VarParsing.multiplicity.singleton,
59 VarParsing.varType.int,
60 "Total number of sections")
63 VarParsing.multiplicity.singleton,
64 VarParsing.varType.int,
65 "This section (from 1..totalSections inclusive)")
68 VarParsing.multiplicity.list,
69 VarParsing.varType.string,
71 self.
register (
'secondaryInputFiles',
73 VarParsing.multiplicity.list,
74 VarParsing.varType.string,
75 "Second group of files to process (if needed)")
78 VarParsing.multiplicity.singleton,
79 VarParsing.varType.string,
80 "String to prepend location of all files")
83 VarParsing.multiplicity.singleton,
84 VarParsing.varType.tagString,
85 "Name of output file (if needed)")
86 self.
register (
'secondaryOutputFile',
88 VarParsing.multiplicity.singleton,
89 VarParsing.varType.tagString,
90 "Name of second output file (if needed)")
93 VarParsing.multiplicity.singleton,
94 VarParsing.varType.string,
95 "tag to add to output filename")
97 ifCond =
'maxEvents > 0',
104 if lower ==
"standard":
108 VarParsing.multiplicity.singleton,
109 VarParsing.varType.int,
110 "Number of events to process (-1 for all)")
113 VarParsing.multiplicity.list,
114 VarParsing.varType.string,
118 VarParsing.multiplicity.list,
119 VarParsing.varType.string,
120 "Second group of files to process (if needed)")
123 VarParsing.multiplicity.singleton,
124 VarParsing.varType.tagString,
125 "Name of output file (if needed)")
128 VarParsing.multiplicity.singleton,
129 VarParsing.varType.tagString,
130 "Name of second output file (if needed)")
132 ifCond =
'maxEvents > 0',
133 tagArg =
'maxEvents')
136 print(
"Error: VarParsing.__init__ doesn't understand '%s'" \
138 raise RuntimeError(
"Failed to create VarParsing object")
142 """Sets up information for tags for output names"""
143 necessaryKeys = set ([
'ifCond',
'tag'])
144 allowedKeys = set ([
'tagArg'])
145 for key
in kwargs.keys():
146 if key
in allowedKeys:
148 if key
in necessaryKeys:
149 necessaryKeys.remove (key)
152 print(
"Unknown option '%s'" % key)
153 raise RuntimeError(
"Unknown option")
157 print(
"Missing keys: %s" % necessaryKeys)
158 raise runtimeError(
"Missing keys")
159 tag = kwargs.get(
'tag')
161 self.
_tags[tag] = kwargs
166 """Parses command line arguments. Parsing starts just after
167 the name of the configuration script. Parsing will fail if
168 there is not 'xxxx.py'"""
175 if not foundPy
and arg.endswith (
'.py'):
184 name, value = arg.split (
'=', 1)
187 name, command = name.split (
'_', 1)
188 command = command.lower()
189 if command ==
'load':
192 if command ==
'clear':
196 print(
"Unknown command '%s' in '%s_%s" % \
197 (command, name, command))
198 raise RuntimeError(
"Illegal parsing command")
202 print(
"Error: '%s' not registered." \
204 raise RuntimeError(
"Unknown variable")
205 if VarParsing.multiplicity.singleton == \
208 if self.
_beenSet.get (name)
and singleAssign:
209 print(
"Variable '%s' assigned multiple times. Use" \
210 ,
"'multipleAssign' command to avoid")
211 raise RuntimeError(
"Multiple assignment")
221 name, command = arg.split (
'_', 1)
222 command = command.lower()
224 print(
"Error: '%s' not registered." \
226 raise RuntimeError(
"Unknown variable")
227 if command ==
'clear':
232 print(
"Do not understand '%s' in '%s'" % (command, arg))
233 raise RuntimeError(
"Unknown command")
236 command = arg.lower()
237 if command ==
'help' or command ==
'--help':
239 elif command ==
'print' or command ==
'--print':
241 elif command ==
'noprint' or command ==
'--noprint':
245 print(
"Do not understand command '%s'" % (arg))
246 raise RuntimeError(
"Unknown command")
252 if 'totalSections' in self.
_register and \
255 self.totalSections
and self.section:
265 if 'storePrepend' in self.
_register and \
268 storeRE = re.compile (
r'^/store/')
271 if storeRE.match (filename):
272 filename = self.storePrepend + filename
273 newFileList.append (filename)
284 filename = self.filePrepend + filename
285 newFileList.append (filename)
292 print(
"VarParsing.parseArguments() Failure: No configuration " + \
293 "file found ending in .py.")
294 raise RuntimeError(
"Invalid configuration ending")
303 """Empties all entries from list"""
305 print(
"Error: '%s' not registered." \
307 raise RuntimeError(
"Unknown variable")
308 if self.
_register[name] != VarParsing.multiplicity.list:
309 print(
"Error: '%s' is not a list" % name)
310 raise RuntimeError(
"Faulty 'clear' command")
316 """Tells lists to not clear default list values when set from
319 print(
"Error: '%s' not registered." \
321 raise RuntimeError(
"Unknown variable")
322 if self.
_register[name] != VarParsing.multiplicity.list:
323 print(
"Error: '%s' is not a list" % name)
324 raise RuntimeError(
"Faulty 'setNoDefaultClear' command")
329 """Tells lists to not split up values by commas."""
331 print(
"Error: '%s' not registered." \
333 raise RuntimeError(
"Unknown variable")
334 if self.
_register[name] != VarParsing.multiplicity.list:
335 print(
"Error: '%s' is not a list" % name)
336 raise RuntimeError(
"Faulty 'setNoCommaSplit' command")
341 """Loads a list from file"""
343 print(
"Error: '%s' not registered." \
345 raise RuntimeError(
"Unknown variable")
346 if self.
_register[name] != VarParsing.multiplicity.list:
347 print(
"Error: '%s' is not a list" % name)
348 raise RuntimeError(
"'load' only works for lists")
349 filename = os.path.expanduser (filename)
350 if not os.path.exists (filename):
351 print(
"Error: '%s' file does not exist.")
352 raise RuntimeError(
"Bad filename")
353 source = open (filename,
'r')
354 for line
in source.readlines():
355 line = re.sub (
r'#.+$',
'', line)
363 """Prints out help information and exits"""
367 multipleAssign : Allows singletons to have multiple assigments
368 print : Prints out current values
369 XXX_clear : Clears list named 'XXX'
376 mult = multiplicity.singleton,
377 mytype = varType.int,
380 """Register a variable"""
382 if not VarParsing.multiplicity.isValidValue (mult):
383 print(
"Error: VarParsing.register() must use ",\
384 "VarParsing.multiplicity.")
385 raise RuntimeError(
"Improper 'mult' value")
386 if not VarParsing.varType.isValidValue (mytype):
387 print(
"Error: VarParsing.register() must use ",\
388 "VarParsing.varType.")
389 raise RuntimeError(
"Improper 'type' value %s" % mytype)
390 if VarParsing.multiplicity.list == mult
and \
391 VarParsing.varType.tagString == mytype:
392 print(
"Error: 'tagString' can only be used with 'singleton'")
393 raise RuntimeError(
"Improper registration")
396 print(
"Error: Name can not contain '_': %s" % name)
397 raise RuntimeError(
"Improper 'name'")
401 print(
"Error: You can not register a name twice, '%s'" \
403 raise RuntimeError(
"Attempt to re-register variable")
406 self.
_info[name] = info
407 self.
_types[name] = mytype
410 if VarParsing.multiplicity.singleton == mult:
417 self.
_lists[name].append (default)
423 if kwargs.get (
'noCommaSplit'):
425 del kwargs[
'noCommaSplit']
426 if kwargs.get (
'noDefaultClear'):
428 del kwargs[
'noDefaultClear']
430 raise RuntimeError(
"register() Unknown arguments %s" % kwargs)
434 """Returns true if a key is registered"""
439 """Change the type of 'name' to 'mytype'"""
440 if not VarParsing.varType.isValidValue (mytype):
441 print(
"Error: VarParsing.setType() must use ",\
442 "VarParsing.varType.")
443 raise RuntimeError(
"Improper 'type' value")
445 self.
_types[name] = mytype
450 """Used to set or change the default of an already registered
454 print(
"Error: VarParsing.setDefault '%s' not already registered." \
456 raise RuntimeError(
"setDefault without registration")
457 if VarParsing.multiplicity.singleton == self.
_register[name]:
460 print(
"Error: VarParsing.setDefault needs exactly 1 ",\
461 "value for '%s'" % name)
462 raise RuntimeError(
"setDefault args problem")
484 if isinstance (args, tuple)
and len (args) == 1:
487 if isinstance (args, tuple):
489 elif isinstance (args, list):
498 mylist.extend( VarParsing.commaRE.split( item ) )
504 """Converts inputVal to the type required by name"""
505 inputVal = str (inputVal)
506 if self.
_types[name] == VarParsing.varType.bool:
507 if VarParsing.trueRE.match (inputVal)
or '1' == inputVal:
509 elif VarParsing.falseRE.match (inputVal)
or '0' == inputVal:
512 raise RuntimeError(
"Unknown bool value '%s'. Must be 'true' or 'false'" % inputVal)
513 if self.
_types[name] == VarParsing.varType.string
or \
514 self.
_types[name] == VarParsing.varType.tagString:
516 elif self.
_types[name] == VarParsing.varType.int:
517 return int (inputVal, 0)
518 elif self.
_types[name] == VarParsing.varType.float:
519 return float (inputVal)
521 raise RuntimeError(
"Unknown varType")
526 print(
"Error: '%s' not registered." \
528 raise RuntimeError(
"Unknown variable")
529 if self.
_register[name] == VarParsing.multiplicity.list:
530 print(
"Error: '%s' is a list" % name)
531 raise RuntimeError(
"withTags() only works on singletons")
533 if retval.endswith (
'.root'):
534 retval, garbage = os.path.splitext (retval)
536 reverseOrder.reverse()
537 for tag
in reverseOrder:
538 tagDict = self.
_tags[tag]
539 ifCond = tagDict[
'ifCond']
540 if ifCond.count(
'%'):
543 ifCond =
"self." + ifCond
544 boolValue = eval (ifCond)
545 tagArg = tagDict.get (
'tagArg')
547 evalString =
"'%s' %% self.%s" % (tag, tagArg)
548 tag = eval (evalString)
550 retval = retval +
"_" + tag
551 return retval +
".root"
555 """String form of self"""
557 form =
" %%-%ds: %%s" % maxLen
558 formInfo =
" %%%ds - %%s" % (maxLen - 2)
559 formItem =
" %%%ds %%s" % (maxLen - 1)
562 retval = retval +
"Singletons:\n"
564 retval = retval + form % (varName, value) +
"\n";
565 if self.
_info.get(varName):
566 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n"
568 retval = retval +
"Lists:\n"
569 for varName, value
in sorted (self.
_lists.
items()):
570 stringValue =
"%s" % value
571 if len (stringValue) < 76 - maxLen:
572 retval = retval + form % (varName, value) +
"\n"
574 varLength = len (value)
575 for index, item
in enumerate (value):
577 retval = retval + form % (varName,
"['" + item)
579 retval = retval + formItem % (
'',
"'" + item)
580 if index == varLength - 1:
581 retval = retval +
"' ]\n"
583 retval = retval +
"',\n"
584 if self.
_info.get(varName):
585 retval = retval + formInfo % (
'', self.
_info[varName]) +
"\n"
590 """Lets me set internal values, or uses setDefault"""
591 if not name.startswith (
"_"):
592 mylist = list (extras)
593 mylist.insert (0, value)
596 object.__setattr__ (self, name, value)
600 """Lets user get the info they want with obj.name"""
601 if name.startswith (
"_"):
603 return object.__getattribute__ (self, name)
607 print(
"Error: '%s' not already registered." \
609 raise RuntimeError(
"Unknown variable")
610 if VarParsing.multiplicity.singleton == self.
_register[name]:
611 if VarParsing.varType.tagString == self.
_types[name] \
627 if __name__ ==
"__main__":
634 historyPath = os.path.expanduser(
"~/.pyhistory")
639 readline.write_history_file(historyPath)
640 if os.path.exists(historyPath):
641 readline.read_history_file(historyPath)
644 atexit.register(save_history)
645 readline.parse_and_bind(
"set show-all-if-ambiguous on")
646 readline.parse_and_bind(
"tab: complete")
647 if os.path.exists (historyPath) :
648 readline.read_history_file(historyPath)
649 readline.set_history_length(-1)
656 obj = VarParsing (
'standard')
657 obj.register (
'someVar',
658 mult=VarParsing.multiplicity.singleton,
660 obj.setupTags (tag =
"someCondition",