5 #include <boost/functional/hash.hpp>
6 #include <GaudiKernel/StatusCode.h>
7 #include "AthLinks/ElementLinkVector.h"
23 teIDs.push_back(te->getId());
85 auto add = [](
ConvProxy *toadd, std::set<ConvProxy *> &coll)
87 if (
std::find(coll.begin(), coll.end(), toadd) == coll.end())
95 auto place =
std::find(coll.begin(), coll.end(), torem);
96 if (place != coll.end())
103 for (
auto otherChild :
other->children)
106 add(
this, otherChild->parents);
109 for (
auto otherParent :
other->parents)
112 add(
this, otherParent->children);
116 for (
auto otherParent :
other->parents)
121 for (
auto otherChild :
other->children)
125 other->children.clear();
126 other->parents.clear();
134 std::ostringstream
os;
137 ret +=
" ptrs: " +
os.str();
159 ATH_MSG_INFO(
"Will use Trigger Navigation from TrigDecisionTool");
164 ATH_MSG_INFO(
"Will use Trigger Navigation decoded from TrigNavigation object");
181 std::string collName;
182 size_t delimeterIndex =
name.find(
'#');
183 if (delimeterIndex != std::string::npos)
186 collName =
name.substr(delimeterIndex + 1);
191 if ( collName.empty() )
205 if (keysSet.size() > 1 and keysSet.count(
"") != 0)
207 ATH_MSG_ERROR(
"Bad configuration for CLID " << clid <<
" requested saving of all (empty coll name configures) collections, yet there are also specific keys");
208 return StatusCode::FAILURE;
213 bool anyChainBad=
false;
215 if (
chain.find(
'*') != std::string::npos or
chain.find(
'|') != std::string::npos ) {
216 ATH_MSG_ERROR(
"Supplied chain name: " <<
chain <<
" contains wildcard characters, this is not supported by the conversion tool");
221 ATH_MSG_ERROR(
"Supplied chain names contain wildcard characters, this is not supported by the conversion tool");
222 return StatusCode::FAILURE;
225 ATH_MSG_INFO(
"No chains list supplied, the conversion will occur for all chains");
239 return StatusCode::SUCCESS;
244 return StatusCode::SUCCESS;
264 standaloneNav.
deserialize(navReadHandle->serialized());
265 run2NavigationPtr = &standaloneNav;
269 run2NavigationPtr =
m_tdt->ExperimentalAndExpertMethods().getNavigation();
293 ATH_MSG_DEBUG(
"Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
308 auto decisionOutput = outputNavigation.
ptr();
331 ATH_MSG_DEBUG(
"Conversion done, from " << convProxies.size() <<
" elements to " << decisionOutput->size() <<
" elements");
337 for (
auto o: *decisionOutput) {
343 for (
auto proxy : convProxies)
348 return StatusCode::SUCCESS;
362 size_t stepToConsider = 0;
363 const size_t sigsSize = ptrChain->
signatures().size();
364 if ( sigsSize < 2 )
return 0;
367 stepToConsider =
step;
371 if ( stepToConsider == 0 )
return 0;
374 auto finalTE = (ptrChain->
signatures()[stepToConsider])->outputTEs()[0];
375 auto preFinalTEs = (ptrChain->
signatures()[stepToConsider-1])->outputTEs();
377 auto finalSeq =
m_configSvc->sequences().getSequence(finalTE->id());
378 std::set<HLT::te_id_type> tesInSeq;
379 std::set<HLT::te_id_type> tesInChain;
381 for (
auto te: finalSeq->inputTEs()) {
382 tesInSeq.insert(te->id());
385 for (
auto te: preFinalTEs) {
386 tesInChain.insert(te->id());
389 if (tesInSeq == tesInChain) {
390 return stepToConsider;
403 std::string
chainName = ptrChain->name();
422 std::map<HLT::te_id_type, HLT::te_id_type> etcutReplacementTEs;
423 auto etcutReplacement = [&etcutReplacementTEs](
HLT::te_id_type in) {
auto out = etcutReplacementTEs.find(in);
return (
out == etcutReplacementTEs.end() ? in :
out->second ); };
424 if (
chainName.find(
"etcut") != std::string::npos ) {
425 std::set<size_t> positionsOfEtCutLegs;
428 ATH_MSG_DEBUG(
"EtCut chains hack, chain with two etcut legs ");
429 positionsOfEtCutLegs.insert({0, 1});
431 ATH_MSG_DEBUG(
"EtCut chains hack, egamma chain with second etcut leg ");
432 positionsOfEtCutLegs.insert({1});
435 positionsOfEtCutLegs.insert({0});
439 std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
440 for (
auto ptrHLTSignature : ptrChain->signatures()) {
442 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
443 if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
444 etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
447 if ( ptrHLTTE->name().find(
"calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) {
448 positionToDesiredIDmap[position] = ptrHLTTE->id();
459 for (
auto ptrHLTSignature : ptrChain->signatures()) {
460 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
461 unsigned int teId = etcutReplacement(ptrHLTTE->id());
462 allTEs[
teId].insert(chainId);
463 if (ptrHLTSignature == ptrChain->signatures().back()) {
464 finalTEs[
teId].insert(chainId);
465 ATH_MSG_DEBUG(
"TE will be used to mark final chain decision " << ptrHLTTE->name() <<
" chain " <<
chainName );
484 std::vector<size_t> mult_hack;
487 ptrChain->set_leg_multiplicities(mult_hack);
492 std::vector<size_t> mult_hack;
495 ptrChain->set_leg_multiplicities(mult_hack);
499 std::vector<unsigned int> teIdsLastHealthyStepIds;
501 for (
auto ptrHLTSignature : ptrChain->signatures())
503 std::vector<int> teCounts;
504 std::vector<unsigned int> teIds;
505 unsigned int lastSeenId = 0;
506 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs())
508 if ( lastSeenId != ptrHLTTE->id()) {
509 teCounts.push_back(1);
510 teIds.push_back(ptrHLTTE->id());
514 lastSeenId = ptrHLTTE->id();
517 ATH_MSG_DEBUG(
"TE multiplicities seen in this step " << teCounts);
521 if ( multiplicityCounts ) {
522 teIdsLastHealthyStepIds = teIds;
523 ATH_MSG_DEBUG(
"There is a match, will assign chain leg IDs to TEs " << teCounts <<
" " << teIds);
524 for (
size_t legNumber = 0; legNumber < teIds.size(); ++ legNumber){
526 allTEs[etcutReplacement(teIds[legNumber])].insert(chainLegId);
530 for (
size_t legNumber = 0; legNumber < teIdsLastHealthyStepIds.size(); ++ legNumber ) {
533 ATH_MSG_DEBUG(
"created leg id " << chainLegId <<
" that will replace TE ID " << etcutReplacement(teIdsLastHealthyStepIds[legNumber]));
534 finalTEs[etcutReplacement(teIdsLastHealthyStepIds[legNumber])].insert(chainLegId);
538 ATH_MSG_DEBUG(
"Recognised " << allTEs.size() <<
" kinds of TEs and among them " << finalTEs.size() <<
" final types");
539 return StatusCode::SUCCESS;
545 std::vector<unsigned int> muons;
546 std::vector<unsigned int>
jets;
547 bool switchedTojets =
false;
548 for (
auto ptrHLTSignature : ptrChain->
signatures()) {
549 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
550 if ( ptrHLTTE->name().find(
"_mu") == std::string::npos ) {
551 switchedTojets =
true;
555 jets.push_back(ptrHLTTE->id());
557 muons.push_back(ptrHLTTE->id());
565 finalTEs[muons[0]].insert(chainId);
567 finalTEs[
jets[0]].insert(chainId);
572 allTEs[muons[
index]].insert(chainId);
576 return StatusCode::SUCCESS;
585 std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
593 convProxies.insert(
proxy);
594 teToProxy[te] =
proxy;
598 ConvProxy *predecessorProxy = teToProxy[predecessor];
599 if (predecessorProxy !=
nullptr)
601 proxy->parents.insert(predecessorProxy);
610 for (
auto proxy : convProxies)
614 for (
auto p :
proxy->children)
616 for (
auto p :
proxy->parents)
619 for (
auto p :
proxy->parents)
621 for (
auto pp :
p->parents)
629 for (
auto c :
proxy->children)
631 for (
auto cc :
c->children)
642 ATH_MSG_DEBUG(
"Created " << convProxies.size() <<
" proxy objects");
643 return StatusCode::SUCCESS;
649 const std::vector<std::function<
void(
const ConvProxy*)>>& printers)
const {
652 for (
auto p: proxies) {
655 for (
auto& printer: printers) {
666 for (
auto &ptrConvProxy : convProxies)
668 auto teId = ptrConvProxy->te->getId();
669 bool teActive = ptrConvProxy->te->getActiveState();
670 auto iter = allTEs.find(
teId);
671 if (iter != allTEs.end())
673 ptrConvProxy->runChains.insert(iter->second.begin(), iter->second.end());
676 ptrConvProxy->passChains.insert(iter->second.begin(), iter->second.end());
680 for (
auto &objTeIdToChain : allTEs)
682 if (
teId == objTeIdToChain.first)
684 for (
auto &chainId : objTeIdToChain.second)
686 (ptrConvProxy->runChains).insert(chainId);
692 return StatusCode::SUCCESS;
703 size_t numberOfUpdates = 0;
704 for (
auto p : convProxies)
706 for (
auto child :
p->children)
708 size_t startSize =
p->runChains.size();
711 if (startSize !=
p->runChains.size())
719 ATH_MSG_DEBUG(
"Needed to propagate chains from " << numberOfUpdates <<
" child(ren)");
720 if (numberOfUpdates == 0)
725 return StatusCode::SUCCESS;
733 if ((*i)->runChains.empty())
739 parent->children.erase(toDel);
743 child->parents.erase(toDel);
746 i = convProxies.erase(
i);
753 ATH_MSG_DEBUG(
"After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
754 return StatusCode::SUCCESS;
769 return StatusCode::SUCCESS;
772 template <
typename MAP>
776 std::vector<ConvProxy *> todelete;
777 for (
auto &[
key, proxies] : keyToProxyMap)
779 if (proxies.size() > 1)
781 ATH_MSG_DEBUG(
"Merging " << proxies.size() <<
" similar proxies");
782 for (
auto p : proxies)
784 if (
p->mergeAllowed(*proxies.begin()))
786 (*proxies.begin())->
merge(
p);
787 todelete.push_back(
p);
793 for (
auto proxy : todelete)
795 convProxies.erase(
proxy);
799 return StatusCode::SUCCESS;
805 const size_t beforeCount = convProxies.size();
806 std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
807 for (
auto proxy : convProxies)
820 for (
auto [feaHash, proxies] : feaToProxyMap)
822 auto first = *proxies.begin();
823 for (
auto p : proxies)
826 filterFEAs(
p->te->getFeatureAccessHelpers(), run2Nav))
828 ATH_MSG_ERROR(
"Proxies grouped by FEA hash have actually distinct features (specific FEAs are different)");
829 for (
auto id:
p->passChains )
ATH_MSG_ERROR(
"... chain id for this proxy " <<
id);
831 for (
auto fea:
first->te->getFeatureAccessHelpers() ) {
834 for (
auto fea:
p->te->getFeatureAccessHelpers() ) {
838 return StatusCode::FAILURE;
845 ATH_MSG_DEBUG(
"Proxies with features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
847 return StatusCode::SUCCESS;
853 struct ParentChildCharacteristics
857 size_t distanceFromParent = 0;
858 bool operator<(
const ParentChildCharacteristics &rhs)
const
861 return parent < rhs.parent;
862 if (child != rhs.child)
863 return child < rhs.child;
864 return distanceFromParent < rhs.distanceFromParent;
867 const size_t beforeCount = convProxies.size();
868 std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
869 for (
auto proxy : convProxies)
882 if (
proxy->children.size() == 1 and
883 std::all_of(
proxy->children.begin(),
proxy->children.end(), hasSomeFeatures ) and
884 proxy->parents.size() == 1 and
885 std::all_of(
proxy->parents.begin(),
proxy->parents.end(), hasSomeFeatures )
889 groupedProxies[{*(
proxy->parents.begin()), *(
proxy->children.begin()), 0}].insert(
proxy);
896 for (
auto pp :
proxy->parents)
901 for (
auto cp :
proxy->children)
910 ATH_MSG_DEBUG(
"Proxies without features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
911 return StatusCode::SUCCESS;
918 if ((*i)->parents.size() > 1)
924 parent->children.erase(toDel);
928 child->parents.erase(toDel);
931 i = convProxies.erase(
i);
938 return StatusCode::SUCCESS;
944 for (
auto &
proxy : convProxies)
946 if (
proxy->te !=
nullptr)
963 return StatusCode::SUCCESS;
970 auto ordered_sorter = [&setRoiName = std::as_const(
m_setRoiName)](
const std::string &left,
const std::string &right) ->
bool
972 return std::find(cbegin(setRoiName), cend(setRoiName), left) <
std::find(cbegin(setRoiName), cend(setRoiName), right);
977 for (
auto &
proxy : convProxies)
981 ATH_MSG_DEBUG(
"Several RoIs pointing to a proxy, taking latest one for now");
997 [](
const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &
p)
998 { return p.second; });
1002 std::set<const ConvProxy*> visited;
1003 std::function<void(std::set<ConvProxy *> &,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &)>
1004 roiPropagator = [&](std::set<ConvProxy *> &convProxyChildren,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &roiParent)
1006 for (
auto &proxyChild : convProxyChildren)
1008 if ( visited.count(proxyChild) == 1 ) {
1011 visited.insert(proxyChild);
1012 if (proxyChild->rois.empty())
1014 proxyChild->rois = roiParent;
1015 if (proxyChild->children.empty() ==
false)
1017 roiPropagator(proxyChild->children, roiParent);
1023 for (
auto &
proxy : convProxies)
1028 return StatusCode::SUCCESS;
1033 for (
auto &
proxy : convProxies)
1044 return StatusCode::SUCCESS;
1049 for (
auto &
proxy : convProxies)
1052 for (
auto chainId :
proxy->runChains)
1057 for (
auto chainId :
proxy->passChains)
1065 for (
auto &
proxy : convProxies)
1067 for (
auto &parentProxy :
proxy->parents)
1073 return StatusCode::SUCCESS;
1083 sfNode->setName(
"SF");
1086 for (
auto chainId : chainIds)
1093 else if (chainId.numeric() == idStore)
1103 if (
proxy->hNode.empty())
1106 makeSingleSFNode(
proxy->imNode,
proxy->runChains, idToStore);
1111 for (
auto &hNode :
proxy->hNode)
1113 makeSingleSFNode(hNode,
proxy->passChains, idToStore);
1118 for (
auto proxy : convProxies)
1121 if (
proxy->children.empty())
1129 std::vector<TCU::DecisionID> toRetain;
1132 auto whereInMap = terminalIds.find(
teId);
1133 if (whereInMap != terminalIds.end())
1135 toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1138 for (
auto chainIdstore : toRetain)
1140 makeSFNodes(
proxy, chainIdstore);
1147 return StatusCode::SUCCESS;
1170 return StatusCode::FAILURE;
1175 filteredIDs.insert(idToCheck);
1178 terminus->
setDecisions( std::vector<TCU::DecisionID>() );
1181 "the terminus node goes from " << currentIDs.size() <<
" to " << filteredIDs.size() <<
" chain IDs.");
1189 return StatusCode::SUCCESS;
1193 const EventContext &context)
const
1196 auto makeL1Node = [&
decisions, &context](
auto firstDecisionNode,
auto chainIds)
1200 for (
auto chainId : chainIds)
1209 for (
auto &
proxy : convProxies)
1212 if (
proxy->parents.empty())
1219 return StatusCode::SUCCESS;
1225 if (
proxy.features.empty())
1229 for (
const auto &fea :
proxy.features)
1231 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1235 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1247 for (
const auto &
proxy : convProxies)
1255 for (
auto chainId :
proxy->passChains)
1262 for (
auto &childProxy :
proxy->children)
1269 if (
proxy->features.empty())
1275 auto hNodeIter =
proxy->hNode.begin();
1276 for (
auto &fea :
proxy->features)
1278 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1280 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1286 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1295 return StatusCode::SUCCESS;
1301 for (
auto &
proxy : convProxies)
1303 for (
auto &roi :
proxy->rois)
1305 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1310 if (
proxy->rois.empty() ==
false)
1317 return StatusCode::SUCCESS;
1322 for (
auto &
proxy : convProxies)
1324 for (
auto &trk :
proxy->tracks)
1334 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, trk);
1338 auto d = std::make_unique<TrigCompositeUtils::Decision>();
1339 d->makePrivateStore();
1340 d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1345 if (
track.isValid())
1348 viewBookkeeper(*
t) = ROIElementLink;
1356 if (
track.isValid())
1359 viewBookkeeper(*
t) = ROIElementLink;
1366 ATH_MSG_WARNING(
"Unable to create an ElementLink into a container with no entries");
1372 return StatusCode::SUCCESS;
1381 return fea.
getCLID() == thePassBitsCLID or fea.
getCLID() == thePassBitsContCLID;
1385 std::vector<HLT::TriggerElement::FeatureAccessHelper>
out;
1386 for (
auto fea : feaVector)
1394 auto [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1398 ATH_MSG_VERBOSE(
"Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName <<
" FEA " << fea);
1411 for (
auto fea :
filterFEAs(feaVector, navigationDecoder))
1413 ATH_MSG_VERBOSE(
"Including FEA in hash CLID: " << fea.getCLID() <<
" te Id: " << te_ptr->
getId());
1414 boost::hash_combine(
hash, fea.getCLID());
1415 boost::hash_combine(
hash, fea.getIndex().subTypeIndex());
1416 boost::hash_combine(
hash, fea.getIndex().objectsBegin());
1417 boost::hash_combine(
hash, fea.getIndex().objectsEnd());
1428 if ( iter->second.empty() )
1430 ATH_MSG_DEBUG(
"fea to save CLID: " << fea.
getCLID() <<
", sgName: " << sgName <<
" " <<iter->second.size() <<
" " << iter->second.empty() );
1431 return iter->second.contains(sgName);
1441 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1452 for (
auto p : proxies)
1454 if (
p->runChains.empty())
1457 return StatusCode::FAILURE;
1461 return StatusCode::SUCCESS;
1466 for (
auto p : proxies)
1468 if (
p->children.empty() and
p->parents.empty() and not
p->runChains.empty())
1470 ATH_MSG_ERROR(
"Orphanted proxy N chains run:" <<
p->runChains.size());
1471 return StatusCode::FAILURE;
1475 return StatusCode::SUCCESS;
1480 ATH_MSG_DEBUG(
"CHECK OK, no excessive number of H nodes per proxy");
1481 return StatusCode::SUCCESS;
1487 std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1490 if (
d->name() ==
"IM" or
d->name() ==
"FS")
1494 linkedHNodes.insert(*
el);
1500 if (
d->name() ==
"H")
1502 if (linkedHNodes.count(
d) == 0)
1505 return StatusCode::FAILURE;
1511 return StatusCode::SUCCESS;
1516 const std::string hltLabel = navigationDecoder.
label(
helper.getCLID(),
helper.getIndex().subTypeIndex());
1518 const CLID saveCLID = [&](
const CLID &clid)
1529 std::string type_name;
1530 if (
m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1540 return {0, saveCLID,
""};
1543 return {
evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel};