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())
40 SequenceFilterNode.__init__(self, Alg,
'Input',
'Output')
45 input_index = self.readInputList().
index(input_name)
46 chains_in_input = self.getPar(
"ChainsPerInput")
47 if len(chains_in_input) == input_index:
48 chains_in_input.append([name])
49 elif len(chains_in_input) > input_index:
50 chains_in_input[input_index].
append(name)
52 log.error(
"Error: why requiring input %i when size is %i ?" , input_index , len(chains_in_input))
53 raise RuntimeError(
"Error: why requiring input %i when size is %i " , input_index , len(chains_in_input))
55 self.Alg.ChainsPerInput= chains_in_input
56 return self.setPar(
"Chains", name)
59 return self.getPar(
"Chains")
62 return self.getPar(
"ChainsPerInput")
67 """ PassFilter is a Filter node without inputs/outputs, so OutputProp=InputProp=empty"""
69 Alg=CompFactory.AthSequencer(
"PassSequence" )
70 Alg.IgnoreFilterPassed=
True
71 SequenceFilterNode.__init__(self, Alg,
'',
'')
86 return isinstance(alg, PassFilterNode)
92 """Class to describe the flow of decisions through ChainStep + filter with their connections (input, output)
93 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)
96 log.debug(
" *** Create CFSequence %s with Filter %s", ChainStep.name, FilterAlg.Alg.getName())
102 seqAndWithFilter = FilterAlg.Alg
if ChainStep.isEmpty
else seqAND(ChainStep.name)
103 self.
ca.addSequence(seqAndWithFilter)
104 self.
seq = seqAndWithFilter
105 if not ChainStep.isEmpty:
106 self.
ca.addEventAlgo(FilterAlg.Alg, sequenceName=seqAndWithFilter.getName())
109 self.
ca.addSequence(self.
stepReco, parentName=seqAndWithFilter.getName())
110 log.debug(
"created parOR %s inside seqAND %s ", self.
stepReco.
getName(), seqAndWithFilter.getName())
113 for menuseq
in ChainStep.sequences:
114 if not isinstance(menuseq, EmptyMenuSequence):
115 self.
ca.
merge(menuseq.hypoAcc, sequenceName=seqAndWithFilter.getName())
119 if self.
step.combo
is not None:
120 self.
ca.
merge(self.
step.combo.acc, sequenceName=seqAndWithFilter.getName())
121 log.debug(
"CFSequence.__init: created %s ",self)
125 """ Set the output decision of this CFSequence as the hypo outputdecision; In case of combo, takes the Combo outputs"""
128 if self.
step.combo
is None:
132 log.debug(
"CFSequence: set out decisions: %s", self.
decisions)
136 """ connect Combo to Hypos"""
137 if self.
step.combo
is None:
138 log.debug(
"CFSequence.connectCombo: no Combo found")
141 for seq
in self.
step.sequences:
142 combo_input=seq.getOutputList()[0]
143 self.
step.combo.addInput(combo_input)
144 inputs = self.
step.combo.readInputList()
145 legindex = inputs.index(combo_input)
146 log.debug(
"CFSequence.connectCombo: adding input to %s: %s", self.
step.combo.Alg.getName(), combo_input)
148 combo_output=CFNaming.comboHypoOutputName (self.
step.combo.Alg.getName(), legindex)
149 self.
step.combo.addOutput(combo_output)
150 log.debug(
"CFSequence.connectCombo: adding output to %s: %s", self.
step.combo.Alg.getName(), combo_output)
153 for menuseq
in chainStep.sequences:
156 except Exception
as e:
157 log.error(f
'Failed to merge into {self.stepReco.getName()}')
165 return "--- CFSequence ---\n + Filter: %s \n + decisions: %s\n + %s \n"%(\
172 """Class to store the Step + its Filter (CFSequence) plus the chains and dictionaries of the legs using that step """
178 log.debug(
"CFGroup.__init: created for %s ",ChainStep.name)
181 '''This creates the CAs for the menu sequences, if fastMenu style, and the CFSequence'''
182 log.debug(
"CFGroup.creating CFSEquence")
193 """Connect filter to ChainStep (and all its sequences) through these connections (which are sets of filter outputs)
194 if a ChainStep contains the same sequence multiple times (for multi-leg chains),
195 the filter is connected only once (to avoid multiple DH links)
197 if log.isEnabledFor(logging.DEBUG):
198 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))
199 log.debug(
" --- sequences: ")
203 if len(connections) == 0:
204 log.error(
"No filter outputs are set!")
208 if len(connections) != len(self.
sequenceCA.step.sequences):
209 log.error(
"CFGroup: Found %d connections and %d MenuSequences in Step %s", len(connections), len(self.
sequenceCA.step.sequences), self.
sequenceCA.step.name)
210 raise Exception(
"[CFGroup] Connections and sequences do not match, this must be fixed!")
212 for nseq, seq
in enumerate(self.
sequenceCA.step.sequences):
213 filter_out = connections[nseq]
214 log.debug(
"CFGroup: Found input %s to sequence::%s from Filter::%s", filter_out, seq.name, self.
sequenceCA.filterNode.Alg.name)
215 seq.connectToFilter( filter_out )
217 log.debug(
"This CFGroup has no sequences: outputs are the Filter outputs, which are %d", len(self.
sequenceCA.decisions))
220 """ set and create HypoTools accumulated on the self.step from an input step configuration
225 log.debug(
"CFGroup.createHypoTools for Step %s", self.
sequenceCA.step.name)
227 for seq, onePartChainDict
in zip(self.
sequenceCA.step.sequences, sdict):
228 log.debug(
' seq: %s, onePartChainDict:', seq.name)
229 log.debug(
' %s', onePartChainDict)
230 if not isinstance(seq, EmptyMenuSequence):
231 hypoToolConf=seq.getHypoToolConf()
232 if hypoToolConf
is None:
233 log.error(
"HypoToolConf not found ", seq.name)
234 hypoToolConf.setConf( onePartChainDict )
235 hypo = HypoAlgNode(Alg = self.
sequenceCA.ca.getEventAlgo(seq.hypo.Alg.getName()))
236 hypoToolAcc = hypo.addHypoTool(flags, hypoToolConf)
237 if isinstance(hypoToolAcc, ComponentAccumulator):
241 chainDict = HLTMenuConfig.getChainDictFromChainName(chain)
242 self.
sequenceCA.step.combo.createComboHypoTools(flags, chainDict, conf)