diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ChainLabelParser.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ChainLabelParser.py index 1f107aa34c88b77807a563b9727e4205c467808d..0e54cfb3f66872744d7e05f8ae1219ead2cbcac7 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ChainLabelParser.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ChainLabelParser.py @@ -1,9 +1,9 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from __future__ import print_function from __future__ import absolute_import from TrigHLTJetHypo.node import Node -from TrigHLTJetHypo.constants import lchars, digits +from TrigHLTJetHypo.constants import lchars, param_alphabet def get_char(s): """character generator""" @@ -158,7 +158,7 @@ class ChainLabelParser(object): c = next(self.gc) - if c in lchars or c in digits or c ==',': + if c in param_alphabet: self.paramAppend(c) return diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py index a313842708186618cb92a7bed17ed7fb4de6b81b..4c6e272af4786a3c242cc8fb13b78027a8706577 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration """Instantiates TrigJetHypoToolConfig_fastreduction AlgTool from a hypo tree.""" @@ -84,6 +84,32 @@ class ConditionsToolSetterFastReduction(object): return condition_tools + + def _make_filter_condition_tool(self, node): + + """Condtion filters use a list of CompoundCondition containing + single jet elemental conditions select a subset of the reco + jets to send to the a Condition""" + + el_condition_tools = [] + + for fc, mult in node.filter_dicts: + + assert len(fc) == 1 # 1 elemental condition + assert mult == 1 + el_condition_tools.extend(self._make_el_condition_tools(fc)) + + if not el_condition_tools: + el_condition_tools.append(self.algToolFactory('all')) + + capacitychecked_condition_tool = self.algToolFactory( + 'capacitychecked') + + capacitychecked_condition_tool.conditionMakers = el_condition_tools + capacitychecked_condition_tool.multiplicity = 1 + + return capacitychecked_condition_tool + def _make_compound_condition_tools(self, node): """For each element of node.conf_attrs, construct a @@ -112,6 +138,7 @@ class ConditionsToolSetterFastReduction(object): for i in range(len(node.conf_attrs)): c, mult = node.conf_attrs[i] cpi = '' + if node.chainpartinds: cpi = node.chainpartinds[i][0] assert mult == node.chainpartinds[i][1] @@ -136,29 +163,6 @@ class ConditionsToolSetterFastReduction(object): return outer_condition_tools - def _make_filter_tool(self, node): - """Condtion filters use a list of CompoundCondition containing - single jet elemental conditions select a subset of the reco - jets to send to the a Condition""" - - el_condition_tools = [] - for fc, mult in node.filter_conditions: - assert len(fc) == 1 # 1 elemental condition - assert mult == 1 - el_condition_tools.extend(self._make_el_condition_tools(fc)) - - if not el_condition_tools: - el_condition_tools.append(self.algToolFactory('all')) - - capacitychecked_condition_tool = self.algToolFactory( - 'capacitychecked') - - capacitychecked_condition_tool.conditionMakers = el_condition_tools - capacitychecked_condition_tool.multiplicity = 1 - - return capacitychecked_condition_tool - - def _mod_leaf(self, node): """ Add Condition tools to For a leaf node.""" @@ -178,16 +182,8 @@ class ConditionsToolSetterFastReduction(object): node.compound_condition_tools = self._make_compound_condition_tools( node) - # make condition builder AlgTools for the condition filters. - # condition filters select subsets of the input jets to present - # to a condition, - - node.filter_tool = self._make_filter_tool(node) - - - # if node.scenario == 'agg': - # print (node) - # assert False + node.filter_condition_tool = self._make_filter_condition_tool( + node) def report(self): return str(self.algToolFactory) @@ -203,10 +199,11 @@ class ConditionsToolSetterFastReduction(object): assert (len(node.compound_condition_tools) == 1) cmap[node.node_id] = node.compound_condition_tools[0] - fmap[node.node_id] = node.filter_tool - + + fmap[node.node_id] = node.filter_condition_tool + else: - # must have a tool for Gaudi to instantiate in + cmap[node.node_id] = self.algToolFactory('capacitychecked') cmap[node.node_id].conditionMakers = [self.algToolFactory('all')] cmap[node.node_id].multiplicity = 1 @@ -215,7 +212,6 @@ class ConditionsToolSetterFastReduction(object): fmap[node.node_id].conditionMakers = [self.algToolFactory('all')] fmap[node.node_id].multiplicity = 1 - for cn in node.children: self._fill_conditions_map(cn, cmap, fmap) @@ -255,23 +251,26 @@ class ConditionsToolSetterFastReduction(object): self._set_conditions(tree) - tree_map = {} + tree_map = {} # tree of node indices self._fill_tree_map(tree, tree_map) - for k, v in tree_map.items(): - log.debug("Tree map debug %s %s", str(k), str(v)) - treeVec = self._map_2_vec(tree_map) conditionsMap = {} filterConditionsMap = {} + self._fill_conditions_map(tree, conditionsMap, filterConditionsMap) - conditionsVec = self._map_2_vec(conditionsMap) + + # conditionVec is an attribute as it will be used directly + # to make prefilter tools, so hold onto it here + self.conditionMakersVec = self._map_2_vec(conditionsMap) filterConditionsVec = self._map_2_vec(filterConditionsMap) # make a config tool and provide it with condition makers config_tool = self.algToolFactory('fastreduction') - config_tool.conditionMakers = conditionsVec + + + config_tool.conditionMakers = self.conditionMakersVec config_tool.filtConditionsMakers = filterConditionsVec config_tool.treeVector = treeVec self.config_tool = config_tool diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/FastReductionAlgToolFactory.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/FastReductionAlgToolFactory.py index 5cf284a9274fcd98d45f458e128bd8abaeb261de..beec83e6d744f1feac1a132e455e438a9ba5c4dd 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/FastReductionAlgToolFactory.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/FastReductionAlgToolFactory.py @@ -11,7 +11,11 @@ class FastReductionAlgToolFactory: self.tool_factories = { 'eta': [CompFactory.TrigJetConditionConfig_abs_eta, 0], 'peta': [CompFactory.TrigJetConditionConfig_signed_eta, 0], + 'ceta': [CompFactory.TrigJetConditionConfig_signed_eta, 0], 'neta': [CompFactory.TrigJetConditionConfig_signed_eta, 0], + 'pphi': [CompFactory.TrigJetConditionConfig_phi, 0], + 'cphi': [CompFactory.TrigJetConditionConfig_phi, 0], + 'nphi': [CompFactory.TrigJetConditionConfig_phi, 0], 'et': [CompFactory.TrigJetConditionConfig_et, 0], 'djmass': [CompFactory.TrigJetConditionConfig_dijet_mass, 0], 'djdphi': [CompFactory.TrigJetConditionConfig_dijet_dphi, 0], @@ -39,7 +43,8 @@ class FastReductionAlgToolFactory: def __call__(self, key, extra=''): - + + key = key.split(':')[-1] # key = 'eta' for 'XXX:eta' klass = self.tool_factories[key][0] sn = self.tool_factories[key][1] diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py index d46791a7c4df7d787d370d5cbaab763d730f600a..c9eb6890c3368d18e15079effa322f2e1a35fef6 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py @@ -1,9 +1,11 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from __future__ import print_function from AthenaConfiguration.ComponentFactory import CompFactory -from TrigHLTJetHypo.treeVisitors import TreeParameterExpander +from TrigHLTJetHypo.treeVisitors import (TreeParameterExpander, + FilterConditionsMover) + from TrigHLTJetHypo.ConditionsToolSetterFastReduction import ( ConditionsToolSetterFastReduction, ) @@ -13,10 +15,10 @@ from TrigHLTJetHypo.FastReductionAlgToolFactory import ( ) from TrigHLTJetHypo.chainDict2jetLabel import chainDict2jetLabel +from TrigHLTJetHypo.prefilterLabelFromChainDict import ( + prefilterLabelFromChainDict,) from TrigHLTJetHypo.ChainLabelParser import ChainLabelParser -from TrigHLTJetHypo.node import Node -from TrigHLTJetHypo.NodeSplitterVisitor import NodeSplitterVisitor from AthenaCommon.Logging import logging @@ -24,74 +26,57 @@ log = logging.getLogger( 'TrigJetHypoToolConfig' ) algToolFactory = FastReductionAlgToolFactory() -def tree2tools(rootless_tree, toolSetter): - - # add a root node so that split simple nodes cann connect. - tree = Node('root') - tree.children = [rootless_tree] - tree.node_id = 0 - tree.parent_id = 0 - rootless_tree.tree_top = False - tree.tree_top = True - - #expand strings of cuts to a cut dictionary +def tree2tools(tree, toolSetter): + + # expand strings of cuts to a cut dictionary visitor = TreeParameterExpander() tree.accept(visitor) log.debug(visitor.report()) - visitor = NodeSplitterVisitor() + # move the filter conditions into node.filter_conditions + visitor = FilterConditionsMover() tree.accept(visitor) # tell the child nodes who their parent is. tree.set_ids(node_id=0, parent_id=0) - # create - possibly nested - tools - - # chain name in run 2 dicts were missing the 'HLT_' prefix - # but it seems it is necessary to run the hypos in AthenaMT ?...? - + # create - possibly nested - tools, The tools are attached to the visitor. toolSetter.mod(tree) return tree # used by debug tools -def nodeForestFromChainLabel( - chain_label, # simple([(260et,320eta490, leg000)]) - chain_name,): # HLT_j260_320eta490_L1J75_31ETA49 - - parser = ChainLabelParser(chain_label, debug=False) +def nodesFromLabel(label): + """from a label eg simple([(260et,320eta490, leg000)]) + create a node. The node may have children, thus forming a tree.""" + parser = ChainLabelParser(label, debug=False) return parser.parse() -def trigJetHypoToolHelperFromDict_( +def trigJetHypoToolHelperConfigurersFromLabel( chain_label, # simple([(260et,320eta490, leg000)]) chain_name,): # HLT_j260_320eta490_L1J75_31ETA49 - - node_forest = nodeForestFromChainLabel(chain_label, - chain_name) - - helper_tool = algToolFactory('helper') + # construct the FastReduction Trees + node_forest = nodesFromLabel(chain_label) + # use a visitor to convert simple types to a HypoConfigurer Tool, + # one for each + # tree, The HypoConfigurer Tool will have ConditionConfigure AlgTools + # each creating a single Condition. + configurer_tools = [] for tree in node_forest: toolSetter = ConditionsToolSetterFastReduction(algToolFactory) tree2tools(tree, toolSetter) - helper_tool.HypoConfigurers.append(toolSetter.config_tool) + configurer_tools.append(toolSetter.config_tool) log.debug(toolSetter.report()) - - return helper_tool -def trigJetHypoToolHelperFromDict(chain_dict): - """Produce a jet trigger hypo tool helper from a chainDict - Helper tools do the hypio work. They are used, for example - by TrigJetHypoToolMT to devide whether an event passes. - A Helper Tool returned by this function may be the root of a Helper - Tool tree structure.""" + return configurer_tools - - log.debug('trigJetHypoToolFromDict chainDict %s', str(chain_dict)) + +def trigJetConfigurerToolsFromDict(chain_dict): try: chain_label = chainDict2jetLabel(chain_dict) @@ -101,17 +86,60 @@ def trigJetHypoToolHelperFromDict(chain_dict): chain_dict['chainName'],) m += ' jet hypo scenario: %s' % ( chain_dict['chainParts'][0]['hypoScenario'],) - - log.error(m) - + log.error(m) raise e chain_name = chain_dict['chainName'] + return trigJetHypoToolHelperConfigurersFromLabel(chain_label, chain_name) + +def trigJetHypoToolHelperFromDict(chain_dict): + """Produce a jet trigger hypo tool helper from a chainDict + Helper tools do the hypio work. They are used, for example + by TrigJetHypoToolMT to devide whether an event passes. + A Helper Tool returned by this function may be the root of a Helper + Tool tree structure.""" - return trigJetHypoToolHelperFromDict_(chain_label, - chain_name) + + log.debug('trigJetHypoToolFromDict chainDict %s', str(chain_dict)) + algToolFactory = FastReductionAlgToolFactory() + + # Build the helper tool + helper_tool = algToolFactory('helper') + # build the Configuration Tools for the JetHypoHelperTool. + # there is one Configurer per tree in the forest. + configurer_tools = trigJetConfigurerToolsFromDict(chain_dict) + + helper_tool.HypoConfigurers = configurer_tools + + # find the prefilters. These are Conditions that will be used + # remove jets from the input jet collection + # before the helper is run (eg blank out eta-phi regions,...) + # + # 1/2021... one could imagine using FastReducer to act as + # a prefilter predicate. For now, more prosaically + # we build a Conditions tree consisting of a root node with + # a single child. The root node willbe an AcceptAll condition. + # Vetoing on this will remove all jets. The usefull conditions + # are in the child node. These will be extracted here. + + label = prefilterLabelFromChainDict(chain_dict) + if label: + forest = ChainLabelParser(label, debug=False).parse() + assert len(forest) == 1 + tree = forest[0] + + assert tree.size() == 2 # root and single child. + + tool_setter = ConditionsToolSetterFastReduction(algToolFactory) + + tree2tools(tree.children[0], tool_setter) # single child node + + helper_tool.prefiltConditionMakers = tool_setter.conditionMakersVec + + return helper_tool + def trigJetHypoToolFromDict_(chain_dict, hypo_tool, debug=False): """Produce a jet trigger hypo tool from a chainDict""" diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py index d06990e10133342deff7bbfb5c37477b4326b2b6..d06b0eb25cd9c0c0ac216677920bb5df2d0a9abf 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from __future__ import print_function from __future__ import absolute_import import re @@ -17,6 +17,19 @@ reject_substr = ( reject_substr_res = re.compile(r'%s' % '|'.join(reject_substr)) +def make_label(scenario, pattern, template, extra={}): + + r = re.compile(pattern) + m = r.match(scenario) + assert m, 'chainDict2jetlabel - pattern %s does not match scenario %s' % ( + pattern, scenario) + + argdict = m.groupdict() + argdict.update(extra) + + label = template % argdict + return label + def _select_simple_chainparts(chain_parts): """ Reject unsuported chain parts """ @@ -43,7 +56,7 @@ def _make_simple_label(chain_parts, leg_label): raise NotImplementedError(msg) chainpartind = 0 - label = 'simple([' + label = 'root([]' for cp in chain_parts: smcstr = str(cp['smc']) jvtstr = str(cp['jvt']) @@ -51,6 +64,7 @@ def _make_simple_label(chain_parts, leg_label): if smcstr == 'nosmc': smcstr = '' for i in range(int(cp['multiplicity'])): + label += 'simple([' # condition_str = '(%set,%s,%s)' % (str(cp['threshold']), # str(cp['etaRange']), # smcstr,) @@ -72,9 +86,9 @@ def _make_simple_label(chain_parts, leg_label): if not condition_str.endswith(')'): condition_str += ')' label += condition_str + label += '])' chainpartind += 1 - - label += '])' + label += ')' return label @@ -103,68 +117,40 @@ def _make_fbdjnoshared_label(chain_parts, leg_label): assert len(chain_parts) == 1 scenario = chain_parts[0]['hypoScenario'] - assert scenario.startswith('f') - args = _args_from_scenario(scenario) - - # arg res tuples constain a regex, and a counter - # to count the number of matches. - arg_res = [ - [re.compile(r'(?P<lo>\d*)(?P<key>fbet)(?P<hi>\d*)'), 0], - [re.compile(r'(?P<lo>\d*)(?P<key>mass)(?P<hi>\d*)'), 0], - [re.compile(r'(?P<lo>\d*)(?P<key>et)(?P<hi>\d*)'), 0], - ] - - defaults = { - 'et0': ('101', 'inf'), - 'et1': ('103', 'inf'), - 'mass0': ('800', 'inf'), - 'fbet0': ('501', 'inf'), - } - - argvals = {} - assert len(args) == len(arg_res) + 1 # +1 because et occurs twice. - while args: - arg = args.pop() - for ar in arg_res: - regx = ar[0] - occurence=ar[1] # no iof time this argument is used eg et used 2x - m = regx.match(arg) - if m is not None: - gd = m.groupdict() - key = gd['key'] + str(occurence) - ar[1] += 1 # bump the occurrence cout - try: - lo = float(gd['lo']) - except ValueError: - lo = defaults[key][0] - argvals[key+'lo'] = lo - try: - hi = float(gd['hi']) - except ValueError: - hi = defaults[key][1] - argvals[key+'hi'] = hi - - assert len(args) == 0 - - argvals['leg_label'] = leg_label - - return """ - all - ( - [] - simple - ( - [(%(fbet0lo).0fet, 500neta, leg000)(%(fbet0lo).0fet, peta500, %(leg_label)s)] - ) - dijet - ( - [(%(mass0lo).0fdjmass, 26djdphi)] - simple - ( - [(%(et0lo).0fet, 0eta320, leg000)(%(et1lo).0fet, 0eta320, %(leg_label)s)] - ) - ) - )""" % argvals + assert scenario.startswith('fbdjnoshared') + + # example scenario: fbdjnosharedSEP10etSEP20etSEP34massSEP50fbet + # example label: + # root([] + # simple([(50et, 500neta, leg000)]) + # simple([(50et, peta500, leg000)]) + # + # dijet + # ( + # [(34djmass, 26djdphi)] + # simple([(20et, 0eta320, leg000)]) + # simple([(10et, 0eta320, leg000)]) + # ) + # ) + + pattern = r'^fbdjnosharedSEP'\ + r'(?P<j1etlo>\d*)et(?P<j1ethi>\d*)SEP'\ + r'(?P<j2etlo>\d*)et(?P<j2ethi>\d*)SEP'\ + r'(?P<masslo>\d*)mass(?P<masshi>\d*)SEP'\ + r'(?P<fbetlo>\d*)fbet(?P<fbethi>\d*)$' + + + template = r'root([]'\ + r'simple([(%(fbetlo)set%(fbethi)s, 500neta, %(leg_label)s)])'\ + r'simple([(%(fbetlo)set%(fbethi)s, peta500, %(leg_label)s)])'\ + r'dijet([(%(masslo)sdjmass%(masshi)s, 26djdphi)]'\ + r'simple([(%(j1etlo)set%(j1ethi)s, 0eta320, %(leg_label)s)])'\ + r'simple([(%(j2etlo)set%(j2ethi)s, 0eta320, %(leg_label)s)])))' + + extra = {'leg_label': leg_label} + + label = make_label(scenario, pattern, template, extra) + return label def _make_fbdjshared_label(chain_parts, leg_label): @@ -174,16 +160,16 @@ def _make_fbdjshared_label(chain_parts, leg_label): return """ - simple - ( - [(50et, 500neta, leg000)(50et, peta500, leg000)] + root([] + simple([(50et, 500neta, %s)]) + simple([(50et, peta500, %s)]) ) dijet ( [(34djmass, 26djdphi)] - simple - ([(10et, 0eta320, leg000)(20et, 0eta320, leg000)]) - )""" + simple([(10et, 0eta320, %s)]) + simple([(20et, 0eta320, %s)]) + )""" % ((leg_label,) * 4) def _make_dijet_label(chain_parts, leg_label): @@ -202,56 +188,27 @@ def _make_dijet_label(chain_parts, leg_label): assert scenario.startswith('dijet') - arg_res = [ - re.compile(r'^(?P<lo>\d*)(?P<key>djmass)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>j1et)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>j1eta)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>j2et)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>j2eta)(?P<hi>\d*)$'), - ] - - defaults = { - 'j1et': ('100', 'inf'), - 'j2et': ('100', 'inf'), - 'j1eta': ('0', '320'), - 'j2eta': ('0', '320'), - 'djmass': ('1000', 'inf'), - } + # example scenario: 'dijetSEP80j1etSEP0j1eta240SEP80j2etSEP0j2eta240SEP700djmass', + pattern = r'^dijetSEP('\ + r'(?P<j1etlo>\d*)j1et(?P<j1ethi>\d*)SEP'\ + r'(?P<j1etalo>\d*)j1eta(?P<j1etahi>\d*)SEP'\ + r'(?P<j2etlo>\d*)j2et(?P<j2ethi>\d*)SEP'\ + r'(?P<j2etalo>\d*)j2eta(?P<j2etahi>\d*)SEP'\ + r'(?P<djmasslo>\d*)djmass(?P<djmasshi>\d*))$' - args = _args_from_scenario(scenario) - argvals = {} - while args: - assert len(args) == len(arg_res) - arg = args.pop() - for r in arg_res: - m = r.match(arg) - if m is not None: - arg_res.remove(r) - gd = m.groupdict() - key = gd['key'] - - try: - lo = float(gd['lo']) - except ValueError: - lo = defaults[key][0] - argvals[key+'lo'] = lo - try: - hi = float(gd['hi']) - except ValueError: - hi = defaults[key][1] - argvals[key+'hi'] = hi - - assert len(args) == len(arg_res) - assert len(args) == 0 - - argvals['leg_label'] = leg_label - - return """ - dijet( - [(%(djmasslo).0fdjmass)] - simple([(%(j1etlo).0fet, %(j1etalo).0feta%(j1etahi).0f, %(leg_label)s) - (%(j2etlo).0fet, %(j2etalo).0feta%(j2etahi).0f, %(leg_label)s)]))""" % argvals + template = 'root([] dijet(' \ + '[(%(djmasslo)sdjmass%(djmasshi)s, 26djdphi)]'\ + 'simple([(%(j1etlo)set, %(j1etalo)seta%(j1etahi)s, %(leg_label)s)])'\ + 'simple([(%(j2etlo)set, %(j2etalo)seta%(j2etahi)s, %(leg_label)s)])))' + + # example label: + # dijet([(700djmass)] simple([(80et, 0eta240, leg002)]) simple([(80et, 0eta240, leg002)]))) + + extra = {'leg_label': leg_label} + label = make_label(scenario, pattern, template, extra) + + return label def _make_agg_label(chain_parts, leg_label): @@ -269,58 +226,23 @@ def _make_agg_label(chain_parts, leg_label): assert len(chain_parts) == 1, '_make_agg_label, no. of chain parts != 1' scenario = chain_parts[0]['hypoScenario'] - assert scenario.startswith('agg'), '_make_agg_label(): scenario does not start with agg' - - arg_res = [ - re.compile(r'^(?P<lo>\d*)(?P<key>ht)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>et)(?P<hi>\d*)$'), - re.compile(r'^(?P<lo>\d*)(?P<key>eta)(?P<hi>\d*)$'), - ] - - defaults = { - 'ht': ('0', 'inf'), - 'et': ('0', 'inf'), - 'eta': ('0', 'inf'), - } - - - args = _args_from_scenario(scenario) - argvals = {} - nargs = len(args) - assert len(args) <= len(arg_res), 'bad num of args %d, expected < %d' % (len(args), - len(arg_res)) - - # obtain argument values frrom scenario - while args: - arg = args.pop() - for r in arg_res: - m = r.match(arg) - if m is not None: - arg_res.remove(r) - gd = m.groupdict() - key = gd['key'] - - try: - lo = float(gd['lo']) - except ValueError: - lo = float(defaults[key][0]) - argvals[key+'lo'] = lo - try: - hi = float(gd['hi']) - except ValueError: - hi = float(defaults[key][1]) - argvals[key+'hi'] = hi - - assert len(argvals) == 2*nargs, 'no of args: %d, expected %d' % (len(argvals), 2*nargs) - - argvals['leg_label'] = leg_label - result = """ - agg([(%(htlo).0fht, %(leg_label)s) - (%(etlo).0fet) - (%(etalo).0feta%(etahi).0f) - ])""" % argvals - print (result) - return result + # assert scenario.startswith('agg'), '_make_agg_label(): scenario does not start with agg' + + # the scenario contains the ht cut, and filter cuts. + # all cuts thast do no start with 'ht are filter cuts + + pattern = r'^aggSEP(?P<htlo>\d*)ht(?P<hthi>\d*)SEP'\ + r'(?P<etlo>\d*)et(?P<ethi>\d*)SEP'\ + r'(?P<etalo>\d*)eta(?P<etahi>\d*)$' + + template = 'root([]agg([(%(htlo)sht, %(leg_label)s)'\ + '(%(etlo)sfltr:et)'\ + '(%(etalo)sfltr:eta%(etahi)s)]))' + + extra = {'leg_label': leg_label} + label = make_label(scenario, pattern, template, extra) + + return label def chainDict2jetLabel(chain_dict): @@ -335,7 +257,8 @@ def chainDict2jetLabel(chain_dict): if len(chainParts) > 1 create and of simple and other. """ - # suported scenarios + # suported scenarios. Caution! two keys in the router dict + # must not share a common initial substring. router = { 'simple': _make_simple_label, 'agg': _make_agg_label, @@ -344,18 +267,23 @@ def chainDict2jetLabel(chain_dict): 'fbdjnoshared': _make_fbdjnoshared_label, } + # check that no key is the initial susbstring of another key + # such a case would break the code below. + keys = sorted(router.keys(), key=len) + for i in range(1, len(keys)): + assert not (keys[i].startswith(keys[i-1])) + # chain_part - scenario association cp_sorter = {} for k in router: cp_sorter[k] = [] chain_parts = chain_dict['chainParts'] for cp in chain_parts: - if cp['signature'] != 'Jet' and cp['signature'] != 'Bjet': - continue - for k in cp_sorter: - if cp['hypoScenario'].startswith(k): - cp_sorter[k].append(cp) - break + if cp['signature'] in ('Jet', 'Bjet'): + for k in cp_sorter: + if cp['hypoScenario'].startswith(k): + cp_sorter[k].append(cp) + break # obtain labels by scenario. labels = [] diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/constants.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/constants.py index 10b599fea3161ccc3a1c21390ea541c3874a40cf..92d11664c9f48111656fa0666c44f47c9caef83a 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/constants.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/constants.py @@ -1,8 +1,12 @@ -# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + lchars = 'abcdefghijklmnopqrstuvwxyz' digits = '0123456789' delims = '()[],' +signs = '-+' +seps = ':,' logicals = ('and', 'or', 'not') -alphabet = lchars + digits + delims +param_alphabet = lchars + digits + seps +alphabet = lchars + digits + delims + signs + seps diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py index 9bc459c46b581f42844a33fecf5078a172767305..3101cbf50a6b9a6e7da4010932827d7b9d2a4a92 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration """ Node - represents a tree structure. scenario and parameters which are strings filled in while parsing a jet hyp[o label. A visitor is used to convert @@ -25,17 +25,20 @@ class Node(object): self.scenario = scenario self.parameters = '' self.children = [] - self.conf_attrs = [] # list of dictionaries + self.conf_attrs = [] # list of dictionaries to build conditions + + # filled in by a CondtionsTollSetter: self.compound_condition_tools = [] self.chainpartinds = [] - + # Condition objects may have filters # eg HT may have an et filter. Filters are made up of conditions # and are used to form jet subsets. - self.filter_conditions = [] - self.filter_tool = None + self.filter_condition_tool = None + self.filter_dicts = [] + self.tree_top = False self.tool = None @@ -94,16 +97,17 @@ class Node(object): for ca in self.conf_attrs: s.append(indent + str(ca)) - s.append(indent + 'filter_conditions [%d]:' % ( - len(self.filter_conditions),)) + s.append(indent + 'filter_dicts [%d]:' % ( + len(self.filter_dicts),)) - for fc in self.filter_conditions: + for fc in self.filter_dicts: s.append(indent + str(fc)) s.append(indent + 'compoundConditionTools [%d]:' % len( self.compound_condition_tools)) - s.append(indent + 'filter_tool :' + str(self.filter_tool)) + s.append(indent + 'condition_filter_tool: %s' % str( + self.filter_condition_tool)) s.append(indent + 'No of children: %d\n' % len(self.children)) @@ -119,6 +123,11 @@ class Node(object): return s + def size(self): + sz = 1 + for c in self.children: sz += c.size() + return sz + def dump(self): return '\n'.join(self.dump_(0)) diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/prefilterLabelFromChainDict.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/prefilterLabelFromChainDict.py new file mode 100644 index 0000000000000000000000000000000000000000..1aa700db6906ecbed6965f7689b47cbfe8d2fa1e --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/prefilterLabelFromChainDict.py @@ -0,0 +1,49 @@ +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + +from __future__ import print_function +from TrigHLTJetHypo.constants import lchars +import re + +cut_re = re.compile(r'(?P<lo>\d*)(?P<key>[%s]+)(?P<hi>\d*)' %lchars) + +def prefilterArgsFromChainDict(chain_dict): + """Marshal and return the strings use to build a prefilter for the jet + hypo. These may be spread across > 1 chainPart within the chainDict.""" + + chain_parts = [cp for cp in chain_dict['chainParts'] if + cp['signature'] in ('Jet', 'Bjet') and 'prefilters' in cp] + + prefilter_args = [] + + [prefilter_args.extend(cp['prefilters']) for cp in chain_parts] + + for p in prefilter_args: + assert p.startswith('pfltr') + + return prefilter_args + + +def prefilterLabelFromChainDict(chain_dict): + """create a jet hypo label. For now, only arguments like + 'prefltrSEP100ceta90SEP100nphi50' are accepted. """ + + + prefilter_args = prefilterArgsFromChainDict(chain_dict) + if not prefilter_args: return '' + + label = 'root([]simple([' + + arg_spacer = ', ' + for pfa in prefilter_args: + frags = pfa.split('SEP')[1:] + assert frags + label += '(' + for frag in frags: + cut_match = cut_re.match(frag) + assert cut_match is not None + label += frag + arg_spacer + label = label[:-len(arg_spacer)] + ')' + label += ']))' + + return label + diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/testChainDictMaker.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/testChainDictMaker.py index 9e37cfaa47b5ce3ffc9226f899391b5c4043a94a..a7b72d6e57c826a48993cde7578ee6440e380102 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/testChainDictMaker.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/testChainDictMaker.py @@ -1,18 +1,20 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration """Make chain dicts for testing jet hypo config modules""" from __future__ import print_function from TriggerMenuMT.HLTMenuConfig.Menu.Physics_pp_run3_v1 import ( - SingleJetGroup, - MultiJetGroup) + SingleJetGroup, + MultiJetGroup, + MuonJetGroup, + PhysicsStream) from TriggerMenuMT.HLTMenuConfig.Menu.ChainDefInMenu import ChainProp from TriggerMenuMT.HLTMenuConfig.Menu.DictFromChainName import dictFromChainName from chainDict2jetLabel import chainDict2jetLabel from TrigJetHypoToolConfig import (trigJetHypoToolFromDict, - nodeForestFromChainLabel, + nodesFromLabel, tree2tools,) from TrigHLTJetHypo.ConditionsToolSetterFastReduction import ( @@ -22,8 +24,9 @@ from TrigHLTJetHypo.ConditionsToolSetterFastReduction import ( from TrigHLTJetHypo.FastReductionAlgToolFactory import ( FastReductionAlgToolFactory,) +import sys -def testChainDictMaker(): +def testChainDictMaker(idict): chain_props = [ ChainProp(name='HLT_j260_320eta490_L1J75_31ETA49', @@ -36,7 +39,7 @@ def testChainDictMaker(): l1SeedThresholds=['FSNOSEED']*2, groups=MultiJetGroup), - ChainProp(name='HLT_j0_HTSEP1000htSEP100etSEP0eta320_L1J15', + ChainProp(name='HLT_j0_aggSEP1000htSEP30etSEP0eta320_L1J15', l1SeedThresholds=['FSNOSEED'], groups=MultiJetGroup), @@ -52,10 +55,30 @@ def testChainDictMaker(): ChainProp(name='HLT_j0_fbdjshared_L1J20', groups=SingleJetGroup), - ChainProp(name='HLT_j40_j0_aggSEP50htSEP10etSEP0eta320_L1J20',l1SeedThresholds=['FSNOSEED']*2, groups=MultiJetGroup), - ChainProp(name='HLT_j0_fbdjnosharedSEP10etSEP20etSEP34massSEP50fbet_L1J20', groups=SingleJetGroup), + ChainProp(name='HLT_j40_j0_aggSEP50htSEP10etSEP0eta320_L1J20', + l1SeedThresholds=['FSNOSEED']*2, + groups=MultiJetGroup), + + ChainProp(name='HLT_j0_fbdjnosharedSEP10etSEP20etSEP34massSEP50fbet_L1J20', + groups=SingleJetGroup), + + ChainProp(name='HLT_j60_pfltrSEP100ceta90SEP100nphi50_L1J20', + groups=SingleJetGroup), + + ChainProp(name='HLT_j45_pf_ftf_preselj20_L1J15', groups=SingleJetGroup), + + ChainProp(name='HLT_j85_ftf_pfltrSEP300ceta210SEP300nphi10_L1J20', + groups=SingleJetGroup), + + ChainProp(name='HLT_j0_dijetSEP80j1etSEP0j1eta240SEP80j2etSEP0j2eta240SEP700djmass_L1J20', groups=SingleJetGroup), + + ChainProp(name='HLT_2mu6_2j50_0eta490_j0_dijetSEP50j1etSEP50j2etSEP900djmass_L1MJJ-500-NFF',l1SeedThresholds=['MU6','FSNOSEED', 'FSNOSEED'],stream=[PhysicsStream], groups=MuonJetGroup), ] + if idict is not None: + chain_props = [chain_props[idict]] + + print (chain_props) result = [] for cp in chain_props: chain_dict = dictFromChainName(cp) @@ -64,7 +87,12 @@ def testChainDictMaker(): return result if __name__ == '__main__': - dicts = testChainDictMaker() + + idict = None + if len(sys.argv) > 1: + idict = int(sys.argv[1]) + + dicts = testChainDictMaker(idict) for d in dicts: print('') print (d) @@ -85,13 +113,13 @@ if __name__ == '__main__': chain_name = d[1]['chainName'] - forest = nodeForestFromChainLabel(label, chain_name) + forest = nodesFromLabel(label) algToolFactory = FastReductionAlgToolFactory() for tree in forest: toolSetter=ConditionsToolSetterFastReduction(algToolFactory) - print (tree2tools(rootless_tree=tree, + print (tree2tools(tree, toolSetter=toolSetter).dump()) print () diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/test_cases.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/test_cases.py index 20946219824c9a31f36d3352998e4cda66e95100..37f605105408686adcf6014085e6cfe20acddc36 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/test_cases.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/test_cases.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from __future__ import print_function @@ -49,6 +49,8 @@ test_strings = [ ) )""", + + 'simple([(38et, 0eta320, 100fltr:neta50, 90fltr:cphi100)])', ] diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py index a91db097e259da63274c673568464df9de136b9c..611bf7ec145a13cf828b4f803b90ac7ec1275e72 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py @@ -1,59 +1,58 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from __future__ import print_function from __future__ import absolute_import -from .constants import lchars +from .constants import (lchars, seps, digits) import re from collections import defaultdict +win_alphabet = lchars + seps +window_re = re.compile( + r'^(?P<lo>\d*)(?P<attr>[%s]+)(?P<hi>\d*)' % win_alphabet) + def defaultParameters(parameter, default=''): # default if parameter unknown - defaults = {'etalo': '0', - 'etahi': '320', - 'petalo': '0', # +ve eta - 'petahi': '320', - 'netalo': '320', # -ve eta - 'netahi': '0', - 'etlo': '0', - 'ethi': 'inf', - 'EtThreshold': '0.', - 'eta_mins': '0.', - 'eta_maxs': '3.2', - 'asymmetricEtas': 0, # exception: not a string - 'djmasslo': '0.0', - 'djmasshi': 'inf', - 'djdetalo': '0.', - 'djdetahi': 'inf', - 'djdphilo': '0.', - 'djdphihi': 'inf', - 'qjmasslo': '0.0', - 'qjmasshi': 'inf', - 'momCutslo': '-inf', - 'momCutshi': 'inf', - 'smclo': '0', - 'smchi': 'inf', - 'jvtlo': '0', - 'jvthi': 'inf', - 'htlo' : '1000.', - 'hthi' : 'inf', + explicit_defaults = { + 'etahi': '320', + 'j1etahi': '320', + 'j2etahi': '320', + 'eta_maxs': '3.2', + 'EtThreshold': '0.', + 'eta_mins': '0.', + 'asymmetricEtas': 0, # exception: not a string + 'momCutslo': '-inf', } + parameter = parameter.split(':')[-1] # fltr:eta.... if parameter.startswith('mom'): parameter = 'momCuts' - if parameter not in defaults: - print ('defaultParameters: unknown parameter, returning default ', - parameter) - return defaults.get(parameter, default) + if parameter in explicit_defaults: return explicit_defaults[parameter] + + if not default: + if parameter.endswith('lo'): + default = '0' + elif parameter.endswith('hi'): + default = 'inf' + else: + raise RuntimeError( + 'cannot find default for parameter ' + str(parameter)) + print ('returning default value for ' + str(parameter) + ': ', default) + return default def scaleFactors(parameter): - defaults = { + + defaults = { # only positive values here. sign done elsewhere 'eta': 0.01, - 'neta': -0.01, + 'neta': 0.01, + 'ceta': 0.01, 'peta': 0.01, + 'nphi': 0.01, + 'cphi': 0.01, + 'pphi': 0.01, 'et': 1000., 'ht': 1000., 'smc': 1000., @@ -64,8 +63,12 @@ def scaleFactors(parameter): 'momCuts': 0.01, 'jvt': 0.01, } + + parameter = parameter.split(':')[-1] # fltr:eta.... + if parameter.startswith('mom'): parameter = 'momCuts' + return defaults[parameter] class Checker(object): @@ -122,8 +125,6 @@ class ConditionsDictMaker(object): """ - window_re = re.compile( - r'^(?P<lo>\d*)(?P<attr>[%s]+)(?P<hi>\d*)' % lchars) # key: substring from chain label. value: attribute of python @@ -141,7 +142,7 @@ class ConditionsDictMaker(object): ['900mass,26dphi'] """ - alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789,' + alphabet = lchars + seps + digits pat = re.compile(r'(^\([%s]+\))'% alphabet ) s = params m = True @@ -151,6 +152,7 @@ class ConditionsDictMaker(object): if m is not None: conditions.append(m.group(0)) s = s[len(conditions[-1]):] + assert params == ''.join(conditions) conditions = [c[1:-1] for c in conditions] # strip parens return conditions @@ -184,8 +186,7 @@ class ConditionsDictMaker(object): toks.remove(chainpartinds[-1][0]) for t in toks: - m = self.window_re.match(t) - limits_dict = {} + m = window_re.match(t) if m is None: msgs.append('match failed for parameter %s' % t) error = True @@ -208,17 +209,23 @@ class ConditionsDictMaker(object): # must be set. The attribute name is used directly, # the defaults do not require multiplying by a scale factor. # - + attr = group_dict['attr'] # attribute name in label lo = group_dict['lo'] # string: low value or '' hi = group_dict['hi'] # string high value or '' def scale_limit(limit, sf): - try: - fl = float(limit) - except TypeError: # limit = 'inf' or similar - return limit + # note on the value inf in python + # the value of float('inf') is inf. + # the value of float('-inf') is -inf. + # the value of 10 * inf is inf. + # + # this is case independent: + # + # the value of float('iNf') is inf. + + fl = float(limit) if fl != 0: # avoid '-0' fl = fl * sf @@ -233,15 +240,37 @@ class ConditionsDictMaker(object): sf = scaleFactors(attr) + # scale fctors and negative limts + # Scaling taking the string version of the limit found in + # the jet labelm and + # + # converts it to a float, and scales it. eg for eta, + # '320' -> '3.2' + # + # Some limits are negative. eg the values assocated with + # neta are bot negative. Eg the '320neta100' represent + # cut values of -3.2 and -1.0. + # + # Currently (1/2021), dor attributes neta and nphi the + # both the low and high limits are negative, while for + # ceta, cphi (c = crossing zero) the lower limits are + # negative. + + neg_low = ('neta', 'nphi', 'ceta', 'cphi') + neg_high = ('neta', 'nphi') + + limits_dict = {} if lo: # find the python proxy class name - limits_dict['min'] = scale_limit(lo, sf) - + ssf = -sf if attr in neg_low else sf + limits_dict['min'] = scale_limit(lo, ssf) + if hi: - limits_dict['max'] = scale_limit(hi, sf) + ssf = -sf if attr in neg_high else sf + limits_dict['max'] = scale_limit(hi, ssf) cdict[attr] = limits_dict - + result.append((cdict, mult)) # append dictionary and mult. @@ -268,9 +297,6 @@ class TreeParameterExpander_simple(object): parameter strings look like '40et, 0eta320, nosmc' """ - window_re = re.compile( - r'^(?P<lo>\d*)(?P<attr>[%s]+)(?P<hi>\d*)' % lchars) - def __init__(self): self.msgs = [] @@ -286,47 +312,6 @@ class TreeParameterExpander_simple(object): return '%s: ' % self.__class__.__name__ + '\n'.join(self.msgs) -class TreeParameterExpander_agg(object): - """Convert parameter string into duction holding low, high window - cut vals, as for the 'simple' scenario. Then place conditions - not in the agg list in the filters dict. These conditions wil be used - to select the subset of the jet collection to be presented to the agg - conditions.""" - - agg_conditions = ('ht',) - - def __init__(self): - self.msgs = [] - - def mod(self, node): - - simple_expander = TreeParameterExpander_simple() - simple_expander.mod(node) - - # example conf_attrs: - # conf_attrs [3]: - # (defaultdict(<class 'dict'>, - # {'ht': {'min': '1000000.0', 'max': 'inf'}}), 1) - # (defaultdict(<class 'dict'>, - # {'et': {'min': '30000.0', 'max': 'inf'}}), 1) - # (defaultdict(<class 'dict'>, - # {'eta': {'min': '0.0', 'max': '3.2'}}), 1) - - - for ca in node.conf_attrs: - assert len(ca) == 2 # (dict, mult) - assert len(ca[0]) == 1 # one entry in dict - ca_keys = ca[0].keys() - cond_name = list(ca_keys)[0] - if cond_name not in self.agg_conditions: - node.filter_conditions.append(ca) - for fc in node.filter_conditions: - node.conf_attrs.remove(fc) - - def report(self): - return '%s: ' % self.__class__.__name__ + '\n'.join(self.msgs) - - class TreeParameterExpander_dijet(object): """Convert parameter string into tuples holding low, high window cut vals. Specialistaion for the dijet scenario @@ -337,10 +322,6 @@ class TreeParameterExpander_dijet(object): which will convert numeric values, and symbolic values such as 'inf' """ - window_re = re.compile( - r'^(?P<lo>\d*)(?P<attr>[%s]+)(?P<hi>\d*)' % lchars) - - def __init__(self): self.msgs = [] @@ -382,6 +363,28 @@ class TreeParameterExpander_all(object): return '%s: ' % self.__class__.__name__ + '\n'.join(self.msgs) +class FilterConditionsMover: + def mod(self, node): + """Move dictionary used to construct the filter for a Condition from + node.conf_attrs to node.filter_dicts""" + + filter_dicts = [] + for ca in node.conf_attrs: + assert len(ca) == 2 # (dict, mult) + ca_keys = ca[0].keys() + n_filtkey = 0 + + for ca_key in ca_keys: + if 'fltr' in ca_key: n_filtkey += 1 + assert n_filtkey == 0 or n_filtkey == len(ca_keys) + + if n_filtkey > 0: + filter_dicts.append(ca) + + [node.conf_attrs.remove(ca) for ca in filter_dicts] + node.filter_dicts = filter_dicts + + class TreeParameterExpander_null(object): """Does nothing except check the parameter string is empty""" @@ -403,7 +406,7 @@ class TreeParameterExpander(object): 'z': TreeParameterExpander_null, 'root': TreeParameterExpander_null, 'simple': TreeParameterExpander_simple, - 'agg': TreeParameterExpander_agg, + 'agg': TreeParameterExpander_simple, 'dijet': TreeParameterExpander_dijet, 'qjet': TreeParameterExpander_simple, 'all': TreeParameterExpander_all, diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.cxx index 04d82ce07394bcbf32635acd2e172bdd4b60b813..feac88b849455d8c4afd0a4f1ddb334de0ea9863 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.cxx @@ -6,12 +6,14 @@ #include "./ConditionFilter.h" -ConditionFilter::ConditionFilter(ConditionPtrs& conditions): +//ConditionFilter::ConditionFilter(ConditionPtrs& conditions): +ConditionFilter::ConditionFilter(ConditionsMT& conditions): m_conditions(std::move(conditions)) { } struct FilterPred{ - FilterPred(const ConditionPtr& cptr, + + FilterPred(const ConditionMT& cptr, const std::unique_ptr<ITrigJetHypoInfoCollector>& collector): m_cptr(cptr), m_collector(collector) { } @@ -21,7 +23,7 @@ struct FilterPred{ return m_cptr->isSatisfied(hjv, m_collector); } - const ConditionPtr& m_cptr; + const ConditionMT& m_cptr; const std::unique_ptr<ITrigJetHypoInfoCollector>& m_collector; }; @@ -54,4 +56,13 @@ std::string ConditionFilter::toString() const { return ss.str(); } - +HypoJetVector +ConditionFilter::filter (const HypoJetVector& jv, + const std::unique_ptr<ITrigJetHypoInfoCollector>& col) const { + return filter(jv.cbegin(), jv.cend(), col); +} + +std::ostream& operator<<(std::ostream& os, const ConditionFilter& cf){ + os << cf.toString(); + return os; +} diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.h index 3911c3f5ff322a8c2d88407e9f8888d0e74fc20d..942c63e839caa24cc9fa15956fa7d144ac34320a 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.h +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ConditionFilter.h @@ -5,23 +5,33 @@ #ifndef TRIGHLTJETHYPO_CONDITIONFILTER_H #define TRIGHLTJETHYPO_CONDITIONFILTER_H -#include "./CapacityCheckedConditionsDefs.h" +#include "./ConditionsDefsMT.h" +#include <ostream> class ConditionFilter { public: - ConditionFilter(ConditionPtrs&); + + ConditionFilter(){}; + + ConditionFilter(ConditionsMT&); // find the subset of jets which satisfy a sequence of conditions HypoJetVector filter (const HypoJetCIter& b, const HypoJetCIter& e, const std::unique_ptr<ITrigJetHypoInfoCollector>& ) const; + + HypoJetVector filter (const HypoJetVector&, + const std::unique_ptr<ITrigJetHypoInfoCollector>& + ) const; std::string toString() const; private: - ConditionPtrs m_conditions; - + ConditionsMT m_conditions; }; +std::ostream& operator<<(std::ostream&, const ConditionFilter&); + + #endif diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4c111d01fb7c36966c32fb0035379c4d0b2a2f3a --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.cxx @@ -0,0 +1,61 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ +# +#include "./PhiConditionMT.h" +#include "./ITrigJetHypoInfoCollector.h" +#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IJet.h" + +#include <sstream> +#include <cmath> +#include <TLorentzVector.h> + +PhiConditionMT::PhiConditionMT(double phiMin, + double phiMax): m_min(phiMin), m_max(phiMax){ +} + + +bool +PhiConditionMT::isSatisfied(const pHypoJet& ip, + const std::unique_ptr<ITrigJetHypoInfoCollector>& collector) const { + + auto phi = ip->phi(); + bool pass = m_min <= phi and m_max > phi; + + if(collector){ + const void* address = static_cast<const void*>(this); + + std::stringstream ss0; + ss0 << "PhiConditionMT: (" << address << ") " + << " phi[" << m_min << ", " << m_max << "]" + << " pass: " << std::boolalpha << pass << '\n'; + + auto j_addr = static_cast<const void*>(ip.get()); + std::stringstream ss1; + ss1 << " jet : ("<< j_addr << ") phi " << phi << '\n'; + + collector->collect(ss0.str(), ss1.str()); + + } + return pass; +} + + +bool +PhiConditionMT::isSatisfied(const HypoJetVector& ips, + const std::unique_ptr<ITrigJetHypoInfoCollector>& c) const { + auto result = isSatisfied(ips[0], c); + return result; +} + + +std::string PhiConditionMT::toString() const { + std::stringstream ss; + ss << "PhiConditionMT (" << this << ") phiMin " + << m_min + << " phiMax " + << m_max + <<'\n'; + + return ss.str(); +} diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.h new file mode 100644 index 0000000000000000000000000000000000000000..d81e6d0793c834b3f1c0677602d4d22041f2f9aa --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PhiConditionMT.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGHLTJETHYPO_PHICONDITIONSIGNEDMT_H +#define TRIGHLTJETHYPO_PHICONDITIONSIGNEDMT_H + + +/******************************************************************** + * + * NAME: PhiConditionSignedMT.h + * PACKAGE: Trigger/TrigHypothesis/TrigHLTJetHypo + * + * AUTHOR: P. Sherwood + *********************************************************************/ + +#include <string> +#include "./IConditionMT.h" + +namespace HypoJet{ + class IJet; +} + +class ITrigJetHypoInfoCollector; + +class PhiConditionMT: public IConditionMT{ + public: + PhiConditionMT(double phiMin, + double phiMax); + + bool isSatisfied(const HypoJetVector&, + const std::unique_ptr<ITrigJetHypoInfoCollector>&) const override; + + virtual unsigned int capacity() const override{return s_capacity;} + std::string toString() const override; + + private: + + double m_min; + double m_max; + bool isSatisfied(const pHypoJet&, + const std::unique_ptr<ITrigJetHypoInfoCollector>&) const; + + const static unsigned int s_capacity{1}; + +}; + +#endif diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HypoJetDefs.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HypoJetDefs.cxx index e29de4a36ddad603c6d38637a144b1c63196a913..cd5330df2cf14a33fe7c3b9b1cc21c280ab3dd5b 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HypoJetDefs.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HypoJetDefs.cxx @@ -12,7 +12,8 @@ std::ostream& operator << (std::ostream& out, const HypoJetVector& hjv) { out << static_cast<const void*>(j.get()) << " e " << j->e() << " et " << j->et() - << " eta " << j->eta() << '\n'; + << " eta " << j->eta() + << " phi " << j->phi() << '\n'; } return out; } diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.cxx new file mode 100644 index 0000000000000000000000000000000000000000..be9e7474b34be62f6b37219828f73dccff450ca4 --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.cxx @@ -0,0 +1,81 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TrigJetConditionConfig_phi.h" + +#include "GaudiKernel/StatusCode.h" +#include "./PhiConditionMT.h" +#include <cmath> + +TrigJetConditionConfig_phi::TrigJetConditionConfig_phi(const std::string& type, + const std::string& name, + const IInterface* parent) : + base_class(type, name, parent){ + +} + +StatusCode TrigJetConditionConfig_phi::initialize() { + + auto convert = [](const std::string& s) { + + if (s == "PI"){ + return M_PI; + } else if (s == "-PI") { + return -M_PI; + } + return std::stod(s); + }; + + try { + m_min = convert(m_strmin); + } catch (...) { + ATH_MSG_ERROR ("Cannot convert " + m_strmin + " to double"); + return StatusCode::FAILURE; + } + + try { + m_max = convert(m_strmax); + } catch (...) { + ATH_MSG_ERROR ("Cannot convert " + m_strmax + " to double"); + return StatusCode::FAILURE; + } + + CHECK(checkVals()); + return StatusCode::SUCCESS; +} + + +ConditionMT TrigJetConditionConfig_phi::getCondition() const { + return std::make_unique<PhiConditionMT>(m_min, m_max); +} + + +StatusCode TrigJetConditionConfig_phi::checkVals() const { + + if (m_min > m_max){ + ATH_MSG_ERROR(" min phi > max phi"); + return StatusCode::FAILURE; + } + + if (m_min < -M_PI) { + ATH_MSG_ERROR(" min phi " << m_min << " out of range"); + return StatusCode::FAILURE; + } + + if (m_max > M_PI) { + ATH_MSG_ERROR(" max phi " << m_max << " out of range"); + return StatusCode::FAILURE; + } + + return StatusCode::SUCCESS; +} + + +bool TrigJetConditionConfig_phi::addToCapacity(std::size_t) { + return false; +} + +std::size_t TrigJetConditionConfig_phi::capacity() const { + return getCondition()->capacity(); +} diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.h new file mode 100644 index 0000000000000000000000000000000000000000..7aeebf68afa8f0e2e7ff3397080cb22500b0179a --- /dev/null +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_phi.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGJETCONDITIONCONFIG_PHI_H +#define TRIGJETCONDITIONCONFIG_PHI_H + +#include "ITrigJetConditionConfig.h" +#include "./ConditionsDefsMT.h" +#include "AthenaBaseComps/AthAlgTool.h" +#include "./ConditionsDefsMT.h" +#include "./ArgStrToDouble.h" + +class TrigJetConditionConfig_phi: +public extends<AthAlgTool, ITrigJetConditionConfig> { + + public: + + TrigJetConditionConfig_phi(const std::string& type, + const std::string& name, + const IInterface* parent); + + virtual StatusCode initialize() override; + virtual ConditionMT getCondition() const override; + + virtual bool addToCapacity(std::size_t) override; + virtual std::size_t capacity() const override; + + private: + + // phi min and max are strings. "PI" and "-PI" , as well + // as any intermediate value that converts to a double value + // in the range (-pi, pi), eg "1.0", are accepted. + + Gaudi::Property<std::string> + m_strmin{this, "min", {}, "min for phi region"}; + + Gaudi::Property<std::string> + m_strmax{this, "max", {}, "max for phi region"}; + + double m_min{0.}; + double m_max{0.}; + + StatusCode checkVals() const; + +}; +#endif diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx index 755ac22a197680c0d9a7da4c66442179f07e2d5b..9fa71359e6daf24fd3426da8670b67c4b1b2f1ee 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx @@ -15,6 +15,7 @@ #include "./CapacityCheckedCondition.h" #include "./FastReductionMatcher.h" #include "./Tree.h" +#include "./ConditionsDefsMT.h" #include "TrigCompositeUtils/TrigCompositeUtils.h" @@ -89,7 +90,8 @@ TrigJetHypoToolConfig_fastreduction::getConditionFilters() const { auto filters = std::vector<std::unique_ptr<ConditionFilter>>(); for(const auto& cm : m_filtConditionMakers){ - ConditionPtrs filterConditions; // will contain a single Condition + + ConditionsMT filterConditions; // will contain a single Condition filterConditions.push_back(cm->getCapacityCheckedCondition()); auto cf = std::make_unique<ConditionFilter>(filterConditions); filters.push_back(std::move(cf)); diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h index de228b5c9df656672ef850083c18f59d5209ba85..51511a4fc23545480b42c7c436ee6bdecd4b7658 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h @@ -62,6 +62,7 @@ public extends<AthAlgTool, ITrigJetHypoToolNoGrouperConfig> { ToolHandleArray<ITrigJetCapacityCheckedConditionConfig> m_filtConditionMakers{ this, "filtConditionsMakers", {}, "hypo tree Condition builder AlgTools for Condition filters"}; + Gaudi::Property<std::vector<std::size_t>> m_treeVec{ this, "treeVector", {}, "integer sequence representation of jet hypo tree"}; diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.cxx index cd5f8306032d7f574e910cd31a7137c8749bd5ff..a21699d8d8ccd408e461e8c2bb6f1e72ceece81b 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.cxx @@ -6,10 +6,11 @@ #include "./ITrigJetHypoInfoCollector.h" #include "./xAODJetCollector.h" #include "./JetTrigTimer.h" -#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/CleanerFactory.h" #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/xAODJetAsIJet.h" // TLorentzVec #include "./nodeIDPrinter.h" #include "./DebugInfoCollector.h" +#include "./ConditionInverter.h" +#include "./CompoundConditionMT.h" #include <algorithm> #include <sstream> @@ -21,6 +22,7 @@ TrigJetHypoToolHelperNoGrouper::TrigJetHypoToolHelperNoGrouper(const std::string StatusCode TrigJetHypoToolHelperNoGrouper::initialize() { + CHECK(makePrefilter()); for (const auto& config : m_configs) { m_matchers.push_back(config->getMatcher()); } @@ -43,38 +45,34 @@ TrigJetHypoToolHelperNoGrouper::collectData(const std::string& exetime, bool -TrigJetHypoToolHelperNoGrouper::pass(HypoJetVector& jets, +TrigJetHypoToolHelperNoGrouper::pass(HypoJetVector& jetsIn, xAODJetCollector& jetCollector, const std::unique_ptr<ITrigJetHypoInfoCollector>& collector) const { if(collector){ std::stringstream ss; - ss << "No of jets " + std::to_string(jets.size()) + '\n'; - ss << jets; + ss << "No of jets " + std::to_string(jetsIn.size()) + '\n'; + ss << jetsIn; collector->collect(name(), ss.str()); } JetTrigTimer timer; timer.start(); - if(jets.empty()){ + if(jetsIn.empty()){ timer.stop(); bool pass = false; collectData(timer.readAndReset(), collector, pass); return pass; } - // jet cleaning + // prefiltering. + + auto jets = m_prefilter.filter(jetsIn, collector); + HypoJetIter jets_begin = jets.begin(); HypoJetIter jets_end = jets.end(); - for(auto cleaner: m_cleaners){ - jets_end = std::partition(jets_begin, - jets_end, - [cleaner](const pHypoJet& j){ - return cleaner->select(j);} - ); - } - + // see if matchers pass. Each matcher conatains a FastReducer tree. // if > matcher, this means the conditions of different trees may // share jets. @@ -107,12 +105,7 @@ std::string TrigJetHypoToolHelperNoGrouper::toString() const { std::stringstream ss; ss << name(); - ss << "Cleaners:\n No of cleaners: " << m_cleaners.size() << '\n'; - - for(auto cleaner : m_cleaners) { - ss << cleaner->toString() - << '\n'; - } + ss << "prefilter:\n " << m_prefilter << '\n'; ss << "\nMatchers [" << m_matchers.size() << "]:\n\n"; unsigned int imatcher{0}; @@ -136,6 +129,40 @@ std::size_t TrigJetHypoToolHelperNoGrouper::requiresNJets() const { return m_configs[0]->requiresNJets(); } +StatusCode TrigJetHypoToolHelperNoGrouper::makePrefilter(){ + /* set up the prefilter by looping over the precondition + Condition maker AlgTools to obtain the elemental Conditions, + place these in a single compound Condition, and warp this in a + CondtionInverter. This is passed to the ConditionFilter object. + */ - + // if no conditions the filter will apply n inverter to an empty + // Compound Condition, which will kill all events. + if (m_prefilterConditionMakers.empty()) {return StatusCode::SUCCESS;} + + auto makeElementalFilterCondition = [](auto& conditionMaker)->ConditionMT { + return conditionMaker->getCapacityCheckedCondition(); + }; + + // fill a container with pointers to an elemental condition + // note: ICapacityCheckedCondition derives from IConditionMT + ConditionsMT prefilterConditions{}; + std::transform(m_prefilterConditionMakers.begin(), + m_prefilterConditionMakers.end(), + std::back_inserter(prefilterConditions), + makeElementalFilterCondition); + + // create a compound condition pointer. + auto cc = std::make_unique<CompoundConditionMT>(prefilterConditions); + + // create a conditonsMT vec, add the inversuion of the compound condition + // to it. With the inversion, the invert compound condition acts as veto + ConditionsMT condVec; + condVec.push_back(std::make_unique<ConditionInverterMT>(std::move(cc))); + + // create an filter from the vector containing the inverted condition. + m_prefilter = ConditionFilter{condVec}; + + return StatusCode::SUCCESS; +} diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.h index c398770e741ab74022aa9f21b63b895bcbc52fe0..e93490bc270f6182119a1fa1c7f02c998fc6a4bb 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.h +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolHelperNoGrouper.h @@ -23,9 +23,11 @@ #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/ICleanerTool.h" #include "./IJetsMatcherMT.h" #include "./ConditionsDefsMT.h" +#include "./ConditionFilter.h" #include "TrigHLTJetHypo/ITrigJetHypoToolHelperMT.h" #include "ITrigJetHypoToolNoGrouperConfig.h" +#include "./ITrigJetCapacityCheckedConditionConfig.h" class ITrigJetHypoInfoCollector; class xAODJetCollector; @@ -56,18 +58,22 @@ public extends<AthAlgTool, ITrigJetHypoToolHelperMT> { // Object that matches jet groups with Conditions std::vector<std::unique_ptr<IJetsMatcherMT>> m_matchers; - // Bridge objects to ICleaner predicate function objects to allow polymorphic - // pointers to be used with the STL (pass by value). - ToolHandleArray<ICleanerTool> m_cleaners; - /////////////////////////////// // Used to generate helper objects foe TrigHLTJetHelper // from user supplied values ToolHandleArray<ITrigJetHypoToolNoGrouperConfig> m_configs { this, "HypoConfigurers", {}, - "Configurers to set up TrigJetHypoHelperNoGrouper"}; + "Configurers to set up TrigJetHypoHelperNoGrouper"}; + + ToolHandleArray<ITrigJetCapacityCheckedConditionConfig> + m_prefilterConditionMakers{this, "prefiltConditionMakers", {}, + "hypo tree Condition builder AlgTools for hypo pre-filtering"}; + + // object that copies selected incomming jets into a new vector. + ConditionFilter m_prefilter{}; + Gaudi::Property<bool> m_debug {this, "debug", false, "instantantiate helpers with this debug flag"}; @@ -76,7 +82,9 @@ public extends<AthAlgTool, ITrigJetHypoToolHelperMT> { const std::unique_ptr<ITrigJetHypoInfoCollector>&, const std::optional<bool>& pass) const; - virtual std::string toString() const override; + StatusCode makePrefilter(); + + virtual std::string toString() const override; }; #endif diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx index 3f1141a4035749d5517fefe64a0c84ef5742ac0a..9b6ea318e3b69b331318c5a4b081952f61c89458 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration */ // ******************************************************************** @@ -75,9 +75,13 @@ TrigJetHypoToolMT::decide(const xAOD::JetContainer* jets, } std::unique_ptr<ITrigJetHypoInfoCollector> infocollector(nullptr); + std::unique_ptr<ITrigJetHypoInfoCollector> jetdumper(nullptr); if(m_visitDebug){ auto collectorName = name() + "_" + std::to_string(m_eventSN->getSN()); infocollector.reset(new DebugInfoCollector(collectorName)); + auto jetdumperName = + name()+"_passingjets_" + std::to_string(m_eventSN->getSN()); + jetdumper.reset(new DebugInfoCollector(jetdumperName)); } @@ -140,7 +144,12 @@ TrigJetHypoToolMT::decide(const xAOD::JetContainer* jets, if (infocollector){ infocollector->collect("TrigJetHypoToolMT", msg); infocollector->write(); + + std::stringstream ss; + ss << jetCollector.hypoJets(); + jetdumper->collect("passed", ss.str()); } + return StatusCode::SUCCESS; } diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/components/TrigHLTJetHypo_entries.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/components/TrigHLTJetHypo_entries.cxx index 4974748f7260026bcd956dea9e4ad01c8ba1b568..b16c516d42fa500a9a38dac6e1423f6f5cc3fd27 100644 --- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/components/TrigHLTJetHypo_entries.cxx +++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/components/TrigHLTJetHypo_entries.cxx @@ -18,6 +18,7 @@ // #include "../TrigJetConditionConfig_abs_eta.h" #include "../TrigJetConditionConfig_signed_eta.h" +#include "../TrigJetConditionConfig_phi.h" #include "../TrigJetConditionConfig_et.h" #include "../TrigJetConditionConfig_ht.h" #include "../TrigJetConditionConfig_htfr.h" @@ -62,6 +63,7 @@ DECLARE_COMPONENT(TrigHLTJetHypo_TLA) DECLARE_COMPONENT(TrigHLTJetHypo_EtaEt) +DECLARE_COMPONENT(TrigJetConditionConfig_phi) DECLARE_COMPONENT(TrigJetConditionConfig_signed_eta) DECLARE_COMPONENT(TrigJetConditionConfig_abs_eta) DECLARE_COMPONENT(TrigJetConditionConfig_et) diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref index 661057efcdc06389c064a87177d42b857d1dc358..1cc1febd15fa9c63b00ac37a2f6c6951fb8ee4a8 100644 --- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref +++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref @@ -2144,6 +2144,12 @@ HLT_j460_a10t_lcw_nojcalib_35smcINF_L1J100: eventCount: 0 HLT_j460_a10t_lcw_nojcalib_L1J100: eventCount: 0 +HLT_j60_j0_fbdjshared_L1J20: + eventCount: 7 + stepCounts: + 0: 7 + stepFeatures: + 0: 177 HLT_j80_0eta240_2j60_320eta490_j0_dijetSEP80j1etSEP0j1eta240SEP80j2etSEP0j2eta240SEP700djmass_L1J20: eventCount: 0 HLT_j80_L1J15: @@ -2164,6 +2170,14 @@ HLT_j85_ftf_L1J20: stepFeatures: 0: 19 1: 22 +HLT_j85_ftf_pfltrSEP300ceta210SEP300nphi10_L1J20: + eventCount: 10 + stepCounts: + 0: 19 + 1: 10 + stepFeatures: + 0: 19 + 1: 14 HLT_j85_pf_ftf_L1J20: eventCount: 13 stepCounts: diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref index 00ed56d809329fffe706bc505f3f5ee36823fe6c..628473f53c78de4f10d4dcfd1bb17547dc2847ff 100644 --- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref +++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref @@ -1070,6 +1070,12 @@ HLT_j460_a10t_lcw_nojcalib_35smcINF_L1J100: eventCount: 0 HLT_j460_a10t_lcw_nojcalib_L1J100: eventCount: 0 +HLT_j60_j0_fbdjshared_L1J20: + eventCount: 1 + stepCounts: + 0: 1 + stepFeatures: + 0: 9 HLT_j80_0eta240_2j60_320eta490_j0_dijetSEP80j1etSEP0j1eta240SEP80j2etSEP0j2eta240SEP700djmass_L1J20: eventCount: 0 HLT_j80_L1J15: @@ -1094,6 +1100,14 @@ HLT_j85_ftf_L1J20: stepFeatures: 0: 5 1: 3 +HLT_j85_ftf_pfltrSEP300ceta210SEP300nphi10_L1J20: + eventCount: 3 + stepCounts: + 0: 5 + 1: 3 + stepFeatures: + 0: 5 + 1: 3 HLT_j85_pf_ftf_L1J20: eventCount: 3 stepCounts: diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py index a85843e8c207bdaef7ca1473a6a82186df900c6f..8d380d8f67a6617e799aeb8575702bde52b47252 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/LS2_v1.py @@ -283,10 +283,15 @@ def setupMenu(): ChainProp(name='HLT_j0_fbdjnosharedSEP10etSEP20etSEP34massSEP50fbet_L1J20', groups=SingleJetGroup), ChainProp(name='HLT_j0_fbdjshared_L1J20', groups=SingleJetGroup), + ChainProp(name='HLT_j60_j0_fbdjshared_L1J20', l1SeedThresholds=['FSNOSEED']*2, groups=MultiJetGroup), ChainProp(name='HLT_j0_aggSEP1000htSEP30etSEP0eta320_L1J20', groups=SingleJetGroup), ChainProp(name='HLT_j0_aggSEP500htSEP30etSEP0eta320_L1J20', groups=SingleJetGroup), + + ChainProp(name='HLT_j85_ftf_pfltrSEP300ceta210SEP300nphi10_L1J20', + groups=SingleJetGroup), + ChainProp(name='HLT_j40_j0_aggSEP50htSEP10etSEP0eta320_L1J20', l1SeedThresholds=['FSNOSEED']*2, groups=MultiJetGroup), diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py index 6167871ac88943742bddbcde9ffb4d35733cbebc..457679351526ff1f580464f3f5cd300ae5187ff5 100644 --- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py +++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/SignatureDicts.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration from AthenaCommon.Logging import logging log = logging.getLogger( __name__ ) log.info("Importing %s",__name__) @@ -143,6 +143,7 @@ JetChainParts = { 'aggSEP100htSEP10etSEP0eta320', 'aggSEP50htSEP10etSEP0eta320', ], + # Simple hypo configuration. Single property cuts defined as MINvarMAX 'etaRange' : ['0eta320', '320eta490', '0eta240', '0eta290'], @@ -150,8 +151,8 @@ JetChainParts = { ['010jvt', '011jvt', '015jvt', '020jvt', '050jvt', '059jvt'], 'momCuts' : # Generic moment cut on single jets ['050momemfrac100','momhecfrac010','050momemfrac100SEPmomhecfrac010'], - 'cleaning' : # Jet cleaning per jet (currently unused) - ['noCleaning',], + 'prefilters' : # Pre-hypo jet selectors (including cleaning) + ['loose', 'pfltrSEP300ceta210SEP300nphi10'], 'smc' : # "Single mass condition" -- rename? ['30smcINF', '35smcINF', '40smcINF', '50smcINF', '60smcINF', 'nosmc'], # Setup for alternative data stream readout @@ -194,7 +195,7 @@ JetChainParts_Default = { 'etaRange' : '0eta320', 'jvt' : '', 'momCuts' : '', - 'cleaning' : 'noCleaning', + 'prefilters' : [], 'hypoScenario' : 'simple', 'smc' : 'nosmc', #