ATLAS Offline Software
CFValidation.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
2 
3 """
4  A set of config-time tests to be run on the HLT top sequence
5 
6 """
7 
8 from AthenaCommon.CFElements import isSequence
9 from TriggerJobOpts.TriggerConfig import collectViewMakers
10 
11 def findViewAlgs( inputNodes, viewNodes ):
12  """ Make lists of algorithms that run in views, and those that don't """
13 
14  allAlgs = []
15  viewAlgs = []
16 
17  # Examine all nodes
18  for node in inputNodes:
19 
20  # If node is a sequence, explore further
21  if isSequence( node ):
22 
23  # Identify view CF nodes
24  if node.getName() in viewNodes.keys():
25 
26  # Retrieve view algorithms
27  # (views don't nest, so will be returned in first list)
28  newViewAlgs, dummy = findViewAlgs( node.getChildren(), {} )
29  viewAlgs += newViewAlgs
30 
31  # Record the fact that the view node is found
32  viewNodes[ node.getName() ] = True
33 
34  # Explore the tree
35  else:
36  newAlgs, newViewAlgs = findViewAlgs( node.getChildren(), viewNodes )
37  allAlgs += newAlgs
38  viewAlgs += newViewAlgs
39 
40  # Node is an algorithm
41  else:
42  allAlgs += [ node.getName() ]
43 
44  return allAlgs, viewAlgs
45 
46 
47 def checkVDV( inputNodes, ancestorNames, allEVCAs ):
48  """ Try to make sure each VDV has a correctly-configred EVCA upstream """
49 
50  for node in inputNodes:
51 
52  # Node is a VDV
53  if "AthViews__ViewDataVerifier" in type( node ).__name__:
54 
55  # Check that VDV has a corresponding, correctly-configured EVCA
56  foundEVCA = False
57  for name in ancestorNames:
58 
59  if name in allEVCAs.keys():
60 
61  # Check EVCA properties
62  parentAllowed = hasattr( allEVCAs[ name ], "RequireParentView" ) and allEVCAs[ name ].RequireParentView
63  eventLevelAllowed = hasattr( allEVCAs[ name ], "ViewFallThrough" ) and allEVCAs[ name ].ViewFallThrough
64  if not ( parentAllowed or eventLevelAllowed ):
65  raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has upstream EventViewCreatorAlgorithm " + allEVCAs[ name ].name() + " with no external data" )
66  foundEVCA = True
67  break
68 
69  if not foundEVCA:
70  raise RuntimeError( "ViewDataVerifier alg " + node.name() + " has no corresponding upstream EventViewCreatorAlgorithm" )
71 
72  # Node is an EVCA
73  if "EventViewCreatorAlgorithm" in type( node ).__name__:
74 
75  # Store EVCA in a dictionary by the node it refers to
76  if node.ViewNodeName in allEVCAs.keys():
77  if node.name() != allEVCAs[ node.ViewNodeName ].name():
78  raise RuntimeError( "Found duplicate view node name " + node.ViewNodeName + " configured for EVCAs " + node.name() + " and " + allEVCAs[ node.ViewNodeName ].name() )
79  allEVCAs[ node.ViewNodeName ] = node
80 
81  if not hasattr(node, "RoITool"):
82  raise RuntimeError( "Node name " + node.name() + " was not supplied with a RoITool" )
83 
84  # Explore nested CF
85  if isSequence( node ):
86 
87  checkVDV( node.getChildren(), ancestorNames + [node.name()], allEVCAs )
88 
89 
90 def testHLTTree( inputSequence ):
91  """ Run all config tests """
92 
93  viewMakers = collectViewMakers( inputSequence )
94 
95  # List all CF nodes to be used with EventViews (and whether they are found)
96  viewNodes = {}
97  for viewMaker in viewMakers:
98  viewNodes[ viewMaker.ViewNodeName ] = False
99  originalLength = len( viewNodes )
100 
101  # Identify the algorithms that will run in EventViews
102  wholeEventAlgs, viewAlgs = findViewAlgs( inputSequence.getChildren(), viewNodes )
103 
104  # Check that all view nodes are found
105  if len( viewNodes ) != originalLength:
106  raise RuntimeError( "Something went wrong with view config inspection" )
107  for viewNode in viewNodes.keys():
108  if not viewNodes[ viewNode ]:
109  raise RuntimeError( "EventView CF node " + viewNode + " was not found attached to the test sequence" )
110 
111  # Look for view algs in the whole event context
112  for viewAlgName in viewAlgs:
113  if viewAlgName in wholeEventAlgs:
114  from AthenaCommon.AlgSequence import dumpSequence
115  dumpSequence( inputSequence )
116  raise RuntimeError( viewAlgName + " is attached to an EventView node, but also runs in the whole event context" )
117 
118  # Make sure that VDVs are configured correctly
119  allEVCAs = {}
120  checkVDV( inputSequence.getChildren(), [inputSequence.name()], allEVCAs )
121 
122  # Check for inconsistent view maker search results
123  if len( allEVCAs ) != originalLength:
124  raise RuntimeError( "EventView creator alg search found different results in structured search (" + str(originalLength) + ") versus naive search (" + str( len( allEVCAs ) ) + "). Implies menu structure error" )
python.AlgSequence.dumpSequence
def dumpSequence(seq, indent=0)
Definition: Control/AthenaCommon/python/AlgSequence.py:101
CFValidation.findViewAlgs
def findViewAlgs(inputNodes, viewNodes)
Definition: CFValidation.py:11
CFValidation.checkVDV
def checkVDV(inputNodes, ancestorNames, allEVCAs)
Definition: CFValidation.py:47
node::name
void name(const std::string &n)
Definition: node.h:37
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
python.TriggerConfig.collectViewMakers
def collectViewMakers(steps)
Definition: TriggerConfig.py:67
CFValidation.testHLTTree
def testHLTTree(inputSequence)
Definition: CFValidation.py:90
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
str
Definition: BTagTrackIpAccessor.cxx:11
python.CFElements.isSequence
def isSequence(obj)
Definition: CFElements.py:96