3 """ Helper functions for configuring MET chains"""
5 from __future__
import annotations
6 from typing
import Any, Optional
8 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
9 from AthenaConfiguration.ComponentFactory
import CompFactory
10 from ..Menu.SignatureDicts
import METChainParts_Default, METChainParts
11 from ..Config.MenuComponents
import (
17 from .StepOutput
import StepOutput
19 from ..CommonSequences.FullScanDefs
import trkFSRoI
20 from AthenaCommon.Logging
import logging
21 from TrigEFMissingET.TrigEFMissingETConfig
import getMETMonTool
22 from abc
import ABC, abstractmethod
23 from string
import ascii_uppercase
24 from TrigMissingETHypo.TrigMissingETHypoConfig
import TrigMETHypoToolFromDict
28 return CompFactory.TrigStreamerHypoTool(chainDict[
"chainName"])
31 log = logging.getLogger(__name__)
45 metFSRoIs: list[str |
None] = [
"",
None, trkFSRoI]
49 """Convert a dictionary containing reconstruction keys to a string
51 Any key (from recoKeys) missing will just be skipped.
55 recoDict : dict[str, str]
56 The reconstruction dictionary
57 skipDefaults : bool, optional
58 If true, skip any values that match the default, by default True
63 The fixed string representation
69 and (
not skipDefaults
or recoDict[k] != METChainParts_Default[k])
74 """Convert a string to a MET reco dict. Optionally only keep entries contained in recoKeys.
75 Necessary for correctly configuring algorithms as inputs to NN.
77 defaults =
copy(METChainParts_Default)
79 defaults = {key: defaults[key]
for key
in recoKeys}
81 for part
in string.split(
"_"):
82 for key, values
in METChainParts.items():
83 if not isinstance(values, list):
86 if isinstance(defaults[key], list):
94 """Base class to describe algorithm configurations
96 Each individual 'EFrecoAlg' should be described by *one* AlgConfig subclass.
97 It must provide its list of required inputs to the constructor and override
100 The name of fexAlg *must* be self.fexName and the METContainerKey property
101 *must* be set to self.outputKey (but this class usually should take care of
104 The subclass must also implement the @classmethod 'algType' which returns
105 the EFrecoAlg string that it describes.
110 """The algorithm that this object configures - this corresponds to the
111 EFrecoAlg in the METChainParts dictionary
113 Note that no two subclasses of AlgConfig can describe the same algorithm
114 (as identified by this string).
116 raise NotImplementedError(
"algType not implemented by subclass!")
119 """Initialise the base class
124 recoDict: Pass *all* the keys required for the recoDict
130 assert all(k
in recoDict
for k
in recoKeys), (
131 f
"AlgConfig.__init__ for {alg_type} did not receive all the recoKeys"
132 " - this suggests a problem in the subclass __init__ method!"
139 """The MET container object produced by this algorithm"""
140 from TrigEDMConfig.TriggerEDM
import recordable
146 """The name of the algorithm made by this configuration"""
150 """Return a version of the reco dict with any necessary post-processing"""
154 """Create the monitoring tool"""
158 return f
"step{ascii_uppercase[idx]}_{self._suffix}"
162 """Create the reconstruction sequences including the FEX
164 Returns a list of CAs split by step
167 def _append_fex(self, flags, fex, inputs: Optional[StepOutput] =
None) ->
None:
168 """Append the FEX to the output object
170 Finalizes the FEX by setting the monitoring tool and output name.
172 fex.MonTool = self.getMonTool(flags)
173 fex.METContainerKey = self.outputKey
175 acc.addEventAlgo(fex, primary=
True)
176 return StepOutput.create(acc, inputs, MET=self.outputKey)
179 """Make the reconstruction sequences for the new JO style"""
181 log.verbose(
"Create inputs for %s", self.
_suffix)
182 steps, inputs = self.inputRegistry.build_steps(
183 flags, self._inputs, metFSRoIs, self.
recoDict, return_ca=
True
186 fex = self.make_fex_accumulator(flags, self.
fexName, inputs)
189 steps[-1].addEventAlgo(fex)
193 """Make the full accumulator steps"""
201 for step_idx, reco_sequence
in enumerate(reco_sequences):
204 step_name = f
"Empty_METStep{step_idx}"
208 if step_idx == len(reco_sequences) - 1:
211 hypo_tool = TrigMETHypoToolFromDict
215 hypo_tool = streamer_hypo_tool
218 reco_acc.mergeReco(reco_sequence)
221 sel_acc = SelectionCA(
"METAthSeq_" + self.
name_step(step_idx))
223 sel_acc.mergeReco(reco_acc)
225 sel_acc.addHypoAlgo(hypo_alg)
232 step_name = sel_acc.name
238 chainDicts=[chainDict],
242 functools.partial(make_MET_menu_sequenceGenCfg, flags, sel_acc, hypo_tool)
244 isEmpty=
True if sel_acc
is None else False
252 """The hypo alg used for this configuration"""
253 return CompFactory.TrigMissingETHypoAlg(
254 f
"METHypoAlg_{self._suffix}", METContainerKey=self.
outputKey
258 return CompFactory.TrigStreamerHypoAlg(
259 "METPassThroughHypo_" + self.
name_step(step)
263 """Get the InEventRecoCA for the given step index"""
264 from TrigT2CaloCommon.CaloDef
import clusterFSInputMaker
265 from AthenaConfiguration.ComponentFactory
import CompFactory
266 from ..CommonSequences.FullScanDefs
import trkFSRoI
274 return InEventRecoCA(
276 inputMaker=CompFactory.InputMakerForRoI(
277 "IM_Jet_TrackingStep",
278 RoITool=CompFactory.ViewCreatorInitialROITool(),
283 raise KeyError(f
"No input maker for step {idx}")
287 """Provides a way to iterate over all subclasses of this class"""
288 for subcls
in cls.__subclasses__():
289 for subsubcls
in subcls.__subclasses__():
296 if subcls.algType() == EFrecoAlg:
297 return subcls(EFrecoAlg=EFrecoAlg, **recoDict)
299 raise ValueError(
"Unknown EFrecoAlg '{}' requested".
format(EFrecoAlg))
302 return MenuSequence(flags, selectionCA=sel_acc, HypoToolGen=hypo_tool)
305 from .
import AlgConfigs
308 AlgConfigs.test_configs()