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)
185 ATH_MSG_ERROR(
"Not support for specific collection name yet");
186 return StatusCode::FAILURE;
188 collName =
name.substr(delimeterIndex + 1);
204 if (keysSet.size() > 1 and keysSet.count(
"") != 0)
206 ATH_MSG_ERROR(
"Bad configuration for CLID " << clid <<
" reuested saving of all (empty coll name configures) collections, yet there are also specific keys");
207 return StatusCode::FAILURE;
212 bool anyChainBad=
false;
214 if (
chain.find(
'*') != std::string::npos or
chain.find(
'|') != std::string::npos ) {
215 ATH_MSG_ERROR(
"Supplied chain name: " <<
chain <<
" contains wildcard characters, this is not supported by the conversion tool");
220 ATH_MSG_ERROR(
"Supplied chain names contain wildcard characters, this is not supported by the conversion tool");
221 return StatusCode::FAILURE;
224 ATH_MSG_INFO(
"No chains list supplied, the conversion will occur for all chains");
238 return StatusCode::SUCCESS;
243 return StatusCode::SUCCESS;
267 standaloneNav.
deserialize(navReadHandle->serialized());
268 run2NavigationPtr = &standaloneNav;
272 run2NavigationPtr =
m_tdt->ExperimentalAndExpertMethods().getNavigation();
296 ATH_MSG_DEBUG(
"Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
311 auto decisionOutput = outputNavigation.
ptr();
334 ATH_MSG_DEBUG(
"Conversion done, from " << convProxies.size() <<
" elements to " << decisionOutput->size() <<
" elements");
340 for (
auto o: *decisionOutput) {
346 for (
auto proxy : convProxies)
351 return StatusCode::SUCCESS;
365 size_t stepToConsider = 0;
366 const size_t sigsSize = ptrChain->
signatures().size();
367 if ( sigsSize < 2 )
return 0;
370 stepToConsider =
step;
374 if ( stepToConsider == 0 )
return 0;
377 auto finalTE = (ptrChain->
signatures()[stepToConsider])->outputTEs()[0];
378 auto preFinalTEs = (ptrChain->
signatures()[stepToConsider-1])->outputTEs();
380 auto finalSeq =
m_configSvc->sequences().getSequence(finalTE->id());
381 std::set<HLT::te_id_type> tesInSeq;
382 std::set<HLT::te_id_type> tesInChain;
384 for (
auto te: finalSeq->inputTEs()) {
385 tesInSeq.insert(te->id());
388 for (
auto te: preFinalTEs) {
389 tesInChain.insert(te->id());
392 if (tesInSeq == tesInChain) {
393 return stepToConsider;
406 std::string
chainName = ptrChain->name();
417 std::map<HLT::te_id_type, HLT::te_id_type> etcutReplacementTEs;
418 auto etcutReplacement = [&etcutReplacementTEs](
HLT::te_id_type in) {
auto out = etcutReplacementTEs.find(in);
return (
out == etcutReplacementTEs.end() ? in :
out->second ); };
419 if (
chainName.find(
"etcut") != std::string::npos ) {
420 std::set<size_t> positionsOfEtCutLegs;
423 ATH_MSG_DEBUG(
"EtCut chains hack, chain with two etcut legs ");
424 positionsOfEtCutLegs.insert({0, 1});
426 ATH_MSG_DEBUG(
"EtCut chains hack, egamma chain with second etcut leg ");
427 positionsOfEtCutLegs.insert({1});
430 positionsOfEtCutLegs.insert({0});
434 std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
435 for (
auto ptrHLTSignature : ptrChain->signatures()) {
437 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
438 if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
439 etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
442 if ( ptrHLTTE->name().find(
"calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) {
443 positionToDesiredIDmap[position] = ptrHLTTE->id();
454 for (
auto ptrHLTSignature : ptrChain->signatures()) {
455 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
456 unsigned int teId = etcutReplacement(ptrHLTTE->id());
457 allTEs[
teId].insert(chainId);
458 if (ptrHLTSignature == ptrChain->signatures().back()) {
459 finalTEs[
teId].insert(chainId);
460 ATH_MSG_DEBUG(
"TE will be used to mark final chain decision " << ptrHLTTE->name() <<
" chain " <<
chainName );
486 std::vector<unsigned int> teIdsLastHealthyStepIds;
488 for (
auto ptrHLTSignature : ptrChain->signatures())
490 std::vector<int> teCounts;
491 std::vector<unsigned int> teIds;
492 unsigned int lastSeenId = 0;
493 for (
auto ptrHLTTE : ptrHLTSignature->outputTEs())
495 if ( lastSeenId != ptrHLTTE->id()) {
496 teCounts.push_back(1);
497 teIds.push_back(ptrHLTTE->id());
501 lastSeenId = ptrHLTTE->id();
504 ATH_MSG_DEBUG(
"TE multiplicities seen in this step " << teCounts);
508 if ( multiplicityCounts ) {
509 teIdsLastHealthyStepIds = teIds;
510 ATH_MSG_DEBUG(
"There is a match, will assign chain leg IDs to TEs " << teCounts <<
" " << teIds);
511 for (
size_t legNumber = 0; legNumber < teIds.size(); ++ legNumber){
513 allTEs[etcutReplacement(teIds[legNumber])].insert(chainLegId);
517 for (
size_t legNumber = 0; legNumber < teIdsLastHealthyStepIds.size(); ++ legNumber ) {
520 ATH_MSG_DEBUG(
"created leg id " << chainLegId <<
" that will replace TE ID " << etcutReplacement(teIdsLastHealthyStepIds[legNumber]));
521 finalTEs[etcutReplacement(teIdsLastHealthyStepIds[legNumber])].insert(chainLegId);
526 ATH_MSG_DEBUG(
"Recognised " << allTEs.size() <<
" kinds of TEs and among them " << finalTEs.size() <<
" final types");
527 return StatusCode::SUCCESS;
534 std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
542 convProxies.insert(
proxy);
543 teToProxy[te] =
proxy;
547 ConvProxy *predecessorProxy = teToProxy[predecessor];
548 if (predecessorProxy !=
nullptr)
550 proxy->parents.insert(predecessorProxy);
559 for (
auto proxy : convProxies)
563 for (
auto p :
proxy->children)
565 for (
auto p :
proxy->parents)
568 for (
auto p :
proxy->parents)
570 for (
auto pp :
p->parents)
578 for (
auto c :
proxy->children)
580 for (
auto cc :
c->children)
591 ATH_MSG_DEBUG(
"Created " << convProxies.size() <<
" proxy objects");
592 return StatusCode::SUCCESS;
598 const std::vector<std::function<
void(
const ConvProxy*)>>& printers)
const {
601 for (
auto p: proxies) {
604 for (
auto& printer: printers) {
615 for (
auto &ptrConvProxy : convProxies)
617 auto teId = ptrConvProxy->te->getId();
618 bool teActive = ptrConvProxy->te->getActiveState();
619 auto iter = allTEs.find(
teId);
620 if (iter != allTEs.end())
622 ptrConvProxy->runChains.insert(iter->second.begin(), iter->second.end());
625 ptrConvProxy->passChains.insert(iter->second.begin(), iter->second.end());
629 for (
auto &objTeIdToChain : allTEs)
631 if (
teId == objTeIdToChain.first)
633 for (
auto &chainId : objTeIdToChain.second)
635 (ptrConvProxy->runChains).insert(chainId);
641 return StatusCode::SUCCESS;
652 size_t numberOfUpdates = 0;
653 for (
auto p : convProxies)
655 for (
auto child :
p->children)
657 size_t startSize =
p->runChains.size();
660 if (startSize !=
p->runChains.size())
668 ATH_MSG_DEBUG(
"Needed to propagate chains from " << numberOfUpdates <<
" child(ren)");
669 if (numberOfUpdates == 0)
674 return StatusCode::SUCCESS;
682 if ((*i)->runChains.empty())
688 parent->children.erase(toDel);
692 child->parents.erase(toDel);
695 i = convProxies.erase(
i);
702 ATH_MSG_DEBUG(
"After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
703 return StatusCode::SUCCESS;
718 return StatusCode::SUCCESS;
721 template <
typename MAP>
725 std::vector<ConvProxy *> todelete;
726 for (
auto &[
key, proxies] : keyToProxyMap)
728 if (proxies.size() > 1)
730 ATH_MSG_DEBUG(
"Merging " << proxies.size() <<
" similar proxies");
731 for (
auto p : proxies)
733 if (
p->mergeAllowed(*proxies.begin()))
735 (*proxies.begin())->
merge(
p);
736 todelete.push_back(
p);
742 for (
auto proxy : todelete)
744 convProxies.erase(
proxy);
748 return StatusCode::SUCCESS;
754 const size_t beforeCount = convProxies.size();
755 std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
756 for (
auto proxy : convProxies)
769 for (
auto [feaHash, proxies] : feaToProxyMap)
771 auto first = *proxies.begin();
772 for (
auto p : proxies)
775 filterFEAs(
p->te->getFeatureAccessHelpers(), run2Nav))
777 ATH_MSG_ERROR(
"Proxies grouped by FEA hash have actually distinct features (specific FEAs are different)");
778 for (
auto id:
p->passChains )
ATH_MSG_ERROR(
"... chain id for this proxy " <<
id);
780 for (
auto fea:
first->te->getFeatureAccessHelpers() ) {
783 for (
auto fea:
p->te->getFeatureAccessHelpers() ) {
787 return StatusCode::FAILURE;
794 ATH_MSG_DEBUG(
"Proxies with features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
796 return StatusCode::SUCCESS;
802 struct ParentChildCharacteristics
806 size_t distanceFromParent = 0;
807 bool operator<(
const ParentChildCharacteristics &rhs)
const
810 return parent < rhs.parent;
811 if (child != rhs.child)
812 return child < rhs.child;
813 return distanceFromParent < rhs.distanceFromParent;
816 const size_t beforeCount = convProxies.size();
817 std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
818 for (
auto proxy : convProxies)
831 if (
proxy->children.size() == 1 and
832 std::all_of(
proxy->children.begin(),
proxy->children.end(), hasSomeFeatures ) and
833 proxy->parents.size() == 1 and
834 std::all_of(
proxy->parents.begin(),
proxy->parents.end(), hasSomeFeatures )
838 groupedProxies[{*(
proxy->parents.begin()), *(
proxy->children.begin()), 0}].insert(
proxy);
845 for (
auto pp :
proxy->parents)
850 for (
auto cp :
proxy->children)
859 ATH_MSG_DEBUG(
"Proxies without features collapsing reduces size from " << beforeCount <<
" to " << convProxies.size());
860 return StatusCode::SUCCESS;
867 if ((*i)->parents.size() > 1)
873 parent->children.erase(toDel);
877 child->parents.erase(toDel);
880 i = convProxies.erase(
i);
887 return StatusCode::SUCCESS;
893 for (
auto &
proxy : convProxies)
895 if (
proxy->te !=
nullptr)
912 return StatusCode::SUCCESS;
919 auto ordered_sorter = [&setRoiName = std::as_const(
m_setRoiName)](
const std::string &left,
const std::string &right) ->
bool
921 return std::find(cbegin(setRoiName), cend(setRoiName), left) <
std::find(cbegin(setRoiName), cend(setRoiName), right);
926 for (
auto &
proxy : convProxies)
930 ATH_MSG_DEBUG(
"Several RoIs pointing to a proxy, taking latest one for now");
946 [](
const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &
p)
947 { return p.second; });
951 std::set<const ConvProxy*> visited;
952 std::function<void(std::set<ConvProxy *> &,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &)>
953 roiPropagator = [&](std::set<ConvProxy *> &convProxyChildren,
const std::vector<HLT::TriggerElement::FeatureAccessHelper> &roiParent)
955 for (
auto &proxyChild : convProxyChildren)
957 if ( visited.count(proxyChild) == 1 ) {
960 visited.insert(proxyChild);
961 if (proxyChild->rois.empty())
963 proxyChild->rois = roiParent;
964 if (proxyChild->children.empty() ==
false)
966 roiPropagator(proxyChild->children, roiParent);
972 for (
auto &
proxy : convProxies)
977 return StatusCode::SUCCESS;
982 for (
auto &
proxy : convProxies)
993 return StatusCode::SUCCESS;
998 for (
auto &
proxy : convProxies)
1001 for (
auto chainId :
proxy->runChains)
1006 for (
auto chainId :
proxy->passChains)
1014 for (
auto &
proxy : convProxies)
1016 for (
auto &parentProxy :
proxy->parents)
1022 return StatusCode::SUCCESS;
1032 sfNode->setName(
"SF");
1035 for (
auto chainId : chainIds)
1042 else if (chainId.numeric() == idStore)
1052 if (
proxy->hNode.empty())
1055 makeSingleSFNode(
proxy->imNode,
proxy->runChains, idToStore);
1060 for (
auto &hNode :
proxy->hNode)
1062 makeSingleSFNode(hNode,
proxy->passChains, idToStore);
1067 for (
auto proxy : convProxies)
1070 if (
proxy->children.empty())
1078 std::vector<TCU::DecisionID> toRetain;
1081 auto whereInMap = terminalIds.find(
teId);
1082 if (whereInMap != terminalIds.end())
1084 toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1087 for (
auto chainIdstore : toRetain)
1089 makeSFNodes(
proxy, chainIdstore);
1096 return StatusCode::SUCCESS;
1119 return StatusCode::FAILURE;
1124 filteredIDs.insert(idToCheck);
1127 terminus->
setDecisions( std::vector<TCU::DecisionID>() );
1130 "the terminus node goes from " << currentIDs.size() <<
" to " << filteredIDs.size() <<
" chain IDs.");
1138 return StatusCode::SUCCESS;
1142 const EventContext &context)
const
1145 auto makeL1Node = [&
decisions, &context](
auto firstDecisionNode,
auto chainIds)
1149 for (
auto chainId : chainIds)
1158 for (
auto &
proxy : convProxies)
1161 if (
proxy->parents.empty())
1168 return StatusCode::SUCCESS;
1174 if (
proxy.features.empty())
1178 for (
const auto &fea :
proxy.features)
1180 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1184 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1196 for (
const auto &
proxy : convProxies)
1204 for (
auto chainId :
proxy->passChains)
1211 for (
auto &childProxy :
proxy->children)
1218 if (
proxy->features.empty())
1224 auto hNodeIter =
proxy->hNode.begin();
1225 for (
auto &fea :
proxy->features)
1227 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, fea);
1228 if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1234 for (
auto n = fea.getIndex().objectsBegin();
n < fea.getIndex().objectsEnd(); ++
n)
1243 return StatusCode::SUCCESS;
1249 for (
auto &
proxy : convProxies)
1251 for (
auto &roi :
proxy->rois)
1253 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1258 if (
proxy->rois.empty() ==
false)
1265 return StatusCode::SUCCESS;
1270 for (
auto &
proxy : convProxies)
1272 for (
auto &trk :
proxy->tracks)
1282 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, trk);
1286 auto d = std::make_unique<TrigCompositeUtils::Decision>();
1287 d->makePrivateStore();
1288 d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1293 if (
track.isValid())
1296 viewBookkeeper(*
t) = ROIElementLink;
1304 if (
track.isValid())
1307 viewBookkeeper(*
t) = ROIElementLink;
1314 ATH_MSG_WARNING(
"Unable to create an ElementLink into a container with no entries");
1320 return StatusCode::SUCCESS;
1329 return fea.
getCLID() == thePassBitsCLID or fea.
getCLID() == thePassBitsContCLID;
1333 std::vector<HLT::TriggerElement::FeatureAccessHelper>
out;
1334 for (
auto fea : feaVector)
1342 auto [sgKey, sgCLID, sgName] =
getSgKey(navigationDecoder, fea);
1346 ATH_MSG_VERBOSE(
"Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName <<
" FEA " << fea);
1359 for (
auto fea :
filterFEAs(feaVector, navigationDecoder))
1361 ATH_MSG_VERBOSE(
"Including FEA in hash CLID: " << fea.getCLID() <<
" te Id: " << te_ptr->
getId());
1362 boost::hash_combine(
hash, fea.getCLID());
1363 boost::hash_combine(
hash, fea.getIndex().subTypeIndex());
1364 boost::hash_combine(
hash, fea.getIndex().objectsBegin());
1365 boost::hash_combine(
hash, fea.getIndex().objectsEnd());
1383 auto [sgKey, sgCLID, sgName] =
getSgKey(run2Nav, roi);
1394 for (
auto p : proxies)
1396 if (
p->runChains.empty())
1399 return StatusCode::FAILURE;
1403 return StatusCode::SUCCESS;
1408 for (
auto p : proxies)
1410 if (
p->children.empty() and
p->parents.empty() and not
p->runChains.empty())
1412 ATH_MSG_ERROR(
"Orphanted proxy N chains run:" <<
p->runChains.size());
1413 return StatusCode::FAILURE;
1417 return StatusCode::SUCCESS;
1422 ATH_MSG_DEBUG(
"CHECK OK, no excessive number of H nodes per proxy");
1423 return StatusCode::SUCCESS;
1429 std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1432 if (
d->name() ==
"IM" or
d->name() ==
"FS")
1436 linkedHNodes.insert(*
el);
1442 if (
d->name() ==
"H")
1444 if (linkedHNodes.count(
d) == 0)
1447 return StatusCode::FAILURE;
1453 return StatusCode::SUCCESS;
1458 const std::string hltLabel = navigationDecoder.
label(
helper.getCLID(),
helper.getIndex().subTypeIndex());
1460 const CLID saveCLID = [&](
const CLID &clid)
1471 std::string type_name;
1472 if (
m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1482 return {0, saveCLID,
""};
1485 return {
evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel};