15 #include <unordered_set>
30 auto data = std::make_unique<DecisionContainer>() ;
31 auto aux = std::make_unique<DecisionAuxContainer>() ;
32 data->setStore( aux.get() );
33 handle.
record( std::move(
data ), std::move( aux ) ).ignore();
38 auto data = std::make_unique<DecisionContainer>() ;
39 auto aux = std::make_unique<DecisionAuxContainer>() ;
40 data->setStore( aux.get() );
41 handle.
record( std::move(
data ), std::move( aux ) ).ignore();
47 if ( !
name.empty() ) {
60 std::vector<DecisionID>&
decisions = readWriteAccessor( *
d );
66 const std::vector<DecisionID>&
decisions = readOnlyAccessor( *
d );
71 return readOnlyAccessor( *
d );
75 return readWriteAccessor( *
d );
89 collateIDs.insert(
src.begin(),
src.end() );
93 vdest.reserve(collateIDs.size());
95 vdest.insert( vdest.end(), collateIDs.begin(), collateIDs.end() );
105 const std::vector<DecisionID>&
decisions = readOnlyAccessor( *
d );
119 return idSet.find(
id ) != idSet.end();
122 #if !defined(XAOD_STANDALONE) && !defined(XAOD_ANALYSIS) // Full athena
126 throw std::runtime_error(
"TrigCompositeUtils::convertToElementLink Using convertToElementLink(d) requires that the Decision d is already in a container");
130 #else // Analysis or Standalone
134 throw std::runtime_error(
"TrigCompositeUtils::convertToElementLink Using convertToElementLink(d) requires that the Decision d is already in a container");
142 if (!seed.isValid()) {
143 throw std::runtime_error(
"TrigCompositeUtils::linkToPrevious Invalid Decision Link key or index provided");
154 return d->hasObjectCollectionLinks(
seedString() );
163 return dest->copyAllLinksFrom(
src);
172 throw std::runtime_error(
"TrigCompositeUtils::createLegName chainIdentifier '"+
name+
"' does not start with 'HLT_'");
175 throw std::runtime_error(
"TrigCompositeUtils::createLegName Leg counters above 999 are invalid.");
181 const std::string&
name = legIdentifier.
name();
183 return legIdentifier;
187 throw std::runtime_error(
"TrigCompositeUtils::getIDFromLeg legIdentifier '"+
name+
"' does not start with 'HLT_' or 'leg' ");
200 std::from_chars(
name.data()+3,
name.data()+6,
id);
202 throw std::runtime_error(
"TrigCompositeUtils::getIndexFromLeg legIdentifier '"+
name+
"' does not start with 'HLT_' or 'leg' ");
212 std::from_chars(
name.data()+3,
name.data()+6,
id);
213 return {
name.substr(7),
id};
215 throw std::runtime_error(
"TrigCompositeUtils::getIDFromLeg legIdentifier '"+
name+
"' does not start with 'HLT_' or 'leg' ");
224 return name.starts_with(
"leg");
232 return name.starts_with(
"HLT_");
271 const auto it = std::find_if(container.
begin(), container.
end(), [&nodeName](
const Decision*
d){return d->name()==nodeName;});
272 if (
it==container.
end()) {
return nullptr;}
277 const EventContext& ctx,
278 const std::string& summaryCollectionKey,
280 const std::set<std::string>& keysToIgnore) {
285 static const std::unordered_set<std::string> knownDistributedSummaryStores{
292 static const std::unordered_set<std::string> knownCompactSummaryStores{
"HLTNav_Summary_OnlineSlimmed",
293 "HLTNav_Summary_ESDSlimmed",
294 "HLTNav_Summary_AODSlimmed",
295 "HLTNav_Summary_DAODSlimmed",
296 "HLTNav_R2ToR3Summary"
299 std::vector<std::string>
keys;
301 if (knownDistributedSummaryStores.contains(summaryCollectionKey) or summaryCollectionKey.empty()) {
305 #ifndef XAOD_STANDALONE
310 throw std::runtime_error(
"Cannot obtain rejected HLT features in AnalysisBase when reading from uncompactified navigation containers, run trigger navigation slimming first if you really need this.");
313 }
else if (knownCompactSummaryStores.contains(summaryCollectionKey)) {
315 keys.push_back(summaryCollectionKey);
319 using namespace msgRejected;
320 ANA_MSG_WARNING(
"getRejectedDecisionNodes has not been told about final collection " << summaryCollectionKey <<
" please update this function. Assuming that it is already compact.");
322 keys.push_back(summaryCollectionKey);
326 std::vector<const Decision*> output;
330 if (!containerRHKey.
initialize().isSuccess()) {
331 throw std::runtime_error(
"Cannot initialize ReadHandleKey for DecisionContainer");
335 for (
const std::string&
key :
keys) {
337 if ( ! (
key.starts_with(
"HLTNav_") ||
key.starts_with(
"_HLTNav_")) ) {
340 if (keysToIgnore.contains(
key)) {
345 containerRHKey =
key;
347 if (!containerRH.isValid()) {
348 throw std::runtime_error(
"Unable to retrieve " +
key +
" from event store.");
356 if (mySeeds.empty()) {
360 if (!allSeedsValid) {
361 using namespace msgRejected;
363 <<
"The trigger navigation information is incomplete. Skipping this Decision object.");
368 decisionIDs(*mySeeds[0], activeChainsIntoThisDecision);
369 if (mySeeds.size() > 1) {
370 for (
size_t i = 1;
i < mySeeds.size(); ++
i) {
376 moreActiveChains.begin(), moreActiveChains.end(),
387 chainsToCheck = activeChainsIntoThisDecision;
395 for (
const DecisionID checkID : chainsToCheck) {
396 if (not activeChainsPassedByThisDecision.contains(checkID) &&
397 activeChainsIntoThisDecision.contains(checkID)) {
410 std::set<const Decision*>& fullyExploredFrom,
412 const bool enforceDecisionOnNode) {
422 #if TRIGCOMPUTILS_ENABLE_EARLY_EXIT == 1
424 if (fullyExploredFrom.count(
node) == 1) {
434 const Decision* seedDecision = *(seed);
441 fullyExploredFrom.insert(
node);
449 const bool enforceDecisionOnStartNode) {
451 std::set<const Decision*> fullyExploredFrom;
460 const bool keepOnlyFinalFeatures,
461 const bool removeEmptySteps,
462 const std::vector<std::string>& nodesToDrop)
464 std::set<NavGraphNode*> fullyExploredFrom;
473 std::set<NavGraphNode*>& fullyExploredFrom,
474 const bool keepOnlyFinalFeatures,
475 const bool removeEmptySteps,
476 const std::vector<std::string>& nodesToDrop)
481 bool keep = modeKeep;
487 const Decision*
const myFirstParent = (
node->seeds().size() ?
node->seeds().at(0)->
node() :
nullptr);
488 const Decision*
const myFirstChild = (
node->children().size() ?
node->children().at(0)->
node() :
nullptr);
492 if (keepOnlyFinalFeatures) {
508 if (!specialBphysCase && !specialR2toR3Case) {
522 for (
const std::string& toDrop : nodesToDrop) {
523 if (me->
name() == toDrop) {
571 #if TRIGCOMPUTILS_ENABLE_EARLY_EXIT == 1
585 bool allowEarlyExit =
true;
586 if (keepOnlyFinalFeatures) {
587 allowEarlyExit = (modeKeep ==
false);
589 if (allowEarlyExit && fullyExploredFrom.count(seed) == 1) {
599 fullyExploredFrom.insert(
node);
604 const std::string& linkName,
605 std::vector<sgkey_t>& keyVec,
606 std::vector<uint32_t>& clidVec,
607 std::vector<Decision::index_type>& indexVec,
608 std::vector<const Decision*>& sourceVec,
609 const unsigned int behaviour,
610 std::set<const Decision*>* fullyExploredFrom)
612 using namespace msgFindLink;
615 if (keyVec.size() != clidVec.size() or clidVec.size() != indexVec.size()) {
616 ANA_MSG_WARNING(
"In typelessFindLinks, keyVec, clidVec, indexVec must all be the same size. Instead have:"
617 << keyVec.size() <<
", " << clidVec.size() <<
", " << indexVec.size());
625 if (
found && (behaviour & TrigDefs::lastFeatureOfType)) {
630 #if TRIGCOMPUTILS_ENABLE_EARLY_EXIT == 1
631 if (fullyExploredFrom !=
nullptr) {
634 if (fullyExploredFrom->count(*seed) == 1) {
639 found |=
typelessFindLinks(*seed, linkName, keyVec, clidVec, indexVec, sourceVec, behaviour, fullyExploredFrom);
642 if (fullyExploredFrom !=
nullptr) {
643 fullyExploredFrom->insert(
start);
650 const std::string& linkName,
651 std::vector<sgkey_t>& keyVec,
652 std::vector<uint32_t>& clidVec,
653 std::vector<Decision::index_type>& indexVec,
654 std::vector<const Decision*>& sourceVec,
655 const unsigned int behaviour,
656 std::set<const Decision*>* fullyExploredFrom)
658 using namespace msgFindLink;
661 if (keyVec.size() != clidVec.size() or clidVec.size() != indexVec.size()) {
662 ANA_MSG_WARNING(
"In typelessFindLinks, keyVec, clidVec, indexVec must all be the same size. Instead have:"
663 << keyVec.size() <<
", " << clidVec.size() <<
", " << indexVec.size());
672 if (
found && (behaviour & TrigDefs::lastFeatureOfType)) {
677 #if TRIGCOMPUTILS_ENABLE_EARLY_EXIT == 1
678 if (fullyExploredFrom !=
nullptr) {
681 const Decision* seed_decisionObject = seed->node();
682 if (fullyExploredFrom->count(seed_decisionObject) == 1) {
687 found |=
typelessFindLinks(seed, linkName, keyVec, clidVec, indexVec, sourceVec, behaviour, fullyExploredFrom);
690 if (fullyExploredFrom !=
nullptr) {
691 fullyExploredFrom->insert(start_decisionObject);
698 const std::string& linkName,
699 std::vector<sgkey_t>& keyVec,
700 std::vector<uint32_t>& clidVec,
701 std::vector<Decision::index_type>& indexVec,
702 std::vector<const Decision*>& sourceVec)
705 std::vector<sgkey_t> tmpKeyVec;
706 std::vector<uint32_t> tmpClidVec;
707 std::vector<Decision::index_type> tmpIndexVec;
708 if (
start->hasObjectCollectionLinks(linkName)) {
709 found =
start->typelessGetObjectCollectionLinks(linkName, tmpKeyVec, tmpClidVec, tmpIndexVec);
711 if (
start->hasObjectLink(linkName)) {
715 found |=
start->typelessGetObjectLink(linkName, tmpKey, tmpClid, tmpIndex);
716 tmpKeyVec.push_back(tmpKey);
717 tmpClidVec.push_back(tmpClid);
718 tmpIndexVec.push_back(tmpIndex);
721 for (
size_t tmpi = 0; tmpi < tmpKeyVec.size(); ++tmpi) {
722 bool alreadyAdded =
false;
723 const uint32_t tmpKey = tmpKeyVec.at(tmpi);
724 const uint32_t tmpClid = tmpClidVec.at(tmpi);
726 for (
size_t veci = 0; veci < keyVec.size(); ++veci) {
728 and clidVec.at(veci) == tmpClid
729 and indexVec.at(veci) == tmpIndex)
736 keyVec.push_back( tmpKey );
737 clidVec.push_back( tmpClid );
738 indexVec.push_back( tmpIndex );
739 sourceVec.push_back(
start );
748 const std::string& linkName,
753 const bool suppressMultipleLinksWarning)
755 using namespace msgFindLink;
762 std::vector<sgkey_t> keyVec;
763 std::vector<uint32_t> clidVec;
764 std::vector<Decision::index_type> indexVec;
765 std::vector<const Decision*> sourceVec;
766 std::set<const xAOD::TrigComposite*> fullyExploredFrom;
768 const bool result =
typelessFindLinks(
start, linkName, keyVec, clidVec, indexVec, sourceVec, TrigDefs::lastFeatureOfType, &fullyExploredFrom);
773 if (keyVec.size() > 1 && !suppressMultipleLinksWarning) {
774 ANA_MSG_WARNING (keyVec.size() <<
" typeless links found for " << linkName
775 <<
" returning the first link, consider using findLinks.");
778 clid = clidVec.at(0);
779 index = indexVec.at(0);
786 const std::string& linkName,
791 const bool suppressMultipleLinksWarning)
793 using namespace msgFindLink;
797 std::vector<sgkey_t> keyVec;
798 std::vector<uint32_t> clidVec;
799 std::vector<Decision::index_type> indexVec;
800 std::vector<const Decision*> sourceVec;
801 std::set<const Decision*> fullyExploredFrom;
805 result |=
typelessFindLinks(finalNode, linkName, keyVec, clidVec, indexVec, sourceVec, TrigDefs::lastFeatureOfType, &fullyExploredFrom);
812 if (keyVec.size() > 1 && !suppressMultipleLinksWarning) {
813 ANA_MSG_WARNING (keyVec.size() <<
" typeless links found for " << linkName
814 <<
" returning the first link, consider using findLinks.");
817 clid = clidVec.at(0);
818 index = indexVec.at(0);
827 const std::vector<std::size_t>& legMultiplicities,
832 if (legMultiplicities.size() == 1)
835 for (std::size_t legIdx = 0; legIdx < legMultiplicities.size(); ++legIdx)
838 if (legMultiplicities[legIdx] == 0)
841 std::vector<LinkInfo<xAOD::IParticleContainer>> legFeatures;
844 legFeatures.push_back(
info);
846 combinations.addLeg(legMultiplicities.at(legIdx), std::move(legFeatures));
855 const std::vector<std::size_t>& legMultiplicities,
882 ret += printerFnc( tc );
886 ret +=
" -> " +
dump( *seedEL, printerFnc );