Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /HLTrigger/Configuration/scripts/hltListPaths is written in an unsupported language. File is not indexed.

0001 #!/usr/bin/env python3
0002 import os
0003 import sys
0004 import argparse
0005 import fnmatch
0006 
0007 import FWCore.ParameterSet.Config as cms
0008 import HLTrigger.Configuration.Tools.pipe as pipe
0009 import HLTrigger.Configuration.Tools.options as options
0010 from HLTrigger.Configuration.extend_argparse import *
0011 
0012 def getPathList(args):
0013 
0014   if isinstance(args.menu, options.ConnectionHLTMenu):
0015     # cmd to download HLT configuration
0016     cmdline = 'hltConfigFromDB'
0017     if args.menu.run:
0018       cmdline += f' --runNumber {args.menu.run}'
0019     else:
0020       cmdline += f' --{args.menu.database} --{args.menu.version} --configName {args.menu.name}'
0021     cmdline += ' --noedsources --noes --noservices'
0022     if args.proxy:
0023       cmdline += f' --dbproxy --dbproxyhost {args.proxy_host} --dbproxyport {args.proxy_port}'
0024 
0025   else:
0026     # use edmConfigDump to ensure the config can be executed
0027     cmdline = f'edmConfigDump {args.menu}'
0028 
0029   # load HLT configuration
0030   try:
0031     foo = {'process': None}
0032     exec(pipe.pipe(cmdline).decode(), foo)
0033     process = foo['process']
0034   except:
0035     raise Exception(f'query did not return a valid python file:\n query="{cmdline}"')
0036 
0037   if not isinstance(process, cms.Process):
0038     raise Exception(f'query did not return a valid HLT menu:\n query="{cmdline}"')
0039 
0040   usePaths, useEndPaths = False, False
0041 
0042   # Paths only
0043   if args.selection == 'paths':
0044     usePaths = True
0045 
0046   # EndPaths only
0047   elif args.selection == 'endpaths':
0048     useEndPaths = True
0049 
0050   # Paths and EndPaths ('all')
0051   elif args.selection == 'all':
0052     usePaths, useEndPaths = True, True
0053 
0054   # invalid value
0055   else:
0056     raise RuntimeError(f'ERROR: invalid value for option "--selection" (must be "paths", "endpaths", or "all"): {args.selection}')
0057 
0058   path_keep_rules = []
0059   for path_keep_rule in args.path_keep_rules.split(','):
0060     if not path_keep_rule:
0061       continue
0062     keep_rule = not path_keep_rule.startswith('-')
0063     pattern_idx = 0 if keep_rule else 1
0064     rule_pattern = path_keep_rule[pattern_idx:]
0065     path_keep_rules += [(keep_rule, rule_pattern)]
0066 
0067   ret = []
0068   for pathDict in [
0069     process.paths_() if usePaths else None,
0070     process.endpaths_() if useEndPaths else None,
0071   ]:
0072     if pathDict == None:
0073       continue
0074 
0075     for pathName in pathDict:
0076 
0077       # keep or drop the Path based on whether or not
0078       # its name complies with the patterns in path_keep_rules (if any)
0079       keepPath = not path_keep_rules
0080       for (keep_rule, rule_pattern) in path_keep_rules:
0081         if fnmatch.fnmatch(pathName, rule_pattern):
0082           keepPath = keep_rule
0083       if not keepPath:
0084         continue
0085 
0086       if args.no_dependent_paths:
0087         # do not include "dependent paths", i.e. paths that depend on the result of other paths in the same job
0088         # the current criterion to identify a path as "dependent" is that
0089         # (1) the path contains a "TriggerResultsFilter" module and
0090         # (2) the latter module uses the TriggerResults of the current process, and has a non-empty list of "triggerConditions"
0091         path = pathDict[pathName]
0092         pathIsDependent = False
0093         isPath = isinstance(path, cms.Path)
0094 
0095         for moduleName in path.moduleNames():
0096           module = getattr(process, moduleName)
0097           if module.type_() != 'TriggerResultsFilter' or (hasattr(module, 'triggerConditions') and len(module.triggerConditions) == 0):
0098             continue
0099 
0100           usesPathStatus = hasattr(module, 'usePathStatus') and module.usePathStatus
0101           usesTrigResOfCurrentProcess = hasattr(module, 'hltResults') and module.hltResults.getProcessName() in [process.name_(), '@currentProcess']+['']*(not isPath)
0102 
0103           if isPath:
0104             if usesPathStatus:
0105               pathIsDependent = True
0106             elif usesTrigResOfCurrentProcess:
0107               # The Path contains a TriggerResultsFilter with usePathStatus=False and forcing access to the TriggerResults of the current Process.
0108               #  - This is not supported, and should result in a runtime error when using cmsRun.
0109               #  - Here, a warning is returned to stderr, and the Path is omitted from the output list.
0110               warning_msg = 'WARNING -- the cms.Path named "'+pathName+'" will be ignored.'
0111               warning_msg += '\n'+' '*12+'- It contains a "TriggerResultsFilter" attempting to access the "TriggerResults" of the current Process (module: "'+moduleName+'").'
0112               warning_msg += '\n'+' '*12+'- This is not supported, and should result in a runtime error when using cmsRun. Please check again the HLT configuration.'
0113               print(warning_msg, file=sys.stderr)
0114               pathIsDependent = True
0115           else:
0116             pathIsDependent = usesPathStatus or usesTrigResOfCurrentProcess
0117 
0118           if pathIsDependent:
0119             break
0120 
0121         if pathIsDependent:
0122           continue
0123 
0124       ret.append(pathName)
0125 
0126   return ret
0127 
0128 # define an argparse parser to parse our options
0129 textwidth = int( 80 )
0130 try:
0131   textwidth = int( os.popen("stty size", "r").read().split()[1] )
0132 except:
0133   pass
0134 formatter = FixedWidthFormatter( HelpFormatterRespectNewlines, width = textwidth )
0135 
0136 # read defaults
0137 defaults = options.HLTProcessOptions()
0138 
0139 def hltMenu(name):
0140   return name if os.path.isfile(name) else options.ConnectionHLTMenu(name)
0141 
0142 parser = argparse.ArgumentParser(
0143   description       = 'List all the Paths and EndPaths of an HLT configuration.',
0144   argument_default  = argparse.SUPPRESS,
0145   formatter_class   = formatter,
0146   add_help          = False )
0147 
0148 # required argument
0149 parser.add_argument('menu',
0150                     action  = 'store',
0151                     type    = hltMenu,
0152                     metavar = 'MENU',
0153                     help    = 'HLT menu (can be a local cmsRun configuration file, or the name of a configuration in the ConfDB database).\nFor ConfDB configurations, supported formats are:\n- /path/to/configuration[/Vn]\n- [[{v1|v2|v3}/]{run3|run2|online|adg}:]/path/to/configuration[/Vn]\n- run:runnumber\nThe possible converters are "v1", "v2, and "v3" (default).\nThe possible databases are\n"run3" (default, used for offline development in Run 3),\n"run2" (used for accessing Run-2 offline development menus),\n"online" (used to extract online menus from inside Point 5) and\n"adg" (used to extract the online menus from outside Point 5).\nIf no menu version is specified, the latest one is automatically used.\nIf "run:" is used instead, the HLT menu used for the given run number is looked up and used.\nNote: other converters and databases exist, but they are only for expert/special use.' )
0154 
0155 # options
0156 parser.add_argument('--dbproxy',
0157                     dest    = 'proxy',
0158                     action  = 'store_true',
0159                     default = defaults.proxy,
0160                     help    = 'Use a socks proxy to connect outside CERN network (default: False)' )
0161 parser.add_argument('--dbproxyport',
0162                     dest    = 'proxy_port',
0163                     action  = 'store',
0164                     metavar = 'PROXYPORT',
0165                     default = defaults.proxy_port,
0166                     help    = 'Port of the socks proxy (default: 8080)' )
0167 parser.add_argument('--dbproxyhost',
0168                     dest    = 'proxy_host',
0169                     action  = 'store',
0170                     metavar = 'PROXYHOST',
0171                     default = defaults.proxy_host,
0172                     help    = 'Host of the socks proxy (default: "localhost")' )
0173 
0174 group = parser.add_mutually_exclusive_group()
0175 group.add_argument('-p', '--only-paths',
0176                     dest    = 'selection',
0177                     action  = 'store_const',
0178                     const   = 'paths',
0179                     help    = 'List only Paths' )
0180 group.add_argument('-e', '--only-endpaths',
0181                     dest    = 'selection',
0182                     action  = 'store_const',
0183                     const   = 'endpaths',
0184                     help    = 'List only EndPaths' )
0185 group.add_argument('-a', '--all', 
0186                     dest    = 'selection',
0187                     action  = 'store_const',
0188                     const   = 'all',
0189                     default = 'all',
0190                     help    = 'List Paths and EndPaths (default)' )
0191 
0192 parser.add_argument('--no-dependent-paths',
0193                     dest    = 'no_dependent_paths',
0194                     action  = 'store_true',
0195                     default = False,
0196                     help    = 'Do not list paths which depend on the result of other paths (default: false)' )
0197 
0198 parser.add_argument('-s', '--select-paths',
0199                     dest    = 'path_keep_rules',
0200                     action  = 'store',
0201                     default = '',
0202                     help    = 'Comma-separated list of Path-name patterns (incl. wildcards) to select a subset of Paths using fnmatch.\nIf a Path-name pattern starts with the dash character (-), the Paths whose name matches that pattern are not selected.\nThe patterns are ordered: a given pattern can override previous ones (example: "*,-Foo,*" retains all Paths)\n(default: empty, meaning all Paths are kept)')
0203 
0204 # redefine "--help" to be the last option, and use a customized message 
0205 parser.add_argument('-h', '--help', 
0206                     action  = 'help', 
0207                     help    = 'Show this help message and exit' )
0208 
0209 # parse command line arguments and options
0210 args = parser.parse_args()
0211 
0212 paths = getPathList(args)
0213 for path in paths:
0214   print(path)