5 #include <boost/functional/hash.hpp>
6 #include <GaudiKernel/StatusCode.h>
7 #include "AthLinks/ElementLinkVector.h"
25 teIDs.push_back(te->getId());
87 auto add = [](
ConvProxy *toadd, std::set<ConvProxy *> &coll)
89 if (
std::find(coll.begin(), coll.end(), toadd) == coll.end())
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)
123 for (
auto otherChild :
other->children)
127 other->children.clear();
128 other->parents.clear();
136 std::ostringstream
os;
139 ret +=
" ptrs: " +
os.str();
161 ATH_MSG_INFO(
"Will use Trigger Navigation from TrigDecisionTool");
166 ATH_MSG_INFO(
"Will use Trigger Navigation decoded from TrigNavigation object");
183 std::string collName;
184 size_t delimeterIndex =
name.find(
'#');
185 if (delimeterIndex != std::string::npos)
188 collName =
name.substr(delimeterIndex + 1);
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");
241 return StatusCode::SUCCESS;
246 return StatusCode::SUCCESS;
266 standaloneNav.
deserialize(navReadHandle->serialized());
267 run2NavigationPtr = &standaloneNav;
271 run2NavigationPtr =
m_tdt->ExperimentalAndExpertMethods().getNavigation();
295 ATH_MSG_DEBUG(
"Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
310 auto decisionOutput = outputNavigation.
ptr();
333 ATH_MSG_DEBUG(
"Conversion done, from " << convProxies.size() <<
" elements to " << decisionOutput->size() <<
" elements");
339 for (
auto o: *decisionOutput) {
345 for (
auto proxy : convProxies)
350 return StatusCode::SUCCESS;
364 size_t stepToConsider = 0;
365 const size_t sigsSize = ptrChain->
signatures().size();
366 if ( sigsSize < 2 )
return 0;
369 stepToConsider =
step;
373 if ( stepToConsider == 0 )
return 0;
376 auto finalTE = (ptrChain->
signatures()[stepToConsider])->outputTEs()[0];
377 auto preFinalTEs = (ptrChain->
signatures()[stepToConsider-1])->outputTEs();
379 auto finalSeq =
m_configSvc->sequences().getSequence(finalTE->id());
380 std::set<HLT::te_id_type> tesInSeq;
381 std::set<HLT::te_id_type> tesInChain;
383 for (
auto te: finalSeq->inputTEs()) {
384 tesInSeq.insert(te->id());
387 for (
auto te: preFinalTEs) {
388 tesInChain.insert(te->id());
391 if (tesInSeq == tesInChain) {
392 return stepToConsider;
405 std::string
chainName = ptrChain->name();
424 std::map<HLT::te_id_type, HLT::te_id_type> etcutReplacementTEs;
425 auto etcutReplacement = [&etcutReplacementTEs](
HLT::te_id_type in) {
auto out = etcutReplacementTEs.find(in);
return (
out == etcutReplacementTEs.end() ? in :
out->second ); };
426 if (
chainName.find(
"etcut") != std::string::npos ) {
427 std::set<size_t> positionsOfEtCutLegs;
430 ATH_MSG_DEBUG(
"EtCut chains hack, chain with two etcut legs ");
431 positionsOfEtCutLegs.insert({0, 1});
433 ATH_MSG_DEBUG(
"EtCut chains hack, egamma chain with second etcut leg ");
434 positionsOfEtCutLegs.insert({1});
437 positionsOfEtCutLegs.insert({0});
441 std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
442 for (
auto ptrHLTSignature : ptrChain->signatures()) {
444 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
445 if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
446 etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
449 if ( ptrHLTTE->name().find(
"calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) {
450 positionToDesiredIDmap[position] = ptrHLTTE->id();
461 for (
auto ptrHLTSignature : ptrChain->signatures()) {
462 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
463 unsigned int teId = etcutReplacement(ptrHLTTE->id());
464 allTEs[
teId].insert(chainId);
465 if (ptrHLTSignature == ptrChain->signatures().back()) {
466 finalTEs[
teId].insert(chainId);
467 ATH_MSG_DEBUG(
"TE will be used to mark final chain decision " << ptrHLTTE->name() <<
" chain " <<
chainName );
486 std::vector<size_t> mult_hack;
489 ptrChain->set_leg_multiplicities(mult_hack);
494 std::vector<size_t> mult_hack;
497 ptrChain->set_leg_multiplicities(mult_hack);
501 std::vector<unsigned int> teIdsLastHealthyStepIds;
503 for (
auto ptrHLTSignature : ptrChain->signatures())
505 std::vector<int> teCounts;
506 std::vector<unsigned int> teIds;
507 unsigned int lastSeenId = 0;
508 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs())
510 if ( lastSeenId != ptrHLTTE->id()) {
511 teCounts.push_back(1);
512 teIds.push_back(ptrHLTTE->id());
516 lastSeenId = ptrHLTTE->id();
519 ATH_MSG_DEBUG(
"TE multiplicities seen in this step " << teCounts);
523 if ( multiplicityCounts ) {
524 teIdsLastHealthyStepIds = teIds;
525 ATH_MSG_DEBUG(
"There is a match, will assign chain leg IDs to TEs " << teCounts <<
" " << teIds);
526 for (
size_t legNumber = 0; legNumber < teIds.size(); ++ legNumber){
528 allTEs[etcutReplacement(teIds[legNumber])].insert(chainLegId);
532 for (
size_t legNumber = 0; legNumber < teIdsLastHealthyStepIds.size(); ++ legNumber ) {
535 ATH_MSG_DEBUG(
"created leg id " << chainLegId <<
" that will replace TE ID " << etcutReplacement(teIdsLastHealthyStepIds[legNumber]));
536 finalTEs[etcutReplacement(teIdsLastHealthyStepIds[legNumber])].insert(chainLegId);
540 ATH_MSG_DEBUG(
"Recognised " << allTEs.size() <<
" kinds of TEs and among them " << finalTEs.size() <<
" final types");
541 return StatusCode::SUCCESS;
547 std::vector<unsigned int> muons;
548 std::vector<unsigned int>
jets;
549 bool switchedTojets =
false;
550 for (
auto ptrHLTSignature : ptrChain->
signatures()) {
551 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
552 if ( ptrHLTTE->name().find(
"_mu") == std::string::npos ) {
553 switchedTojets =
true;
557 jets.push_back(ptrHLTTE->id());
559 muons.push_back(ptrHLTTE->id());
567 finalTEs[muons[0]].insert(chainId);
569 finalTEs[
jets[0]].insert(chainId);
574 allTEs[muons[
index]].insert(chainId);
578 return StatusCode::SUCCESS;
587 std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
595 convProxies.insert(
proxy);
596 teToProxy[te] =
proxy;
600 ConvProxy *predecessorProxy = teToProxy[predecessor];
601 if (predecessorProxy !=
nullptr)
603 proxy->parents.insert(predecessorProxy);
612 for (
auto proxy : convProxies)
616 for (
auto p :
proxy->children)
618 for (
auto p :
proxy->parents)
621 for (
auto p :
proxy->parents)
623 for (
auto pp :
p->parents)
631 for (
auto c :
proxy->children)
633 for (
auto cc :
c->children)
644 ATH_MSG_DEBUG(
"Created " << convProxies.size() <<
" proxy objects");
645 return StatusCode::SUCCESS;
651 const std::vector<std::function<
void(
const ConvProxy*)>>& printers)
const {
654 for (
auto p: proxies) {
657 for (
auto& printer: printers) {
668 for (
auto &ptrConvProxy : convProxies)
670 auto teId = ptrConvProxy->te->getId();
671 bool teActive = ptrConvProxy->te->getActiveState();
673 if (
iter != allTEs.end())
675 ptrConvProxy->runChains.insert(
iter->second.begin(),
iter->second.end());
678 ptrConvProxy->passChains.insert(
iter->second.begin(),
iter->second.end());
682 for (
auto &objTeIdToChain : allTEs)
684 if (
teId == objTeIdToChain.first)
686 for (
auto &chainId : objTeIdToChain.second)
688 (ptrConvProxy->runChains).insert(chainId);
694 return StatusCode::SUCCESS;
705 size_t numberOfUpdates = 0;
706 for (
auto p : convProxies)
708 for (
auto child :
p->children)
710 size_t startSize =
p->runChains.size();
713 if (startSize !=
p->runChains.size())
721 ATH_MSG_DEBUG(
"Needed to propagate chains from " << numberOfUpdates <<
" child(ren)");
722 if (numberOfUpdates == 0)
727 return StatusCode::SUCCESS;
735 if ((*i)->runChains.empty())
741 parent->children.erase(toDel);
745 child->parents.erase(toDel);
748 i = convProxies.erase(
i);
755 ATH_MSG_DEBUG(
"After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
756 return StatusCode::SUCCESS;
771 return StatusCode::SUCCESS;
774 template <
typename MAP>
778 std::vector<ConvProxy *> todelete;
779 for (
auto &[
key, proxies] : keyToProxyMap)
781 if (proxies.size() > 1)
783 ATH_MSG_DEBUG(
"Merging " << proxies.size() <<
" similar proxies");
784 for (
auto p : proxies)
786 if (
p->mergeAllowed(*proxies.begin()))
788 (*proxies.begin())->
merge(
p);
789 todelete.push_back(
p);
795 for (
auto proxy : todelete)
797 convProxies.erase(
proxy);
801 return StatusCode::SUCCESS;
807 const size_t beforeCount = convProxies.size();
808 std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
809 for (
auto proxy : convProxies)
822 for (
auto [feaHash, proxies] : feaToProxyMap)
824 auto first = *proxies.begin();
825 for (
auto p : proxies)
828 filterFEAs(
p->te->getFeatureAccessHelpers(), run2Nav))
830 ATH_MSG_ERROR(
"Proxies grouped by FEA hash have actually distinct features (specific FEAs are different)");
831 for (
auto id:
p->passChains )
ATH_MSG_ERROR(
"... chain id for this proxy " <<
id);
833 for (
auto fea:
first->te->getFeatureAccessHelpers() ) {
836 for (
auto fea:
p->te->getFeatureAccessHelpers() ) {
840 return StatusCode::FAILURE;
847 ATH_MSG_DEBUG(
"Proxies with features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
849 return StatusCode::SUCCESS;
855 struct ParentChildCharacteristics
859 size_t distanceFromParent = 0;
860 bool operator<(
const ParentChildCharacteristics &rhs)
const
863 return parent < rhs.parent;
864 if (child != rhs.child)
865 return child < rhs.child;
866 return distanceFromParent < rhs.distanceFromParent;
869 const size_t beforeCount = convProxies.size();
870 std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
871 for (
auto proxy : convProxies)
884 if (
proxy->children.size() == 1 and
885 std::all_of(
proxy->children.begin(),
proxy->children.end(), hasSomeFeatures ) and
886 proxy->parents.size() == 1 and
887 std::all_of(
proxy->parents.begin(),
proxy->parents.end(), hasSomeFeatures )
891 groupedProxies[{*(
proxy->parents.begin()), *(
proxy->children.begin()), 0}].insert(
proxy);
898 for (
auto pp :
proxy->parents)
903 for (
auto cp :
proxy->children)
912 ATH_MSG_DEBUG(
"Proxies without features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
913 return StatusCode::SUCCESS;
920 if ((*i)->parents.size() > 1)
926 parent->children.erase(toDel);
930 child->parents.erase(toDel);
933 i = convProxies.erase(
i);
940 return StatusCode::SUCCESS;
946 for (
auto &
proxy : convProxies)
948 if (
proxy->te !=
nullptr)
965 return StatusCode::SUCCESS;
972 auto ordered_sorter = [&setRoiName = std::as_const(
m_setRoiName)](
const std::string &left,
const std::string &right) ->
bool
974 return std::find(cbegin(setRoiName), cend(setRoiName), left) <
std::find(cbegin(setRoiName), cend(setRoiName), right);
979 for (
auto &
proxy : convProxies)
983 ATH_MSG_DEBUG(
"Several RoIs pointing to a proxy, taking latest one for now");
999 [](
const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &
p)
1000 { return p.second; });
1004 std::set<const ConvProxy*> visited;
1005 std::function<void(std::set<ConvProxy *> &,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &)>
1006 roiPropagator = [&](std::set<ConvProxy *> &convProxyChildren,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &roiParent)
1008 for (
auto &proxyChild : convProxyChildren)
1010 if ( visited.count(proxyChild) == 1 ) {
1013 visited.insert(proxyChild);
1014 if (proxyChild->rois.empty())
1016 proxyChild->rois = roiParent;
1017 if (proxyChild->children.empty() ==
false)
1019 roiPropagator(proxyChild->children, roiParent);
1025 for (
auto &
proxy : convProxies)
1030 return StatusCode::SUCCESS;
1035 for (
auto &
proxy : convProxies)
1046 return StatusCode::SUCCESS;
1051 for (
auto &
proxy : convProxies)
1054 for (
auto chainId :
proxy->runChains)
1059 for (
auto chainId :
proxy->passChains)
1067 for (
auto &
proxy : convProxies)
1069 for (
auto &parentProxy :
proxy->parents)
1075 return StatusCode::SUCCESS;
1085 sfNode->setName(
"SF");
1088 for (
auto chainId : chainIds)
1095 else if (chainId.numeric() == idStore)
1105 if (
proxy->hNode.empty())
1108 makeSingleSFNode(
proxy->imNode,
proxy->runChains, idToStore);
1113 for (
auto &hNode :
proxy->hNode)
1115 makeSingleSFNode(hNode,
proxy->passChains, idToStore);
1120 for (
auto proxy : convProxies)
1123 if (
proxy->children.empty())
1131 std::vector<TCU::DecisionID> toRetain;
1134 auto whereInMap = terminalIds.find(
teId);
1135 if (whereInMap != terminalIds.end())
1137 toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1140 for (
auto chainIdstore : toRetain)
1142 makeSFNodes(
proxy, chainIdstore);
1149 return StatusCode::SUCCESS;
1172 return StatusCode::FAILURE;
1177 filteredIDs.insert(idToCheck);
1180 terminus->
setDecisions( std::vector<TCU::DecisionID>() );
1183 "the terminus node goes from " << currentIDs.size() <<
" to " << filteredIDs.size() <<
" chain IDs.");
1191 return StatusCode::SUCCESS;
1195 const EventContext &context)
const
1198 auto makeL1Node = [&
decisions, &context](
auto firstDecisionNode,
auto chainIds)
1202 for (
auto chainId : chainIds)
1211 for (
auto &
proxy : convProxies)
1214 if (
proxy->parents.empty())
1221 return StatusCode::SUCCESS;
1227 if (
proxy.features.empty())
1231 for (
const auto &fea :
proxy.features)
1233 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1237 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1249 for (
const auto &
proxy : convProxies)
1259 for (
auto chainId :
proxy->passChains)
1266 for (
auto &childProxy :
proxy->children)
1273 if (
proxy->features.empty())
1279 auto hNodeIter =
proxy->hNode.begin();
1280 for (std::size_t feaIdx = 0; feaIdx <
proxy->features.size(); ++feaIdx)
1282 auto &fea =
proxy->features[feaIdx];
1283 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1285 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1291 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1294 const std::string& linkName = (feaIdx == bestFeaIdx &&
n == bestObjIdx) ?
1296 (*hNodeIter)->typelessSetObjectLink(linkName, sgKey, sgCLID,
n,
n + 1);
1302 return StatusCode::SUCCESS;
1308 for (
auto &
proxy : convProxies)
1310 for (
auto &roi :
proxy->rois)
1312 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1317 if (
proxy->rois.empty() ==
false)
1324 return StatusCode::SUCCESS;
1329 for (
auto &
proxy : convProxies)
1331 for (
auto &trk :
proxy->tracks)
1341 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, trk);
1345 auto d = std::make_unique<TrigCompositeUtils::Decision>();
1346 d->makePrivateStore();
1347 d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1352 if (
track.isValid())
1355 viewBookkeeper(*
t) = ROIElementLink;
1363 if (
track.isValid())
1366 viewBookkeeper(*
t) = ROIElementLink;
1373 ATH_MSG_WARNING(
"Unable to create an ElementLink into a container with no entries");
1379 return StatusCode::SUCCESS;
1388 return fea.
getCLID() == thePassBitsCLID or fea.
getCLID() == thePassBitsContCLID;
1392 std::vector<HLT::TriggerElement::FeatureAccessHelper>
out;
1393 for (
auto fea : feaVector)
1401 auto [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1405 ATH_MSG_VERBOSE(
"Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName <<
" FEA " << fea);
1418 for (
auto fea :
filterFEAs(feaVector, navigationDecoder))
1420 ATH_MSG_VERBOSE(
"Including FEA in hash CLID: " << fea.getCLID() <<
" te Id: " << te_ptr->
getId());
1421 boost::hash_combine(
hash, fea.getCLID());
1422 boost::hash_combine(
hash, fea.getIndex().subTypeIndex());
1423 boost::hash_combine(
hash, fea.getIndex().objectsBegin());
1424 boost::hash_combine(
hash, fea.getIndex().objectsEnd());
1431 boost::hash_combine(
hash, te_ptr->
getId());
1432 boost::hash_combine(
hash,
reinterpret_cast<std::uintptr_t
>(te_ptr));
1442 if (
iter->second.empty() )
1444 ATH_MSG_DEBUG(
"fea to save CLID: " << fea.
getCLID() <<
", sgName: " << sgName <<
" " <<
iter->second.size() <<
" " <<
iter->second.empty() );
1445 return iter->second.contains(sgName);
1455 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1466 for (
auto p : proxies)
1468 if (
p->runChains.empty())
1471 return StatusCode::FAILURE;
1475 return StatusCode::SUCCESS;
1480 for (
auto p : proxies)
1482 if (
p->children.empty() and
p->parents.empty() and not
p->runChains.empty())
1484 ATH_MSG_ERROR(
"Orphanted proxy N chains run:" <<
p->runChains.size());
1485 return StatusCode::FAILURE;
1489 return StatusCode::SUCCESS;
1494 ATH_MSG_DEBUG(
"CHECK OK, no excessive number of H nodes per proxy");
1495 return StatusCode::SUCCESS;
1501 std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1504 if (
d->name() ==
"IM" or
d->name() ==
"FS")
1508 linkedHNodes.insert(*
el);
1514 if (
d->name() ==
"H")
1516 if (linkedHNodes.count(
d) == 0)
1519 return StatusCode::FAILURE;
1525 return StatusCode::SUCCESS;
1530 const std::string hltLabel = navigationDecoder.
label(
helper.getCLID(),
helper.getIndex().subTypeIndex());
1532 const CLID saveCLID = [&](
const CLID &clid)
1543 std::string type_name;
1544 if (
m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1554 return {0, saveCLID,
""};
1557 return {
evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel};
1564 std::size_t bestObj = 0;
1565 float bestPt = -1.0;
1567 for (std::size_t
i = 0;
i <
proxy.features.size(); ++
i) {
1568 const auto& fea =
proxy.features[
i];
1569 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1573 if (sgKey == 0)
continue;
1574 const std::string* keyStr =
evtStore()->keyToString(sgKey, sgCLID);
1575 if (!keyStr)
continue;
1578 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n) {
1579 if (
n >= cont->
size())
continue;
1582 if (
p->pt() > bestPt) {
1590 for (std::size_t
i = 0;
i <
proxy.features.size(); ++
i) {
1591 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav,
proxy.features[
i]);
1594 bestObj =
proxy.features[
i].getIndex().objectsBegin();
1598 return {bestFea, bestObj};