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