CMS 3D CMS Logo

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