Warning, /HLTrigger/Configuration/scripts/hltDumpStream is written in an unsupported language. File is not indexed.
0001 #!/usr/bin/env python3
0002 # -*- coding: utf-8 -*-
0003 """hltDumpStream: print information on streams, primary datasets, triggers and (HLT) prescales of a HLT menu
0004
0005 examples:
0006 # run hltDumpStream on HLT menu used in run 123456 (output in CSV format)
0007 hltConfigFromDB --runNumber 123456 | hltDumpStream --mode csv
0008 # run hltDumpStream on local cfg file hlt.py (output in text format)
0009 hltDumpStream hlt.py --mode text
0010 """
0011 import os
0012 import sys
0013 import argparse
0014 import re
0015 import fnmatch
0016 import operator
0017 from importlib.machinery import SourceFileLoader
0018 import types
0019 import tempfile
0020 import FWCore.ParameterSet.Config as cms
0021
0022 def getPathSeeds(path):
0023 '''list of strings, each corresponding to one of the seeds of the trigger
0024 '''
0025 seeds = []
0026 pathModList = path.expandAndClone()._seq._collection
0027 for pathMod in pathModList:
0028 # skip ignored EDFilters
0029 if pathMod.isOperation() and pathMod.decoration() == '-':
0030 continue
0031
0032 if pathMod.type_() == 'HLTPrescaler':
0033 break
0034
0035 elif pathMod.type_() == 'HLTL1TSeed':
0036 seeds.append(pathMod.L1SeedsLogicalExpression.value())
0037
0038 elif pathMod.type_() == 'TriggerResultsFilter':
0039 trigConds = pathMod.triggerConditions
0040 if len(trigConds) == 1:
0041 seeds.append(trigConds[0])
0042 else:
0043 seeds.append('(' + ') OR ('.join(trigConds) + ')')
0044 return seeds
0045
0046 def getPathSeedsDescription(path):
0047 '''string representing the logical expression of the trigger's seeding
0048 '''
0049 seeds = getPathSeeds(path)
0050 if len(seeds) == 0:
0051 seedDesc = '(none)'
0052 elif len(seeds) == 1:
0053 seedDesc = seeds[0]
0054 else:
0055 seedDesc = '(' + ') AND ('.join(seeds) + ')'
0056 return seedDesc
0057
0058 def getBPTXMatching(path):
0059 '''integer representing the BPTX coincidence information for the given path
0060 '''
0061 bptxDict = {
0062 'hltL1sL1BPTX': False,
0063 'hltL1sL1BPTXPlusOnly': False,
0064 'hltL1sL1BPTXMinusOnly': False,
0065 'hltL1sZeroBias': False,
0066 'hltBPTXCoincidence': False,
0067 }
0068 for bptxMod in bptxDict:
0069 if hasattr(process, bptxMod):
0070 bptxDict[bptxMod] = path.contains(getattr(process, bptxMod))
0071
0072 if bptxDict['hltL1sL1BPTX'] or bptxDict['hltL1sL1BPTXPlusOnly'] or \
0073 bptxDict['hltL1sL1BPTXMinusOnly'] or bptxDict['hltL1sZeroBias']:
0074 bptx = 2
0075 elif bptxDict['hltBPTXCoincidence']:
0076 bptx = 1
0077 else:
0078 bptx = 0
0079 return bptx
0080
0081 def getBPTXMatchingDescription(path):
0082 '''string representing the BPTX coincidence information for the given path
0083 '''
0084 return ' ~='[getBPTXMatching(path)]
0085
0086 def getStreamsInfoFromProcess(process, prescaleValues, numberOfPrescaleColumns):
0087 '''extract the info on streams, datasets and triggers:
0088 the return type is a list of dictionaries, one per stream
0089
0090 each stream dict contains the following entries (key: value)
0091 - name: name of the stream
0092 - path: cms.EndPath associated to the stream
0093 - prescales: list of prescale values (1 per PS column) applied to the EndPath associated to the stream
0094 - smartPrescales: dictionary (path:ps) of smart-prescales applied at stream level
0095 - datasets: list of dataset dictionaries (see below)
0096
0097 every dataset dictionary contains the following entries (key: value)
0098 - name: name of the dataset
0099 - path: cms.Path associated to the dataset, i.e. the "DatasetPath" (path=None if there is no DatasetPath)
0100 - prescales: list of prescale values (1 per PS column) applied to the DatasetPath (a list of 1s if there is no DatasetPath)
0101 - smartPrescales: dictionary (path:ps) of smart-prescales applied at dataset level (a list of 1s if there is no DatasetPath)
0102 - triggers: list of trigger dictionaries (see below)
0103
0104 every trigger dictionary contains the following entries (key: value)
0105 - name: name of the high-level trigger
0106 - path: cms.Path associated to the trigger
0107 - prescales: list of prescale values (1 per PS column) applied to the Path
0108 - bptx: string expressing the BPTX condition used by the trigger (if any)
0109 - seed: string expressing the logical expression seeding the trigger
0110 (this is tipically based on L1-Trigger algorithms,
0111 but in general it can also include selections on other HLT Paths, incl. DatasetPaths);
0112 seed modules are required to precede the HLTPrescaler module of the trigger (if any)
0113 '''
0114
0115 # get hold of Schedule if present
0116 procSchedule = process.schedule_()
0117 if procSchedule == None:
0118 # older HLT configs used "HLTSchedule", which appears under '_Process__partialschedules'
0119 partialScheduleNames = list(process._Process__partialschedules.keys())
0120 if len(partialScheduleNames) == 1:
0121 procSchedule = getattr(process, partialScheduleNames[0])
0122 elif len(partialScheduleNames) > 1:
0123 raise RuntimeError('ERROR -- the process holds multiple partial schedules: '+str(process._Process__partialschedules))
0124
0125 # find list of streams:
0126 # - stream XYZ exists if the configuration contains a EndPath that contains an OutputModule named hltOutputXYZ
0127 # - if more than one such EndPath exists, it is an error (unsupported configuration)
0128 # - if the configuration contains a cms.Schedule, the EndPath is required to be part of the cms.Schedule
0129 # - reliance on the PSet "streams" is minimised:
0130 # - the latter PSet, if present, should be a superset of the streams found in the configuration
0131 # (this is the case for HLT configs containing only a subset of the triggers of a menu, e.g. "hltGetConfiguration --paths [..]")
0132 streams = []
0133
0134 # regex to find smart-prescale value
0135 smartPS_recomp = re.compile(r'(.*)\s*/\s*(\d+)')
0136
0137 # find valid streams based on OutputModules
0138 for outModName in process.outputModules_():
0139 # find stream OutputModules by name: "hltOutput*"
0140 if not outModName.startswith('hltOutput'):
0141 continue
0142 streamName = outModName[len('hltOutput'):]
0143
0144 # find EndPath containing stream OutputModule
0145 streamPath = None
0146 outputModule = process.outputModules_()[outModName]
0147 for efPath in process.endpaths_().values():
0148 if procSchedule != None:
0149 # skip EndPath if not included in the schedule
0150 # (schedule.contains does not seem to be enough, so the index of the EndPath in the schedule is searched;
0151 # if the EndPath is not in the schedule, this search leads to a runtime-error)
0152 try: procSchedule.index(efPath)
0153 except: continue
0154 if efPath.contains(outputModule):
0155 # if streamPath is already set, throw a runtime error:
0156 # no more than one EndPath can hold a given OutputModule in valid HLT configurations
0157 if streamPath != None:
0158 errMsg = 'ERROR -- output module "'+outModName+'" is associated to'
0159 errMsg += ' more than one EndPath: '+str([streamPath.label(), efPath.label()])
0160 raise RuntimeError(errMsg)
0161 streamPath = efPath
0162
0163 # OutputModule not included in any active EndPath
0164 if streamPath == None:
0165 continue
0166
0167 # fill info of all datasets assigned to this stream
0168 datasetsOfStream = []
0169
0170 datasetNames = []
0171 usesDatasetPaths = False
0172
0173 pathsOfStream = sorted(list(set(fooPathName for fooPathName in outputModule.SelectEvents.SelectEvents)))
0174 datasetPathsOfStream = [foo for foo in pathsOfStream if foo.startswith('Dataset_')]
0175
0176 if len(datasetPathsOfStream) == 0:
0177 # no DatasetPaths found (older HLT menus, before Run 3), fall back on the "streams" PSet
0178 datasetNames = sorted(list(set(getattr(process.streams, streamName))))
0179
0180 elif len(datasetPathsOfStream) == len(pathsOfStream):
0181 # HLT menus with OutputModules selecting on DatasetPaths (HLT menus of 2022 and later)
0182 datasetNames = [foo[len('Dataset_'):] for foo in datasetPathsOfStream]
0183 usesDatasetPaths = True
0184
0185 else:
0186 # only a subset of the Paths in the OutputModule's SelectEvents are DatasetPaths:
0187 # this is not expected to happen in valid HLT configurations
0188 errMsg = 'ERROR -- output module "'+outModName+'" has a mixture of DatasetPaths and non-DatasetPaths'
0189 errMsg += ' in its SelectEvents.SelectEvents PSet: '+str(outputModule.SelectEvents.SelectEvents)
0190 raise RuntimeError(errMsg)
0191
0192 for datasetName in datasetNames:
0193
0194 datasetPath = None
0195 datasetPrescales = [1]*numberOfPrescaleColumns
0196 datasetSmartPrescales = {}
0197
0198 if not usesDatasetPaths:
0199 # for non-DatasetPaths, fall back on "datasets" PSet
0200 pathNames = sorted(list(set(getattr(process.datasets, datasetName))))
0201 for foo in pathNames:
0202 datasetSmartPrescales[foo] = 1
0203
0204 else:
0205 datasetPathName = 'Dataset_'+datasetName
0206 if datasetPathName in psValues:
0207 datasetPrescales = psValues[datasetPathName]
0208
0209 if not hasattr(process, datasetPathName):
0210 msgErr = 'ERROR -- process does not have DatasetPath "'+datasetPathName+'" required by stream "'+streamName+'"'
0211 raise RuntimeError(msgErr)
0212
0213 datasetPath = getattr(process, datasetPathName)
0214
0215 datasetSmartPrescales = {}
0216
0217 # find smart-PS module of DatasetPath
0218 # (used to extract both trigger name and smart-PS values)
0219 datasetPathSmartPSModule = None
0220 for pathMod in datasetPath.expandAndClone()._seq._collection:
0221 # check only EDFilters
0222 if not isinstance(pathMod, cms.EDFilter):
0223 continue
0224 if pathMod.type_() == 'TriggerResultsFilter':
0225 if datasetPathSmartPSModule == None:
0226 datasetPathSmartPSModule = pathMod
0227 else:
0228 msgErr = 'ERROR -- found more than one smart-PS module associated to DatasetPath "'+datasetPathName+'":'
0229 msgErr = ' '+str([datasetPathSmartPSModule.label(), pathMod.label()])
0230 raise RuntimeError(msgErr)
0231
0232 if datasetPathSmartPSModule == None:
0233 raise RuntimeError('ERROR -- DatasetPath "'+datasetPathName+'" does not contain any smart-PS module (type: TriggerResultsFilter)')
0234
0235 # get list of Paths, and their smartPSs, from TriggerResultsFilter module of the Dataset Path
0236 # (by construction, the smart-PS module inside a DatasetPath does not use wildcards, but only the exact names of the Paths)
0237 for triggerCond in datasetPathSmartPSModule.triggerConditions:
0238 smartPS_match = smartPS_recomp.match(triggerCond)
0239 if smartPS_match:
0240 smartPS_key = smartPS_match.group(1).strip()
0241 smartPS_val = int(smartPS_match.group(2))
0242 else:
0243 smartPS_key = triggerCond
0244 smartPS_val = 1
0245
0246 if smartPS_key in datasetSmartPrescales:
0247 msgErr = 'ERROR -- multiple smart-PS for trigger expression "'+smartPS_key+'" in module "'+datasetPathSmartPSModule.label()+'"'
0248 raise RuntimeError(msgErr)
0249
0250 datasetSmartPrescales[smartPS_key] = smartPS_val
0251
0252 pathNames = sorted(datasetSmartPrescales.keys())
0253
0254 # info on triggers assigned to a dataset
0255 triggersOfDataset = []
0256 for pathName in pathNames:
0257 if not hasattr(process, pathName):
0258 msgErr = 'ERROR -- process does not have Path "'+pathName+'" required by dataset "'+datasetName+'"'
0259 raise RuntimeError(msgErr)
0260 path = getattr(process, pathName)
0261 # seed of HLT path (tipically, a selection on L1-Trigger algos)
0262 seedStr = getPathSeedsDescription(path)
0263 # look for BPTX coincidence in the given path
0264 bptxStr = getBPTXMatchingDescription(path)
0265 # global prescales of the trigger
0266 pathPrescales = prescaleValues[pathName] if pathName in prescaleValues else [1]*numberOfPrescaleColumns
0267 # trigger information
0268 triggersOfDataset += [{
0269 'name': pathName,
0270 'path': path,
0271 'seed': seedStr,
0272 'BPTX': bptxStr,
0273 'prescales': pathPrescales,
0274 }]
0275
0276 # order triggers alphabetically by name
0277 triggersOfDataset.sort(key = lambda x: x['name'])
0278
0279 datasetsOfStream += [{
0280 'name': datasetName,
0281 'path': datasetPath,
0282 'prescales': datasetPrescales,
0283 'smartPrescales': datasetSmartPrescales,
0284 'triggers': triggersOfDataset,
0285 }]
0286
0287 # order datasets alphabetically by name
0288 datasetsOfStream.sort(key = lambda x: x['name'])
0289
0290 # fill smart-PS applied at stream level
0291 # (in Run-2 HLT menus, smart-PSs are applied to standard Paths in the stream EndPath)
0292 streamSmartPrescales = {} # dictionary of smart-PSs applied at stream level
0293 smartPSModuleName = None # smart-PS module in the stream EndPath
0294
0295 # build list of Paths that can have a smart-PS at stream level:
0296 # this includes the Paths of all datasets in the stream, and the DatasetPaths (if present)
0297 pathNamesForStreamSmartPS = []
0298 for dset in datasetsOfStream:
0299 pathNamesForStreamSmartPS += [foo['name'] for foo in dset['triggers']]
0300 if dset['path'] != None:
0301 pathNamesForStreamSmartPS += [dset['path'].label()]
0302 pathNamesForStreamSmartPS = sorted(list(set(pathNamesForStreamSmartPS)))
0303
0304 # default to 1 (correct value if smart-PS module is absent)
0305 for foo in pathNamesForStreamSmartPS:
0306 streamSmartPrescales[foo] = 1
0307
0308 # loop on modules preceding the OutputModule in the EndPath
0309 # to extract smart prescales at stream level, requiring no more than one smart-PS module
0310 streamPathExpanded = streamPath.expandAndClone()
0311 for modIdx in range(streamPathExpanded.index(outputModule)):
0312 mod = streamPathExpanded._seq._collection[modIdx]
0313
0314 # find smart-PS modules by type
0315 if mod.type_() not in ['TriggerResultsFilter', 'HLTHighLevelDev']:
0316 continue
0317
0318 if smartPSModuleName != None:
0319 msgErr = 'ERROR -- found more than one smart-PS module associated to stream "'+streamName+'":'
0320 msgErr = ' '+str([smartPSModuleName, mod.label()])
0321 raise RuntimeError(msgErr)
0322 else:
0323 smartPSModuleName = mod.label()
0324
0325 # smart-PS module is present: start by setting to None, and extract smart-PSs
0326 for foo in pathNamesForStreamSmartPS:
0327 streamSmartPrescales[foo] = None
0328
0329 # "TriggerResultsFilter": latest type of smart-prescale module
0330 if mod.type_() == 'TriggerResultsFilter':
0331
0332 for triggerCond in mod.triggerConditions:
0333 smartPS_match = smartPS_recomp.match(triggerCond)
0334 if smartPS_match:
0335 smartPS_key = smartPS_match.group(1).strip()
0336 smartPS_val = int(smartPS_match.group(2))
0337 else:
0338 smartPS_key = triggerCond
0339 smartPS_val = 1
0340
0341 for pathName in streamSmartPrescales:
0342 if fnmatch.fnmatch(pathName, smartPS_key):
0343 if streamSmartPrescales[pathName] == None:
0344 streamSmartPrescales[pathName] = smartPS_val
0345 else:
0346 msgWarn = 'WARNING -- multiple matches for smart-PS of Path "'+pathName+'" in stream "'+streamName+'"'
0347 msgWarn += ', the lowest smart-PS value will be used (ignoring zero).'
0348 print(msgWarn, file=sys.stderr)
0349 streamSmartPrescales[pathName] = min(streamSmartPrescales[pathName], max(1, smartPS_val))
0350
0351 # "HLTHighLevelDev": old type of smart-prescale module
0352 else:
0353 for idx,triggerExpr in enumerate(mod.HLTPaths.value()):
0354 smartPS_key = triggerExpr
0355 smartPS_val = mod.HLTPathsPrescales.value()[idx] * mod.HLTOverallPrescale.value()
0356
0357 for pathName in streamSmartPrescales:
0358 if fnmatch.fnmatch(pathName, smartPS_key):
0359 if streamSmartPrescales[pathName] == None:
0360 streamSmartPrescales[pathName] = smartPS_val
0361 else:
0362 msgWarn = 'WARNING -- multiple matches for smart-PS of Path "'+pathName+'" in stream "'+streamName+'"'
0363 msgWarn += ', the lowest smart-PS value will be used (ignoring zero).'
0364 print(msgWarn, file=sys.stderr)
0365 streamSmartPrescales[pathName] = min(streamSmartPrescales[pathName], max(1, smartPS_val))
0366
0367 # if a smart-PS is still None, there is a smart-PS module,
0368 # but no match for a given Path, so set its smart-PS to zero
0369 for foo in pathNamesForStreamSmartPS:
0370 if streamSmartPrescales[foo] == None:
0371 msgWarn = 'WARNING -- smart-PS of Path "'+foo+'" in stream "'+streamName+'" not found, will be set to zero.'
0372 print(msgWarn, file=sys.stderr)
0373 streamSmartPrescales[foo] = 0
0374
0375 streams += [{
0376 'name': streamName,
0377 'path': streamPath,
0378 'prescales': prescaleValues[streamPath.label()] if streamPath.label() in prescaleValues else [1]*numberOfPrescaleColumns,
0379 'datasets': datasetsOfStream,
0380 'smartPrescales': streamSmartPrescales,
0381 }]
0382
0383 # order streams alphabetically by name
0384 streams.sort(key = lambda x: x['name'])
0385
0386 return streams
0387
0388 def printHeader(mode, selectedPrescaleColumns):
0389 '''print to stdout the header of the hltDumpStream output
0390 '''
0391 if mode == 'text':
0392 if len(selectedPrescaleColumns) > 0:
0393 print('-----------------')
0394 print('Prescale Columns:')
0395 print('-----------------')
0396 for psColIdx,psColName in selectedPrescaleColumns:
0397 print(f'{psColIdx: >4d} : {psColName}')
0398 print('-----------------\n')
0399 elif mode == 'csv':
0400 psColNamesStr = ', '.join(foo[1] for foo in selectedPrescaleColumns)
0401 if psColNamesStr: psColNamesStr += ', '
0402 print('stream, dataset, path, ' + psColNamesStr + 'seed')
0403
0404 def printStreamInfo(mode, stream, selectedPrescaleColumns, pathStrSize=100, showPrescaleValues=True, showSeedNames=True):
0405 '''print to stdout the information on triggers and datasets of a given stream
0406 '''
0407 streamName = stream['name']
0408 if mode == 'text':
0409 print('stream', streamName)
0410
0411 for dataset in stream['datasets']:
0412 datasetName = dataset['name']
0413 if mode == 'text':
0414 print(' dataset', datasetName)
0415
0416 datasetPathName = None
0417 if dataset['path'] != None:
0418 datasetPathName = dataset['path'].label()
0419
0420 datasetSmartPrescaleInStream = 1
0421 if datasetPathName != None:
0422 datasetSmartPrescaleInStream = stream['smartPrescales'][datasetPathName]
0423
0424 for trigger in dataset['triggers']:
0425
0426 triggerName = trigger['name']
0427 triggerSeedDesc = trigger['seed']
0428 triggerBPTXDesc = trigger['BPTX']
0429
0430 triggerSmartPrescaleInDataset = dataset['smartPrescales'][triggerName]
0431 triggerSmartPrescaleInStream = stream['smartPrescales'][triggerName]
0432
0433 triggerSmartPrescale = triggerSmartPrescaleInDataset * triggerSmartPrescaleInStream * datasetSmartPrescaleInStream
0434
0435 prescales = []
0436
0437 for psColIdx,_ in selectedPrescaleColumns:
0438 triggerPrescale = trigger['prescales'][psColIdx]
0439 datasetPrescale = dataset['prescales'][psColIdx]
0440 streamPrescale = stream['prescales'][psColIdx]
0441 prescales.append(triggerSmartPrescale * triggerPrescale * datasetPrescale * streamPrescale)
0442
0443 triggerStr = ''
0444
0445 if mode == 'text':
0446 triggerStr += ' %s %-*s' % (triggerBPTXDesc, pathStrSize, triggerName)
0447 if showPrescaleValues:
0448 triggerStr += '%s' % (''.join(' %6d' % p for p in prescales))
0449 if showSeedNames:
0450 triggerStr += ' %s' % (triggerSeedDesc)
0451
0452 elif mode == 'csv':
0453 triggerStr += '%s, %s, %s' % (streamName, datasetName, triggerName)
0454 if showPrescaleValues:
0455 prescaleStr = '%s' % (', '.join('%s' % p for p in prescales))
0456 if prescaleStr: prescaleStr = ', '+prescaleStr
0457 triggerStr += prescaleStr
0458 if showSeedNames:
0459 triggerStr += ', %s' % (triggerSeedDesc)
0460
0461 print(triggerStr)
0462
0463 if mode == 'text':
0464 print('---')
0465
0466 ##
0467 ## main
0468 ##
0469 if __name__ == '__main__':
0470
0471 ### args
0472 parser = argparse.ArgumentParser(
0473 prog = './'+os.path.basename(__file__),
0474 formatter_class = argparse.RawDescriptionHelpFormatter,
0475 description = __doc__,
0476 argument_default = argparse.SUPPRESS,
0477 )
0478
0479 # menu: name of ConfDB config, or local cmsRun cfg file, or stdin
0480 parser.add_argument('menu',
0481 nargs = '?',
0482 metavar = 'MENU',
0483 default = None,
0484 help = 'path to local cmsRun cfg file (if not specified, stdin is used)' )
0485
0486 # mode: format of output file
0487 parser.add_argument('-m', '--mode',
0488 dest = 'mode',
0489 action = 'store',
0490 metavar = 'MODE',
0491 default = 'text',
0492 choices = ['text', 'csv'],
0493 help = 'format of output file (must be "text", or "csv") [default: "text"]' )
0494
0495 # prescale-columns: select prescale columns via regular expressions
0496 group = parser.add_mutually_exclusive_group()
0497 group.add_argument('-p', '--prescale-columns',
0498 dest = 'ps_columns',
0499 metavar = 'COLUMN',
0500 nargs = '+',
0501 default = ['*'],
0502 help = 'list of patterns, passed to fnmatch, to select prescale columns [default: ["*"]]')
0503 group.add_argument('--no-prescales',
0504 dest = 'ps_columns',
0505 action = 'store_const',
0506 const = [],
0507 help = 'do not show information on prescales')
0508
0509 # no-seeds: do not show information on trigger seeds
0510 parser.add_argument('--no-seeds',
0511 dest = 'no_seeds',
0512 action = 'store_true',
0513 default = False,
0514 help = 'do not show the seed of a HLT path [default: False]' )
0515
0516 # parse command line arguments and options
0517 opts = parser.parse_args()
0518
0519 # parse the HLT configuration from a local cfg file, or from standard input
0520 if opts.menu != None:
0521 loader = SourceFileLoader("pycfg", opts.menu)
0522 hlt = types.ModuleType(loader.name)
0523 loader.exec_module(hlt)
0524 else:
0525 with tempfile.NamedTemporaryFile(dir = "./", delete = False, suffix = ".py") as temp_file:
0526 temp_file.write(bytes(sys.stdin.read(), 'utf-8'))
0527 configname = temp_file.name
0528 # VarParsing expects python/cmsRun python.py
0529 sys.argv.append(configname)
0530 loader = SourceFileLoader("pycfg", configname)
0531 hlt = types.ModuleType(loader.name)
0532 loader.exec_module(hlt)
0533 os.remove(configname)
0534
0535 # get hold of cms.Process object
0536 if 'process' in hlt.__dict__:
0537 process = hlt.process
0538 elif 'fragment' in hlt.__dict__:
0539 process = hlt.fragment
0540 else:
0541 sys.stderr.write("Error: the input is not a valid HLT configuration")
0542 sys.exit(1)
0543
0544 # Info from PrescaleService:
0545 # values of all (global, i.e. non-smart) HLT prescales, and names of selected prescale columns
0546 # - prescaleValues: dictionary of (key) name of Path to (value) list of Path's prescales
0547 # - selectedPSColumns: list of tuples, each holding (index, name) of selected prescale column
0548 psValues = dict()
0549 numPSColumns = 0
0550 selectedPSColumns = []
0551 showPSValues = True
0552 if opts.ps_columns:
0553 if hasattr(process, 'PrescaleService') and process.PrescaleService.type_() == 'PrescaleService':
0554 # number of prescale columns in the configuration
0555 numPSColumns = len(process.PrescaleService.lvl1Labels)
0556 # keep PS values for all columns
0557 for entry in process.PrescaleService.prescaleTable:
0558 psValues[entry.pathName.value()] = entry.prescales.value()
0559 # find index and name of selected PS columns
0560 for psColIdx,psColName in enumerate(process.PrescaleService.lvl1Labels):
0561 for psColPattern in opts.ps_columns:
0562 if fnmatch.fnmatch(psColName, psColPattern):
0563 selectedPSColumns.append((psColIdx, psColName))
0564 break
0565 if not selectedPSColumns:
0566 print('WARNING -- selected zero prescale columns: information on prescales will not be shown.', file=sys.stderr)
0567 showPSValues = False
0568 else:
0569 print('WARNING -- PrescaleService module not found: information on prescales will not be shown.', file=sys.stderr)
0570 showPSValues = False
0571
0572 # show seed expression of every HLT Path
0573 showSeeds = not opts.no_seeds
0574
0575 # extract streams' information from cms.Process
0576 streams = getStreamsInfoFromProcess(process, psValues, numPSColumns)
0577
0578 # print header information
0579 printHeader(opts.mode, selectedPSColumns)
0580
0581 maxPathNameLength = max([16] + [len(foo) for foo in process.paths_() if not foo.startswith('Dataset_')])
0582
0583 # print information of every stream
0584 for stream_i in streams:
0585 printStreamInfo(opts.mode, stream_i, selectedPSColumns, maxPathNameLength, showPSValues, showSeeds)