CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ConfigBuilder.py
Go to the documentation of this file.
1 #! /usr/bin/env python
2 
3 __version__ = "$Revision: 1.19 $"
4 __source__ = "$Source: /local/reps/CMSSW/CMSSW/Configuration/Applications/python/ConfigBuilder.py,v $"
5 
6 import FWCore.ParameterSet.Config as cms
7 from FWCore.ParameterSet.Modules import _Module
8 import sys
9 import re
10 import collections
11 from subprocess import Popen,PIPE
12 import FWCore.ParameterSet.DictTypes as DictTypes
13 class Options:
14  pass
15 
16 # the canonical defaults
17 defaultOptions = Options()
18 defaultOptions.datamix = 'DataOnSim'
19 defaultOptions.isMC=False
20 defaultOptions.isData=True
21 defaultOptions.step=''
22 defaultOptions.pileup='NoPileUp'
23 defaultOptions.pileup_input = None
24 defaultOptions.geometry = 'SimDB'
25 defaultOptions.geometryExtendedOptions = ['ExtendedGFlash','Extended','NoCastor']
26 defaultOptions.magField = ''
27 defaultOptions.conditions = None
28 defaultOptions.useCondDBv1 = False
29 defaultOptions.scenarioOptions=['pp','cosmics','nocoll','HeavyIons']
30 defaultOptions.harvesting= 'AtRunEnd'
31 defaultOptions.gflash = False
32 defaultOptions.number = -1
33 defaultOptions.number_out = None
34 defaultOptions.arguments = ""
35 defaultOptions.name = "NO NAME GIVEN"
36 defaultOptions.evt_type = ""
37 defaultOptions.filein = ""
38 defaultOptions.dasquery=""
39 defaultOptions.secondfilein = ""
40 defaultOptions.customisation_file = []
41 defaultOptions.customisation_file_unsch = []
42 defaultOptions.customise_commands = ""
43 defaultOptions.inline_custom=False
44 defaultOptions.particleTable = 'pythiapdt'
45 defaultOptions.particleTableList = ['pythiapdt','pdt']
46 defaultOptions.dirin = ''
47 defaultOptions.dirout = ''
48 defaultOptions.filetype = 'EDM'
49 defaultOptions.fileout = 'output.root'
50 defaultOptions.filtername = ''
51 defaultOptions.lazy_download = False
52 defaultOptions.custom_conditions = ''
53 defaultOptions.hltProcess = ''
54 defaultOptions.eventcontent = None
55 defaultOptions.datatier = None
56 defaultOptions.inlineEventContent = True
57 defaultOptions.inlineObjets =''
58 defaultOptions.hideGen=False
59 from Configuration.StandardSequences.VtxSmeared import VtxSmearedDefaultKey,VtxSmearedHIDefaultKey
60 defaultOptions.beamspot=None
61 defaultOptions.outputDefinition =''
62 defaultOptions.inputCommands = None
63 defaultOptions.outputCommands = None
64 defaultOptions.inputEventContent = ''
65 defaultOptions.dropDescendant = False
66 defaultOptions.relval = None
67 defaultOptions.slhc = None
68 defaultOptions.profile = None
69 defaultOptions.isRepacked = False
70 defaultOptions.restoreRNDSeeds = False
71 defaultOptions.donotDropOnInput = ''
72 defaultOptions.python_filename =''
73 defaultOptions.io=None
74 defaultOptions.lumiToProcess=None
75 defaultOptions.fast=False
76 defaultOptions.runsAndWeightsForMC = None
77 defaultOptions.runsScenarioForMC = None
78 defaultOptions.runUnscheduled = False
79 defaultOptions.timeoutOutput = False
80 defaultOptions.nThreads = '1'
81 
82 # some helper routines
83 def dumpPython(process,name):
84  theObject = getattr(process,name)
85  if isinstance(theObject,cms.Path) or isinstance(theObject,cms.EndPath) or isinstance(theObject,cms.Sequence):
86  return "process."+name+" = " + theObject.dumpPython("process")
87  elif isinstance(theObject,_Module) or isinstance(theObject,cms.ESProducer):
88  return "process."+name+" = " + theObject.dumpPython()+"\n"
89  else:
90  return "process."+name+" = " + theObject.dumpPython()+"\n"
91 def filesFromList(fileName,s=None):
92  import os
93  import FWCore.ParameterSet.Config as cms
94  prim=[]
95  sec=[]
96  for line in open(fileName,'r'):
97  if line.count(".root")>=2:
98  #two files solution...
99  entries=line.replace("\n","").split()
100  if not entries[0] in prim:
101  prim.append(entries[0])
102  if not entries[1] in sec:
103  sec.append(entries[1])
104  elif (line.find(".root")!=-1):
105  entry=line.replace("\n","")
106  if not entry in prim:
107  prim.append(entry)
108  if s:
109  if not hasattr(s,"fileNames"):
110  s.fileNames=cms.untracked.vstring(prim)
111  else:
112  s.fileNames.extend(prim)
113  if len(sec)!=0:
114  if not hasattr(s,"secondaryFileNames"):
115  s.secondaryFileNames=cms.untracked.vstring(sec)
116  else:
117  s.secondaryFileNames.extend(sec)
118  print "found files: ",prim
119  if len(prim)==0:
120  raise Exception("There are not files in input from the file list")
121  if len(sec)!=0:
122  print "found parent files:",sec
123  return (prim,sec)
124 
125 def filesFromDASQuery(query,s=None):
126  import os,time
127  import FWCore.ParameterSet.Config as cms
128  prim=[]
129  sec=[]
130  print "the query is",query
131  eC=5
132  count=0
133  while eC!=0 and count<3:
134  if count!=0:
135  print 'Sleeping, then retrying DAS'
136  time.sleep(100)
137  p = Popen('das_client.py --query "%s"'%(query), stdout=PIPE,shell=True)
138  tupleP = os.waitpid(p.pid, 0)
139  eC=tupleP[1]
140  count=count+1
141  pipe=p.stdout.read()
142  if eC==0:
143  print "DAS succeeded after",count,"attempts",eC
144  else:
145  print "DAS failed 3 times- I give up"
146  for line in pipe.split('\n'):
147  if line.count(".root")>=2:
148  #two files solution...
149  entries=line.replace("\n","").split()
150  if not entries[0] in prim:
151  prim.append(entries[0])
152  if not entries[1] in sec:
153  sec.append(entries[1])
154  elif (line.find(".root")!=-1):
155  entry=line.replace("\n","")
156  if not entry in prim:
157  prim.append(entry)
158  if s:
159  if not hasattr(s,"fileNames"):
160  s.fileNames=cms.untracked.vstring(prim)
161  else:
162  s.fileNames.extend(prim)
163  if len(sec)!=0:
164  if not hasattr(s,"secondaryFileNames"):
165  s.secondaryFileNames=cms.untracked.vstring(sec)
166  else:
167  s.secondaryFileNames.extend(sec)
168  print "found files: ",prim
169  if len(sec)!=0:
170  print "found parent files:",sec
171  return (prim,sec)
172 
173 def MassReplaceInputTag(aProcess,oldT="rawDataCollector",newT="rawDataRepacker"):
174  from PhysicsTools.PatAlgos.tools.helpers import massSearchReplaceAnyInputTag
175  for s in aProcess.paths_().keys():
176  massSearchReplaceAnyInputTag(getattr(aProcess,s),oldT,newT)
177 
178 def anyOf(listOfKeys,dict,opt=None):
179  for k in listOfKeys:
180  if k in dict:
181  toReturn=dict[k]
182  dict.pop(k)
183  return toReturn
184  if opt!=None:
185  return opt
186  else:
187  raise Exception("any of "+','.join(listOfKeys)+" are mandatory entries of --output options")
188 
190  """The main building routines """
191 
192  def __init__(self, options, process = None, with_output = False, with_input = False ):
193  """options taken from old cmsDriver and optparse """
194 
195  options.outfile_name = options.dirout+options.fileout
196 
197  self._options = options
198 
199  if self._options.isData and options.isMC:
200  raise Exception("ERROR: You may specify only --data or --mc, not both")
201  #if not self._options.conditions:
202  # raise Exception("ERROR: No conditions given!\nPlease specify conditions. E.g. via --conditions=IDEAL_30X::All")
203 
204  # check that MEtoEDMConverter (running in ENDJOB) and DQMIO don't run in the same job
205  if 'ENDJOB' in self._options.step:
206  if (hasattr(self._options,"outputDefinition") and \
207  self._options.outputDefinition != '' and \
208  any(anyOf(['t','tier','dataTier'],outdic) == 'DQMIO' for outdic in eval(self._options.outputDefinition))) or \
209  (hasattr(self._options,"datatier") and \
210  self._options.datatier and \
211  'DQMIO' in self._options.datatier):
212  print "removing ENDJOB from steps since not compatible with DQMIO dataTier"
213  self._options.step=self._options.step.replace(',ENDJOB','')
214 
215 
216 
217  # what steps are provided by this class?
218  stepList = [re.sub(r'^prepare_', '', methodName) for methodName in ConfigBuilder.__dict__ if methodName.startswith('prepare_')]
219  self.stepMap={}
220  self.stepKeys=[]
221  for step in self._options.step.split(","):
222  if step=='': continue
223  stepParts = step.split(":")
224  stepName = stepParts[0]
225  if stepName not in stepList and not stepName.startswith('re'):
226  raise ValueError("Step "+stepName+" unknown")
227  if len(stepParts)==1:
228  self.stepMap[stepName]=""
229  elif len(stepParts)==2:
230  self.stepMap[stepName]=stepParts[1].split('+')
231  elif len(stepParts)==3:
232  self.stepMap[stepName]=(stepParts[2].split('+'),stepParts[1])
233  else:
234  raise ValueError("Step definition "+step+" invalid")
235  self.stepKeys.append(stepName)
236 
237  #print "map of steps is:",self.stepMap
238 
239  self.with_output = with_output
240  if hasattr(self._options,"no_output_flag") and self._options.no_output_flag:
241  self.with_output = False
242  self.with_input = with_input
243  if process == None:
244  self.process = cms.Process(self._options.name)
245  else:
246  self.process = process
247  self.imports = []
248  self.importsUnsch = []
249  self.define_Configs()
250  self.schedule = list()
251 
252  # we are doing three things here:
253  # creating a process to catch errors
254  # building the code to re-create the process
255 
256  self.additionalCommands = []
257  # TODO: maybe a list of to be dumped objects would help as well
258  self.blacklist_paths = []
259  self.addedObjects = []
260  self.additionalOutputs = {}
261 
262  self.productionFilterSequence = None
263  self.nextScheduleIsConditional=False
264  self.conditionalPaths=[]
265  self.excludedPaths=[]
266 
267  def profileOptions(self):
268  """
269  addIgProfService
270  Function to add the igprof profile service so that you can dump in the middle
271  of the run.
272  """
273  profileOpts = self._options.profile.split(':')
274  profilerStart = 1
275  profilerInterval = 100
276  profilerFormat = None
277  profilerJobFormat = None
278 
279  if len(profileOpts):
280  #type, given as first argument is unused here
281  profileOpts.pop(0)
282  if len(profileOpts):
283  startEvent = profileOpts.pop(0)
284  if not startEvent.isdigit():
285  raise Exception("%s is not a number" % startEvent)
286  profilerStart = int(startEvent)
287  if len(profileOpts):
288  eventInterval = profileOpts.pop(0)
289  if not eventInterval.isdigit():
290  raise Exception("%s is not a number" % eventInterval)
291  profilerInterval = int(eventInterval)
292  if len(profileOpts):
293  profilerFormat = profileOpts.pop(0)
294 
295 
296  if not profilerFormat:
297  profilerFormat = "%s___%s___%s___%s___%s___%s___%%I.gz" % (self._options.evt_type.replace("_cfi", ""),
298  self._options.step,
299  self._options.pileup,
300  self._options.conditions,
301  self._options.datatier,
302  self._options.profileTypeLabel)
303  if not profilerJobFormat and profilerFormat.endswith(".gz"):
304  profilerJobFormat = profilerFormat.replace(".gz", "_EndOfJob.gz")
305  elif not profilerJobFormat:
306  profilerJobFormat = profilerFormat + "_EndOfJob.gz"
307 
308  return (profilerStart,profilerInterval,profilerFormat,profilerJobFormat)
309 
310  def load(self,includeFile):
311  includeFile = includeFile.replace('/','.')
312  self.process.load(includeFile)
313  return sys.modules[includeFile]
314 
315  def loadAndRemember(self, includeFile,unsch=0):
316  """helper routine to load am memorize imports"""
317  # we could make the imports a on-the-fly data method of the process instance itself
318  # not sure if the latter is a good idea
319  includeFile = includeFile.replace('/','.')
320  if unsch==0:
321  self.imports.append(includeFile)
322  self.process.load(includeFile)
323  return sys.modules[includeFile]
324  else:
325  self.importsUnsch.append(includeFile)
326  return 0#sys.modules[includeFile]
327 
328  def executeAndRemember(self, command):
329  """helper routine to remember replace statements"""
330  self.additionalCommands.append(command)
331  if not command.strip().startswith("#"):
332  # substitute: process.foo = process.bar -> self.process.foo = self.process.bar
333  import re
334  exec(re.sub(r"([^a-zA-Z_0-9]|^)(process)([^a-zA-Z_0-9])",r"\1self.process\3",command))
335  #exec(command.replace("process.","self.process."))
336 
337  def addCommon(self):
338  if 'HARVESTING' in self.stepMap.keys() or 'ALCAHARVEST' in self.stepMap.keys():
339  self.process.options = cms.untracked.PSet( Rethrow = cms.untracked.vstring('ProductNotFound'),fileMode = cms.untracked.string('FULLMERGE'))
340  else:
341  self.process.options = cms.untracked.PSet( )
342 
343  if self._options.runUnscheduled:
344  self.process.options.allowUnscheduled=cms.untracked.bool(True)
345 
346  self.addedObjects.append(("","options"))
347 
348  if self._options.lazy_download:
349  self.process.AdaptorConfig = cms.Service("AdaptorConfig",
350  stats = cms.untracked.bool(True),
351  enable = cms.untracked.bool(True),
352  cacheHint = cms.untracked.string("lazy-download"),
353  readHint = cms.untracked.string("read-ahead-buffered")
354  )
355  self.addedObjects.append(("Setup lazy download","AdaptorConfig"))
356 
357  #self.process.cmsDriverCommand = cms.untracked.PSet( command=cms.untracked.string('cmsDriver.py '+self._options.arguments) )
358  #self.addedObjects.append(("what cmsDriver command was used","cmsDriverCommand"))
359 
360  if self._options.profile:
361  (start, interval, eventFormat, jobFormat)=self.profileOptions()
362  self.process.IgProfService = cms.Service("IgProfService",
363  reportFirstEvent = cms.untracked.int32(start),
364  reportEventInterval = cms.untracked.int32(interval),
365  reportToFileAtPostEvent = cms.untracked.string("| gzip -c > %s"%(eventFormat)),
366  reportToFileAtPostEndJob = cms.untracked.string("| gzip -c > %s"%(jobFormat)))
367  self.addedObjects.append(("Setup IGProf Service for profiling","IgProfService"))
368 
369  def addMaxEvents(self):
370  """Here we decide how many evts will be processed"""
371  self.process.maxEvents=cms.untracked.PSet(input=cms.untracked.int32(int(self._options.number)))
372  if self._options.number_out:
373  self.process.maxEvents.output = cms.untracked.int32(int(self._options.number_out))
374  self.addedObjects.append(("","maxEvents"))
375 
376  def addSource(self):
377  """Here the source is built. Priority: file, generator"""
378  self.addedObjects.append(("Input source","source"))
379 
380  def filesFromOption(self):
381  for entry in self._options.filein.split(','):
382  print "entry",entry
383  if entry.startswith("filelist:"):
384  filesFromList(entry[9:],self.process.source)
385  elif entry.startswith("dbs:") or entry.startswith("das:"):
386  filesFromDASQuery('file dataset = %s'%(entry[4:]),self.process.source)
387  else:
388  self.process.source.fileNames.append(self._options.dirin+entry)
389  if self._options.secondfilein:
390  if not hasattr(self.process.source,"secondaryFileNames"):
391  raise Exception("--secondfilein not compatible with "+self._options.filetype+"input type")
392  for entry in self._options.secondfilein.split(','):
393  print "entry",entry
394  if entry.startswith("filelist:"):
395  self.process.source.secondaryFileNames.extend((filesFromList(entry[9:]))[0])
396  elif entry.startswith("dbs:") or entry.startswith("das:"):
397  self.process.source.secondaryFileNames.extend((filesFromDASQuery('file dataset = %s'%(entry[4:])))[0])
398  else:
399  self.process.source.secondaryFileNames.append(self._options.dirin+entry)
400 
401  if self._options.filein or self._options.dasquery:
402  if self._options.filetype == "EDM":
403  self.process.source=cms.Source("PoolSource",
404  fileNames = cms.untracked.vstring(),
405  secondaryFileNames= cms.untracked.vstring())
406  filesFromOption(self)
407  elif self._options.filetype == "DAT":
408  self.process.source=cms.Source("NewEventStreamFileReader",fileNames = cms.untracked.vstring())
409  filesFromOption(self)
410  elif self._options.filetype == "LHE":
411  self.process.source=cms.Source("LHESource", fileNames = cms.untracked.vstring())
412  if self._options.filein.startswith("lhe:"):
413  #list the article directory automatically
414  args=self._options.filein.split(':')
415  article=args[1]
416  print 'LHE input from article ',article
417  location='/store/lhe/'
418  import os
419  textOfFiles=os.popen('cmsLHEtoEOSManager.py -l '+article)
420  for line in textOfFiles:
421  for fileName in [x for x in line.split() if '.lhe' in x]:
422  self.process.source.fileNames.append(location+article+'/'+fileName)
423  if len(args)>2:
424  self.process.source.skipEvents = cms.untracked.uint32(int(args[2]))
425  else:
426  filesFromOption(self)
427 
428 
429  elif self._options.filetype == "DQM":
430  self.process.source=cms.Source("DQMRootSource",
431  fileNames = cms.untracked.vstring())
432  filesFromOption(self)
433 
434  elif self._options.filetype == "DQMDAQ":
435  # FIXME: how to configure it if there are no input files specified?
436  self.process.source=cms.Source("DQMStreamerReader")
437 
438 
439  if ('HARVESTING' in self.stepMap.keys() or 'ALCAHARVEST' in self.stepMap.keys()) and (not self._options.filetype == "DQM"):
440  self.process.source.processingMode = cms.untracked.string("RunsAndLumis")
441 
442  if self._options.dasquery!='':
443  self.process.source=cms.Source("PoolSource", fileNames = cms.untracked.vstring(),secondaryFileNames = cms.untracked.vstring())
444  filesFromDASQuery(self._options.dasquery,self.process.source)
445 
446  ##drop LHEXMLStringProduct on input to save memory if appropriate
447  if 'GEN' in self.stepMap.keys():
448  if self._options.inputCommands:
449  self._options.inputCommands+=',drop LHEXMLStringProduct_*_*_*,'
450  else:
451  self._options.inputCommands='keep *, drop LHEXMLStringProduct_*_*_*,'
452 
453  if self.process.source and self._options.inputCommands:
454  if not hasattr(self.process.source,'inputCommands'): self.process.source.inputCommands=cms.untracked.vstring()
455  for command in self._options.inputCommands.split(','):
456  # remove whitespace around the keep/drop statements
457  command = command.strip()
458  if command=='': continue
459  self.process.source.inputCommands.append(command)
460  if not self._options.dropDescendant:
461  self.process.source.dropDescendantsOfDroppedBranches = cms.untracked.bool(False)
462 
463  if self._options.lumiToProcess:
464  import FWCore.PythonUtilities.LumiList as LumiList
465  self.process.source.lumisToProcess = cms.untracked.VLuminosityBlockRange( LumiList.LumiList(self._options.lumiToProcess).getCMSSWString().split(',') )
466 
467  if 'GEN' in self.stepMap.keys() or 'LHE' in self.stepMap or (not self._options.filein and hasattr(self._options, "evt_type")):
468  if self.process.source is None:
469  self.process.source=cms.Source("EmptySource")
470 
471  # modify source in case of run-dependent MC
472  self.runsAndWeights=None
473  if self._options.runsAndWeightsForMC or self._options.runsScenarioForMC :
474  if not self._options.isMC :
475  raise Exception("options --runsAndWeightsForMC and --runsScenarioForMC are only valid for MC")
476  if self._options.runsAndWeightsForMC:
477  self.runsAndWeights = eval(self._options.runsAndWeightsForMC)
478  else:
479  from Configuration.StandardSequences.RunsAndWeights import RunsAndWeights
480  if type(RunsAndWeights[self._options.runsScenarioForMC])==str:
481  __import__(RunsAndWeights[self._options.runsScenarioForMC])
482  self.runsAndWeights = sys.modules[RunsAndWeights[self._options.runsScenarioForMC]].runProbabilityDistribution
483  else:
484  self.runsAndWeights = RunsAndWeights[self._options.runsScenarioForMC]
485 
486  if self.runsAndWeights:
487  import SimGeneral.Configuration.ThrowAndSetRandomRun as ThrowAndSetRandomRun
488  ThrowAndSetRandomRun.throwAndSetRandomRun(self.process.source,self.runsAndWeights)
489  self.additionalCommands.append('import SimGeneral.Configuration.ThrowAndSetRandomRun as ThrowAndSetRandomRun')
490  self.additionalCommands.append('ThrowAndSetRandomRun.throwAndSetRandomRun(process.source,%s)'%(self.runsAndWeights))
491 
492  return
493 
494  def addOutput(self):
495  """ Add output module to the process """
496  result=""
497  if self._options.outputDefinition:
498  if self._options.datatier:
499  print "--datatier & --eventcontent options ignored"
500 
501  #new output convention with a list of dict
502  outList = eval(self._options.outputDefinition)
503  for (id,outDefDict) in enumerate(outList):
504  outDefDictStr=outDefDict.__str__()
505  if not isinstance(outDefDict,dict):
506  raise Exception("--output needs to be passed a list of dict"+self._options.outputDefinition+" is invalid")
507  #requires option: tier
508  theTier=anyOf(['t','tier','dataTier'],outDefDict)
509  #optional option: eventcontent, filtername, selectEvents, moduleLabel, filename
510  ## event content
511  theStreamType=anyOf(['e','ec','eventContent','streamType'],outDefDict,theTier)
512  theFilterName=anyOf(['f','ftN','filterName'],outDefDict,'')
513  theSelectEvent=anyOf(['s','sE','selectEvents'],outDefDict,'')
514  theModuleLabel=anyOf(['l','mL','moduleLabel'],outDefDict,'')
515  theExtraOutputCommands=anyOf(['o','oC','outputCommands'],outDefDict,'')
516  # module label has a particular role
517  if not theModuleLabel:
518  tryNames=[theStreamType.replace(theTier.replace('-',''),'')+theTier.replace('-','')+'output',
519  theStreamType.replace(theTier.replace('-',''),'')+theTier.replace('-','')+theFilterName+'output',
520  theStreamType.replace(theTier.replace('-',''),'')+theTier.replace('-','')+theFilterName+theSelectEvent.split(',')[0].replace(':','for').replace(' ','')+'output'
521  ]
522  for name in tryNames:
523  if not hasattr(self.process,name):
524  theModuleLabel=name
525  break
526  if not theModuleLabel:
527  raise Exception("cannot find a module label for specification: "+outDefDictStr)
528  if id==0:
529  defaultFileName=self._options.outfile_name
530  else:
531  defaultFileName=self._options.outfile_name.replace('.root','_in'+theTier+'.root')
532 
533  theFileName=self._options.dirout+anyOf(['fn','fileName'],outDefDict,defaultFileName)
534  if not theFileName.endswith('.root'):
535  theFileName+='.root'
536 
537  if len(outDefDict.keys()):
538  raise Exception("unused keys from --output options: "+','.join(outDefDict.keys()))
539  if theStreamType=='DQMIO': theStreamType='DQM'
540  if theStreamType=='ALL':
541  theEventContent = cms.PSet(outputCommands = cms.untracked.vstring('keep *'))
542  else:
543  theEventContent = getattr(self.process, theStreamType+"EventContent")
544 
545 
546  addAlCaSelects=False
547  if theStreamType=='ALCARECO' and not theFilterName:
548  theFilterName='StreamALCACombined'
549  addAlCaSelects=True
550 
551  CppType='PoolOutputModule'
552  if self._options.timeoutOutput:
553  CppType='TimeoutPoolOutputModule'
554  if theStreamType=='DQM' and theTier=='DQMIO': CppType='DQMRootOutputModule'
555  output = cms.OutputModule(CppType,
556  theEventContent.clone(),
557  fileName = cms.untracked.string(theFileName),
558  dataset = cms.untracked.PSet(
559  dataTier = cms.untracked.string(theTier),
560  filterName = cms.untracked.string(theFilterName))
561  )
562  if not theSelectEvent and hasattr(self.process,'generation_step') and theStreamType!='LHE':
563  output.SelectEvents = cms.untracked.PSet(SelectEvents = cms.vstring('generation_step'))
564  if not theSelectEvent and hasattr(self.process,'filtering_step'):
565  output.SelectEvents = cms.untracked.PSet(SelectEvents = cms.vstring('filtering_step'))
566  if theSelectEvent:
567  output.SelectEvents =cms.untracked.PSet(SelectEvents = cms.vstring(theSelectEvent))
568 
569  if addAlCaSelects:
570  if not hasattr(output,'SelectEvents'):
571  output.SelectEvents=cms.untracked.PSet(SelectEvents=cms.vstring())
572  for alca in self.AlCaPaths:
573  output.SelectEvents.SelectEvents.extend(getattr(self.process,'OutALCARECO'+alca).SelectEvents.SelectEvents)
574 
575 
576  if hasattr(self.process,theModuleLabel):
577  raise Exception("the current process already has a module "+theModuleLabel+" defined")
578  #print "creating output module ",theModuleLabel
579  setattr(self.process,theModuleLabel,output)
580  outputModule=getattr(self.process,theModuleLabel)
581  setattr(self.process,theModuleLabel+'_step',cms.EndPath(outputModule))
582  path=getattr(self.process,theModuleLabel+'_step')
583  self.schedule.append(path)
584 
585  if not self._options.inlineEventContent and hasattr(self.process,theStreamType+"EventContent"):
586  def doNotInlineEventContent(instance,label = "cms.untracked.vstring(process."+theStreamType+"EventContent.outputCommands)"):
587  return label
588  outputModule.outputCommands.__dict__["dumpPython"] = doNotInlineEventContent
589  if theExtraOutputCommands:
590  if not isinstance(theExtraOutputCommands,list):
591  raise Exception("extra ouput command in --option must be a list of strings")
592  if hasattr(self.process,theStreamType+"EventContent"):
593  self.executeAndRemember('process.%s.outputCommands.extend(%s)'%(theModuleLabel,theExtraOutputCommands))
594  else:
595  outputModule.outputCommands.extend(theExtraOutputCommands)
596 
597  result+="\nprocess."+theModuleLabel+" = "+outputModule.dumpPython()
598 
599  ##ends the --output options model
600  return result
601 
602  streamTypes=self._options.eventcontent.split(',')
603  tiers=self._options.datatier.split(',')
604  if not self._options.outputDefinition and len(streamTypes)!=len(tiers):
605  raise Exception("number of event content arguments does not match number of datatier arguments")
606 
607  # if the only step is alca we don't need to put in an output
608  if self._options.step.split(',')[0].split(':')[0] == 'ALCA':
609  return "\n"
610 
611  for i,(streamType,tier) in enumerate(zip(streamTypes,tiers)):
612  if streamType=='': continue
613  if streamType=='DQMIO': streamType='DQM'
614  theEventContent = getattr(self.process, streamType+"EventContent")
615  if i==0:
616  theFileName=self._options.outfile_name
617  theFilterName=self._options.filtername
618  else:
619  theFileName=self._options.outfile_name.replace('.root','_in'+streamType+'.root')
620  theFilterName=self._options.filtername
621  CppType='PoolOutputModule'
622  if self._options.timeoutOutput:
623  CppType='TimeoutPoolOutputModule'
624  if streamType=='DQM' and tier=='DQMIO': CppType='DQMRootOutputModule'
625  output = cms.OutputModule(CppType,
626  theEventContent,
627  fileName = cms.untracked.string(theFileName),
628  dataset = cms.untracked.PSet(dataTier = cms.untracked.string(tier),
629  filterName = cms.untracked.string(theFilterName)
630  )
631  )
632  if hasattr(self.process,"generation_step") and streamType!='LHE':
633  output.SelectEvents = cms.untracked.PSet(SelectEvents = cms.vstring('generation_step'))
634  if hasattr(self.process,"filtering_step"):
635  output.SelectEvents = cms.untracked.PSet(SelectEvents = cms.vstring('filtering_step'))
636 
637  if streamType=='ALCARECO':
638  output.dataset.filterName = cms.untracked.string('StreamALCACombined')
639 
640  if "MINIAOD" in streamType:
641  output.dropMetaData = cms.untracked.string('ALL')
642  output.fastCloning= cms.untracked.bool(False)
643  output.overrideInputFileSplitLevels = cms.untracked.bool(True)
644 
645  outputModuleName=streamType+'output'
646  setattr(self.process,outputModuleName,output)
647  outputModule=getattr(self.process,outputModuleName)
648  setattr(self.process,outputModuleName+'_step',cms.EndPath(outputModule))
649  path=getattr(self.process,outputModuleName+'_step')
650  self.schedule.append(path)
651 
652  if self._options.outputCommands and streamType!='DQM':
653  for evct in self._options.outputCommands.split(','):
654  if not evct: continue
655  self.executeAndRemember("process.%s.outputCommands.append('%s')"%(outputModuleName,evct.strip()))
656 
657  if not self._options.inlineEventContent:
658  def doNotInlineEventContent(instance,label = "process."+streamType+"EventContent.outputCommands"):
659  return label
660  outputModule.outputCommands.__dict__["dumpPython"] = doNotInlineEventContent
661 
662  result+="\nprocess."+outputModuleName+" = "+outputModule.dumpPython()
663 
664  return result
665 
667  """
668  Add selected standard sequences to the process
669  """
670  # load the pile up file
671  if self._options.pileup:
672  pileupSpec=self._options.pileup.split(',')[0]
673 
674  # FastSim: GEN-mixing or DIGI-RECO mixing?
675  GEN_mixing = False
676  if self._options.fast and pileupSpec.find("GEN_") == 0:
677  GEN_mixing = True
678  pileupSpec = pileupSpec[4:]
679 
680  # Does the requested pile-up scenario exist?
681  from Configuration.StandardSequences.Mixing import Mixing,defineMixing
682  if not pileupSpec in Mixing and '.' not in pileupSpec and 'file:' not in pileupSpec:
683  message = pileupSpec+' is not a know mixing scenario:\n available are: '+'\n'.join(Mixing.keys())
684  if self._options.fast:
685  message += "\n-"*20+"\n additional options for FastSim (gen-mixing):\n" + "-"*20 + "\n" + '\n'.join(["GEN_" + x for x in Mixing.keys()]) + "\n"
686  raise Exception(message)
687 
688  # Put mixing parameters in a dictionary
689  if '.' in pileupSpec:
690  mixingDict={'file':pileupSpec}
691  elif pileupSpec.startswith('file:'):
692  mixingDict={'file':pileupSpec[5:]}
693  else:
694  import copy
695  mixingDict=copy.copy(Mixing[pileupSpec])
696  if len(self._options.pileup.split(','))>1:
697  mixingDict.update(eval(self._options.pileup[self._options.pileup.find(',')+1:]))
698 
699  # Load the pu cfg file corresponding to the requested pu scenario
700  if 'file:' in pileupSpec:
701  #the file is local
702  self.process.load(mixingDict['file'])
703  print "inlining mixing module configuration"
704  self._options.inlineObjets+=',mix'
705  else:
706  self.loadAndRemember(mixingDict['file'])
707 
708  # FastSim: transform cfg of MixingModule from FullSim to FastSim
709  if self._options.fast:
710  if GEN_mixing:
711  self._options.customisation_file.insert(0,"FastSimulation/Configuration/MixingModule_Full2Fast.prepareGenMixing")
712  else:
713  self._options.customisation_file.insert(0,"FastSimulation/Configuration/MixingModule_Full2Fast.prepareDigiRecoMixing")
714 
715  mixingDict.pop('file')
716  if not "DATAMIX" in self.stepMap.keys(): # when DATAMIX is present, pileup_input refers to pre-mixed GEN-RAW
717  if self._options.pileup_input:
718  if self._options.pileup_input.startswith('dbs:') or self._options.pileup_input.startswith('das:'):
719  mixingDict['F']=filesFromDASQuery('file dataset = %s'%(self._options.pileup_input[4:],))[0]
720  else:
721  mixingDict['F']=self._options.pileup_input.split(',')
722  specialization=defineMixing(mixingDict)
723  for command in specialization:
724  self.executeAndRemember(command)
725  if len(mixingDict)!=0:
726  raise Exception('unused mixing specification: '+mixingDict.keys().__str__())
727 
728 
729  # load the geometry file
730  try:
731  if len(self.stepMap):
732  self.loadAndRemember(self.GeometryCFF)
733  if ('SIM' in self.stepMap or 'reSIM' in self.stepMap) and not self._options.fast:
734  self.loadAndRemember(self.SimGeometryCFF)
735  if self.geometryDBLabel:
736  self.executeAndRemember('process.XMLFromDBSource.label = cms.string("%s")'%(self.geometryDBLabel))
737  except ImportError:
738  print "Geometry option",self._options.geometry,"unknown."
739  raise
740 
741  if len(self.stepMap):
742  self.loadAndRemember(self.magFieldCFF)
743 
744  for stepName in self.stepKeys:
745  stepSpec = self.stepMap[stepName]
746  print "Step:", stepName,"Spec:",stepSpec
747  if stepName.startswith('re'):
748  ##add the corresponding input content
749  if stepName[2:] not in self._options.donotDropOnInput:
750  self._options.inputEventContent='%s,%s'%(stepName.upper(),self._options.inputEventContent)
751  stepName=stepName[2:]
752  if stepSpec=="":
753  getattr(self,"prepare_"+stepName)(sequence = getattr(self,stepName+"DefaultSeq"))
754  elif type(stepSpec)==list:
755  getattr(self,"prepare_"+stepName)(sequence = '+'.join(stepSpec))
756  elif type(stepSpec)==tuple:
757  getattr(self,"prepare_"+stepName)(sequence = ','.join([stepSpec[1],'+'.join(stepSpec[0])]))
758  else:
759  raise ValueError("Invalid step definition")
760 
761  if self._options.restoreRNDSeeds!=False:
762  #it is either True, or a process name
763  if self._options.restoreRNDSeeds==True:
764  self.executeAndRemember('process.RandomNumberGeneratorService.restoreStateLabel=cms.untracked.string("randomEngineStateProducer")')
765  else:
766  self.executeAndRemember('process.RandomNumberGeneratorService.restoreStateTag=cms.untracked.InputTag("randomEngineStateProducer","","%s")'%(self._options.restoreRNDSeeds))
767  if self._options.inputEventContent or self._options.inputCommands:
768  if self._options.inputCommands:
769  self._options.inputCommands+='keep *_randomEngineStateProducer_*_*,'
770  else:
771  self._options.inputCommands='keep *_randomEngineStateProducer_*_*,'
772 
773 
775  if self._options.inputEventContent:
776  import copy
777  def dropSecondDropStar(iec):
778  #drop occurence of 'drop *' in the list
779  count=0
780  for item in iec:
781  if item=='drop *':
782  if count!=0:
783  iec.remove(item)
784  count+=1
785 
786 
787  ## allow comma separated input eventcontent
788  if not hasattr(self.process.source,'inputCommands'): self.process.source.inputCommands=cms.untracked.vstring()
789  for evct in self._options.inputEventContent.split(','):
790  if evct=='': continue
791  theEventContent = getattr(self.process, evct+"EventContent")
792  if hasattr(theEventContent,'outputCommands'):
793  self.process.source.inputCommands.extend(copy.copy(theEventContent.outputCommands))
794  if hasattr(theEventContent,'inputCommands'):
795  self.process.source.inputCommands.extend(copy.copy(theEventContent.inputCommands))
796 
797  dropSecondDropStar(self.process.source.inputCommands)
798 
799  if not self._options.dropDescendant:
800  self.process.source.dropDescendantsOfDroppedBranches = cms.untracked.bool(False)
801 
802 
803  return
804 
805  def addConditions(self):
806  """Add conditions to the process"""
807  if not self._options.conditions: return
808 
809  if 'FrontierConditions_GlobalTag' in self._options.conditions:
810  print 'using FrontierConditions_GlobalTag in --conditions is not necessary anymore and will be deprecated soon. please update your command line'
811  self._options.conditions = self._options.conditions.replace("FrontierConditions_GlobalTag,",'')
812 
813  self.loadAndRemember(self.ConditionsDefaultCFF)
814 
815  if self._options.useCondDBv1:
816  from Configuration.AlCa.GlobalTag_condDBv1 import GlobalTag
817  else:
818  from Configuration.AlCa.GlobalTag import GlobalTag
819 
820  self.process.GlobalTag = GlobalTag(self.process.GlobalTag, self._options.conditions, self._options.custom_conditions)
821 
822  if self._options.useCondDBv1:
823  self.additionalCommands.append('from Configuration.AlCa.GlobalTag_condDBv1 import GlobalTag')
824  else:
825  self.additionalCommands.append('from Configuration.AlCa.GlobalTag import GlobalTag')
826 
827  self.additionalCommands.append('process.GlobalTag = GlobalTag(process.GlobalTag, %s, %s)' % (repr(self._options.conditions), repr(self._options.custom_conditions)))
828 
829  if self._options.slhc:
830  self.loadAndRemember("SLHCUpgradeSimulations/Geometry/fakeConditions_%s_cff"%(self._options.slhc,))
831 
832 
833  def addCustomise(self,unsch=0):
834  """Include the customise code """
835 
836  custOpt=[]
837  if unsch==0:
838  for c in self._options.customisation_file:
839  custOpt.extend(c.split(","))
840  else:
841  for c in self._options.customisation_file_unsch:
842  custOpt.extend(c.split(","))
843 
845  for opt in custOpt:
846  if opt=='': continue
847  if opt.count('.')>1:
848  raise Exception("more than . in the specification:"+opt)
849  fileName=opt.split('.')[0]
850  if opt.count('.')==0: rest='customise'
851  else:
852  rest=opt.split('.')[1]
853  if rest=='py': rest='customise' #catch the case of --customise file.py
854 
855  if fileName in custMap:
856  custMap[fileName].extend(rest.split('+'))
857  else:
858  custMap[fileName]=rest.split('+')
859 
860  if len(custMap)==0:
861  final_snippet='\n'
862  else:
863  final_snippet='\n# customisation of the process.\n'
864 
865  allFcn=[]
866  for opt in custMap:
867  allFcn.extend(custMap[opt])
868  for fcn in allFcn:
869  if allFcn.count(fcn)!=1:
870  raise Exception("cannot specify twice "+fcn+" as a customisation method")
871 
872  for f in custMap:
873  # let python search for that package and do syntax checking at the same time
874  packageName = f.replace(".py","").replace("/",".")
875  __import__(packageName)
876  package = sys.modules[packageName]
877 
878  # now ask the package for its definition and pick .py instead of .pyc
879  customiseFile = re.sub(r'\.pyc$', '.py', package.__file__)
880 
881  final_snippet+='\n# Automatic addition of the customisation function from '+packageName+'\n'
882  if self._options.inline_custom:
883  for line in file(customiseFile,'r'):
884  if "import FWCore.ParameterSet.Config" in line:
885  continue
886  final_snippet += line
887  else:
888  final_snippet += 'from %s import %s \n'%(packageName,','.join(custMap[f]))
889  for fcn in custMap[f]:
890  print "customising the process with",fcn,"from",f
891  if not hasattr(package,fcn):
892  #bound to fail at run time
893  raise Exception("config "+f+" has no function "+fcn)
894  #execute the command
895  self.process=getattr(package,fcn)(self.process)
896  #and print it in the configuration
897  final_snippet += "\n#call to customisation function "+fcn+" imported from "+packageName
898  final_snippet += "\nprocess = %s(process)\n"%(fcn,)
899 
900  if len(custMap)!=0:
901  final_snippet += '\n# End of customisation functions\n'
902 
903  ### now for a useful command
904  if unsch==1 or not self._options.runUnscheduled:
905  if self._options.customise_commands:
906  import string
907  final_snippet +='\n# Customisation from command line'
908  for com in self._options.customise_commands.split('\\n'):
909  com=string.lstrip(com)
910  self.executeAndRemember(com)
911  final_snippet +='\n'+com
912 
913  return final_snippet
914 
915  #----------------------------------------------------------------------------
916  # here the methods to define the python includes for each step or
917  # conditions
918  #----------------------------------------------------------------------------
919  def define_Configs(self):
920  if len(self.stepMap):
921  self.loadAndRemember('Configuration/StandardSequences/Services_cff')
922  if self._options.particleTable not in defaultOptions.particleTableList:
923  print 'Invalid particle table provided. Options are:'
924  print defaultOptions.particleTable
925  sys.exit(-1)
926  else:
927  if len(self.stepMap):
928  self.loadAndRemember('SimGeneral.HepPDTESSource.'+self._options.particleTable+'_cfi')
929 
930  self.loadAndRemember('FWCore/MessageService/MessageLogger_cfi')
931 
932  self.ALCADefaultCFF="Configuration/StandardSequences/AlCaRecoStreams_cff"
933  self.GENDefaultCFF="Configuration/StandardSequences/Generator_cff"
934  self.SIMDefaultCFF="Configuration/StandardSequences/Sim_cff"
935  self.DIGIDefaultCFF="Configuration/StandardSequences/Digi_cff"
936  self.DIGI2RAWDefaultCFF="Configuration/StandardSequences/DigiToRaw_cff"
937  self.L1EMDefaultCFF='Configuration/StandardSequences/SimL1Emulator_cff'
938  self.L1MENUDefaultCFF="Configuration/StandardSequences/L1TriggerDefaultMenu_cff"
939  self.HLTDefaultCFF="Configuration/StandardSequences/HLTtable_cff"
940  self.RAW2DIGIDefaultCFF="Configuration/StandardSequences/RawToDigi_Data_cff"
941  self.L1RecoDefaultCFF="Configuration/StandardSequences/L1Reco_cff"
942  self.L1TrackTriggerDefaultCFF="Configuration/StandardSequences/L1TrackTrigger_cff"
943  self.RECODefaultCFF="Configuration/StandardSequences/Reconstruction_Data_cff"
944  self.PATDefaultCFF="Configuration/StandardSequences/PAT_cff"
945  self.EIDefaultCFF=None
946  self.SKIMDefaultCFF="Configuration/StandardSequences/Skims_cff"
947  self.POSTRECODefaultCFF="Configuration/StandardSequences/PostRecoGenerator_cff"
948  self.VALIDATIONDefaultCFF="Configuration/StandardSequences/Validation_cff"
949  self.L1HwValDefaultCFF = "Configuration/StandardSequences/L1HwVal_cff"
950  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOffline_cff"
951  self.HARVESTINGDefaultCFF="Configuration/StandardSequences/Harvesting_cff"
952  self.ALCAHARVESTDefaultCFF="Configuration/StandardSequences/AlCaHarvesting_cff"
953  self.ENDJOBDefaultCFF="Configuration/StandardSequences/EndOfProcess_cff"
954  if self._options.useCondDBv1:
955  self.ConditionsDefaultCFF = "Configuration/StandardSequences/FrontierConditions_GlobalTag_condDBv1_cff"
956  else:
957  self.ConditionsDefaultCFF = "Configuration/StandardSequences/FrontierConditions_GlobalTag_cff"
958  self.CFWRITERDefaultCFF = "Configuration/StandardSequences/CrossingFrameWriter_cff"
959  self.REPACKDefaultCFF="Configuration/StandardSequences/DigiToRaw_Repack_cff"
960 
961  if "DATAMIX" in self.stepMap.keys():
962  self.DATAMIXDefaultCFF="Configuration/StandardSequences/DataMixer"+self._options.datamix+"_cff"
963  if self._options.datamix == 'PreMix':
964  self.DIGIDefaultCFF="Configuration/StandardSequences/DigiDMPreMix_cff"
965  else:
966  self.DIGIDefaultCFF="Configuration/StandardSequences/DigiDM_cff"
967  self.DIGI2RAWDefaultCFF="Configuration/StandardSequences/DigiToRawDM_cff"
968  self.L1EMDefaultCFF='Configuration/StandardSequences/SimL1EmulatorDM_cff'
969 
970  if "DIGIPREMIX" in self.stepMap.keys():
971  self.DIGIDefaultCFF="Configuration/StandardSequences/Digi_PreMix_cff"
972 
973  self.ALCADefaultSeq=None
974  self.LHEDefaultSeq='externalLHEProducer'
975  self.GENDefaultSeq='pgen'
976  self.SIMDefaultSeq='psim'
977  self.DIGIDefaultSeq='pdigi'
978  self.DIGIPREMIXDefaultSeq='pdigi'
979  self.DIGIPREMIX_S2DefaultSeq='pdigi'
980  self.DATAMIXDefaultSeq=None
981  self.DIGI2RAWDefaultSeq='DigiToRaw'
982  self.HLTDefaultSeq='GRun'
983  self.L1DefaultSeq=None
984  self.L1REPACKDefaultSeq='GT'
985  self.HARVESTINGDefaultSeq=None
986  self.ALCAHARVESTDefaultSeq=None
987  self.CFWRITERDefaultSeq=None
988  self.RAW2DIGIDefaultSeq='RawToDigi'
989  self.L1RecoDefaultSeq='L1Reco'
990  self.L1TrackTriggerDefaultSeq='L1TrackTrigger'
991  if 'RAW2DIGI' in self.stepMap and 'RECO' in self.stepMap:
992  self.RECODefaultSeq='reconstruction'
993  else:
994  self.RECODefaultSeq='reconstruction_fromRECO'
995 
996  self.EIDefaultSeq='top'
997  self.POSTRECODefaultSeq=None
998  self.L1HwValDefaultSeq='L1HwVal'
999  self.DQMDefaultSeq='DQMOffline'
1000  self.VALIDATIONDefaultSeq=''
1001  self.ENDJOBDefaultSeq='endOfProcess'
1002  self.REPACKDefaultSeq='DigiToRawRepack'
1003  self.PATDefaultSeq='miniAOD'
1004 
1005  self.EVTCONTDefaultCFF="Configuration/EventContent/EventContent_cff"
1006 
1007  if not self._options.beamspot:
1008  self._options.beamspot=VtxSmearedDefaultKey
1009 
1010  # if its MC then change the raw2digi
1011  if self._options.isMC==True:
1012  self.RAW2DIGIDefaultCFF="Configuration/StandardSequences/RawToDigi_cff"
1013  self.RECODefaultCFF="Configuration/StandardSequences/Reconstruction_cff"
1014  self.PATDefaultCFF="Configuration/StandardSequences/PATMC_cff"
1015  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOfflineMC_cff"
1016  self.ALCADefaultCFF="Configuration/StandardSequences/AlCaRecoStreamsMC_cff"
1017  else:
1018  self._options.beamspot = None
1019 
1020  #patch for gen, due to backward incompatibility
1021  if 'reGEN' in self.stepMap:
1022  self.GENDefaultSeq='fixGenInfo'
1023 
1024  if self._options.scenario=='cosmics':
1025  self._options.pileup='Cosmics'
1026  self.DIGIDefaultCFF="Configuration/StandardSequences/DigiCosmics_cff"
1027  self.RECODefaultCFF="Configuration/StandardSequences/ReconstructionCosmics_cff"
1028  self.SKIMDefaultCFF="Configuration/StandardSequences/SkimsCosmics_cff"
1029  self.EVTCONTDefaultCFF="Configuration/EventContent/EventContentCosmics_cff"
1030  self.VALIDATIONDefaultCFF="Configuration/StandardSequences/ValidationCosmics_cff"
1031  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOfflineCosmics_cff"
1032  if self._options.isMC==True:
1033  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOfflineCosmicsMC_cff"
1034  self.HARVESTINGDefaultCFF="Configuration/StandardSequences/HarvestingCosmics_cff"
1035  self.RECODefaultSeq='reconstructionCosmics'
1036  self.DQMDefaultSeq='DQMOfflineCosmics'
1037 
1038  if self._options.scenario=='HeavyIons':
1039  if not self._options.beamspot:
1040  self._options.beamspot=VtxSmearedHIDefaultKey
1041  self.HLTDefaultSeq = 'HIon'
1042  self.VALIDATIONDefaultCFF="Configuration/StandardSequences/ValidationHeavyIons_cff"
1043  self.VALIDATIONDefaultSeq=''
1044  self.EVTCONTDefaultCFF="Configuration/EventContent/EventContentHeavyIons_cff"
1045  self.RECODefaultCFF="Configuration/StandardSequences/ReconstructionHeavyIons_cff"
1046  self.RECODefaultSeq='reconstructionHeavyIons'
1047  self.ALCADefaultCFF = "Configuration/StandardSequences/AlCaRecoStreamsHeavyIons_cff"
1048  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOfflineHeavyIons_cff"
1049  self.DQMDefaultSeq='DQMOfflineHeavyIons'
1050  self.SKIMDefaultCFF="Configuration/StandardSequences/SkimsHeavyIons_cff"
1051  self.HARVESTINGDefaultCFF="Configuration/StandardSequences/HarvestingHeavyIons_cff"
1052  if self._options.isMC==True:
1053  self.DQMOFFLINEDefaultCFF="DQMOffline/Configuration/DQMOfflineHeavyIonsMC_cff"
1054 
1055 
1056  self.RAW2RECODefaultSeq=','.join([self.RAW2DIGIDefaultSeq,self.RECODefaultSeq])
1057 
1058  self.USERDefaultSeq='user'
1059  self.USERDefaultCFF=None
1060 
1061  # the magnetic field
1062  if self._options.isData:
1063  if self._options.magField==defaultOptions.magField:
1064  print "magnetic field option forced to: AutoFromDBCurrent"
1065  self._options.magField='AutoFromDBCurrent'
1066  self.magFieldCFF = 'Configuration/StandardSequences/MagneticField_'+self._options.magField.replace('.','')+'_cff'
1067  self.magFieldCFF = self.magFieldCFF.replace("__",'_')
1068 
1069  # the geometry
1070  self.GeometryCFF='Configuration/StandardSequences/GeometryRecoDB_cff'
1071  self.geometryDBLabel=None
1072  simGeometry=''
1073  if self._options.fast:
1074  if 'start' in self._options.conditions.lower():
1075  self.GeometryCFF='FastSimulation/Configuration/Geometries_START_cff'
1076  else:
1077  self.GeometryCFF='FastSimulation/Configuration/Geometries_MC_cff'
1078  else:
1079  def inGeometryKeys(opt):
1080  from Configuration.StandardSequences.GeometryConf import GeometryConf
1081  if opt in GeometryConf:
1082  return GeometryConf[opt]
1083  else:
1084  return opt
1085 
1086  geoms=self._options.geometry.split(',')
1087  if len(geoms)==1: geoms=inGeometryKeys(geoms[0]).split(',')
1088  if len(geoms)==2:
1089  #may specify the reco geometry
1090  if '/' in geoms[1] or '_cff' in geoms[1]:
1091  self.GeometryCFF=geoms[1]
1092  else:
1093  self.GeometryCFF='Configuration/Geometry/Geometry'+geoms[1]+'_cff'
1094 
1095  if (geoms[0].startswith('DB:')):
1096  self.SimGeometryCFF='Configuration/StandardSequences/GeometrySimDB_cff'
1097  self.geometryDBLabel=geoms[0][3:]
1098  print "with DB:"
1099  else:
1100  if '/' in geoms[0] or '_cff' in geoms[0]:
1101  self.SimGeometryCFF=geoms[0]
1102  else:
1103  simGeometry=geoms[0]
1104  if self._options.gflash==True:
1105  self.SimGeometryCFF='Configuration/Geometry/Geometry'+geoms[0]+'GFlash_cff'
1106  else:
1107  self.SimGeometryCFF='Configuration/Geometry/Geometry'+geoms[0]+'_cff'
1108 
1109  # synchronize the geometry configuration and the FullSimulation sequence to be used
1110  if simGeometry not in defaultOptions.geometryExtendedOptions:
1111  self.SIMDefaultCFF="Configuration/StandardSequences/SimIdeal_cff"
1112 
1113  if self._options.scenario=='nocoll' or self._options.scenario=='cosmics':
1114  self.SIMDefaultCFF="Configuration/StandardSequences/SimNOBEAM_cff"
1115  self._options.beamspot='NoSmear'
1116 
1117  # if fastsim switch event content
1118  if self._options.fast:
1119  self.SIMDefaultCFF = 'FastSimulation.Configuration.SimIdeal_cff'
1120  self.SIMDefaultSeq = 'psim'
1121  self.RECODefaultCFF= 'FastSimulation.Configuration.Reconstruction_AftMix_cff'
1122  self.RECODefaultSeq= 'reconstruction'
1123  self.EVTCONTDefaultCFF = "FastSimulation.Configuration.EventContent_cff"
1124  self.VALIDATIONDefaultCFF = "FastSimulation.Configuration.Validation_cff"
1125  self.RECOBEFMIXDefaultCFF = 'FastSimulation.Configuration.Reconstruction_BefMix_cff'
1126  self.RECOBEFMIXDefaultSeq = 'reconstruction_befmix'
1127  self.DIGIDefaultCFF = 'FastSimulation.Configuration.Digi_cff'
1128  if self._options.datamix == 'PreMix':
1129  self.DIGIDefaultCFF="FastSimulation.Configuration.DigiDMPreMix_cff"
1130  if "DIGIPREMIX" in self.stepMap.keys():
1131  self.DIGIDefaultCFF="FastSimulation.Configuration.Digi_PreMix_cff"
1132  if "DATAMIX" in self.stepMap.keys():
1133  self.DATAMIXDefaultCFF="FastSimulation.Configuration.DataMixer"+self._options.datamix+"_cff"
1134 
1135  self.DIGIDefaultSeq = 'pdigi'
1136  self.L1EMDefaultCFF='FastSimulation.Configuration.SimL1Emulator_cff'
1137  self.L1RecoDefaultCFF='FastSimulation.Configuration.L1Reco_cff'
1138  self.DIGI2RAWDefaultCFF = 'FastSimulation.Configuration.DigiToRaw_cff'
1139  self.DIGI2RAWDefaultSeq = 'DigiToRaw'
1140  self.EVTCONTDefaultCFF = "FastSimulation.Configuration.EventContent_cff"
1141  self.VALIDATIONDefaultCFF = "FastSimulation.Configuration.Validation_cff"
1142 
1143 
1144 
1145  # Mixing
1146  if self._options.pileup=='default':
1147  from Configuration.StandardSequences.Mixing import MixingDefaultKey
1148  self._options.pileup=MixingDefaultKey
1149  # temporary, until digi-reco mixing becomes standard in RelVals
1150  if self._options.fast:
1151  self._options.pileup="GEN_" + MixingDefaultKey
1152 
1153 
1154  #not driven by a default cff anymore
1155  if self._options.isData:
1156  self._options.pileup=None
1157 
1158  if self._options.slhc:
1159  self.GeometryCFF='SLHCUpgradeSimulations.Geometry.%s_cmsSimIdealGeometryXML_cff'%(self._options.slhc,)
1160  if 'stdgeom' not in self._options.slhc:
1161  self.SimGeometryCFF='SLHCUpgradeSimulations.Geometry.%s_cmsSimIdealGeometryXML_cff'%(self._options.slhc,)
1162  self.DIGIDefaultCFF='SLHCUpgradeSimulations/Geometry/Digi_%s_cff'%(self._options.slhc,)
1163  if self._options.pileup!=defaultOptions.pileup:
1164  self._options.pileup='SLHC_%s_%s'%(self._options.pileup,self._options.slhc)
1165 
1166  self.REDIGIDefaultSeq=self.DIGIDefaultSeq
1167 
1168  # for alca, skims, etc
1169  def addExtraStream(self,name,stream,workflow='full'):
1170  # define output module and go from there
1171  output = cms.OutputModule("PoolOutputModule")
1172  if stream.selectEvents.parameters_().__len__()!=0:
1173  output.SelectEvents = stream.selectEvents
1174  else:
1175  output.SelectEvents = cms.untracked.PSet()
1176  output.SelectEvents.SelectEvents=cms.vstring()
1177  if isinstance(stream.paths,tuple):
1178  for path in stream.paths:
1179  output.SelectEvents.SelectEvents.append(path.label())
1180  else:
1181  output.SelectEvents.SelectEvents.append(stream.paths.label())
1182 
1183 
1184 
1185  if isinstance(stream.content,str):
1186  evtPset=getattr(self.process,stream.content)
1187  for p in evtPset.parameters_():
1188  setattr(output,p,getattr(evtPset,p))
1189  if not self._options.inlineEventContent:
1190  def doNotInlineEventContent(instance,label = "process."+stream.content+".outputCommands"):
1191  return label
1192  output.outputCommands.__dict__["dumpPython"] = doNotInlineEventContent
1193  else:
1194  output.outputCommands = stream.content
1195 
1196 
1197  output.fileName = cms.untracked.string(self._options.dirout+stream.name+'.root')
1198 
1199  output.dataset = cms.untracked.PSet( dataTier = stream.dataTier,
1200  filterName = cms.untracked.string(stream.name))
1201 
1202  if self._options.filtername:
1203  output.dataset.filterName= cms.untracked.string(self._options.filtername+"_"+stream.name)
1204 
1205  #add an automatic flushing to limit memory consumption
1206  output.eventAutoFlushCompressedSize=cms.untracked.int32(5*1024*1024)
1207 
1208  if workflow in ("producers,full"):
1209  if isinstance(stream.paths,tuple):
1210  for path in stream.paths:
1211  self.schedule.append(path)
1212  else:
1213  self.schedule.append(stream.paths)
1214 
1215 
1216  # in case of relvals we don't want to have additional outputs
1217  if (not self._options.relval) and workflow in ("full","output"):
1218  self.additionalOutputs[name] = output
1219  setattr(self.process,name,output)
1220 
1221  if workflow == 'output':
1222  # adjust the select events to the proper trigger results from previous process
1223  filterList = output.SelectEvents.SelectEvents
1224  for i, filter in enumerate(filterList):
1225  filterList[i] = filter+":"+self._options.triggerResultsProcess
1226 
1227  return output
1228 
1229  #----------------------------------------------------------------------------
1230  # here the methods to create the steps. Of course we are doing magic here ;)
1231  # prepare_STEPNAME modifies self.process and what else's needed.
1232  #----------------------------------------------------------------------------
1233 
1234  def loadDefaultOrSpecifiedCFF(self, sequence,defaultCFF,unsch=0):
1235  if ( len(sequence.split('.'))==1 ):
1236  l=self.loadAndRemember(defaultCFF,unsch)
1237  elif ( len(sequence.split('.'))==2 ):
1238  l=self.loadAndRemember(sequence.split('.')[0],unsch)
1239  sequence=sequence.split('.')[1]
1240  else:
1241  print "sub sequence configuration must be of the form dir/subdir/cff.a+b+c or cff.a"
1242  print sequence,"not recognized"
1243  raise
1244  return l
1245 
1246  def scheduleSequence(self,seq,prefix,what='Path'):
1247  if '*' in seq:
1248  #create only one path with all sequences in it
1249  for i,s in enumerate(seq.split('*')):
1250  if i==0:
1251  setattr(self.process,prefix,getattr(cms,what)( getattr(self.process, s) ))
1252  else:
1253  p=getattr(self.process,prefix)
1254  p+=getattr(self.process, s)
1255  self.schedule.append(getattr(self.process,prefix))
1256  return
1257  else:
1258  #create as many path as many sequences
1259  if not '+' in seq:
1260  if self.nextScheduleIsConditional:
1261  self.conditionalPaths.append(prefix)
1262  setattr(self.process,prefix,getattr(cms,what)( getattr(self.process, seq) ))
1263  self.schedule.append(getattr(self.process,prefix))
1264  else:
1265  for i,s in enumerate(seq.split('+')):
1266  sn=prefix+'%d'%(i)
1267  setattr(self.process,sn,getattr(cms,what)( getattr(self.process, s) ))
1268  self.schedule.append(getattr(self.process,sn))
1269  return
1270 
1271  def scheduleSequenceAtEnd(self,seq,prefix):
1272  self.scheduleSequence(seq,prefix,what='EndPath')
1273  return
1274 
1275  def prepare_ALCAPRODUCER(self, sequence = None):
1276  self.prepare_ALCA(sequence, workflow = "producers")
1277 
1278  def prepare_ALCAOUTPUT(self, sequence = None):
1279  self.prepare_ALCA(sequence, workflow = "output")
1280 
1281  def prepare_ALCA(self, sequence = None, workflow = 'full'):
1282  """ Enrich the process with alca streams """
1283  print 'DL enriching',workflow,sequence
1284  alcaConfig=self.loadDefaultOrSpecifiedCFF(sequence,self.ALCADefaultCFF)
1285  sequence = sequence.split('.')[-1]
1286 
1287  # decide which ALCA paths to use
1288  alcaList = sequence.split("+")
1289  maxLevel=0
1290  from Configuration.AlCa.autoAlca import autoAlca
1291  # support @X from autoAlca.py, and recursion support: i.e T0:@Mu+@EG+...
1292  self.expandMapping(alcaList,autoAlca)
1293  self.AlCaPaths=[]
1294  for name in alcaConfig.__dict__:
1295  alcastream = getattr(alcaConfig,name)
1296  shortName = name.replace('ALCARECOStream','')
1297  if shortName in alcaList and isinstance(alcastream,cms.FilteredStream):
1298  output = self.addExtraStream(name,alcastream, workflow = workflow)
1299  self.executeAndRemember('process.ALCARECOEventContent.outputCommands.extend(process.OutALCARECO'+shortName+'_noDrop.outputCommands)')
1300  self.AlCaPaths.append(shortName)
1301  if 'DQM' in alcaList:
1302  if not self._options.inlineEventContent and hasattr(self.process,name):
1303  self.executeAndRemember('process.' + name + '.outputCommands.append("keep *_MEtoEDMConverter_*_*")')
1304  else:
1305  output.outputCommands.append("keep *_MEtoEDMConverter_*_*")
1306 
1307  #rename the HLT process name in the alca modules
1308  if self._options.hltProcess or 'HLT' in self.stepMap:
1309  if isinstance(alcastream.paths,tuple):
1310  for path in alcastream.paths:
1311  self.renameHLTprocessInSequence(path.label())
1312  else:
1313  self.renameHLTprocessInSequence(alcastream.paths.label())
1314 
1315  for i in range(alcaList.count(shortName)):
1316  alcaList.remove(shortName)
1317 
1318  # DQM needs a special handling
1319  elif name == 'pathALCARECODQM' and 'DQM' in alcaList:
1320  path = getattr(alcaConfig,name)
1321  self.schedule.append(path)
1322  alcaList.remove('DQM')
1323 
1324  if isinstance(alcastream,cms.Path):
1325  #black list the alca path so that they do not appear in the cfg
1326  self.blacklist_paths.append(alcastream)
1327 
1328 
1329  if len(alcaList) != 0:
1330  available=[]
1331  for name in alcaConfig.__dict__:
1332  alcastream = getattr(alcaConfig,name)
1333  if isinstance(alcastream,cms.FilteredStream):
1334  available.append(name.replace('ALCARECOStream',''))
1335  print "The following alcas could not be found "+str(alcaList)
1336  print "available ",available
1337  #print "verify your configuration, ignoring for now"
1338  raise Exception("The following alcas could not be found "+str(alcaList))
1339 
1340  def prepare_LHE(self, sequence = None):
1341  #load the fragment
1342  ##make it loadable
1343  loadFragment = self._options.evt_type.replace('.py','',).replace('.','_').replace('python/','').replace('/','.')
1344  print "Loading lhe fragment from",loadFragment
1345  __import__(loadFragment)
1346  self.process.load(loadFragment)
1347  ##inline the modules
1348  self._options.inlineObjets+=','+sequence
1349 
1350  getattr(self.process,sequence).nEvents = int(self._options.number)
1351 
1352  #schedule it
1353  self.process.lhe_step = cms.Path( getattr( self.process,sequence) )
1354  self.excludedPaths.append("lhe_step")
1355  self.schedule.append( self.process.lhe_step )
1356 
1357  def prepare_GEN(self, sequence = None):
1358  """ load the fragment of generator configuration """
1359  loadFailure=False
1360  #remove trailing .py
1361  #support old style .cfi by changing into something.cfi into something_cfi
1362  #remove python/ from the name
1363  loadFragment = self._options.evt_type.replace('.py','',).replace('.','_').replace('python/','')
1364  #standard location of fragments
1365  if not '/' in loadFragment:
1366  loadFragment='Configuration.Generator.'+loadFragment
1367  else:
1368  loadFragment=loadFragment.replace('/','.')
1369  try:
1370  print "Loading generator fragment from",loadFragment
1371  __import__(loadFragment)
1372  except:
1373  loadFailure=True
1374  #if self.process.source and self.process.source.type_()=='EmptySource':
1375  if not (self._options.filein or self._options.dasquery):
1376  raise Exception("Neither gen fragment of input files provided: this is an inconsistent GEN step configuration")
1377 
1378  if not loadFailure:
1379  generatorModule=sys.modules[loadFragment]
1380  genModules=generatorModule.__dict__
1381  #remove lhe producer module since this should have been
1382  #imported instead in the LHE step
1383  if self.LHEDefaultSeq in genModules:
1384  del genModules[self.LHEDefaultSeq]
1385 
1386  if self._options.hideGen:
1387  self.loadAndRemember(loadFragment)
1388  else:
1389  self.process.load(loadFragment)
1390  # expose the objects from that fragment to the configuration
1391  import FWCore.ParameterSet.Modules as cmstypes
1392  for name in genModules:
1393  theObject = getattr(generatorModule,name)
1394  if isinstance(theObject, cmstypes._Module):
1395  self._options.inlineObjets=name+','+self._options.inlineObjets
1396  elif isinstance(theObject, cms.Sequence) or isinstance(theObject, cmstypes.ESProducer):
1397  self._options.inlineObjets+=','+name
1398 
1399  if sequence == self.GENDefaultSeq or sequence == 'pgen_genonly':
1400  if 'ProductionFilterSequence' in genModules and ('generator' in genModules):
1401  self.productionFilterSequence = 'ProductionFilterSequence'
1402  elif 'generator' in genModules:
1403  self.productionFilterSequence = 'generator'
1404 
1405  """ Enrich the schedule with the rest of the generation step """
1406  self.loadDefaultOrSpecifiedCFF(sequence,self.GENDefaultCFF)
1407  genSeqName=sequence.split('.')[-1]
1408 
1409  if True:
1410  try:
1411  from Configuration.StandardSequences.VtxSmeared import VtxSmeared
1412  cffToBeLoaded=VtxSmeared[self._options.beamspot]
1413  self.loadAndRemember(cffToBeLoaded)
1414  except ImportError:
1415  raise Exception("VertexSmearing type or beamspot "+self._options.beamspot+" unknown.")
1416 
1417  if self._options.scenario == 'HeavyIons':
1418  if self._options.pileup=='HiMixGEN':
1419  self.loadAndRemember("Configuration/StandardSequences/GeneratorMix_cff")
1420  else:
1421  self.loadAndRemember("Configuration/StandardSequences/GeneratorHI_cff")
1422 
1423  self.process.generation_step = cms.Path( getattr(self.process,genSeqName) )
1424  self.schedule.append(self.process.generation_step)
1425 
1426  #register to the genstepfilter the name of the path (static right now, but might evolve)
1427  self.executeAndRemember('process.genstepfilter.triggerConditions=cms.vstring("generation_step")')
1428 
1429  if 'reGEN' in self.stepMap:
1430  #stop here
1431  return
1432 
1433  """ Enrich the schedule with the summary of the filter step """
1434  #the gen filter in the endpath
1435  self.loadAndRemember("GeneratorInterface/Core/genFilterSummary_cff")
1436  self.scheduleSequenceAtEnd('genFilterSummary','genfiltersummary_step')
1437  return
1438 
1439  def prepare_SIM(self, sequence = None):
1440  """ Enrich the schedule with the simulation step"""
1441  self.loadDefaultOrSpecifiedCFF(sequence,self.SIMDefaultCFF)
1442  if not self._options.fast:
1443  if self._options.gflash==True:
1444  self.loadAndRemember("Configuration/StandardSequences/GFlashSIM_cff")
1445 
1446  if self._options.magField=='0T':
1447  self.executeAndRemember("process.g4SimHits.UseMagneticField = cms.bool(False)")
1448  else:
1449  if self._options.magField=='0T':
1450  self.executeAndRemember("process.famosSimHits.UseMagneticField = cms.bool(False)")
1451 
1452  self.scheduleSequence(sequence.split('.')[-1],'simulation_step')
1453  return
1454 
1455  def prepare_DIGI(self, sequence = None):
1456  """ Enrich the schedule with the digitisation step"""
1457  self.loadDefaultOrSpecifiedCFF(sequence,self.DIGIDefaultCFF)
1458 
1459  if self._options.gflash==True:
1460  self.loadAndRemember("Configuration/StandardSequences/GFlashDIGI_cff")
1461 
1462  if sequence == 'pdigi_valid':
1463  self.executeAndRemember("process.mix.digitizers = cms.PSet(process.theDigitizersValid)")
1464 
1465  if sequence != 'pdigi_nogen' and sequence != 'pdigi_valid_nogen' and not self.process.source.type_()=='EmptySource':
1466  if self._options.inputEventContent=='':
1467  self._options.inputEventContent='REGEN'
1468  else:
1469  self._options.inputEventContent=self._options.inputEventContent+',REGEN'
1470 
1471 
1472  self.scheduleSequence(sequence.split('.')[-1],'digitisation_step')
1473  return
1474 
1475  def prepare_DIGIPREMIX(self, sequence = None):
1476  """ Enrich the schedule with the digitisation step"""
1477  self.loadDefaultOrSpecifiedCFF(sequence,self.DIGIDefaultCFF)
1478 
1479  self.loadAndRemember("SimGeneral/MixingModule/digi_noNoise_cfi")
1480 
1481  if sequence == 'pdigi_valid':
1482  self.executeAndRemember("process.mix.digitizers = cms.PSet(process.theDigitizersNoNoiseValid)")
1483  else:
1484  self.executeAndRemember("process.mix.digitizers = cms.PSet(process.theDigitizersNoNoise)")
1485 
1486  self.scheduleSequence(sequence.split('.')[-1],'digitisation_step')
1487  return
1488 
1489  def prepare_DIGIPREMIX_S2(self, sequence = None):
1490  """ Enrich the schedule with the digitisation step"""
1491  self.loadDefaultOrSpecifiedCFF(sequence,self.DIGIDefaultCFF)
1492 
1493  self.loadAndRemember("SimGeneral/MixingModule/digi_MixPreMix_cfi")
1494 
1495 
1496  if sequence == 'pdigi_valid':
1497  self.executeAndRemember("process.mix.digitizers = cms.PSet(process.theDigitizersMixPreMixValid)")
1498  else:
1499  self.executeAndRemember("process.mix.digitizers = cms.PSet(process.theDigitizersMixPreMix)")
1500 
1501  self.scheduleSequence(sequence.split('.')[-1],'digitisation_step')
1502  return
1503 
1504  def prepare_CFWRITER(self, sequence = None):
1505  """ Enrich the schedule with the crossing frame writer step"""
1506  self.loadAndRemember(self.CFWRITERDefaultCFF)
1507  self.scheduleSequence('pcfw','cfwriter_step')
1508  return
1509 
1510  def prepare_DATAMIX(self, sequence = None):
1511  """ Enrich the schedule with the digitisation step"""
1512  self.loadAndRemember(self.DATAMIXDefaultCFF)
1513  self.scheduleSequence('pdatamix','datamixing_step')
1514 
1515  if self._options.pileup_input:
1516  theFiles=''
1517  if self._options.pileup_input.startswith('dbs:') or self._options.pileup_input.startswith('das:'):
1518  theFiles=filesFromDASQuery('file dataset = %s'%(self._options.pileup_input[4:],))[0]
1519  elif self._options.pileup_input.startswith("filelist:"):
1520  theFiles= (filesFromList(self._options.pileup_input[9:]))[0]
1521  else:
1522  theFiles=self._options.pileup_input.split(',')
1523  #print theFiles
1524  self.executeAndRemember( "process.mixData.input.fileNames = cms.untracked.vstring(%s)"%( theFiles ) )
1525 
1526  return
1527 
1528  def prepare_DIGI2RAW(self, sequence = None):
1529  self.loadDefaultOrSpecifiedCFF(sequence,self.DIGI2RAWDefaultCFF)
1530  self.scheduleSequence(sequence.split('.')[-1],'digi2raw_step')
1531  if "DIGIPREMIX" in self.stepMap.keys():
1532  self.executeAndRemember("process.esDigiToRaw.Label = cms.string('mix')") ##terrible hack - bypass zero suppression
1533  self.executeAndRemember("process.SiStripDigiToRaw.FedReadoutMode = cms.string('PREMIX_RAW')") ##special readout mode for StripTracker
1534 
1535  return
1536 
1537  def prepare_REPACK(self, sequence = None):
1538  self.loadDefaultOrSpecifiedCFF(sequence,self.REPACKDefaultCFF)
1539  self.scheduleSequence(sequence.split('.')[-1],'digi2repack_step')
1540  return
1541 
1542  def prepare_L1(self, sequence = None):
1543  """ Enrich the schedule with the L1 simulation step"""
1544  assert(sequence == None)
1545  self.loadAndRemember(self.L1EMDefaultCFF)
1546  self.scheduleSequence('SimL1Emulator','L1simulation_step')
1547  return
1548 
1549  def prepare_L1REPACK(self, sequence = None):
1550  """ Enrich the schedule with the L1 simulation step, running the L1 emulator on data unpacked from the RAW collection, and repacking the result in a new RAW collection"""
1551  supported = ['GT','GT1','GT2','GCTGT']
1552  if sequence in supported:
1553  self.loadAndRemember('Configuration/StandardSequences/SimL1EmulatorRepack_%s_cff'%sequence)
1554  if self._options.scenario == 'HeavyIons':
1555  self.renameInputTagsInSequence("SimL1Emulator","rawDataCollector","rawDataRepacker")
1556  self.scheduleSequence('SimL1Emulator','L1RePack_step')
1557  else:
1558  print "L1REPACK with '",sequence,"' is not supported! Supported choices are: ",supported
1559  raise Exception('unsupported feature')
1560 
1561 
1562  def prepare_HLT(self, sequence = None):
1563  """ Enrich the schedule with the HLT simulation step"""
1564  if not sequence:
1565  print "no specification of the hlt menu has been given, should never happen"
1566  raise Exception('no HLT sequence provided')
1567 
1568  if '@' in sequence:
1569  # case where HLT:@something was provided
1570  from Configuration.HLT.autoHLT import autoHLT
1571  key = sequence[1:]
1572  if key in autoHLT:
1573  sequence = autoHLT[key]
1574  else:
1575  raise ValueError('no HLT mapping key "%s" found in autoHLT' % key)
1576 
1577  if ',' in sequence:
1578  #case where HLT:something:something was provided
1579  self.executeAndRemember('import HLTrigger.Configuration.Utilities')
1580  optionsForHLT = {}
1581  if self._options.scenario == 'HeavyIons':
1582  optionsForHLT['type'] = 'HIon'
1583  else:
1584  optionsForHLT['type'] = 'GRun'
1585  optionsForHLTConfig = ', '.join('%s=%s' % (key, repr(val)) for (key, val) in optionsForHLT.iteritems())
1586  if sequence == 'run,fromSource':
1587  if hasattr(self.process.source,'firstRun'):
1588  self.executeAndRemember('process.loadHltConfiguration("run:%%d"%%(process.source.firstRun.value()),%s)'%(optionsForHLTConfig))
1589  elif hasattr(self.process.source,'setRunNumber'):
1590  self.executeAndRemember('process.loadHltConfiguration("run:%%d"%%(process.source.setRunNumber.value()),%s)'%(optionsForHLTConfig))
1591  else:
1592  raise Exception('Cannot replace menu to load %s'%(sequence))
1593  else:
1594  self.executeAndRemember('process.loadHltConfiguration("%s",%s)'%(sequence.replace(',',':'),optionsForHLTConfig))
1595  else:
1596  self.loadAndRemember('HLTrigger/Configuration/HLT_%s_cff' % sequence)
1597 
1598  if self._options.isMC:
1599  if self._options.fast:
1600  self._options.customisation_file.append("HLTrigger/Configuration/customizeHLTforMC.customizeHLTforFastSim")
1601  else:
1602  self._options.customisation_file.append("HLTrigger/Configuration/customizeHLTforMC.customizeHLTforFullSim")
1603 
1604  if self._options.name != 'HLT':
1605  self.additionalCommands.append('from HLTrigger.Configuration.CustomConfigs import ProcessName')
1606  self.additionalCommands.append('process = ProcessName(process)')
1607  self.additionalCommands.append('')
1608  from HLTrigger.Configuration.CustomConfigs import ProcessName
1609  self.process = ProcessName(self.process)
1610 
1611  self.schedule.append(self.process.HLTSchedule)
1612  [self.blacklist_paths.append(path) for path in self.process.HLTSchedule if isinstance(path,(cms.Path,cms.EndPath))]
1613 
1614  #this is a fake, to be removed with fastim migration and HLT menu dump
1615  if self._options.fast:
1616  if not hasattr(self.process,'HLTEndSequence'):
1617  self.executeAndRemember("process.HLTEndSequence = cms.Sequence( process.dummyModule )")
1618 
1619 
1620  def prepare_RAW2RECO(self, sequence = None):
1621  if ','in sequence:
1622  seqReco=sequence.split(',')[1]
1623  seqDigi=sequence.split(',')[0]
1624  else:
1625  print "RAW2RECO requires two specifications",sequence,"insufficient"
1626 
1627  self.prepare_RAW2DIGI(seqDigi)
1628  self.prepare_RECO(seqReco)
1629  return
1630 
1631  def prepare_RAW2DIGI(self, sequence = "RawToDigi"):
1632  self.loadDefaultOrSpecifiedCFF(sequence,self.RAW2DIGIDefaultCFF)
1633  self.scheduleSequence(sequence,'raw2digi_step')
1634  # if self._options.isRepacked:
1635  #self.renameInputTagsInSequence(sequence)
1636  return
1637 
1638  def prepare_PATFILTER(self, sequence=None):
1639  self.loadAndRemember("PhysicsTools/PatAlgos/slimming/metFilterPaths_cff")
1640  from PhysicsTools.PatAlgos.slimming.metFilterPaths_cff import allMetFilterPaths
1641  for filt in allMetFilterPaths:
1642  self.schedule.append(getattr(self.process,'Flag_'+filt))
1643 
1644  def prepare_L1HwVal(self, sequence = 'L1HwVal'):
1645  ''' Enrich the schedule with L1 HW validation '''
1646  self.loadDefaultOrSpecifiedCFF(sequence,self.L1HwValDefaultCFF)
1647  #self.scheduleSequence(sequence.split('.')[-1],'l1hwval_step')
1648  print '\n\n\n DEPRECATED this has no action \n\n\n'
1649  return
1650 
1651  def prepare_L1Reco(self, sequence = "L1Reco"):
1652  ''' Enrich the schedule with L1 reconstruction '''
1653  self.loadDefaultOrSpecifiedCFF(sequence,self.L1RecoDefaultCFF)
1654  self.scheduleSequence(sequence.split('.')[-1],'L1Reco_step')
1655  return
1656 
1657  def prepare_L1TrackTrigger(self, sequence = "L1TrackTrigger"):
1658  ''' Enrich the schedule with L1 reconstruction '''
1660  self.scheduleSequence(sequence.split('.')[-1],'L1TrackTrigger_step')
1661  return
1662 
1663  def prepare_FILTER(self, sequence = None):
1664  ''' Enrich the schedule with a user defined filter sequence '''
1665  ## load the relevant part
1666  filterConfig=self.load(sequence.split('.')[0])
1667  filterSeq=sequence.split('.')[-1]
1668  ## print it in the configuration
1670  def __init__(self):
1671  self.inliner=''
1672  pass
1673  def enter(self,visitee):
1674  try:
1675  label=visitee.label()
1676  ##needs to be in reverse order
1677  self.inliner=label+','+self.inliner
1678  except:
1679  pass
1680  def leave(self,v): pass
1681 
1682  expander=PrintAllModules()
1683  getattr(self.process,filterSeq).visit( expander )
1684  self._options.inlineObjets+=','+expander.inliner
1685  self._options.inlineObjets+=','+filterSeq
1686 
1687  ## put the filtering path in the schedule
1688  self.scheduleSequence(filterSeq,'filtering_step')
1689  self.nextScheduleIsConditional=True
1690  ## put it before all the other paths
1691  self.productionFilterSequence = filterSeq
1692 
1693  return
1694 
1695  def prepare_RECO(self, sequence = "reconstruction"):
1696  ''' Enrich the schedule with reconstruction '''
1697  self.loadDefaultOrSpecifiedCFF(sequence,self.RECODefaultCFF)
1698  self.scheduleSequence(sequence.split('.')[-1],'reconstruction_step')
1699  return
1700 
1701  def prepare_RECOBEFMIX(self, sequence = "reconstruction"):
1702  ''' Enrich the schedule with the part of reconstruction that is done before mixing in FastSim'''
1703  if not self._options.fast:
1704  print "ERROR: this step is only implemented for FastSim"
1705  sys.exit()
1706  self.loadDefaultOrSpecifiedCFF(self.RECOBEFMIXDefaultSeq,self.RECOBEFMIXDefaultCFF)
1707  self.scheduleSequence(sequence.split('.')[-1],'reconstruction_befmix_step')
1708  return
1709 
1710  def prepare_PAT(self, sequence = "miniAOD"):
1711  ''' Enrich the schedule with PAT '''
1712  self.prepare_PATFILTER(self)
1713  self.loadDefaultOrSpecifiedCFF(sequence,self.PATDefaultCFF,1) #this is unscheduled
1714  if not self._options.runUnscheduled:
1715  raise Exception("MiniAOD production can only run in unscheduled mode, please run cmsDriver with --runUnscheduled")
1716  if self._options.isData:
1717  self._options.customisation_file_unsch.append("PhysicsTools/PatAlgos/slimming/miniAOD_tools.miniAOD_customizeAllData")
1718  else:
1719  self._options.customisation_file_unsch.append("PhysicsTools/PatAlgos/slimming/miniAOD_tools.miniAOD_customizeAllMC")
1720  if self._options.fast:
1721  self._options.customisation_file_unsch.append("PhysicsTools/PatAlgos/slimming/metFilterPaths_cff.miniAOD_customizeMETFiltersFastSim")
1722  return
1723 
1724  def prepare_EI(self, sequence = None):
1725  ''' Enrich the schedule with event interpretation '''
1726  from Configuration.StandardSequences.EventInterpretation import EventInterpretation
1727  if sequence in EventInterpretation:
1728  self.EIDefaultCFF = EventInterpretation[sequence]
1729  sequence = 'EIsequence'
1730  else:
1731  raise Exception('Cannot set %s event interpretation'%( sequence) )
1732  self.loadDefaultOrSpecifiedCFF(sequence,self.EIDefaultCFF)
1733  self.scheduleSequence(sequence.split('.')[-1],'eventinterpretaion_step')
1734  return
1735 
1736  def prepare_SKIM(self, sequence = "all"):
1737  ''' Enrich the schedule with skimming fragments'''
1738  skimConfig = self.loadDefaultOrSpecifiedCFF(sequence,self.SKIMDefaultCFF)
1739  sequence = sequence.split('.')[-1]
1740 
1741  skimlist=sequence.split('+')
1742  ## support @Mu+DiJet+@Electron configuration via autoSkim.py
1743  from Configuration.Skimming.autoSkim import autoSkim
1744  self.expandMapping(skimlist,autoSkim)
1745 
1746  #print "dictionnary for skims:",skimConfig.__dict__
1747  for skim in skimConfig.__dict__:
1748  skimstream = getattr(skimConfig,skim)
1749  if isinstance(skimstream,cms.Path):
1750  #black list the alca path so that they do not appear in the cfg
1751  self.blacklist_paths.append(skimstream)
1752  if (not isinstance(skimstream,cms.FilteredStream)):
1753  continue
1754  shortname = skim.replace('SKIMStream','')
1755  if (sequence=="all"):
1756  self.addExtraStream(skim,skimstream)
1757  elif (shortname in skimlist):
1758  self.addExtraStream(skim,skimstream)
1759  #add a DQM eventcontent for this guy
1760  if self._options.datatier=='DQM':
1761  self.process.load(self.EVTCONTDefaultCFF)
1762  skimstreamDQM = cms.FilteredStream(
1763  responsible = skimstream.responsible,
1764  name = skimstream.name+'DQM',
1765  paths = skimstream.paths,
1766  selectEvents = skimstream.selectEvents,
1767  content = self._options.datatier+'EventContent',
1768  dataTier = cms.untracked.string(self._options.datatier)
1769  )
1770  self.addExtraStream(skim+'DQM',skimstreamDQM)
1771  for i in range(skimlist.count(shortname)):
1772  skimlist.remove(shortname)
1773 
1774 
1775 
1776  if (skimlist.__len__()!=0 and sequence!="all"):
1777  print 'WARNING, possible typo with SKIM:'+'+'.join(skimlist)
1778  raise Exception('WARNING, possible typo with SKIM:'+'+'.join(skimlist))
1779 
1780  def prepare_USER(self, sequence = None):
1781  ''' Enrich the schedule with a user defined sequence '''
1782  self.loadDefaultOrSpecifiedCFF(sequence,self.USERDefaultCFF)
1783  self.scheduleSequence(sequence.split('.')[-1],'user_step')
1784  return
1785 
1786  def prepare_POSTRECO(self, sequence = None):
1787  """ Enrich the schedule with the postreco step """
1788  self.loadAndRemember(self.POSTRECODefaultCFF)
1789  self.scheduleSequence('postreco_generator','postreco_step')
1790  return
1791 
1792 
1793  def prepare_VALIDATION(self, sequence = 'validation'):
1794  print sequence,"in preparing validation"
1795  self.loadDefaultOrSpecifiedCFF(sequence,self.VALIDATIONDefaultCFF)
1796  from Validation.Configuration.autoValidation import autoValidation
1797  #in case VALIDATION:something:somethingelse -> something,somethingelse
1798  sequence=sequence.split('.')[-1]
1799  if sequence.find(',')!=-1:
1800  prevalSeqName=sequence.split(',')[0].split('+')
1801  valSeqName=sequence.split(',')[1].split('+')
1802  self.expandMapping(prevalSeqName,autoValidation,index=0)
1803  self.expandMapping(valSeqName,autoValidation,index=1)
1804  else:
1805  if '@' in sequence:
1806  prevalSeqName=sequence.split('+')
1807  valSeqName=sequence.split('+')
1808  self.expandMapping(prevalSeqName,autoValidation,index=0)
1809  self.expandMapping(valSeqName,autoValidation,index=1)
1810  else:
1811  postfix=''
1812  if sequence:
1813  postfix='_'+sequence
1814  prevalSeqName=['prevalidation'+postfix]
1815  valSeqName=['validation'+postfix]
1816  if not hasattr(self.process,valSeqName[0]):
1817  prevalSeqName=['']
1818  valSeqName=[sequence]
1819 
1820  def NFI(index):
1821  ##name from index, required to keep backward compatibility
1822  if index==0:
1823  return ''
1824  else:
1825  return '%s'%index
1826 
1827  if not 'DIGI' in self.stepMap and not self._options.fast and not any(map( lambda s : s.startswith('genvalid'), valSeqName)):
1828  if self._options.restoreRNDSeeds==False and not self._options.restoreRNDSeeds==True:
1829  self._options.restoreRNDSeeds=True
1830 
1831  #rename the HLT process in validation steps
1832  if ('HLT' in self.stepMap and not self._options.fast) or self._options.hltProcess:
1833  for s in valSeqName+prevalSeqName:
1834  if s:
1836  for (i,s) in enumerate(prevalSeqName):
1837  if s:
1838  setattr(self.process,'prevalidation_step%s'%NFI(i), cms.Path( getattr(self.process, s)) )
1839  self.schedule.append(getattr(self.process,'prevalidation_step%s'%NFI(i)))
1840 
1841  for (i,s) in enumerate(valSeqName):
1842  setattr(self.process,'validation_step%s'%NFI(i), cms.EndPath( getattr(self.process, s)))
1843  self.schedule.append(getattr(self.process,'validation_step%s'%NFI(i)))
1844 
1845  if not 'DIGI' in self.stepMap and not self._options.fast:
1846  self.executeAndRemember("process.mix.playback = True")
1847  self.executeAndRemember("process.mix.digitizers = cms.PSet()")
1848  self.executeAndRemember("for a in process.aliases: delattr(process, a)")
1849  self._options.customisation_file.append("SimGeneral/MixingModule/fullMixCustomize_cff.setCrossingFrameOn")
1850 
1851  if hasattr(self.process,"genstepfilter") and len(self.process.genstepfilter.triggerConditions):
1852  #will get in the schedule, smoothly
1853  for (i,s) in enumerate(valSeqName):
1854  getattr(self.process,'validation_step%s'%NFI(i))._seq = self.process.genstepfilter * getattr(self.process,'validation_step%s'%NFI(i))._seq
1855 
1856  return
1857 
1858 
1860  """Visitor that travels within a cms.Sequence, looks for a parameter and replace its value
1861  It will climb down within PSets, VPSets and VInputTags to find its target"""
1862  def __init__(self, paramSearch, paramReplace, verbose=False, whitelist=()):
1863  self._paramReplace = paramReplace
1864  self._paramSearch = paramSearch
1865  self._verbose = verbose
1866  self._whitelist = whitelist
1867 
1868  def doIt(self,pset,base):
1869  if isinstance(pset, cms._Parameterizable):
1870  for name in pset.parameters_().keys():
1871  # skip whitelisted parameters
1872  if name in self._whitelist:
1873  continue
1874  # if I use pset.parameters_().items() I get copies of the parameter values
1875  # so I can't modify the nested pset
1876  value = getattr(pset,name)
1877  type = value.pythonTypeName()
1878  if type in ('cms.PSet', 'cms.untracked.PSet'):
1879  self.doIt(value,base+"."+name)
1880  elif type in ('cms.VPSet', 'cms.untracked.VPSet'):
1881  for (i,ps) in enumerate(value): self.doIt(ps, "%s.%s[%d]"%(base,name,i) )
1882  elif type in ('cms.string', 'cms.untracked.string'):
1883  if value.value() == self._paramSearch:
1884  if self._verbose: print "set string process name %s.%s %s ==> %s"% (base, name, value, self._paramReplace)
1885  setattr(pset, name,self._paramReplace)
1886  elif type in ('cms.VInputTag', 'cms.untracked.VInputTag'):
1887  for (i,n) in enumerate(value):
1888  if not isinstance(n, cms.InputTag):
1889  n=cms.InputTag(n)
1890  if n.processName == self._paramSearch:
1891  # VInputTag can be declared as a list of strings, so ensure that n is formatted correctly
1892  if self._verbose:print "set process name %s.%s[%d] %s ==> %s " % (base, name, i, n, self._paramReplace)
1893  setattr(n,"processName",self._paramReplace)
1894  value[i]=n
1895  elif type in ('cms.vstring', 'cms.untracked.vstring'):
1896  for (i,n) in enumerate(value):
1897  if n==self._paramSearch:
1898  getattr(pset,name)[i]=self._paramReplace
1899  elif type in ('cms.InputTag', 'cms.untracked.InputTag'):
1900  if value.processName == self._paramSearch:
1901  if self._verbose: print "set process name %s.%s %s ==> %s " % (base, name, value, self._paramReplace)
1902  setattr(getattr(pset, name),"processName",self._paramReplace)
1903 
1904  def enter(self,visitee):
1905  label = ''
1906  try:
1907  label = visitee.label()
1908  except AttributeError:
1909  label = '<Module not in a Process>'
1910  except:
1911  label = 'other execption'
1912  self.doIt(visitee, label)
1913 
1914  def leave(self,visitee):
1915  pass
1916 
1917  #visit a sequence to repalce all input tags
1918  def renameInputTagsInSequence(self,sequence,oldT="rawDataCollector",newT="rawDataRepacker"):
1919  print "Replacing all InputTag %s => %s"%(oldT,newT)
1920  from PhysicsTools.PatAlgos.tools.helpers import massSearchReplaceAnyInputTag
1921  massSearchReplaceAnyInputTag(getattr(self.process,sequence),oldT,newT)
1922  loadMe='from PhysicsTools.PatAlgos.tools.helpers import massSearchReplaceAnyInputTag'
1923  if not loadMe in self.additionalCommands:
1924  self.additionalCommands.append(loadMe)
1925  self.additionalCommands.append('massSearchReplaceAnyInputTag(process.%s,"%s","%s",False,True)'%(sequence,oldT,newT))
1926 
1927  #change the process name used to address HLT results in any sequence
1928  def renameHLTprocessInSequence(self,sequence,proc=None,HLTprocess='HLT'):
1929  if self._options.hltProcess:
1930  proc=self._options.hltProcess
1931  else:
1932  proc=self.process.name_()
1933  if proc==HLTprocess: return
1934  # look up all module in dqm sequence
1935  print "replacing %s process name - sequence %s will use '%s'" % (HLTprocess,sequence, proc)
1936  getattr(self.process,sequence).visit(ConfigBuilder.MassSearchReplaceProcessNameVisitor(HLTprocess,proc,whitelist = ("subSystemFolder",)))
1937  if 'from Configuration.Applications.ConfigBuilder import ConfigBuilder' not in self.additionalCommands:
1938  self.additionalCommands.append('from Configuration.Applications.ConfigBuilder import ConfigBuilder')
1939  self.additionalCommands.append('process.%s.visit(ConfigBuilder.MassSearchReplaceProcessNameVisitor("%s", "%s", whitelist = ("subSystemFolder",)))'% (sequence,HLTprocess, proc))
1940 
1941 
1942  def expandMapping(self,seqList,mapping,index=None):
1943  maxLevel=20
1944  level=0
1945  while '@' in repr(seqList) and level<maxLevel:
1946  level+=1
1947  for specifiedCommand in seqList:
1948  if specifiedCommand.startswith('@'):
1949  location=specifiedCommand[1:]
1950  if not location in mapping:
1951  raise Exception("Impossible to map "+location+" from "+repr(mapping))
1952  mappedTo=mapping[location]
1953  if index!=None:
1954  mappedTo=mappedTo[index]
1955  seqList.remove(specifiedCommand)
1956  seqList.extend(mappedTo.split('+'))
1957  break;
1958  if level==maxLevel:
1959  raise Exception("Could not fully expand "+repr(seqList)+" from "+repr(mapping))
1960 
1961  def prepare_DQM(self, sequence = 'DQMOffline'):
1962  # this one needs replacement
1963 
1964  self.loadDefaultOrSpecifiedCFF(sequence,self.DQMOFFLINEDefaultCFF)
1965  sequenceList=sequence.split('.')[-1].split('+')
1966  from DQMOffline.Configuration.autoDQM import autoDQM
1967  self.expandMapping(sequenceList,autoDQM,index=0)
1968 
1969  if len(set(sequenceList))!=len(sequenceList):
1970  sequenceList=list(set(sequenceList))
1971  print "Duplicate entries for DQM:, using",sequenceList
1972  pathName='dqmoffline_step'
1973 
1974  for (i,sequence) in enumerate(sequenceList):
1975  if (i!=0):
1976  pathName='dqmoffline_%d_step'%(i)
1977 
1978  if 'HLT' in self.stepMap.keys() or self._options.hltProcess:
1979  self.renameHLTprocessInSequence(sequence)
1980 
1981  # if both HLT and DQM are run in the same process, schedule [HLT]DQM in an EndPath
1982  if 'HLT' in self.stepMap.keys():
1983  # need to put [HLT]DQM in an EndPath, to access the HLT trigger results
1984  setattr(self.process,pathName, cms.EndPath( getattr(self.process, sequence ) ) )
1985  else:
1986  # schedule DQM as a standard Path
1987  setattr(self.process,pathName, cms.Path( getattr(self.process, sequence) ) )
1988  self.schedule.append(getattr(self.process,pathName))
1989 
1990 
1991  def prepare_HARVESTING(self, sequence = None):
1992  """ Enrich the process with harvesting step """
1993  self.DQMSaverCFF='Configuration/StandardSequences/DQMSaver'+self._options.harvesting+'_cff'
1994  self.loadAndRemember(self.DQMSaverCFF)
1995 
1996  harvestingConfig = self.loadDefaultOrSpecifiedCFF(sequence,self.HARVESTINGDefaultCFF)
1997  sequence = sequence.split('.')[-1]
1998 
1999  # decide which HARVESTING paths to use
2000  harvestingList = sequence.split("+")
2001  from DQMOffline.Configuration.autoDQM import autoDQM
2002  from Validation.Configuration.autoValidation import autoValidation
2003  import copy
2004  combined_mapping = copy.deepcopy( autoDQM )
2005  combined_mapping.update( autoValidation )
2006  self.expandMapping(harvestingList,combined_mapping,index=-1)
2007 
2008  if len(set(harvestingList))!=len(harvestingList):
2009  harvestingList=list(set(harvestingList))
2010  print "Duplicate entries for HARVESTING, using",harvestingList
2011 
2012  for name in harvestingList:
2013  if not name in harvestingConfig.__dict__:
2014  print name,"is not a possible harvesting type. Available are",harvestingConfig.__dict__.keys()
2015  continue
2016  harvestingstream = getattr(harvestingConfig,name)
2017  if isinstance(harvestingstream,cms.Path):
2018  self.schedule.append(harvestingstream)
2019  self.blacklist_paths.append(harvestingstream)
2020  if isinstance(harvestingstream,cms.Sequence):
2021  setattr(self.process,name+"_step",cms.Path(harvestingstream))
2022  self.schedule.append(getattr(self.process,name+"_step"))
2023 
2024  self.scheduleSequence('DQMSaver','dqmsave_step')
2025  return
2026 
2027  def prepare_ALCAHARVEST(self, sequence = None):
2028  """ Enrich the process with AlCaHarvesting step """
2029  harvestingConfig = self.loadAndRemember(self.ALCAHARVESTDefaultCFF)
2030  sequence=sequence.split(".")[-1]
2031 
2032  # decide which AlcaHARVESTING paths to use
2033  harvestingList = sequence.split("+")
2034 
2035 
2036 
2037  from Configuration.AlCa.autoPCL import autoPCL
2038  self.expandMapping(harvestingList,autoPCL)
2039 
2040  for name in harvestingConfig.__dict__:
2041  harvestingstream = getattr(harvestingConfig,name)
2042  if name in harvestingList and isinstance(harvestingstream,cms.Path):
2043  self.schedule.append(harvestingstream)
2044  self.executeAndRemember("process.PoolDBOutputService.toPut.append(process.ALCAHARVEST" + name + "_dbOutput)")
2045  self.executeAndRemember("process.pclMetadataWriter.recordsToMap.append(process.ALCAHARVEST" + name + "_metadata)")
2046  harvestingList.remove(name)
2047  # append the common part at the end of the sequence
2048  lastStep = getattr(harvestingConfig,"ALCAHARVESTDQMSaveAndMetadataWriter")
2049  self.schedule.append(lastStep)
2050 
2051  if len(harvestingList) != 0 and 'dummyHarvesting' not in harvestingList :
2052  print "The following harvesting could not be found : ", harvestingList
2053  raise Exception("The following harvesting could not be found : "+str(harvestingList))
2054 
2055 
2056 
2057  def prepare_ENDJOB(self, sequence = 'endOfProcess'):
2058  self.loadDefaultOrSpecifiedCFF(sequence,self.ENDJOBDefaultCFF)
2059  self.scheduleSequenceAtEnd(sequence.split('.')[-1],'endjob_step')
2060  return
2061 
2063  self.process.reconstruction = cms.Path(self.process.reconstructionWithFamos)
2064  self.schedule.append(self.process.reconstruction)
2065 
2066 
2067  def build_production_info(self, evt_type, evtnumber):
2068  """ Add useful info for the production. """
2069  self.process.configurationMetadata=cms.untracked.PSet\
2070  (version=cms.untracked.string("$Revision: 1.19 $"),
2071  name=cms.untracked.string("Applications"),
2072  annotation=cms.untracked.string(evt_type+ " nevts:"+str(evtnumber))
2073  )
2074 
2075  self.addedObjects.append(("Production Info","configurationMetadata"))
2076 
2077 
2078  def prepare(self, doChecking = False):
2079  """ Prepare the configuration string and add missing pieces."""
2080 
2081  self.loadAndRemember(self.EVTCONTDefaultCFF) #load the event contents regardless
2082  self.addMaxEvents()
2083  if self.with_input:
2084  self.addSource()
2085  self.addStandardSequences()
2086  ##adding standard sequences might change the inputEventContent option and therefore needs to be finalized after
2087  self.completeInputCommand()
2088  self.addConditions()
2089 
2090 
2091  outputModuleCfgCode=""
2092  if not 'HARVESTING' in self.stepMap.keys() and not 'ALCAHARVEST' in self.stepMap.keys() and not 'ALCAOUTPUT' in self.stepMap.keys() and self.with_output:
2093  outputModuleCfgCode=self.addOutput()
2094 
2095  self.addCommon()
2096 
2097  self.pythonCfgCode = "# Auto generated configuration file\n"
2098  self.pythonCfgCode += "# using: \n# "+__version__[1:-1]+"\n# "+__source__[1:-1]+'\n'
2099  self.pythonCfgCode += "# with command line options: "+self._options.arguments+'\n'
2100  self.pythonCfgCode += "import FWCore.ParameterSet.Config as cms\n\n"
2101  if hasattr(self._options,"era") and self._options.era :
2102  self.pythonCfgCode += "from Configuration.StandardSequences.Eras import eras\n\n"
2103  self.pythonCfgCode += "process = cms.Process('"+self.process.name_()+"'" # Start of the line, finished after the loop
2104  # Multiple eras can be specified in a comma seperated list
2105  for requestedEra in self._options.era.split(",") :
2106  self.pythonCfgCode += ",eras."+requestedEra
2107  self.pythonCfgCode += ")\n\n" # end of the line
2108  else :
2109  self.pythonCfgCode += "process = cms.Process('"+self.process.name_()+"')\n\n"
2110 
2111  self.pythonCfgCode += "# import of standard configurations\n"
2112  for module in self.imports:
2113  self.pythonCfgCode += ("process.load('"+module+"')\n")
2114 
2115  # production info
2116  if not hasattr(self.process,"configurationMetadata"):
2117  self.build_production_info(self._options.evt_type, self._options.number)
2118  else:
2119  #the PSet was added via a load
2120  self.addedObjects.append(("Production Info","configurationMetadata"))
2121 
2122  self.pythonCfgCode +="\n"
2123  for comment,object in self.addedObjects:
2124  if comment!="":
2125  self.pythonCfgCode += "\n# "+comment+"\n"
2126  self.pythonCfgCode += dumpPython(self.process,object)
2127 
2128  # dump the output definition
2129  self.pythonCfgCode += "\n# Output definition\n"
2130  self.pythonCfgCode += outputModuleCfgCode
2131 
2132  # dump all additional outputs (e.g. alca or skim streams)
2133  self.pythonCfgCode += "\n# Additional output definition\n"
2134  #I do not understand why the keys are not normally ordered.
2135  nl=self.additionalOutputs.keys()
2136  nl.sort()
2137  for name in nl:
2138  output = self.additionalOutputs[name]
2139  self.pythonCfgCode += "process.%s = %s" %(name, output.dumpPython())
2140  tmpOut = cms.EndPath(output)
2141  setattr(self.process,name+'OutPath',tmpOut)
2142  self.schedule.append(tmpOut)
2143 
2144  # dump all additional commands
2145  self.pythonCfgCode += "\n# Other statements\n"
2146  for command in self.additionalCommands:
2147  self.pythonCfgCode += command + "\n"
2148 
2149  #comma separated list of objects that deserve to be inlined in the configuration (typically from a modified config deep down)
2150  for object in self._options.inlineObjets.split(','):
2151  if not object:
2152  continue
2153  if not hasattr(self.process,object):
2154  print 'cannot inline -'+object+'- : not known'
2155  else:
2156  self.pythonCfgCode +='\n'
2157  self.pythonCfgCode +=dumpPython(self.process,object)
2158 
2159  # dump all paths
2160  self.pythonCfgCode += "\n# Path and EndPath definitions\n"
2161  for path in self.process.paths:
2162  if getattr(self.process,path) not in self.blacklist_paths:
2163  self.pythonCfgCode += dumpPython(self.process,path)
2164 
2165  for endpath in self.process.endpaths:
2166  if getattr(self.process,endpath) not in self.blacklist_paths:
2167  self.pythonCfgCode += dumpPython(self.process,endpath)
2168 
2169  # dump the schedule
2170  self.pythonCfgCode += "\n# Schedule definition\n"
2171  result = "process.schedule = cms.Schedule("
2172 
2173  # handling of the schedule
2174  self.process.schedule = cms.Schedule()
2175  for item in self.schedule:
2176  if not isinstance(item, cms.Schedule):
2177  self.process.schedule.append(item)
2178  else:
2179  self.process.schedule.extend(item)
2180 
2181  if hasattr(self.process,"HLTSchedule"):
2182  beforeHLT = self.schedule[:self.schedule.index(self.process.HLTSchedule)]
2183  afterHLT = self.schedule[self.schedule.index(self.process.HLTSchedule)+1:]
2184  pathNames = ['process.'+p.label_() for p in beforeHLT]
2185  result += ','.join(pathNames)+')\n'
2186  result += 'process.schedule.extend(process.HLTSchedule)\n'
2187  pathNames = ['process.'+p.label_() for p in afterHLT]
2188  result += 'process.schedule.extend(['+','.join(pathNames)+'])\n'
2189  else:
2190  pathNames = ['process.'+p.label_() for p in self.schedule]
2191  result ='process.schedule = cms.Schedule('+','.join(pathNames)+')\n'
2192 
2193  self.pythonCfgCode += result
2194 
2195  if self._options.nThreads is not "1":
2196  self.pythonCfgCode +="\n"
2197  self.pythonCfgCode +="#Setup FWK for multithreaded\n"
2198  self.pythonCfgCode +="process.options.numberOfThreads=cms.untracked.uint32("+self._options.nThreads+")\n"
2199  self.pythonCfgCode +="process.options.numberOfStreams=cms.untracked.uint32(0)\n"
2200  #repacked version
2201  if self._options.isRepacked:
2202  self.pythonCfgCode +="\n"
2203  self.pythonCfgCode +="from Configuration.Applications.ConfigBuilder import MassReplaceInputTag\n"
2204  self.pythonCfgCode +="MassReplaceInputTag(process)\n"
2205  MassReplaceInputTag(self.process)
2206 
2207  # special treatment in case of production filter sequence 2/2
2208  if self.productionFilterSequence:
2209  self.pythonCfgCode +='# filter all path with the production filter sequence\n'
2210  self.pythonCfgCode +='for path in process.paths:\n'
2211  if len(self.conditionalPaths):
2212  self.pythonCfgCode +='\tif not path in %s: continue\n'%str(self.conditionalPaths)
2213  if len(self.excludedPaths):
2214  self.pythonCfgCode +='\tif path in %s: continue\n'%str(self.excludedPaths)
2215  self.pythonCfgCode +='\tgetattr(process,path)._seq = process.%s * getattr(process,path)._seq \n'%(self.productionFilterSequence,)
2216  pfs = getattr(self.process,self.productionFilterSequence)
2217  for path in self.process.paths:
2218  if not path in self.conditionalPaths: continue
2219  if path in self.excludedPaths: continue
2220  getattr(self.process,path)._seq = pfs * getattr(self.process,path)._seq
2221 
2222 
2223  # dump customise fragment
2224  self.pythonCfgCode += self.addCustomise()
2225 
2226  if self._options.runUnscheduled:
2227  # prune and delete paths
2228  #this is not supporting the blacklist at this point since I do not understand it
2229  self.pythonCfgCode+="#do not add changes to your config after this point (unless you know what you are doing)\n"
2230  self.pythonCfgCode+="from FWCore.ParameterSet.Utilities import convertToUnscheduled\n"
2231  self.pythonCfgCode+="process=convertToUnscheduled(process)\n"
2232 
2233  from FWCore.ParameterSet.Utilities import convertToUnscheduled
2234  self.process=convertToUnscheduled(self.process)
2235 
2236  #now add the unscheduled stuff
2237  for module in self.importsUnsch:
2238  self.process.load(module)
2239  self.pythonCfgCode += ("process.load('"+module+"')\n")
2240 
2241  #and clean the unscheduled stuff
2242  self.pythonCfgCode+="from FWCore.ParameterSet.Utilities import cleanUnscheduled\n"
2243  self.pythonCfgCode+="process=cleanUnscheduled(process)\n"
2244 
2245  from FWCore.ParameterSet.Utilities import cleanUnscheduled
2246  self.process=cleanUnscheduled(self.process)
2247 
2248 
2249  self.pythonCfgCode += self.addCustomise(1)
2250 
2251 
2252  # make the .io file
2253 
2254  if self._options.io:
2255  #io=open(self._options.python_filename.replace('.py','.io'),'w')
2256  if not self._options.io.endswith('.io'): self._option.io+='.io'
2257  io=open(self._options.io,'w')
2258  ioJson={}
2259  if hasattr(self.process.source,"fileNames"):
2260  if len(self.process.source.fileNames.value()):
2261  ioJson['primary']=self.process.source.fileNames.value()
2262  if hasattr(self.process.source,"secondaryFileNames"):
2263  if len(self.process.source.secondaryFileNames.value()):
2264  ioJson['secondary']=self.process.source.secondaryFileNames.value()
2265  if self._options.pileup_input and (self._options.pileup_input.startswith('dbs:') or self._options.pileup_input.startswith('das:')):
2266  ioJson['pileup']=self._options.pileup_input[4:]
2267  for (o,om) in self.process.outputModules_().items():
2268  ioJson[o]=om.fileName.value()
2269  ioJson['GT']=self.process.GlobalTag.globaltag.value()
2270  if self.productionFilterSequence:
2271  ioJson['filter']=self.productionFilterSequence
2272  import json
2273  io.write(json.dumps(ioJson))
2274  return
2275 
bool any(const std::vector< T > &v, const T &what)
Definition: ECalSD.cc:34
assert(m_qm.get())
def visit
Retrieve data from a perf suite output (sub) directory, only examines TimeSize at the moment...
def prepare_RECO
put the filtering path in the schedule
def massSearchReplaceAnyInputTag
Definition: helpers.py:262
def defineMixing
Definition: Mixing.py:167
inliner
needs to be in reverse order
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def convertToUnscheduled
Definition: Utilities.py:69
list object
Definition: dbtoconf.py:77
def cleanUnscheduled
Definition: Utilities.py:107
double split
Definition: MVATrainer.cc:139
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run