CMS 3D CMS Logo

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