32 return StatusCode::SUCCESS;
43 return StatusCode::SUCCESS;
49 bool onlyValidateOneStep,
50 bool runTwoConversion)
53 std::set<const Decision*> fullyExploredFrom;
54 for (
const Decision* d : *outputHandle) {
58 msg << MSG::ERROR <<
"Invalid seed element link in recursiveValidateGraph" <<
endmsg;
59 return StatusCode::FAILURE;
64 return StatusCode::FAILURE;
67 return StatusCode::SUCCESS;
73 bool onlyValidateOneStep,
74 bool runTwoConversion,
76 std::set<const Decision*>& fullyExploredFrom)
78 if (onlyValidateOneStep && callDepth > 0) {
82 return StatusCode::SUCCESS;
90 return StatusCode::FAILURE;
95 return StatusCode::FAILURE;
101 return StatusCode::FAILURE;
104 return StatusCode::FAILURE;
109 return StatusCode::FAILURE;
112 return StatusCode::FAILURE;
118 if (fullyExploredFrom.count( (*seed) ) == 1) {
121 if ( not seed.isValid() ) {
122 msg << MSG::ERROR <<
"Invalid seed element link in recursiveValidateGraph" <<
endmsg;
123 return StatusCode::FAILURE;
125 if (
recursiveValidateGraph(seed,
msg, onlyValidateOneStep, runTwoConversion, callDepth + 1, fullyExploredFrom).isFailure() ) {
126 return StatusCode::FAILURE;
130 fullyExploredFrom.insert( *dEL );
131 return StatusCode::SUCCESS;
137 bool runTwoConversion)
141 const std::string& name = (*dEL)->name();
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;
151 if (seeds.size() > 0) {
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;
158 return StatusCode::SUCCESS;
162 static const std::set<std::string> expectedParentsInputMaker = {
filterNodeName()};
168 const std::set<std::string>* expectedParentsPtr =
nullptr;
170 expectedParentsPtr = &expectedParentsFilter;
172 expectedParentsPtr = &expectedParentsInputMaker;
174 expectedParentsPtr = &expectedParentsFilter;
176 expectedParentsPtr = &expectedParentsHypoAlg;
178 expectedParentsPtr = &expectedParentsComboHypoAlg;
180 expectedParentsPtr = &expectedParentsSummaryFilter;
182 expectedParentsPtr = &expectedParentsSummaryPassed;
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;
192 if (!expectedParentsPtr->contains( (*seed)->name() )) {
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;
199 msg << MSG::ERROR <<
"! SOLUTION: Find where this invalid parent was added and correct it." <<
endmsg;
201 return StatusCode::FAILURE;
205 return StatusCode::SUCCESS;
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;
225 return StatusCode::SUCCESS;
235 if (decisionIDSet.size() != (*dEL)->decisions().size()) {
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;
243 return StatusCode::SUCCESS;
253 return StatusCode::SUCCESS;
262 size_t parentsWithDecision = 0;
264 if ( not seed.isValid() ) {
265 msg << MSG::ERROR <<
"Invalid seed element link in recursiveValidateGraph" <<
endmsg;
266 return StatusCode::FAILURE;
274 ++parentsWithDecision;
277 for (
auto sid: seedIDSet){
279 ++parentsWithDecision;
286 if (mode ==
kRequireOne && parentsWithDecision == 0) {
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;
294 msg << MSG::ERROR <<
"! Index:" << (*seed)->index() <<
" from collection:" << seed.dataID() <<
endmsg;
295 msg << MSG::ERROR <<
"! " << **seed <<
endmsg;
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()) {
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;
319 msg << MSG::ERROR <<
"! Index:" << (*seed)->index() <<
" from collection:" << seed.dataID() <<
endmsg;
320 msg << MSG::ERROR <<
"! " << **seed <<
endmsg;
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;
334 return StatusCode::SUCCESS;
341 const std::string& name = (*dEL)->name();
346 return StatusCode::SUCCESS;
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;
360 if ((*dEL)->hasDetail<int32_t>(
"isEmpty") and (*dEL)->getDetail<int32_t>(
"isEmpty") == 1) {
364 if (not (*dEL)->hasObjectLink(
roiString() ) and not exempt) {
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;
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;
386 return StatusCode::SUCCESS;
391 msg << MSG::ERROR <<
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" <<
endmsg;
399 msg << MSG::ERROR <<
"! RUNTIME TRIGGER NAVIGATION VALIDATION ERROR" <<
endmsg;
400 msg << MSG::ERROR <<
"! Caused by Decision with index:" << (*dEL)->index() <<
endmsg;
402 msg << MSG::ERROR <<
"! " << **dEL <<
endmsg;
409 msg() <<
"Exiting with " << outputHandle->size() <<
" Decision objects" <<
endmsg;
411 for (
const Decision* d : *outputHandle){
414 msg() <<
"Number of positive decisions for Decision object #" <<
count++ <<
": " << objDecisions.size() <<
endmsg;
420 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define CHECK(...)
Evaluate an expression and check for errors.
virtual StatusCode sysInitialize() override
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
ElementLink implementation for ROOT usage.
const ID_type & dataID() const
Get the key that we reference, as a string.
bool isValid() const
Test to see if the link can be dereferenced.
std::string name() const
reports human redable name
@ kRequireOne
Require all DecisionIDs to be present in at least one of my parent Decision objects.
SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > m_output
output decisions
static void printBangs(MsgStream &msg)
Print header line.
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_input
input decisions
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...
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.
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...
Gaudi::Property< bool > m_runtimeValidation
Enabling of detailed validation checks for use during development.
static StatusCode runtimeValidation(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MsgStream &msg, bool onlyValidateOneStep=true, bool runTwoConversion=false)
Executes all individual runtime tests.
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...
virtual ~HypoBase()
destructor
static void printErrorHeader(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
A problem was found, print common output data.
static StatusCode validateDecisionIDs(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
Ensure that all present IDs correspond to configured chains.
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...
virtual StatusCode sysInitialize() override
initialise this base class
HypoBase(const std::string &name, ISvcLocator *pSvcLocator)
constructor, to be called by sub-class constructors
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...
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.
static StatusCode validateDuplicatedDecisionID(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg)
Ensure that no space is being wasted by duplicated DecisionIDs in any Decision objects.
static StatusCode validateLogicalFlow(const ElementLink< TrigCompositeUtils::DecisionContainer > &dEL, MsgStream &msg, const LogicalFlowCheckMode mode)
Ensure that all DecisionIDs have propagated correctly from their parent.
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 ®x)
count how many occurances of a regx are in a string
bool isChainId(const HLT::Identifier &chainIdentifier)
Recognise whether the HLT identifier corresponds to a whole chain.
const std::string & inputMakerNodeName()
const std::string & summaryFilterNodeName()
xAOD::TrigComposite Decision
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()
xAOD::TrigCompositeContainer DecisionContainer
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.