3 from TriggerMenuMT.HLT.Config.MenuComponents
import AlgNode, HypoAlgNode
4 from TriggerMenuMT.HLT.Config.ControlFlow.MenuComponentsNaming
import CFNaming
5 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig
import HLTMenuConfig
6 from TriggerMenuMT.HLT.Config.ControlFlow.HLTCFTools
import isComboHypoAlg
7 from TriggerMenuMT.HLT.Config.MenuComponents
import EmptyMenuSequence
8 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
9 from AthenaConfiguration.ComponentFactory
import CompFactory
10 from AthenaCommon.CFElements
import findAlgorithmByPredicate, parOR, seqAND
11 from functools
import lru_cache
13 from AthenaCommon.Logging
import logging
14 log = logging.getLogger( __name__ )
16 RoRSeqFilter = CompFactory.RoRSeqFilter
17 PassFilter = CompFactory.PassFilter
21 """Node for any kind of sequence filter"""
22 def __init__(self, Alg, inputProp, outputProp):
23 AlgNode.__init__(self, Alg, inputProp, outputProp)
35 return "SequenceFilter::%s [%s] -> [%s], chains=%s"%(self.Alg.name,
' '.
join(map(str, self.getInputList())),
' '.
join(map(str, self.getOutputList())), self.
getChains())
41 SequenceFilterNode.__init__(self, Alg,
'Input',
'Output')
44 input_index = self.readInputList().
index(input_name)
45 if len(self.Alg.ChainsPerInput) == input_index:
46 self.Alg.ChainsPerInput.append([name])
47 elif len(self.Alg.ChainsPerInput) > input_index:
48 self.Alg.ChainsPerInput[input_index].
append(name)
50 log.error(
"Error: why requiring input %i when size is %i ?" , input_index , len(self.Alg.ChainsPerInput))
51 raise RuntimeError(
"Error: why requiring input %i when size is %i " , input_index , len(self.Alg.ChainsPerInput))
53 return self.Alg.Chains.append(name)
56 return self.Alg.Chains
59 return self.Alg.ChainsPerInput
64 """ PassFilter is a Filter node without inputs/outputs, so OutputProp=InputProp=empty"""
66 Alg=CompFactory.AthSequencer(
"PassSequence" )
67 Alg.IgnoreFilterPassed=
True
68 SequenceFilterNode.__init__(self, Alg,
'',
'')
83 return isinstance(alg, PassFilterNode)
89 """Class to describe the flow of decisions through ChainStep + filter with their connections (input, output)
90 A Filter can have more than one input/output if used in different chains, so this class stores and manages all of them (when doing the connect)
93 log.debug(
" *** Create CFSequence %s with Filter %s", ChainStep.name, FilterAlg.Alg.getName())
99 seqAndWithFilter = FilterAlg.Alg
if ChainStep.isEmpty
else seqAND(ChainStep.name)
100 self.
ca.addSequence(seqAndWithFilter)
101 self.
seq = seqAndWithFilter
102 if not ChainStep.isEmpty:
103 self.
ca.addEventAlgo(FilterAlg.Alg, sequenceName=seqAndWithFilter.getName())
106 self.
ca.addSequence(self.
stepReco, parentName=seqAndWithFilter.getName())
107 log.debug(
"created parOR %s inside seqAND %s ", self.
stepReco.
getName(), seqAndWithFilter.getName())
110 for menuseq
in ChainStep.sequences:
111 if not isinstance(menuseq, EmptyMenuSequence):
112 self.
ca.
merge(menuseq.hypoAcc, sequenceName=seqAndWithFilter.getName())
116 if self.
step.combo
is not None:
117 self.
ca.
merge(self.
step.combo.acc, sequenceName=seqAndWithFilter.getName())
118 log.debug(
"CFSequence.__init: created %s ",self)
122 """ Set the output decision of this CFSequence as the hypo outputdecision; In case of combo, takes the Combo outputs"""
125 if self.
step.combo
is None:
129 log.debug(
"CFSequence: set out decisions: %s", self.
decisions)
133 """ connect Combo to Hypos"""
134 if self.
step.combo
is None:
135 log.debug(
"CFSequence.connectCombo: no Combo found")
138 for seq
in self.
step.sequences:
139 combo_input=seq.getOutputList()[0]
140 self.
step.combo.addInput(combo_input)
141 inputs = self.
step.combo.readInputList()
142 legindex = inputs.index(combo_input)
143 log.debug(
"CFSequence.connectCombo: adding input to %s: %s", self.
step.combo.Alg.getName(), combo_input)
145 combo_output=CFNaming.comboHypoOutputName (self.
step.combo.Alg.getName(), legindex)
146 self.
step.combo.addOutput(combo_output)
147 log.debug(
"CFSequence.connectCombo: adding output to %s: %s", self.
step.combo.Alg.getName(), combo_output)
150 for menuseq
in chainStep.sequences:
153 except Exception
as e:
154 log.error(f
'Failed to merge into {self.stepReco.getName()}')
162 return "--- CFSequence ---\n + Filter: %s \n + decisions: %s\n + %s \n"%(\
169 """Class to store the Step + its Filter (CFSequence) plus the chains and dictionaries of the legs using that step """
175 log.debug(
"CFGroup.__init: created for %s ",ChainStep.name)
178 '''This creates the CAs for the menu sequences, if fastMenu style, and the CFSequence'''
179 log.debug(
"CFGroup.creating CFSEquence")
190 """Connect filter to ChainStep (and all its sequences) through these connections (which are sets of filter outputs)
191 if a ChainStep contains the same sequence multiple times (for multi-leg chains),
192 the filter is connected only once (to avoid multiple DH links)
194 if log.isEnabledFor(logging.DEBUG):
195 log.debug(
"CFGroup: connect Filter %s with %d menuSequences of step %s, using %d connections", self.
sequenceCA.filterNode.Alg.name, len(self.
sequenceCA.step.sequences), self.
sequenceCA.step.name, len(connections))
196 log.debug(
" --- sequences: ")
200 if len(connections) == 0:
201 log.error(
"No filter outputs are set!")
205 if len(connections) != len(self.
sequenceCA.step.sequences):
206 log.error(
"CFGroup: Found %d connections and %d MenuSequences in Step %s", len(connections), len(self.
sequenceCA.step.sequences), self.
sequenceCA.step.name)
207 raise Exception(
"[CFGroup] Connections and sequences do not match, this must be fixed!")
209 for nseq, seq
in enumerate(self.
sequenceCA.step.sequences):
210 filter_out = connections[nseq]
211 log.debug(
"CFGroup: Found input %s to sequence::%s from Filter::%s", filter_out, seq.name, self.
sequenceCA.filterNode.Alg.name)
212 seq.connectToFilter( filter_out )
214 log.debug(
"This CFGroup has no sequences: outputs are the Filter outputs, which are %d", len(self.
sequenceCA.decisions))
217 """ set and create HypoTools accumulated on the self.step from an input step configuration
222 log.debug(
"CFGroup.createHypoTools for Step %s", self.
sequenceCA.step.name)
224 for seq, onePartChainDict
in zip(self.
sequenceCA.step.sequences, sdict):
225 log.debug(
' seq: %s, onePartChainDict:', seq.name)
226 log.debug(
' %s', onePartChainDict)
227 if not isinstance(seq, EmptyMenuSequence):
228 hypoToolConf=seq.getHypoToolConf()
229 if hypoToolConf
is None:
230 log.error(
"HypoToolConf not found ", seq.name)
231 hypoToolConf.setConf( onePartChainDict )
232 hypo = HypoAlgNode(Alg = self.
sequenceCA.ca.getEventAlgo(seq.hypo.Alg.getName()))
233 hypoToolAcc = hypo.addHypoTool(flags, hypoToolConf)
234 if isinstance(hypoToolAcc, ComponentAccumulator):
238 chainDict = HLTMenuConfig.getChainDictFromChainName(chain)
239 self.
sequenceCA.step.combo.createComboHypoTools(flags, chainDict, conf)