2 from AthenaConfiguration.ComponentFactory
import CompFactory
5 AthSequencer = CompFactory.AthSequencer
8 """parallel AND sequencer"""
13 Members = subs.copy() )
16 """parallel OR sequencer
17 This is the default sequencer and lets the DataFlow govern the execution entirely.
23 Members = subs.copy() )
26 """sequential AND sequencer"""
31 Members = subs.copy() )
34 """sequential OR sequencer
35 Used when a barrier needs to be set by all subs reached irrespective of the decision
41 Members = subs.copy() )
45 """Return sequence children (empty if comp is not a sequence)"""
48 except AttributeError:
53 """ Generate a list of sequence names and depths in the graph, e.g.
54 [('AthAlgSeq', 0), ('seq1', 1), ('seq2', 1), ('seq1', 2)]
56 \\__ AthAlgSeq (seq: PAR AND)
57 \\__ seq1 (seq: SEQ AND)
58 \\__ seq2 (seq: SEQ AND)
61 seqNameList = [(seq.getName(), depth)]
70 """ Enforce rules for sequence graph - identical items can not be added to itself (even indirectly) """
72 def __noSubSequenceOfName( s, n, seen = set() ):
77 raise RuntimeError(f
"Sequence {c.getName()} contains itself")
80 raise RuntimeError(f
"Sequence {n} contains sub-sequence of the same name")
81 __noSubSequenceOfName( c, c.getName(), seen )
82 __noSubSequenceOfName( c, n, seen )
84 __noSubSequenceOfName( seq, seq.getName() )
90 """ elementary HLT step sequencer, filterAlg is gating, rest is anything that needs to happen within the step """
91 stepReco =
parOR(name+
"_reco", rest)
92 stepAnd =
seqAND(name, [ filterAlg, stepReco ])
97 return isinstance(obj, AthSequencer)
101 """ Traverse sequences tree to find a sequence of a given name. The first one is returned. """
102 if start.getName() == nameToLookFor:
106 if c.getName() == nameToLookFor:
115 """ find sequence that owns the sequence nameTooLookFor"""
117 if c.getName() == nameToLookFor:
127 """ Traverse sequences tree to find the first algorithm satisfying given predicate. The first encountered is returned.
129 Depth of the search can be controlled by the depth parameter.
130 Typical use is to limit search to the startSequence with depth parameter set to 1
146 """ Traverse sequences tree to find the algorithm of given name. The first encountered is returned.
148 The name() method is used to obtain the algorithm name, that one has to match to the request.
155 Returns flat listof of all algorithm instances in this, and in sub-sequences
162 if nameToLookFor
is None or child.getName() == nameToLookFor:
163 algorithms.append(child)
169 Finds all algorithms in sequence and groups them by name
171 Resulting dict has a following structure
172 {"Alg1Name":[(Alg1Instance, parentSequenceA, indexInSequenceA),(Alg1Instance, parentSequenceB, indexInSequenceB)],
173 "Alg2Name":(Alg2Instance, parentSequence, indexInThisSequence),
176 algorithms = collections.defaultdict(list)
178 if child.getName() == sequence.getName():
179 raise RuntimeError(f
"Recursively-nested sequence: {child.getName()} contains itself")
182 for algName
in childAlgs:
183 algorithms[algName] += childAlgs[algName]
185 if namesToLookFor
is None or child.getName()
in namesToLookFor:
186 algorithms[child.getName()].
append( (child, sequence, idx) )
191 """ Converts tree like structure of sequences into dictionary
192 keyed by top/start sequence name containing lists of of algorithms & sequences."""
194 def __inner( seq, collector ):
196 collector[seq.getName()].
append( c )
198 __inner( c, collector )
200 from collections
import defaultdict,OrderedDict
201 c = defaultdict(list)
203 return OrderedDict(c)
207 """Iterator of sequences and their algorithms from (and including) the `start`
208 sequence object. Do start from a sequence name use findSubSequence."""
213 yield from __inner(c)
215 yield from __inner(start)
223 import AthenaPython.PyAthena
as PyAthena
226 top.Members += [
parOR(
"nest1")]
228 top.Members += [nest2]
230 nest2.Members += [
parOR(
"deep_nest1")]
231 nest2.Members += [
parOR(
"deep_nest2")]
240 self.assertIsNotNone( f,
"Can not find sequence at start" )
241 self.assertEqual( f.getName(),
"top",
"Wrong sequence" )
244 self.assertIsNotNone( nest2,
"Can not find sub sequence" )
245 self.assertEqual( nest2.getName(),
"nest2",
"Sub sequence incorrect" )
250 self.assertIsNotNone( d,
"Deep searching for sub seqeunce fails" )
251 self.assertEqual( d.getName(),
"deep_nest2",
"Wrong sub sequence in deep search" )
256 self.assertIsNone( d,
"Algorithm confused as a sequence" )
260 self.assertIsNone( inexistent,
"ERROR, found sub sequence that does not relay exist" )
264 self.assertIsNone( inexistent,
"ERROR, found owner of inexistent sequence " )
268 self.assertEqual( owner.getName(),
"nest2",
"Wrong owner %s" % owner.getName() )
271 self.assertEqual( owner.getName(),
"nest2",
"Wrong owner %s" % owner.getName() )
274 self.assertEqual( owner.getName(),
"nest2",
"Wrong owner %s" % owner.getName() )
277 self.assertEqual( owner.getName() ,
"top",
"Wrong owner %s" % owner.getName() )
282 self.assertEqual( result, [
'top',
'nest1',
'nest2',
'deep_nest1',
'deep_nest2',
283 'SomeAlg1',
'SomeAlg2',
'SomeAlg3',
'SomeAlg0'] )
288 self.assertEqual( result, [
'nest2',
'deep_nest1',
'deep_nest2',
289 'SomeAlg1',
'SomeAlg2',
'SomeAlg3'] )
293 result = [seq.getName()
for seq
in iterSequences( deep_nest2 )]
294 self.assertEqual( result, [
'deep_nest2'] )
299 self.assertEqual( result, [
'SomeAlg1'] )
303 self.assertIsNotNone( a1,
"Can't find algorithm present in sequence" )
306 self.assertIsNotNone( a1,
"Can't find nested algorithm " )
311 self.assertIsNone( a1,
"Finding algorithm that is in the upper sequence" )
314 self.assertIsNone( a1,
"Finding algorithm that is does not exist" )
317 self.assertIsNotNone( a1,
"Could not find algorithm within the required nesting depth == 1" )
320 self.assertIsNone( a1,
"Could find algorithm even if it is deep in sequences structure" )
323 self.assertIsNotNone( a1,
"Could not find algorithm within the required nesting depth == 2" )
326 self.assertIsNotNone( a1
is None,
"Could find algorithm even if it is deep in sequences structure" )
331 global isComponentAccumulatorCfg
332 isComponentAccumulatorCfg =
lambda :
True
335 nest1 =
parOR(
"nest1")
337 top.Members += [nest1, nest2]
339 deep_nest1 =
seqAND(
"deep_nest1")
340 nest1.Members += [deep_nest1]
342 nest2.Members += [nest1]
344 deep_nest1.Members += [nest1]
345 self.assertRaises( RuntimeError, checkSequenceConsistency, top )