00001
00002 import FWCore.ParameterSet.parsecf.pyparsing as pp
00003 import FWCore.ParameterSet.Config as cms
00004 from FWCore.ParameterSet.DictTypes import SortedKeysDict
00005 from Mixins import PrintOptions
00006 import copy
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 _fileStack = ["{config}"]
00029
00030 def _validateLabelledList(params):
00031 """enforces the rule that no label can be used more than once
00032 and if an include is done more than once we remove the duplicates
00033 """
00034 l = params[:]
00035 l.sort( lambda x,y:cmp(x[0],y[0]))
00036 previous=None
00037 toRemove = []
00038 for item in l:
00039 if previous and item[0]==previous:
00040 if type(item[1]) == _IncludeNode:
00041 toRemove.append(item[0])
00042 elif hasattr(item[1],'multiplesAllowed') and item[1].multiplesAllowed:
00043 continue
00044 else:
00045 raise RuntimeError("multiple items found with label:"+item[0])
00046 previous = item[0]
00047 for remove in toRemove:
00048 for index,item in enumerate(params):
00049 if item[0] == remove:
00050 del params[index]
00051 break
00052 return params
00053
00054
00055 class _DictAdapter(object):
00056 def __init__(self,d, addSource=False):
00057 """Lets a dictionary be looked up by attributes"""
00058
00059
00060
00061 self.__dict__['d'] = d
00062 if addSource and self.d.has_key('source'):
00063 self.d[d['source'].type_()]=d['source']
00064 def __setattr__(self,name,value):
00065 self.d[name]=value
00066 def __getattr__(self,name):
00067
00068 return self.d[name]
00069
00070 class _DictCopyAdapter(object):
00071 def __init__(self,d):
00072
00073
00074
00075 self.d = d.copy()
00076 if self.d.has_key('source'):
00077 self.d[d['source'].type_()]=d['source']
00078 def __getattr__(self,name):
00079
00080 return self.d[name]
00081
00082
00083
00084 class _IncludeFile(file):
00085 def __init__(self,filename):
00086 """Searches for the 'filename' using the appropriate paths"""
00087 import os.path
00088 from os import environ
00089 try:
00090 paths = environ['CMSSW_SEARCH_PATH']
00091 except KeyError:
00092 raise RuntimeError("The environment variable 'CMSSW_SEARCH_PATH' must be set for include to work")
00093 lpaths = paths.split(':')
00094 lpaths.append('/afs/cern.ch/cms/sdt/misc/oldConfig/CMSSW')
00095 lpaths.append('.')
00096 f = None
00097 for path in lpaths:
00098 path +='/'+filename
00099 if os.path.exists(path):
00100 f=path
00101 break
00102 if f is None:
00103 raise RuntimeError("Unable to find file '"+filename+"' using the search path ${'CMSSW_SEARCH_PATH'} \n"
00104 +paths)
00105 super(_IncludeFile,self).__init__(path,'r')
00106 _fileFactory = _IncludeFile
00107
00108 def _findAndHandleParameterIncludes(values):
00109 return _findAndHandleParameterIncludesRecursive(values,set(),set())
00110 def _findAndHandleParameterIncludesRecursive(values,otherFiles,recurseFiles):
00111 newValues = []
00112 for l,v in values:
00113 if isinstance(v,_IncludeNode):
00114
00115 newValues.extend(v.extract(l, otherFiles,
00116 recurseFiles,
00117 onlyParameters.parseFile,
00118 _validateLabelledList,
00119 _findAndHandleParameterIncludesRecursive))
00120 else:
00121 newValues.append((l,v))
00122 return newValues
00123
00124 def _findAndHandleProcessBlockIncludes(values):
00125 return _findAndHandleProcessBlockIncludesRecursive(values,set(),set())
00126 def _findAndHandleProcessBlockIncludesRecursive(values,otherFiles,recurseFiles):
00127 newValues = []
00128 for l,v in values:
00129 if isinstance(v,_IncludeNode):
00130
00131 newValues.extend(v.extract(l, otherFiles,
00132 recurseFiles,
00133 onlyProcessBody.parseFile,
00134 _validateLabelledList,
00135 _findAndHandleProcessBlockIncludesRecursive))
00136 else:
00137 newValues.append((l,v))
00138 return newValues
00139
00140 def _handleInclude(fileName,otherFiles,recurseFiles,parser,validator,recursor):
00141 """reads in the file with name 'fileName' making sure it does not recursively include itself
00142 by looking in 'otherFiles' then applies the 'parser' to the contents of the file,
00143 runs the validator and then applies the recursor to see if other files must now be included"""
00144 global _fileStack
00145 if fileName in recurseFiles:
00146 raise RuntimeError('the file '+fileName+' eventually includes itself')
00147 if fileName in otherFiles:
00148 return list()
00149 newRecurseFiles = recurseFiles.copy()
00150 newRecurseFiles.add(fileName)
00151 otherFiles.add(fileName)
00152 _fileStack.append(fileName)
00153 try:
00154 factory = _fileFactory
00155 f = factory(fileName)
00156 try:
00157 values = parser(f)
00158 values = validator(values)
00159 values =recursor(values,otherFiles,newRecurseFiles)
00160 except pp.ParseException, e:
00161 raise RuntimeError('include file '+fileName+' had the parsing error \n'+str(e))
00162 except Exception, e:
00163 raise RuntimeError('include file '+fileName+' had the error \n'+str(e))
00164 try:
00165 values = validator(values)
00166 except Exception, e:
00167 raise RuntimeError('after including all other files, include file '+fileName+' had the error \n'+str(e))
00168 return values
00169 finally:
00170 _fileStack.pop()
00171
00172 def _handleUsing(using,otherUsings,process,allUsingLabels):
00173 """recursively go through the using blocks and return all the contained valued"""
00174 if using.value() in otherUsings:
00175 raise pp.ParseFatalException(using.s,using.loc,
00176 "the using.labelled '"+using.value()+"' recursively uses itself"+
00177 "\n from file "+using.file)
00178 allUsingLabels.add(using.value())
00179 values = []
00180 valuesFromOtherUsings=[]
00181 otherUsings = otherUsings.copy()
00182 otherUsings.add(using.value())
00183 if using.value() not in process:
00184 raise pp.ParseFatalException(using.s,using.loc,
00185 "the using.labelled '"+using.value()+"' does not correspond to a known block or PSet"
00186 +"\n from file "+using.file)
00187 d = process[using.value()].__dict__
00188 usingLabels=[]
00189 for label,param in (x for x in d.iteritems() if isinstance(x[1],cms._ParameterTypeBase)):
00190 if isinstance(param,cms.UsingBlock):
00191 newValues=_handleUsing(param,otherUsings,process,allUsingLabels)
00192 valuesFromOtherUsings.extend( newValues)
00193 values.extend(newValues)
00194 usingLabels.append(label)
00195 else:
00196 values.append((label,copy.deepcopy(param)))
00197 for label in usingLabels:
00198
00199 delattr(process[using.value()],label)
00200 for plabel,param in valuesFromOtherUsings:
00201 item = process[using.value()]
00202 if hasattr(item,plabel):
00203 raise pp.ParseFatalException(using.s,using.loc,
00204 "the using labelled '"+using.value()+"' tried to add the label '"+
00205 plabel+"' which already exists in this block"
00206 +"\n from file "+using.file)
00207 setattr(item,plabel,param)
00208 return values
00209
00210 def _findAndHandleUsingBlocksRecursive(label,item,process,allUsingLabels):
00211 otherUsings = set( (label,))
00212 values = []
00213 usingLabels = []
00214 usingForValues = []
00215 for tempLabel,param in item.__dict__.iteritems():
00216 if isinstance(param,cms.UsingBlock):
00217 oldSize = len(values)
00218 values.extend(_handleUsing(param,otherUsings,process,allUsingLabels))
00219 usingLabels.append(tempLabel)
00220 usingForValues.extend([param]*(len(values)-oldSize))
00221 elif isinstance(param,cms._Parameterizable):
00222 _findAndHandleUsingBlocksRecursive(tempLabel,param,process,allUsingLabels)
00223 elif isinstance(param,cms.VPSet):
00224 for pset in param:
00225 _findAndHandleUsingBlocksRecursive(tempLabel,pset,process,allUsingLabels)
00226 for tempLabel in usingLabels:
00227 delattr(item,tempLabel)
00228 for index,(plabel,param) in enumerate(values):
00229 if hasattr(item,plabel):
00230 using = usingForValues[index]
00231 raise pp.ParseFatalException(using.s,using.loc,
00232 "the using labelled '"+using.value()+"' tried to add the label '"+
00233 plabel+"' which already exists in this block"
00234 +"\n from file "+using.file)
00235 setattr(item,plabel,param)
00236
00237 def _findAndHandleProcessUsingBlock(values):
00238 d=dict(values)
00239 allUsingLabels = set()
00240 for label,item in d.iteritems():
00241 if isinstance(item,cms._Parameterizable):
00242 _findAndHandleUsingBlocksRecursive(label,item,d,allUsingLabels)
00243 elif isinstance(item,cms.VPSet):
00244 for pset in item:
00245 _findAndHandleUsingBlocksRecursive(label,pset,d,allUsingLabels)
00246 return allUsingLabels
00247
00248 def _flagUsingBlocks(values):
00249 """Only flags whether they're resolvable or not"""
00250 d=dict(values)
00251 for label,item in d.iteritems():
00252 if isinstance(item,cms._Parameterizable):
00253 _flagUsingBlocksRecursive(item,d)
00254 elif isinstance(item,cms.VPSet):
00255 for pset in item:
00256 _flagUsingBlocksRecursive(pset,d)
00257
00258 def _flagUsingBlocksRecursive(item, d):
00259 for label,param in item.__dict__.iteritems():
00260 if isinstance(param,cms.UsingBlock):
00261 if item.label in d.keys():
00262 item.isResolved = True
00263 elif isinstance(param,cms._Parameterizable):
00264 _flagUsingBlocksRecursive(label,param,process)
00265 elif isinstance(param,cms.VPSet):
00266 for pset in param:
00267 _flagUsingBlocksRecursive(label,pset,process)
00268
00269
00270 def _badLabel(s,loc,expr,err):
00271 """a mal formed label was detected"""
00272 raise pp.ParseFatalException(s,loc,"inappropriate label name")
00273
00274 def _makeParameter(s,loc,toks):
00275 """create the appropriate parameter object from the tokens"""
00276 tracked = True
00277 if len(toks[0])==4:
00278 tracked = False
00279 del toks[0][0]
00280 if not hasattr(cms,toks[0][0]):
00281 raise pp.ParseFatalException(s,loc,'unknown parameter type '+toks[0][0])
00282 ptype = getattr(cms,toks[0][0])
00283 try:
00284 p = ptype._valueFromString(toks[0][2])
00285 except Exception,e:
00286 raise pp.ParseFatalException(s,loc,
00287 "failed to parse parameter '"+toks[0][1]+"' because of error\n"+str(e))
00288 if not tracked:
00289 cms.untracked(p)
00290 return (toks[0][1],p)
00291
00292 def _makeLabeledInputTag(s,loc,toks):
00293 """create an InputTag parameter from the tokens"""
00294 tracked = True
00295 if len(toks[0])==4:
00296 tracked = False
00297 del toks[0][0]
00298 if isinstance(toks[0][2], str):
00299 p = cms.InputTag(toks[0][2])
00300 else:
00301 values = list(iter(toks[0][2]))
00302 if len(values) == 1:
00303 values +=''
00304 p = cms.InputTag(*values)
00305 if not tracked:
00306 cms.untracked(p)
00307 return (toks[0][1],p)
00308
00309 def _makeLabeledVInputTag(s,loc,toks):
00310 """create an VInputTag parameter from the tokens"""
00311 tracked = True
00312 if len(toks[0])==4:
00313 tracked = False
00314 del toks[0][0]
00315
00316 values = list(iter(toks[0][2]))
00317 items = []
00318 for x in values:
00319 if isinstance(x, str):
00320 items.append(cms.InputTag(x))
00321 else:
00322 items.append(cms.InputTag(*x))
00323
00324 p = cms.VInputTag(*items)
00325 if not tracked:
00326 cms.untracked(p)
00327 return (toks[0][1],p)
00328
00329 def _makeLabeledEventID(s,loc,toks):
00330 """create an EventID parameter from the tokens"""
00331 tracked = True
00332 if len(toks[0])==4:
00333 tracked = False
00334 del toks[0][0]
00335 p = cms.EventID(int(toks[0][2][0]), int(toks[0][2][1]))
00336 if not tracked:
00337 cms.untracked(p)
00338 return (toks[0][1],p)
00339
00340 def _makeLabeledVEventID(s,loc,toks):
00341 """create an VEventID parameter from the tokens"""
00342 tracked = True
00343 if len(toks[0])==4:
00344 tracked = False
00345 del toks[0][0]
00346 values = list(iter(toks[0][2]))
00347 items = [cms.EventID(*x) for x in values]
00348 p = cms.VEventID(*items)
00349 if not tracked:
00350 cms.untracked(p)
00351 return (toks[0][1],p)
00352
00353 def _makeLabeledLuminosityBlockID(s,loc,toks):
00354 """create an EventID parameter from the tokens"""
00355 tracked = True
00356 if len(toks[0])==4:
00357 tracked = False
00358 del toks[0][0]
00359 p = cms.LuminosityBlockID(int(toks[0][2][0]), int(toks[0][2][1]))
00360 if not tracked:
00361 cms.untracked(p)
00362 return (toks[0][1],p)
00363
00364
00365 def _makeDictFromList(values):
00366 values = _validateLabelledList(values)
00367 values = _findAndHandleParameterIncludes(values)
00368 values = _validateLabelledList(values)
00369 return dict(values)
00370
00371 def _makePSetFromList(values):
00372 d = _makeDictFromList(values)
00373 p = cms.PSet(*[],**d)
00374 return p
00375
00376 def _makePSet(s,loc,toks):
00377 """create a PSet from the tokens"""
00378 values = list(iter(toks[0]))
00379 try:
00380 return _makePSetFromList(values)
00381 except Exception, e:
00382 raise pp.ParseFatalException(s,loc,"PSet contains the error \n"+str(e))
00383
00384
00385 def _makeLabeledPSet(s,loc,toks):
00386 """create an PSet parameter from the tokens"""
00387 tracked = True
00388 if len(toks[0])==4:
00389 tracked = False
00390 del toks[0][0]
00391 p=_makePSet(s,loc,[toks[0][2]])
00392 if not tracked:
00393 cms.untracked(p)
00394 return (toks[0][1],p)
00395
00396 class _ObjectHolder(object):
00397 """If I return a VPSet directly to the parser it appears to 'eat it'"""
00398 def __init__(self,hold):
00399 self.hold = hold
00400
00401 def _makeVPSetFromList(values):
00402 items = [_makePSetFromList(x) for x in values]
00403 p = cms.VPSet(*items)
00404 return p
00405 def _makeVPSet(s,loc,toks):
00406 """create an VPSet from the tokens"""
00407 values = list(iter(toks[0]))
00408 try:
00409 p = _makeVPSetFromList(values)
00410 return _ObjectHolder(p)
00411 except Exception, e:
00412 raise pp.ParseFatalException(s,loc,"VPSet contains the error \n"+str(e))
00413
00414 def _makeLabeledVPSet(s,loc,toks):
00415 """create an VPSet parameter from the tokens"""
00416 tracked = True
00417 if len(toks[0])==4:
00418 tracked = False
00419 del toks[0][0]
00420 p = _makeVPSet(s,loc,(toks[0][2],)).hold
00421 if not tracked:
00422 cms.untracked(p)
00423 return (toks[0][1],p)
00424
00425 def _makeLabeledSecSource(s,loc,toks):
00426 tracked = True
00427 if len(toks[0])==4:
00428 tracked = False
00429 del toks[0][0]
00430 ss=toks[0][2]
00431 if not tracked:
00432 cms.untracked(ss)
00433 return (toks[0][1],ss)
00434
00435
00436
00437
00438 _allUsingLabels = set()
00439 def _makeUsing(s,loc,toks):
00440 global _allUsingLabels
00441 _allUsingLabels.add(toks[0][1])
00442
00443
00444
00445
00446 options = PrintOptions()
00447 return ('using_'+toks[0][1],cms.UsingBlock(toks[0][1], s, loc, _fileStack[-1]))
00448
00449 class _IncludeNode(cms._ParameterTypeBase):
00450 """For injection purposes, pretend this is a new parameter type
00451 then have a post process step which strips these out
00452 """
00453 def __init__(self,filename):
00454 self.filename = filename
00455 def parse(self, parser, validator):
00456 """Only the top-level nodes. No recursion"""
00457 global _fileStack
00458 _fileStack.append(self.filename)
00459 try:
00460
00461
00462 f = _fileFactory(self.filename)
00463 try:
00464 values = parser(f)
00465 values = validator(values)
00466 except pp.ParseException, e:
00467 raise RuntimeError('include file '+self.filename+' had the parsing error \n'+str(e))
00468 except Exception, e:
00469 raise RuntimeError('include file '+self.filename+' had the error \n'+str(e))
00470 return values
00471 finally:
00472 _fileStack.pop()
00473
00474
00475
00476 def extract(self, label, otherFiles,recurseFiles,parser,validator,recursor):
00477 """reads in the file with name 'fileName' making sure it does not recursively include itself
00478 by looking in 'otherFiles' then applies the 'parser' to the contents of the file,
00479 runs the validator and then applies the recursor to see if other files must now be included"""
00480 fileName = self.filename
00481 if fileName in recurseFiles:
00482 raise RuntimeError('the file '+fileName+' eventually includes itself')
00483 if fileName in otherFiles:
00484 return list()
00485 newRecurseFiles = recurseFiles.copy()
00486 newRecurseFiles.add(fileName)
00487 otherFiles.add(fileName)
00488 values = self.parse(parser, validator)
00489 values =recursor(values,otherFiles,newRecurseFiles)
00490 try:
00491 values = validator(values)
00492 except pp.ParseException, e:
00493 raise RuntimeError('after including all other files,include file '+fileName+' had the parsing error \n'+str(e))
00494 except Exception, e:
00495 raise RuntimeError('after including all other files, include file '+fileName+' had the error \n'+str(e))
00496 return values
00497
00498 def pythonFileRoot(self):
00499
00500 return self.filename.replace('.','_').replace('-','_')
00501 def pythonFileName(self):
00502 return self.pythonFileRoot().replace('/data/','/python/').replace('/test/','/python/test/')+".py"
00503 def pythonModuleName(self):
00504
00505 return self.pythonFileRoot().replace('/','.').replace('.data.','.')
00506 def dumpPython(self, options):
00507 if options.isCfg:
00508
00509 return "process.load(\"" + self.pythonModuleName() + "\")\n"
00510 else:
00511 return "from "+self.pythonModuleName()+" import *"
00512 def createFile(self, overwrite):
00513 import os
00514 import os.path
00515 pythonName = self.pythonFileName()
00516 cmsswSrc = os.path.expandvars("$CMSSW_BASE/src/")
00517 cmsswReleaseSrc = os.path.expandvars("$CMSSW_RELEASE_BASE/src/")
00518 if overwrite or (not os.path.exists(cmsswSrc+pythonName) and \
00519 not os.path.exists(cmsswReleaseSrc+pythonName)):
00520
00521 cwd = os.getcwd()
00522 os.chdir(cmsswSrc)
00523 pythonDir = os.path.dirname(pythonName)
00524
00525 if overwrite and os.path.exists(pythonName):
00526 os.remove(pythonName)
00527 if not os.path.exists(pythonName):
00528
00529 if not os.path.exists(pythonDir):
00530
00531 os.makedirs(pythonDir)
00532
00533 f=open(pythonName, 'w')
00534 f.write(dumpCff(self.filename))
00535 f.close()
00536 os.chdir(pythonDir)
00537 os.chdir(cwd)
00538
00539
00540 class _IncludeFromNode(_IncludeNode):
00541 """An IncludeNode with a label, so it will only
00542 extract the named node, plus any IncludeNodes,
00543 which are presumed to be blocks"""
00544 def __init__(self,fromLabel, filename):
00545 super(_IncludeFromNode,self).__init__(filename)
00546 self._fromLabel = fromLabel
00547 def extract(self, newLabel, otherFiles,recurseFiles,parser,validator,recursor):
00548 import copy
00549
00550
00551 wasHere = (self.filename in otherFiles)
00552 if wasHere:
00553 otherFiles.remove(self.filename)
00554 expandedValues = _IncludeNode.extract(self, newLabel, otherFiles,recurseFiles,parser,validator,recursor)
00555
00556 if not wasHere:
00557 otherFiles.remove(self.filename)
00558 found = False
00559 for l,v in expandedValues:
00560 if l == self._fromLabel:
00561 found = True
00562
00563
00564 expandedValues.remove((l,v))
00565 expandedValues.append((newLabel, copy.deepcopy(v)))
00566 if not found:
00567 raise RuntimeError("the file "+self.filename+" does not contain a "+self._fromLabel
00568 +"\n from file "+_fileStack[-1])
00569 return expandedValues
00570 def dumpPythonAs(self, newLabel, options):
00571 result = "import "+self.pythonModuleName() +"\n"
00572 result += newLabel + " = "
00573 result += self.pythonModuleName() + '.' + self._fromLabel+".clone()\n"
00574 return result
00575
00576
00577 def _makeInclude(s,loc,toks):
00578 return (toks[0][0],_IncludeNode(toks[0][0]))
00579
00580 letterstart = pp.Word(pp.alphas,pp.srange("[a-zA-Z0-9\-_]"))
00581
00582
00583
00584
00585
00586
00587
00588
00589 parameterValue = pp.Word(pp.alphanums+'.'+':'+'-'+'+')
00590 simpleParameterType = pp.Keyword("bool")|pp.Keyword("int32")|pp.Keyword("uint32")|pp.Keyword("int64")|pp.Keyword("uint64")|pp.Keyword("double")
00591 vSimpleParameterType = pp.Keyword("vint32")^pp.Keyword("vuint32")^pp.Keyword("vint64")^pp.Keyword("vuint64")^pp.Keyword("vdouble")
00592 any = parameterValue | letterstart
00593
00594 _scopeBegin = pp.Suppress('{')
00595 _scopeEnd = pp.Suppress('}')
00596 label = letterstart.copy()
00597 label.setFailAction(_badLabel)
00598 untracked = pp.Optional('untracked')
00599
00600 _equalTo = pp.Suppress('=').setFailAction(_badLabel)
00601
00602 simpleParameter = pp.Group(untracked+simpleParameterType+label
00603 +_equalTo+any).setParseAction(_makeParameter)
00604 vsimpleParameter = pp.Group(untracked+vSimpleParameterType+label+_equalTo
00605 +_scopeBegin
00606 +pp.Group(pp.Optional(pp.delimitedList(any)))
00607 +_scopeEnd
00608 ).setParseAction(_makeParameter)
00609
00610 def _handleString(s,loc,toks):
00611
00612 return eval(toks[0])
00613 quotedString = pp.quotedString.copy().setParseAction(_handleString)
00614
00615 stringParameter = pp.Group(untracked+pp.Keyword('string')+label+_equalTo+
00616 quotedString).setParseAction(_makeParameter)
00617 vstringParameter =pp.Group(untracked+pp.Keyword("vstring")+label+_equalTo
00618 +_scopeBegin
00619 +pp.Group(pp.Optional(pp.delimitedList(quotedString)))
00620 +_scopeEnd
00621 ).setParseAction(_makeParameter)
00622
00623 fileInPathParameter = pp.Group(untracked+pp.Keyword('FileInPath')+label+_equalTo+
00624 quotedString).setParseAction(_makeParameter)
00625
00626 inputTagFormat = pp.Group(letterstart+pp.Optional(pp.Suppress(':')+pp.Optional(pp.NotAny(pp.White())+pp.Word(pp.alphanums),"")+
00627 pp.Optional(pp.Suppress(':')+pp.Optional(pp.NotAny(pp.White())+pp.Word(pp.alphanums)))))
00628 anyInputTag = inputTagFormat|quotedString
00629
00630
00631
00632
00633 inputTagParameter = pp.Group(untracked+pp.Keyword('InputTag')+label+_equalTo+
00634 anyInputTag
00635 ).setParseAction(_makeLabeledInputTag)
00636
00637
00638 vinputTagParameter =pp.Group(untracked+pp.Keyword("VInputTag")+label+_equalTo
00639 +_scopeBegin
00640 +pp.Group(pp.Optional(pp.delimitedList(anyInputTag)))
00641 +_scopeEnd
00642 ).setParseAction(_makeLabeledVInputTag)
00643
00644 eventIDParameter = pp.Group(untracked+pp.Keyword("EventID")+label+_equalTo
00645 + pp.Group( pp.Word(pp.nums) + pp.Suppress(':') + pp.Word(pp.nums) )
00646 ).setParseAction(_makeLabeledEventID)
00647
00648 luminosityBlockIDParameter = pp.Group(untracked+pp.Keyword("LuminosityBlockID")+label+_equalTo
00649 + pp.Group( pp.Word(pp.nums) + pp.Suppress(':') + pp.Word(pp.nums) )
00650 ).setParseAction(_makeLabeledLuminosityBlockID)
00651
00652
00653 PSetParameter = pp.Forward()
00654 VPSetParameter = pp.Forward()
00655 secsourceParameter = pp.Forward()
00656 block = pp.Forward()
00657
00658 def _makeLabeledBlock(s,loc,toks):
00659 """create a PSet parameter from the tokens"""
00660 p=_makePSet(s,loc,[toks[0][2]])
00661
00662
00663 return (toks[0][1],p)
00664
00665 using = pp.Group(pp.Keyword("using")+letterstart).setParseAction(_makeUsing)
00666 include = pp.Group(pp.Keyword("include").suppress()+quotedString).setParseAction(_makeInclude)
00667
00668
00669 parameter = simpleParameter|stringParameter|vsimpleParameter|fileInPathParameter|vstringParameter|inputTagParameter|vinputTagParameter|eventIDParameter|luminosityBlockIDParameter|PSetParameter|VPSetParameter|secsourceParameter|block|include
00670
00671 scopedParameters = _scopeBegin+pp.Group(pp.ZeroOrMore(parameter|using|include))+_scopeEnd
00672
00673 block << pp.Group(untracked+pp.Keyword("block")+label+_equalTo+scopedParameters
00674 ).setParseAction(_makeLabeledBlock)
00675
00676 PSetParameter << pp.Group(untracked+pp.Keyword("PSet")+label+_equalTo+scopedParameters
00677 ).setParseAction(_makeLabeledPSet)
00678 VPSetParameter << pp.Group(untracked+pp.Keyword("VPSet")+label+_equalTo
00679 +_scopeBegin
00680 +pp.Group(pp.Optional(pp.delimitedList(scopedParameters)))
00681 +_scopeEnd
00682 ).setParseAction(_makeLabeledVPSet)
00683
00684 parameters = pp.OneOrMore(parameter)
00685 parameters.ignore(pp.cppStyleComment)
00686 parameters.ignore(pp.pythonStyleComment)
00687
00688
00689
00690
00691
00692
00693 class _MakePlugin(object):
00694 def __init__(self,plugin):
00695 self.__plugin = plugin
00696 def __call__(self,s,loc,toks):
00697 global _fileStack
00698 type = toks[0][0]
00699 values = list(iter(toks[0][1]))
00700 try:
00701 values = _validateLabelledList(values)
00702 values = _findAndHandleParameterIncludes(values)
00703 values = _validateLabelledList(values)
00704 except Exception, e:
00705 raise pp.ParseFatalException(s,loc,type+" contains the error "+str(e)
00706 +"\n from file "+_fileStack[-1])
00707 d = dict(values)
00708 return self.__plugin(*[type],**d)
00709 class _MakeFrom(object):
00710 def __init__(self,plugin):
00711 self.__plugin = plugin
00712 def __call__(self,s,loc,toks):
00713 global _fileStack
00714 label = toks[0][0]
00715 inc = toks[0][1]
00716 return _IncludeFromNode(label, inc[0])
00717
00718 def _replaceKeywordWithType(s,loc,toks):
00719 type = toks[0][1].type_()
00720 return (type,toks[0][1])
00721
00722 def _MakeESPrefer(s, loc, toks):
00723 value = None
00724 label = 'es_prefer_'+toks[0][1]
00725 if len(toks[0]) == 4:
00726
00727 value = cms.ESPrefer(toks[0][2], toks[0][1])
00728 elif len(toks[0])==3:
00729 value = cms.ESPrefer(toks[0][1])
00730 else:
00731 print "Strange parse of es_prefer "+str(toks)
00732 return (label,value)
00733
00734
00735 typeWithParameters = pp.Group(letterstart+scopedParameters)
00736
00737
00738 secsourceParameter << pp.Group(untracked+pp.Keyword("secsource")+label+_equalTo
00739 +typeWithParameters.copy().setParseAction(_MakePlugin(cms.SecSource))
00740 ).setParseAction(_makeLabeledSecSource)
00741
00742 source = pp.Group(pp.Keyword("source")+_equalTo
00743 +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Source))
00744 )
00745 looper = pp.Group(pp.Keyword("looper")+_equalTo
00746 +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Looper))
00747 )
00748
00749 service = pp.Group(pp.Keyword("service")+_equalTo
00750 +typeWithParameters.copy().setParseAction(_MakePlugin(cms.Service))
00751 ).setParseAction(_replaceKeywordWithType)
00752
00753 es_prefer = pp.Group(pp.Keyword("es_prefer")+pp.Optional(letterstart)+_equalTo+label+scopedParameters).setParseAction(_MakeESPrefer)
00754
00755
00756
00757
00758 module = pp.Group(pp.Suppress(pp.Keyword("module"))+label+_equalTo
00759 +typeWithParameters.copy().setParseAction(_MakePlugin(cms.EDFilter))|
00760 pp.Suppress(pp.Keyword("module"))+label+_equalTo
00761 +pp.Group(label+pp.Group(pp.Keyword("from").suppress()+quotedString).setParseAction(_makeInclude)).setParseAction(_MakeFrom(cms.EDFilter)))
00762
00763 def _guessTypeFromClassName(regexp,type):
00764 return pp.Group(pp.Suppress(pp.Keyword('module'))+label+_equalTo
00765 +pp.Group(pp.Regex(regexp)
00766 +scopedParameters
00767 ).setParseAction(_MakePlugin(type))
00768 )
00769 outputModuleGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*OutputModule",cms.OutputModule)
00770 producerGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*Prod(?:ucer)?",cms.EDProducer)
00771 analyzerGuess = _guessTypeFromClassName(r"[a-zA-Z]\w*Analyzer",cms.EDAnalyzer)
00772
00773 def _labelOptional(alabel,type,appendToLabel=''):
00774 def useTypeIfNoLabel(s,loc,toks):
00775 if len(toks[0])==2:
00776 alabel = toks[0][0]
00777 del toks[0][0]
00778 else:
00779 alabel = toks[0][0].type_()
00780 alabel +=appendToLabel
00781 return (alabel,toks[0][0])
00782
00783 return pp.Group(pp.Suppress(pp.Keyword(alabel))+pp.Optional(letterstart)+_equalTo
00784 +typeWithParameters.copy().setParseAction(_MakePlugin(type))|
00785 pp.Keyword(alabel).suppress()+pp.Optional(letterstart)+_equalTo+pp.Group(label+pp.Group(pp.Keyword("from").suppress()+quotedString).setParseAction(_makeInclude)).setParseAction(_MakeFrom(type))
00786 ).setParseAction(useTypeIfNoLabel)
00787
00788 es_module = _labelOptional("es_module",cms.ESProducer)
00789 es_source = _labelOptional("es_source",cms.ESSource)
00790
00791 plugin = source|looper|service|outputModuleGuess|producerGuess|analyzerGuess|module|es_module|es_source|es_prefer
00792 plugin.ignore(pp.cppStyleComment)
00793 plugin.ignore(pp.pythonStyleComment)
00794
00795
00796
00797
00798
00799
00800
00801 pathexp = pp.Forward()
00802
00803 _pathAtom = pp.Combine(pp.Optional("!")+pp.Optional("-")+letterstart)
00804
00805 worker = (_pathAtom)^pp.Group(pp.Suppress(')')+pathexp+pp.Suppress('('))
00806 pathseq = pp.Forward()
00807 pathseq << pp.Group(worker + pp.ZeroOrMore(','+pathseq))
00808 pathexp << pp.Group(pathseq + pp.ZeroOrMore('&'+pathexp))
00809
00810 class _LeafNode(object):
00811 def __init__(self,label):
00812 self.__isNot = False
00813 self.__isIgnore = False
00814 self._label = label
00815 if self._label[0]=='!':
00816 self._label=self._label[1:]
00817 self.__isNot = True
00818 elif self._label[0]=='-':
00819 self._label=self._label[1:]
00820 self.__isIgnore = True
00821
00822 def __str__(self):
00823 v=''
00824 if self.__isNot:
00825 v='!'
00826 elif self.__isIgnore:
00827 v += '-'
00828 return v+self._label
00829 def make(self,process):
00830
00831 v = getattr(process,self._label)
00832 if self.__isNot:
00833 v= ~v
00834 elif self.__isIgnore:
00835 v= cms.ignore(v)
00836 return v
00837 def getLeaves(self, leaves):
00838 leaves.append(self)
00839 def dumpPython(self, options):
00840 result = ''
00841 if self.__isNot:
00842 result += '~'
00843 elif self.__isIgnore:
00844 result += 'cms.ignore('
00845 if options.isCfg:
00846 result += "process."
00847 result += self._label
00848 if self.__isIgnore:
00849 result += ')'
00850 return result
00851
00852 class _AidsOp(object):
00853 def __init__(self,left,right):
00854 self.__left = left
00855 self.__right = right
00856 def __str__(self):
00857 return '('+str(self.__left)+','+str(self.__right)+')'
00858 def getLeaves(self, leaves):
00859 self.__left.getLeaves(leaves)
00860 self.__right.getLeaves(leaves)
00861 def dumpPython(self, options):
00862 return self.__left.dumpPython(options)+'*'+self.__right.dumpPython(options)
00863 def make(self,process):
00864 left = self.__left.make(process)
00865 right = self.__right.make(process)
00866 return left*right
00867
00868 class _FollowsOp(object):
00869 def __init__(self,left,right):
00870 self.__left = left
00871 self.__right = right
00872 def __str__(self):
00873 return '('+str(self.__left)+'&'+str(self.__right)+')'
00874 def getLeaves(self, leaves):
00875 self.__left.getLeaves(leaves)
00876 self.__right.getLeaves(leaves)
00877 def dumpPython(self, options):
00878 return self.__left.dumpPython(options)+'+'+self.__right.dumpPython(options)
00879 def make(self,process):
00880 left = self.__left.make(process)
00881 right = self.__right.make(process)
00882 return left+right
00883
00884 def _buildTree(tree):
00885
00886 if isinstance(tree,type('')):
00887 return _LeafNode(tree)
00888 if len(tree) == 1:
00889 return _buildTree(tree[0])
00890 assert(len(tree) == 3)
00891 left = _buildTree(tree[0])
00892 right = _buildTree(tree[2])
00893 theOp = _FollowsOp
00894 if ',' == tree[1]:
00895 theOp = _AidsOp
00896
00897 return theOp(right,left)
00898
00899 def _parsePathInReverse(s,loc,toks):
00900 backwards = list(toks[0])
00901 backwards.reverse()
00902 return [_buildTree(pathexp.parseString(' '.join(backwards)))]
00903
00904 class _ModuleSeries(object):
00905 def __init__(self,topNode,s,loc,toks):
00906 global _fileStack
00907
00908 self.topNode = topNode
00909 self.forErrorMessage = (s,loc,toks,_fileStack[-1])
00910 def make(self,process):
00911 try:
00912 nodes = self.topNode.make(process)
00913 return self.factory()(nodes)
00914 except AttributeError, e:
00915 raise pp.ParseFatalException(self.forErrorMessage[0],
00916 self.forErrorMessage[1],
00917 self.type()+" '"
00918 +self.forErrorMessage[2][0][0]+
00919 "' contains the error: "
00920 +str(e)
00921 +"\n from file "+self.forErrorMessage[3])
00922 except Exception, e:
00923 raise pp.ParseFatalException(self.forErrorMessage[0],
00924 self.forErrorMessage[1],
00925 self.type()
00926 +" '"+self.forErrorMessage[2][0][0]
00927 +"' contains the error: "+str(e)
00928 +"\n from file "+self.forErrorMessage[3])
00929 def __str__(self):
00930 return str(self.topNode)
00931 def __repr__(self):
00932 options = PrintOptions()
00933
00934 options.isCfg = False
00935 return self.dumpPython(options)
00936 def getLeaves(self, leaves):
00937 self.topNode.getLeaves(leaves)
00938 def dumpPython(self, options):
00939 return "cms."+self.factory().__name__+"("+self.topNode.dumpPython(options)+")"
00940
00941
00942 class _Sequence(_ModuleSeries):
00943 def factory(self):
00944 return cms.Sequence
00945 def type(self):
00946 return 'sequence'
00947 class _Path(_ModuleSeries):
00948 def factory(self):
00949 return cms.Path
00950 def type(self):
00951 return 'path'
00952 class _EndPath(_ModuleSeries):
00953 def factory(self):
00954 return cms.EndPath
00955 def type(self):
00956 return 'endpath'
00957
00958
00959 class _MakeSeries(object):
00960 def __init__(self,factory):
00961 self.factory = factory
00962 def __call__(self,s,loc,toks):
00963 return (toks[0][0],self.factory(toks[0][1],s,loc,toks))
00964
00965 pathtoken = (pp.Combine(pp.Optional("!")+pp.Optional("-")+letterstart))|'&'|','|'('|')'
00966 pathbody = pp.Group(letterstart+_equalTo
00967 +_scopeBegin
00968 +pp.Group(pp.OneOrMore(pathtoken)).setParseAction(_parsePathInReverse)
00969 +_scopeEnd)
00970 path = pp.Keyword('path').suppress()+pathbody.copy().setParseAction(_MakeSeries(_Path))
00971 endpath = pp.Keyword('endpath').suppress()+pathbody.copy().setParseAction(_MakeSeries(_EndPath))
00972 sequence = pp.Keyword('sequence').suppress()+pathbody.copy().setParseAction(_MakeSeries(_Sequence))
00973
00974
00975 class _Schedule(object):
00976 """Stand-in for a Schedule since we can't build the real Schedule
00977 till the Paths have been created"""
00978 def __init__(self,labels):
00979 self.labels = labels
00980 def dumpPython(self, options):
00981 result = "cms.Schedule("
00982
00983 newLabels = list()
00984 if options.isCfg:
00985 for label in self.labels:
00986 newLabels.append('process.'+label)
00987 result += ','.join(newLabels)
00988 result += ')\n'
00989
00990 return result
00991
00992
00993 def _makeSchedule(s,loc,toks):
00994 """create the appropriate parameter object from the tokens"""
00995 values = list(iter(toks[0][0]))
00996 p = _Schedule(values)
00997 return ('schedule',p)
00998
00999 schedule = pp.Group(pp.Keyword('schedule').suppress()+_equalTo+
01000 _scopeBegin
01001 +pp.Group(pp.Optional(pp.delimitedList(label)))
01002 +_scopeEnd
01003 ).setParseAction(_makeSchedule)
01004
01005
01006
01007
01008
01009 class _ReplaceNode(object):
01010 """Handles the 'replace' command"""
01011 def __init__(self,path,setter,s,loc):
01012 global _fileStack
01013 self.path = path
01014 self.setter = setter
01015 self.forErrorMessage =(s,loc,_fileStack[-1])
01016 self.multiplesAllowed = setter.multiplesAllowed
01017 def getValue(self):
01018 return self.setter.value
01019 value = property(fget = getValue,
01020 doc='returns the value of the replace command (for testing)')
01021 def rootLabel(self):
01022 return self.path[0]
01023 def do(self,process):
01024 if hasattr(self.setter, 'setProcess'):
01025 self.setter.setProcess(process)
01026 try:
01027 self._recurse(self.path,process)
01028 except Exception,e:
01029 raise pp.ParseException(self.forErrorMessage[0],
01030 self.forErrorMessage[1],
01031 "The replace statement '"+'.'.join(self.path)
01032 +"' had the error \n"+str(e)
01033 +"\n from file "+self.forErrorMessage[2]
01034 )
01035 def _setValue(self,obj,attr):
01036 self.setter.setValue(obj,attr)
01037 def _recurse(self,path,obj):
01038 if len(path) == 1:
01039 self._setValue(obj,path[0])
01040 return
01041 self._recurse(path[1:],getattr(obj,path[0]))
01042 def __repr__(self):
01043 options = PrintOptions()
01044 return self.dumpPython(options)
01045 def dumpPython(self, options):
01046
01047 s = self.getValue()
01048 return '.'.join(self.path)+self.setter.dumpPython(options)
01049
01050 class _ReplaceSetter(object):
01051 """Used to 'set' an unknown type of value from a Replace node"""
01052 def __init__(self,value):
01053 self.value = value
01054
01055 self.multiplesAllowed = False
01056 def setValue(self,obj,attr):
01057 theAt = getattr(obj,attr)
01058
01059
01060
01061
01062 v=theAt._valueFromString(self.value)
01063 v.setIsTracked(theAt.isTracked())
01064 setattr(obj,attr,v)
01065 def dumpPython(self, options):
01066
01067 return " = "+self._pythonValue(self.value, options)
01068 @staticmethod
01069 def _pythonValue(value, options):
01070
01071 result = str(value)
01072 nodots = result.replace('.','')
01073 if nodots.isdigit() or (len(nodots) > 0 and nodots[0] == '-') or (len(nodots) > 1 and (nodots[0:2] == '0x' or nodots[0:2] == '0X')):
01074 pass
01075 elif result == 'true':
01076 result = 'True'
01077 elif result == 'false':
01078 result = 'False'
01079 elif len(value) == 0:
01080 result = repr(value)
01081 elif result[0] == '[':
01082 l = eval(result)
01083 isVInputTag = False
01084 result = ''
01085 indented = False
01086 for i, x in enumerate(l):
01087 if i == 0:
01088 if hasattr(x, "_nPerLine"):
01089 nPerLine = x._nPerLine
01090 else:
01091 nPerLine = 5
01092 else:
01093 result += ', '
01094 if i % nPerLine == 0:
01095 if not indented:
01096 indented = True
01097 options.indent()
01098 result += '\n'+options.indentation()
01099 element = _ReplaceSetter._pythonValue(x, options)
01100 if element.find('InputTag') != -1:
01101 isVInputTag = True
01102 result += element
01103 if indented:
01104 options.unindent()
01105 if isVInputTag:
01106 result = "cms.VInputTag("+result+")"
01107 else:
01108 result = "["+result+"]"
01109
01110
01111
01112 else:
01113
01114 result = repr(value)
01115 return result
01116
01117
01118
01119 class _ParameterReplaceSetter(_ReplaceSetter):
01120 """Base used to 'set' a PSet or VPSet replace node"""
01121 def setValue(self,obj,attr):
01122
01123 theAt = getattr(obj,attr)
01124 self.value.setIsTracked(theAt.isTracked())
01125 setattr(obj,attr,self.value)
01126 @staticmethod
01127 def _pythonValue(value, options):
01128 return value.dumpPython(options)
01129
01130 class _VPSetReplaceSetter(_ParameterReplaceSetter):
01131 """Used to 'set' a VPSet replace node"""
01132 def __init__(self,value):
01133 super(_VPSetReplaceSetter,self).__init__(_makeVPSetFromList(value))
01134 class _PSetReplaceSetter(_ParameterReplaceSetter):
01135 """Used to 'set' a VPSet replace node"""
01136 def __init__(self,value):
01137 super(_PSetReplaceSetter,self).__init__(_makePSetFromList(value))
01138
01139 class _SimpleListTypeExtendSetter(_ReplaceSetter):
01140 """replace command to extends a list"""
01141 def __init__(self,value):
01142 super(type(self),self).__init__(value)
01143 self.multiplesAllowed = True
01144 def setValue(self,obj,attr):
01145 theAt=getattr(obj,attr)
01146 theAt.extend(theAt._valueFromString(self.value))
01147 def dumpPython(self, options):
01148 return ".extend("+self._pythonValue(self.value, options)+")"
01149
01150
01151 class _SimpleListTypeAppendSetter(_ReplaceSetter):
01152 """replace command to append to a list"""
01153 def __init__(self,value):
01154 super(type(self),self).__init__(value)
01155 self.multiplesAllowed = True
01156 def setValue(self,obj,attr):
01157 theAt=getattr(obj,attr)
01158 theAt.append(theAt._valueFromString([self.value])[0])
01159 def dumpPython(self, options):
01160 return ".append("+self._pythonValue(self.value, options)+")"
01161
01162
01163
01164 class _VPSetExtendSetter(_VPSetReplaceSetter):
01165 """replace command to extend a VPSet"""
01166 def __init__(self,value):
01167 super(type(self),self).__init__(value)
01168 self.multiplesAllowed = True
01169 def setValue(self,obj,attr):
01170 theAt=getattr(obj,attr)
01171 theAt.extend(self.value)
01172 def dumpPython(self, options):
01173 return ".extend("+self._pythonValue(self.value, options)+")"
01174
01175
01176
01177 class _VPSetAppendSetter(_PSetReplaceSetter):
01178 """replace command to append a PSet to a VPSet"""
01179 def __init__(self,value):
01180 super(type(self),self).__init__(value)
01181 self.multiplesAllowed = True
01182 def setValue(self,obj,attr):
01183 theAt=getattr(obj,attr)
01184 theAt.append(self.value)
01185 def dumpPython(self, options):
01186 return ".append("+self._pythonValue(self.value, options)+")"
01187
01188
01189
01190 class _IncrementFromVariableSetter(_ReplaceSetter):
01191 """replace command which gets its value from another parameter"""
01192 def __init__(self,value):
01193 self.valuePath = value
01194 super(type(self),self).__init__('.'.join(value))
01195 self.multiplesAllowed = True
01196 self.oldValue = None
01197 def setProcess(self,process):
01198 if self.oldValue is None:
01199 self.oldValue = self.value
01200 attr=None
01201 path = self.valuePath
01202 attr = process
01203 while path:
01204 attr = getattr(attr,path[0])
01205 path = path[1:]
01206 self.value = attr
01207 def setValue(self,obj,attr):
01208 theAt = getattr(obj,attr)
01209
01210 try:
01211 if type(theAt) is type(self.value):
01212 theAt.extend(self.value)
01213
01214 else:
01215 theAt.append(self.value.value())
01216 except Exception, e:
01217 raise RuntimeError("replacing with "+self.oldValue+" failed because\n"+str(e))
01218 def dumpPython(self, options):
01219 v = str(self.value)
01220 if options.isCfg:
01221 v = 'process.'+v
01222
01223 if v[0] == '[':
01224 return ".extend("+v+")"
01225 elif v.endswith('s'):
01226 return ".extend("+v+")"
01227 else:
01228 return ".append("+v+")"
01229
01230
01231
01232 class _MakeSetter(object):
01233 """Uses a 'factory' to create the proper Replace setter"""
01234 def __init__(self,setter):
01235 self.setter = setter
01236 def __call__(self,s,loc,toks):
01237 value = toks[0]
01238 if isinstance(value,pp.ParseResults):
01239 value = value[:]
01240 return self.setter(value)
01241
01242 def _makeReplace(s,loc,toks):
01243 try:
01244 path = toks[0][0]
01245 setter = toks[0][1]
01246 return ('.'.join(path),_ReplaceNode(list(path),setter,s,loc))
01247 except Exception, e:
01248 global _fileStack
01249 raise pp.ParseException(s,loc,"replace statement '"
01250 +'.'.join(list(path))
01251 +"' had the error \n"
01252 +str(e)
01253 +"\n from file "+_fileStack[-1])
01254
01255 _replaceValue = (pp.Group(_scopeBegin+_scopeEnd
01256 ).setParseAction(_MakeSetter(_ReplaceSetter))|
01257 (scopedParameters.copy()
01258 ).setParseAction(_MakeSetter(_PSetReplaceSetter))|
01259 (_scopeBegin+pp.Group(pp.delimitedList(scopedParameters))
01260 +_scopeEnd).setParseAction(_MakeSetter(_VPSetReplaceSetter))|
01261 (quotedString|
01262 (_scopeBegin+pp.Group(pp.delimitedList(quotedString))+_scopeEnd)|
01263 (_scopeBegin+pp.Group(pp.Optional(pp.delimitedList(any)))+_scopeEnd)|
01264 any).setParseAction(_MakeSetter(_ReplaceSetter)))
01265 _replaceExtendValue = (
01266 scopedParameters.copy().setParseAction(_MakeSetter(_VPSetAppendSetter)) |
01267 (_scopeBegin+pp.Group(pp.delimitedList(scopedParameters))
01268 +_scopeEnd).setParseAction(_MakeSetter(_VPSetExtendSetter))|
01269 ((_scopeBegin+pp.Group(pp.delimitedList(quotedString))+_scopeEnd)|
01270 (_scopeBegin+pp.Group(pp.Optional(pp.delimitedList(any)))+_scopeEnd)
01271 ).setParseAction(_MakeSetter(_SimpleListTypeExtendSetter)) |
01272 (pp.Group(letterstart+pp.OneOrMore(pp.Literal('.').suppress()+letterstart)).setParseAction(
01273 _MakeSetter(_IncrementFromVariableSetter))) |
01274 ((quotedString|any).setParseAction(_MakeSetter(_SimpleListTypeAppendSetter)))
01275 )
01276 _plusEqualTo = pp.Suppress('+=')
01277
01278
01279 _eqTo = pp.Suppress("=")
01280 replace = pp.Group(pp.Keyword('replace').suppress()+
01281 pp.Group(letterstart+
01282 pp.OneOrMore(pp.Literal('.').suppress()+letterstart)
01283 )+
01284 ((_plusEqualTo+_replaceExtendValue
01285 ) | (
01286 _eqTo+_replaceValue))
01287 ).setParseAction(_makeReplace)
01288
01289 class _ProcessAdapter(object):
01290 def __init__(self,seqs,process):
01291 self.__dict__['_seqs'] = seqs
01292 self.__dict__['_process'] = process
01293 def seqs(self):
01294 return self.__dict__['_seqs']
01295 def process(self):
01296 return self.__dict__['_process']
01297 def __getattr__(self,name):
01298 if hasattr(self.process(), name):
01299 return getattr(self.process(),name)
01300 setattr(self.process(),name,self.seqs()[name].make(self))
01301 return getattr(self.process(),name)
01302 def __setattr__(self,name,value):
01303 if hasattr(self.process(),name):
01304 return
01305 setattr(self.process(),name,value)
01306 def _finalizeProcessFragment(values,usingLabels):
01307 try:
01308 values = _validateLabelledList(values)
01309 values = _findAndHandleProcessBlockIncludes(values)
01310 values = _validateLabelledList(values)
01311 except Exception, e:
01312 raise RuntimeError("the configuration contains the error \n"+str(e))
01313
01314 d = SortedKeysDict(values)
01315 dct = dict(d)
01316 replaces=[]
01317 sequences = {}
01318 series = []
01319 for label,item in values:
01320 if isinstance(item,_ReplaceNode):
01321 replaces.append(item)
01322
01323 if label in d:
01324 del d[label]
01325 if label in dct:
01326 del dct[label]
01327 elif isinstance(item,_Sequence):
01328 sequences[label]=item
01329 del dct[label]
01330 elif isinstance(item,_ModuleSeries):
01331 series.append((label,item))
01332 del dct[label]
01333 try:
01334
01335
01336 adapted = _DictAdapter(dict(d),True)
01337
01338
01339
01340 for replace in replaces:
01341 if isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01342 replace.do(adapted)
01343 _findAndHandleProcessUsingBlock(values)
01344 for replace in replaces:
01345 if not isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01346 replace.do(adapted)
01347
01348 _findAndHandleProcessUsingBlock(values)
01349 except Exception, e:
01350 raise RuntimeError("the configuration contains the error \n"+str(e))
01351
01352
01353
01354
01355 adapted = _DictAdapter(d)
01356 pa = _ProcessAdapter(sequences,_DictAdapter(dct))
01357 for label,obj in sequences.iteritems():
01358 if label not in dct:
01359 d[label]=obj.make(pa)
01360 dct[label]=d[label]
01361 else:
01362 d[label] = dct[label]
01363 for label,obj in series:
01364 d[label]=obj.make(adapted)
01365 return d
01366
01367
01368
01369 def _getCompressedNodes(s,loc, values):
01370 """Inlines the using statements, but not the Includes or Replaces"""
01371 compressedValues = []
01372 for l,v in values:
01373 compressedValues.append((l,v))
01374
01375 try:
01376 compressedValues = _validateLabelledList(compressedValues)
01377 expandedValues = _findAndHandleProcessBlockIncludes(compressedValues)
01378 expandedValues = _validateLabelledList(expandedValues)
01379
01380 except Exception, e:
01381 raise pp.ParseFatalException(s,loc,"the process contains the error \n"+str(e))
01382
01383 return compressedValues
01384
01385 def _dumpCfg(s,loc,toks):
01386 label = toks[0][0]
01387 p=cms.Process(label)
01388
01389 values = _getCompressedNodes(s, loc, list(iter(toks[0][1])) )
01390 options = PrintOptions()
01391 options.isCfg = True
01392 result = "import FWCore.ParameterSet.Config as cms\n\nprocess = cms.Process(\""+label+"\")\n"
01393 result += dumpPython(values, options)
01394 return result
01395
01396 def _makeProcess(s,loc,toks):
01397 """create a Process from the tokens"""
01398
01399 label = toks[0][0]
01400 p=cms.Process(label)
01401 values = list(iter(toks[0][1]))
01402 try:
01403 values = _validateLabelledList(values)
01404 values = _findAndHandleProcessBlockIncludes(values)
01405 values = _validateLabelledList(values)
01406 except Exception, e:
01407 raise RuntimeError("the process contains the error \n"+str(e)
01408 )
01409
01410
01411
01412 d = dict(values)
01413 sequences={}
01414 series=[]
01415 replaces=[]
01416 prefers = {}
01417 schedule = None
01418
01419
01420
01421
01422 try:
01423 for label,item in values:
01424 if isinstance(item,_Sequence):
01425 sequences[label]=item
01426 del d[label]
01427 elif isinstance(item,_ModuleSeries):
01428 series.append((label,item))
01429 del d[label]
01430 elif isinstance(item,_ReplaceNode):
01431 replaces.append(item)
01432
01433 if label in d: del d[label]
01434 elif isinstance(item,_Schedule):
01435 if schedule is None:
01436 schedule = item
01437 del d[label]
01438 else:
01439 raise RuntimeError("multiple 'schedule's are present, only one is allowed")
01440 elif isinstance(item,cms.ESPrefer):
01441 prefers[label[0:-7]]=item
01442 del d[label]
01443
01444
01445 adapted = _DictCopyAdapter(d)
01446
01447
01448
01449 for replace in replaces:
01450 if isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01451 replace.do(adapted)
01452 _findAndHandleProcessUsingBlock(values)
01453 for replace in replaces:
01454 if not isinstance(getattr(adapted,replace.rootLabel()),cms.PSet):
01455 replace.do(adapted)
01456
01457
01458
01459 _findAndHandleProcessUsingBlock(values)
01460
01461
01462
01463
01464
01465
01466 global _lookuptable
01467 _lookuptable = {}
01468
01469 for label,obj in d.iteritems():
01470 setattr(p,label,obj)
01471 if not isinstance(obj,list): _lookuptable[obj] = label
01472 for label,obj in prefers.iteritems():
01473 setattr(p,label,obj)
01474 pa = _ProcessAdapter(sequences,p)
01475 for label,obj in sequences.iteritems():
01476 setattr(pa,label,obj.make(pa))
01477 for label,obj in series:
01478 setattr(p,label,obj.make(p))
01479 if schedule is not None:
01480 pathlist = []
01481 for label in schedule.labels:
01482 pathlist.append( getattr(p,label))
01483 p.schedule = cms.Schedule(*pathlist)
01484 except Exception, e:
01485 raise RuntimeError("the process contains the error \n"+str(e))
01486
01487 return p
01488
01489
01490 processNode = plugin|PSetParameter|VPSetParameter|block|include|path|endpath|sequence|schedule|replace
01491 processBody = pp.OneOrMore(processNode)
01492 processBody.ignore(pp.cppStyleComment)
01493 processBody.ignore(pp.pythonStyleComment)
01494
01495
01496
01497 onlyPlugin = plugin|pp.empty+pp.StringEnd()
01498
01499 onlyProcessBody = processBody|pp.empty+pp.StringEnd()
01500 onlyProcessBody.ignore(pp.cppStyleComment)
01501 onlyProcessBody.ignore(pp.pythonStyleComment)
01502 onlyParameters = parameters|pp.empty+pp.StringEnd()
01503 onlyFragment =processBody|parameters|plugin|pp.empty+pp.StringEnd()
01504 onlyFragment.ignore(pp.cppStyleComment)
01505 onlyFragment.ignore(pp.pythonStyleComment)
01506
01507 process = pp.Group(pp.Suppress('process')+label+_equalTo+
01508 _scopeBegin+
01509 pp.Group(processBody)+
01510 _scopeEnd).setParseAction(_makeProcess)+pp.StringEnd()
01511 process.ignore(pp.cppStyleComment)
01512 process.ignore(pp.pythonStyleComment)
01513
01514 cfgDumper = pp.Group(pp.Suppress('process')+label+_equalTo+
01515 _scopeBegin+
01516 pp.Group(processBody)+
01517 _scopeEnd).setParseAction(_dumpCfg)+pp.StringEnd()
01518 cfgDumper.ignore(pp.cppStyleComment)
01519 cfgDumper.ignore(pp.pythonStyleComment)
01520
01521
01522 def dumpDict(d):
01523 result = 'import FWCore.ParameterSet.Config as cms\n\n'
01524 options = PrintOptions()
01525 options.isCfg = False
01526 return result+dumpPython(d, options)
01527
01528
01529 def dumpPython(d, options):
01530
01531 includes = ''
01532 replaces = ''
01533 others = ''
01534 sequences = ''
01535 schedules = ''
01536 prefix = ''
01537 if options.isCfg:
01538 prefix = 'process.'
01539 for key,value in d:
01540 newLabel = prefix+key
01541
01542 newLabel.replace('-','_')
01543 if isinstance(value,_IncludeFromNode):
01544 value.createFile(False)
01545 includes += value.dumpPythonAs(newLabel, options)
01546 elif isinstance(value,_IncludeNode):
01547 value.createFile(False)
01548 includes += value.dumpPython(options)+"\n"
01549 elif isinstance(value,_ReplaceNode):
01550 replaces += prefix+value.dumpPython(options)+"\n"
01551 elif isinstance(value,_ModuleSeries):
01552 sequences += newLabel+" = "+value.dumpPython(options)+"\n"
01553 elif isinstance(value,_Schedule):
01554 schedules += newLabel+" = "+value.dumpPython(options)+"\n"
01555 elif isinstance(value, cms.ESPrefer):
01556 others += value.dumpPythonAs(key, options)
01557 else:
01558 others += newLabel+" = "+value.dumpPython(options)+"\n"
01559 return includes+others+sequences+schedules+replaces+"\n"
01560
01561 class _ConfigReturn(object):
01562 def __init__(self,d):
01563 for key,value in d.iteritems():
01564 setattr(self, key, value)
01565 def commentedOutRepr(self):
01566
01567 for key,value in self.__dict__.iteritems():
01568 if isinstance(value, cms._Labelable):
01569 value.setLabel(key)
01570 result = 'import FWCore.ParameterSet.Config as cms\n'
01571
01572 return dumpDict(self.__dict__.iteritems())
01573
01574 def parseCfgFile(fileName):
01575 """Read a .cfg file and create a Process object"""
01576
01577
01578
01579 global _allUsingLabels
01580 global _fileStack
01581 _allUsingLabels = set()
01582 oldFileStack = _fileStack
01583 _fileStack = [fileName]
01584 import os.path
01585 try:
01586 if os.path.exists(fileName):
01587 f=open(fileName)
01588 else:
01589 f=_fileFactory(fileName)
01590 return process.parseFile(f)[0]
01591 finally:
01592 _fileStack = oldFileStack
01593
01594 def parseCffFile(fileName):
01595 """Read a .cff file and return a dictionary"""
01596 global _fileStack
01597 _fileStack.append(fileName)
01598 try:
01599 t=onlyFragment.parseFile(_fileFactory(fileName))
01600 global _allUsingLabels
01601
01602 d=_finalizeProcessFragment(t,_allUsingLabels)
01603 return _ConfigReturn(d)
01604 finally:
01605 _fileStack.pop()
01606
01607 def parseConfigString(aString):
01608 """Read an old style config string and return a dictionary"""
01609 t=onlyFragment.parseString(aString)
01610 global _allUsingLabels
01611 d=_finalizeProcessFragment(t,_allUsingLabels)
01612 return _ConfigReturn(d)
01613
01614 def dumpCfg(fileName):
01615 return cfgDumper.parseFile(_fileFactory(fileName))[0]
01616
01617
01618 def dumpCff(fileName):
01619
01620 values = onlyFragment.parseFile(_fileFactory(fileName))
01621
01622 compressedValues = _getCompressedNodes(fileName, 0, values)
01623
01624 for key,value in compressedValues:
01625 if isinstance(value, cms._Labelable):
01626 value.setLabel(key)
01627
01628 _validateSequences(compressedValues)
01629
01630 return dumpDict(compressedValues)
01631
01632 def _validateSequences(values):
01633 """ Takes the usual list of pairs, and for each
01634 sequence, checks see if the keys are defined yet.
01635 Adds a placeholders for missing keys"""
01636 keys = set()
01637 leaves = list()
01638 expandedValues = _findAndHandleProcessBlockIncludes(values)
01639 for key, value in expandedValues:
01640 keys.add(key)
01641 if isinstance(value, _ModuleSeries):
01642 value.getLeaves(leaves)
01643 for leaf in leaves:
01644 if not leaf._label in keys:
01645 leaf._label = "cms.SequencePlaceholder(\""+leaf._label+"\")"
01646
01647 def processFromString(configString):
01648 """Reads a string containing the equivalent content of a .cfg file and
01649 creates a Process object"""
01650 global _allUsingLabels
01651 global _fileStack
01652 _allUsingLabels = set()
01653 oldFileStack = _fileStack
01654 _fileStack = ["{string}"]
01655 try:
01656 return process.parseString(configString)[0]
01657 finally:
01658 _fileStack = oldFileStack
01659
01660 def importConfig(fileName):
01661 """Use the file extension to decide how to parse the file"""
01662 ext = fileName[fileName.rfind('.'):]
01663 if ext == '.cfg':
01664 return parseCfgFile(fileName)
01665 if ext != '.cff' and ext != '.cfi':
01666 raise RuntimeError("the file '"+fileName+"' has an unknown extension")
01667 return parseCffFile(fileName)
01668
01669 if __name__=="__main__":
01670 import unittest
01671 import StringIO
01672 class TestFactory(object):
01673 def __init__(self,name, contents):
01674 self._name=name
01675
01676 self._contents = contents
01677 def __call__(self, filename):
01678 if self._name != filename:
01679 raise RuntimeError("wrong file name, expected "+self._name+' saw '+filename)
01680 return StringIO.StringIO(self._contents)
01681
01682 class TestModuleCommand(unittest.TestCase):
01683 def setUp(self):
01684 """Nothing to do """
01685
01686 def testPlaceholder(self):
01687 t=path.parseString('path p = {out}')
01688 _validateSequences(t)
01689 self.assertEqual(repr(t[0][1]), "cms.Path(cms.SequencePlaceholder(\"out\"))")
01690
01691 def testLetterstart(self):
01692 t = letterstart.parseString("abcd")
01693 self.assertEqual(len(t),1)
01694 self.assertEqual(t[0],"abcd")
01695 t = letterstart.parseString("a1cd")
01696 self.assertEqual(len(t),1)
01697 self.assertEqual(t[0],"a1cd")
01698 t = letterstart.parseString("a_cd")
01699 self.assertEqual(t[0],"a_cd")
01700 t = letterstart.parseString("a-cd")
01701 self.assertEqual(t[0],"a-cd")
01702 self.assertRaises(pp.ParseBaseException,letterstart.parseString,("1abc"))
01703 def testParameters(self):
01704 t=onlyParameters.parseString("bool blah = True")
01705 d =dict(iter(t))
01706 self.assertEqual(type(d['blah']),cms.bool)
01707 self.assertEqual(d['blah'].value(),True)
01708 t=onlyParameters.parseString("bool blah = 1")
01709 d =dict(iter(t))
01710 self.assertEqual(type(d['blah']),cms.bool)
01711 self.assertEqual(d['blah'].value(),True)
01712 t=onlyParameters.parseString("bool blah = False")
01713 d =dict(iter(t))
01714 self.assertEqual(type(d['blah']),cms.bool)
01715 self.assertEqual(d['blah'].value(),False)
01716 t=onlyParameters.parseString("bool blah = 2")
01717 d =dict(iter(t))
01718 self.assertEqual(type(d['blah']),cms.bool)
01719 self.assertEqual(d['blah'].value(),True)
01720 t=onlyParameters.parseString("vint32 blah = {}")
01721 d=dict(iter(t))
01722 self.assertEqual(type(d['blah']),cms.vint32)
01723 self.assertEqual(len(d['blah']),0)
01724 t=onlyParameters.parseString("vint32 blah = {1}")
01725 d=dict(iter(t))
01726 self.assertEqual(type(d['blah']),cms.vint32)
01727 self.assertEqual(d['blah'],[1])
01728 t=onlyParameters.parseString("vint32 blah = {1,2}")
01729 d=dict(iter(t))
01730 self.assertEqual(type(d['blah']),cms.vint32)
01731 self.assertEqual(d['blah'],[1,2])
01732 t=onlyParameters.parseString("string blah = 'a string'")
01733 d=dict(iter(t))
01734 self.assertEqual(type(d['blah']),cms.string)
01735 self.assertEqual(d['blah'].value(),'a string')
01736 t=onlyParameters.parseString('string blah = "a string"')
01737 d=dict(iter(t))
01738 self.assertEqual(type(d['blah']),cms.string)
01739 self.assertEqual(d['blah'].value(),'a string')
01740 t=onlyParameters.parseString('string blah = "\\0"')
01741 d=dict(iter(t))
01742 self.assertEqual(type(d['blah']),cms.string)
01743 self.assertEqual(d['blah'].value(),'\0')
01744
01745 t=onlyParameters.parseString("vstring blah = {}")
01746 d=dict(iter(t))
01747 self.assertEqual(type(d['blah']),cms.vstring)
01748 self.assertEqual(len(d['blah']),0)
01749 t=onlyParameters.parseString("vstring blah = {'abc'}")
01750 d=dict(iter(t))
01751 self.assertEqual(type(d['blah']),cms.vstring)
01752 self.assertEqual(d['blah'],['abc'])
01753 t=onlyParameters.parseString("vstring blah = {'abc','def'}")
01754 d=dict(iter(t))
01755 self.assertEqual(type(d['blah']),cms.vstring)
01756 self.assertEqual(d['blah'],['abc','def'])
01757
01758 t = onlyParameters.parseString("InputTag blah = tag")
01759 d=dict(iter(t))
01760 self.assertEqual(type(d['blah']),cms.InputTag)
01761 self.assertEqual(d['blah'].moduleLabel,'tag')
01762 self.assertEqual(d['blah'].productInstanceLabel,'')
01763 t = onlyParameters.parseString("InputTag blah = tag:")
01764 d=dict(iter(t))
01765 self.assertEqual(type(d['blah']),cms.InputTag)
01766 self.assertEqual(d['blah'].moduleLabel,'tag')
01767 self.assertEqual(d['blah'].productInstanceLabel,'')
01768
01769 t = onlyParameters.parseString("InputTag blah =tag:youIt")
01770
01771
01772 d=dict(iter(t))
01773 self.assertEqual(type(d['blah']),cms.InputTag)
01774 self.assertEqual(d['blah'].moduleLabel,'tag')
01775 self.assertEqual(d['blah'].productInstanceLabel,'youIt')
01776
01777 t = onlyParameters.parseString("InputTag blah = tag::proc")
01778 d=dict(iter(t))
01779 self.assertEqual(type(d['blah']),cms.InputTag)
01780 self.assertEqual(d['blah'].moduleLabel,'tag')
01781 self.assertEqual(d['blah'].processName,'proc')
01782
01783 t = onlyParameters.parseString("InputTag blah = tag:youIt:Now")
01784 d=dict(iter(t))
01785 self.assertEqual(type(d['blah']),cms.InputTag)
01786 self.assertEqual(d['blah'].moduleLabel,'tag')
01787 self.assertEqual(d['blah'].productInstanceLabel,'youIt')
01788 self.assertEqual(d['blah'].processName,'Now')
01789
01790 t=onlyParameters.parseString("VInputTag blah = {}")
01791 d=dict(iter(t))
01792 self.assertEqual(type(d['blah']),cms.VInputTag)
01793 self.assertEqual(len(d['blah']),0)
01794 t=onlyParameters.parseString("VInputTag blah = {abc}")
01795 d=dict(iter(t))
01796 self.assertEqual(type(d['blah']),cms.VInputTag)
01797 self.assertEqual(d['blah'],[cms.InputTag('abc')])
01798 t=onlyParameters.parseString("VInputTag blah = {abc, def}")
01799 d=dict(iter(t))
01800 self.assertEqual(type(d['blah']),cms.VInputTag)
01801 self.assertEqual(d['blah'],[cms.InputTag('abc'),cms.InputTag('def')])
01802 t=onlyParameters.parseString("VInputTag blah = {'abc', def}")
01803 d=dict(iter(t))
01804 self.assertEqual(type(d['blah']),cms.VInputTag)
01805 self.assertEqual(d['blah'],[cms.InputTag('abc'),cms.InputTag('def')])
01806
01807
01808 t=onlyParameters.parseString("EventID eid= 1:2")
01809 d=dict(iter(t))
01810 self.assertEqual(type(d['eid']),cms.EventID)
01811 self.assertEqual(d['eid'].run(), 1)
01812 self.assertEqual(d['eid'].event(), 2)
01813 t=onlyParameters.parseString("LuminosityBlockID lbid= 1:2")
01814 d=dict(iter(t))
01815 self.assertEqual(type(d['lbid']),cms.LuminosityBlockID)
01816 self.assertEqual(d['lbid'].run(), 1)
01817 self.assertEqual(d['lbid'].luminosityBlock(), 2)
01818
01819
01820
01821 t=onlyParameters.parseString("PSet blah = {}")
01822 d=dict(iter(t))
01823 self.assertEqual(type(d['blah']),cms.PSet)
01824
01825 t=onlyParameters.parseString("PSet blah = {int32 ick = 1 }")
01826 d=dict(iter(t))
01827 self.assertEqual(type(d['blah']),cms.PSet)
01828 self.assertEqual(d['blah'].ick.value(), 1)
01829
01830 t=onlyParameters.parseString("""PSet blah = {
01831 int32 ick = 1
01832 }""")
01833 d=dict(iter(t))
01834 self.assertEqual(type(d['blah']),cms.PSet)
01835 self.assertEqual(d['blah'].ick.value(), 1)
01836
01837 t=onlyParameters.parseString("""PSet blah = {
01838 InputTag t1 = abc:
01839 InputTag t2 = def:GHI
01840 }""")
01841 d=dict(iter(t))
01842 self.assertEqual(type(d['blah']),cms.PSet)
01843
01844 t=onlyParameters.parseString("VPSet blah = {}")
01845 d=dict(iter(t))
01846 self.assertEqual(type(d['blah']),cms.VPSet)
01847
01848 t=onlyParameters.parseString("VPSet blah = { {} }")
01849 d=dict(iter(t))
01850 self.assertEqual(type(d['blah']),cms.VPSet)
01851 self.assertEqual(len(d['blah']),1)
01852
01853 t=onlyParameters.parseString("VPSet blah = { {int32 ick = 1 } }")
01854 d=dict(iter(t))
01855 self.assertEqual(type(d['blah']),cms.VPSet)
01856 self.assertEqual(len(d['blah']),1)
01857 t=onlyParameters.parseString("VPSet blah = { {int32 ick = 1 }, {int32 ick =2} }")
01858 d=dict(iter(t))
01859 self.assertEqual(type(d['blah']),cms.VPSet)
01860 self.assertEqual(len(d['blah']),2)
01861
01862 t=onlyParameters.parseString("secsource blah = Foo {int32 ick=1}")
01863 d=dict(iter(t))
01864 self.assertEqual(type(d['blah']),cms.SecSource)
01865
01866 def testValidation(self):
01867 self.assertRaises(pp.ParseFatalException,onlyParameters.parseString,("""
01868 PSet blah = {
01869 int32 ick = 1
01870 int32 ick = 2
01871 }"""),**dict())
01872 global _fileFactory
01873 oldFactory = _fileFactory
01874 try:
01875 _fileFactory = TestFactory('blah.cfi', 'int32 blah = 1')
01876 t=onlyParameters.parseString("""
01877 PSet blah = {
01878 include "blah.cfi"
01879 include "blah.cfi"
01880 }""")
01881 d = dict(iter(t))
01882 self.assertEqual(getattr(d['blah'],"blah").value(), 1)
01883 _fileFactory = TestFactory('blah.cfi', 'int32 blah = 1')
01884 self.assertRaises(pp.ParseFatalException,onlyParameters.parseString,("""
01885 PSet blah = {
01886 include "blah.cfi"
01887 int32 blah = 2
01888 }"""),**dict())
01889 finally:
01890 _fileFactory=oldFactory
01891 def testUsing(self):
01892
01893 t=onlyParameters.parseString("PSet blah = {using ick}")
01894 d=dict(iter(t))
01895 self.assertEqual(type(d['blah']),cms.PSet)
01896 self.assertEqual(d['blah'].using_ick.value(), 'ick')
01897 def testInclude(self):
01898
01899 import StringIO
01900 global _fileFactory
01901 oldFactory = _fileFactory
01902 try:
01903 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', 'int32 blah = 1')
01904 t=onlyParameters.parseString("PSet blah = {include 'Sub/Pack/data/foo.cff'}")
01905 d=dict(iter(t))
01906 self.assertEqual(type(d['blah']),cms.PSet)
01907 self.assertEqual(getattr(d['blah'],"blah").value(), 1)
01908
01909 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'module foo = TestProd {}')
01910 t=onlyProcessBody.parseString("include 'Sub/Pack/data/foo.cfi'")
01911 d=dict(iter(t))
01912 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01913 t = _findAndHandleProcessBlockIncludes(t)
01914 d=dict(iter(t))
01915 self.assertEqual(type(d['foo']),cms.EDProducer)
01916
01917
01918 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', """module c = CProd {}
01919 #""")
01920 t=onlyProcessBody.parseString("""module b = BProd {}
01921 include 'Sub/Pack/data/foo.cfi'""")
01922 d=dict(iter(t))
01923 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01924 t = _findAndHandleProcessBlockIncludes(t)
01925
01926 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', "include 'Sub/Pack/data/foo.cfi'")
01927 t=onlyProcessBody.parseString("include 'Sub/Pack/data/foo.cfi'")
01928 d=dict(iter(t))
01929 self.assertEqual(d['Sub/Pack/data/foo.cfi'].filename, 'Sub/Pack/data/foo.cfi')
01930 self.assertRaises(RuntimeError,_findAndHandleProcessBlockIncludes,t)
01931
01932
01933 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', '#an empty file')
01934 t=onlyParameters.parseString("PSet blah = {include 'Sub/Pack/data/foo.cff'}")
01935 d=dict(iter(t))
01936 self.assertEqual(type(d['blah']),cms.PSet)
01937
01938
01939 _fileFactory = TestFactory('Sub/Pack/data/foo.cff', """block c = { ##
01940 ##
01941 double EBs25notContainment = 0.965}
01942 """)
01943 t=onlyProcessBody.parseString("""module b = BProd {using c}
01944 include 'Sub/Pack/data/foo.cff'""")
01945 d=dict(iter(t))
01946 self.assertEqual(d['Sub/Pack/data/foo.cff'].filename, 'Sub/Pack/data/foo.cff')
01947 t = _findAndHandleProcessBlockIncludes(t)
01948
01949 _fileFactory = TestFactory('Sub/Pack/data/foo.cff',
01950 """path p = {doesNotExist}""")
01951 try:
01952 process.parseString("""process T = { include 'Sub/Pack/data/foo.cff' }""")
01953 except Exception,e:
01954 self.assertEqual(str(e),
01955 """the process contains the error
01956 path 'p' contains the error: 'Process' object has no attribute 'doesNotExist'
01957 from file Sub/Pack/data/foo.cff (at char 4), (line:1, col:5)""")
01958 else:
01959 self.fail("failed to throw exception")
01960 finally:
01961 _fileFactory = oldFactory
01962 def testParseCffFile(self):
01963 import StringIO
01964 global _fileFactory
01965 oldFactory = _fileFactory
01966 try:
01967 _fileFactory = TestFactory('Sub/Pack/data/foo.cff',
01968 """module a = AProducer {}
01969 sequence s1 = {s}
01970 sequence s = {a}""")
01971 p=parseCffFile('Sub/Pack/data/foo.cff')
01972 self.assertEqual(p.a.type_(),'AProducer')
01973 self.assertEqual(type(p.s1),cms.Sequence)
01974 self.assertTrue(p.s1._seq is p.s)
01975 pr=cms.Process('Test')
01976 pr.extend(p)
01977 self.assertEqual(str(pr.s),'a')
01978 pr.dumpConfig()
01979 finally:
01980 _fileFactory = oldFactory
01981
01982 def testPlugin(self):
01983 t=plugin.parseString("source = PoolSource { }")
01984 d=dict(iter(t))
01985 self.assertEqual(type(d['source']),cms.Source)
01986 self.assertEqual(d['source'].type_(),"PoolSource")
01987
01988 t=plugin.parseString("source = PoolSource { }")
01989 d=dict(iter(t))
01990 self.assertEqual(type(d['source']),cms.Source)
01991 self.assertEqual(d['source'].type_(),"PoolSource")
01992
01993 t=plugin.parseString("service = MessageLogger { }")
01994 d=dict(iter(t))
01995 self.assertEqual(type(d['MessageLogger']),cms.Service)
01996 self.assertEqual(d['MessageLogger'].type_(),"MessageLogger")
01997
01998 t=plugin.parseString("module foo = FooMod { }")
01999 d=dict(iter(t))
02000 self.assertEqual(type(d['foo']),cms.EDFilter)
02001 self.assertEqual(d['foo'].type_(),"FooMod")
02002
02003 t=plugin.parseString("module out = AsciiOutputModule { }")
02004 d=dict(iter(t))
02005 self.assertEqual(type(d['out']),cms.OutputModule)
02006 self.assertEqual(d['out'].type_(),"AsciiOutputModule")
02007
02008 t=plugin.parseString("module foo = FooProd { }")
02009 d=dict(iter(t))
02010 self.assertEqual(type(d['foo']),cms.EDProducer)
02011 self.assertEqual(d['foo'].type_(),"FooProd")
02012
02013 t=plugin.parseString("module foo = FooProducer { }")
02014 d=dict(iter(t))
02015 self.assertEqual(type(d['foo']),cms.EDProducer)
02016 self.assertEqual(d['foo'].type_(),"FooProducer")
02017
02018 t=plugin.parseString("es_module = NoLabel {}")
02019 d=dict(iter(t))
02020 self.assertEqual(type(d['NoLabel']),cms.ESProducer)
02021 self.assertEqual(d['NoLabel'].type_(),"NoLabel")
02022
02023 t=plugin.parseString("es_module foo = WithLabel {}")
02024 d=dict(iter(t))
02025 self.assertEqual(type(d['foo']),cms.ESProducer)
02026 self.assertEqual(d['foo'].type_(),"WithLabel")
02027
02028 t=plugin.parseString("""module mix = MixingModule {
02029 secsource input = PoolRASource {
02030 vstring fileNames = {}
02031 }
02032 }
02033 """)
02034 global _fileFactory
02035 oldFactory = _fileFactory
02036 try:
02037 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'module foo = TestProd {}')
02038 t=plugin.parseString("module bar = foo from 'Sub/Pack/data/foo.cfi'")
02039 t = _findAndHandleProcessBlockIncludes(t)
02040 d = dict(iter(t))
02041 self.assertEqual(type(d['bar']),cms.EDProducer)
02042 self.assertEqual(d['bar'].type_(),"TestProd")
02043
02044
02045 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi', 'es_module foo = TestProd {}')
02046 t=plugin.parseString("es_module bar = foo from 'Sub/Pack/data/foo.cfi'")
02047 t = _findAndHandleProcessBlockIncludes(t)
02048 d=dict(iter(t))
02049 self.assertEqual(type(d['bar']),cms.ESProducer)
02050 self.assertEqual(d['bar'].type_(),"TestProd")
02051 finally:
02052 _fileFactory = oldFactory
02053
02054 self.assertRaises(pp.ParseFatalException,
02055 plugin.parseString,
02056 ("""es_module foo = WithLabel {
02057 uint32 a = 1
02058 int32 a = 1
02059 }"""))
02060 def testProcess(self):
02061 global _allUsingLabels
02062 _allUsingLabels = set()
02063 t=process.parseString(
02064 """
02065 process RECO = {
02066 source = PoolSource {
02067 untracked vstring fileNames = {"file:foo.root"}
02068 }
02069 module out = PoolOutputModule {
02070 untracked string fileName = "blah.root"
02071 }
02072 path p = {out}
02073 }""")
02074 self.assertEqual(t[0].source.type_(),"PoolSource")
02075 self.assertEqual(t[0].out.type_(),"PoolOutputModule")
02076 self.assertEqual(type(t[0].p),cms.Path)
02077 self.assertEqual(str(t[0].p),'out')
02078
02079 import StringIO
02080 global _fileFactory
02081 oldFactory = _fileFactory
02082 try:
02083 _fileFactory = TestFactory('Sub/Pack/data/foo.cfi',
02084 'module foo = FooProd {}')
02085 _allUsingLabels = set()
02086 t=process.parseString(
02087 """
02088 process RECO = {
02089 source = PoolSource {
02090 untracked vstring fileNames = {"file:foo.root"}
02091 }
02092 include "Sub/Pack/data/foo.cfi"
02093 path p = {foo}
02094 }""")
02095 self.assertEqual(t[0].foo.type_(),"FooProd")
02096 finally:
02097 _fileFactory = oldFactory
02098
02099 _allUsingLabels = set()
02100 t=process.parseString(
02101 """
02102 process RECO = {
02103 source = PoolSource {
02104 untracked vstring fileNames = {"file:foo.root"}
02105 }
02106 module out = PoolOutputModule {
02107 untracked string fileName = "blah.root"
02108 }
02109 endpath e = {out}
02110 module foo = FooProd {}
02111 module bar = BarProd {}
02112 module fii = FiiProd {}
02113 path p = {s&fii}
02114 sequence s = {foo,bar}
02115 }""")
02116 self.assertEqual(str(t[0].p),'foo*bar+fii')
02117 self.assertEqual(str(t[0].s),'foo*bar')
02118 t[0].dumpConfig()
02119
02120 _allUsingLabels = set()
02121 t=process.parseString(
02122 """
02123 process RECO = {
02124 source = PoolSource {
02125 untracked vstring fileNames = {"file:foo.root"}
02126 }
02127 module out = PoolOutputModule {
02128 untracked string fileName = "blah.root"
02129 }
02130 endpath e = {out}
02131 module foo = FooProd {}
02132 module bar = BarProd {}
02133 module fii = FiiProd {}
02134 path p = {s&!fii}
02135 sequence s = {foo,bar}
02136 }""")
02137 self.assertEqual(str(t[0].p),'foo*bar+~fii')
02138 self.assertEqual(str(t[0].s),'foo*bar')
02139 t[0].dumpConfig()
02140
02141 s="""
02142 process RECO = {
02143 module foo = FooProd {}
02144 path p = {fo}
02145 }
02146 """
02147 self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02148 try:
02149 _allUsingLabels = set()
02150 t=process.parseString(s)
02151 except Exception, e:
02152 print e
02153
02154 _allUsingLabels = set()
02155 t=process.parseString("""
02156 process RECO = {
02157 block outputStuff = {
02158 vstring outputCommands = {"drop *"}
02159 }
02160 block toKeep = {
02161 vstring outputCommands = {"keep blah_*_*_*"}
02162 }
02163 replace outputStuff.outputCommands += toKeep.outputCommands
02164 }
02165 """)
02166 self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02167
02168 _allUsingLabels = set()
02169 t=process.parseString("""
02170 process RECO = {
02171 module i = iterativeCone5CaloJets from "FWCore/ParameterSet/test/chainIncludeModule.cfi"
02172 }
02173 """)
02174 self.assertEqual(t[0].i.jetType.value(), "CaloJet")
02175
02176
02177 _allUsingLabels = set()
02178 t=process.parseString("""
02179 process RECO = {
02180 include "FWCore/ParameterSet/test/chainIncludeBlock.cfi"
02181 replace CaloJetParameters.inputEMin = 0.1
02182 module i = iterativeConeNoBlock from "FWCore/ParameterSet/test/chainIncludeModule2.cfi"
02183 }
02184 """)
02185 self.assertEqual(t[0].i.jetType.value(), "CaloJet")
02186 self.assertEqual(t[0].i.inputEMin.value(), 0.1)
02187
02188
02189
02190 _allUsingLabels = set()
02191 t=process.parseString("""
02192 process RECO = {
02193 block outputStuff = {
02194 vstring outputCommands = {"drop *"}
02195 }
02196 block toKeep1 = {
02197 vstring outputCommands = {"keep blah1_*_*_*"}
02198 }
02199 block toKeep2 = {
02200 vstring outputCommands = {"keep blah2_*_*_*"}
02201 }
02202 block toKeep3 = {
02203 vstring outputCommands = {"keep blah3_*_*_*"}
02204 }
02205 replace outputStuff.outputCommands += toKeep1.outputCommands
02206 replace outputStuff.outputCommands += toKeep2.outputCommands
02207 replace outputStuff.outputCommands += toKeep3.outputCommands
02208 }
02209 """)
02210 self.assertEqual(t[0].outputStuff.outputCommands,["drop *",
02211 "keep blah1_*_*_*",
02212 "keep blah2_*_*_*",
02213 "keep blah3_*_*_*"])
02214
02215 _allUsingLabels = set()
02216 t=process.parseString("""
02217 process RECO = {
02218 block outputStuff = {
02219 vstring outputCommands = {"drop *"}
02220 }
02221 block toKeep1 = {
02222 vstring outputCommands = {"keep blah1_*_*_*"}
02223 }
02224 block toKeep2 = {
02225 vstring outputCommands = {"keep blah2_*_*_*"}
02226 }
02227 block toKeep3 = {
02228 vstring outputCommands = {"keep blah3_*_*_*"}
02229 }
02230 replace outputStuff.outputCommands += toKeep1.outputCommands
02231 replace outputStuff.outputCommands += toKeep2.outputCommands
02232 replace outputStuff.outputCommands += toKeep3.outputCommands
02233
02234 module out = PoolOutputModule {
02235 using outputStuff
02236 }
02237 }
02238 """)
02239 self.assertEqual(t[0].out.outputCommands,["drop *",
02240 "keep blah1_*_*_*",
02241 "keep blah2_*_*_*",
02242 "keep blah3_*_*_*"])
02243 t=process.parseString("""
02244 process RECO = {
02245 block FEVTEventContent = {
02246 vstring outputCommands = {"drop *"}
02247 }
02248 block FEVTSIMEventContent = {
02249 vstring outputCommands = {"drop *"}
02250 }
02251 block toKeep1 = {
02252 vstring outputCommands = {"keep blah1_*_*_*"}
02253 }
02254 block toKeep2 = {
02255 vstring outputCommands = {"keep blah2_*_*_*"}
02256 }
02257 block toKeep3 = {
02258 vstring outputCommands = {"keep blah3_*_*_*"}
02259 }
02260
02261 block toKeepSim1 = {
02262 vstring outputCommands = {"keep blahs1_*_*_*"}
02263 }
02264 block toKeepSim2 = {
02265 vstring outputCommands = {"keep blahs2_*_*_*"}
02266 }
02267 block toKeepSim3 = {
02268 vstring outputCommands = {"keep blahs3_*_*_*"}
02269 }
02270
02271 replace FEVTEventContent.outputCommands += toKeep1.outputCommands
02272 replace FEVTEventContent.outputCommands += toKeep2.outputCommands
02273 replace FEVTEventContent.outputCommands += toKeep3.outputCommands
02274
02275 replace FEVTSIMEventContent.outputCommands += FEVTEventContent.outputCommands
02276
02277 replace FEVTSIMEventContent.outputCommands += toKeepSim1.outputCommands
02278 replace FEVTSIMEventContent.outputCommands += toKeepSim2.outputCommands
02279 replace FEVTSIMEventContent.outputCommands += toKeepSim3.outputCommands
02280
02281 }
02282 """)
02283 self.assertEqual(t[0].FEVTEventContent.outputCommands,["drop *",
02284 "keep blah1_*_*_*",
02285 "keep blah2_*_*_*",
02286 "keep blah3_*_*_*"])
02287
02288 self.assertEqual(t[0].FEVTSIMEventContent.outputCommands,["drop *",
02289 "drop *",
02290 "keep blah1_*_*_*",
02291 "keep blah2_*_*_*",
02292 "keep blah3_*_*_*",
02293 "keep blahs1_*_*_*",
02294 "keep blahs2_*_*_*",
02295 "keep blahs3_*_*_*"])
02296
02297 t=process.parseString("""
02298 process RECO = {
02299 block FEVTEventContent = {
02300 vstring outputCommands = {"drop *"}
02301 }
02302 block FEVTSIMEventContent = {
02303 vstring outputCommands = {"drop *"}
02304 }
02305 block toKeep1 = {
02306 vstring outputCommands = {"keep blah1_*_*_*"}
02307 }
02308 block toKeep2 = {
02309 vstring outputCommands = {"keep blah2_*_*_*"}
02310 }
02311 block toKeep3 = {
02312 vstring outputCommands = {"keep blah3_*_*_*"}
02313 }
02314
02315 block toKeepSim1 = {
02316 vstring outputCommands = {"keep blahs1_*_*_*"}
02317 }
02318 block toKeepSim2 = {
02319 vstring outputCommands = {"keep blahs2_*_*_*"}
02320 }
02321 block toKeepSim3 = {
02322 vstring outputCommands = {"keep blahs3_*_*_*"}
02323 }
02324
02325 replace FEVTEventContent.outputCommands += toKeep1.outputCommands
02326 replace FEVTEventContent.outputCommands += toKeep2.outputCommands
02327 replace FEVTEventContent.outputCommands += toKeep3.outputCommands
02328
02329 replace FEVTSIMEventContent.outputCommands += FEVTEventContent.outputCommands
02330
02331 replace FEVTSIMEventContent.outputCommands += toKeepSim1.outputCommands
02332 replace FEVTSIMEventContent.outputCommands += toKeepSim2.outputCommands
02333 replace FEVTSIMEventContent.outputCommands += toKeepSim3.outputCommands
02334
02335 module out = PoolOutputModule {
02336 using FEVTSIMEventContent
02337 }
02338 }
02339 """)
02340 self.assertEqual(t[0].FEVTEventContent.outputCommands,["drop *",
02341 "keep blah1_*_*_*",
02342 "keep blah2_*_*_*",
02343 "keep blah3_*_*_*"])
02344
02345 self.assertEqual(t[0].FEVTSIMEventContent.outputCommands,["drop *",
02346 "drop *",
02347 "keep blah1_*_*_*",
02348 "keep blah2_*_*_*",
02349 "keep blah3_*_*_*",
02350 "keep blahs1_*_*_*",
02351 "keep blahs2_*_*_*",
02352 "keep blahs3_*_*_*"])
02353 self.assertEqual(t[0].out.outputCommands,
02354 t[0].FEVTSIMEventContent.outputCommands)
02355
02356
02357
02358 _allUsingLabels = set()
02359 s="""
02360 process RECO = {
02361 block outputStuff = {
02362 vstring outputCommands = {"drop *"}
02363 }
02364 block aTest = {
02365 vstring outputCommands = {"keep blah_*_*_*"}
02366 }
02367 block toKeep = {
02368 using aTest
02369 }
02370 replace outputStuff.outputCommands += toKeep.outputCommands
02371 }
02372 """
02373 self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02374
02375
02376 _allUsingLabels = set()
02377 t=process.parseString("""
02378 process RECO = {
02379 block outputStuff = {
02380 vstring outputCommands = {"drop *"}
02381 }
02382 block toKeep = {
02383 vstring outputCommands = {"keep blah_*_*_*"}
02384 }
02385
02386 block final = {
02387 using outputStuff
02388 }
02389 replace outputStuff.outputCommands += toKeep.outputCommands
02390 }
02391 """)
02392 self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02393 self.assertEqual(t[0].final.outputCommands,["drop *","keep blah_*_*_*"])
02394
02395 _allUsingLabels = set()
02396 t=process.parseString("""
02397 process TEST = {
02398 service = MessageLogger {
02399 untracked vstring destinations = {"dummy"}
02400 untracked PSet default = {
02401 untracked int32 limit = -1
02402 }
02403 untracked PSet dummy = {}
02404 }
02405 replace MessageLogger.default.limit = 10
02406 replace MessageLogger.destinations += {"goofy"}
02407 replace MessageLogger.dummy = { untracked string threshold = "WARNING" }
02408 }""")
02409 self.assertEqual(t[0].MessageLogger.default.limit.value(),10)
02410 self.assertEqual(t[0].MessageLogger.destinations,["dummy","goofy"])
02411 self.assertEqual(t[0].MessageLogger.dummy.threshold.value(),"WARNING")
02412
02413 _allUsingLabels = set()
02414 t=process.parseString("""
02415 process TEST = {
02416 PSet first = {
02417 int32 foo = 1
02418 int32 fii = 2
02419 }
02420
02421 module second = AModule {
02422 using first
02423 }
02424
02425 replace first.foo = 2
02426
02427 replace second.fii = 3
02428 }
02429 """)
02430 self.assertEqual(t[0].first.foo.value(), 2)
02431 self.assertEqual(t[0].first.fii.value(),2)
02432 self.assertEqual(t[0].second.foo.value(),2)
02433 self.assertEqual(t[0].second.fii.value(),3)
02434
02435 _allUsingLabels = set()
02436 t=process.parseString("""
02437 process TEST = {
02438 es_module = UnnamedProd {
02439 int32 foo = 10
02440 }
02441
02442 es_module me = NamedProd {
02443 int32 fii = 5
02444 }
02445
02446 replace UnnamedProd.foo = 1
02447
02448 replace me.fii = 10
02449 }
02450 """)
02451 self.assertEqual(t[0].UnnamedProd.foo.value(),1)
02452 self.assertEqual(t[0].me.fii.value(),10)
02453
02454 _allUsingLabels = set()
02455 t=process.parseString("""
02456 process RECO = {
02457 block outputStuff = {
02458 vstring outputCommands = {"drop *"}
02459 }
02460 block toKeep = {
02461 vstring outputCommands = {"keep blah_*_*_*"}
02462 }
02463 replace outputStuff.outputCommands += toKeep.outputCommands
02464
02465 source = PoolSource {
02466 untracked vstring fileNames = {"file:foo.root"}
02467 untracked vint32 foos = {1}
02468 }
02469 module out = PoolOutputModule {
02470 using outputStuff
02471 untracked string fileName = "blah.root"
02472 }
02473 replace PoolSource.fileNames = {"file:bar.root"}
02474 replace out.fileName = 'blih.root'
02475 replace PoolSource.foos += 2
02476 replace PoolSource.foos += 3
02477 }""")
02478 self.assertEqual(t[0].source.fileNames,["file:bar.root"])
02479 self.assertEqual(t[0].out.fileName.value(),"blih.root")
02480 self.assertEqual(t[0].source.foos,[1,2,3])
02481 self.assertEqual(t[0].outputStuff.outputCommands,["drop *","keep blah_*_*_*"])
02482 self.assertEqual(t[0].out.outputCommands,["drop *","keep blah_*_*_*"])
02483
02484 _allUsingLabels = set()
02485 t=process.parseString("""
02486 process RECO = {
02487 module foo = FooProd {using b}
02488 PSet b = {uint32 i = 1}
02489 PSet c = {using b}
02490 block p1 = { int32 x = 2
02491 int32 y = 9
02492 }
02493 PSet p2 = { using p1 }
02494 module m1 = MProd { using p2 }
02495 module m2 = MProd { using p2 }
02496 block b1 = {double y = 1.1 }
02497 block b2 = {double x = 2.2 }
02498 }
02499 """)
02500 self.assertEqual(t[0].foo.i.value(),1)
02501 self.assertEqual(t[0].c.i.value(),1)
02502 self.assert_(not hasattr(t[0].foo,'using_b') )
02503 self.assertEqual(t[0].p2.x.value(),2)
02504 self.assertEqual(t[0].m1.x.value(),2)
02505 self.assertEqual(t[0].m2.x.value(),2)
02506
02507
02508 _allUsingLabels = set()
02509 s="""
02510 process RECO = {
02511 module foo = FooProd {using b}
02512 PSet b = {using c}
02513 PSet c = {using b}
02514 }
02515 """
02516 self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02517
02518 _allUsingLabels = set()
02519 s="""
02520 process RECO = {
02521 module foo = FooProd {using b
02522 uint32 alreadyHere = 1
02523 }
02524 PSet b = {uint32 alreadyHere = 2}
02525 }
02526 """
02527 self.assertRaises(RuntimeError,process.parseString,(s),**dict())
02528
02529
02530 _allUsingLabels = set()
02531 t=process.parseString("""
02532 process USER =
02533 {
02534 source = PoolInput
02535 {
02536 string filename = "here"
02537 }
02538
02539 block p1 = {
02540 int32 x = 2
02541 int32 y = 9
02542 }
02543 PSet p2 = {
02544 using p1
02545 }
02546
02547 module m1 = MidpointJetProducer
02548 {
02549 using p2
02550 }
02551
02552 module m2 = MidpointJetProducer
02553 {
02554 using p2
02555 }
02556
02557 block b1 = { double y = 1.1 }
02558 block b2 = { double x = 2.2 }
02559
02560 block G = {
02561 int32 g = 0
02562 }
02563
02564 block H = {
02565 using G
02566 }
02567
02568 block I = {
02569 using J
02570 }
02571
02572 block J = {
02573 int32 j = 0
02574 }
02575
02576 replace J.j = 1
02577
02578 module A = UnconfigurableModule { }
02579 module B = UnconfigurableModule { }
02580 module C = UnconfigurableModule { }
02581 module D = UnconfigurableModule { }
02582 module E = UnconfigurableModule { }
02583 module F = UnconfigurableModule { }
02584 module filter = UnconfigurableFilter { }
02585
02586 sequence s0a = { A}
02587 sequence s0b = { A,B}
02588 sequence s0c = { A&B}
02589 sequence s1 = { A,B&C,(D,E)&F }
02590 sequence s2 = { C&(A,B), m1,m2,s1 }
02591 sequence s3 = {s0a}
02592
02593 path t1 = { (A,B&C,D),s0a,filter }
02594 path t2 = { A,B,C,D }
02595 path t3 = {s3&F}
02596 endpath te = { A&B }
02597
02598 schedule = {t1,t2}
02599
02600 }
02601 """)
02602 self.assertEqual(t[0].p2.x.value(), 2)
02603 self.assertEqual(t[0].m1.x.value(),2)
02604 self.assertEqual(t[0].m2.x.value(),2)
02605 self.assertEqual(t[0].J.j.value(),1)
02606 self.assertEqual(t[0].I.j.value(),1)
02607
02608 t[0].dumpConfig()
02609
02610 _allUsingLabels = set()
02611 t=process.parseString("""
02612 process USER =
02613 {
02614 block a = {int32 i = 1}
02615 PSet b = {PSet c = {using a
02616 VPSet e={{using a} } } }
02617 VPSet d = {{using a}, {}}
02618 }""")
02619 self.assertEqual(t[0].b.c.i.value(),1)
02620 self.assertEqual(t[0].d[0].i.value(),1)
02621 self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02622
02623 t[0].dumpConfig()
02624
02625 _allUsingLabels = set()
02626 t=process.parseString("""
02627 process USER =
02628 {
02629 block a = {int32 i = 1}
02630 PSet b = { PSet c = {}
02631 VPSet g = {} }
02632 replace b.c = {using a
02633 VPSet e={{using a} } }
02634 VPSet d = {{using a}, {}}
02635 }""")
02636 self.assertEqual(t[0].b.c.i.value(),1)
02637 self.assertEqual(t[0].d[0].i.value(),1)
02638 self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02639
02640 t[0].dumpConfig()
02641
02642 _allUsingLabels = set()
02643 t=process.parseString("""
02644 process USER =
02645 {
02646 block a = {int32 i = 1}
02647 PSet b = { PSet c = {} }
02648 replace b.c = { PSet d = { using a }
02649 VPSet e={{using a} } }
02650 }""")
02651 self.assertEqual(t[0].b.c.d.i.value(),1)
02652 self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02653
02654 t[0].dumpConfig()
02655
02656 t=process.parseString("""
02657 process USER =
02658 {
02659 block a = {int32 i = 1}
02660 module b = BWorker { PSet c = {} }
02661 replace b.c = { PSet d = { using a }
02662 VPSet e={{using a} } }
02663 }""")
02664 self.assertEqual(t[0].b.c.d.i.value(),1)
02665 self.assertEqual(t[0].b.c.e[0].i.value(), 1)
02666
02667 t[0].dumpConfig()
02668
02669 t=process.parseString("""
02670 process p = {
02671
02672 block roster = {
02673 string thirdBase = 'Some dude'
02674 PSet outfielders = {
02675 string rightField = 'Some dude'
02676 }
02677 }
02678
02679 module bums = Ballclub {
02680 using roster
02681 }
02682
02683
02684 module allstars = Ballclub {
02685 using roster
02686 }
02687
02688 replace allstars.thirdBase = 'Chuck Norris'
02689 replace allstars.outfielders.rightField = 'Babe Ruth'
02690 }""")
02691 self.assertEqual(t[0].bums.thirdBase.value(), 'Some dude')
02692 self.assertEqual(t[0].bums.outfielders.rightField.value(), 'Some dude')
02693 self.assertEqual(t[0].allstars.thirdBase.value(), 'Chuck Norris')
02694 self.assertEqual(t[0].allstars.outfielders.rightField.value(), 'Babe Ruth')
02695
02696 _allUsingLabels = set()
02697
02698 input= """process RECO = {
02699 es_prefer label = FooESProd {
02700 }
02701 es_module label = FooESProd {
02702 }
02703 }"""
02704
02705 t=process.parseString(input)
02706 self.assertEqual(t[0].label.type_(),"FooESProd")
02707 print t[0].dumpConfig()
02708
02709 _allUsingLabels = set()
02710 t=process.parseString(
02711 """
02712 process RECO = {
02713 es_prefer = FooESProd {
02714 }
02715 es_module = FooESProd {
02716 }
02717 }""")
02718 self.assertEqual(t[0].FooESProd.type_(),"FooESProd")
02719 print t[0].dumpConfig()
02720
02721
02722 def testPath(self):
02723 p = cms.Process('Test')
02724 p.out = cms.OutputModule('PoolOutputModule')
02725 p.a = cms.EDProducer('AProd')
02726 p.b = cms.EDProducer('BProd')
02727 p.c = cms.EDProducer('CProd')
02728 t=path.parseString('path p = {out}')
02729 self.assertEqual(str(t[0][1]),'out')
02730 pth = t[0][1].make(p)
02731 self.assertEqual(str(pth),'out')
02732
02733
02734
02735
02736 t=path.parseString('path p = {a,b}')
02737 self.assertEqual(str(t[0][1]),'(a,b)')
02738 self.checkRepr(t[0][1], 'cms.Path(a*b)')
02739 options = PrintOptions()
02740 options.isCfg = True
02741 self.assertEqual(t[0][1].dumpPython(options), 'cms.Path(process.a*process.b)')
02742 pth = t[0][1].make(p)
02743 self.assertEqual(str(pth),'a*b')
02744
02745
02746 t=path.parseString('path p = {a&b}')
02747 self.assertEqual(str(t[0][1]),'(a&b)')
02748 pth = t[0][1].make(p)
02749 self.assertEqual(str(pth),'a+b')
02750
02751 t=path.parseString('path p = {a,b,c}')
02752 self.assertEqual(str(t[0][1]),'((a,b),c)')
02753 pth = t[0][1].make(p)
02754 self.assertEqual(str(pth),'a*b*c')
02755
02756 t=path.parseString('path p = {a&b&c}')
02757 self.assertEqual(str(t[0][1]),'((a&b)&c)')
02758 pth = t[0][1].make(p)
02759 self.assertEqual(str(pth),'a+b+c')
02760
02761 t=path.parseString('path p = {a&b,c}')
02762 self.assertEqual(str(t[0][1]),'(a&(b,c))')
02763 pth = t[0][1].make(p)
02764 self.assertEqual(str(pth),'a+b*c')
02765
02766 t=path.parseString('path p = {a,b&c}')
02767 self.assertEqual(str(t[0][1]),'((a,b)&c)')
02768 pth = t[0][1].make(p)
02769 self.assertEqual(str(pth),'a*b+c')
02770
02771 t=path.parseString('path p = {(a,b)&c}')
02772 self.assertEqual(str(t[0][1]),'((a,b)&c)')
02773 pth = t[0][1].make(p)
02774 self.assertEqual(str(pth),'a*b+c')
02775
02776 t=path.parseString('path p = {(a&b),c}')
02777 self.assertEqual(str(t[0][1]),'((a&b),c)')
02778 pth = t[0][1].make(p)
02779 self.assertEqual(str(pth),'(a+b)*c')
02780
02781 t=path.parseString('path p = {a,(b&c)}')
02782 self.assertEqual(str(t[0][1]),'(a,(b&c))')
02783 pth = t[0][1].make(p)
02784 self.assertEqual(str(pth),'a*(b+c)')
02785
02786 t=path.parseString('path p = {a&(b,c)}')
02787 self.assertEqual(str(t[0][1]),'(a&(b,c))')
02788 pth = t[0][1].make(p)
02789 self.assertEqual(str(pth),'a+b*c')
02790
02791 p.d = cms.Sequence(p.a*p.b)
02792 t=path.parseString('path p = {d,c}')
02793 self.assertEqual(str(t[0][1]),'(d,c)')
02794 pth = t[0][1].make(p)
02795 self.assertEqual(str(pth),'a*b*c')
02796
02797 t=path.parseString('path p = {a&!b}')
02798 self.assertEqual(str(t[0][1]),'(a&!b)')
02799 pth = t[0][1].make(p)
02800 self.assertEqual(str(pth),'a+~b')
02801
02802 t=path.parseString('path p = {!a&!b&!c}')
02803 self.assertEqual(str(t[0][1]),'((!a&!b)&!c)')
02804 pth = t[0][1].make(p)
02805 self.assertEqual(str(pth),'~a+~b+~c')
02806
02807 t=path.parseString('path p = {a&-b}')
02808 self.assertEqual(str(t[0][1]),'(a&-b)')
02809 pth = t[0][1].make(p)
02810 self.assertEqual(str(pth),'a+cms.ignore(b)')
02811
02812 @staticmethod
02813 def strip(value):
02814 """strip out whitespace & newlines"""
02815 return value.replace(' ','').replace('\n','')
02816 def checkRepr(self, obj, expected):
02817
02818 observe = self.strip(repr(obj))
02819 expect = self.strip(expected)
02820 self.assertEqual(observe, expect)
02821 def testReplace(self):
02822 process = cms.Process("Test")
02823 process.a = cms.EDProducer('FooProd', b=cms.uint32(2))
02824 t=replace.parseString('replace a.b = 1')
02825 self.assertEqual(t[0][0],'a.b')
02826 self.assertEqual(t[0][1].path, ['a','b'])
02827 self.assertEqual(t[0][1].value,'1')
02828 self.checkRepr(t[0][1], "a.b = 1")
02829 t[0][1].do(process)
02830 self.assertEqual(process.a.b.value(),1)
02831
02832 process = cms.Process("Test")
02833 process.a = cms.EDProducer('FooProd', b=cms.PSet(c=cms.double(2)))
02834 t=replace.parseString('replace a.b.c = 1')
02835 self.assertEqual(t[0][0],'a.b.c')
02836 self.assertEqual(t[0][1].path, ['a','b','c'])
02837 self.assertEqual(t[0][1].value,'1')
02838 self.checkRepr(t[0][1], "a.b.c = 1")
02839 self.assertEqual(type(process.a.b),cms.PSet)
02840 t[0][1].do(process)
02841 self.assertEqual(type(process.a.b),cms.PSet)
02842 self.assertEqual(process.a.b.c.value(),1.0)
02843
02844 t=replace.parseString('replace a.b.c = 1.359')
02845 self.assertEqual(t[0][0],'a.b.c')
02846 self.assertEqual(t[0][1].path, ['a','b','c'])
02847 self.assertEqual(t[0][1].value,'1.359')
02848 self.checkRepr(t[0][1], "a.b.c = 1.359")
02849 t[0][1].do(process)
02850 self.assertEqual(type(process.a.b),cms.PSet)
02851 self.assertEqual(process.a.b.c.value(),1.359)
02852
02853 process = cms.Process("Test")
02854 process.a = cms.EDProducer('FooProd', b=cms.untracked.PSet())
02855 self.assertEqual(process.a.b.isTracked(),False)
02856 t=replace.parseString('replace a.b = {untracked string threshold ="DEBUG"}')
02857 t[0][1].do(process)
02858 self.assertEqual(type(process.a.b),cms.PSet)
02859 self.assertEqual(process.a.b.isTracked(),False)
02860 self.assertEqual(process.a.b.threshold.value(),"DEBUG")
02861 self.assertEqual(process.a.b.threshold.isTracked(),False)
02862
02863 process = cms.Process("Test")
02864 process.a = cms.EDProducer('FooProd', b=cms.PSet(c=cms.untracked.double(2)))
02865 self.assertEqual(process.a.b.c.value(),2.0)
02866 self.assertEqual(process.a.b.c.isTracked(),False)
02867 t=replace.parseString('replace a.b.c = 1')
02868 self.checkRepr(t[0][1], "a.b.c = 1")
02869 t[0][1].do(process)
02870 self.assertEqual(type(process.a.b),cms.PSet)
02871 self.assertEqual(process.a.b.c.value(),1.0)
02872 self.assertEqual(process.a.b.c.isTracked(),False)
02873
02874 t=replace.parseString('replace a.b = "all that"')
02875 self.assertEqual(t[0][0],'a.b')
02876 self.assertEqual(t[0][1].path, ['a','b'])
02877 self.assertEqual(t[0][1].value,'all that')
02878 process = cms.Process("Test")
02879 process.a = cms.EDProducer('FooProd', b=cms.string('thing'))
02880 self.checkRepr(t[0][1], "a.b = \'all that\'")
02881 t[0][1].do(process)
02882 self.assertEqual(process.a.b.value(),'all that')
02883
02884 t=replace.parseString('replace a.b = {}')
02885 self.assertEqual(t[0][0],'a.b')
02886 self.assertEqual(t[0][1].path, ['a','b'])
02887 self.assertEqual(t[0][1].value,[])
02888 self.checkRepr(t[0][1], "a.b = []")
02889
02890
02891 t=replace.parseString('replace a.b = {1, 3, 6}')
02892 self.assertEqual(t[0][0],'a.b')
02893 self.assertEqual(t[0][1].path, ['a','b'])
02894 self.assertEqual(t[0][1].value,['1','3','6'])
02895 process = cms.Process("Test")
02896 process.a = cms.EDProducer('FooProd', b=cms.vint32())
02897 self.checkRepr(t[0][1], "a.b = [1, 3, 6]")
02898
02899 t[0][1].do(process)
02900 self.assertEqual(len(process.a.b),3)
02901
02902 t=replace.parseString('replace a.b = {"all", "that"}')
02903 self.assertEqual(t[0][0],'a.b')
02904 self.assertEqual(t[0][1].path, ['a','b'])
02905 self.assertEqual(t[0][1].value,['all','that'])
02906 self.checkRepr(t[0][1], "a.b = [\'all\', \'that\']")
02907 t=replace.parseString('replace a.b = {"all that"}')
02908 self.assertEqual(t[0][0],'a.b')
02909 self.assertEqual(t[0][1].path, ['a','b'])
02910 self.assertEqual(t[0][1].value,['all that'])
02911
02912 t=replace.parseString('replace a.b = { int32 i = 1 }')
02913 self.assertEqual(t[0][0],'a.b')
02914 self.assertEqual(t[0][1].path, ['a','b'])
02915 self.assertEqual(type(t[0][1].value),cms.PSet)
02916 self.assertEqual(t[0][1].value.i.value(), 1)
02917 self.checkRepr(t[0][1], "a.b = cms.PSet(i=cms.int32(1))")
02918 process = cms.Process("Test")
02919 process.a = cms.EDProducer('FooProd', b=cms.PSet(j=cms.uint32(5)))
02920 t[0][1].do(process)
02921 self.assertEqual(process.a.b.i.value(),1)
02922 self.assertEqual(getattr(process.a.b,'j',None),None)
02923
02924
02925 t=replace.parseString('replace a.b = { { int32 i = 1 } }')
02926 self.assertEqual(t[0][0],'a.b')
02927 self.assertEqual(t[0][1].path, ['a','b'])
02928 self.assertEqual(type(t[0][1].value),cms.VPSet)
02929 self.assertEqual(t[0][1].value[0].i.value(), 1)
02930 self.checkRepr(t[0][1], "a.b = cms.VPSet(cms.PSet(i=cms.int32(1)))")
02931 process = cms.Process("Test")
02932 process.a = cms.EDProducer('FooProd', b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02933 t[0][1].do(process)
02934 self.assertEqual(process.a.b[0].i.value(),1)
02935
02936 process = cms.Process("Test")
02937 process.a = cms.EDProducer('FooProd', b=cms.vuint32(2))
02938 t=replace.parseString('replace a.b += 1')
02939 self.assertEqual(t[0][0],'a.b')
02940 self.assertEqual(t[0][1].path, ['a','b'])
02941 self.assertEqual(t[0][1].value,'1')
02942 self.checkRepr(t[0][1], "a.b.append(1)")
02943 t[0][1].do(process)
02944 self.assertEqual(list(process.a.b),[2,1])
02945
02946 process = cms.Process("Test")
02947 process.a = cms.EDProducer('FooProd', b=cms.vuint32(2))
02948 t=replace.parseString('replace a.b += {1,3}')
02949 self.assertEqual(t[0][0],'a.b')
02950 self.assertEqual(t[0][1].path, ['a','b'])
02951 self.assertEqual(t[0][1].value,['1','3'])
02952 self.checkRepr(t[0][1], "a.b.extend([1,3])")
02953 t[0][1].do(process)
02954 self.assertEqual(list(process.a.b),[2,1,3])
02955
02956 t=replace.parseString('replace a.b += "all that"')
02957 self.assertEqual(t[0][0],'a.b')
02958 self.assertEqual(t[0][1].path, ['a','b'])
02959 self.assertEqual(t[0][1].value,'all that')
02960 self.checkRepr(t[0][1], "a.b.append(\'all that\')")
02961 process = cms.Process("Test")
02962 process.a = cms.EDProducer('FooProd', b=cms.vstring('thing'))
02963 t[0][1].do(process)
02964 self.assertEqual(list(process.a.b),['thing','all that'])
02965
02966 t=replace.parseString('replace a.b += {"all that","and more"}')
02967 self.assertEqual(t[0][0],'a.b')
02968 self.assertEqual(t[0][1].path, ['a','b'])
02969 self.assertEqual(t[0][1].value,['all that','and more'])
02970 self.checkRepr(t[0][1], "a.b.extend([\'all that\', \'and more\'])")
02971 process = cms.Process("Test")
02972 process.a = cms.EDProducer('FooProd', b=cms.vstring('thing'))
02973 t[0][1].do(process)
02974 self.assertEqual(list(process.a.b),['thing','all that','and more'])
02975
02976 t=replace.parseString('replace a.b += { int32 i = 1 }')
02977 self.assertEqual(t[0][0],'a.b')
02978 self.assertEqual(t[0][1].path, ['a','b'])
02979 self.assertEqual(type(t[0][1].value),cms.PSet)
02980 self.assertEqual(t[0][1].value.i.value(), 1)
02981 self.checkRepr(t[0][1], "a.b.append(cms.PSet(i=cms.int32(1)))")
02982 process = cms.Process("Test")
02983 process.a = cms.EDProducer('FooProd',
02984 b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02985 t[0][1].do(process)
02986 self.assertEqual(len(process.a.b),2)
02987 self.assertEqual(process.a.b[1].i.value(),1)
02988
02989 t=replace.parseString('replace a.b += { { int32 i = 1 } }')
02990 self.assertEqual(t[0][0],'a.b')
02991 self.assertEqual(t[0][1].path, ['a','b'])
02992 self.assertEqual(type(t[0][1].value),cms.VPSet)
02993 self.assertEqual(t[0][1].value[0].i.value(), 1)
02994 self.checkRepr(t[0][1], "a.b.extend(cms.VPSet(cms.PSet(i=cms.int32(1))))")
02995 process = cms.Process("Test")
02996 process.a = cms.EDProducer('FooProd', b=cms.VPSet((cms.PSet(j=cms.uint32(5)))))
02997 t[0][1].do(process)
02998 self.assertEqual(len(process.a.b),2)
02999 self.assertEqual(process.a.b[1].i.value(),1)
03000
03001 process = cms.Process("Test")
03002 process.a = cms.EDProducer('FooProd', b=cms.vuint32(2), c=cms.vuint32(1))
03003 t=replace.parseString('replace a.b += a.c')
03004 self.assertEqual(t[0][0],'a.b')
03005 self.assertEqual(t[0][1].path, ['a','b'])
03006 self.assertEqual(t[0][1].value,'a.c')
03007 self.checkRepr(t[0][1], "a.b.append(process.a.c)")
03008 t[0][1].do(process)
03009 self.assertEqual(list(process.a.b),[2,1])
03010
03011 process = cms.Process("Test")
03012 process.a = cms.EDProducer('FooProd', b=cms.vuint32(2), c=cms.uint32(1))
03013 t=replace.parseString('replace a.b += a.c')
03014 self.assertEqual(t[0][0],'a.b')
03015 self.assertEqual(t[0][1].path, ['a','b'])
03016 self.assertEqual(t[0][1].value,'a.c')
03017 self.checkRepr(t[0][1], "a.b.append(process.a.c)")
03018 t[0][1].do(process)
03019 self.assertEqual(list(process.a.b),[2,1])
03020
03021 process = cms.Process("Test")
03022 foobar = 'cms.InputTag("foobar","","")'
03023 fooRepr = 'foobar:'
03024 process.a = cms.EDProducer('FooProd', b=cms.InputTag("bar",""))
03025 t = replace.parseString('replace a.b = foobar:')
03026 self.checkRepr(t[0][1], "a.b ='foobar:'")
03027 t[0][1].do(process)
03028 self.assertEqual(process.a.b.configValue(),'foobar')
03029
03030 process = cms.Process("Test")
03031 process.a = cms.EDProducer('FooProd', b=cms.VInputTag((cms.InputTag("bar"))))
03032 t = replace.parseString('replace a.b = {foobar:}')
03033 self.checkRepr(t[0][1], "a.b = ['foobar:']")
03034 t[0][1].do(process)
03035
03036 self.assertEqual(list(process.a.b),[cms.InputTag('foobar')])
03037
03038 process = cms.Process("Test")
03039 process.a = cms.EDProducer('FooProd', b=cms.VInputTag((cms.InputTag("bar"))))
03040 t = replace.parseString('replace a.b += {foobar:}')
03041 self.checkRepr(t[0][1], "a.b.extend(['foobar:'])")
03042 t[0][1].do(process)
03043
03044 self.assertEqual(list(process.a.b),[cms.InputTag("bar"),cms.InputTag('foobar')])
03045
03046 process = cms.Process("Test")
03047 process.a = cms.EDProducer("FooProd", b = cms.uint32(1))
03048 t = replace.parseString('replace a.c = 2')
03049 self.assertRaises(pp.ParseBaseException,t[0][1].do,(process))
03050
03051 unittest.main()
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068