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()}')
159 if menuseq.globalRecoCA:
160 self.
ca.
merge(menuseq.globalRecoCA)
167 return "--- CFSequence ---\n + Filter: %s \n + decisions: %s\n + %s \n"%(\
174 """Class to store the Step + its Filter (CFSequence) plus the chains and dictionaries of the legs using that step """
180 log.debug(
"CFGroup.__init: created for %s ",ChainStep.name)
183 '''This creates the CAs for the menu sequences, if fastMenu style, and the CFSequence'''
184 log.debug(
"CFGroup.creating CFSEquence")
195 """Connect filter to ChainStep (and all its sequences) through these connections (which are sets of filter outputs)
196 if a ChainStep contains the same sequence multiple times (for multi-leg chains),
197 the filter is connected only once (to avoid multiple DH links)
199 if log.isEnabledFor(logging.DEBUG):
200 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))
201 log.debug(
" --- sequences: ")
205 if len(connections) == 0:
206 log.error(
"No filter outputs are set!")
210 if len(connections) != len(self.
sequenceCA.step.sequences):
211 log.error(
"CFGroup: Found %d connections and %d MenuSequences in Step %s", len(connections), len(self.
sequenceCA.step.sequences), self.
sequenceCA.step.name)
212 raise Exception(
"[CFGroup] Connections and sequences do not match, this must be fixed!")
214 for nseq, seq
in enumerate(self.
sequenceCA.step.sequences):
215 filter_out = connections[nseq]
216 log.debug(
"CFGroup: Found input %s to sequence::%s from Filter::%s", filter_out, seq.name, self.
sequenceCA.filterNode.Alg.name)
217 seq.connectToFilter( filter_out )
219 log.debug(
"This CFGroup has no sequences: outputs are the Filter outputs, which are %d", len(self.
sequenceCA.decisions))
222 """ set and create HypoTools accumulated on the self.step from an input step configuration
227 log.debug(
"CFGroup.createHypoTools for Step %s", self.
sequenceCA.step.name)
229 for seq, onePartChainDict
in zip(self.
sequenceCA.step.sequences, sdict):
230 log.debug(
' seq: %s, onePartChainDict:', seq.name)
231 log.debug(
' %s', onePartChainDict)
232 if not isinstance(seq, EmptyMenuSequence):
233 hypoToolConf=seq.getHypoToolConf()
234 if hypoToolConf
is None:
235 log.error(
"HypoToolConf not found ", seq.name)
236 hypoToolConf.setConf( onePartChainDict )
237 hypo = HypoAlgNode(Alg = self.
sequenceCA.ca.getEventAlgo(seq.hypo.Alg.getName()))
238 hypoToolAcc = hypo.addHypoTool(flags, hypoToolConf)
239 if isinstance(hypoToolAcc, ComponentAccumulator):
243 chainDict = HLTMenuConfig.getChainDictFromChainName(chain)
244 self.
sequenceCA.step.combo.createComboHypoTools(flags, chainDict, conf)