3 from TriggerMenuMT.HLT.Config.Utility.HLTMenuConfig
import HLTMenuConfig
4 from TriggerMenuMT.HLT.Config.ControlFlow.MenuComponentsNaming
import CFNaming
5 from TriggerMenuMT.HLT.Config.ControlFlow.HLTCFTools
import (NoHypoToolCreated,
9 from AthenaCommon.CFElements
import parOR, seqAND, findAlgorithmByPredicate
10 from AthenaConfiguration.ComponentAccumulator
import ComponentAccumulator
11 from AthenaConfiguration.ComponentFactory
import CompFactory
12 from DecisionHandling.DecisionHandlingConfig
import ComboHypoCfg
14 from TrigCompositeUtils.TrigCompositeUtils
import legName
15 from TriggerJobOpts.TriggerConfigFlags
import ROBPrefetching
17 from collections.abc
import MutableSequence
22 from AthenaCommon.Logging
import logging
23 log = logging.getLogger( __name__ )
25 _ComboHypoPool = dict()
28 """base class representing one Alg + inputs + outputs, to be used to connect """
29 """stores all the inputs, even if repeated (self.inputs)"""
31 self.
name = (
"%sNode")%( Alg.getName() )
53 """Node class that represent an algorithm: sets R/W handles (as unique input/output) and properties as parameters """
54 """Automatically de-duplicates input ReadHandles upon repeated calls to addInput."""
55 def __init__(self, Alg, inputProp, outputProp):
56 Node.__init__(self, Alg)
65 cval = getattr( self.
Alg, propname)
66 if isinstance(cval, MutableSequence):
68 return setattr(self.
Alg, propname, cval)
70 return setattr(self.
Alg, propname, value)
73 cval = getattr(self.
Alg, prop)
74 if isinstance(cval, MutableSequence):
75 return setattr(self.
Alg, prop, [])
77 return setattr(self.
Alg, prop,
"")
80 return getattr(self.
Alg, prop)
91 log.debug(
"Output DH not added in %s: %s already set!", self.
Alg.
getName(), name)
96 log.debug(
"no outputProp set for output of %s", self.
Alg.
getName())
97 Node.addOutput(self, name)
101 return (cval
if isinstance(cval, MutableSequence)
else
102 ([
str(cval)]
if cval
else []))
107 log.debug(
"Input DH not added in %s: %s already set!", self.
Alg.
getName(), name)
112 log.debug(
"no InputProp set for input of %s", self.
Alg.
getName())
113 Node.addInput(self, name)
118 return (cval
if isinstance(cval, MutableSequence)
else
119 ([
str(cval)]
if cval
else []))
126 """ Class to group info on hypotools for ChainDict"""
129 self.
hasFlags =
'flags' in inspect.signature(hypoToolGen).parameters
134 if type(chainDict)
is not dict:
135 raise RuntimeError(
"Configuring hypo with %s, not good anymore, use chainDict" %
str(chainDict) )
139 """creates instance of the hypo tool"""
146 """sets the configuration and creates instance of the hypo tool"""
152 """AlgNode for HypoAlgs"""
153 initialOutput=
'StoreGateSvc+UNSPECIFIED_OUTPUT'
155 assert isHypoBase(Alg),
"Error in creating HypoAlgNode from Alg " + Alg.name
156 AlgNode.__init__(self, Alg,
'HypoInputDecisions',
'HypoOutputDecisions')
162 log.debug(
"Output DH not added in %s: %s already set!", self.
name, name)
164 AlgNode.addOutput(self, name)
166 log.error(
"Hypo %s has already %s as configured output: you may want to duplicate the Hypo!",
167 self.
name, outputs[0])
170 log.debug(
"Adding HypoTool %s for chain %s to %s", hypoToolConf.name, hypoToolConf.chainDict[
'chainName'], self.
Alg.
getName())
172 result = hypoToolConf.create(flags)
173 if isinstance(result, ComponentAccumulator):
174 tool = result.popPrivateTools()
175 assert not isinstance(tool, list),
"Can not handle list of tools"
176 self.
Alg.HypoTools.append(tool)
179 self.
Alg.HypoTools = self.
Alg.HypoTools + [result]
181 except NoHypoToolCreated
as e:
182 log.debug(
"%s returned empty tool: %s", hypoToolConf.name, e)
190 return "HypoAlg::%s [%s] -> [%s], previous = [%s], HypoTools=[%s]" % \
194 ' '.
join([t.getName()
for t
in self.
Alg.HypoTools]))
198 """AlgNode for InputMaker Algs"""
200 assert isInputMakerBase(Alg),
"Error in creating InputMakerNode from Alg " + Alg.name
201 AlgNode.__init__(self, Alg,
'InputMakerInputDecisions',
'InputMakerOutputDecisions')
204 input_maker_output = CFNaming.inputMakerOutName(self.
Alg.name)
209 """AlgNode for Combo HypoAlgs"""
212 self.
prop2 =
"LegToInputCollectionMap"
215 thealgs= self.
acc.getEventAlgos()
217 log.error(
"ComboHypoNode: Combo alg %s not found", name)
218 if len(thealgs) != 1:
219 log.error(
"ComboHypoNode: Combo alg %s len is %d",name, len(thealgs))
222 log.debug(
"ComboHypoNode init: Alg %s", name)
223 AlgNode.__init__(self, Alg,
'HypoInputDecisions',
'HypoOutputDecisions')
234 log.debug(
"ComboHypoNode.create %s",name)
238 AlgNode automatically de-duplicates input ReadHandles upon repeated calls to addInput.
239 Node instead stores all the inputs, even if repeated (self.inputs)
240 This function maps from the raw number of times that addInput was called to the de-duplicated index of the handle.
241 E.g. a step processing chains such as HLT_e5_mu6 would return [0,1]
242 E.g. a step processing chains such as HLT_e5_e6 would return [0,0]
243 E.g. a step processing chains such as HLT_e5_mu6_mu7 would return [0,1,1]
244 These data are needed to configure the step's ComboHypo
249 for rawInput
in self.
inputs:
250 mapping.append( theInputs.index(rawInput) )
255 chainName = chainDict[
'chainName']
256 chainMult = chainDict[
'chainMultiplicities']
258 if len(chainMult) != len(legsToInputCollections):
259 log.error(
"ComboHypoNode for Alg:{} with addChain for:{} Chain multiplicity:{} Per leg input collection index:{}."
260 .
format(self.
Alg.name, chainName, tuple(chainMult), tuple(legsToInputCollections)))
261 log.error(
"The size of the multiplicies vector must be the same size as the per leg input collection vector.")
262 log.error(
"The ComboHypo needs to know which input DecisionContainers contain the DecisionObjects to be used for each leg.")
263 log.error(
"Check why ComboHypoNode.addInput(...) was not called exactly once per leg.")
264 raise Exception(
"[createDataFlow] Error in ComboHypoNode.addChain. Cannot proceed.")
266 cval1 = getattr(self.
Alg, self.
prop1)
267 cval2 = getattr(self.
Alg, self.
prop2)
268 if type(cval1)
is dict
or isinstance(cval1, GaudiConfig2.semantics._DictHelper):
269 if chainName
in cval1.keys():
270 log.error(
"ERROR in configuration: ComboAlg %s has already been configured for chain %s", self.
Alg.name, chainName)
271 raise Exception(
"[createDataFlow] Error in ComboHypoNode.addChain. Cannot proceed.")
273 cval1[chainName] = chainMult
274 cval2[chainName] = legsToInputCollections
276 cval1 = {chainName : chainMult}
277 cval2 = {chainName : legsToInputCollections}
279 setattr(self.
Alg, self.
prop1, cval1)
280 setattr(self.
Alg, self.
prop2, cval2)
284 cval = getattr(self.
Alg, self.
prop1)
289 """Create the ComboHypoTools and add them to the main alg"""
290 if not len(comboToolConfs):
292 confs = [
HypoToolConf( tool )
for tool
in comboToolConfs ]
293 log.debug(
"ComboHypoNode.createComboHypoTools for chain %s, Alg %s with %d tools", chainDict[
"chainName"],self.
Alg.
getName(), len(comboToolConfs))
295 log.debug(
"ComboHypoNode.createComboHypoTools adding %s", conf)
296 tools = self.
Alg.ComboHypoTools
297 self.
Alg.ComboHypoTools = tools + [ conf.confAndCreate( flags, chainDict ) ]
305 """Class to emulate reco sequences with no Hypo"""
306 """It contains an InputMaker and and empty seqAND used for merging"""
307 """It contains empty function to follow the same MenuSequence behaviour"""
309 log.debug(
"Made EmptySequence %s", the_name)
315 makerAlg = CompFactory.InputMakerForRoI(f
"IM{the_name}",
317 RoIsLink =
'initialRoI')
323 self.
ca.addSequence(
seqAND(the_name))
324 self.
ca.addEventAlgo(makerAlg, sequenceName=the_name)
350 return self.
maker.readOutputList()
353 """Connect filter to the InputMaker"""
359 def buildDFDot(self, cfseq_algs, all_hypos, last_step_hypo_nodes, file):
360 cfseq_algs.append(self.
maker)
362 file.write(
" %s[fillcolor=%s]\n"%(self.
maker.Alg.getName(),
algColor(self.
maker.Alg)))
364 return cfseq_algs, all_hypos, last_step_hypo_nodes
367 return "MenuSequence::%s \n Hypo::%s \n Maker::%s \n Sequence::%s \n HypoTool::%s\n"\
368 %(self.
name,
"Empty", self.
maker.Alg.getName(), self.
sequence.Alg.getName(),
"None")
371 """Function to create a EmptyMenuSequence (used in the functools.partial)"""
375 return o.func.__name__ ==
"EmptyMenuSequenceCfg"
378 """Class to group reco sequences with the Hypo.
379 By construction it has one Hypo only, which gives the name to this class object"""
381 def __init__(self, flags, selectionCA, HypoToolGen, globalRecoCA=None):
382 self.
ca = selectionCA
392 assert len(inputMaker) == 1, f
"{len(inputMaker)} input makers in the ComponentAccumulator"
393 inputMaker = inputMaker[0]
394 assert inputMaker.name.startswith(
"IM"), f
"Input maker {inputMaker.name} name needs to start with 'IM'"
396 input_maker_output = self.
maker.readOutputList()[0]
400 hypoAlg = selectionCA.hypoAcc.getEventAlgos()
401 assert len(hypoAlg) == 1, f
"{len(hypoAlg)} hypo algs in the ComponentAccumulator"
403 hypoAlg.RuntimeValidation = flags.Trigger.doRuntimeNaviVal
405 self.
_name = CFNaming.menuSequenceName(hypoAlg.name)
407 self.
_hypo.addOutput( CFNaming.hypoAlgOutName(hypoAlg.name) )
408 self.
_hypo.setPreviousDecision( input_maker_output )
412 if ROBPrefetching.StepRoI
in flags.Trigger.ROBPrefetchingOptions:
413 for child
in sequence.Members:
414 if ( isinstance(child, CompFactory.ROBPrefetchingAlg)
and
415 input_maker_output
not in child.ROBPrefetchingInputDecisions ):
416 child.ROBPrefetchingInputDecisions.append(input_maker_output)
418 log.debug(
"connecting InputMaker and HypoAlg, adding: InputMaker::%s.output=%s",
419 self.
maker.Alg.name, input_maker_output)
420 log.debug(
"HypoAlg::%s.HypoInputDecisions=%s, HypoAlg::%s.HypoOutputDecisions=%s",
421 self.
hypo.Alg.name, self.
hypo.readInputList()[0],
422 self.
hypo.Alg.name, self.
hypo.readOutputList()[0])
455 return [self.
_hypo.readOutputList()[0]]
458 """Connect filter to the InputMaker"""
459 log.debug(
"connecting %s to inputs of %s", outfilter, self.
maker.Alg.name)
466 def buildDFDot(self, cfseq_algs, all_hypos, last_step_hypo_nodes, file):
467 cfseq_algs.append(self.
maker)
469 file.write(
" %s[fillcolor=%s]\n"%(self.
maker.Alg.getName(),
algColor(self.
maker.Alg)))
471 cfseq_algs.append(self.
_hypo)
473 all_hypos.append(self.
_hypo)
474 return cfseq_algs, all_hypos, last_step_hypo_nodes
477 hyponame = self.
_hypo.Alg.name
479 return "MenuSequence::%s \n Hypo::%s \n Maker::%s \n Sequence::%s \n HypoTool::%s\n"\
484 """Basic class to define the trigger menu """
485 __slots__ =
'name',
'steps',
'nSteps',
'alignmentGroups',
'L1decisions',
'topoMap'
486 def __init__(self, name, ChainSteps, L1decisions, nSteps = None, alignmentGroups = None, topoMap=None):
489 Construct the Chain from the steps
490 Out of all arguments the ChainSteps & L1Thresholds are most relevant, the chain name is used in debug messages
494 if nSteps
is None: nSteps = []
495 if alignmentGroups
is None: alignmentGroups = []
516 log.debug(
"[Chain.__init__] Made Chain %s with seeds: %s ", name, self.
L1decisions)
519 assert len(self.
nSteps) == 1,
"[Chain.append_bjet_steps] appending already-merged step lists - chain object will be broken. This should only be used to append Bjets to jets!"
524 assert len(self.
nSteps) == 1,
"[Chain.append_step_to_jet] appending already-merged step lists - chain object will be broken. This is used either for appending Beamspot algorithms to jets!"
530 if len(self.
steps)==0:
533 for stepID,step
in enumerate(self.
steps):
534 step_name = step.name
535 if re.search(
'^Step[0-9]_',step_name):
536 step_name = step_name[6:]
537 elif re.search(
'^Step[0-9]{2}_', step_name):
538 step_name = step_name[7:]
539 step.name =
'Step%d_'%(stepID+1)+step_name
547 if len(self.
steps) == 0 :
548 log.error(
"I can't insert empty steps because the chain doesn't have any steps yet!")
550 if len(self.
steps) < start_position :
551 log.error(
"I can't insert empty steps at step %d because the chain doesn't have that many steps!", start_position)
554 chain_steps_pre_split = self.
steps[:start_position]
555 chain_steps_post_split = self.
steps[start_position:]
561 if start_position == 0:
562 next_step_name = chain_steps_post_split[0].name
563 if re.search(
'^Step[0-9]_',next_step_name):
564 next_step_name = next_step_name[6:]
565 elif re.search(
'^Step[0-9]{2}_', next_step_name):
566 next_step_name = next_step_name[7:]
569 prev_chain_dict = chain_steps_post_split[0].stepDicts
571 if len(chain_steps_post_split) == 0:
572 log.error(
"Adding empty steps to the end of a chain (%s)- why would you do this?",self.
name)
574 prev_step_name = chain_steps_pre_split[-1].name
575 next_step_name = chain_steps_post_split[0].name
576 prev_chain_dict = chain_steps_pre_split[-1].stepDicts
580 for stepID
in range(1,n_new_steps+1):
581 new_step_name = prev_step_name+
'_'+empty_step_name+
'%d_'%stepID+next_step_name
583 log.debug(
"Configuring empty step %s", new_step_name)
584 steps_to_add += [
ChainStep(new_step_name, chainDicts=prev_chain_dict, comboHypoCfg=ComboHypoCfg, isEmpty=
True)]
586 self.
steps = chain_steps_pre_split + steps_to_add + chain_steps_post_split
592 if len(self.
steps) == 0:
594 mult=[
sum(step.multiplicity)
for step
in self.
steps]
595 not_empty_mult = [m
for m
in mult
if m!=0]
596 if len(not_empty_mult) == 0:
597 log.error(
"checkMultiplicity: Chain %s has all steps with multiplicity =0: what to do?", self.
name)
599 if not_empty_mult.count(not_empty_mult[0]) != len(not_empty_mult):
600 log.error(
"checkMultiplicity: Chain %s has steps with differnt multiplicities: %s", self.
name,
' '.
join(mult))
604 log.error(
"checkMultiplicity: Chain %s has %d multiplicity per step, and %d L1Decisions", self.
name, mult, len(self.
L1decisions))
606 return not_empty_mult[0]
613 stepname =
"last step" if step==
"last" else step.name
614 log.debug(
"Adding topo configurator %s for %s to %s", topoPair[0].__qualname__, topoPair[1],
"step " + stepname)
618 return "\n-*- Chain %s -*- \n + Seeds: %s, Steps: %s, AlignmentGroups: %s \n + Steps: \n %s \n"%(\
625 """Class to describe one step of a chain; if multiplicity is greater than 1, the step is combo/combined. Set one multiplicity value per sequence"""
627 def __init__(self, name, SequenceGens = None, chainDicts = None, comboHypoCfg = ComboHypoCfg , comboToolConfs = None, isEmpty = False, createsGhostLegs = False):
630 if SequenceGens
is None: SequenceGens = []
631 if comboToolConfs
is None: comboToolConfs = []
633 assert chainDicts
is not None,
"Error building a ChainStep without a chainDicts"
647 log.debug(
"Building step %s for chain %s: len=%d multiplicty=%s", name, chainDicts[0][
'chainName'], len(chainDicts),
' '.
join(map(str,[mult
for mult
in self.
multiplicity])))
649 if len(chainDicts) != len(self.
multiplicity)
and 'Jet' not in chainDicts[0][
'signatures']:
650 log.error(
"[ChainStep] SequenceGens: %s",self.
sequenceGens)
651 log.error(
"[ChainStep] chainDicts: %s",chainDicts)
652 log.error(
"[ChainStep] multiplicity: %s",self.
multiplicity)
653 raise RuntimeError(
"[ChainStep] Tried to configure a ChainStep %s with %i multiplicity and %i dictionaries. These lists must have the same size" % (name, len(self.
multiplicity), len(chainDicts)) )
657 if not isinstance(seq, functools.partial):
658 log.error(
"[ChainStep] %s SequenceGens verification failed, sequence %d is not partial function, likely ChainBase.getStep function was not used", self.
name, iseq)
659 log.error(
"[ChainStep] It rather seems to be of type %s trying to print it",
type(seq))
660 raise RuntimeError(
"Sequence is not packaged in a tuple, see error message above" )
664 if len(chainDicts) > 0
and 'signature' in chainDicts[0]:
665 leg_signatures = [step[
'signature']
for step
in chainDicts
if step[
'signature'] !=
'Bjet']
666 if (len(self.
multiplicity) > 0
and leg_signatures.count(
'Jet') == 1)
and (len(
set(leg_signatures)) > 1
and chainDicts[0][
'signatures'].
count(
'Jet') > 1)
and (len(leg_signatures) != 2
or leg_signatures.count(
'MET') == 0):
667 index_jetLeg = leg_signatures.index(
'Jet')
668 self.
multiplicity[index_jetLeg:index_jetLeg] = [1] * (len(chainDicts[0][
'chainMultiplicities']) - len(self.
multiplicity))
669 sig_set =
set([step[
'signature']
for step
in chainDicts])
670 if len(sig_set) == 1
and (
'Jet' in sig_set
or 'Bjet' in sig_set):
672 if len(sig_set) == 2
and (
'Jet' in sig_set
and 'Bjet' in sig_set):
684 """ creation of this step sequences with instantiation of the CAs"""
685 log.debug(
"creating sequences for step %s", self.
name)
694 if 'Jet' in step_dict[
'signatures']
or 'Bjet' in step_dict[
'signatures']:
696 leg_counter += [len(step_dict[
'chainParts'])]
697 elif len(step_dict[
'chainParts']) > 1:
698 log.error(
"[relabelLegIdsForJets] this should only happen for jet chains, but the signatures are %s",step_dict[
'signatures'])
699 raise Exception(
"[relabelLegIdsForJets] leg labelling is probably wrong...")
707 log.debug(
"[relabelLegIdsForJets] leg_counter: %s , onlyjets: %s, multiplicity: %s...",leg_counter, self.
onlyJets, self.
multiplicity)
709 if not has_jets
or len(leg_counter) == len(self.
multiplicity):
712 if len(leg_counter) == 1
or (len(
set(leg_counter)) == 1
and leg_counter[0] == 1):
715 elif len(
set(leg_counter[:-1])) == 1
and leg_counter[0] == 1:
720 for i,nLegParts
in enumerate(leg_counter):
721 oldLegName = self.
stepDicts[i][
'chainName']
722 if re.search(
'^leg[0-9]{3}_',oldLegName):
723 oldLegName = oldLegName[7:]
725 log.error(
"[relabelLegIdsForJets] you told me to relabel the legs for %s",self.
stepDicts)
726 raise Exception(
"[relabelLegIdsForJets] you told me to relabel the legs but this leg doesn't have a legXXX_ name!")
734 lists_of_chainPartNames = []
736 if len(lists_of_chainPartNames) == 0:
737 lists_of_chainPartNames += [[cp[
'chainPartName']
for cp
in step_dict[
'chainParts']]]
739 new_list_of_chainPartNames = [cp[
'chainPartName']
for cp
in step_dict[
'chainParts']]
740 if new_list_of_chainPartNames == lists_of_chainPartNames[-1]:
741 leg_counter -= len(new_list_of_chainPartNames)
742 for chainPart
in step_dict[
'chainParts']:
743 chainPart[
'chainPartIndex'] = leg_counter
748 """ get the gelId from the step dictionary for multi-leg chains"""
752 for istep,step_dict
in enumerate(self.
stepDicts):
753 if step_dict[
'chainName'][0:3] !=
'leg':
757 log.error(
"[getLegIds] chain %s has multiplicities %s but no legs? ",step_dict[
'chainName'], self.
multiplicity)
758 raise Exception(
"[getLegIds] cannot extract leg IDs, exiting.")
760 leg_ids += [
int(step_dict[
'chainName'][3:6])]
771 """ Configure the Combo Hypo Alg and generate the corresponding function, without instantiation which is done in createSequences() """
775 comboNameFromStep = CFNaming.comboHypoName(self.
name)
777 key =
hash((comboNameFromStep, funcName))
778 if key
not in _ComboHypoPool:
782 if comboNameFromStep+
"Node" != tmpCombo.name:
783 log.info(
"WARNING Created ComboHypo with name %s, expected from the step is instead %s. This is accepted only for allowed custom ComboHypos", tmpCombo.name, comboNameFromStep)
784 key =
hash((tmpCombo.name, funcName))
785 _ComboHypoPool[key] = tmpCombo
786 self.
combo = _ComboHypoPool[key]
787 log.debug(
"Created combo %s with name %s, step comboName %s, key %s", funcName, self.
combo.name, comboNameFromStep,key)
795 chainDict = HLTMenuConfig.getChainDictFromChainName(chainName)
799 """ This is extrapolating the chain legs from the step dictionaries"""
800 legs = [part[
'chainName']
for part
in self.
stepDicts]
804 if self.
combo is not None:
810 return "\n--- ChainStep %s ---\n is Empty, ChainDict = %s "%(self.
name,
' '.
join(map(str, [dic[
'chainName']
for dic
in self.
stepDicts])) )
812 repr_string=
"\n--- ChainStep %s ---\n , multiplicity = %s ChainDict = %s \n + MenuSequenceGens = %s "%\
814 ' '.
join(map(str, [dic[
'chainName']
for dic
in self.
stepDicts])),
817 if self.
combo is not None:
818 repr_string +=
"\n + ComboHypo = %s" % self.
combo.Alg.name
820 repr_string +=
", ComboHypoTools = %s" %(
' '.
join(map(str, [tool.__name__
for tool
in self.
comboToolConfs])))
826 """ Class to handle in-event reco """
827 def __init__(self, name, inputMaker=None, **inputMakerArgs):
828 super( InEventRecoCA, self ).
__init__()
833 assert len(inputMakerArgs) == 0,
"No support for explicitly passed input maker and and input maker arguments at the same time"
836 assert 'name' not in inputMakerArgs,
"The name of input maker is predefined by the name of sequence"
837 args = {
'name':
"IM"+name,
838 'RoIsLink' :
'initialRoI',
839 'RoIs' : f
'{name}RoIs',
840 'RoITool': CompFactory.ViewCreatorInitialROITool(),
841 'mergeUsingFeature':
False}
842 args.update(**inputMakerArgs)
848 self.addSequence( self.
recoSeq )
851 """ Merged CA moving reconstruction algorithms into the right sequence """
853 return self.merge( ca, sequenceName=self.
recoSeq.name )
856 """ Place algorithm in the correct reconstruction sequence """
858 return self.addEventAlgo( algo, sequenceName=self.
recoSeq.name )
866 """ Class to handle in-view reco, sets up the View maker if not provided and exposes InputMaker so that more inputs to it can be added in the process of assembling the menu """
867 def __init__(self, name, viewMaker=None, isProbe=False, **viewMakerArgs):
868 super( InViewRecoCA, self ).
__init__()
869 self.
name = name +
"_probe" if isProbe
else name
870 def updateHandle(baseTool, probeTool, handleName):
871 if hasattr(baseTool, handleName)
and getattr(baseTool, handleName).Path!=
"StoreGateSvc+":
872 setattr(probeTool, handleName, getattr(probeTool, handleName).Path +
"_probe")
874 if len(viewMakerArgs) != 0:
875 assert viewMaker
is None,
"No support for explicitly passed view maker and args for EventViewCreatorAlgorithm"
878 assert len(viewMakerArgs) == 0,
"No support for explicitly passed view maker and args for EventViewCreatorAlgorithm"
880 self.
viewMakerAlg = viewMaker.__class__(viewMaker.getName()+
'_probe', **viewMaker._properties)
883 log.debug(f
"InViewRecoCA: Setting InputCachedViews on {self.viewMaker.getName()} to read decisions from tag leg {viewMaker.getName()}: {viewMaker.InputMakerOutputDecisions}")
884 self.
viewMakerAlg.InputCachedViews = viewMaker.InputMakerOutputDecisions
885 updateHandle(viewMakerArgs[
'RoITool'], roiTool,
"RoisWriteHandleKey")
886 if hasattr(viewMakerArgs[
'RoITool'],
"RoiCreator"):
887 updateHandle(viewMakerArgs[
'RoITool'], roiTool,
"ExtraPrefetchRoIsKey")
888 updateHandle(viewMakerArgs[
'RoITool'].RoiCreator, roiTool.RoiCreator,
"RoisWriteHandleKey")
894 assert 'name' not in viewMakerArgs,
"The name of view maker is predefined by the name of sequence"
895 assert 'Views' not in viewMakerArgs,
"The Views is predefined by the name of sequence"
896 assert 'ViewsNodeName' not in viewMakerArgs,
"The ViewsNodeName is predefined by the name of sequence"
897 if 'RoITool' in viewMakerArgs:
898 roiTool = viewMakerArgs[
'RoITool']
900 roiTool = CompFactory.ViewCreatorInitialROITool()
903 args = {
'name': f
'IM_{self.name}',
904 'ViewFallThrough' :
True,
905 'RoIsLink' :
'initialRoI',
907 'InViewRoIs' : f
'{name}RoIs',
908 'Views' : f
'{name}Views'+
'_probe' if isProbe
else f
'{name}Views',
909 'ViewNodeName' : f
'{name}InViews'+
'_probe' if isProbe
else f
'{name}InViews',
910 'RequireParentView' :
False,
911 'mergeUsingFeature' :
False }
912 args.update(**viewMakerArgs)
913 self.
viewMakerAlg = CompFactory.EventViewCreatorAlgorithm(**args)
915 updateHandle(args[
'RoITool'], roiTool,
"RoisWriteHandleKey")
916 if hasattr(args[
'RoITool'],
"RoiCreator"):
917 updateHandle(args[
'RoITool'], roiTool,
"ExtraPrefetchRoIsKey")
918 updateHandle(args[
'RoITool'].RoiCreator, roiTool.RoiCreator,
"RoisWriteHandleKey")
923 """ Merge CA moving reconstruction algorithms into the right sequence """
924 return self.merge( ca, sequenceName=self.
viewsSeq.name )
928 """ Place algorithm in the correct reconstruction sequence """
929 return self.addEventAlgo( algo, sequenceName=self.
viewsSeq.name )
937 """ CA component for MenuSequence sequence """
939 self.
name = name+
"_probe" if isProbe
else name
941 super( SelectionCA, self ).
__init__()
950 def mergeReco(self, recoCA, robPrefetchCA=None, upSequenceCA=None):
951 ''' upSequenceCA is the user CA to run before the recoCA'''
956 ca.addEventAlgo(recoCA.inputMaker(), sequenceName=self.
stepViewSequence.name)
963 """To be used when the hypo alg configuration comes with auxiliary tools/services"""
967 """To be used when the hypo alg configuration does not require auxiliary tools/services"""
969 newname = algo.getName()+
'_probe'
971 self.
hypoAcc.addEventAlgo(algo)
974 """Access hypo algo (or throws)"""
976 assert h
is not None,
"No hypo in SeelectionCA {}".
format(self.
name)
980 """Access Input Maker (or throws)"""
982 assert im
is not None,
"No input maker in SeelectionCA {}".
format(self.
name)