ATLAS Offline Software
Loading...
Searching...
No Matches
HypoBase.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include <set>
9
10using namespace TrigCompositeUtils;
11
12HypoBase::HypoBase( const std::string& name, ISvcLocator* pSvcLocator )
13 : ::AthReentrantAlgorithm( name, pSvcLocator ) {}
14
16
17
21
25
27 CHECK( AthReentrantAlgorithm::sysInitialize() ); // initialise base class
28 CHECK( m_input.initialize() );
29 ATH_MSG_DEBUG("HypoBase::sysInitialize() Will consume decision: " << m_input.key() );
30 CHECK( m_output.initialize() );
31 ATH_MSG_DEBUG("HypoBase::sysInitialize() And produce decision: " << m_output.key() );
32 return StatusCode::SUCCESS;
33}
34
35StatusCode HypoBase::hypoBaseOutputProcessing(SG::WriteHandle<DecisionContainer>& outputHandle, MSG::Level lvl) const {
36
37 ATH_CHECK( printDebugInformation(outputHandle, lvl) );
38
40 ATH_CHECK( runtimeValidation(outputHandle, msg()) );
41 }
42
43 return StatusCode::SUCCESS;
44}
45
46
48 MsgStream& msg,
49 bool onlyValidateOneStep,
50 bool runTwoConversion)
51{
52 // Detailed checks on the output container of this HypoAlg
53 std::set<const Decision*> fullyExploredFrom; // Cache used to avoid exploring regions of the graph more than once
54 for (const Decision* d : *outputHandle) {
55 const DecisionContainer* dContainer = dynamic_cast<const DecisionContainer*>( d->container() );
56 const ElementLink<DecisionContainer> dEL = ElementLink<DecisionContainer>(*dContainer, d->index());
57 if (not dEL.isValid()) {
58 msg << MSG::ERROR << "Invalid seed element link in recursiveValidateGraph" << endmsg;
59 return StatusCode::FAILURE;
60 }
61 // Check that we can reach L1 along all navigation paths up from each Decision
62 // and validate these Decisions on the way up too.
63 if (recursiveValidateGraph(dEL, msg, onlyValidateOneStep, runTwoConversion, 0, fullyExploredFrom).isFailure()) {
64 return StatusCode::FAILURE;
65 }
66 }
67 return StatusCode::SUCCESS;
68}
69
70
72 MsgStream& msg,
73 bool onlyValidateOneStep,
74 bool runTwoConversion,
75 size_t callDepth,
76 std::set<const Decision*>& fullyExploredFrom)
77{
78 if (onlyValidateOneStep && callDepth > 0) {
79 if ((*dEL)->name() == hypoAlgNodeName()) {
80 // Validation is called from HypoAlg nodes. So if we have reached the _previous_ HypoAlg node, then we have already
81 // validated back from here in the past. Can stop at this point.
82 return StatusCode::SUCCESS;
83 }
84 }
85
86 // Check logical flow at this place in the graph
87 if ((*dEL)->name() == hypoAlgNodeName()) {
88 // Check that all Hypo Decisions produced here satisfy the more-strict all-parent logical flow
89 if ( validateLogicalFlow(dEL, msg, kRequireAll).isFailure() ) {
90 return StatusCode::FAILURE;
91 }
92 } else {
93 // (looser requirement of one-valid-parent-with-decision than we had when we knew that d corresponded to a HypoAlg output)
94 if ( validateLogicalFlow(dEL, msg, kRequireOne).isFailure() ) {
95 return StatusCode::FAILURE;
96 }
97 }
98
99 // Check my IDs
100 if ( validateDecisionIDs(dEL, msg).isFailure() ) {
101 return StatusCode::FAILURE;
102 }
103 if ( validateDuplicatedDecisionID(dEL, msg).isFailure() ) {
104 return StatusCode::FAILURE;
105 }
106
107 // Check my linking
108 if( validateParentLinking(dEL, msg, runTwoConversion).isFailure() ) {
109 return StatusCode::FAILURE;
110 }
111 if ( validateHasLinks(dEL, msg).isFailure() ) {
112 return StatusCode::FAILURE;
113 }
114
115 // Continue upstream
116 const std::vector<ElementLink<DecisionContainer>> seeds = (*dEL)->objectCollectionLinks<DecisionContainer>(seedString());
117 for (const ElementLink<DecisionContainer>& seed : seeds) {
118 if (fullyExploredFrom.count( (*seed) ) == 1) {
119 continue; // Already fully explored from this seed and up
120 }
121 if ( not seed.isValid() ) {
122 msg << MSG::ERROR << "Invalid seed element link in recursiveValidateGraph" << endmsg;
123 return StatusCode::FAILURE;
124 }
125 if ( recursiveValidateGraph(seed, msg, onlyValidateOneStep, runTwoConversion, callDepth + 1, fullyExploredFrom).isFailure() ) {
126 return StatusCode::FAILURE;
127 }
128 }
129
130 fullyExploredFrom.insert( *dEL );
131 return StatusCode::SUCCESS;
132}
133
134
136 MsgStream& msg,
137 bool runTwoConversion)
138{
139 const std::vector<ElementLink<DecisionContainer>> seeds = (*dEL)->objectCollectionLinks<DecisionContainer>(seedString());
140 // All Decision object must have at least one parent, unless they are the initial set of objects created by the HLTSeeding
141 const std::string& name = (*dEL)->name();
142 if (seeds.size() == 0 && name != hltSeedingNodeName()) {
143 printErrorHeader(dEL, msg);
144 msg << MSG::ERROR << "! Decision has zero parents. This is only allowed for the initial Decisions created by the HLTSeeding." << endmsg;
145 msg << MSG::ERROR << "! SOLUTION: Attach parent Decision(s) with TrigCompositeUtils::linkToPrevious" << endmsg;
147 return StatusCode::FAILURE;
148 }
149
150 if (name == hltSeedingNodeName()) {
151 if (seeds.size() > 0) {
152 printErrorHeader(dEL, msg);
153 msg << MSG::ERROR << "! Decision has parents. This is not allowed for the initial Decisions created by the HLTSeeding." << endmsg;
154 msg << MSG::ERROR << "! SOLUTION: Check HLTSeeding, no where should it be adding a parent link." << endmsg;
156 return StatusCode::FAILURE;
157 }
158 return StatusCode::SUCCESS;
159 }
160
161 static const std::set<std::string> expectedParentsFilter = {hypoAlgNodeName(), comboHypoAlgNodeName(), hltSeedingNodeName()};
162 static const std::set<std::string> expectedParentsInputMaker = {filterNodeName()};
163 static const std::set<std::string> expectedParentsHypoAlg = {inputMakerNodeName()};
164 static const std::set<std::string> expectedParentsComboHypoAlg = {hypoAlgNodeName(), inputMakerNodeName(), hltSeedingNodeName()}; // TODO check hltSeedingNodeName(), needed for newJO
165 static const std::set<std::string> expectedParentsSummaryFilter = {hypoAlgNodeName(), comboHypoAlgNodeName(), hltSeedingNodeName()};
166 static const std::set<std::string> expectedParentsSummaryPassed = {summaryFilterNodeName()};
167
168 const std::set<std::string>* expectedParentsPtr = nullptr;
169 if (name == filterNodeName()) {
170 expectedParentsPtr = &expectedParentsFilter;
171 } else if (name == inputMakerNodeName() and !runTwoConversion) {
172 expectedParentsPtr = &expectedParentsInputMaker;
173 } else if (name == inputMakerNodeName() and runTwoConversion) {
174 expectedParentsPtr = &expectedParentsFilter; // We don't have Filter nodes in the R2->R3 conversion
175 } else if (name == hypoAlgNodeName()) {
176 expectedParentsPtr = &expectedParentsHypoAlg;
177 } else if (name == comboHypoAlgNodeName()) {
178 expectedParentsPtr = &expectedParentsComboHypoAlg;
179 } else if (name == summaryFilterNodeName()) {
180 expectedParentsPtr = &expectedParentsSummaryFilter;
181 } else if (name == summaryPassNodeName()) {
182 expectedParentsPtr = &expectedParentsSummaryPassed;
183 } else {
184 printErrorHeader(dEL, msg);
185 msg << MSG::ERROR << "! Invalid Node name '" << name << "'." << endmsg;
186 msg << MSG::ERROR << "! SOLUTION: Find the alg which made a node with this name. Allowed named may be found in TrigCompositeUtils.h, See:'Constant string literals used within the HLT'." << endmsg;
188 return StatusCode::FAILURE;
189 }
190
191 for (const ElementLink<DecisionContainer>& seed : seeds) {
192 if (!expectedParentsPtr->contains( (*seed)->name() )) {
193 printErrorHeader(dEL, msg);
194 msg << MSG::ERROR << "! Invalid linking from node with name '" << name << "' to one with name '"<< (*seed)->name() << "'." << endmsg;
195 msg << MSG::ERROR << "! Allowed seed names are:" << endmsg;
196 for (const std::string& allowed : *expectedParentsPtr) {
197 msg << MSG::ERROR << "! " << allowed << endmsg;
198 }
199 msg << MSG::ERROR << "! SOLUTION: Find where this invalid parent was added and correct it." << endmsg;
201 return StatusCode::FAILURE;
202 }
203 }
204
205 return StatusCode::SUCCESS;
206}
207
208
210 MsgStream& msg)
211{
212 // All numeric IDs must correspond to a know, configured, HLT chain
213 DecisionIDContainer decisionIDSet;
214 decisionIDs(*dEL, decisionIDSet);
215 for (const DecisionID id : decisionIDSet) {
216 const std::string chain = HLT::Identifier( id ).name();
217 if (!isChainId(chain) and !isLegId(chain)) {
218 printErrorHeader(dEL, msg);
219 msg << MSG::ERROR << "! Decision contains an ID which does not correspond to a configured chain or a configured chain-leg: " << HLT::Identifier( id ) << endmsg;
220 msg << MSG::ERROR << "! SOLUTION: Locate the producer of the collection, investigate how this bad ID could have been added." << endmsg;
222 return StatusCode::FAILURE;
223 }
224 }
225 return StatusCode::SUCCESS;
226}
227
228
230 MsgStream& msg)
231{
232 // Persistent vector storage does not guarantee against duplicate entries
233 DecisionIDContainer decisionIDSet;
234 decisionIDs(*dEL, decisionIDSet);
235 if (decisionIDSet.size() != (*dEL)->decisions().size()) {
236 printErrorHeader(dEL, msg);
237 msg << MSG::ERROR << "! Decision contains duplicate DecisionIDs." << endmsg;
238 msg << MSG::ERROR << "! SOLUTION: If combining DecisionIDs from multiple parents, de-duplicate the internal std::vector<DecisionID> of 'Decision* d' with:" << endmsg;
239 msg << MSG::ERROR << "! TrigCompositeUtils::insertDecisionIDs(DecisionIDContainer(), d);" << endmsg;
241 return StatusCode::FAILURE;
242 }
243 return StatusCode::SUCCESS;
244}
245
246
248 MsgStream& msg,
249 const LogicalFlowCheckMode mode)
250{
251 // Do not need to validate for L1 Decisions as these have no parents
252 if ((*dEL)->name() == hltSeedingNodeName()) {
253 return StatusCode::SUCCESS;
254 }
255
256 // Get all my passed DecisionIDs
257 DecisionIDContainer decisionIDSet;
258 decisionIDs(*dEL, decisionIDSet);
259 const std::vector<ElementLink<DecisionContainer>> seeds = (*dEL)->objectCollectionLinks<DecisionContainer>(seedString());
260 for (const DecisionID id : decisionIDSet) {
261 // For each chain that I'm passing, check how many of my parents were also passing the chain
262 size_t parentsWithDecision = 0;
263 for (const ElementLink<DecisionContainer>& seed : seeds) {
264 if ( not seed.isValid() ) {
265 msg << MSG::ERROR << "Invalid seed element link in recursiveValidateGraph" << endmsg;
266 return StatusCode::FAILURE;
267 }
268 DecisionIDContainer seedIDSet;
269 decisionIDs(*seed, seedIDSet);
270 // Id may be a chain-ID (represents a whole chain) or a leg-ID (represents just a single leg of a multi-leg chain)
271 // Is ID is in this parent's set of passed IDs?
272 // Or, (if ID is a leg-ID) is the chain-ID of leg-ID in the parent's set of passed IDs?
273 if (passed(id, seedIDSet) or passed(getIDFromLeg(id).numeric(), seedIDSet)) {
274 ++parentsWithDecision;
275 }
276 else{ // Or, for each of the seed IDs, if the seed ID is a leg-ID, is the seed chain-ID of the seed leg-ID the same as ID?
277 for (auto sid: seedIDSet){
278 if (getIDFromLeg(sid).numeric() == id){
279 ++parentsWithDecision;
280 break;
281 }
282 }
283 }
284 }
285
286 if (mode == kRequireOne && parentsWithDecision == 0) {
287 // InputMakers may merge multiple of their input collections in order to run reconstruction on a common set of ROI (for example)
288 // So the DecisionIDs may have come from any one or more of the inputs. But zero is not allowed.
289 printErrorHeader(dEL, msg);
290 msg << MSG::ERROR << "! This Decision object is not respecting logical flow of DecisionIDs for chain: " << HLT::Identifier( id ) << endmsg;
291 msg << MSG::ERROR << "! This chain's DecisionID can not be found in any parents of this Decision object:" << endmsg;
292 size_t seed_n = 0;
293 for (const ElementLink<DecisionContainer>& seed : seeds) {
294 msg << MSG::ERROR << "! Index:" << (*seed)->index() << " from collection:" << seed.dataID() << endmsg;
295 msg << MSG::ERROR << "! " << **seed << endmsg;
296 DecisionIDContainer objDecisions;
297 decisionIDs(*seed, objDecisions);
298 for (const TrigCompositeUtils::DecisionID id : objDecisions ) {
299 msg << "! --- Passing in parent #" << seed_n << ": " << HLT::Identifier( id ) << endmsg;
300 }
301 ++seed_n;
302 }
303 msg << MSG::ERROR << "! SOLUTION: Ensure that the producer of this Decision object only adds DecisionIDs"
304 " which were present in at least one of its parents." << endmsg;
306 return StatusCode::FAILURE;
307 } else if (mode == kRequireAll && parentsWithDecision != seeds.size()) {
308 // HypoAlgs may form a new physics object from multiple objects in the previous step
309 // (think a BPhysics object whose parents are two Decisions which each correspond to a different L1 MU RoI,
310 // both ROI need to be in active state for the chain, if the chain's HypoTool considers the BPhysics object)
311 // This case requires *all* of the physics objects which are being combined together to be active for the chain
312 // in order to preserve logical flow
313 printErrorHeader(dEL, msg);
314 msg << MSG::ERROR << "! This Decision object is not respecting logical flow of DecisionIDs for chain: " << HLT::Identifier( id ) << endmsg;
315 msg << MSG::ERROR << "! As this Decision object represents the output of a HypoAlg, it must respect logical flow on all "
316 << seeds.size() << " of its parent(s):" << endmsg;
317 size_t seed_n = 0;
318 for (const ElementLink<DecisionContainer>& seed : seeds) {
319 msg << MSG::ERROR << "! Index:" << (*seed)->index() << " from collection:" << seed.dataID() << endmsg;
320 msg << MSG::ERROR << "! " << **seed << endmsg;
321 DecisionIDContainer objDecisions;
322 decisionIDs(*seed, objDecisions);
323 for (const TrigCompositeUtils::DecisionID id : objDecisions ) {
324 msg << "! --- Passing in parent #" << seed_n << ": " << HLT::Identifier( id ) << endmsg;
325 }
326 ++seed_n;
327 }
328 msg << MSG::ERROR << "! SOLUTION: Ensure that the HypoTool responsible for " << HLT::Identifier( id )
329 << " in this HypoAlg only runs if this ID is present in all parent decisions." << endmsg;
331 return StatusCode::FAILURE;
332 }
333 }
334 return StatusCode::SUCCESS;
335}
336
337
339 MsgStream& msg)
340{
341 const std::string& name = (*dEL)->name();
342 if (name == hypoAlgNodeName()) {
343
344 // Check that I have a "feature"
345 if ((*dEL)->hasObjectLink( featureString() )) {
346 return StatusCode::SUCCESS;
347 }
348 printErrorHeader(dEL, msg);
349 msg << MSG::ERROR << "! Decision has no '" << featureString() << "' ElementLink." << endmsg;
350 msg << MSG::ERROR << "! Every Decision created by a HypoAlg must correspond to some physics object, and be linked to the object." << endmsg;
351 msg << MSG::ERROR << "! SOLUTION: Ensure that all produced Decision objects are assigned their feature:" << endmsg;
352 msg << MSG::ERROR << "! SOLUTION: decision->setObjectLink<MY_FEATURE_CONTANER_TYPE>(featureString(), MY_FEATURE_ELEMENT_LINK);" << endmsg;
354 return StatusCode::FAILURE;
355
356 } else if (name == inputMakerNodeName()) {
357
358 // This requirement is dropped for empty input makers to avoid unnecessary graph clutter.
359 bool exempt = false;
360 if ((*dEL)->hasDetail<int32_t>("isEmpty") and (*dEL)->getDetail<int32_t>("isEmpty") == 1) {
361 exempt = true;
362 }
363
364 if (not (*dEL)->hasObjectLink( roiString() ) and not exempt) {
365 printErrorHeader(dEL, msg);
366 msg << MSG::ERROR << "! Decision has no '" << roiString() << "' ElementLink." << endmsg;
367 msg << MSG::ERROR << "! Every Decision created by a InputMaker must link to the ROI which reconstruction will run on for that Decision object in this Step." << endmsg;
368 msg << MSG::ERROR << "! It can be the FullScan ROI created by the HLTSeeding (FSNOSEED) if no other suitable ROI exists." << endmsg;
369 msg << MSG::ERROR << "! SOLUTION: Check the configuration of InputMakerForRoI or EventViewCreatorAlgorithm responsible for creating this Decision Object" << endmsg;
370 msg << MSG::ERROR << "! SOLUTION: The algorithm must have an ROITool which must attach an '"<< roiString() <<"' link to each Decision Object" << endmsg;
372 }
373
374 } else if (name == hltSeedingNodeName()) {
375
376 if (not (*dEL)->hasObjectLink( initialRoIString() )) {
377 printErrorHeader(dEL, msg);
378 msg << MSG::ERROR << "! Decision has no '" << initialRoIString() << "' ElementLink." << endmsg;
379 msg << MSG::ERROR << "! Every Decision created by the HLTSeeding must link to the initial ROI which caused it to be created." << endmsg;
380 msg << MSG::ERROR << "! This includes the Decision Object created to represent the Full-Scan/NoSeed (FSNOSEED) ROI." << endmsg;
381 msg << MSG::ERROR << "! SOLUTION: Check the configuration of the HLTSeeding tool responsible for creating this Decision Object" << endmsg;
383 }
384
385 }
386 return StatusCode::SUCCESS;
387}
388
389
390void HypoBase::printBangs(MsgStream& msg) {
391 msg << MSG::ERROR << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endmsg;
392}
393
394
396 MsgStream& msg)
397{
399 msg << MSG::ERROR << "! RUNTIME TRIGGER NAVIGATION VALIDATION ERROR" << endmsg;
400 msg << MSG::ERROR << "! Caused by Decision with index:" << (*dEL)->index() << endmsg;
401 msg << MSG::ERROR << "! From collection:" << dEL.dataID() << endmsg;
402 msg << MSG::ERROR << "! " << **dEL << endmsg;
403}
404
405
406StatusCode HypoBase::printDebugInformation(SG::WriteHandle<DecisionContainer>& outputHandle, MSG::Level lvl) const {
407 if (msgLvl(lvl)) {
408 msg() << lvl;
409 msg() << "Exiting with " << outputHandle->size() <<" Decision objects" << endmsg;
410 size_t count = 0;
411 for (const Decision* d : *outputHandle){
412 DecisionIDContainer objDecisions;
413 decisionIDs( d, objDecisions );
414 msg() << "Number of positive decisions for Decision object #" << count++ << ": " << objDecisions.size() << endmsg;
415 for (const TrigCompositeUtils::DecisionID id : objDecisions ) {
416 msg() << " --- Passes: " << HLT::Identifier( id ) << endmsg;
417 }
418 }
419 }
420 return StatusCode::SUCCESS;
421}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
#define CHECK(...)
Evaluate an expression and check for errors.
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
std::string name() const
reports human redable name
LogicalFlowCheckMode
Definition HypoBase.h:52
@ kRequireOne
Require all DecisionIDs to be present in at least one of my parent Decision objects.
Definition HypoBase.h:53
@ kRequireAll
Definition HypoBase.h:54
SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > m_output
output decisions
Definition HypoBase.h:103
static void printBangs(MsgStream &msg)
Print header line.
Definition HypoBase.cxx:390
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_input
input decisions
Definition HypoBase.h:101
const SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > & decisionInput() const
methods for derived classes to access handles of the base class input other read/write handles may be...
Definition HypoBase.cxx:18
StatusCode printDebugInformation(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl) const
Common base function to print information on chains passed by objects considered in the hypo.
Definition HypoBase.cxx:406
const SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > & decisionOutput() const
methods for derived classes to access handles of the base class output other read/write handles may b...
Definition HypoBase.cxx:22
Gaudi::Property< bool > m_runtimeValidation
Enabling of detailed validation checks for use during development.
Definition HypoBase.h:105
static StatusCode runtimeValidation(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MsgStream &msg, bool onlyValidateOneStep=true, bool runTwoConversion=false)
Executes all individual runtime tests.
Definition HypoBase.cxx:47
StatusCode hypoBaseOutputProcessing(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl=MSG::DEBUG) const
Base class function to be called once slice specific code has finished. Handles debug printing and va...
Definition HypoBase.cxx:35
virtual ~HypoBase()
destructor
Definition HypoBase.cxx:15
static void printErrorHeader(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
A problem was found, print common output data.
Definition HypoBase.cxx:395
static StatusCode validateDecisionIDs(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
Ensure that all present IDs correspond to configured chains.
Definition HypoBase.cxx:209
static StatusCode validateParentLinking(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg, bool runTwoConversion)
Ensure that the Decision has at least one valid parent, unless it is a initial Decision from the HLTS...
Definition HypoBase.cxx:135
virtual StatusCode sysInitialize() override
initialise this base class
Definition HypoBase.cxx:26
HypoBase(const std::string &name, ISvcLocator *pSvcLocator)
constructor, to be called by sub-class constructors
Definition HypoBase.cxx:12
static StatusCode recursiveValidateGraph(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg, bool onlyValidateOneStep, bool runTwoConversion, size_t callDepth, std::set< const TrigCompositeUtils::Decision * > &fullyExploredFrom)
Execute all checks on one node in the graph, d, then recursive call self on all parent nodes up to L1...
Definition HypoBase.cxx:71
static StatusCode validateHasLinks(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
Ensure all Decisions have the named ElementLink graph edges which they are required to by spec.
Definition HypoBase.cxx:338
static StatusCode validateDuplicatedDecisionID(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
Ensure that no space is being wasted by duplicated DecisionIDs in any Decision objects.
Definition HypoBase.cxx:229
static StatusCode validateLogicalFlow(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg, const LogicalFlowCheckMode mode)
Ensure that all DecisionIDs have propagated correctly from their parent.
Definition HypoBase.cxx:247
Property holding a SG store/key/clid from which a ReadHandle is made.
Property holding a SG store/key/clid from which a WriteHandle is made.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
bool isChainId(const HLT::Identifier &chainIdentifier)
Recognise whether the HLT identifier corresponds to a whole chain.
const std::string & inputMakerNodeName()
unsigned int DecisionID
const std::string & summaryFilterNodeName()
const std::string & roiString()
const std::string & featureString()
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
const std::string & filterNodeName()
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
const std::string & comboHypoAlgNodeName()
std::set< DecisionID > DecisionIDContainer
const std::string & hypoAlgNodeName()
const std::string & initialRoIString()
const std::string & seedString()
const std::string & summaryPassNodeName()
const std::string & hltSeedingNodeName()
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.