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()
29 """base class representing one Alg + inputs + outputs, to be used to Draw dot diagrams and connect objects"""
31 self.
name = (
"%sNode")%( Alg.getName() )
53 """Node class that connects inputs and outputs to basic alg. properties """
54 def __init__(self, Alg, inputProp, outputProp):
55 Node.__init__(self, Alg)
64 cval = getattr( self.
Alg, propname)
65 if isinstance(cval, MutableSequence):
67 return setattr(self.
Alg, propname, cval)
69 return setattr(self.
Alg, propname, value)
72 cval = getattr(self.
Alg, prop)
73 if isinstance(cval, MutableSequence):
74 return setattr(self.
Alg, prop, [])
76 return setattr(self.
Alg, prop,
"")
79 return getattr(self.
Alg, prop)
90 log.debug(
"Output DH not added in %s: %s already set!", self.
Alg.getName(), name)
95 log.debug(
"no outputProp set for output of %s", self.
Alg.getName())
96 Node.addOutput(self, name)
100 return (cval
if isinstance(cval, MutableSequence)
else
101 ([
str(cval)]
if cval
else []))
106 log.debug(
"Input DH not added in %s: %s already set!", self.
Alg.getName(), name)
111 log.debug(
"no InputProp set for input of %s", self.
Alg.getName())
112 Node.addInput(self, name)
117 return (cval
if isinstance(cval, MutableSequence)
else
118 ([
str(cval)]
if cval
else []))
125 """ Class to group info on hypotools for ChainDict"""
128 self.
hasFlags =
'flags' in inspect.signature(hypoToolGen).parameters
133 if type(chainDict)
is not dict:
134 raise RuntimeError(
"Configuring hypo with %s, not good anymore, use chainDict" %
str(chainDict) )
138 """creates instance of the hypo tool"""
145 """sets the configuration and creates instance of the hypo tool"""
151 """Node for HypoAlgs"""
152 initialOutput=
'StoreGateSvc+UNSPECIFIED_OUTPUT'
154 assert isHypoBase(Alg),
"Error in creating HypoAlgNode from Alg " + Alg.name
155 AlgNode.__init__(self, Alg,
'HypoInputDecisions',
'HypoOutputDecisions')
161 log.debug(
"Output DH not added in %s: %s already set!", self.
name, name)
163 AlgNode.addOutput(self, name)
165 log.error(
"Hypo %s has already %s as configured output: you may want to duplicate the Hypo!",
166 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)
195 return "HypoAlg::%s [%s] -> [%s], previous = [%s], HypoTools=[%s]" % \
199 ' '.
join([t.getName()
for t
in self.
Alg.HypoTools]))
204 assert isInputMakerBase(Alg),
"Error in creating InputMakerNode from Alg " + Alg.name
205 AlgNode.__init__(self, Alg,
'InputMakerInputDecisions',
'InputMakerOutputDecisions')
208 input_maker_output = CFNaming.inputMakerOutName(self.
Alg.name)
215 self.
prop2 =
"LegToInputCollectionMap"
218 thealgs= self.
acc.getEventAlgos()
220 log.error(
"ComboMaker: Combo alg %s not found", name)
221 if len(thealgs) != 1:
222 log.error(
"ComboMaker: Combo alg %s len is %d",name, len(thealgs))
225 log.debug(
"ComboMaker init: Alg %s", name)
226 AlgNode.__init__(self, Alg,
'HypoInputDecisions',
'HypoOutputDecisions')
237 log.debug(
"ComboMaker.create %s",name)
241 AlgNode automatically de-duplicates input ReadHandles upon repeated calls to addInput.
242 Node instead stores all the inputs, even if repeated (self.inputs)
243 This function maps from the raw number of times that addInput was called to the de-duplicated index of the handle.
244 E.g. a step processing chains such as HLT_e5_mu6 would return [0,1]
245 E.g. a step processing chains such as HLT_e5_e6 would return [0,0]
246 E.g. a step processing chains such as HLT_e5_mu6_mu7 would return [0,1,1]
247 These data are needed to configure the step's ComboHypo
252 for rawInput
in self.
inputs:
253 mapping.append( theInputs.index(rawInput) )
256 """ overwrite AlgNode::addInput with Node::addInput"""
258 return AlgNode.addInput(self, name)
261 chainName = chainDict[
'chainName']
262 chainMult = chainDict[
'chainMultiplicities']
264 if len(chainMult) != len(legsToInputCollections):
265 log.error(
"ComboMaker for Alg:{} with addChain for:{} Chain multiplicity:{} Per leg input collection index:{}."
266 .
format(self.
Alg.name, chainName, tuple(chainMult), tuple(legsToInputCollections)))
267 log.error(
"The size of the multiplicies vector must be the same size as the per leg input collection vector.")
268 log.error(
"The ComboHypo needs to know which input DecisionContainers contain the DecisionObjects to be used for each leg.")
269 log.error(
"Check why ComboMaker.addInput(...) was not called exactly once per leg.")
270 raise Exception(
"[createDataFlow] Error in ComboMaker.addChain. Cannot proceed.")
272 cval1 = getattr(self.
Alg, self.
prop1)
273 cval2 = getattr(self.
Alg, self.
prop2)
274 if type(cval1)
is dict
or isinstance(cval1, GaudiConfig2.semantics._DictHelper):
275 if chainName
in cval1.keys():
276 log.error(
"ERROR in configuration: ComboAlg %s has already been configured for chain %s", self.
Alg.name, chainName)
277 raise Exception(
"[createDataFlow] Error in ComboMaker.addChain. Cannot proceed.")
279 cval1[chainName] = chainMult
280 cval2[chainName] = legsToInputCollections
282 cval1 = {chainName : chainMult}
283 cval2 = {chainName : legsToInputCollections}
285 setattr(self.
Alg, self.
prop1, cval1)
286 setattr(self.
Alg, self.
prop2, cval2)
290 cval = getattr(self.
Alg, self.
prop1)
295 """Created the ComboHypoTools"""
296 if not len(comboToolConfs):
298 confs = [
HypoToolConf( tool )
for tool
in comboToolConfs ]
299 log.debug(
"ComboMaker.createComboHypoTools for chain %s, Alg %s with %d tools", chainDict[
"chainName"],self.
Alg.getName(), len(comboToolConfs))
301 log.debug(
"ComboMaker.createComboHypoTools adding %s", conf)
302 tools = self.
Alg.ComboHypoTools
303 self.
Alg.ComboHypoTools = tools + [ conf.confAndCreate( flags, chainDict ) ]
311 """Class to emulate reco sequences with no Hypo"""
314 log.debug(
"Made EmptySequence %s", the_name)
320 makerAlg = CompFactory.InputMakerForRoI(f
"IM{the_name}",
322 RoIsLink =
'initialRoI')
328 self.
ca.addSequence(
seqAND(the_name))
329 self.
ca.addEventAlgo(makerAlg, sequenceName=the_name)
355 return self.
maker.readOutputList()
358 """Connect filter to the InputMaker"""
359 self.
maker.addInput(outfilter)
367 def buildDFDot(self, cfseq_algs, all_hypos, last_step_hypo_nodes, file):
368 cfseq_algs.append(self.
maker)
370 file.write(
" %s[fillcolor=%s]\n"%(self.
maker.Alg.getName(),
algColor(self.
maker.Alg)))
372 return cfseq_algs, all_hypos, last_step_hypo_nodes
375 return "MenuSequence::%s \n Hypo::%s \n Maker::%s \n Sequence::%s \n HypoTool::%s\n"\
376 %(self.
name,
"Empty", self.
maker.Alg.getName(), self.
sequence.Alg.getName(),
"None")
382 return o == EmptyMenuSequenceCfg
385 """Class to group reco sequences with the Hypo.
386 By construction it has one Hypo only; behaviour changed to support muFastOvlpRmSequence(),
387 which has two, but this will change."""
389 def __init__(self, flags, selectionCA, HypoToolGen, isProbe=None, globalRecoCA=None):
392 self.
ca = selectionCA
402 assert len(inputMaker) == 1, f
"{len(inputMaker)} input makers in the ComponentAccumulator"
403 inputMaker = inputMaker[0]
405 input_maker_output = self.
maker.readOutputList()[0]
406 assert inputMaker.name.startswith(
"IM"), f
"Input maker {inputMaker.name} name needs to start with 'IM'"
409 hypoAlg = selectionCA.hypoAcc.getEventAlgos()
410 assert len(hypoAlg) == 1, f
"{len(hypoAlg)} hypo algs in the ComponentAccumulator"
412 hypoAlg.RuntimeValidation = flags.Trigger.doRuntimeNaviVal
414 self.
_name = CFNaming.menuSequenceName(hypoAlg.name)
416 self.
_hypo.addOutput( CFNaming.hypoAlgOutName(hypoAlg.name) )
417 self.
_hypo.setPreviousDecision( input_maker_output )
421 if ROBPrefetching.StepRoI
in flags.Trigger.ROBPrefetchingOptions:
422 for child
in sequence.Members:
423 if ( isinstance(child, CompFactory.ROBPrefetchingAlg)
and
424 input_maker_output
not in child.ROBPrefetchingInputDecisions ):
425 child.ROBPrefetchingInputDecisions.append(input_maker_output)
427 log.debug(
"connecting InputMaker and HypoAlg, adding: InputMaker::%s.output=%s",
428 self.
maker.Alg.name, input_maker_output)
429 log.debug(
"HypoAlg::%s.HypoInputDecisions=%s, HypoAlg::%s.HypoOutputDecisions=%s",
430 self.
hypo.Alg.name, self.
hypo.readInputList()[0],
431 self.
hypo.Alg.name, self.
hypo.readOutputList()[0])
464 return [self.
_hypo.readOutputList()[0]]
467 """Connect filter to the InputMaker"""
468 log.debug(
"connecting %s to inputs of %s", outfilter, self.
maker.Alg.name)
469 self.
maker.addInput(outfilter)
476 hypo_list.add(self.
_hypo.Alg)
478 def buildDFDot(self, cfseq_algs, all_hypos, last_step_hypo_nodes, file):
479 cfseq_algs.append(self.
maker)
481 file.write(
" %s[fillcolor=%s]\n"%(self.
maker.Alg.getName(),
algColor(self.
maker.Alg)))
483 cfseq_algs.append(self.
_hypo)
485 all_hypos.append(self.
_hypo)
486 return cfseq_algs, all_hypos, last_step_hypo_nodes
489 hyponame = self.
_hypo.Alg.name
491 return "MenuSequence::%s \n Hypo::%s \n Maker::%s \n Sequence::%s \n HypoTool::%s\n"\
496 """Basic class to define the trigger menu """
497 __slots__ =
'name',
'steps',
'nSteps',
'alignmentGroups',
'L1decisions',
'topoMap'
498 def __init__(self, name, ChainSteps, L1decisions, nSteps = [], alignmentGroups = [], topoMap=None):
501 Construct the Chain from the steps
502 Out of all arguments the ChainSteps & L1Thresholds are most relevant, the chain name is used in debug messages
522 log.debug(
"[Chain.__init__] Made Chain %s with seeds: %s ", name, self.
L1decisions)
525 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!"
530 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!"
536 if len(self.
steps)==0:
539 for stepID,step
in enumerate(self.
steps):
540 step_name = step.name
541 if re.search(
'^Step[0-9]_',step_name):
542 step_name = step_name[6:]
543 elif re.search(
'^Step[0-9]{2}_', step_name):
544 step_name = step_name[7:]
545 step.name =
'Step%d_'%(stepID+1)+step_name
553 if len(self.
steps) == 0 :
554 log.error(
"I can't insert empty steps because the chain doesn't have any steps yet!")
556 if len(self.
steps) < start_position :
557 log.error(
"I can't insert empty steps at step %d because the chain doesn't have that many steps!", start_position)
560 chain_steps_pre_split = self.
steps[:start_position]
561 chain_steps_post_split = self.
steps[start_position:]
567 if start_position == 0:
568 next_step_name = chain_steps_post_split[0].name
569 if re.search(
'^Step[0-9]_',next_step_name):
570 next_step_name = next_step_name[6:]
571 elif re.search(
'^Step[0-9]{2}_', next_step_name):
572 next_step_name = next_step_name[7:]
575 prev_chain_dict = chain_steps_post_split[0].stepDicts
577 if len(chain_steps_post_split) == 0:
578 log.error(
"Adding empty steps to the end of a chain (%s)- why would you do this?",self.
name)
580 prev_step_name = chain_steps_pre_split[-1].name
581 next_step_name = chain_steps_post_split[0].name
582 prev_chain_dict = chain_steps_pre_split[-1].stepDicts
586 for stepID
in range(1,n_new_steps+1):
587 new_step_name = prev_step_name+
'_'+empty_step_name+
'%d_'%stepID+next_step_name
589 log.debug(
"Configuring empty step %s", new_step_name)
590 steps_to_add += [
ChainStep(new_step_name, [], [], chainDicts=prev_chain_dict, comboHypoCfg=ComboHypoCfg)]
592 self.
steps = chain_steps_pre_split + steps_to_add + chain_steps_post_split
597 if len(self.
steps) == 0:
599 mult=[
sum(step.multiplicity)
for step
in self.
steps]
600 not_empty_mult = [m
for m
in mult
if m!=0]
601 if len(not_empty_mult) == 0:
602 log.error(
"checkMultiplicity: Chain %s has all steps with multiplicity =0: what to do?", self.
name)
604 if not_empty_mult.count(not_empty_mult[0]) != len(not_empty_mult):
605 log.error(
"checkMultiplicity: Chain %s has steps with differnt multiplicities: %s", self.
name,
' '.
join(mult))
609 log.error(
"checkMultiplicity: Chain %s has %d multiplicity per step, and %d L1Decisions", self.
name, mult, len(self.
L1decisions))
611 return not_empty_mult[0]
618 stepname =
"last step" if step==
"last" else step.name
619 log.debug(
"Adding topo configurator %s for %s to %s", topoPair[0].__qualname__, topoPair[1],
"step " + stepname)
623 return "-*- Chain %s -*- \n + Seeds: %s, Steps: %s, AlignmentGroups: %s \n + Steps: \n %s \n"%(\
629 """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"""
630 def __init__(self, name, Sequences = [], multiplicity = [1], chainDicts = [], comboHypoCfg = ComboHypoCfg, comboToolConfs = [], isEmpty = False, createsGhostLegs = False):
633 if sum(multiplicity) == 0:
636 log.debug(
"chain %s, step %s: len=%d multiplicty=%d", chainDicts[0][
'chainName'], name, len(chainDicts), len(multiplicity))
638 if len(chainDicts) != len(multiplicity):
639 log.error(
"[ChainStep] Sequences: %s",Sequences)
640 log.error(
"[ChainStep] chainDicts: %s",chainDicts)
641 log.error(
"[ChainStep] multiplicity: %s",multiplicity)
642 raise RuntimeError(
"[ChainStep] Tried to configure a ChainStep %s with %i multiplicity and %i dictionaries. These lists must have the same size" % (name, len(multiplicity), len(chainDicts)) )
644 if len(Sequences) != len(multiplicity)
and 'Jet' not in chainDicts[0][
'signatures']:
645 log.error(
"[ChainStep] Sequences: %s",Sequences)
646 log.error(
"[ChainStep] multiplicities: %s",multiplicity)
647 raise RuntimeError(
"Tried to configure a ChainStep %s with %i Sequences and %i multiplicities. These lists must have the same size" % (name, len(Sequences), len(multiplicity)) )
653 if not isinstance(seq, functools.partial):
654 log.error(
"[ChainStep] %s Sequences verification failed, sequence %d is not partial function, likely ChainBase.getStep function was not used", self.
name, iseq)
655 log.error(
"[ChainStep] It rather seems to be of type %s trying to print it",
type(seq))
656 raise RuntimeError(
"Sequence is not packaged in a tuple, see error message above" )
660 if len(chainDicts) > 0
and 'signature' in chainDicts[0]:
661 leg_signatures = [step[
'signature']
for step
in chainDicts
if step[
'signature'] !=
'Bjet']
662 if (len(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):
663 index_jetLeg = leg_signatures.index(
'Jet')
664 multiplicity[index_jetLeg:index_jetLeg] = [1] * (len(chainDicts[0][
'chainMultiplicities']) - len(multiplicity))
665 sig_set =
set([step[
'signature']
for step
in chainDicts])
666 if len(sig_set) == 1
and (
'Jet' in sig_set
or 'Bjet' in sig_set):
668 if len(sig_set) == 2
and (
'Jet' in sig_set
and 'Bjet' in sig_set):
683 """ creation of this step sequences with instantiation of the CAs"""
684 log.debug(
"creating sequences for step %s", self.
name)
693 if 'Jet' in step_dict[
'signatures']
or 'Bjet' in step_dict[
'signatures']:
695 leg_counter += [len(step_dict[
'chainParts'])]
696 elif len(step_dict[
'chainParts']) > 1:
697 log.error(
"[relabelLegIdsForJets] this should only happen for jet chains, but the signatures are %s",step_dict[
'signatures'])
698 raise Exception(
"[relabelLegIdsForJets] leg labelling is probably wrong...")
706 log.debug(
"[relabelLegIdsForJets] leg_counter: %s , onlyjets: %s, multiplicity: %s...",leg_counter, self.
onlyJets, self.
multiplicity)
708 if not has_jets
or len(leg_counter) == len(self.
multiplicity):
711 if len(leg_counter) == 1
or (len(
set(leg_counter)) == 1
and leg_counter[0] == 1):
714 elif len(
set(leg_counter[:-1])) == 1
and leg_counter[0] == 1:
719 for i,nLegParts
in enumerate(leg_counter):
720 oldLegName = self.
stepDicts[i][
'chainName']
721 if re.search(
'^leg[0-9]{3}_',oldLegName):
722 oldLegName = oldLegName[7:]
724 log.error(
"[relabelLegIdsForJets] you told me to relabel the legs for %s",self.
stepDicts)
725 raise Exception(
"[relabelLegIdsForJets] you told me to relabel the legs but this leg doesn't have a legXXX_ name!")
733 lists_of_chainPartNames = []
735 if len(lists_of_chainPartNames) == 0:
736 lists_of_chainPartNames += [[cp[
'chainPartName']
for cp
in step_dict[
'chainParts']]]
738 new_list_of_chainPartNames = [cp[
'chainPartName']
for cp
in step_dict[
'chainParts']]
739 if new_list_of_chainPartNames == lists_of_chainPartNames[-1]:
740 leg_counter -= len(new_list_of_chainPartNames)
741 for chainPart
in step_dict[
'chainParts']:
742 chainPart[
'chainPartIndex'] = leg_counter
748 for istep,step_dict
in enumerate(self.
stepDicts):
749 if step_dict[
'chainName'][0:3] !=
'leg':
753 log.error(
"[getLegIds] chain %s has multiplicities %s but no legs? ",step_dict[
'chainName'], self.
multiplicity)
754 raise Exception(
"[getLegIds] cannot extract leg IDs, exiting.")
756 leg_ids += [
int(step_dict[
'chainName'][3:6])]
767 comboName = CFNaming.comboHypoName(self.
name)
769 if key
not in _ComboHypoPool:
771 self.
combo = _ComboHypoPool[key]
775 chainDict = HLTMenuConfig.getChainDictFromChainName(chainName)
779 """ This is extrapolating the chain legs from the step dictionaries"""
780 legs = [part[
'chainName']
for part
in self.
stepDicts]
784 if self.
combo is not None:
790 return "--- ChainStep %s ---\n is Empty, ChainDict = %s "%(self.
name,
' '.
join(map(str, [dic[
'chainName']
for dic
in self.
stepDicts])) )
792 repr_string=
"--- ChainStep %s ---\n , multiplicity = %s ChainDict = %s \n + MenuSequences = %s "%\
794 ' '.
join(map(str, [dic[
'chainName']
for dic
in self.
stepDicts])),
797 if self.
combo is not None:
798 repr_string +=
"\n + ComboHypo = %s" % self.
combo.Alg.name
800 repr_string +=
", ComboHypoTools = %s" %(
' '.
join(map(str, [tool.__name__
for tool
in self.
comboToolConfs])))
806 """ Class to handle in-event reco """
807 def __init__(self, name, inputMaker=None, **inputMakerArgs):
808 super( InEventRecoCA, self ).
__init__()
813 assert len(inputMakerArgs) == 0,
"No support for explicitly passed input maker and and input maker arguments at the same time"
816 assert 'name' not in inputMakerArgs,
"The name of input maker is predefined by the name of sequence"
817 args = {
'name':
"IM"+name,
818 'RoIsLink' :
'initialRoI',
819 'RoIs' : f
'{name}RoIs',
820 'RoITool': CompFactory.ViewCreatorInitialROITool(),
821 'mergeUsingFeature':
False}
822 args.update(**inputMakerArgs)
828 self.addSequence( self.
recoSeq )
831 """ Merged CA moving reconstruction algorithms into the right sequence """
833 return self.merge( ca, sequenceName=self.
recoSeq.name )
836 """ Place algorithm in the correct reconstruction sequence """
838 return self.addEventAlgo( algo, sequenceName=self.
recoSeq.name )
846 """ 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 """
847 def __init__(self, name, viewMaker=None, isProbe=False, **viewMakerArgs):
848 super( InViewRecoCA, self ).
__init__()
849 self.
name = name +
"_probe" if isProbe
else name
850 def updateHandle(baseTool, probeTool, handleName):
851 if hasattr(baseTool, handleName)
and getattr(baseTool, handleName).Path!=
"StoreGateSvc+":
852 setattr(probeTool, handleName, getattr(probeTool, handleName).Path +
"_probe")
854 if len(viewMakerArgs) != 0:
855 assert viewMaker
is None,
"No support for explicitly passed view maker and args for EventViewCreatorAlgorithm"
858 assert len(viewMakerArgs) == 0,
"No support for explicitly passed view maker and args for EventViewCreatorAlgorithm"
860 self.
viewMakerAlg = viewMaker.__class__(viewMaker.getName()+
'_probe', **viewMaker._properties)
863 log.debug(f
"InViewRecoCA: Setting InputCachedViews on {self.viewMaker.getName()} to read decisions from tag leg {viewMaker.getName()}: {viewMaker.InputMakerOutputDecisions}")
864 self.
viewMakerAlg.InputCachedViews = viewMaker.InputMakerOutputDecisions
865 updateHandle(viewMakerArgs[
'RoITool'], roiTool,
"RoisWriteHandleKey")
866 if hasattr(viewMakerArgs[
'RoITool'],
"RoiCreator"):
867 updateHandle(viewMakerArgs[
'RoITool'], roiTool,
"ExtraPrefetchRoIsKey")
868 updateHandle(viewMakerArgs[
'RoITool'].RoiCreator, roiTool.RoiCreator,
"RoisWriteHandleKey")
874 assert 'name' not in viewMakerArgs,
"The name of view maker is predefined by the name of sequence"
875 assert 'Views' not in viewMakerArgs,
"The Views is predefined by the name of sequence"
876 assert 'ViewsNodeName' not in viewMakerArgs,
"The ViewsNodeName is predefined by the name of sequence"
877 if 'RoITool' in viewMakerArgs:
878 roiTool = viewMakerArgs[
'RoITool']
880 roiTool = CompFactory.ViewCreatorInitialROITool()
883 args = {
'name': f
'IM_{self.name}',
884 'ViewFallThrough' :
True,
885 'RoIsLink' :
'initialRoI',
887 'InViewRoIs' : f
'{name}RoIs',
888 'Views' : f
'{name}Views'+
'_probe' if isProbe
else f
'{name}Views',
889 'ViewNodeName' : f
'{name}InViews'+
'_probe' if isProbe
else f
'{name}InViews',
890 'RequireParentView' :
False,
891 'mergeUsingFeature' :
False }
892 args.update(**viewMakerArgs)
893 self.
viewMakerAlg = CompFactory.EventViewCreatorAlgorithm(**args)
895 updateHandle(args[
'RoITool'], roiTool,
"RoisWriteHandleKey")
896 if hasattr(args[
'RoITool'],
"RoiCreator"):
897 updateHandle(args[
'RoITool'], roiTool,
"ExtraPrefetchRoIsKey")
898 updateHandle(args[
'RoITool'].RoiCreator, roiTool.RoiCreator,
"RoisWriteHandleKey")
903 """ Merge CA moving reconstruction algorithms into the right sequence """
904 return self.merge( ca, sequenceName=self.
viewsSeq.name )
908 """ Place algorithm in the correct reconstruction sequence """
909 return self.addEventAlgo( algo, sequenceName=self.
viewsSeq.name )
917 """ CA component for MenuSequenceCA sequence """
919 self.
name = name+
"_probe" if isProbe
else name
921 super( SelectionCA, self ).
__init__()
930 def mergeReco(self, recoCA, robPrefetchCA=None, upSequenceCA=None):
931 ''' upSequenceCA is the user CA to run before the recoCA'''
936 ca.addEventAlgo(recoCA.inputMaker(), sequenceName=self.
stepViewSequence.name)
943 """To be used when the hypo alg configuration comes with auxiliary tools/services"""
947 """To be used when the hypo alg configuration does not require auxiliary tools/services"""
949 newname = algo.getName()+
'_probe'
951 self.
hypoAcc.addEventAlgo(algo)
954 """Access hypo algo (or throws)"""
956 assert h
is not None,
"No hypo in SeelectionCA {}".
format(self.
name)
960 """Access Input Maker (or throws)"""
962 assert im
is not None,
"No input maker in SeelectionCA {}".
format(self.
name)