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)