CMS 3D CMS Logo

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