5#include <boost/functional/hash.hpp>
6#include <GaudiKernel/StatusCode.h>
7#include "AthLinks/ElementLinkVector.h"
33 if ( c->isChild(other) )
43 if ( c->isParent(other) )
69 runChains.insert(other->runChains.begin(), other->runChains.end());
70 passChains.insert(other->passChains.begin(), other->passChains.end());
71 teIDs.push_back(other->te->getId());
87 auto add = [](
ConvProxy *toadd, std::set<ConvProxy *> &coll)
89 if (std::find(coll.begin(), coll.end(), toadd) == coll.end())
95 auto remove = [](
ConvProxy *torem, std::set<ConvProxy *> &coll)
97 auto place = std::find(coll.begin(), coll.end(), torem);
98 if (place != coll.end())
105 for (
auto otherChild : other->children)
108 add(
this, otherChild->parents);
111 for (
auto otherParent : other->parents)
114 add(
this, otherParent->children);
118 for (
auto otherParent : other->parents)
120 remove(other, otherParent->children);
123 for (
auto otherChild : other->children)
125 remove(other, otherChild->parents);
127 other->children.clear();
128 other->parents.clear();
134 ret +=
" N parents: " + std::to_string(
parents.size());
135 ret +=
" N children: " + std::to_string(
children.size());
136 std::ostringstream os;
139 ret +=
" ptrs: " + os.str();
140 ret +=
" feaHash: " + std::to_string(
feaHash);
141 ret +=
" N run chains: " + std::to_string(
runChains.size());
161 ATH_MSG_INFO(
"Will use Trigger Navigation from TrigDecisionTool");
166 ATH_MSG_INFO(
"Will use Trigger Navigation decoded from TrigNavigation object");
182 std::string typeName = name;
183 std::string collName;
184 size_t delimeterIndex = name.find(
'#');
185 if (delimeterIndex != std::string::npos)
187 typeName = name.substr(0, delimeterIndex);
188 collName = name.substr(delimeterIndex + 1);
192 ATH_MSG_DEBUG(
"Will be linking collection type " << typeName <<
" name (empty==all) " << collName);
193 if ( collName.empty() )
207 if (!keysSet.empty() and keysSet.contains(
""))
209 ATH_MSG_ERROR(
"Bad configuration for CLID " << clid <<
" requested saving of all (empty coll name configures) collections, yet there are also specific keys");
210 return StatusCode::FAILURE;
215 bool anyChainBad=
false;
217 if ( chain.contains(
'*') or chain.contains(
'|')) {
218 ATH_MSG_ERROR(
"Supplied chain name: " << chain <<
" contains wildcard characters, this is not supported by the conversion tool");
223 ATH_MSG_ERROR(
"Supplied chain names contain wildcard characters, this is not supported by the conversion tool");
224 return StatusCode::FAILURE;
227 ATH_MSG_INFO(
"No chains list supplied, the conversion will occur for all chains");
245 return StatusCode::SUCCESS;
250 return StatusCode::SUCCESS;
270 bool ok = standaloneNav.
deserialize(navReadHandle->serialized());
273 return StatusCode::FAILURE;
275 run2NavigationPtr = &standaloneNav;
279 run2NavigationPtr =
m_tdt->ExperimentalAndExpertMethods().getNavigation();
303 ATH_MSG_DEBUG(
"Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
318 auto decisionOutput = outputNavigation.
ptr();
341 ATH_MSG_DEBUG(
"Conversion done, from " << convProxies.size() <<
" elements to " << decisionOutput->size() <<
" elements");
347 for (
auto o: *decisionOutput) {
353 for (
auto proxy : convProxies)
358 return StatusCode::SUCCESS;
372 size_t stepToConsider = 0;
373 const size_t sigsSize = ptrChain->
signatures().size();
374 if ( sigsSize < 2 )
return 0;
375 for (
size_t step = sigsSize-1; step > 1; step --) {
376 if ( (ptrChain->
signatures()[step-1])->outputTEs().size() == 2 and (ptrChain->
signatures()[step])->outputTEs().size() == 1 ) {
377 stepToConsider = step;
381 if ( stepToConsider == 0 )
return 0;
384 auto finalTE = (ptrChain->
signatures()[stepToConsider])->outputTEs()[0];
385 auto preFinalTEs = (ptrChain->
signatures()[stepToConsider-1])->outputTEs();
387 auto finalSeq =
m_configSvc->sequences().getSequence(finalTE->id());
388 std::set<HLT::te_id_type> tesInSeq;
389 std::set<HLT::te_id_type> tesInChain;
391 for (
auto te: finalSeq->inputTEs()) {
392 tesInSeq.insert(te->id());
395 for (
auto te: preFinalTEs) {
396 tesInChain.insert(te->id());
399 if (tesInSeq == tesInChain) {
400 return stepToConsider;
413 std::string chainName = ptrChain->name();
431 std::map<HLT::te_id_type, HLT::te_id_type> etcutReplacementTEs;
432 auto etcutReplacement = [&etcutReplacementTEs](
HLT::te_id_type in) {
auto out = etcutReplacementTEs.find(in);
return (out == etcutReplacementTEs.end() ? in : out->second ); };
433 if ( chainName.find(
"etcut") != std::string::npos ) {
434 std::set<size_t> positionsOfEtCutLegs;
437 ATH_MSG_DEBUG(
"EtCut chains hack, chain with two etcut legs ");
438 positionsOfEtCutLegs.insert({0, 1});
440 ATH_MSG_DEBUG(
"EtCut chains hack, egamma chain with second etcut leg ");
441 positionsOfEtCutLegs.insert({1});
444 positionsOfEtCutLegs.insert({0});
448 std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
449 for (
auto ptrHLTSignature : ptrChain->signatures()) {
451 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
452 if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
453 etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
456 if ( ptrHLTTE->name().find(
"calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) {
457 positionToDesiredIDmap[position] = ptrHLTTE->id();
467 ATH_MSG_DEBUG(
" CHAIN name " << chainName <<
" CHAIN Id " << chainId);
468 for (
auto ptrHLTSignature : ptrChain->signatures()) {
469 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
470 unsigned int teId = etcutReplacement(ptrHLTTE->id());
471 allTEs[teId].insert(chainId);
472 if (ptrHLTSignature == ptrChain->signatures().back()) {
473 finalTEs[teId].insert(chainId);
474 ATH_MSG_DEBUG(
"TE will be used to mark final chain decision " << ptrHLTTE->name() <<
" chain " << chainName );
483 multiplicities={1,1};
485 if ( multiplicities.size() > 1 ) {
500 std::vector<size_t> mult_hack(multiplicities.begin(), multiplicities.end());
501 ptrChain->set_leg_multiplicities(mult_hack);
506 std::vector<size_t> mult_hack;
507 if (multiplicities.size()==3) mult_hack={1,1};
508 else if (multiplicities.size()==2) mult_hack={2};
509 ptrChain->set_leg_multiplicities(mult_hack);
510 multiplicities.assign(mult_hack.begin(), mult_hack.end());
513 ATH_MSG_DEBUG(
"CHAIN " << chainName <<
" needs legs: " << multiplicities );
515 if ( multiplicities.size() <= 1 ) {
516 ATH_MSG_DEBUG(
"Chain " << chainName <<
" has a single effective leg after special-case handling - no leg IDs assigned");
527 std::vector<std::string> legTokens;
528 bool legTokensUsable =
true;
530 if (legInfo.signature.empty() || legInfo.threshold < 0) {
531 legTokensUsable =
false;
534 legTokens.push_back(legInfo.signature + std::to_string(legInfo.threshold));
536 if (legTokens.size() > multiplicities.size()) {
538 legTokens.resize(multiplicities.size());
540 if (legTokens.size() != multiplicities.size()
541 || std::set<std::string>(legTokens.begin(), legTokens.end()).size() != legTokens.size()) {
544 legTokensUsable =
false;
546 ATH_MSG_DEBUG(
"Semantic leg tokens " << (legTokensUsable ?
"usable" :
"NOT usable") <<
": " << legTokens);
556 if (legInfo.legName().find(
"noL1") != std::string::npos) {
557 noL1Leg = (noL1Leg == -1) ? legIndex : -2;
561 if (noL1Leg == -2) noL1Leg = -1;
567 const size_t nLegs = multiplicities.size();
568 auto semanticLeg = [&legTokens, legTokensUsable, noL1Leg, nLegs](
const std::string& teName) ->
int {
569 if (teName.find(
"MultiComb") != std::string::npos)
571 if (legTokensUsable) {
573 for (
size_t l = 0; l < legTokens.size(); ++l) {
574 if (teName.find(legTokens[l]) != std::string::npos) {
575 if (found != -1) { found = -1;
break; }
576 found =
static_cast<int>(l);
579 if (found >= 0)
return found;
582 if (teName.find(
"_FS") != std::string::npos || teName.find(
"FSHypo") != std::string::npos
583 || teName.find(
"FStracks") != std::string::npos) {
596 auto assignLegNumbers = [&semanticLeg, nLegs](
const std::vector<std::string>& teNames) {
597 const size_t n = teNames.size();
598 std::vector<int> legOf(n, -1);
599 std::vector<bool> legUsed(nLegs,
false);
602 for (
size_t pos = 0; pos < n; ++pos) {
603 const int l = semanticLeg(teNames[pos]);
604 if (l >= 0 && l <
static_cast<int>(nLegs) && !legUsed[l]) {
613 for (
size_t pos = 0; pos < n; ++pos) {
614 if (legOf[pos] != -1)
continue;
615 while (nextFree < nLegs && legUsed[nextFree]) ++nextFree;
616 if (nextFree >= nLegs)
break;
617 legOf[pos] =
static_cast<int>(nextFree);
618 legUsed[nextFree] =
true;
625 std::map<int, unsigned int> lastTEofLeg;
627 for (
auto ptrHLTSignature : ptrChain->signatures())
629 std::vector<int> teCounts;
630 std::vector<unsigned int> teIds;
631 std::vector<std::string> teNames;
632 unsigned int lastSeenId = 0;
633 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs())
635 if ( lastSeenId != ptrHLTTE->id()) {
636 teCounts.push_back(1);
637 teIds.push_back(ptrHLTTE->id());
638 teNames.push_back(ptrHLTTE->name());
642 lastSeenId = ptrHLTTE->id();
645 ATH_MSG_DEBUG(
"TE multiplicities seen in this step " << teCounts <<
" TEs: " << teNames);
646 bool multiplicityCounts = multiplicities == teCounts;
649 if ( multiplicityCounts ) {
650 const std::vector<int> legOf = assignLegNumbers(teNames);
651 ATH_MSG_DEBUG(
"There is a match, will assign chain leg IDs to TEs " << teCounts <<
" " << teIds);
652 for (
size_t pos = 0; pos < teIds.size(); ++ pos){
653 if (legOf[pos] < 0)
continue;
655 ATH_MSG_DEBUG(
" TE " << teNames[pos] <<
" -> " << chainLegId);
656 allTEs[etcutReplacement(teIds[pos])].insert(chainLegId);
657 lastTEofLeg[legOf[pos]] = teIds[pos];
664 for (
size_t pos = 0; pos < teIds.size(); ++ pos){
665 const int leg = semanticLeg(teNames[pos]);
666 if (leg < 0)
continue;
668 ATH_MSG_DEBUG(
" (irregular step) TE " << teNames[pos] <<
" -> " << chainLegId);
669 allTEs[etcutReplacement(teIds[pos])].insert(chainLegId);
670 lastTEofLeg[leg] = teIds[pos];
674 for (
const auto& [legNumber, teId] : lastTEofLeg) {
676 ATH_MSG_DEBUG(
"created leg id " << chainLegId <<
" that will replace TE ID " << etcutReplacement(teId));
677 finalTEs[etcutReplacement(teId)].insert(chainLegId);
682 ATH_MSG_DEBUG(
"Recognised " << allTEs.size() <<
" kinds of TEs and among them " << finalTEs.size() <<
" final types");
683 return StatusCode::SUCCESS;
689 std::vector<unsigned int> muons;
690 std::vector<unsigned int> jets;
691 bool switchedTojets =
false;
692 for (
auto ptrHLTSignature : ptrChain->
signatures()) {
693 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
694 if ( ptrHLTTE->name().find(
"_mu") == std::string::npos ) {
695 switchedTojets =
true;
699 jets.push_back(ptrHLTTE->id());
701 muons.push_back(ptrHLTTE->id());
709 finalTEs[muons[0]].insert(chainId);
711 finalTEs[jets[0]].insert(chainId);
713 for (
size_t index = 0;
index < std::min(muons.size(), jets.size()); ++
index)
716 allTEs[muons[
index]].insert(chainId);
718 allTEs[jets[
index]].insert(chainId);
720 return StatusCode::SUCCESS;
729 std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
737 convProxies.insert(proxy);
738 teToProxy[te] = proxy;
742 ConvProxy *predecessorProxy = teToProxy[predecessor];
743 if (predecessorProxy !=
nullptr)
745 proxy->parents.insert(predecessorProxy);
746 predecessorProxy->
children.insert(proxy);
754 for (
auto proxy : convProxies)
757 ATH_MSG_DEBUG(
"Proxy " << counter <<
" " << proxy->description() <<
"ptr " << proxy);
758 for (
auto p : proxy->children)
760 for (
auto p : proxy->parents)
763 for (
auto p : proxy->parents)
765 for (
auto pp : p->parents)
773 for (
auto c : proxy->children)
775 for (
auto cc : c->children)
786 ATH_MSG_DEBUG(
"Created " << convProxies.size() <<
" proxy objects");
787 return StatusCode::SUCCESS;
792 std::function<
bool(
const ConvProxy*)> selector,
793 const std::vector<std::function<
void(
const ConvProxy*)>>& printers)
const {
796 for (
auto p: proxies) {
799 for (
auto& printer: printers) {
810 for (
auto &ptrConvProxy : convProxies)
812 auto teId = ptrConvProxy->te->getId();
813 bool teActive = ptrConvProxy->te->getActiveState();
814 auto iter = allTEs.find(teId);
815 if (iter != allTEs.end())
817 ptrConvProxy->runChains.insert(iter->second.begin(), iter->second.end());
820 ptrConvProxy->passChains.insert(iter->second.begin(), iter->second.end());
824 for (
auto &objTeIdToChain : allTEs)
826 if (teId == objTeIdToChain.first)
828 for (
auto &chainId : objTeIdToChain.second)
830 (ptrConvProxy->runChains).insert(chainId);
836 return StatusCode::SUCCESS;
849 auto insertFromChild = [](
const ConvProxy& child, std::set<HLT::Identifier>& dest) {
866 size_t numberOfUpdates = 0;
867 for (
auto p : convProxies)
869 for (
auto child : p->children)
871 size_t startSize = p->runChains.size();
872 insertFromChild(*child, p->runChains);
874 if (startSize != p->runChains.size())
878 insertFromChild(*child, p->passChains);
882 ATH_MSG_DEBUG(
"Needed to propagate chains from " << numberOfUpdates <<
" child(ren)");
883 if (numberOfUpdates == 0)
888 return StatusCode::SUCCESS;
894 for (
auto i = std::begin(convProxies); i != std::end(convProxies);)
896 if ((*i)->runChains.empty())
900 for (
auto parent : toDel->
parents)
902 parent->children.erase(toDel);
906 child->parents.erase(toDel);
909 i = convProxies.erase(i);
916 ATH_MSG_DEBUG(
"After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
917 return StatusCode::SUCCESS;
932 return StatusCode::SUCCESS;
935template <
typename MAP>
939 std::vector<ConvProxy *> todelete;
940 for (
auto &[key, proxies] : keyToProxyMap)
942 if (proxies.size() > 1)
944 ATH_MSG_DEBUG(
"Merging " << proxies.size() <<
" similar proxies");
945 for (
auto p : proxies)
947 if (p->mergeAllowed(*proxies.begin()))
949 (*proxies.begin())->merge(p);
950 todelete.push_back(p);
956 for (
auto proxy : todelete)
958 convProxies.erase(proxy);
962 return StatusCode::SUCCESS;
968 const size_t beforeCount = convProxies.size();
969 std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
970 for (
auto proxy : convProxies)
972 proxy->feaHash =
feaToHash(proxy->te->getFeatureAccessHelpers(), proxy->te, run2Nav);
974 feaToProxyMap[proxy->feaHash].insert(proxy);
983 for (
auto [feaHash, proxies] : feaToProxyMap)
985 auto first = *proxies.begin();
986 for (
auto p : proxies)
988 if (
filterFEAs(first->te->getFeatureAccessHelpers(), run2Nav) !=
989 filterFEAs(p->te->getFeatureAccessHelpers(), run2Nav))
991 ATH_MSG_ERROR(
"Proxies grouped by FEA hash have actually distinct features (specific FEAs are different)");
992 for (
auto id: p->passChains )
ATH_MSG_ERROR(
" Chain ID: " <<
id);
994 for (
auto fea: first->te->getFeatureAccessHelpers() ) {
997 for (
auto fea: p->te->getFeatureAccessHelpers() ) {
1001 return StatusCode::FAILURE;
1008 ATH_MSG_DEBUG(
"Proxies with features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
1010 return StatusCode::SUCCESS;
1016 struct ParentChildCharacteristics
1020 size_t distanceFromParent = 0;
1021 bool operator<(
const ParentChildCharacteristics &rhs)
const
1023 if (parent != rhs.parent)
1024 return parent < rhs.parent;
1025 if (child != rhs.child)
1026 return child < rhs.child;
1027 return distanceFromParent < rhs.distanceFromParent;
1030 const size_t beforeCount = convProxies.size();
1031 std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
1032 for (
auto proxy : convProxies)
1036 ATH_MSG_VERBOSE(
"Featureless proxy to deal with: " << proxy->description());
1045 if (proxy->children.size() == 1 and
1046 std::all_of(proxy->children.begin(), proxy->children.end(), hasSomeFeatures ) and
1047 proxy->parents.size() == 1 and
1048 std::all_of(proxy->parents.begin(), proxy->parents.end(), hasSomeFeatures )
1052 groupedProxies[{*(proxy->parents.begin()), *(proxy->children.begin()), 0}].insert(proxy);
1057 ATH_MSG_VERBOSE(
"Featureless proxy in noncanonical situation " << proxy->description());
1059 for (
auto pp : proxy->parents)
1064 for (
auto cp : proxy->children)
1073 ATH_MSG_DEBUG(
"Proxies without features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
1074 return StatusCode::SUCCESS;
1079 for (
auto i = std::begin(convProxies); i != std::end(convProxies);)
1081 if ((*i)->parents.size() > 1)
1085 for (
auto parent : toDel->
parents)
1087 parent->children.erase(toDel);
1091 child->parents.erase(toDel);
1094 i = convProxies.erase(i);
1101 return StatusCode::SUCCESS;
1107 for (
auto &proxy : convProxies)
1109 if (proxy->te !=
nullptr)
1120 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, helper);
1126 if (expectedCLID != 0 && sgCLID != expectedCLID)
1128 ATH_MSG_VERBOSE(
"Skipping feature with CLID " << sgCLID <<
" (name: " << sgName
1129 <<
") for TE " << teName <<
" because expected CLID is " << expectedCLID);
1132 proxy->features.push_back(helper);
1133 ATH_MSG_VERBOSE(
"Added feature with CLID " << sgCLID <<
" (name: " << sgName <<
") for TE " << teName);
1140 return StatusCode::SUCCESS;
1147 auto ordered_sorter = [&setRoiName = std::as_const(
m_setRoiName)](
const std::string &left,
const std::string &right) ->
bool
1149 return std::find(cbegin(setRoiName), cend(setRoiName), left) < std::find(cbegin(setRoiName), cend(setRoiName), right);
1154 for (
auto &proxy : convProxies)
1158 ATH_MSG_DEBUG(
"Several RoIs pointing to a proxy, taking latest one for now");
1164 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, helper);
1170 mp[sgName] = helper;
1173 std::transform(cbegin(mp), cend(mp), back_inserter(proxy->rois),
1174 [](
const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &p)
1175 { return p.second; });
1179 std::set<const ConvProxy*> visited;
1180 std::function<void(std::set<ConvProxy *> &,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &)>
1181 roiPropagator = [&](std::set<ConvProxy *> &convProxyChildren,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &roiParent)
1183 for (
auto &proxyChild : convProxyChildren)
1185 if ( visited.count(proxyChild) == 1 ) {
1188 visited.insert(proxyChild);
1189 if (proxyChild->rois.empty())
1191 proxyChild->rois = roiParent;
1192 if (proxyChild->children.empty() ==
false)
1194 roiPropagator(proxyChild->children, roiParent);
1200 for (
auto &proxy : convProxies)
1202 roiPropagator(proxy->children, proxy->rois);
1205 return StatusCode::SUCCESS;
1210 for (
auto &proxy : convProxies)
1216 proxy->tracks.push_back(helper);
1221 return StatusCode::SUCCESS;
1235 std::set<HLT::Identifier> chainsWithLegs;
1249 for (
auto &proxy : convProxies)
1252 addNodeIDs(proxy->runChains, proxy->imNode);
1254 addNodeIDs(proxy->passChains, proxy->hNode.back());
1259 for (
auto &proxy : convProxies)
1261 for (
auto &parentProxy : proxy->parents)
1266 ATH_MSG_DEBUG(
"IM & H nodes made, output nav elements " << decisions.size());
1267 return StatusCode::SUCCESS;
1277 sfNode->setName(
"SF");
1280 for (
auto chainId : chainIds)
1287 else if (chainId.numeric() == idStore)
1297 if (proxy->hNode.empty())
1300 makeSingleSFNode(proxy->imNode, proxy->runChains, idToStore);
1305 for (
auto &hNode : proxy->hNode)
1307 makeSingleSFNode(hNode, proxy->passChains, idToStore);
1312 for (
auto proxy : convProxies)
1315 if (proxy->children.empty())
1323 std::vector<TCU::DecisionID> toRetain;
1324 for (
auto teId : proxy->teIDs)
1326 auto whereInMap = terminalIds.find(teId);
1327 if (whereInMap != terminalIds.end())
1329 toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1332 for (
auto chainIdstore : toRetain)
1334 makeSFNodes(proxy, chainIdstore);
1340 ATH_MSG_DEBUG(
"SF nodes made, output nav elements " << decisions.size());
1341 return StatusCode::SUCCESS;
1362 ATH_MSG_ERROR(
"Navigation information for chain " << chainName <<
" in "
1364 return StatusCode::FAILURE;
1369 filteredIDs.insert(idToCheck);
1372 terminus->
setDecisions( std::vector<TCU::DecisionID>() );
1375 "the terminus node goes from " << currentIDs.size() <<
" to " << filteredIDs.size() <<
" chain IDs.");
1376 if (
msgLvl(MSG::VERBOSE))
1383 return StatusCode::SUCCESS;
1387 const EventContext &context)
const
1390 auto makeL1Node = [&decisions, &context](
auto firstDecisionNode,
auto chainIds)
1394 for (
auto chainId : chainIds)
1403 for (
auto &proxy : convProxies)
1406 if (proxy->parents.empty())
1408 proxy->l1Node = makeL1Node(proxy->imNode,
TCU::decisionIDs(proxy->imNode));
1413 return StatusCode::SUCCESS;
1419 if (proxy.features.empty())
1423 for (
const auto &fea : proxy.features)
1425 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1429 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1441 for (
const auto &proxy : convProxies)
1451 for (
auto chainId : proxy->passChains)
1458 for (
auto &childProxy : proxy->children)
1465 if (proxy->features.empty())
1471 auto hNodeIter = proxy->hNode.begin();
1472 for (std::size_t feaIdx = 0; feaIdx < proxy->features.size(); ++feaIdx)
1474 auto &fea = proxy->features[feaIdx];
1475 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1477 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1483 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1486 const std::string& linkName = (feaIdx == bestFeaIdx && n == bestObjIdx) ?
1488 (*hNodeIter)->typelessSetObjectLink(linkName, sgKey, sgCLID, n, n + 1);
1494 return StatusCode::SUCCESS;
1500 for (
auto &proxy : convProxies)
1502 for (
auto &roi : proxy->rois)
1504 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1509 if (proxy->rois.empty() ==
false)
1516 return StatusCode::SUCCESS;
1521 for (
auto &proxy : convProxies)
1523 for (
auto &trk : proxy->tracks)
1533 const auto & [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, trk);
1537 const std::string tNameStr{tName};
1538 auto d = std::make_unique<TrigCompositeUtils::Decision>();
1539 d->makePrivateStore();
1540 d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1545 if (track.isValid())
1548 viewBookkeeper(*t) = ROIElementLink;
1556 if (track.isValid())
1559 viewBookkeeper(*t) = ROIElementLink;
1566 ATH_MSG_WARNING(
"Unable to create an ElementLink into a container with no entries");
1572 return StatusCode::SUCCESS;
1581 return fea.
getCLID() == thePassBitsCLID or fea.
getCLID() == thePassBitsContCLID;
1585 std::vector<HLT::TriggerElement::FeatureAccessHelper> out;
1586 for (
auto fea : feaVector)
1594 auto [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1598 ATH_MSG_VERBOSE(
"Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName <<
" FEA " << fea);
1613 ATH_MSG_VERBOSE(
"Calculating FEA hash for TE " << teName <<
" expecting CLID " << expectedCLID);
1615 for (
auto fea :
filterFEAs(feaVector, navigationDecoder))
1617 const auto & [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1620 if (expectedCLID != 0 && sgCLID != expectedCLID)
1622 ATH_MSG_VERBOSE(
"Skipping FEA with CLID " << sgCLID <<
" for TE " << teName
1623 <<
" (expected " << expectedCLID <<
")");
1627 ATH_MSG_VERBOSE(
"Including FEA in hash CLID: " << fea.getCLID() <<
" te Id: " << te_ptr->
getId());
1628 boost::hash_combine(hash, fea.getCLID());
1629 boost::hash_combine(hash, fea.getIndex().subTypeIndex());
1630 boost::hash_combine(hash, fea.getIndex().objectsBegin());
1631 boost::hash_combine(hash, fea.getIndex().objectsEnd());
1638 boost::hash_combine(hash, te_ptr->
getId());
1639 boost::hash_combine(hash,
reinterpret_cast<std::uintptr_t
>(te_ptr));
1649 if ( iter->second.empty() )
1651 ATH_MSG_DEBUG(
"fea to save CLID: " << fea.
getCLID() <<
", sgName: " << sgName <<
" " <<iter->second.size() <<
" " << iter->second.empty() );
1652 return iter->second.contains(sgName);
1662 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1673 for (
auto p : proxies)
1675 if (p->runChains.empty())
1678 return StatusCode::FAILURE;
1682 return StatusCode::SUCCESS;
1687 for (
auto p : proxies)
1689 if (p->children.empty() and p->parents.empty() and not p->runChains.empty())
1691 ATH_MSG_ERROR(
"Orphaned proxy, N chains run: " << p->runChains.size());
1692 return StatusCode::FAILURE;
1696 return StatusCode::SUCCESS;
1701 ATH_MSG_DEBUG(
"CHECK OK, no excessive number of H nodes per proxy");
1702 return StatusCode::SUCCESS;
1708 std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1709 for (
auto d : decisions)
1711 if (d->name() ==
"IM" or d->name() ==
"FS")
1715 linkedHNodes.insert(*el);
1719 for (
auto d : decisions)
1721 if (d->name() ==
"H")
1723 if (linkedHNodes.count(d) == 0)
1726 return StatusCode::FAILURE;
1732 return StatusCode::SUCCESS;
1737 const std::string hltLabel = navigationDecoder.
label(helper.getCLID(), helper.getIndex().subTypeIndex());
1739 const CLID saveCLID = [&](
const CLID &clid)
1748 }(helper.getCLID());
1750 std::string type_name;
1751 if (
m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1757 const bool isAvailable =
evtStore()->contains(saveCLID, sgStringKey);
1758 ATH_MSG_DEBUG(
" Objects presence " << helper <<
" " << sgStringKey << (isAvailable ?
" present" :
" absent"));
1761 return {0, saveCLID,
""};
1764 return {
evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel};
1770 std::size_t bestFea = std::numeric_limits<std::size_t>::max();
1771 std::size_t bestObj = 0;
1772 float bestPt = -1.0;
1774 for (std::size_t i = 0; i < proxy.features.size(); ++i) {
1775 const auto& fea = proxy.features[i];
1776 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1780 if (sgKey == 0)
continue;
1781 const std::string* keyStr =
evtStore()->keyToString(sgKey, sgCLID);
1782 if (!keyStr)
continue;
1784 if (
evtStore()->retrieve(cont, *keyStr).isFailure())
continue;
1785 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n) {
1786 if (n >= cont->
size())
continue;
1789 if (p->pt() > bestPt) {
1796 if (bestFea == std::numeric_limits<std::size_t>::max()) {
1797 for (std::size_t i = 0; i < proxy.features.size(); ++i) {
1798 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, proxy.features[i]);
1799 if (!
feaToSave(proxy.features[i], sgName))
continue;
1801 bestObj = proxy.features[i].getIndex().objectsBegin();
1805 return {bestFea, bestObj};
1815 if (teName.find(
"etcut") != std::string::npos &&
1816 teName.find(
"trkcut") == std::string::npos) {
1820 else if (teName.rfind(
"EF_e", 0) == 0) {
1824 else if (teName.rfind(
"EF_g", 0) == 0) {
1828 else if (teName.rfind(
"EF_mu", 0) == 0 || teName.find(
"_mu") != std::string::npos) {
1832 else if (teName.rfind(
"EF_tau", 0) == 0 || teName.find(
"_tau") != std::string::npos) {
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
uint32_t CLID
The Class ID type.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
bool feaToSkip(const HLT::TriggerElement::FeatureAccessHelper &fea)
std::map< HLT::te_id_type, std::set< HLT::Identifier > > TEIdToChainsMap_t
std::set< ConvProxy * > ConvProxySet_t
ServiceHandle< StoreGateSvc > & evtStore()
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
Helper class that provides access to information about individual legs.
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
bool isValid() const
Check if the element can be found.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
std::string name() const
reports human redable name
virtual bool deserialize(const std::vector< uint32_t > &input)
static bool isInitialNode(const TriggerElement *te)
queries if node is an initial one
std::vector< TriggerElement * > & getAllTEs()
access needed by slimming tools.
static const std::vector< TriggerElement * > & getRoINodes(const TriggerElement *somenode)
gets all RoI type nodes seeding indirectly this TriggerElement
static const std::vector< TriggerElement * > & getDirectPredecessors(const TriggerElement *te)
returns list of direct predecessors (nodes seeding me)
std::string label(class_id_type clid, const index_or_label_type &sti_or_label) const
the FeatureAccessHelper is a class used to keep track of features attached to this TE.
class_id_type getCLID() const
Class ID of object.
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
te_id_type getId() const
reset internals.
StatusCode createIMHNodes(ConvProxySet_t &, xAOD::TrigCompositeContainer &, const EventContext &) const
Gaudi::Property< bool > m_doLinkFeatures
StatusCode linkRoiNode(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
std::vector< std::string > m_setRoiName
Gaudi::Property< std::vector< std::string > > m_chainsToSave
virtual ~Run2ToRun3TrigNavConverterV2() override
CLID m_CaloClusterContainerCLID
std::function< void(const ConvProxy *)> m_teIDPrinter
PublicToolHandle< Trig::TrigDecisionTool > m_tdt
StatusCode extractTECtoChainMapping(TEIdToChainsMap_t &allTES, TEIdToChainsMap_t &finalTEs) const
Gaudi::Property< std::vector< std::string > > m_roisToSave
StatusCode collapseFeaturesProxies(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
virtual StatusCode execute(const EventContext &context) const override
ServiceHandle< IClassIDSvc > m_clidSvc
Gaudi::Property< bool > m_doCompression
StatusCode cureUnassociatedProxies(ConvProxySet_t &) const
StatusCode updateTerminusNode(xAOD::TrigCompositeContainer &, const EventContext &context) const
CLID m_TrigRingerRingsCLID
StatusCode mirrorTEsStructure(ConvProxySet_t &, const HLT::TrigNavStructure &run2Nav) const
StatusCode createSFNodes(const ConvProxySet_t &, xAOD::TrigCompositeContainer &, const TEIdToChainsMap_t &finalTEs, const EventContext &context) const
StatusCode removeTopologicalProxies(ConvProxySet_t &) const
CLID m_TrigEMClusterContainerCLID
SG::ReadHandleKey< xAOD::TrigNavigation > m_trigNavKey
CLID m_TauJetContainerCLID
Run2ToRun3TrigNavConverterV2(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode removeUnassociatedProxies(ConvProxySet_t &) const
StatusCode linkFeaNode(ConvProxySet_t &convProxies, xAOD::TrigCompositeContainer &, const HLT::TrigNavStructure &run2Nav, const EventContext &context) const
StatusCode associateChainsToProxies(ConvProxySet_t &, const TEIdToChainsMap_t &) const
CLID getExpectedParticleCLID(const std::string &teName) const
Helper function to determine expected particle CLID based on TE name Returns 0 if no specific type is...
CLID m_TauTrackContainerCLID
StatusCode bjetMuChainConfigDecoder(TEIdToChainsMap_t &allTES, TEIdToChainsMap_t &finalTEs, const TrigConf::HLTChain *ptrChain) const
std::pair< std::size_t, std::size_t > getHighestPtObject(const ConvProxy &, const HLT::TrigNavStructure &) const
Return pair of indices (feature index in proxy->features vector, object index) identifying the highes...
StatusCode noUnconnectedHNodes(const xAOD::TrigCompositeContainer &) const
bool feaToSave(const HLT::TriggerElement::FeatureAccessHelper &fea, const std::string &sgName) const
uint64_t feaToHash(const std::vector< HLT::TriggerElement::FeatureAccessHelper > &feaVector, const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder) const
returns true if this particular feature is to be saved (linked)
size_t is2LegTopoChain(const TrigConf::HLTChain *ptrChain) const
bool roiToSave(const HLT::TrigNavStructure &run2Nav, const HLT::TriggerElement::FeatureAccessHelper &fea) const
Gaudi::Property< bool > m_doSelfValidation
StatusCode doCompression(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
StatusCode linkTrkNode(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
StatusCode numberOfHNodesPerProxyNotExcessive(const ConvProxySet_t &) const
virtual StatusCode finalize() override
void printProxies(const ConvProxySet_t &proxies, std::function< bool(const ConvProxy *)> selector=[](const ConvProxy *){return true;}, const std::vector< std::function< void(const ConvProxy *)> > &printers={}) const
CLID m_TrackParticleContainerCLID
StatusCode fillRelevantTracks(ConvProxySet_t &convProxies) const
CLID m_roIDescriptorCollectionCLID
CLID m_ElectronContainerCLID
Gaudi::Property< bool > m_includeTauTrackFeatures
TEIdToChainsMap_t m_allTEIdsToChains
std::tuple< uint32_t, CLID, std::string > getSgKey(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper) const
StatusCode fillRelevantRois(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
StatusCode allProxiesHaveChain(const ConvProxySet_t &) const
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_trigOutputNavKey
StatusCode createL1Nodes(const ConvProxySet_t &convProxies, xAOD::TrigCompositeContainer &decisions, const EventContext &context) const
Gaudi::Property< std::vector< std::string > > m_collectionsToSave
std::function< void(const ConvProxy *)> m_chainIdsPrinter
std::map< CLID, std::set< std::string > > m_collectionsToSaveDecoded
CLID m_TrigRingerRingsContainerCLID
StatusCode fillRelevantFeatures(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
TEIdToChainsMap_t m_finalTEIdsToChains
std::size_t getFeaSize(const ConvProxy &) const
virtual StatusCode initialize() override
CLID m_PhotonContainerCLID
std::mutex m_configUpdateMutex
StatusCode collapseFeaturelessProxies(ConvProxySet_t &) const
ServiceHandle< TrigConf::IHLTConfigSvc > m_configSvc
StatusCode allProxiesConnected(const ConvProxySet_t &) const
StatusCode collapseProxies(ConvProxySet_t &, MAP &) const
std::vector< HLT::TriggerElement::FeatureAccessHelper > filterFEAs(const std::vector< HLT::TriggerElement::FeatureAccessHelper > &feaVector, const HLT::TrigNavStructure &navigationDecoder) const
< both method skip TrigPassBits
Exception — ForwardIndexingPolicy: internal link state is invalid.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
Dereference the pointer.
HLT chain configuration information.
const std::vector< HLTSignature * > & signatures() const
static const std::string hash2string(HLTHash, const std::string &category=s_defaultCategory)
hash function translating identifiers into names (via internal dictionary)
const std::string & name() const
Class providing the definition of the 4-vector interface.
void setDecisions(const std::vector< TrigCompositeUtils::DecisionID > &decisions)
Set positive HLT chain decisions associated with this TrigComposite. Navigation use.
const std::string & name() const
Get a human-readable name for the object.
bool add(const std::string &hname, TKey *tobj)
std::vector< int > multiplicities(const std::string &chain)
std::string formatSGkey(const std::string &prefix, const std::string &containername, const std::string &label)
declaration of formatting function.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
const std::regex gammaXeChain
const std::regex egammaDiEtcut
const std::regex egammaCombinedWithEtcut
const std::regex egammaEtcut
const std::regex bjetMuChain
const std::regex mu2MunoL1Special
const std::regex tauXeChain
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
const std::string & inputMakerNodeName()
xAOD::TrigComposite Decision
void insertDecisionIDs(const Decision *src, Decision *dest)
Appends the decision IDs of src to the dest decision object.
const std::string & roiString()
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name)
Helper method to create a Decision object, place it in the container and return a pointer to it.
const std::vector< ElementLink< DecisionContainer > > getLinkToPrevious(const Decision *d)
returns links to previous decision object 'seed'
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.
std::set< DecisionID > DecisionIDContainer
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
const std::string & hypoAlgNodeName()
void linkToPrevious(Decision *d, const std::string &previousCollectionKey, size_t previousIndex)
Links to the previous object, location of previous 'seed' decision supplied by hand.
const std::string & initialRoIString()
const std::string & summaryPassNodeName()
void addDecisionID(DecisionID id, Decision *d)
Appends the decision (given as ID) to the decision object.
const std::string & hltSeedingNodeName()
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
ElementLink< DecisionContainer > decisionToElementLink(const Decision *d, const EventContext &ctx)
Takes a raw pointer to a Decision and returns an ElementLink to the Decision.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
static const unsigned int allowResurrectedDecision
static const unsigned int Physics
void reverse(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of reverse for DataVector/List.
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
TauTrackContainer_v1 TauTrackContainer
Definition of the current TauTrack container version.
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
Struct containing information on each leg of a chain.
static constexpr CLID ID()
std::set< ConvProxy * > children
std::vector< HLT::te_id_type > teIDs
static const uint64_t MissingFEA
bool mergeAllowed(const ConvProxy *other) const
std::set< HLT::Identifier > runChains
std::set< HLT::Identifier > passChains
std::set< ConvProxy * > parents
const HLT::TriggerElement * te
bool isParent(const ConvProxy *other) const
bool isChild(const ConvProxy *other) const
void merge(ConvProxy *other)
ConvProxy(const HLT::TriggerElement *te)
std::string description() const