CMS 3D CMS Logo

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