CMS 3D CMS Logo

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