CMS 3D CMS Logo

confdb.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import sys
4 import re
5 import os
6 import urllib, urllib2
7 from pipe import pipe as _pipe
8 from options import globalTag
9 from itertools import islice
10 
11 def splitter(iterator, n):
12  i = iterator.__iter__()
13  while True:
14  l = list(islice(i, n))
15  if l:
16  yield l
17  else:
18  break
19 
20 
22 
23  def __init__(self, configuration):
24  self.config = configuration
25  self.data = None
26  self.source = []
27  self.parent = []
28 
29  self.options = {
30  'essources' : [],
31  'esmodules' : [],
32  'modules' : [],
33  'sequences' : [],
34  'services' : [],
35  'paths' : [],
36  'psets' : [],
37  'blocks' : [],
38  }
39 
40  self.labels = {}
41  if self.config.fragment:
42  self.labels['process'] = 'fragment'
43  self.labels['dict'] = 'fragment.__dict__'
44  else:
45  self.labels['process'] = 'process'
46  self.labels['dict'] = 'process.__dict__'
47 
48  if self.config.online:
49  self.labels['connect'] = 'frontier://FrontierProd'
50  else:
51  self.labels['connect'] = 'frontier://FrontierProd'
52 
53  if self.config.prescale and (self.config.prescale.lower() != 'none'):
54  self.labels['prescale'] = self.config.prescale
55 
56  # get the configuration from ConfdB
57  from confdbOfflineConverter import OfflineConverter
58  self.converter = OfflineConverter(version = self.config.menu.version, database = self.config.menu.database)
59  self.buildPathList()
60  self.buildOptions()
63  self.customize()
64 
66  if not self.config.setup:
67  return
68  ## if --setup is a python file, use directly that file as setup_cff.py
69  if ".py" in self.config.setup:
70  self.config.setupFile = self.config.setup.split(".py")[0]
71  return
72  args = ['--configName', self.config.setup ]
73  args.append('--noedsources')
74  args.append('--nopaths')
75  for key, vals in self.options.iteritems():
76  if vals:
77  args.extend(('--'+key, ','.join(vals)))
78  args.append('--cff')
79  data, err = self.converter.query( *args )
80  if 'ERROR' in err or 'Exhausted Resultset' in err or 'CONFIG_NOT_FOUND' in err:
81  sys.stderr.write("%s: error while retrieving the HLT setup menu\n\n" % os.path.basename(sys.argv[0]))
82  sys.stderr.write(err + "\n\n")
83  sys.exit(1)
84  self.config.setupFile = "setup_"+self.config.setup[1:].replace("/","_")+"_cff"
85  file(self.config.setupFile+".py","w+").write("# This file is automatically generated by hltGetConfiguration.\n" + data)
86 
88  if self.config.menu.run:
89  args = ['--runNumber', self.config.menu.run]
90  else:
91  args = ['--configName', self.config.menu.name ]
92  args.append('--noedsources')
93  for key, vals in self.options.iteritems():
94  if vals:
95  args.extend(('--'+key, ','.join(vals)))
96 
97  data, err = self.converter.query( *args )
98  if 'ERROR' in err or 'Exhausted Resultset' in err or 'CONFIG_NOT_FOUND' in err:
99  sys.stderr.write("%s: error while retrieving the HLT menu\n\n" % os.path.basename(sys.argv[0]))
100  sys.stderr.write(err + "\n\n")
101  sys.exit(1)
102  self.data = data
103 
104  def getPathList(self):
105  if self.config.menu.run:
106  args = ['--runNumber', self.config.menu.run]
107  else:
108  args = ['--configName', self.config.menu.name]
109  args.extend( (
110  '--cff',
111  '--noedsources',
112  '--noes',
113  '--noservices',
114  '--nosequences',
115  '--nomodules'
116  ) )
117 
118  data, err = self.converter.query( *args )
119  if 'ERROR' in err or 'Exhausted Resultset' in err or 'CONFIG_NOT_FOUND' in err:
120  sys.stderr.write("%s: error while retrieving the list of paths from the HLT menu\n\n" % os.path.basename(sys.argv[0]))
121  sys.stderr.write(err + "\n\n")
122  sys.exit(1)
123  filter = re.compile(r' *= *cms.(End)?Path.*')
124  paths = [ filter.sub('', line) for line in data.splitlines() if filter.search(line) ]
125  return paths
126 
127 
128  @staticmethod
129  def expandWildcards(globs, collection):
130  # expand a list of unix-style wildcards matching a given collection
131  # wildcards with no matches are silently discarded
132  matches = []
133  for glob in globs:
134  negate = ''
135  if glob[0] == '-':
136  negate = '-'
137  glob = glob[1:]
138  # translate a unix-style glob expression into a regular expression
139  filter = re.compile(r'^' + glob.replace('?', '.').replace('*', '.*').replace('[!', '[^') + r'$')
140  matches.extend( negate + element for element in collection if filter.match(element) )
141  return matches
142 
143 
144  @staticmethod
145  def consolidateNegativeList(elements):
146  # consolidate a list of path exclusions and re-inclusions
147  # the result is the list of paths to be removed from the dump
148  result = set()
149  for element in elements:
150  if element[0] == '-':
151  result.add( element )
152  else:
153  result.discard( '-' + element )
154  return sorted( element for element in result )
155 
156  @staticmethod
157  def consolidatePositiveList(elements):
158  # consolidate a list of path selection and re-exclusions
159  # the result is the list of paths to be included in the dump
160  result = set()
161  for element in elements:
162  if element[0] == '-':
163  result.discard( element[1:] )
164  else:
165  result.add( element )
166  return sorted( element for element in result )
167 
168 
169  # dump the final configuration
170  def dump(self):
171  self.data = self.data % self.labels
172  if self.config.fragment:
173  self.data = re.sub( r'\bprocess\b', 'fragment', self.data )
174  self.data = re.sub( r'\bProcess\b', 'ProcessFragment', self.data )
175  return self.data
176 
177 
178  # add specific customizations
179  def specificCustomize(self):
180  # specific customizations now live in HLTrigger.Configuration.customizeHLTforALL.customizeHLTforAll(.,.)
181  if self.config.fragment:
182  self.data += """
183 # add specific customizations
184 from HLTrigger.Configuration.customizeHLTforALL import customizeHLTforAll
185 fragment = customizeHLTforAll(fragment,"%s")
186 """ % (self.config.type)
187  else:
188  if self.config.type=="Fake":
189  prefix = "run1"
190  else:
191  prefix = "run2"
192  _gtData = "auto:"+prefix+"_hlt_"+self.config.type
193  _gtMc = "auto:"+prefix+"_mc_" +self.config.type
194  self.data += """
195 # add specific customizations
196 _customInfo = {}
197 _customInfo['menuType' ]= "%s"
198 _customInfo['globalTags']= {}
199 _customInfo['globalTags'][True ] = "%s"
200 _customInfo['globalTags'][False] = "%s"
201 _customInfo['inputFiles']={}
202 _customInfo['inputFiles'][True] = "file:RelVal_Raw_%s_DATA.root"
203 _customInfo['inputFiles'][False] = "file:RelVal_Raw_%s_MC.root"
204 _customInfo['maxEvents' ]= %s
205 _customInfo['globalTag' ]= "%s"
206 _customInfo['inputFile' ]= %s
207 _customInfo['realData' ]= %s
208 from HLTrigger.Configuration.customizeHLTforALL import customizeHLTforAll
209 %%(process)s = customizeHLTforAll(%%(process)s,"%s",_customInfo)
210 """ % (self.config.type,_gtData,_gtMc,self.config.type,self.config.type,self.config.events,self.config.globaltag,self.source,self.config.data,self.config.type)
211 
212  self.data += """
213 from HLTrigger.Configuration.customizeHLTforCMSSW import customizeHLTforCMSSW
214 %%(process)s = customizeHLTforCMSSW(%%(process)s,"%s")
215 """ % (self.config.type)
216 
217  # Eras-based customisations
218  self.data += """
219 # Eras-based customisations
220 from HLTrigger.Configuration.Eras import modifyHLTforEras
221 modifyHLTforEras(%(process)s)
222 """
223  # add the user-defined customization functions, if any
224  if self.config.customise:
225  self.data += "\n"
226  self.data += "#User-defined customization functions\n"
227  for customise in self.config.customise.split(","):
228  customiseValues = customise.split(".")
229  if len(customiseValues)>=3: raise Exception("--customise option cannot contain more than one dot.")
230  if len(customiseValues)==1:
231  customiseValues.append("customise")
232  customiseValues[0] = customiseValues[0].replace("/",".")
233  self.data += "from "+customiseValues[0]+" import "+customiseValues[1]+"\n"
234  self.data += "process = "+customiseValues[1]+"(process)\n"
235 
236  # customize the configuration according to the options
237  def customize(self):
238 
239  # adapt the source to the current scenario
240  if not self.config.fragment:
241  self.build_source()
242 
243  # manual override some parameters
244  if self.config.type in ('HIon', ):
245  if self.config.data:
246  if not self.config.fragment:
247  self._fix_parameter( type = 'InputTag', value = 'rawDataCollector', replace = 'rawDataRepacker')
248 
249  # if requested, remove the HLT prescales
250  self.fixPrescales()
251 
252  # if requested, override all ED/HLTfilters to always pass ("open" mode)
253  self.instrumentOpenMode()
254 
255  # if requested, change all HLTTriggerTypeFilter EDFilters to accept only error events (SelectedTriggerType = 0)
257 
258  # if requested, instrument the self with the modules and EndPath needed for timing studies
259  self.instrumentTiming()
260 
261  # if requested, override the L1 self from the GlobalTag (Xml)
262  self.overrideL1MenuXml()
263 
264  # if requested, run the L1 emulator
265  self.runL1Emulator()
266 
267  # add process.load("setup_cff")
268  self.loadSetupCff()
269 
270  if self.config.fragment:
271  self.data += """
272 # dummyfy hltGetConditions in cff's
273 if 'hltGetConditions' in %(dict)s and 'HLTriggerFirstPath' in %(dict)s :
274  %(process)s.hltDummyConditions = cms.EDFilter( "HLTBool",
275  result = cms.bool( True )
276  )
277  %(process)s.HLTriggerFirstPath.replace(%(process)s.hltGetConditions,%(process)s.hltDummyConditions)
278 """
279 
280  else:
281 
282  # override the process name and adapt the relevant filters
283  self.overrideProcessName()
284 
285  # select specific Eras
286  self.addEras()
287 
288  # override the output modules to output root files
289  self.overrideOutput()
290 
291  # add global options
292  self.addGlobalOptions()
293 
294  # if requested or necessary, override the GlobalTag and connection strings (incl. L1!)
295  self.overrideGlobalTag()
296 
297  # request summary informations from the MessageLogger
298  self.updateMessageLogger()
299 
300  # replace DQMStore and DQMRootOutputModule with a configuration suitable for running offline
301  self.instrumentDQM()
302 
303  # load 5.2.x JECs, until they are in the GlobalTag
304 # self.loadAdditionalConditions('load 5.2.x JECs',
305 # {
306 # 'record' : 'JetCorrectionsRecord',
307 # 'tag' : 'JetCorrectorParametersCollection_AK5Calo_2012_V8_hlt_mc',
308 # 'label' : 'AK5CaloHLT',
309 # 'connect' : '%(connect)s/CMS_CONDITIONS'
310 # }, {
311 # 'record' : 'JetCorrectionsRecord',
312 # 'tag' : 'JetCorrectorParametersCollection_AK5PF_2012_V8_hlt_mc',
313 # 'label' : 'AK5PFHLT',
314 # 'connect' : '%(connect)s/CMS_CONDITIONS'
315 # }, {
316 # 'record' : 'JetCorrectionsRecord',
317 # 'tag' : 'JetCorrectorParametersCollection_AK5PFchs_2012_V8_hlt_mc',
318 # 'label' : 'AK5PFchsHLT',
319 # 'connect' : '%(connect)s/CMS_CONDITIONS'
320 # }
321 # )
322 
323  # add specific customisations
324  self.specificCustomize()
325 
326 
327  def addGlobalOptions(self):
328  # add global options
329  self.data += """
330 # limit the number of events to be processed
331 %%(process)s.maxEvents = cms.untracked.PSet(
332  input = cms.untracked.int32( %d )
333 )
334 """ % self.config.events
335 
336  if not self.config.profiling:
337  self.data += """
338 # enable TrigReport, TimeReport and MultiThreading
339 %(process)s.options = cms.untracked.PSet(
340  wantSummary = cms.untracked.bool( True ),
341  numberOfThreads = cms.untracked.uint32( 4 ),
342  numberOfStreams = cms.untracked.uint32( 0 ),
343  sizeOfStackForThreadsInKB = cms.untracked.uint32( 10*1024 )
344 )
345 """
346 
347  def _fix_parameter(self, **args):
348  """arguments:
349  name: parameter name (optional)
350  type: parameter type (look for tracked and untracked variants)
351  value: original value
352  replace: replacement value
353  """
354  if 'name' in args:
355  self.data = re.sub(
356  r'%(name)s = cms(?P<tracked>(?:\.untracked)?)\.%(type)s\( (?P<quote>["\']?)%(value)s(?P=quote)' % args,
357  r'%(name)s = cms\g<tracked>.%(type)s( \g<quote>%(replace)s\g<quote>' % args,
358  self.data)
359  else:
360  self.data = re.sub(
361  r'cms(?P<tracked>(?:\.untracked)?)\.%(type)s\( (?P<quote>["\']?)%(value)s(?P=quote)' % args,
362  r'cms\g<tracked>.%(type)s( \g<quote>%(replace)s\g<quote>' % args,
363  self.data)
364 
365 
366  def fixPrescales(self):
367  # update the PrescaleService to match the new list of paths
368  if self.options['paths']:
369  if self.options['paths'][0][0] == '-':
370  # drop requested paths
371  for minuspath in self.options['paths']:
372  path = minuspath[1:]
373  self.data = re.sub(r' cms.PSet\( pathName = cms.string\( "%s" \),\n prescales = cms.vuint32\( .* \)\n \),?\n' % path, '', self.data)
374  else:
375  # keep requested paths
376  for path in self.all_paths:
377  if path not in self.options['paths']:
378  self.data = re.sub(r' cms.PSet\( pathName = cms.string\( "%s" \),\n prescales = cms.vuint32\( .* \)\n \),?\n' % path, '', self.data)
379 
380  if self.config.prescale and (self.config.prescale.lower() != 'none'):
381  # TO DO: check that the requested prescale column is valid
382  self.data += """
383 # force the use of a specific HLT prescale column
384 if 'PrescaleService' in %(dict)s:
385  %(process)s.PrescaleService.forceDefault = True
386  %(process)s.PrescaleService.lvl1DefaultLabel = '%(prescale)s'
387 """
388 
389 
391  if self.config.open:
392  # find all EDfilters
393  filters = [ match[1] for match in re.findall(r'(process\.)?\b(\w+) = cms.EDFilter', self.data) ]
394  re_sequence = re.compile( r'cms\.(Path|Sequence)\((.*)\)' )
395  # remove existing 'cms.ignore' and '~' modifiers
396  self.data = re_sequence.sub( lambda line: re.sub( r'cms\.ignore *\( *((process\.)?\b(\w+)) *\)', r'\1', line.group(0) ), self.data )
397  self.data = re_sequence.sub( lambda line: re.sub( r'~', '', line.group(0) ), self.data )
398  # wrap all EDfilters with "cms.ignore( ... )", 1000 at a time (python 2.6 complains for too-big regular expressions)
399  for some in splitter(filters, 1000):
400  re_filters = re.compile( r'\b((process\.)?(' + r'|'.join(some) + r'))\b' )
401  self.data = re_sequence.sub( lambda line: re_filters.sub( r'cms.ignore( \1 )', line.group(0) ), self.data )
402 
403 
405  if self.config.errortype:
406  # change all HLTTriggerTypeFilter EDFilters to accept only error events (SelectedTriggerType = 0)
407  self._fix_parameter(name = 'SelectedTriggerType', type ='int32', value = '1', replace = '0')
408  self._fix_parameter(name = 'SelectedTriggerType', type ='int32', value = '2', replace = '0')
409  self._fix_parameter(name = 'SelectedTriggerType', type ='int32', value = '3', replace = '0')
410 
411 
412  def overrideGlobalTag(self):
413  # overwrite GlobalTag
414  # the logic is:
415  # - always set the correct connection string and pfnPrefix
416  # - if a GlobalTag is specified on the command line:
417  # - override the global tag
418  # - if the GT is "auto:...", insert the code to read it from Configuration.AlCa.autoCond
419  # - if a GlobalTag is NOT specified on the command line:
420  # - when running on data, do nothing, and keep the global tag in the menu
421  # - when running on mc, take the GT from the configuration.type
422 
423  # override the GlobalTag connection string and pfnPrefix
424  text = """
425 # override the GlobalTag, connection string and pfnPrefix
426 if 'GlobalTag' in %(dict)s:
427 """
428 
429  # when running on MC, override the global tag even if not specified on the command line
430  if not self.config.data and not self.config.globaltag:
431  if self.config.type in globalTag:
432  self.config.globaltag = globalTag[self.config.type]
433  else:
434  self.config.globaltag = globalTag['GRun']
435 
436  # if requested, override the L1 menu from the GlobalTag (using the same connect as the GlobalTag itself)
437  if self.config.l1.override:
438  self.config.l1.tag = self.config.l1.override
439  self.config.l1.record = 'L1TUtmTriggerMenuRcd'
440  self.config.l1.connect = '%(connect)s/CMS_CONDITIONS'
441  self.config.l1.label = ''
442  if not self.config.l1.snapshotTime:
443  self.config.l1.snapshotTime = '9999-12-31 23:59:59.000'
444  self.config.l1cond = '%(tag)s,%(record)s,%(connect)s,%(label)s,%(snapshotTime)s' % self.config.l1.__dict__
445  else:
446  self.config.l1cond = None
447 
448  if self.config.globaltag or self.config.l1cond:
449  text += " from Configuration.AlCa.GlobalTag import GlobalTag as customiseGlobalTag\n"
450  text += " %(process)s.GlobalTag = customiseGlobalTag(%(process)s.GlobalTag"
451  if self.config.globaltag:
452  text += ", globaltag = %s" % repr(self.config.globaltag)
453  if self.config.l1cond:
454  text += ", conditions = %s" % repr(self.config.l1cond)
455  text += ")\n"
456 
457  text += """ %(process)s.GlobalTag.connect = '%(connect)s/CMS_CONDITIONS'
458 """
459 # %(process)s.GlobalTag.pfnPrefix = cms.untracked.string('%(connect)s/')
460 # for pset in %(process)s.GlobalTag.toGet.value():
461 # pset.connect = pset.connect.value().replace('frontier://FrontierProd/', '%(connect)s/')
462 # # fix for multi-run processing
463 # %(process)s.GlobalTag.RefreshEachRun = cms.untracked.bool( False )
464 # %(process)s.GlobalTag.ReconnectEachRun = cms.untracked.bool( False )
465  self.data += text
466 
467  def overrideL1MenuXml(self):
468  # if requested, override the GlobalTag's L1T menu from an Xml file
469  if self.config.l1Xml.XmlFile:
470  text = """
471 # override the GlobalTag's L1T menu from an Xml file
472 from HLTrigger.Configuration.CustomConfigs import L1XML
473 %%(process)s = L1XML(%%(process)s,"%s")
474 """ % (self.config.l1Xml.XmlFile)
475  self.data += text
476 
477  def runL1Emulator(self):
478  # if requested, run the Full L1T emulator, then repack the data into a new RAW collection, to be used by the HLT
479  if self.config.emulator:
480  text = """
481 # run the Full L1T emulator, then repack the data into a new RAW collection, to be used by the HLT
482 from HLTrigger.Configuration.CustomConfigs import L1REPACK
483 %%(process)s = L1REPACK(%%(process)s,"%s")
484 """ % (self.config.emulator)
485  self.data += text
486 
487  def overrideOutput(self):
488  # override the "online" ShmStreamConsumer output modules with "offline" PoolOutputModule's
489  self.data = re.sub(
490  r'\b(process\.)?hltOutput(\w+) *= *cms\.OutputModule\( *"ShmStreamConsumer" *,',
491  r'%(process)s.hltOutput\2 = cms.OutputModule( "PoolOutputModule",\n fileName = cms.untracked.string( "output\2.root" ),\n fastCloning = cms.untracked.bool( False ),\n dataset = cms.untracked.PSet(\n filterName = cms.untracked.string( "" ),\n dataTier = cms.untracked.string( "RAW" )\n ),',
492  self.data
493  )
494 
495  if not self.config.fragment and self.config.output == 'full':
496  # add a single "keep *" output
497  self.data += """
498 # add a single "keep *" output
499 %(process)s.hltOutputFULL = cms.OutputModule( "PoolOutputModule",
500  fileName = cms.untracked.string( "outputFULL.root" ),
501  fastCloning = cms.untracked.bool( False ),
502  dataset = cms.untracked.PSet(
503  dataTier = cms.untracked.string( 'RECO' ),
504  filterName = cms.untracked.string( '' )
505  ),
506  outputCommands = cms.untracked.vstring( 'keep *' )
507 )
508 %(process)s.FULLOutput = cms.EndPath( %(process)s.hltOutputFULL )
509 """
510  # select specific Eras
511  def addEras(self):
512  if self.config.eras is None:
513  return
514  self.data = re.sub(r'process = cms.Process\( *"\w+"', 'from Configuration.StandardSequences.Eras import eras\n\g<0>, '+', '.join('eras.' + era for era in self.config.eras.split(',')), self.data)
515 
516  # select specific Eras
517  def loadSetupCff(self):
518  if self.config.setup is None:
519  return
520  processLine = self.data.find("\n",self.data.find("cms.Process"))
521  self.data = self.data[:processLine]+'\nprocess.load("%s")'%self.config.setupFile+self.data[processLine:]
522 
523  # override the process name and adapt the relevant filters
525  if self.config.name is None:
526  return
527 
528  # sanitise process name
529  self.config.name = self.config.name.replace("_","")
530  # override the process name
531  quote = '[\'\"]'
532  self.data = re.compile(r'^(process\s*=\s*cms\.Process\(\s*' + quote + r')\w+(' + quote + r'\s*\).*)$', re.MULTILINE).sub(r'\1%s\2' % self.config.name, self.data, 1)
533 
534  # the following was stolen and adapted from HLTrigger.Configuration.customL1THLT_Options
535  self.data += """
536 # adapt HLT modules to the correct process name
537 if 'hltTrigReport' in %%(dict)s:
538  %%(process)s.hltTrigReport.HLTriggerResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
539 
540 if 'hltPreExpressCosmicsOutputSmart' in %%(dict)s:
541  %%(process)s.hltPreExpressCosmicsOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
542 
543 if 'hltPreExpressOutputSmart' in %%(dict)s:
544  %%(process)s.hltPreExpressOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
545 
546 if 'hltPreDQMForHIOutputSmart' in %%(dict)s:
547  %%(process)s.hltPreDQMForHIOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
548 
549 if 'hltPreDQMForPPOutputSmart' in %%(dict)s:
550  %%(process)s.hltPreDQMForPPOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
551 
552 if 'hltPreHLTDQMResultsOutputSmart' in %%(dict)s:
553  %%(process)s.hltPreHLTDQMResultsOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
554 
555 if 'hltPreHLTDQMOutputSmart' in %%(dict)s:
556  %%(process)s.hltPreHLTDQMOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
557 
558 if 'hltPreHLTMONOutputSmart' in %%(dict)s:
559  %%(process)s.hltPreHLTMONOutputSmart.hltResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
560 
561 if 'hltDQMHLTScalers' in %%(dict)s:
562  %%(process)s.hltDQMHLTScalers.triggerResults = cms.InputTag( 'TriggerResults', '', '%(name)s' )
563  %%(process)s.hltDQMHLTScalers.processname = '%(name)s'
564 
565 if 'hltDQML1SeedLogicScalers' in %%(dict)s:
566  %%(process)s.hltDQML1SeedLogicScalers.processname = '%(name)s'
567 """ % self.config.__dict__
568 
569 
571  # request summary informations from the MessageLogger
572  self.data += """
573 if 'MessageLogger' in %(dict)s:
574  %(process)s.MessageLogger.categories.append('TriggerSummaryProducerAOD')
575  %(process)s.MessageLogger.categories.append('L1GtTrigReport')
576  %(process)s.MessageLogger.categories.append('L1TGlobalSummary')
577  %(process)s.MessageLogger.categories.append('HLTrigReport')
578  %(process)s.MessageLogger.categories.append('FastReport')
579 """
580 
581 
582  def loadAdditionalConditions(self, comment, *conditions):
583  # load additional conditions
584  self.data += """
585 # %s
586 if 'GlobalTag' in %%(dict)s:
587 """ % comment
588  for condition in conditions:
589  self.data += """ %%(process)s.GlobalTag.toGet.append(
590  cms.PSet(
591  record = cms.string( '%(record)s' ),
592  tag = cms.string( '%(tag)s' ),
593  label = cms.untracked.string( '%(label)s' ),
594  connect = cms.untracked.string( '%(connect)s' )
595  )
596  )
597 """ % condition
598 
599 
600  def loadCffCommand(self, module):
601  # load a cfi or cff module
602  if self.config.fragment:
603  return 'from %s import *\n' % module
604  else:
605  return 'process.load( "%s" )\n' % module
606 
607  def loadCff(self, module):
608  self.data += self.loadCffCommand(module)
609 
610 
611  def overrideParameters(self, module, parameters):
612  # override a module's parameter if the module is present in the configuration
613  self.data += "if '%s' in %%(dict)s:\n" % module
614  for (parameter, value) in parameters:
615  self.data += " %%(process)s.%s.%s = %s\n" % (module, parameter, value)
616  self.data += "\n"
617 
618 
619  def instrumentTiming(self):
620  if self.config.profiling:
621  # instrument the menu for profiling: remove the HLTAnalyzerEndpath, add/override the HLTriggerFirstPath, with hltGetRaw and hltGetConditions
622  text = ''
623 
624  if not 'hltGetRaw' in self.data:
625  # add hltGetRaw
626  text += """
627 %(process)s.hltGetRaw = cms.EDAnalyzer( "HLTGetRaw",
628  RawDataCollection = cms.InputTag( "rawDataCollector" )
629 )
630 """
631 
632  if not 'hltGetConditions' in self.data:
633  # add hltGetConditions
634  text += """
635 %(process)s.hltGetConditions = cms.EDAnalyzer( 'EventSetupRecordDataGetter',
636  verbose = cms.untracked.bool( False ),
637  toGet = cms.VPSet( )
638 )
639 """
640 
641  if not 'hltBoolFalse' in self.data:
642  # add hltBoolFalse
643  text += """
644 %(process)s.hltBoolFalse = cms.EDFilter( "HLTBool",
645  result = cms.bool( False )
646 )
647 """
648 
649  # add the definition of HLTriggerFirstPath
650  # FIXME in a cff, should also update the HLTSchedule
651  text += """
652 %(process)s.HLTriggerFirstPath = cms.Path( %(process)s.hltGetRaw + %(process)s.hltGetConditions + %(process)s.hltBoolFalse )
653 """
654  self.data = re.sub(r'.*cms\.(End)?Path.*', text + r'\g<0>', self.data, 1)
655 
656 
657  # instrument the menu with the Service, EDProducer and EndPath needed for timing studies
658  # FIXME in a cff, should also update the HLTSchedule
659  if self.config.timing:
660  self.data += """
661 # instrument the menu with the modules and EndPath needed for timing studies
662 """
663 
664  self.data += '\n# configure the FastTimerService\n'
665  if not 'FastTimerService' in self.data:
666  self.loadCff('HLTrigger.Timer.FastTimerService_cfi')
667 
668  self.data += """# print a text summary at the end of the job
669 %(process)s.FastTimerService.printJobSummary = True
670 
671 # enable DQM plots
672 %(process)s.FastTimerService.enableDQM = True
673 
674 # disable per-module DQM plots
675 %(process)s.FastTimerService.enableDQMbyModule = False
676 
677 # enable per-event DQM plots by lumisection
678 %(process)s.FastTimerService.enableDQMbyLumiSection = True
679 %(process)s.FastTimerService.dqmLumiSectionsRange = 2500
680 
681 # set the time resolution of the DQM plots
682 %(process)s.FastTimerService.dqmTimeRange = 1000.
683 %(process)s.FastTimerService.dqmTimeResolution = 5.
684 %(process)s.FastTimerService.dqmPathTimeRange = 100.
685 %(process)s.FastTimerService.dqmPathTimeResolution = 0.5
686 %(process)s.FastTimerService.dqmModuleTimeRange = 40.
687 %(process)s.FastTimerService.dqmModuleTimeResolution = 0.2
688 
689 # set the base DQM folder for the plots
690 %(process)s.FastTimerService.dqmPath = 'HLT/TimerService'
691 %(process)s.FastTimerService.enableDQMbyProcesses = True
692 """
693 
694 
695  def instrumentDQM(self):
696  if not self.config.hilton:
697  # remove any reference to the hltDQMFileSaver
698  if 'hltDQMFileSaver' in self.data:
699  self.data = re.sub(r'\b(process\.)?hltDQMFileSaver \+ ', '', self.data)
700  self.data = re.sub(r' \+ \b(process\.)?hltDQMFileSaver', '', self.data)
701  self.data = re.sub(r'\b(process\.)?hltDQMFileSaver', '', self.data)
702 
703  # instrument the HLT menu with DQMStore and DQMRootOutputModule suitable for running offline
704  dqmstore = "\n# load the DQMStore and DQMRootOutputModule\n"
705  dqmstore += self.loadCffCommand('DQMServices.Core.DQMStore_cfi')
706  dqmstore += "%(process)s.DQMStore.enableMultiThread = True\n"
707  dqmstore += """
708 %(process)s.dqmOutput = cms.OutputModule("DQMRootOutputModule",
709  fileName = cms.untracked.string("DQMIO.root")
710 )
711 """
712 
713  empty_path = re.compile(r'.*\b(process\.)?DQMOutput = cms\.EndPath\( *\).*')
714  other_path = re.compile(r'(.*\b(process\.)?DQMOutput = cms\.EndPath\()(.*)')
715  if empty_path.search(self.data):
716  # replace an empty DQMOutput path
717  self.data = empty_path.sub(dqmstore + '\n%(process)s.DQMOutput = cms.EndPath( %(process)s.dqmOutput )\n', self.data)
718  elif other_path.search(self.data):
719  # prepend the dqmOutput to the DQMOutput path
720  self.data = other_path.sub(dqmstore + r'\g<1> %(process)s.dqmOutput +\g<3>', self.data)
721  else:
722  # ceate a new DQMOutput path with the dqmOutput module
723  self.data += dqmstore
724  self.data += '\n%(process)s.DQMOutput = cms.EndPath( %(process)s.dqmOutput )\n'
725 
726 
727  @staticmethod
728  def dumppaths(paths):
729  sys.stderr.write('Path selection:\n')
730  for path in paths:
731  sys.stderr.write('\t%s\n' % path)
732  sys.stderr.write('\n\n')
733 
734  def buildPathList(self):
735  self.all_paths = self.getPathList()
736 
737  if self.config.paths:
738  # no path list was requested, dump the full table, minus unsupported / unwanted paths
739  paths = self.config.paths.split(',')
740  else:
741  # dump only the requested paths, plus the eventual output endpaths
742  paths = []
743 
744  if self.config.fragment or self.config.output in ('none', 'full'):
745  # 'full' removes all outputs (same as 'none') and then adds a single "keep *" output (see the overrideOutput method)
746  if self.config.paths:
747  # paths are removed by default
748  pass
749  else:
750  # drop all output endpaths
751  paths.append( "-*Output" )
752  paths.append( "-RatesMonitoring")
753  paths.append( "-DQMHistograms")
754  elif self.config.output == 'minimal':
755  # drop all output endpaths but HLTDQMResultsOutput
756  if self.config.paths:
757  paths.append( "HLTDQMResultsOutput" )
758  else:
759  paths.append( "-*Output" )
760  paths.append( "-RatesMonitoring")
761  paths.append( "-DQMHistograms")
762  paths.append( "HLTDQMResultsOutput" )
763  else:
764  # keep / add back all output endpaths
765  if self.config.paths:
766  paths.append( "*Output" )
767  else:
768  pass # paths are kepy by default
769 
770  # drop unwanted paths for profiling (and timing studies)
771  if self.config.profiling:
772  paths.append( "-HLTriggerFirstPath" )
773  paths.append( "-HLTAnalyzerEndpath" )
774 
775  # this should never be in any dump (nor online menu)
776  paths.append( "-OfflineOutput" )
777 
778  # expand all wildcards
779  paths = self.expandWildcards(paths, self.all_paths)
780 
781  if self.config.paths:
782  # do an "additive" consolidation
783  self.options['paths'] = self.consolidatePositiveList(paths)
784  if not self.options['paths']:
785  raise RuntimeError('Error: option "--paths %s" does not select any valid paths' % self.config.paths)
786  else:
787  # do a "subtractive" consolidation
788  self.options['paths'] = self.consolidateNegativeList(paths)
789 
790 
791  def buildOptions(self):
792  # common configuration for all scenarios
793  self.options['services'].append( "-DQM" )
794  self.options['services'].append( "-FUShmDQMOutputService" )
795  self.options['services'].append( "-MicroStateService" )
796  self.options['services'].append( "-ModuleWebRegistry" )
797  self.options['services'].append( "-TimeProfilerService" )
798 
799  # remove the DAQ modules and the online definition of the DQMStore and DQMFileSaver
800  # unless a hilton-like configuration has been requested
801  if not self.config.hilton:
802  self.options['services'].append( "-EvFDaqDirector" )
803  self.options['services'].append( "-FastMonitoringService" )
804  self.options['services'].append( "-DQMStore" )
805  self.options['modules'].append( "-hltDQMFileSaver" )
806 
807  if self.config.fragment:
808  # extract a configuration file fragment
809  self.options['essources'].append( "-GlobalTag" )
810  self.options['essources'].append( "-HepPDTESSource" )
811  self.options['essources'].append( "-XMLIdealGeometryESSource" )
812  self.options['essources'].append( "-eegeom" )
813  self.options['essources'].append( "-es_hardcode" )
814  self.options['essources'].append( "-magfield" )
815 
816  self.options['esmodules'].append( "-AutoMagneticFieldESProducer" )
817  self.options['esmodules'].append( "-SlaveField0" )
818  self.options['esmodules'].append( "-SlaveField20" )
819  self.options['esmodules'].append( "-SlaveField30" )
820  self.options['esmodules'].append( "-SlaveField35" )
821  self.options['esmodules'].append( "-SlaveField38" )
822  self.options['esmodules'].append( "-SlaveField40" )
823  self.options['esmodules'].append( "-VBF0" )
824  self.options['esmodules'].append( "-VBF20" )
825  self.options['esmodules'].append( "-VBF30" )
826  self.options['esmodules'].append( "-VBF35" )
827  self.options['esmodules'].append( "-VBF38" )
828  self.options['esmodules'].append( "-VBF40" )
829  self.options['esmodules'].append( "-CSCGeometryESModule" )
830  self.options['esmodules'].append( "-CaloGeometryBuilder" )
831  self.options['esmodules'].append( "-CaloTowerHardcodeGeometryEP" )
832  self.options['esmodules'].append( "-CastorHardcodeGeometryEP" )
833  self.options['esmodules'].append( "-DTGeometryESModule" )
834  self.options['esmodules'].append( "-EcalBarrelGeometryEP" )
835  self.options['esmodules'].append( "-EcalElectronicsMappingBuilder" )
836  self.options['esmodules'].append( "-EcalEndcapGeometryEP" )
837  self.options['esmodules'].append( "-EcalLaserCorrectionService" )
838  self.options['esmodules'].append( "-EcalPreshowerGeometryEP" )
839  self.options['esmodules'].append( "-HcalHardcodeGeometryEP" )
840  self.options['esmodules'].append( "-HcalTopologyIdealEP" )
841  self.options['esmodules'].append( "-MuonNumberingInitialization" )
842  self.options['esmodules'].append( "-ParametrizedMagneticFieldProducer" )
843  self.options['esmodules'].append( "-RPCGeometryESModule" )
844  self.options['esmodules'].append( "-SiStripGainESProducer" )
845  self.options['esmodules'].append( "-SiStripRecHitMatcherESProducer" )
846  self.options['esmodules'].append( "-SiStripQualityESProducer" )
847  self.options['esmodules'].append( "-StripCPEfromTrackAngleESProducer" )
848  self.options['esmodules'].append( "-TrackerDigiGeometryESModule" )
849  self.options['esmodules'].append( "-TrackerGeometricDetESModule" )
850  self.options['esmodules'].append( "-VolumeBasedMagneticFieldESProducer" )
851  self.options['esmodules'].append( "-ZdcHardcodeGeometryEP" )
852  self.options['esmodules'].append( "-hcal_db_producer" )
853  self.options['esmodules'].append( "-L1GtTriggerMaskAlgoTrigTrivialProducer" )
854  self.options['esmodules'].append( "-L1GtTriggerMaskTechTrigTrivialProducer" )
855  self.options['esmodules'].append( "-hltESPEcalTrigTowerConstituentsMapBuilder" )
856  self.options['esmodules'].append( "-hltESPGlobalTrackingGeometryESProducer" )
857  self.options['esmodules'].append( "-hltESPMuonDetLayerGeometryESProducer" )
858  self.options['esmodules'].append( "-hltESPTrackerRecoGeometryESProducer" )
859  self.options['esmodules'].append( "-trackerTopology" )
860 
861  self.options['esmodules'].append( "-CaloTowerGeometryFromDBEP" )
862  self.options['esmodules'].append( "-CastorGeometryFromDBEP" )
863  self.options['esmodules'].append( "-EcalBarrelGeometryFromDBEP" )
864  self.options['esmodules'].append( "-EcalEndcapGeometryFromDBEP" )
865  self.options['esmodules'].append( "-EcalPreshowerGeometryFromDBEP" )
866  self.options['esmodules'].append( "-HcalGeometryFromDBEP" )
867  self.options['esmodules'].append( "-ZdcGeometryFromDBEP" )
868  self.options['esmodules'].append( "-XMLFromDBSource" )
869  self.options['esmodules'].append( "-sistripconn" )
870 
871  self.options['services'].append( "-MessageLogger" )
872 
873  self.options['psets'].append( "-maxEvents" )
874  self.options['psets'].append( "-options" )
875 
876  if self.config.fragment or (self.config.prescale and (self.config.prescale.lower() == 'none')):
877  self.options['services'].append( "-PrescaleService" )
878 
879  if self.config.fragment or self.config.timing:
880  self.options['services'].append( "-FastTimerService" )
881 
882 
883  def append_filenames(self, name, filenames):
884  if len(filenames) > 255:
885  token_open = "( *("
886  token_close = ") )"
887  else:
888  token_open = "("
889  token_close = ")"
890 
891  self.data += " %s = cms.untracked.vstring%s\n" % (name, token_open)
892  for line in filenames:
893  self.data += " '%s',\n" % line
894  self.data += " %s,\n" % (token_close)
895 
896 
897  def expand_filenames(self, input):
898  # check if the input is a dataset or a list of files
899  if input[0:8] == 'dataset:':
900  from dasFileQuery import dasFileQuery
901  # extract the dataset name, and use DAS to fine the list of LFNs
902  dataset = input[8:]
903  files = dasFileQuery(dataset)
904  else:
905  # assume a comma-separated list of input files
906  files = self.config.input.split(',')
907  return files
908 
909  def build_source(self):
910  if self.config.input:
911  # if a dataset or a list of input files was given, use it
912  self.source = self.expand_filenames(self.config.input)
913  elif self.config.online:
914  # online we always run on data
915  self.source = [ "file:/tmp/InputCollection.root" ]
916  elif self.config.data:
917  # offline we can run on data...
918  self.source = [ "file:RelVal_Raw_%s_DATA.root" % self.config.type ]
919  else:
920  # ...or on mc
921  self.source = [ "file:RelVal_Raw_%s_MC.root" % self.config.type ]
922 
923  if self.config.parent:
924  # if a dataset or a list of input files was given for the parent data, use it
925  self.parent = self.expand_filenames(self.config.parent)
926 
927  self.data += """
928 %(process)s.source = cms.Source( "PoolSource",
929 """
930  self.append_filenames("fileNames", self.source)
931  if (self.parent):
932  self.append_filenames("secondaryFileNames", self.parent)
933  self.data += """\
934  inputCommands = cms.untracked.vstring(
935  'keep *'
936  )
937 )
938 """
def __init__(self, configuration)
Definition: confdb.py:23
def splitter(iterator, n)
Definition: confdb.py:11
def loadSetupCff(self)
Definition: confdb.py:517
def addGlobalOptions(self)
Definition: confdb.py:327
def getSetupConfigurationFromDB(self)
Definition: confdb.py:65
def overrideProcessName(self)
Definition: confdb.py:524
def runL1Emulator(self)
Definition: confdb.py:477
def instrumentErrorEventType(self)
Definition: confdb.py:404
def buildOptions(self)
Definition: confdb.py:791
def replace(string, replacements)
def overrideOutput(self)
Definition: confdb.py:487
def dump(self)
Definition: confdb.py:170
def getPathList(self)
Definition: confdb.py:104
def customize(self)
Definition: confdb.py:237
def addEras(self)
Definition: confdb.py:511
def expand_filenames(self, input)
Definition: confdb.py:897
def updateMessageLogger(self)
Definition: confdb.py:570
def overrideL1MenuXml(self)
Definition: confdb.py:467
def overrideGlobalTag(self)
Definition: confdb.py:412
def specificCustomize(self)
Definition: confdb.py:179
def consolidatePositiveList(elements)
Definition: confdb.py:157
def overrideParameters(self, module, parameters)
Definition: confdb.py:611
def instrumentOpenMode(self)
Definition: confdb.py:390
def dumppaths(paths)
Definition: confdb.py:728
def getRawConfigurationFromDB(self)
Definition: confdb.py:87
def loadAdditionalConditions(self, comment, conditions)
Definition: confdb.py:582
def build_source(self)
Definition: confdb.py:909
def loadCffCommand(self, module)
Definition: confdb.py:600
def instrumentDQM(self)
Definition: confdb.py:695
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def loadCff(self, module)
Definition: confdb.py:607
def buildPathList(self)
Definition: confdb.py:734
def fixPrescales(self)
Definition: confdb.py:366
def consolidateNegativeList(elements)
Definition: confdb.py:145
def write(self, setup)
def instrumentTiming(self)
Definition: confdb.py:619
def expandWildcards(globs, collection)
Definition: confdb.py:129
def _fix_parameter(self, args)
Definition: confdb.py:347
def append_filenames(self, name, filenames)
Definition: confdb.py:883
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