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.size() > 1 and keysSet.count(
"") != 0)
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.find(
'*') != std::string::npos or chain.find(
'|') != std::string::npos ) {
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 standaloneNav.
deserialize(navReadHandle->serialized());
271 run2NavigationPtr = &standaloneNav;
275 run2NavigationPtr =
m_tdt->ExperimentalAndExpertMethods().getNavigation();
299 ATH_MSG_DEBUG(
"Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
314 auto decisionOutput = outputNavigation.
ptr();
337 ATH_MSG_DEBUG(
"Conversion done, from " << convProxies.size() <<
" elements to " << decisionOutput->size() <<
" elements");
343 for (
auto o: *decisionOutput) {
349 for (
auto proxy : convProxies)
354 return StatusCode::SUCCESS;
368 size_t stepToConsider = 0;
369 const size_t sigsSize = ptrChain->
signatures().size();
370 if ( sigsSize < 2 )
return 0;
371 for (
size_t step = sigsSize-1; step > 1; step --) {
372 if ( (ptrChain->
signatures()[step-1])->outputTEs().size() == 2 and (ptrChain->
signatures()[step])->outputTEs().size() == 1 ) {
373 stepToConsider = step;
377 if ( stepToConsider == 0 )
return 0;
380 auto finalTE = (ptrChain->
signatures()[stepToConsider])->outputTEs()[0];
381 auto preFinalTEs = (ptrChain->
signatures()[stepToConsider-1])->outputTEs();
383 auto finalSeq =
m_configSvc->sequences().getSequence(finalTE->id());
384 std::set<HLT::te_id_type> tesInSeq;
385 std::set<HLT::te_id_type> tesInChain;
387 for (
auto te: finalSeq->inputTEs()) {
388 tesInSeq.insert(te->id());
391 for (
auto te: preFinalTEs) {
392 tesInChain.insert(te->id());
395 if (tesInSeq == tesInChain) {
396 return stepToConsider;
409 std::string chainName = ptrChain->name();
427 std::map<HLT::te_id_type, HLT::te_id_type> etcutReplacementTEs;
428 auto etcutReplacement = [&etcutReplacementTEs](
HLT::te_id_type in) {
auto out = etcutReplacementTEs.find(in);
return (out == etcutReplacementTEs.end() ? in : out->second ); };
429 if ( chainName.find(
"etcut") != std::string::npos ) {
430 std::set<size_t> positionsOfEtCutLegs;
433 ATH_MSG_DEBUG(
"EtCut chains hack, chain with two etcut legs ");
434 positionsOfEtCutLegs.insert({0, 1});
436 ATH_MSG_DEBUG(
"EtCut chains hack, egamma chain with second etcut leg ");
437 positionsOfEtCutLegs.insert({1});
440 positionsOfEtCutLegs.insert({0});
444 std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
445 for (
auto ptrHLTSignature : ptrChain->signatures()) {
447 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
448 if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
449 etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
452 if ( ptrHLTTE->name().find(
"calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) {
453 positionToDesiredIDmap[position] = ptrHLTTE->id();
463 ATH_MSG_DEBUG(
" CHAIN name " << chainName <<
" CHAIN Id " << chainId);
464 for (
auto ptrHLTSignature : ptrChain->signatures()) {
465 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
466 unsigned int teId = etcutReplacement(ptrHLTTE->id());
467 allTEs[teId].insert(chainId);
468 if (ptrHLTSignature == ptrChain->signatures().back()) {
469 finalTEs[teId].insert(chainId);
470 ATH_MSG_DEBUG(
"TE will be used to mark final chain decision " << ptrHLTTE->name() <<
" chain " << chainName );
479 multiplicities={1,1};
481 if ( multiplicities.size() > 1 ) {
489 std::vector<size_t> mult_hack;
490 if (multiplicities.size()==3) mult_hack={1,1};
491 else if (multiplicities.size()==2) mult_hack={1};
492 ptrChain->set_leg_multiplicities(mult_hack);
497 std::vector<size_t> mult_hack;
498 if (multiplicities.size()==3) mult_hack={1,1};
499 else if (multiplicities.size()==2) mult_hack={2};
500 ptrChain->set_leg_multiplicities(mult_hack);
503 ATH_MSG_DEBUG(
"CHAIN " << chainName <<
" needs legs: " << multiplicities );
504 std::vector<unsigned int> teIdsLastHealthyStepIds;
506 for (
auto ptrHLTSignature : ptrChain->signatures())
508 std::vector<int> teCounts;
509 std::vector<unsigned int> teIds;
510 unsigned int lastSeenId = 0;
511 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs())
513 if ( lastSeenId != ptrHLTTE->id()) {
514 teCounts.push_back(1);
515 teIds.push_back(ptrHLTTE->id());
519 lastSeenId = ptrHLTTE->id();
522 ATH_MSG_DEBUG(
"TE multiplicities seen in this step " << teCounts);
523 bool multiplicityCounts = multiplicities == teCounts;
526 if ( multiplicityCounts ) {
527 teIdsLastHealthyStepIds = teIds;
528 ATH_MSG_DEBUG(
"There is a match, will assign chain leg IDs to TEs " << teCounts <<
" " << teIds);
529 for (
size_t legNumber = 0; legNumber < teIds.size(); ++ legNumber){
531 allTEs[etcutReplacement(teIds[legNumber])].insert(chainLegId);
535 for (
size_t legNumber = 0; legNumber < teIdsLastHealthyStepIds.size(); ++ legNumber ) {
538 ATH_MSG_DEBUG(
"created leg id " << chainLegId <<
" that will replace TE ID " << etcutReplacement(teIdsLastHealthyStepIds[legNumber]));
539 finalTEs[etcutReplacement(teIdsLastHealthyStepIds[legNumber])].insert(chainLegId);
543 ATH_MSG_DEBUG(
"Recognised " << allTEs.size() <<
" kinds of TEs and among them " << finalTEs.size() <<
" final types");
544 return StatusCode::SUCCESS;
550 std::vector<unsigned int> muons;
551 std::vector<unsigned int> jets;
552 bool switchedTojets =
false;
553 for (
auto ptrHLTSignature : ptrChain->
signatures()) {
554 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
555 if ( ptrHLTTE->name().find(
"_mu") == std::string::npos ) {
556 switchedTojets =
true;
560 jets.push_back(ptrHLTTE->id());
562 muons.push_back(ptrHLTTE->id());
570 finalTEs[muons[0]].insert(chainId);
572 finalTEs[jets[0]].insert(chainId);
574 for (
size_t index = 0;
index < std::min(muons.size(), jets.size()); ++
index)
577 allTEs[muons[
index]].insert(chainId);
579 allTEs[jets[
index]].insert(chainId);
581 return StatusCode::SUCCESS;
590 std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
598 convProxies.insert(proxy);
599 teToProxy[te] = proxy;
603 ConvProxy *predecessorProxy = teToProxy[predecessor];
604 if (predecessorProxy !=
nullptr)
606 proxy->parents.insert(predecessorProxy);
607 predecessorProxy->
children.insert(proxy);
615 for (
auto proxy : convProxies)
618 ATH_MSG_DEBUG(
"Proxy " << counter <<
" " << proxy->description() <<
"ptr " << proxy);
619 for (
auto p : proxy->children)
621 for (
auto p : proxy->parents)
624 for (
auto p : proxy->parents)
626 for (
auto pp : p->parents)
634 for (
auto c : proxy->children)
636 for (
auto cc : c->children)
647 ATH_MSG_DEBUG(
"Created " << convProxies.size() <<
" proxy objects");
648 return StatusCode::SUCCESS;
653 std::function<
bool(
const ConvProxy*)> selector,
654 const std::vector<std::function<
void(
const ConvProxy*)>>& printers)
const {
657 for (
auto p: proxies) {
660 for (
auto& printer: printers) {
671 for (
auto &ptrConvProxy : convProxies)
673 auto teId = ptrConvProxy->te->getId();
674 bool teActive = ptrConvProxy->te->getActiveState();
675 auto iter = allTEs.find(teId);
676 if (iter != allTEs.end())
678 ptrConvProxy->runChains.insert(iter->second.begin(), iter->second.end());
681 ptrConvProxy->passChains.insert(iter->second.begin(), iter->second.end());
685 for (
auto &objTeIdToChain : allTEs)
687 if (teId == objTeIdToChain.first)
689 for (
auto &chainId : objTeIdToChain.second)
691 (ptrConvProxy->runChains).insert(chainId);
697 return StatusCode::SUCCESS;
708 size_t numberOfUpdates = 0;
709 for (
auto p : convProxies)
711 for (
auto child : p->children)
713 size_t startSize = p->runChains.size();
714 p->runChains.insert(std::begin(child->runChains), std::end(child->runChains));
716 if (startSize != p->runChains.size())
720 p->passChains.insert(std::begin(child->runChains), std::end(child->runChains));
724 ATH_MSG_DEBUG(
"Needed to propagate chains from " << numberOfUpdates <<
" child(ren)");
725 if (numberOfUpdates == 0)
730 return StatusCode::SUCCESS;
736 for (
auto i = std::begin(convProxies); i != std::end(convProxies);)
738 if ((*i)->runChains.empty())
742 for (
auto parent : toDel->
parents)
744 parent->children.erase(toDel);
748 child->parents.erase(toDel);
751 i = convProxies.erase(i);
758 ATH_MSG_DEBUG(
"After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
759 return StatusCode::SUCCESS;
774 return StatusCode::SUCCESS;
777template <
typename MAP>
781 std::vector<ConvProxy *> todelete;
782 for (
auto &[key, proxies] : keyToProxyMap)
784 if (proxies.size() > 1)
786 ATH_MSG_DEBUG(
"Merging " << proxies.size() <<
" similar proxies");
787 for (
auto p : proxies)
789 if (p->mergeAllowed(*proxies.begin()))
791 (*proxies.begin())->merge(p);
792 todelete.push_back(p);
798 for (
auto proxy : todelete)
800 convProxies.erase(proxy);
804 return StatusCode::SUCCESS;
810 const size_t beforeCount = convProxies.size();
811 std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
812 for (
auto proxy : convProxies)
814 proxy->feaHash =
feaToHash(proxy->te->getFeatureAccessHelpers(), proxy->te, run2Nav);
816 feaToProxyMap[proxy->feaHash].insert(proxy);
825 for (
auto [feaHash, proxies] : feaToProxyMap)
827 auto first = *proxies.begin();
828 for (
auto p : proxies)
830 if (
filterFEAs(first->te->getFeatureAccessHelpers(), run2Nav) !=
831 filterFEAs(p->te->getFeatureAccessHelpers(), run2Nav))
833 ATH_MSG_ERROR(
"Proxies grouped by FEA hash have actually distinct features (specific FEAs are different)");
834 for (
auto id: p->passChains )
ATH_MSG_ERROR(
"... chain id for this proxy " <<
id);
836 for (
auto fea: first->te->getFeatureAccessHelpers() ) {
839 for (
auto fea: p->te->getFeatureAccessHelpers() ) {
843 return StatusCode::FAILURE;
850 ATH_MSG_DEBUG(
"Proxies with features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
852 return StatusCode::SUCCESS;
858 struct ParentChildCharacteristics
862 size_t distanceFromParent = 0;
863 bool operator<(
const ParentChildCharacteristics &rhs)
const
865 if (parent != rhs.parent)
866 return parent < rhs.parent;
867 if (child != rhs.child)
868 return child < rhs.child;
869 return distanceFromParent < rhs.distanceFromParent;
872 const size_t beforeCount = convProxies.size();
873 std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
874 for (
auto proxy : convProxies)
878 ATH_MSG_VERBOSE(
"Featureless proxy to deal with: " << proxy->description());
887 if (proxy->children.size() == 1 and
888 std::all_of(proxy->children.begin(), proxy->children.end(), hasSomeFeatures ) and
889 proxy->parents.size() == 1 and
890 std::all_of(proxy->parents.begin(), proxy->parents.end(), hasSomeFeatures )
894 groupedProxies[{*(proxy->parents.begin()), *(proxy->children.begin()), 0}].insert(proxy);
899 ATH_MSG_VERBOSE(
"Featureless proxy in noncanonical situation " << proxy->description());
901 for (
auto pp : proxy->parents)
906 for (
auto cp : proxy->children)
915 ATH_MSG_DEBUG(
"Proxies without features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
916 return StatusCode::SUCCESS;
921 for (
auto i = std::begin(convProxies); i != std::end(convProxies);)
923 if ((*i)->parents.size() > 1)
927 for (
auto parent : toDel->
parents)
929 parent->children.erase(toDel);
933 child->parents.erase(toDel);
936 i = convProxies.erase(i);
943 return StatusCode::SUCCESS;
949 for (
auto &proxy : convProxies)
951 if (proxy->te !=
nullptr)
962 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, helper);
968 if (expectedCLID != 0 && sgCLID != expectedCLID)
970 ATH_MSG_VERBOSE(
"Skipping feature with CLID " << sgCLID <<
" (name: " << sgName
971 <<
") for TE " << teName <<
" because expected CLID is " << expectedCLID);
974 proxy->features.push_back(helper);
975 ATH_MSG_VERBOSE(
"Added feature with CLID " << sgCLID <<
" (name: " << sgName <<
") for TE " << teName);
982 return StatusCode::SUCCESS;
989 auto ordered_sorter = [&setRoiName = std::as_const(
m_setRoiName)](
const std::string &left,
const std::string &right) ->
bool
991 return std::find(cbegin(setRoiName), cend(setRoiName), left) < std::find(cbegin(setRoiName), cend(setRoiName), right);
996 for (
auto &proxy : convProxies)
1000 ATH_MSG_DEBUG(
"Several RoIs pointing to a proxy, taking latest one for now");
1006 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, helper);
1012 mp[sgName] = helper;
1015 std::transform(cbegin(mp), cend(mp), back_inserter(proxy->rois),
1016 [](
const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &p)
1017 { return p.second; });
1021 std::set<const ConvProxy*> visited;
1022 std::function<void(std::set<ConvProxy *> &,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &)>
1023 roiPropagator = [&](std::set<ConvProxy *> &convProxyChildren,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &roiParent)
1025 for (
auto &proxyChild : convProxyChildren)
1027 if ( visited.count(proxyChild) == 1 ) {
1030 visited.insert(proxyChild);
1031 if (proxyChild->rois.empty())
1033 proxyChild->rois = roiParent;
1034 if (proxyChild->children.empty() ==
false)
1036 roiPropagator(proxyChild->children, roiParent);
1042 for (
auto &proxy : convProxies)
1044 roiPropagator(proxy->children, proxy->rois);
1047 return StatusCode::SUCCESS;
1052 for (
auto &proxy : convProxies)
1058 proxy->tracks.push_back(helper);
1063 return StatusCode::SUCCESS;
1068 for (
auto &proxy : convProxies)
1071 for (
auto chainId : proxy->runChains)
1076 for (
auto chainId : proxy->passChains)
1084 for (
auto &proxy : convProxies)
1086 for (
auto &parentProxy : proxy->parents)
1091 ATH_MSG_DEBUG(
"IM & H nodes made, output nav elements " << decisions.size());
1092 return StatusCode::SUCCESS;
1102 sfNode->setName(
"SF");
1105 for (
auto chainId : chainIds)
1112 else if (chainId.numeric() == idStore)
1122 if (proxy->hNode.empty())
1125 makeSingleSFNode(proxy->imNode, proxy->runChains, idToStore);
1130 for (
auto &hNode : proxy->hNode)
1132 makeSingleSFNode(hNode, proxy->passChains, idToStore);
1137 for (
auto proxy : convProxies)
1140 if (proxy->children.empty())
1148 std::vector<TCU::DecisionID> toRetain;
1149 for (
auto teId : proxy->teIDs)
1151 auto whereInMap = terminalIds.find(teId);
1152 if (whereInMap != terminalIds.end())
1154 toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1157 for (
auto chainIdstore : toRetain)
1159 makeSFNodes(proxy, chainIdstore);
1165 ATH_MSG_DEBUG(
"SF nodes made, output nav elements " << decisions.size());
1166 return StatusCode::SUCCESS;
1187 ATH_MSG_ERROR(
"Navigation information for chain " << chainName <<
" in "
1189 return StatusCode::FAILURE;
1192 if (
m_tdt->isPassed(chainName))
1194 filteredIDs.insert(idToCheck);
1197 terminus->
setDecisions( std::vector<TCU::DecisionID>() );
1200 "the terminus node goes from " << currentIDs.size() <<
" to " << filteredIDs.size() <<
" chain IDs.");
1201 if (
msgLvl(MSG::VERBOSE))
1208 return StatusCode::SUCCESS;
1212 const EventContext &context)
const
1215 auto makeL1Node = [&decisions, &context](
auto firstDecisionNode,
auto chainIds)
1219 for (
auto chainId : chainIds)
1228 for (
auto &proxy : convProxies)
1231 if (proxy->parents.empty())
1233 proxy->l1Node = makeL1Node(proxy->imNode,
TCU::decisionIDs(proxy->imNode));
1238 return StatusCode::SUCCESS;
1244 if (proxy.features.empty())
1248 for (
const auto &fea : proxy.features)
1250 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1254 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1266 for (
const auto &proxy : convProxies)
1276 for (
auto chainId : proxy->passChains)
1283 for (
auto &childProxy : proxy->children)
1290 if (proxy->features.empty())
1296 auto hNodeIter = proxy->hNode.begin();
1297 for (std::size_t feaIdx = 0; feaIdx < proxy->features.size(); ++feaIdx)
1299 auto &fea = proxy->features[feaIdx];
1300 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1302 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1308 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1311 const std::string& linkName = (feaIdx == bestFeaIdx && n == bestObjIdx) ?
1313 (*hNodeIter)->typelessSetObjectLink(linkName, sgKey, sgCLID, n, n + 1);
1319 return StatusCode::SUCCESS;
1325 for (
auto &proxy : convProxies)
1327 for (
auto &roi : proxy->rois)
1329 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1334 if (proxy->rois.empty() ==
false)
1341 return StatusCode::SUCCESS;
1346 for (
auto &proxy : convProxies)
1348 for (
auto &trk : proxy->tracks)
1358 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, trk);
1362 auto d = std::make_unique<TrigCompositeUtils::Decision>();
1363 d->makePrivateStore();
1364 d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1369 if (track.isValid())
1372 viewBookkeeper(*t) = ROIElementLink;
1380 if (track.isValid())
1383 viewBookkeeper(*t) = ROIElementLink;
1390 ATH_MSG_WARNING(
"Unable to create an ElementLink into a container with no entries");
1396 return StatusCode::SUCCESS;
1405 return fea.
getCLID() == thePassBitsCLID or fea.
getCLID() == thePassBitsContCLID;
1409 std::vector<HLT::TriggerElement::FeatureAccessHelper> out;
1410 for (
auto fea : feaVector)
1418 auto [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1422 ATH_MSG_VERBOSE(
"Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName <<
" FEA " << fea);
1437 ATH_MSG_VERBOSE(
"Calculating FEA hash for TE " << teName <<
" expecting CLID " << expectedCLID);
1439 for (
auto fea :
filterFEAs(feaVector, navigationDecoder))
1441 const auto & [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1444 if (expectedCLID != 0 && sgCLID != expectedCLID)
1446 ATH_MSG_VERBOSE(
"Skipping FEA with CLID " << sgCLID <<
" for TE " << teName
1447 <<
" (expected " << expectedCLID <<
")");
1451 ATH_MSG_VERBOSE(
"Including FEA in hash CLID: " << fea.getCLID() <<
" te Id: " << te_ptr->
getId());
1452 boost::hash_combine(hash, fea.getCLID());
1453 boost::hash_combine(hash, fea.getIndex().subTypeIndex());
1454 boost::hash_combine(hash, fea.getIndex().objectsBegin());
1455 boost::hash_combine(hash, fea.getIndex().objectsEnd());
1462 boost::hash_combine(hash, te_ptr->
getId());
1463 boost::hash_combine(hash,
reinterpret_cast<std::uintptr_t
>(te_ptr));
1473 if ( iter->second.empty() )
1475 ATH_MSG_DEBUG(
"fea to save CLID: " << fea.
getCLID() <<
", sgName: " << sgName <<
" " <<iter->second.size() <<
" " << iter->second.empty() );
1476 return iter->second.contains(sgName);
1486 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1497 for (
auto p : proxies)
1499 if (p->runChains.empty())
1502 return StatusCode::FAILURE;
1506 return StatusCode::SUCCESS;
1511 for (
auto p : proxies)
1513 if (p->children.empty() and p->parents.empty() and not p->runChains.empty())
1515 ATH_MSG_ERROR(
"Orphanted proxy N chains run:" << p->runChains.size());
1516 return StatusCode::FAILURE;
1520 return StatusCode::SUCCESS;
1525 ATH_MSG_DEBUG(
"CHECK OK, no excessive number of H nodes per proxy");
1526 return StatusCode::SUCCESS;
1532 std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1533 for (
auto d : decisions)
1535 if (d->name() ==
"IM" or d->name() ==
"FS")
1539 linkedHNodes.insert(*el);
1543 for (
auto d : decisions)
1545 if (d->name() ==
"H")
1547 if (linkedHNodes.count(d) == 0)
1550 return StatusCode::FAILURE;
1556 return StatusCode::SUCCESS;
1561 const std::string hltLabel = navigationDecoder.
label(helper.getCLID(), helper.getIndex().subTypeIndex());
1563 const CLID saveCLID = [&](
const CLID &clid)
1572 }(helper.getCLID());
1574 std::string type_name;
1575 if (
m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1581 const bool isAvailable =
evtStore()->contains(saveCLID, sgStringKey);
1582 ATH_MSG_DEBUG(
" Objects presence " << helper <<
" " << sgStringKey << (isAvailable ?
" present" :
" absent"));
1585 return {0, saveCLID,
""};
1588 return {
evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel};
1594 std::size_t bestFea = std::numeric_limits<std::size_t>::max();
1595 std::size_t bestObj = 0;
1596 float bestPt = -1.0;
1598 for (std::size_t i = 0; i < proxy.features.size(); ++i) {
1599 const auto& fea = proxy.features[i];
1600 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1604 if (sgKey == 0)
continue;
1605 const std::string* keyStr =
evtStore()->keyToString(sgKey, sgCLID);
1606 if (!keyStr)
continue;
1608 if (
evtStore()->retrieve(cont, *keyStr).isFailure())
continue;
1609 for (
auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n) {
1610 if (n >= cont->
size())
continue;
1613 if (p->pt() > bestPt) {
1620 if (bestFea == std::numeric_limits<std::size_t>::max()) {
1621 for (std::size_t i = 0; i < proxy.features.size(); ++i) {
1622 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, proxy.features[i]);
1623 if (!
feaToSave(proxy.features[i], sgName))
continue;
1625 bestObj = proxy.features[i].getIndex().objectsBegin();
1629 return {bestFea, bestObj};
1639 if (teName.find(
"etcut") != std::string::npos &&
1640 teName.find(
"trkcut") == std::string::npos) {
1644 else if (teName.rfind(
"EF_e", 0) == 0) {
1648 else if (teName.rfind(
"EF_g", 0) == 0) {
1652 else if (teName.rfind(
"EF_mu", 0) == 0 || teName.find(
"_mu") != std::string::npos) {
1656 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_VERBOSE(x)
#define ATH_MSG_WARNING(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.
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.
size_type size() const noexcept
Returns the number of elements in the collection.
ElementLink implementation for ROOT usage.
bool isValid() const
Test to see if the link can be dereferenced.
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
Helper class to provide type-safe access to aux data.
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="TE")
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.
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.
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.
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