diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/Root/FeatureRequestDescriptor.cxx b/Trigger/TrigAnalysis/TrigDecisionTool/Root/FeatureRequestDescriptor.cxx new file mode 100644 index 0000000000000000000000000000000000000000..329210d3cbb94f36c3d2b16d77ca54fee9c3e5ff --- /dev/null +++ b/Trigger/TrigAnalysis/TrigDecisionTool/Root/FeatureRequestDescriptor.cxx @@ -0,0 +1,149 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#include "TrigDecisionTool/FeatureRequestDescriptor.h" + +namespace Trig { + + + FeatureRequestDescriptor::FeatureRequestDescriptor(const std::string& chainGroupName, + const unsigned int condition, + const std::string& containerSGKey, + const unsigned int featureCollectionMode, + const std::string& navElementLinkKey, + const int restrictToLegIndex) { + setChainGroup(chainGroupName); + setCondition(condition); + setRequireSGKey(containerSGKey); + setFeatureCollectionMode(featureCollectionMode); + setLinkName(navElementLinkKey); + setRestrictRequestToLeg(restrictToLegIndex); + } + + + FeatureRequestDescriptor::FeatureRequestDescriptor(const std::string& chainGroupName) { + reset(); + setChainGroup(chainGroupName); + } + + + void FeatureRequestDescriptor::reset() { + m_chainGroupName = "HLT_.*"; + m_condition = TrigDefs::Physics; + m_containerSGKey = ""; + m_featureCollectionMode = TrigDefs::lastFeatureOfType; + m_navElementLinkKey = TrigCompositeUtils::featureString(); + m_restrictToLegIndex = -1; + } + + + void FeatureRequestDescriptor::print(MsgStream& msg, const MSG::Level level) { + msg << level << "Feature Request Descriptor configuration:" << endmsg; + msg << level << "-- Chain Group name:'" << chainGroup() << "'." << endmsg; + ///////////////////////// + if (condition() == TrigDefs::Physics) { + msg << level << "-- Condition: TrigDefs::Physics, only paths which accepted chains in the ChainGroup will be explored." << endmsg; + } else if (condition() == TrigDefs::includeFailedDecisions) { + msg << level << "-- Condition: TrigDefs::includeFailedDecisions, passed and failed paths for chains in the ChainGroup will be explored." << endmsg; + } else { + msg << MSG::ERROR << "-- Unknown condition: " << condition() << endmsg; + } + ///////////////////////// + if (SGKey().empty()) { + msg << level << "-- No filtering on Container StoreGate Key" << endmsg; + } else { + msg << level << "-- Container StoreGate Key: ElementLinks must regex match the container name '" << SGKey() << "'." << endmsg; + } + ///////////////////////// + if (featureCollectionMode() == TrigDefs::lastFeatureOfType) { + msg << level << "-- Feature Collection Mode: TrigDefs::lastFeatureOfType, only one (final) matching ElementLink will be returned on each path through the navigation." << endmsg; + } else if (featureCollectionMode() == TrigDefs::allFeaturesOfType) { + msg << level << "-- Condition: TrigDefs::includeFailedDecisions, all matching ElementLinks will be returned on each path through the navigation." << endmsg; + } else { + msg << MSG::ERROR << "-- Unknown feature collection mode: " << featureCollectionMode() << "." << endmsg; + } + ///////////////////////// + msg << level << "-- Link Name: ElementLinks referenced by graph edges named '" << linkName() << "' will be returned." << endmsg; + ///////////////////////// + if (restrictRequestToLeg() == -1) { + msg << level << "-- Restrict Request To Leg: ElementLinks will be collected from all legs of any multi-leg chains in the ChainGroup." << endmsg; + } else { + msg << level << "-- Restrict Request To Leg: ElementLinks will be collected only from leg #" << restrictRequestToLeg() << " of all chains in the ChainGroup." << endmsg; + } + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setChainGroup(const std::string& chainGroupName) { + m_chainGroupName = chainGroupName; + return *this; + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setCondition(const unsigned int condition) { + if (condition != TrigDefs::Physics and condition != TrigDefs::includeFailedDecisions) { + throw std::runtime_error("Invalid option supplied to FeatureRequestDescriptor::setCondition. Must be Physics or includeFailedDecisions."); + } + m_condition = condition; + return *this; + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setRequireSGKey(const std::string& containerSGKey) { + m_containerSGKey = containerSGKey; + return *this; + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setFeatureCollectionMode(const unsigned int featureCollectionMode) { + if (featureCollectionMode != TrigDefs::lastFeatureOfType and featureCollectionMode != TrigDefs::allFeaturesOfType) { + throw std::runtime_error("Invalid option supplied to FeatureRequestDescriptor::featureCollectionMode. Must be lastFeatureOfType or allFeaturesOfType."); + } + m_featureCollectionMode = featureCollectionMode; + return *this; + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setLinkName(const std::string& navElementLinkKey) { + m_navElementLinkKey = navElementLinkKey; + return *this; + } + + + FeatureRequestDescriptor& FeatureRequestDescriptor::setRestrictRequestToLeg(const int restrictToLegIndex) { + m_restrictToLegIndex = restrictToLegIndex; + return *this; + } + + + const std::string& FeatureRequestDescriptor::chainGroup() const { + return m_chainGroupName; + } + + + unsigned int FeatureRequestDescriptor::condition() const { + return m_condition; + } + + + const std::string& FeatureRequestDescriptor::SGKey() const { + return m_containerSGKey; + } + + + unsigned int FeatureRequestDescriptor::featureCollectionMode() const { + return m_featureCollectionMode; + } + + + const std::string& FeatureRequestDescriptor::linkName() const { + return m_navElementLinkKey; + } + + + int FeatureRequestDescriptor::restrictRequestToLeg() const { + return m_restrictToLegIndex; + } + + +} diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.h b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.h index c840ac513e06a13167e2289be0d0392876fafb8a..be99272ee23e24d95d828128c3bd9f6d9ebede0a 100644 --- a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.h +++ b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.h @@ -30,6 +30,7 @@ #include "TrigDecisionTool/Conditions.h" #include "TrigDecisionTool/FeatureContainer.h" #include "TrigDecisionTool/Logger.h" +#include "TrigDecisionTool/FeatureRequestDescriptor.h" #include "TrigSteeringEvent/Enums.h" #include "TrigCompositeUtils/TrigCompositeUtils.h" @@ -124,6 +125,7 @@ namespace Trig { * @param[in] containerSGKey Optional requirement to return only features within the specified container name. Not checked if not specified. * @param[in] featureCollectionMode For lastFeatureOfType, stop exploring each route through the navigation once one matching feature has been found. * @param[in] navElementLinkKey Optional name of element link as saved online. The "feature" link is enforced, others may have been added. + * @param[in] restrictToLegIndex Optional index of a leg for mult-leg chains. Features will only be returned on the specified leg. Default is all legs. * @return Vector of LinkInfo, where each entry wraps an ElementLink to the feature, and the Decision object it came from. **/ template<class CONTAINER> @@ -132,7 +134,8 @@ namespace Trig { unsigned int condition = TrigDefs::Physics, const std::string& containerSGKey = "", const unsigned int featureCollectionMode = TrigDefs::lastFeatureOfType, - const std::string& navElementLinkKey = "feature") const; + const std::string& navElementLinkKey = TrigCompositeUtils::featureString(), + const int restrictToLegIndex = -1) const; // const std::vector< std::string >& patterns() const {return m_patterns;} diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.icc b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.icc index c0c62cfc47567486d22f8d4c1ffe5a787a949025..f84a1cd09908c5cfd7150eab410954b43289c0b3 100644 --- a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.icc +++ b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/ChainGroup.icc @@ -9,7 +9,8 @@ template<class CONTAINER> std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > Trig::ChainGroup::features(EventPtr_t eventStore, SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer>& HLTSummaryKeyIn, unsigned int condition, const std::string& containerSGKey, - const unsigned int featureCollectionMode, const std::string& navElementLinkKey) const { + const unsigned int featureCollectionMode, const std::string& navElementLinkKey, + const int restrictToLegIndex) const { bool errState = false; if ( condition != TrigDefs::Physics && condition != TrigDefs::includeFailedDecisions ) { @@ -69,9 +70,17 @@ std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > Trig::ChainGroup::feature if (legMultiplicites.size() == 0) { ATH_MSG_ERROR("chain " << chainID << " has invalid configuration, no multiplicity data."); } else if (legMultiplicites.size() > 1) { + if (restrictToLegIndex >= (int)legMultiplicites.size()) { + ATH_MSG_WARNING("Requested features from leg index " << restrictToLegIndex << " for chain " << chainID << + " but this chain only has " << legMultiplicites.size() << " legs"); + } // For multi-leg chains, the DecisionIDs are handled per leg. // We don't care here exactly how many objects are required per leg, just that there are two-or-more legs for (size_t legNumeral = 0; legNumeral < legMultiplicites.size(); ++legNumeral) { + // If restrictToLegIndex is -1 then we are NOT filtering on legs, we return features over all legs. + if (restrictToLegIndex != -1 and restrictToLegIndex != (int)legNumeral) { + continue; + } HLT::Identifier legID = TrigCompositeUtils::createLegName(chainID, legNumeral); allRequestedChainIDs.insert( legID.numeric() ); thisChainIDs.insert( legID.numeric() ); diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.h b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.h index 20b09dbecfb744f1a4d68019c994d40342ea8302..0f9a919929bf94aceec3a4aaf1c4e47d9eeec56d 100644 --- a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.h +++ b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.h @@ -30,6 +30,7 @@ #include "TrigDecisionTool/Feature.h" #include "TrigDecisionTool/FeatureContainer.h" #include "TrigDecisionTool/ChainGroup.h" +#include "TrigDecisionTool/FeatureRequestDescriptor.h" #include "TrigCompositeUtils/TrigCompositeUtils.h" @@ -113,6 +114,14 @@ namespace Trig { /// @name Run 3 functions /// @{ + /** + * @brief Runs 3+. Returns all features related to given chain group + * @param[in] featureRequest Helper object which encapsulates all configurable options of a request for features from the TDT + * @return Vector of LinkInfo, where each entry wraps an ElementLink to the feature, and the Decision object it came from. + **/ + template<class CONTAINER> + std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > + features(const Trig::FeatureRequestDescriptor& featureRequest) const; /** * @brief Runs 3+. Returns all features related to given chain group @@ -120,7 +129,8 @@ namespace Trig { * @param[in] condition Condition requirement. Only TrigDefs::Physics and TrigDefs::includeFailedDecisions are supported. * @param[in] containerSGKey Optional requirement to return only features within the specified container name. Not checked if not specified. * @param[in] featureCollectionMode For lastFeatureOfType, stop exploring each route through the navigation once one matching feature has been found. - * @param[in] navElementLinkKey Optional name of element link as saved online. The "feature" link is enforced, others may have been added. + * @param[in] navElementLinkKey Optional name of element link as saved online. The "feature" link is enforced, others may have been added. + * @param[in] restrictToLegIndex Optional index of a leg for mult-leg chains. Features will only be returned on the specified leg. Default is all legs. * @return Vector of LinkInfo, where each entry wraps an ElementLink to the feature, and the Decision object it came from. **/ template<class CONTAINER> @@ -129,7 +139,8 @@ namespace Trig { const unsigned int condition = TrigDefs::Physics, const std::string& containerSGKey = "", const unsigned int featureCollectionMode = TrigDefs::lastFeatureOfType, - const std::string& navElementLinkKey = "feature") const; + const std::string& navElementLinkKey = TrigCompositeUtils::featureString(), + const int restrictToLegIndex = -1) const; /** * @brief Runs 3+. Returns features related to given chain @@ -138,6 +149,7 @@ namespace Trig { * @param[in] containerSGKey Optional requirement to return only features within the specified container name. Not checked if not specified. * @param[in] featureCollectionMode For lastFeatureOfType, stop exploring each route through the navigation once one matching feature has been found. * @param[in] navElementLinkKey Optional name of element link as saved online. The "feature" link is enforced, others may have been added. + * @param[in] restrictToLegIndex Optional index of a leg for mult-leg chains. Features will only be returned on the specified leg. Default is all legs. * @return Vector of LinkInfo, where each entry wraps an ElementLink to the feature, and the Decision object it came from. **/ template<class CONTAINER> @@ -146,7 +158,8 @@ namespace Trig { const unsigned int condition = TrigDefs::Physics, const std::string& containerSGKey = "", const unsigned int featureCollectionMode = TrigDefs::lastFeatureOfType, - const std::string& navElementLinkKey = "feature") const; + const std::string& navElementLinkKey = TrigCompositeUtils::featureString(), + const int restrictToLegIndex = -1) const; /** * @brief Runs 3+. Returns a range over a container which are associated with a particular EventView instance from online. diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.icc b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.icc index 6debe8b61bc56916644a8f457879508637b98deb..22cc6c2b8f296a920de19624a3fc1ae59666991c 100644 --- a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.icc +++ b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/DecisionAccess.icc @@ -43,13 +43,20 @@ const std::vector<Trig::Feature<T> > Trig::DecisionAccess::ancestors(const HLT:: #endif // XAOD_STANDALONE +template<class CONTAINER> +std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > Trig::DecisionAccess::features(const Trig::FeatureRequestDescriptor& featureRequest) const { + return features<CONTAINER>(featureRequest.chainGroup(), featureRequest.condition(), featureRequest.SGKey(), + featureRequest.featureCollectionMode(), featureRequest.linkName(), featureRequest.restrictRequestToLeg()); +} + template<class CONTAINER> std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > Trig::DecisionAccess::features(const Trig::ChainGroup* group, const unsigned int condition, const std::string& containerSGKey, const unsigned int featureCollectionMode, - const std::string& navElementLinkKey) const { - return group->features<CONTAINER>(cgm()->store(), cgm()->getRun3NavigationKeyPtr(), condition, containerSGKey, featureCollectionMode, navElementLinkKey); + const std::string& navElementLinkKey, + const int restrictToLegIndex) const { + return group->features<CONTAINER>(cgm()->store(), cgm()->getRun3NavigationKeyPtr(), condition, containerSGKey, featureCollectionMode, navElementLinkKey, restrictToLegIndex); } template<class CONTAINER> @@ -57,9 +64,10 @@ std::vector< TrigCompositeUtils::LinkInfo<CONTAINER> > Trig::DecisionAccess::fea const unsigned int condition, const std::string& containerSGKey, const unsigned int featureCollectionMode, - const std::string& navElementLinkKey) const { + const std::string& navElementLinkKey, + const int restrictToLegIndex) const { const Trig::ChainGroup *g = cgm()->createChainGroup(Trig::convertStringToVector(chainName)); - return features<CONTAINER>(g, condition, containerSGKey, featureCollectionMode, navElementLinkKey); + return features<CONTAINER>(g, condition, containerSGKey, featureCollectionMode, navElementLinkKey, restrictToLegIndex); } template<class CONTAINER, class FEATURE_CONTAINER> diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/FeatureRequestDescriptor.h b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/FeatureRequestDescriptor.h new file mode 100644 index 0000000000000000000000000000000000000000..4f64469e19f71ed0bb16224568ad583253e45844 --- /dev/null +++ b/Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/FeatureRequestDescriptor.h @@ -0,0 +1,167 @@ +// -*- c++ -*- + +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef TRIGGER_DECISION_TOOL_FEATUREREQUESTDESCRIPTOR_H +#define TRIGGER_DECISION_TOOL_FEATUREREQUESTDESCRIPTOR_H + +/********************************************************************************** + * @Project: TrigDecisionTool + * @Package: TrigDecisionTool + * @class : FeatureRequestDescriptor + * + * @brief Helper class to encapsulate all possible configuration options when making a + * request for trigger chain features using the TrigDecisionTool's run 3 interface. + * + ***********************************************************************************/ +#include <string> +#include <sstream> + +#include "AsgMessaging/MsgStream.h" +#include "TrigDecisionTool/Conditions.h" +#include "TrigCompositeUtils/TrigCompositeUtils.h" + + +namespace Trig { + + class FeatureRequestDescriptor { + + public: + + /** + * @brief Default Constructor supplying all properties. See below for individual property descriptions. + **/ + FeatureRequestDescriptor(const std::string& chainGroupName = "HLT_.*", + const unsigned int condition = TrigDefs::Physics, + const std::string& containerSGKey = "", + const unsigned int featureCollectionMode = TrigDefs::lastFeatureOfType, + const std::string& navElementLinkKey = TrigCompositeUtils::featureString(), + const int restrictToLegIndex = -1); + + /** + * @brief Constructor for a specific Chain or Chain Group, supplied by name. Regex supported. + **/ + FeatureRequestDescriptor(const std::string& chainGroupName); + + + /** + * @brief Default destructor. No heap allocations. + **/ + ~FeatureRequestDescriptor() = default; + + /** + * @brief Default move constructor. + **/ + FeatureRequestDescriptor(FeatureRequestDescriptor&&) = default; + + /** + * @brief Default copy constructor. + **/ + FeatureRequestDescriptor(const FeatureRequestDescriptor&) = default; + + /** + * @brief Reset the FeatureRequestDescriptor to its default configuration. + **/ + void reset(); + + /** + * @brief Print the configuration of the FeatureRequestDescriptor to the supplied message stream. + **/ + void print(MsgStream& msg, const MSG::Level level = MSG::INFO); + + /** + * @brief Set the desired Chain or Chain Group. Regex supported. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setChainGroup(const std::string& chainGroupName); + + /** + * @brief Set the Condition: + * TrigDefs::Physics - (default), only returns features from paths through the navigation which accepted the event + * for at least one of the chains in the ChainGroup. + * TrigDefs::includeFailedDecisions - follows more paths through the navigation, the paths which were active for at + * least one of the chains in the ChainGroup, but which failed for all of these chains by some non-final Step. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setCondition(const unsigned int condition); + + /** + * @brief Set the StoreGate key filter. ElementLinks will have their StoreGate collection key checked against + * this filter, it must match for the ElementLink to be collected. Regex supported. + * Set to an empty string (default) to disable the filter. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setRequireSGKey(const std::string& containerSGKey); + + /** + * @brief Set the Feature Collection Mode: + * TrigDefs::lastFeatureOfType - (default) stop exploring up each path through the navigation as soon as one ElementLink + * has been collected along the path. As all paths are explored from their last step backwards, this equates to collecting + * the "final" feature along each path (after accounting for all other filtering options). + * TrigDefs::allFeatureOfType - does not stop once an ElementLink is collected when exploring paths through the navigation, instead + * keeps exploring always back to the L1 node. Potentially returns many features along each path, corresponding to intermediate + * physics objects as well as the "final" physics object. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setFeatureCollectionMode(const unsigned int featureCollectionMode); + + /** + * @brief Set the Link Name Key. Sets which named-edges in the navigation graph are returned by the call. + * By default the TrigDecisionTool looks for edges named "feature", however "roi", "initialRoI" or slice-specific + * custom-named edges can be alternatively used here. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setLinkName(const std::string& navElementLinkKey); + + /** + * @brief Set to -1 by default, indicating that all legs of multi-leg chains are searched. + * If set to an integer >= 0, the search will be restricted to the single specified leg for all chains in the ChainGroup. + * @return reference to self, allows chaining. + **/ + FeatureRequestDescriptor& setRestrictRequestToLeg(const int restrictToLegIndex); + + /** + * @return String corresponding to the chain group. Will be mapped to an actual ChainGroup by the TrigDecisionTool. + **/ + const std::string& chainGroup() const; + + /** + * @return The Condition, TrigDefs::Physics or TrigDefs::includeFailedDecisions + **/ + unsigned int condition() const; + + /** + * @return The StoreGate key filter (regex). Or an empty string if no filtering is requested. + **/ + const std::string& SGKey() const; + + /** + * @return The feature collection mode, TrigDefs::lastFeatureOfType or TrigDefs::allFeatureOfType + **/ + unsigned int featureCollectionMode() const; + + /** + * @return The name of the edges in the navigation graph which will be collected and returned. + **/ + const std::string& linkName() const; + + /** + * @return The chain-leg which the request is restricted to follow. -1 indicates no leg-specific filtering. + **/ + int restrictRequestToLeg() const; + + private: + + std::string m_chainGroupName; + int m_condition; + std::string m_containerSGKey; + int m_featureCollectionMode; + std::string m_navElementLinkKey; + int m_restrictToLegIndex; + + }; +} // End of namespace + +#endif // TRIGGER_DECISION_TOOL_FEATUREREQUESTDESCRIPTOR_H