ATLAS Offline Software
Run2ToRun3TrigNavConverterV2.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <boost/functional/hash.hpp>
6 #include <GaudiKernel/StatusCode.h>
7 #include "AthLinks/ElementLinkVector.h"
16 #include "SpecialCases.h"
17 #include <limits>
18 #include <cstdint>
19 
20 namespace TCU = TrigCompositeUtils;
21 
22 // helper class
24 {
25  teIDs.push_back(te->getId());
26 }
27 
28 // find if proxy is a child of other proxies, also follows to children of the children etc...
29 bool ConvProxy::isChild(const ConvProxy* other ) const {
30  for ( auto c: children ) {
31  if (other == c)
32  return true;
33  if ( c->isChild(other) )
34  return true;
35  }
36  return false;
37 }
38 
39 bool ConvProxy::isParent(const ConvProxy* other ) const {
40  for ( auto c: parents ) {
41  if (other == c)
42  return true;
43  if ( c->isParent(other) )
44  return true;
45  }
46  return false;
47 }
48 
49 
51 {
52  if (this == other)
53  return false; // no merging with self
54  // never merge children with parents
55  if ( isChild(other) )
56  return false;
57  if ( isParent(other) )
58  return false;
59  return true;
60 }
61 
63 {
64  if (other == this)
65  {
66  return;
67  }
68  // copy over chains
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());
72  /* the intention of the code below is following.
73  Intial structure like is like this (the line is always bidirectional):
74  P1 P2 P3 <- parents
75  | | /
76  T1 T2 <- "this" and "other"
77  | |
78  C1 C2 <- children
79  1) Lets assume that the first proxies we treat are B1 & B2 ath they are mergable. The resulting structure should look like this:
80  P1 P2 P3
81  |/__/
82  T1 T2
83  |\
84  C1 C2
85 
86  */
87  auto add = [](ConvProxy *toadd, std::set<ConvProxy *> &coll)
88  {
89  if (std::find(coll.begin(), coll.end(), toadd) == coll.end())
90  {
91  coll.insert(toadd);
92  }
93  };
94 
95  auto remove = [](ConvProxy *torem, std::set<ConvProxy *> &coll)
96  {
97  auto place = std::find(coll.begin(), coll.end(), torem);
98  if (place != coll.end())
99  {
100  coll.erase(place);
101  }
102  };
103 
104  // this is T <-> C connection
105  for (auto otherChild : other->children)
106  {
107  add(otherChild, children);
108  add(this, otherChild->parents);
109  }
110  // this is T <-> P connection rewiring
111  for (auto otherParent : other->parents)
112  {
113  add(otherParent, parents);
114  add(this, otherParent->children);
115  }
116 
117  // now need to remove links back to the "other"
118  for (auto otherParent : other->parents)
119  {
120  remove(other, otherParent->children);
121  }
122 
123  for (auto otherChild : other->children)
124  {
125  remove(other, otherChild->parents);
126  }
127  other->children.clear();
128  other->parents.clear();
129 }
130 
131 std::string ConvProxy::description() const
132 {
133  std::string ret;
134  ret += " N parents: " + std::to_string(parents.size());
135  ret += " N children: " + std::to_string(children.size());
136  std::ostringstream os;
137  for ( auto c: children )
138  os << c << " ";
139  ret += " ptrs: " + os.str();
140  ret += " feaHash: " + std::to_string(feaHash);
141  ret += " N run chains: " + std::to_string(runChains.size());
142  return ret;
143 }
144 
145 // the algorithm
146 Run2ToRun3TrigNavConverterV2::Run2ToRun3TrigNavConverterV2(const std::string &name, ISvcLocator *pSvcLocator) : AthReentrantAlgorithm(name, pSvcLocator)
147 {
148 }
149 
151 {
152 }
153 
155 {
156  ATH_CHECK(m_trigOutputNavKey.initialize());
157  ATH_CHECK(m_tdt.empty() != m_trigNavKey.key().empty()); // either of the two has to be enabled but not both
158  if (!m_tdt.empty())
159  {
160  ATH_CHECK(m_tdt.retrieve());
161  ATH_MSG_INFO("Will use Trigger Navigation from TrigDecisionTool");
162  }
163  else
164  {
166  ATH_MSG_INFO("Will use Trigger Navigation decoded from TrigNavigation object");
167  }
168 
169  if (!m_chainsToSave.empty()) {
170  ATH_MSG_DEBUG("Will only save features for these chains " << m_chainsToSave);
171  }
172 
173  ATH_CHECK(m_configSvc.retrieve());
174  ATH_CHECK(m_clidSvc.retrieve());
175 
176  // configured collections can be either just type name, or type#key
177  // decoding takes this into account, if only the type is configured then empty string is places in the decoded lookup map
178  // else CLID + a name is placed
179 
180  for (const auto &name : m_collectionsToSave)
181  {
182  std::string typeName = name;
183  std::string collName;
184  size_t delimeterIndex = name.find('#');
185  if (delimeterIndex != std::string::npos)
186  {
187  typeName = name.substr(0, delimeterIndex);
188  collName = name.substr(delimeterIndex + 1);
189  }
190  CLID id{0};
191  ATH_CHECK(m_clidSvc->getIDOfTypeName(typeName, id));
192  ATH_MSG_DEBUG("Will be linking collection type " << typeName << " name (empty==all) " << collName);
193  if ( collName.empty() )
194  m_collectionsToSaveDecoded[id]; // creates empty set
195  else
196  m_collectionsToSaveDecoded[id].insert(collName);
197  }
198 
199  for (const auto &name : m_roisToSave)
200  {
201  m_setRoiName.push_back(name);
202  }
203 
204  // sanity check, i.e. if there is at least one entry w/o the coll name no other entries are needed for a given clid
205  for (auto [clid, keysSet] : m_collectionsToSaveDecoded)
206  {
207  if (keysSet.size() > 1 and keysSet.count("") != 0)
208  {
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;
211  }
212 
213  }
214 
215  bool anyChainBad=false;
216  for ( auto chain: m_chainsToSave ) {
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");
219  anyChainBad=true;
220  }
221  }
222  if ( anyChainBad ) {
223  ATH_MSG_ERROR("Supplied chain names contain wildcard characters, this is not supported by the conversion tool");
224  return StatusCode::FAILURE;
225  }
226  if ( m_chainsToSave.empty() ) {
227  ATH_MSG_INFO("No chains list supplied, the conversion will occur for all chains");
228  }
229 
230  ATH_CHECK(m_clidSvc->getIDOfTypeName("TrigRoiDescriptor", m_roIDescriptorCLID));
231  ATH_CHECK(m_clidSvc->getIDOfTypeName("TrigRoiDescriptorCollection", m_roIDescriptorCollectionCLID));
232  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TrigRingerRings", m_TrigRingerRingsCLID));
233  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TrigRingerRingsContainer", m_TrigRingerRingsContainerCLID));
234  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TrigEMCluster", m_TrigEMClusterCLID));
235  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TrigEMClusterContainer", m_TrigEMClusterContainerCLID));
236  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::CaloCluster", m_CaloClusterCLID));
237  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::CaloClusterContainer", m_CaloClusterContainerCLID));
238  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TrackParticleContainer", m_TrackParticleContainerCLID));
239  ATH_CHECK(m_clidSvc->getIDOfTypeName("xAOD::TauTrackContainer", m_TauTrackContainerCLID));
240 
241  return StatusCode::SUCCESS;
242 }
243 
245 {
246  return StatusCode::SUCCESS;
247 }
248 
249 StatusCode Run2ToRun3TrigNavConverterV2::execute(const EventContext &context) const
250 {
251  {
252  // configuration reading could not be done before the event loop
253  // it needs to be done only once though
254  std::scoped_lock lock(m_configUpdateMutex);
255  if (m_allTEIdsToChains.empty())
257  }
258 
259  ConvProxySet_t convProxies;
260  HLT::StandaloneNavigation standaloneNav; // needed to keep TEs around, so it is out of the scope where it is filled and referenced
261  const HLT::TrigNavStructure *run2NavigationPtr = nullptr;
262  if (!m_trigNavKey.key().empty())
263  {
264  SG::ReadHandle navReadHandle(m_trigNavKey, context);
265  ATH_CHECK(navReadHandle.isValid());
266  standaloneNav.deserialize(navReadHandle->serialized());
267  run2NavigationPtr = &standaloneNav;
268  }
269  else
270  {
271  run2NavigationPtr = m_tdt->ExperimentalAndExpertMethods().getNavigation();
272  }
273 
274  ATH_CHECK(mirrorTEsStructure(convProxies, *run2NavigationPtr));
275  // printProxies(convProxies, [](auto ){ return true;},
276  // {m_chainIdsPrinter});
277 
278  if (m_doSelfValidation)
279  ATH_CHECK(allProxiesConnected(convProxies));
280 
282  // printProxies(convProxies, [](auto ){ return true;},
283  // {m_chainIdsPrinter});
284 
285  ATH_CHECK(cureUnassociatedProxies(convProxies));
286  ATH_MSG_DEBUG("Proxies to chains mapping done");
287 
288  ATH_CHECK(removeTopologicalProxies(convProxies));
289 
290  if (not m_chainsToSave.empty())
291  {
292  ATH_CHECK(removeUnassociatedProxies(convProxies));
293  printProxies(convProxies, [](auto ){ return true;},
295  ATH_MSG_DEBUG("Removed proxies to chains that are not converted, remaining number of elements " << convProxies.size());
296  }
297  if (m_doSelfValidation)
298  {
299  ATH_CHECK(allProxiesHaveChain(convProxies));
300  }
301  if (m_doCompression)
302  {
303  ATH_CHECK(doCompression(convProxies, *run2NavigationPtr));
304  // printProxies(convProxies, [](auto ){ return true;},
305  // {m_chainIdsPrinter});
306 
307  }
308 
310  auto decisionOutput = outputNavigation.ptr();
311  TrigCompositeUtils::newDecisionIn(decisionOutput, TCU::summaryPassNodeName()); // we rely on the fact that the 1st element is the top
312 
313  if (m_doLinkFeatures)
314  {
315  ATH_CHECK(fillRelevantFeatures(convProxies, *run2NavigationPtr));
316  ATH_CHECK(fillRelevantRois(convProxies, *run2NavigationPtr));
317  ATH_CHECK(fillRelevantTracks(convProxies));
318  ATH_MSG_DEBUG("Features to link found");
319  }
320 
321  ATH_CHECK(createIMHNodes(convProxies, *decisionOutput, context));
322  if (m_doSelfValidation)
323  {
325  }
326 
327  ATH_CHECK(createL1Nodes(convProxies, *decisionOutput, context));
328  ATH_CHECK(linkFeaNode(convProxies, *decisionOutput, *run2NavigationPtr, context));
329  ATH_CHECK(linkRoiNode(convProxies, *run2NavigationPtr));
330  ATH_CHECK(linkTrkNode(convProxies, *run2NavigationPtr));
331  ATH_CHECK(createSFNodes(convProxies, *decisionOutput, m_finalTEIdsToChains, context));
332  ATH_CHECK(updateTerminusNode(*decisionOutput, context));
333  ATH_MSG_DEBUG("Conversion done, from " << convProxies.size() << " elements to " << decisionOutput->size() << " elements");
334 
335  printProxies(convProxies, [](auto ){ return true;},
337  ATH_MSG_DEBUG("Resulting nodes");
338  size_t index = 0;
339  for ( auto o: *decisionOutput) {
340  ATH_MSG_DEBUG("Index: " << index << " " << *o);
341  index++;
342  }
343 
344  // dispose temporaries
345  for (auto proxy : convProxies)
346  {
347  delete proxy;
348  }
349 
350  return StatusCode::SUCCESS;
351 }
352 
354  // chains of configs structure
355  // A B
356  // \/
357  // C
358  // where C is the output TE of sequence consuming A & B
359  // sometimes there are an additional leafs
360  // C
361  // |
362  // D
363  if ( not std::regex_match(ptrChain->name(), SpecialCases::isTopo) ) return 0;
364  size_t stepToConsider = 0;
365  const size_t sigsSize = ptrChain->signatures().size();
366  if ( sigsSize < 2 ) return 0;
367  for ( size_t step = sigsSize-1; step > 1; step --) {
368  if ( (ptrChain->signatures()[step-1])->outputTEs().size() == 2 and (ptrChain->signatures()[step])->outputTEs().size() == 1 ) {
369  stepToConsider = step;
370  break;
371  }
372  }
373  if ( stepToConsider == 0 ) return 0; // not a topo
374 
375  //counting is right, need to see now if TEs are connected
376  auto finalTE = (ptrChain->signatures()[stepToConsider])->outputTEs()[0];
377  auto preFinalTEs = (ptrChain->signatures()[stepToConsider-1])->outputTEs();
378 
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;
382 
383  for ( auto te: finalSeq->inputTEs()) {
384  tesInSeq.insert(te->id());
385  }
386 
387  for ( auto te: preFinalTEs) {
388  tesInChain.insert(te->id());
389  }
390 
391  if (tesInSeq == tesInChain) {
392  return stepToConsider;
393  }
394  return 0;
395 }
396 
398 {
399 
400  ATH_CHECK(not m_configSvc->chains().empty());
401 
402  // obtain map output TE -> input TE via sequences
403  for (auto ptrChain : m_configSvc->chains())
404  {
405  std::string chainName = ptrChain->name();
406 
407 
408  if (not m_chainsToSave.empty())
409  {
410  auto found = std::find(m_chainsToSave.begin(), m_chainsToSave.end(), chainName);
411  if (found == m_chainsToSave.end())
412  {
413  continue;
414  }
415  }
416 
417  if (std::regex_match(chainName, SpecialCases::bjetMuChain )) {
418  ATH_CHECK(bjetMuChainConfigDecoder(allTEs, finalTEs, ptrChain));
419  continue;
420  }
421 
422  // hack for etcut chains
423  // if we ever need to generalise that it should be moved to separate function
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;
428  // use heuristics to mention
429  if( std::regex_match(chainName, SpecialCases::egammaDiEtcut) ) {
430  ATH_MSG_DEBUG("EtCut chains hack, chain with two etcut legs ");
431  positionsOfEtCutLegs.insert({0, 1});
432  } else if ( std::regex_match(chainName, SpecialCases::egammaCombinedWithEtcut) ) {
433  ATH_MSG_DEBUG("EtCut chains hack, egamma chain with second etcut leg ");
434  positionsOfEtCutLegs.insert({1});
435  } else if ( std::regex_match(chainName, SpecialCases::egammaEtcut) ) {
436  ATH_MSG_DEBUG("EtCut chains hack, single leg egamma chain");
437  positionsOfEtCutLegs.insert({0});
438  }
439 
440  // pilot pass to fill the replacement map
441  std::map<size_t, HLT::te_id_type> positionToDesiredIDmap;
442  for (auto ptrHLTSignature : ptrChain->signatures()) {
443  size_t position = 0;
444  for (auto ptrHLTTE : ptrHLTSignature->outputTEs()) {
445  if (positionsOfEtCutLegs.count(position) and positionToDesiredIDmap.find(position) != positionToDesiredIDmap.end() ) {
446  etcutReplacementTEs[ptrHLTTE->id()] = positionToDesiredIDmap[position];
447  ATH_MSG_DEBUG("EtCut chains hack, TE " << ptrHLTTE->name() << " will be replaced by: " << TrigConf::HLTUtils::hash2string(positionToDesiredIDmap[position]));
448  } else {
449  if ( ptrHLTTE->name().find("calocalib") != std::string::npos and positionsOfEtCutLegs.count(position) ) { // we have final TE for this leg
450  positionToDesiredIDmap[position] = ptrHLTTE->id();
451  }
452  }
453  position++;
454  }
455  }
456  }
457 
458  // chains with a single leg
460  ATH_MSG_DEBUG(" CHAIN name " << chainName << " CHAIN Id " << chainId);
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 );
468  }
469  }
470  }
471  // chains with a multiple legs
473 
474  // dirty hacks for failing chains parsing
475  if(std::regex_match(chainName, SpecialCases::gammaXeChain))
476  multiplicities={1,1};
477 
478  if ( multiplicities.size() > 1 ) {
479  ATH_MSG_DEBUG(" this " << (is2LegTopoChain(ptrChain) ? "is": "is not") << " topological chain");
480  // the chain structure (in terms of multiplicities) may change along the way
481  // we'll assign legs only to these TEs of the steps that have identical multiplicity pattern
482  // e.g. for the chain: HLT_2g25_loose_g20 the multiplicities are: [2, 1]
483 
484  // hack for HLT.*tau.*xe.* case
485  if (std::regex_match(chainName, SpecialCases::tauXeChain)) {
486  std::vector<size_t> mult_hack; // type mismatch with ChainNameParser::multiplicities
487  if (multiplicities.size()==3) mult_hack={1,1};
488  else if (multiplicities.size()==2) mult_hack={1};
489  ptrChain->set_leg_multiplicities(mult_hack); // HLTChain needs vector<size_t>
490  }
491 
492  // hack for mu2MunoL1Special
493  if (std::regex_match(chainName, SpecialCases::mu2MunoL1Special)) {
494  std::vector<size_t> mult_hack;
495  if (multiplicities.size()==3) mult_hack={1,1};
496  else if (multiplicities.size()==2) mult_hack={2}; // HLT_mu11_nomucomb_2mu4noL1_nscan03_L1MU11_2MU6
497  ptrChain->set_leg_multiplicities(mult_hack);
498  }
499 
500  ATH_MSG_DEBUG("CHAIN " << chainName << " needs legs: " << multiplicities );
501  std::vector<unsigned int> teIdsLastHealthyStepIds;
502 
503  for (auto ptrHLTSignature : ptrChain->signatures())
504  {
505  std::vector<int> teCounts;
506  std::vector<unsigned int> teIds;
507  unsigned int lastSeenId = 0;
508  for (auto ptrHLTTE : ptrHLTSignature->outputTEs())
509  {
510  if ( lastSeenId != ptrHLTTE->id()) {
511  teCounts.push_back(1);
512  teIds.push_back(ptrHLTTE->id());
513  } else {
514  teCounts.back()++;
515  }
516  lastSeenId = ptrHLTTE->id();
517  }
518 
519  ATH_MSG_DEBUG("TE multiplicities seen in this step " << teCounts);
520  bool multiplicityCounts = multiplicities == teCounts;
521  // hack for HLT.*tau.*xe.* case
522  if(std::regex_match(chainName, SpecialCases::tauXeChain)) multiplicityCounts = true;
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){
527  HLT::Identifier chainLegId = TrigCompositeUtils::createLegName(chainId, legNumber);
528  allTEs[etcutReplacement(teIds[legNumber])].insert(chainLegId);
529  }
530  }
531  }
532  for ( size_t legNumber = 0; legNumber < teIdsLastHealthyStepIds.size(); ++ legNumber ) {
533  HLT::Identifier chainLegId = TrigCompositeUtils::createLegName(chainId, legNumber);
534 
535  ATH_MSG_DEBUG("created leg id " << chainLegId << " that will replace TE ID " << etcutReplacement(teIdsLastHealthyStepIds[legNumber]));
536  finalTEs[etcutReplacement(teIdsLastHealthyStepIds[legNumber])].insert(chainLegId);
537  }
538  }
539  }
540  ATH_MSG_DEBUG("Recognised " << allTEs.size() << " kinds of TEs and among them " << finalTEs.size() << " final types");
541  return StatusCode::SUCCESS;
542 }
543 
545  HLT::Identifier chainId = HLT::Identifier(ptrChain->name());
546 
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;
554  }
555 
556  if ( switchedTojets)
557  jets.push_back(ptrHLTTE->id());
558  else
559  muons.push_back(ptrHLTTE->id());
560  }
561  }
562  ATH_CHECK(not muons.empty());
563  ATH_CHECK(not jets.empty());
564  std::reverse(std::begin(muons), std::end(muons));
566  finalTEs[muons[0]].insert(TrigCompositeUtils::createLegName(chainId, 0));
567  finalTEs[muons[0]].insert(chainId);
568  finalTEs[jets[0]].insert(TrigCompositeUtils::createLegName(chainId, 1));
569  finalTEs[jets[0]].insert(chainId);
570 
571  for ( size_t index = 0; index < std::min(muons.size(), jets.size()); ++index)
572  {
573  allTEs[muons[index]].insert(TrigCompositeUtils::createLegName(chainId, 0));
574  allTEs[muons[index]].insert(chainId);
575  allTEs[jets[index]].insert(TrigCompositeUtils::createLegName(chainId, 1));
576  allTEs[jets[index]].insert(chainId);
577  }
578  return StatusCode::SUCCESS;
579 }
580 
581 
582 
584 {
585 
586  // iterate over the TEs, for each make the ConvProxy and build connections
587  std::map<const HLT::TriggerElement *, ConvProxy *> teToProxy;
588  ATH_MSG_DEBUG("TrigNavStructure with " << run2Nav.getAllTEs().size() << " TEs acquired");
589  for (auto te : run2Nav.getAllTEs())
590  {
591  // skip event seed node
593  continue;
594  auto proxy = new ConvProxy(te);
595  convProxies.insert(proxy);
596  teToProxy[te] = proxy;
597  // add linking
598  for (auto predecessor : HLT::TrigNavStructure::getDirectPredecessors(te))
599  {
600  ConvProxy *predecessorProxy = teToProxy[predecessor];
601  if (predecessorProxy != nullptr)
602  { // because we skip some
603  proxy->parents.insert(predecessorProxy);
604  predecessorProxy->children.insert(proxy);
605  }
606  }
607  }
608 
609  if (m_doSelfValidation)
610  {
611  int counter = -1;
612  for (auto proxy : convProxies)
613  {
614  counter++;
615  ATH_MSG_DEBUG("Proxy " << counter << " " << proxy->description() << "ptr " << proxy);
616  for (auto p : proxy->children)
617  ATH_MSG_DEBUG("Child ptr " << p);
618  for (auto p : proxy->parents)
619  ATH_MSG_DEBUG("Parent ptr " << p);
620 
621  for (auto p : proxy->parents)
622  {
623  for (auto pp : p->parents)
624  {
625  if (pp == proxy)
626  {
627  ATH_MSG_WARNING("Weird, proxy is in parents list of parents");
628  }
629  }
630  }
631  for (auto c : proxy->children)
632  {
633  for (auto cc : c->children)
634  {
635  if (cc == proxy)
636  {
637  ATH_MSG_WARNING("Weird, proxy is in children list of children");
638  }
639  }
640  }
641  }
642  }
643 
644  ATH_MSG_DEBUG("Created " << convProxies.size() << " proxy objects");
645  return StatusCode::SUCCESS;
646 }
647 
648 
650  std::function<bool(const ConvProxy*)> selector,
651  const std::vector<std::function<void(const ConvProxy*)>>& printers) const {
652  ATH_MSG_DEBUG("Printing proxies");
653  ATH_MSG_DEBUG("" );
654  for ( auto p: proxies) {
655  if ( selector(p) ){
656  ATH_MSG_DEBUG("Proxy " << p->description() );
657  for (auto& printer: printers) {
658  printer(p);
659  }
660  ATH_MSG_DEBUG("" );
661  }
662  }
663 }
664 
666 {
667 
668  for (auto &ptrConvProxy : convProxies)
669  {
670  auto teId = ptrConvProxy->te->getId();
671  bool teActive = ptrConvProxy->te->getActiveState();
672  auto iter = allTEs.find(teId);
673  if (iter != allTEs.end())
674  {
675  ptrConvProxy->runChains.insert(iter->second.begin(), iter->second.end());
676  if (teActive)
677  {
678  ptrConvProxy->passChains.insert(iter->second.begin(), iter->second.end());
679  }
680  }
681 
682  for (auto &objTeIdToChain : allTEs)
683  {
684  if (teId == objTeIdToChain.first)
685  {
686  for (auto &chainId : objTeIdToChain.second)
687  {
688  (ptrConvProxy->runChains).insert(chainId);
689  }
690  break;
691  }
692  }
693  }
694  return StatusCode::SUCCESS;
695 }
696 
698 {
699  // propagate up (towards L1) chain IDs if they are not in proxies
700  // technically each proxy looks at the children proxies and inserts from it all unseen chains
701  // procedure is repeated until, no single proxy needs an update (tedious - we may be smarter in future)
702 
703  while (true)
704  {
705  size_t numberOfUpdates = 0;
706  for (auto p : convProxies)
707  {
708  for (auto child : p->children)
709  {
710  size_t startSize = p->runChains.size();
711  p->runChains.insert(std::begin(child->runChains), std::end(child->runChains));
712 
713  if (startSize != p->runChains.size())
714  { // some chain needed to be inserted
715  numberOfUpdates++;
716  // if update was need, it means set of chains that passed need update as well
717  p->passChains.insert(std::begin(child->runChains), std::end(child->runChains));
718  }
719  }
720  }
721  ATH_MSG_DEBUG("Needed to propagate chains from " << numberOfUpdates << " child(ren)");
722  if (numberOfUpdates == 0)
723  {
724  break;
725  }
726  }
727  return StatusCode::SUCCESS;
728 }
729 
731 {
732  // remove proxies that have no chains
733  for (auto i = std::begin(convProxies); i != std::end(convProxies);)
734  {
735  if ((*i)->runChains.empty())
736  {
737  ConvProxy *toDel = *i;
738  // remove it from parents/children
739  for (auto parent : toDel->parents)
740  {
741  parent->children.erase(toDel);
742  }
743  for (auto child : toDel->children)
744  {
745  child->parents.erase(toDel);
746  }
747  delete toDel;
748  i = convProxies.erase(i);
749  }
750  else
751  {
752  ++i;
753  }
754  }
755  ATH_MSG_DEBUG("After eliminating proxies not associated to chainsof intereset left with " << convProxies.size());
756  return StatusCode::SUCCESS;
757 }
758 
760 {
761 
762  ATH_CHECK(collapseFeaturesProxies(convProxies, run2Nav));
764  if (m_doSelfValidation)
765  {
766  ATH_CHECK(allProxiesHaveChain(convProxies));
767  ATH_CHECK(allProxiesConnected(convProxies));
768  }
769  ATH_MSG_DEBUG("Compression done");
770 
771  return StatusCode::SUCCESS;
772 }
773 
774 template <typename MAP>
776 {
777  // collapse proxies based on the mapping in the map argument(generic) and clean proxiesSet
778  std::vector<ConvProxy *> todelete;
779  for (auto &[key, proxies] : keyToProxyMap)
780  {
781  if (proxies.size() > 1)
782  {
783  ATH_MSG_DEBUG("Merging " << proxies.size() << " similar proxies");
784  for (auto p : proxies)
785  {
786  if (p->mergeAllowed(*proxies.begin()))
787  {
788  (*proxies.begin())->merge(p);
789  todelete.push_back(p);
790  }
791  // TODO consider scanning proxies another time if merge is not allowed, it may be allowed with other proxies here
792  }
793  }
794  }
795  for (auto proxy : todelete)
796  {
797  convProxies.erase(proxy);
798  delete proxy;
799  }
800  // remove from proxies set all elements that are now unassociated (remember to delete after)
801  return StatusCode::SUCCESS;
802 }
803 
805 {
806 
807  const size_t beforeCount = convProxies.size();
808  std::map<uint64_t, ConvProxySet_t> feaToProxyMap;
809  for (auto proxy : convProxies)
810  {
811  proxy->feaHash = feaToHash(proxy->te->getFeatureAccessHelpers(), proxy->te, run2Nav);
812  if (proxy->feaHash != ConvProxy::MissingFEA)
813  feaToProxyMap[proxy->feaHash].insert(proxy);
814 
815  ATH_MSG_VERBOSE("TE " << TrigConf::HLTUtils::hash2string(proxy->te->getId()) << " FEA hash " << proxy->feaHash);
816  for (const HLT::TriggerElement::FeatureAccessHelper& fea : proxy->te->getFeatureAccessHelpers())
817  {
818  ATH_MSG_VERBOSE("FEA: " << fea);
819  }
820  }
821 
822  for (auto [feaHash, proxies] : feaToProxyMap)
823  {
824  auto first = *proxies.begin();
825  for (auto p : proxies)
826  {
827  if (filterFEAs(first->te->getFeatureAccessHelpers(), run2Nav) !=
828  filterFEAs(p->te->getFeatureAccessHelpers(), run2Nav))
829  {
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);
832  ATH_MSG_ERROR(".... TE id of this proxy: " << TrigConf::HLTUtils::hash2string(p->te->getId()));
833  for ( auto fea: first->te->getFeatureAccessHelpers() ) {
834  ATH_MSG_ERROR("FEA1 " << fea);
835  }
836  for ( auto fea: p->te->getFeatureAccessHelpers() ) {
837  ATH_MSG_ERROR("FEA2 " << fea);
838  }
839 
840  return StatusCode::FAILURE;
841  }
842  }
843  }
844 
845 
846  ATH_CHECK(collapseProxies(convProxies, feaToProxyMap));
847  ATH_MSG_DEBUG("Proxies with features collapsing reduces size from " << beforeCount << " to " << convProxies.size());
848 
849  return StatusCode::SUCCESS;
850 }
851 
853 {
854  // merge proxies bases on the parent child relation (this has to run after feature based collapsing)
855  struct ParentChildCharacteristics
856  {
857  ConvProxy *parent = nullptr;
858  ConvProxy *child = nullptr;
859  size_t distanceFromParent = 0;
860  bool operator<(const ParentChildCharacteristics &rhs) const
861  {
862  if (parent != rhs.parent)
863  return parent < rhs.parent;
864  if (child != rhs.child)
865  return child < rhs.child;
866  return distanceFromParent < rhs.distanceFromParent;
867  }
868  };
869  const size_t beforeCount = convProxies.size();
870  std::map<ParentChildCharacteristics, ConvProxySet_t> groupedProxies;
871  for (auto proxy : convProxies)
872  {
873  if (proxy->feaHash == ConvProxy::MissingFEA)
874  {
875  ATH_MSG_VERBOSE("Featureless proxy to deal with: " << proxy->description());
876  /* the canonical case
877  merged parent
878  / | | \
879  C1 C2 C3 C4 <-- proxies to merge
880  \ | | /
881  merged child
882  */
883  auto hasSomeFeatures = [](const ConvProxy* p){ return p->feaHash != ConvProxy::MissingFEA; };
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 )
888  )
889  {
890  ATH_MSG_VERBOSE("Proxy to possibly merge: " << proxy->description());
891  groupedProxies[{*(proxy->parents.begin()), *(proxy->children.begin()), 0}].insert(proxy);
892  // TODO expand it to cover longer featureless sequences
893  }
894  else
895  {
896  ATH_MSG_VERBOSE("Featureless proxy in noncanonical situation " << proxy->description());
897  ATH_MSG_VERBOSE("parents ");
898  for (auto pp : proxy->parents)
899  {
900  ATH_MSG_VERBOSE(pp->description());
901  }
902  ATH_MSG_VERBOSE("children ");
903  for (auto cp : proxy->children)
904  {
905  ATH_MSG_VERBOSE(cp->description());
906  }
907  }
908  }
909  }
910 
911  ATH_CHECK(collapseProxies(convProxies, groupedProxies));
912  ATH_MSG_DEBUG("Proxies without features collapsing reduces size from " << beforeCount << " to " << convProxies.size());
913  return StatusCode::SUCCESS;
914 }
915 
917 {
918  for (auto i = std::begin(convProxies); i != std::end(convProxies);)
919  {
920  if ((*i)->parents.size() > 1)
921  {
922  ConvProxy *toDel = *i;
923  // remove it from parents/children
924  for (auto parent : toDel->parents)
925  {
926  parent->children.erase(toDel);
927  }
928  for (auto child : toDel->children)
929  {
930  child->parents.erase(toDel);
931  }
932  delete toDel;
933  i = convProxies.erase(i);
934  }
935  else
936  {
937  ++i;
938  }
939  }
940  return StatusCode::SUCCESS;
941 }
942 
944 {
945  // from all FEAs of the associated TE pick those objects that are to be linked
946  for (auto &proxy : convProxies)
947  {
948  if (proxy->te != nullptr)
949  {
950 
951  for (const HLT::TriggerElement::FeatureAccessHelper& helper : proxy->te->getFeatureAccessHelpers())
952  {
953  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, helper);
954  if (sgKey != 0)
955  {
956  if (feaToSave(helper, sgName))
957  {
958  proxy->features.push_back(helper);
959  }
960  }
961  }
962  }
963  }
964 
965  return StatusCode::SUCCESS;
966 }
967 
969 {
970 
971  // ordered_sorter
972  auto ordered_sorter = [&setRoiName = std::as_const(m_setRoiName)](const std::string &left, const std::string &right) -> bool
973  {
974  return std::find(cbegin(setRoiName), cend(setRoiName), left) < std::find(cbegin(setRoiName), cend(setRoiName), right);
975  };
976 
977  std::map<std::string, HLT::TriggerElement::FeatureAccessHelper, decltype(ordered_sorter)> mp(ordered_sorter);
978 
979  for (auto &proxy : convProxies)
980  {
981  // TODO need check & handling of case when there is more RoIs, now overwriting
982  if (HLT::TrigNavStructure::getRoINodes(proxy->te).size() > 1)
983  ATH_MSG_DEBUG("Several RoIs pointing to a proxy, taking latest one for now");
984 
985  mp.clear();
986 
987  for (const HLT::TriggerElement::FeatureAccessHelper& helper : proxy->te->getFeatureAccessHelpers())
988  {
989  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, helper);
990  if (std::find(m_setRoiName.begin(), m_setRoiName.end(), sgName) == m_setRoiName.end())
991  {
992  // do not filter continue;
993  continue;
994  }
995  mp[sgName] = helper;
996  }
997 
998  std::transform(cbegin(mp), cend(mp), back_inserter(proxy->rois),
999  [](const std::map<std::string, HLT::TriggerElement::FeatureAccessHelper>::value_type &p)
1000  { return p.second; });
1001  }
1002 
1003  // roiPropagator
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)
1007  {
1008  for (auto &proxyChild : convProxyChildren)
1009  {
1010  if ( visited.count(proxyChild) == 1 ) {
1011  continue;
1012  }
1013  visited.insert(proxyChild);
1014  if (proxyChild->rois.empty())
1015  { // no roi update, copy from parent
1016  proxyChild->rois = roiParent;
1017  if (proxyChild->children.empty() == false)
1018  {
1019  roiPropagator(proxyChild->children, roiParent);
1020  }
1021  }
1022  }
1023  };
1024 
1025  for (auto &proxy : convProxies)
1026  {
1027  roiPropagator(proxy->children, proxy->rois);
1028  }
1029 
1030  return StatusCode::SUCCESS;
1031 }
1032 
1034 {
1035  for (auto &proxy : convProxies)
1036  {
1037  for (const HLT::TriggerElement::FeatureAccessHelper& helper : proxy->te->getFeatureAccessHelpers())
1038  {
1039  if (helper.getCLID() == m_TrackParticleContainerCLID || helper.getCLID() == m_TauTrackContainerCLID)
1040  {
1041  proxy->tracks.push_back(helper);
1042  }
1043  }
1044  }
1045 
1046  return StatusCode::SUCCESS;
1047 }
1048 
1050 {
1051  for (auto &proxy : convProxies)
1052  {
1054  for (auto chainId : proxy->runChains)
1055  {
1056  TrigCompositeUtils::addDecisionID(chainId, proxy->imNode);
1057  }
1059  for (auto chainId : proxy->passChains)
1060  {
1061  TrigCompositeUtils::addDecisionID(chainId, proxy->hNode.back());
1062  }
1063 
1064  TrigCompositeUtils::linkToPrevious(proxy->hNode.front(), proxy->imNode, context); // H low IM up
1065  }
1066  // connecting current IM to all Hs in parent proxies
1067  for (auto &proxy : convProxies)
1068  {
1069  for (auto &parentProxy : proxy->parents)
1070  {
1071  TrigCompositeUtils::linkToPrevious(proxy->imNode, parentProxy->hNode.front(), context); // IM low H up (in parent)
1072  }
1073  }
1074  ATH_MSG_DEBUG("IM & H nodes made, output nav elements " << decisions.size());
1075  return StatusCode::SUCCESS;
1076 }
1077 
1079  const TEIdToChainsMap_t &terminalIds, const EventContext &context) const
1080 {
1081  // make node & link it properly
1082  auto makeSingleSFNode = [&decisions, &context](auto lastDecisionNode, auto chainIds, TrigCompositeUtils::DecisionID idStore = 0)
1083  {
1085  sfNode->setName("SF");
1086  TrigCompositeUtils::linkToPrevious(decisions.at(0), sfNode, context);
1087  TrigCompositeUtils::linkToPrevious(sfNode, lastDecisionNode, context);
1088  for (auto chainId : chainIds)
1089  {
1090  if (idStore == 0)
1091  {
1092  TrigCompositeUtils::addDecisionID(chainId, sfNode);
1094  }
1095  else if (chainId.numeric() == idStore)
1096  {
1097  TrigCompositeUtils::addDecisionID(chainId, sfNode);
1099  }
1100  }
1101  return sfNode;
1102  };
1103  auto makeSFNodes = [makeSingleSFNode](auto proxy, TrigCompositeUtils::DecisionID idToStore = 0)
1104  {
1105  if (proxy->hNode.empty())
1106  { // nothing has passed, so link to the IM node
1107  // TODO make sure it needs to be done like that
1108  makeSingleSFNode(proxy->imNode, proxy->runChains, idToStore);
1109  }
1110  else
1111  {
1112  // makeSFNode(proxy->hNode[0], TCU::decisionIDs(proxy->hNode[0])); // not using passChains as there may be additional filtering
1113  for (auto &hNode : proxy->hNode)
1114  {
1115  makeSingleSFNode(hNode, proxy->passChains, idToStore); // using passChains
1116  }
1117  }
1118  };
1119 
1120  for (auto proxy : convProxies)
1121  {
1122  // associate terminal nodes to filter nodes,
1123  if (proxy->children.empty())
1124  { // the H modes are terminal
1125  makeSFNodes(proxy);
1126  }
1127  else
1128  {
1129  // likely need more iterations
1130  // nonterminal nodes that are nevertheless terminal for a given chain
1131  std::vector<TCU::DecisionID> toRetain;
1132  for (auto teId : proxy->teIDs)
1133  {
1134  auto whereInMap = terminalIds.find(teId);
1135  if (whereInMap != terminalIds.end())
1136  {
1137  toRetain.insert(toRetain.end(), whereInMap->second.begin(), whereInMap->second.end());
1138  }
1139  }
1140  for (auto chainIdstore : toRetain)
1141  {
1142  makeSFNodes(proxy, chainIdstore);
1143  }
1144  }
1145  }
1146  // associate all nodes designated as final one with the filter nodes
1147 
1148  ATH_MSG_DEBUG("SF nodes made, output nav elements " << decisions.size());
1149  return StatusCode::SUCCESS;
1150 }
1151 
1153 {
1154  // Check that only ChainIDs (not LegIDs) are present in the terminus "HLTPassRaw" node.
1155  // Check that only chains which pass the event are included.
1156  TCU::Decision* terminus = decisions.at(0);
1157  ATH_CHECK( terminus->name() == TCU::summaryPassNodeName() );
1158  TCU::DecisionIDContainer currentIDs;
1159  TCU::DecisionIDContainer filteredIDs;
1160  TCU::decisionIDs(terminus, currentIDs); // Extract, std::vector -> std::set
1161  for (const TCU::DecisionID id : currentIDs)
1162  {
1163  const TCU::DecisionID idToCheck = ( TCU::isLegId(id) ? TCU::getIDFromLeg( HLT::Identifier(id) ).numeric() : id );
1164  const std::string chainName = HLT::Identifier(idToCheck).name();
1165  // Sanity check
1166  if (!m_chainsToSave.empty())
1167  {
1168  if (std::find(m_chainsToSave.begin(), m_chainsToSave.end(), chainName) == m_chainsToSave.end())
1169  {
1170  ATH_MSG_ERROR("Navigation information for chain " << chainName << " in "
1171  << TCU::summaryPassNodeName() << " but this chain wasn't on the list of chains to save");
1172  return StatusCode::FAILURE;
1173  }
1174  }
1175  if (m_tdt->isPassed(chainName))
1176  {
1177  filteredIDs.insert(idToCheck);
1178  }
1179  }
1180  terminus->setDecisions( std::vector<TCU::DecisionID>() ); // decisions.clear(), but via the xAOD setter function
1181  TCU::insertDecisionIDs(filteredIDs, terminus); // Insert, std::set -> std::vector
1182  ATH_MSG_VERBOSE("After filtering out leg IDs and checking isPassed, "
1183  "the terminus node goes from " << currentIDs.size() << " to " << filteredIDs.size() << " chain IDs.");
1184  if (msgLvl(MSG::VERBOSE))
1185  {
1186  for (const TCU::DecisionID id : filteredIDs)
1187  {
1188  ATH_MSG_VERBOSE(" -- Retained passing ID: " << HLT::Identifier(id));
1189  }
1190  }
1191  return StatusCode::SUCCESS;
1192 }
1193 
1195  const EventContext &context) const
1196 {
1197 
1198  auto makeL1Node = [&decisions, &context](auto firstDecisionNode, auto chainIds)
1199  {
1201  L1Node->setName(TrigCompositeUtils::hltSeedingNodeName()); // L1
1202  for (auto chainId : chainIds)
1203  {
1204  TrigCompositeUtils::addDecisionID(chainId, L1Node);
1205  }
1206  TrigCompositeUtils::linkToPrevious(firstDecisionNode, L1Node, context); // IM -> L1
1207 
1208  return L1Node;
1209  };
1210 
1211  for (auto &proxy : convProxies)
1212  {
1213  // associate initial node to filter nodes,
1214  if (proxy->parents.empty())
1215  { // the IM node is initial
1216  proxy->l1Node = makeL1Node(proxy->imNode, TCU::decisionIDs(proxy->imNode)); // not using passChains as there may be additional filtering
1217  }
1218  }
1219 
1220  ATH_MSG_DEBUG("L1 nodes made, output nav elements ");
1221  return StatusCode::SUCCESS;
1222 }
1223 
1225 {
1226  size_t feaCount{0};
1227  if (proxy.features.empty())
1228  { // no features
1229  ++feaCount;
1230  }
1231  for (const auto &fea : proxy.features)
1232  {
1233  if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1234  {
1235  ++feaCount;
1236  }
1237  for (auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1238  {
1239  ++feaCount;
1240  }
1241  }
1242  // 1 means a deafult H node created is enough, no need to expand H nodes
1243  return feaCount;
1244 }
1245 
1247 {
1248  // from all FEAs of the associated TE pick those objects that are to be linked
1249  for (const auto &proxy : convProxies)
1250  {
1251  auto [bestFeaIdx, bestObjIdx] = getHighestPtObject(*proxy, run2Nav);
1252 
1253  auto feaN = getFeaSize(*proxy);
1254  if (feaN > 1)
1255  { // expand for more H nodes and connect them
1256  while (--feaN)
1257  {
1259  for (auto chainId : proxy->passChains) // adding hash values of active chains to expanded H nodes
1260  {
1261  TrigCompositeUtils::addDecisionID(chainId, proxy->hNode.back());
1262  }
1263  // connecting to upeer IM node
1264  TrigCompositeUtils::linkToPrevious(proxy->hNode.back(), proxy->imNode, context); // H low IM up
1265  // connecting created H to IM in children proxies
1266  for (auto &childProxy : proxy->children)
1267  {
1268  TrigCompositeUtils::linkToPrevious(childProxy->imNode, proxy->hNode.back(), context); // IM child H up (just created))
1269  }
1270  }
1271  }
1272 
1273  if (proxy->features.empty())
1274  { // no features attached, self link
1276  proxy->hNode.front()->setObjectLink<xAOD::TrigCompositeContainer>(TrigCompositeUtils::featureString(), linkToSelf);
1277  }
1278 
1279  auto hNodeIter = proxy->hNode.begin();
1280  for (std::size_t feaIdx = 0; feaIdx < proxy->features.size(); ++feaIdx)
1281  {
1282  auto &fea = proxy->features[feaIdx];
1283  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, fea);
1284  // link to itself when lined collection has size 0
1285  if (fea.getIndex().objectsBegin() == fea.getIndex().objectsEnd())
1286  {
1288  (*hNodeIter)->setObjectLink<xAOD::TrigCompositeContainer>(TrigCompositeUtils::featureString(), linkToSelf);
1289  ++hNodeIter;
1290  }
1291  for (auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n)
1292  {
1293  // connecting feature or subfeature
1294  const std::string& linkName = (feaIdx == bestFeaIdx && n == bestObjIdx) ?
1295  TrigCompositeUtils::featureString() : "subfeature";
1296  (*hNodeIter)->typelessSetObjectLink(linkName, sgKey, sgCLID, n, n + 1);
1297  ++hNodeIter;
1298  }
1299  }
1300  }
1301 
1302  return StatusCode::SUCCESS;
1303 }
1304 
1306 {
1307  // from all Rois of the associated TE pick those objects that are to be linked
1308  for (auto &proxy : convProxies)
1309  {
1310  for (auto &roi : proxy->rois)
1311  {
1312  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, roi);
1313  if (proxy->l1Node)
1314  {
1315  proxy->l1Node->typelessSetObjectLink(TrigCompositeUtils::initialRoIString(), sgKey, sgCLID, roi.getIndex().objectsBegin());
1316  }
1317  if (proxy->rois.empty() == false)
1318  {
1319  proxy->imNode->typelessSetObjectLink(TrigCompositeUtils::roiString(), sgKey, sgCLID, roi.getIndex().objectsBegin());
1320  }
1321  }
1322  }
1323 
1324  return StatusCode::SUCCESS;
1325 }
1326 
1328 {
1329  for (auto &proxy : convProxies)
1330  {
1331  for (auto &trk : proxy->tracks)
1332  {
1333  if (proxy->imNode->hasObjectLink(TrigCompositeUtils::roiString()))
1334  {
1335  try
1336  {
1338  if (ROIElementLink.isValid())
1339  {
1341  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, trk);
1342  if (sgCLID == m_TrackParticleContainerCLID || sgCLID == m_TauTrackContainerCLID)
1343  {
1344  const char *tName = sgCLID == m_TrackParticleContainerCLID ? "TEMP_TRACKS" : "TEMP_TAU_TRACKS";
1345  auto d = std::make_unique<TrigCompositeUtils::Decision>();
1346  d->makePrivateStore();
1347  d->typelessSetObjectLink(tName, sgKey, sgCLID, trk.getIndex().objectsBegin());
1348  if (sgCLID == m_TrackParticleContainerCLID)
1349  {
1350  for (const ElementLink<xAOD::TrackParticleContainer> &track : d->objectCollectionLinks<xAOD::TrackParticleContainer>(tName))
1351  {
1352  if (track.isValid())
1353  {
1354  const xAOD::TrackParticle *t = *track;
1355  viewBookkeeper(*t) = ROIElementLink;
1356  }
1357  }
1358  }
1359  if (m_includeTauTrackFeatures == false && sgCLID == m_TauTrackContainerCLID)
1360  {
1361  for (const ElementLink<xAOD::TauTrackContainer> &track : d->objectCollectionLinks<xAOD::TauTrackContainer>(tName))
1362  {
1363  if (track.isValid())
1364  {
1365  const xAOD::TauTrack_v1 *t = *track;
1366  viewBookkeeper(*t) = ROIElementLink;
1367  }
1368  }
1369  }
1370  }
1371  }
1372  } catch (SG::ExcBadForwardLink&) {
1373  ATH_MSG_WARNING("Unable to create an ElementLink into a container with no entries");
1374  }
1375  }
1376  }
1377  }
1378 
1379  return StatusCode::SUCCESS;
1380 }
1381 
1382 // does not need to be a method, so kept as local
1384 {
1385  CLID thePassBitsCLID = ClassID_traits<xAOD::TrigPassBits>::ID();
1386  CLID thePassBitsContCLID = ClassID_traits<xAOD::TrigPassBitsContainer>::ID();
1387 
1388  return fea.getCLID() == thePassBitsCLID or fea.getCLID() == thePassBitsContCLID;
1389 }
1390 
1391 std::vector<HLT::TriggerElement::FeatureAccessHelper> Run2ToRun3TrigNavConverterV2::filterFEAs(const std::vector<HLT::TriggerElement::FeatureAccessHelper> &feaVector, const HLT::TrigNavStructure &navigationDecoder) const {
1392  std::vector<HLT::TriggerElement::FeatureAccessHelper> out;
1393  for (auto fea : feaVector)
1394  {
1395  if (feaToSkip(fea))
1396  {
1397  ATH_MSG_VERBOSE("Skipping in FEA hash calculation");
1398  continue;
1399  }
1400 
1401  auto [sgKey, sgCLID, sgName] = getSgKey(navigationDecoder, fea);
1402 
1403  if (sgKey == 0)
1404  {
1405  ATH_MSG_VERBOSE("Skipping unrecorded (missing in SG) FEA hash calculation - name in SG: " << sgName << " FEA " << fea);
1406  continue;
1407  }
1408  out.push_back(fea);
1409  }
1410  return out;
1411 }
1412 
1413 uint64_t Run2ToRun3TrigNavConverterV2::feaToHash(const std::vector<HLT::TriggerElement::FeatureAccessHelper> &feaVector, const HLT::TriggerElement *te_ptr, const HLT::TrigNavStructure &navigationDecoder) const
1414 {
1415  // FEA vectors hashing
1416  ATH_MSG_VERBOSE("Calculating FEA hash");
1417  uint64_t hash = 0;
1418  for (auto fea : filterFEAs(feaVector, navigationDecoder))
1419  {
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());
1425  }
1426  // Include the originating TE identifier and pointer to ensure that
1427  // navigation elements stemming from different Trigger Elements do not
1428  // collapse into a single proxy even if their features are otherwise
1429  // identical. The TE ID alone is not sufficient, as multiple clones of the
1430  // same TE share the ID, so we also add the pointer value to the hash.
1431  boost::hash_combine(hash, te_ptr->getId());
1432  boost::hash_combine(hash, reinterpret_cast<std::uintptr_t>(te_ptr));
1433  ATH_MSG_VERBOSE("Obtained FEA hash " << hash);
1434  return hash;
1435 }
1436 
1438 {
1439  auto iter = m_collectionsToSaveDecoded.find(fea.getCLID());
1440  if (iter != m_collectionsToSaveDecoded.end())
1441  {
1442  if ( iter->second.empty() )
1443  return true; // feature accepted for saving
1444  ATH_MSG_DEBUG("fea to save CLID: " << fea.getCLID() << ", sgName: " << sgName << " " <<iter->second.size() << " " << iter->second.empty() );
1445  return iter->second.contains(sgName);
1446  }
1447 
1448  return false;
1449 }
1450 
1451 
1452 
1454 {
1455  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, roi);
1456  if (std::find(m_setRoiName.begin(), m_setRoiName.end(), sgName) != m_setRoiName.end())
1457  {
1458  return true;
1459  }
1460 
1461  return false;
1462 }
1463 
1465 {
1466  for (auto p : proxies)
1467  {
1468  if (p->runChains.empty())
1469  {
1470  ATH_MSG_ERROR("Proxy with no chains");
1471  return StatusCode::FAILURE;
1472  }
1473  }
1474  ATH_MSG_DEBUG("CHECK OK, no proxies w/o a chain");
1475  return StatusCode::SUCCESS;
1476 }
1477 
1479 {
1480  for (auto p : proxies)
1481  {
1482  if (p->children.empty() and p->parents.empty() and not p->runChains.empty())
1483  {
1484  ATH_MSG_ERROR("Orphanted proxy N chains run:" << p->runChains.size());
1485  return StatusCode::FAILURE;
1486  }
1487  }
1488  ATH_MSG_DEBUG("CHECK OK, no orphanted proxies");
1489  return StatusCode::SUCCESS;
1490 }
1491 
1493 {
1494  ATH_MSG_DEBUG("CHECK OK, no excessive number of H nodes per proxy");
1495  return StatusCode::SUCCESS;
1496 }
1497 
1499 {
1500  // build map of all links to H nodes from IMs and FS
1501  std::set<const TrigCompositeUtils::Decision *> linkedHNodes;
1502  for (auto d : decisions)
1503  {
1504  if (d->name() == "IM" or d->name() == "FS")
1505  {
1506  for (auto el : TCU::getLinkToPrevious(d))
1507  {
1508  linkedHNodes.insert(*el); // dereferences to bare pointer
1509  }
1510  }
1511  }
1512  for (auto d : decisions)
1513  {
1514  if (d->name() == "H")
1515  {
1516  if (linkedHNodes.count(d) == 0)
1517  {
1518  ATH_MSG_ERROR("Orphaned H node");
1519  return StatusCode::FAILURE;
1520  }
1521  }
1522  }
1523  ATH_MSG_DEBUG("CHECK OK, all H modes are connected");
1524 
1525  return StatusCode::SUCCESS;
1526 }
1527 
1528 std::tuple<uint32_t, CLID, std::string> Run2ToRun3TrigNavConverterV2::getSgKey(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper) const
1529 {
1530  const std::string hltLabel = navigationDecoder.label(helper.getCLID(), helper.getIndex().subTypeIndex());
1531 
1532  const CLID saveCLID = [&](const CLID &clid)
1533  {
1534  if (clid == m_roIDescriptorCLID)
1536  if (clid == m_TrigEMClusterCLID)
1538  if (clid == m_TrigRingerRingsCLID)
1540  return clid;
1541  }(helper.getCLID());
1542 
1543  std::string type_name;
1544  if (m_clidSvc->getTypeNameOfID(saveCLID, type_name).isFailure())
1545  {
1546  return {0, 0, ""};
1547  }
1548 
1549  const auto sgStringKey = HLTNavDetails::formatSGkey("HLT", type_name, hltLabel);
1550  const bool isAvailable = evtStore()->contains(saveCLID, sgStringKey);
1551  ATH_MSG_DEBUG(" Objects presence " << helper << " " << sgStringKey << (isAvailable ? " present" : " absent"));
1552  if (!isAvailable)
1553  {
1554  return {0, saveCLID, ""};
1555  }
1556 
1557  return {evtStore()->stringToKey(sgStringKey, saveCLID), saveCLID, hltLabel}; // sgKey, sgCLID, sgName
1558 }
1559 
1560 std::pair<std::size_t, std::size_t> Run2ToRun3TrigNavConverterV2::getHighestPtObject(
1561  const ConvProxy& proxy, const HLT::TrigNavStructure& run2Nav) const
1562 {
1563  std::size_t bestFea = std::numeric_limits<std::size_t>::max();
1564  std::size_t bestObj = 0;
1565  float bestPt = -1.0;
1566 
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);
1570  if (!feaToSave(fea, sgName)) {
1571  continue;
1572  }
1573  if (sgKey == 0) continue;
1574  const std::string* keyStr = evtStore()->keyToString(sgKey, sgCLID);
1575  if (!keyStr) continue;
1576  const xAOD::IParticleContainer* cont = nullptr;
1577  if (evtStore()->retrieve(cont, *keyStr).isFailure()) continue;
1578  for (auto n = fea.getIndex().objectsBegin(); n < fea.getIndex().objectsEnd(); ++n) {
1579  if (n >= cont->size()) continue;
1580  const xAOD::IParticle* p = (*cont)[n];
1581  if (!p) continue;
1582  if (p->pt() > bestPt) {
1583  bestPt = p->pt();
1584  bestFea = i;
1585  bestObj = n;
1586  }
1587  }
1588  }
1589  if (bestFea == std::numeric_limits<std::size_t>::max()) {
1590  for (std::size_t i = 0; i < proxy.features.size(); ++i) {
1591  auto [sgKey, sgCLID, sgName] = getSgKey(run2Nav, proxy.features[i]);
1592  if (!feaToSave(proxy.features[i], sgName)) continue;
1593  bestFea = i;
1594  bestObj = proxy.features[i].getIndex().objectsBegin();
1595  break;
1596  }
1597  }
1598  return {bestFea, bestObj};
1599 }
Run2ToRun3TrigNavConverterV2::fillRelevantTracks
StatusCode fillRelevantTracks(ConvProxySet_t &convProxies) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1033
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
operator<
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
TrigCompositeUtils::featureString
const std::string & featureString()
Definition: TrigCompositeUtils.h:420
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
Run2ToRun3TrigNavConverterV2::m_roIDescriptorCLID
CLID m_roIDescriptorCLID
Definition: Run2ToRun3TrigNavConverterV2.h:181
SpecialCases::mu2MunoL1Special
const std::regex mu2MunoL1Special
Definition: SpecialCases.h:36
Run2ToRun3TrigNavConverterV2::collapseProxies
StatusCode collapseProxies(ConvProxySet_t &, MAP &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:775
Run2ToRun3TrigNavConverterV2::m_trigNavKey
SG::ReadHandleKey< xAOD::TrigNavigation > m_trigNavKey
Definition: Run2ToRun3TrigNavConverterV2.h:80
TrigConf::TrigConfData::name
const std::string & name() const
Definition: TrigConfData.h:22
Run2ToRun3TrigNavConverterV2::fillRelevantRois
StatusCode fillRelevantRois(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:968
Run2ToRun3TrigNavConverterV2::createL1Nodes
StatusCode createL1Nodes(const ConvProxySet_t &convProxies, xAOD::TrigCompositeContainer &decisions, const EventContext &context) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1194
ChainNameParser.h
ConvProxy::merge
void merge(ConvProxy *other)
Definition: Run2ToRun3TrigNavConverterV2.cxx:62
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:407
Run2ToRun3TrigNavConverterV2::initialize
virtual StatusCode initialize() override
Definition: Run2ToRun3TrigNavConverterV2.cxx:154
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
TrigCompositeUtils::DecisionID
unsigned int DecisionID
Definition: TrigComposite_v1.h:27
Run2ToRun3TrigNavConverterV2::~Run2ToRun3TrigNavConverterV2
virtual ~Run2ToRun3TrigNavConverterV2() override
Definition: Run2ToRun3TrigNavConverterV2.cxx:150
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
ConvProxy::runChains
std::set< HLT::Identifier > runChains
Definition: Run2ToRun3TrigNavConverterV2.h:46
Run2ToRun3TrigNavConverterV2::Run2ToRun3TrigNavConverterV2
Run2ToRun3TrigNavConverterV2(const std::string &name, ISvcLocator *pSvcLocator)
Definition: Run2ToRun3TrigNavConverterV2.cxx:146
HLT::TrigNavStructure::label
std::string label(class_id_type clid, const index_or_label_type &sti_or_label) const
Definition: TrigNavStructure.cxx:773
HLT::Identifier::numeric
TrigCompositeUtils::DecisionID numeric() const
numeric ID
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:41
Run2ToRun3TrigNavConverterV2::linkRoiNode
StatusCode linkRoiNode(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1305
Run2ToRun3TrigNavConverterV2::updateTerminusNode
StatusCode updateTerminusNode(xAOD::TrigCompositeContainer &, const EventContext &context) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1152
TrigCompositeUtils::newDecisionIn
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.
Definition: TrigCompositeUtilsRoot.cxx:44
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
Run2ToRun3TrigNavConverterV2::allProxiesConnected
StatusCode allProxiesConnected(const ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1478
hist_file_dump.d
d
Definition: hist_file_dump.py:142
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
xAOD::teId
teId
Definition: L2StandAloneMuon_v1.cxx:324
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
Run2ToRun3TrigNavConverterV2::m_configSvc
ServiceHandle< TrigConf::IHLTConfigSvc > m_configSvc
Definition: Run2ToRun3TrigNavConverterV2.h:82
Run2ToRun3TrigNavConverterV2::m_configUpdateMutex
std::mutex m_configUpdateMutex
Definition: Run2ToRun3TrigNavConverterV2.h:97
Run2ToRun3TrigNavConverterV2::removeUnassociatedProxies
StatusCode removeUnassociatedProxies(ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:730
TrigCompositeUtils::addDecisionID
void addDecisionID(DecisionID id, Decision *d)
Appends the decision (given as ID) to the decision object.
Definition: TrigCompositeUtilsRoot.cxx:59
Run2ToRun3TrigNavConverterV2::getSgKey
std::tuple< uint32_t, CLID, std::string > getSgKey(const HLT::TrigNavStructure &navigationDecoder, const HLT::TriggerElement::FeatureAccessHelper &helper) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1528
ConvProxy::MissingFEA
static const uint64_t MissingFEA
Definition: Run2ToRun3TrigNavConverterV2.h:48
SpecialCases::bjetMuChain
const std::regex bjetMuChain
Definition: SpecialCases.h:38
Run2ToRun3TrigNavConverterV2::getHighestPtObject
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...
Definition: Run2ToRun3TrigNavConverterV2.cxx:1560
TrigCompositeUtils::summaryPassNodeName
const std::string & summaryPassNodeName()
Definition: TrigCompositeUtils.h:429
Run2ToRun3TrigNavConverterV2::m_collectionsToSave
Gaudi::Property< std::vector< std::string > > m_collectionsToSave
Definition: Run2ToRun3TrigNavConverterV2.h:91
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
python.TrigCompositeUtils.isLegId
def isLegId(chainName)
Definition: DecisionHandling/python/TrigCompositeUtils.py:18
HLT::TriggerElement::getId
te_id_type getId() const
reset internals.
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:43
Run2ToRun3TrigNavConverterV2::m_trigOutputNavKey
SG::WriteHandleKey< xAOD::TrigCompositeContainer > m_trigOutputNavKey
Definition: Run2ToRun3TrigNavConverterV2.h:94
Run2ToRun3TrigNavConverterV2::bjetMuChainConfigDecoder
StatusCode bjetMuChainConfigDecoder(TEIdToChainsMap_t &allTES, TEIdToChainsMap_t &finalTEs, const TrigConf::HLTChain *ptrChain) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:544
HLT::TriggerElement::FeatureAccessHelper::getCLID
class_id_type getCLID() const
Class ID of object.
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:208
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
Run2ToRun3TrigNavConverterV2.h
defineDB.jets
jets
Definition: JetTagCalibration/share/defineDB.py:24
SpecialCases.h
TrigCompositeUtils::insertDecisionIDs
void insertDecisionIDs(const Decision *src, Decision *dest)
Appends the decision IDs of src to the dest decision object.
Definition: TrigCompositeUtilsRoot.cxx:78
Run2ToRun3TrigNavConverterV2::m_roisToSave
Gaudi::Property< std::vector< std::string > > m_roisToSave
Definition: Run2ToRun3TrigNavConverterV2.h:92
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Run2ToRun3TrigNavConverterV2::m_TrigRingerRingsCLID
CLID m_TrigRingerRingsCLID
Definition: Run2ToRun3TrigNavConverterV2.h:183
Run2ToRun3TrigNavConverterV2::m_setRoiName
std::vector< std::string > m_setRoiName
Definition: Run2ToRun3TrigNavConverterV2.h:179
TrigConf::HLTChain::signatures
const std::vector< HLTSignature * > & signatures() const
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:110
xAOD::TrigComposite_v1::setDecisions
void setDecisions(const std::vector< TrigCompositeUtils::DecisionID > &decisions)
Set positive HLT chain decisions associated with this TrigComposite. Navigation use.
Run2ToRun3TrigNavConverterV2::m_collectionsToSaveDecoded
std::map< CLID, std::set< std::string > > m_collectionsToSaveDecoded
Definition: Run2ToRun3TrigNavConverterV2.h:177
HLTNavDetails::formatSGkey
std::string formatSGkey(const std::string &prefix, const std::string &containername, const std::string &label)
declaration of formatting function.
Definition: Holder.cxx:122
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
Run2ToRun3TrigNavConverterV2::m_TauTrackContainerCLID
CLID m_TauTrackContainerCLID
Definition: Run2ToRun3TrigNavConverterV2.h:190
Run2ToRun3TrigNavConverterV2::m_tdt
PublicToolHandle< Trig::TrigDecisionTool > m_tdt
Definition: Run2ToRun3TrigNavConverterV2.h:81
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TrigConf::HLTChain
HLT chain configuration information.
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:35
Run2ToRun3TrigNavConverterV2::m_chainIdsPrinter
std::function< void(const ConvProxy *)> m_chainIdsPrinter
Definition: Run2ToRun3TrigNavConverterV2.h:150
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
Run2ToRun3TrigNavConverterV2::m_allTEIdsToChains
TEIdToChainsMap_t m_allTEIdsToChains
Definition: Run2ToRun3TrigNavConverterV2.h:98
HLT::TrigNavStructure
Definition: TrigNavStructure.h:40
TrigCompositeUtils::createAndStore
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
Definition: TrigCompositeUtilsRoot.cxx:28
TrigCompositeUtils::roiString
const std::string & roiString()
Definition: TrigCompositeUtils.h:418
SpecialCases::egammaDiEtcut
const std::regex egammaDiEtcut
Definition: SpecialCases.h:30
SpecialCases::gammaXeChain
const std::regex gammaXeChain
Definition: SpecialCases.h:29
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
ConvProxy::children
std::set< ConvProxy * > children
Definition: Run2ToRun3TrigNavConverterV2.h:44
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
Run2ToRun3TrigNavConverterV2::feaToHash
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)
Definition: Run2ToRun3TrigNavConverterV2.cxx:1413
Run2ToRun3TrigNavConverterV2::m_roIDescriptorCollectionCLID
CLID m_roIDescriptorCollectionCLID
Definition: Run2ToRun3TrigNavConverterV2.h:182
runBeamSpotCalibration.helper
helper
Definition: runBeamSpotCalibration.py:115
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
Run2ToRun3TrigNavConverterV2::createSFNodes
StatusCode createSFNodes(const ConvProxySet_t &, xAOD::TrigCompositeContainer &, const TEIdToChainsMap_t &finalTEs, const EventContext &context) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1078
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Run2ToRun3TrigNavConverterV2::filterFEAs
std::vector< HLT::TriggerElement::FeatureAccessHelper > filterFEAs(const std::vector< HLT::TriggerElement::FeatureAccessHelper > &feaVector, const HLT::TrigNavStructure &navigationDecoder) const
< both method skip TrigPassBits
Definition: Run2ToRun3TrigNavConverterV2.cxx:1391
HLTUtils.h
Run2ToRun3TrigNavConverterV2::extractTECtoChainMapping
StatusCode extractTECtoChainMapping(TEIdToChainsMap_t &allTES, TEIdToChainsMap_t &finalTEs) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:397
HLT::TrigNavStructure::getDirectPredecessors
static const std::vector< TriggerElement * > & getDirectPredecessors(const TriggerElement *te)
returns list of direct predecessors (nodes seeding me)
Definition: TrigNavStructure.cxx:120
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
TrigPassBitsContainer.h
ConvProxy::teIDs
std::vector< HLT::te_id_type > teIDs
Definition: Run2ToRun3TrigNavConverterV2.h:42
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrigCompositeUtils::getLinkToPrevious
const std::vector< ElementLink< DecisionContainer > > getLinkToPrevious(const Decision *d)
returns links to previous decision object 'seed'
Definition: TrigCompositeUtilsRoot.cxx:157
ClassID_traits.h
a traits class that associates a CLID to a type T It also detects whether T inherits from Gaudi DataO...
beamspotman.n
n
Definition: beamspotman.py:727
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SpecialCases::isTopo
const std::regex isTopo
Definition: SpecialCases.h:33
HLT::TriggerElement
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:27
ConvProxy::description
std::string description() const
Definition: Run2ToRun3TrigNavConverterV2.cxx:131
Types.h
TriggerElement.h
Run2ToRun3TrigNavConverterV2::linkTrkNode
StatusCode linkTrkNode(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1327
Run2ToRun3TrigNavConverterV2::createIMHNodes
StatusCode createIMHNodes(ConvProxySet_t &, xAOD::TrigCompositeContainer &, const EventContext &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1049
ConvProxy::passChains
std::set< HLT::Identifier > passChains
Definition: Run2ToRun3TrigNavConverterV2.h:47
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Run2ToRun3TrigNavConverterV2::m_includeTauTrackFeatures
Gaudi::Property< bool > m_includeTauTrackFeatures
Definition: Run2ToRun3TrigNavConverterV2.h:88
Run2ToRun3TrigNavConverterV2::m_TrigEMClusterContainerCLID
CLID m_TrigEMClusterContainerCLID
Definition: Run2ToRun3TrigNavConverterV2.h:186
TEIdToChainsMap_t
std::map< HLT::te_id_type, std::set< HLT::Identifier > > TEIdToChainsMap_t
Definition: Run2ToRun3TrigNavConverterV2.h:62
test_pyathena.parent
parent
Definition: test_pyathena.py:15
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
add
bool add(const std::string &hname, TKey *tobj)
Definition: fastadd.cxx:55
python.getProblemFolderFromLogs.el
dictionary el
Definition: getProblemFolderFromLogs.py:48
xAOD::TrigComposite_v1
Class used to describe composite objects in the HLT.
Definition: TrigComposite_v1.h:49
TrigCompositeUtils::initialRoIString
const std::string & initialRoIString()
Definition: TrigCompositeUtils.h:416
ConvProxy::ConvProxy
ConvProxy(const HLT::TriggerElement *te)
Definition: Run2ToRun3TrigNavConverterV2.cxx:23
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
HLT::Identifier
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:19
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
TrigCompositeUtils::hltSeedingNodeName
const std::string & hltSeedingNodeName()
Definition: TrigCompositeUtils.h:423
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::decisions
decisions
Definition: TrigComposite_v1.cxx:101
Run2ToRun3TrigNavConverterV2::removeTopologicalProxies
StatusCode removeTopologicalProxies(ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:916
Run2ToRun3TrigNavConverterV2::noUnconnectedHNodes
StatusCode noUnconnectedHNodes(const xAOD::TrigCompositeContainer &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1498
SpecialCases::egammaEtcut
const std::regex egammaEtcut
Definition: SpecialCases.h:31
columnar::isAvailable
bool isAvailable(ObjectId< CI, CM > id) const noexcept
Definition: ColumnAccessor.h:181
ChainNameParser::multiplicities
std::vector< int > multiplicities(const std::string &chain)
Definition: ChainNameParser.cxx:226
ConvProxy::isParent
bool isParent(const ConvProxy *other) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:39
Run2ToRun3TrigNavConverterV2::collapseFeaturesProxies
StatusCode collapseFeaturesProxies(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:804
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
Run2ToRun3TrigNavConverterV2::m_finalTEIdsToChains
TEIdToChainsMap_t m_finalTEIdsToChains
Definition: Run2ToRun3TrigNavConverterV2.h:98
HLT::StandaloneNavigation
Definition: StandaloneNavigation.h:14
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
Run2ToRun3TrigNavConverterV2::m_doCompression
Gaudi::Property< bool > m_doCompression
Definition: Run2ToRun3TrigNavConverterV2.h:86
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
ConvProxySet_t
std::set< ConvProxy * > ConvProxySet_t
Definition: Run2ToRun3TrigNavConverterV2.h:61
TrigConf::HLTUtils::hash2string
static const std::string hash2string(HLTHash, const std::string &category="TE")
hash function translating identifiers into names (via internal dictionary)
Run2ToRun3TrigNavConverterV2::associateChainsToProxies
StatusCode associateChainsToProxies(ConvProxySet_t &, const TEIdToChainsMap_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:665
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
LArNewCalib_PedestalAutoCorr.cp
cp
Definition: LArNewCalib_PedestalAutoCorr.py:188
Run2ToRun3TrigNavConverterV2::m_doLinkFeatures
Gaudi::Property< bool > m_doLinkFeatures
Definition: Run2ToRun3TrigNavConverterV2.h:87
Run2ToRun3TrigNavConverterV2::execute
virtual StatusCode execute(const EventContext &context) const override
Definition: Run2ToRun3TrigNavConverterV2.cxx:249
Run2ToRun3TrigNavConverterV2::getFeaSize
std::size_t getFeaSize(const ConvProxy &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1224
Run2ToRun3TrigNavConverterV2::numberOfHNodesPerProxyNotExcessive
StatusCode numberOfHNodesPerProxyNotExcessive(const ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1492
TrigCompositeUtils::createLegName
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
Definition: TrigCompositeUtilsRoot.cxx:166
Run2ToRun3TrigNavConverterV2::allProxiesHaveChain
StatusCode allProxiesHaveChain(const ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1464
HLT::TrigNavStructure::getRoINodes
static const std::vector< TriggerElement * > & getRoINodes(const TriggerElement *somenode)
gets all RoI type nodes seeding indirectly this TriggerElement
Definition: TrigNavStructure.cxx:73
Run2ToRun3TrigNavConverterV2::fillRelevantFeatures
StatusCode fillRelevantFeatures(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:943
Run2ToRun3TrigNavConverterV2::feaToSave
bool feaToSave(const HLT::TriggerElement::FeatureAccessHelper &fea, const std::string &sgName) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1437
xAOD::TrigComposite_v1::name
const std::string & name() const
Get a human-readable name for the object.
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
HLT::TrigNavStructure::getAllTEs
std::vector< TriggerElement * > & getAllTEs()
access needed by slimming tools.
Definition: TrigNavStructure.cxx:374
TrigCompositeUtils::linkToPrevious
void linkToPrevious(Decision *d, const std::string &previousCollectionKey, size_t previousIndex)
Links to the previous object, location of previous 'seed' decision supplied by hand.
Definition: TrigCompositeUtilsRoot.cxx:140
DeMoScan.index
string index
Definition: DeMoScan.py:362
Run2ToRun3TrigNavConverterV2::collapseFeaturelessProxies
StatusCode collapseFeaturelessProxies(ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:852
Run2ToRun3TrigNavConverterV2::m_CaloClusterCLID
CLID m_CaloClusterCLID
Definition: Run2ToRun3TrigNavConverterV2.h:187
HLT::TrigNavStructure::isInitialNode
static bool isInitialNode(const TriggerElement *te)
queries if node is an initial one
Definition: TrigNavStructure.cxx:499
TrigCompositeUtils::DecisionIDContainer
std::set< DecisionID > DecisionIDContainer
Definition: TrigComposite_v1.h:28
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
Run2ToRun3TrigNavConverterV2::roiToSave
bool roiToSave(const HLT::TrigNavStructure &run2Nav, const HLT::TriggerElement::FeatureAccessHelper &fea) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1453
python.selector.AtlRunQuerySelectorLhcOlc.selector
selector
Definition: AtlRunQuerySelectorLhcOlc.py:610
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:108
HLT::TriggerElement::FeatureAccessHelper
the FeatureAccessHelper is a class used to keep track of features attached to this TE.
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:192
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigRoiDescriptorCollection
Definition: TrigRoiDescriptorCollection.h:21
xAOD::TauTrack_v1
Definition: TauTrack_v1.h:27
HLT::StandaloneNavigation::deserialize
virtual bool deserialize(const std::vector< uint32_t > &input)
Definition: StandaloneNavigation.cxx:88
HLTSequenceList.h
Run2ToRun3TrigNavConverterV2::is2LegTopoChain
size_t is2LegTopoChain(const TrigConf::HLTChain *ptrChain) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:353
TrigCompositeUtils::hypoAlgNodeName
const std::string & hypoAlgNodeName()
Definition: TrigCompositeUtils.h:426
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Run2ToRun3TrigNavConverterV2::mirrorTEsStructure
StatusCode mirrorTEsStructure(ConvProxySet_t &, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:583
python.TriggerAPI.TriggerAPISession.chainName
chainName
Definition: TriggerAPISession.py:426
Run2ToRun3TrigNavConverterV2::finalize
virtual StatusCode finalize() override
Definition: Run2ToRun3TrigNavConverterV2.cxx:244
Run2ToRun3TrigNavConverterV2::m_clidSvc
ServiceHandle< IClassIDSvc > m_clidSvc
Definition: Run2ToRun3TrigNavConverterV2.h:83
TrigCompositeUtils::decisionIDs
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Definition: TrigCompositeUtilsRoot.cxx:65
Run2ToRun3TrigNavConverterV2::doCompression
StatusCode doCompression(ConvProxySet_t &convProxies, const HLT::TrigNavStructure &run2Nav) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:759
python.utility.LHE.merge
def merge(input_file_pattern, output_file)
Merge many input LHE files into a single output file.
Definition: LHE.py:29
HLT::Identifier::name
std::string name() const
reports human redable name
Definition: HLTIdentifier.cxx:12
Run2ToRun3TrigNavConverterV2::m_CaloClusterContainerCLID
CLID m_CaloClusterContainerCLID
Definition: Run2ToRun3TrigNavConverterV2.h:188
ConvProxy
Definition: Run2ToRun3TrigNavConverterV2.h:35
LArCellBinning.step
step
Definition: LArCellBinning.py:158
TrigCompositeUtils
Definition: Event/xAOD/xAODTrigger/xAODTrigger/TrigComposite.h:19
feaToSkip
bool feaToSkip(const HLT::TriggerElement::FeatureAccessHelper &fea)
Definition: Run2ToRun3TrigNavConverterV2.cxx:1383
ReadCalibFromCool.typeName
typeName
Definition: ReadCalibFromCool.py:477
SpecialCases::tauXeChain
const std::regex tauXeChain
Definition: SpecialCases.h:37
Run2ToRun3TrigNavConverterV2::printProxies
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
Definition: Run2ToRun3TrigNavConverterV2.cxx:649
ConvProxy::mergeAllowed
bool mergeAllowed(const ConvProxy *other) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:50
ConvProxy::feaHash
uint64_t feaHash
Definition: Run2ToRun3TrigNavConverterV2.h:49
Run2ToRun3TrigNavConverterV2::linkFeaNode
StatusCode linkFeaNode(ConvProxySet_t &convProxies, xAOD::TrigCompositeContainer &, const HLT::TrigNavStructure &run2Nav, const EventContext &context) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:1246
ClassID_traits::ID
static CLID ID()
Definition: Control/AthenaKernel/AthenaKernel/ClassID_traits.h:44
Run2ToRun3TrigNavConverterV2::m_TrigRingerRingsContainerCLID
CLID m_TrigRingerRingsContainerCLID
Definition: Run2ToRun3TrigNavConverterV2.h:184
Run2ToRun3TrigNavConverterV2::cureUnassociatedProxies
StatusCode cureUnassociatedProxies(ConvProxySet_t &) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:697
TrigCompositeUtils::getIDFromLeg
HLT::Identifier getIDFromLeg(const HLT::Identifier &legIdentifier)
Generate the HLT::Identifier which corresponds to the chain name from the leg name.
Definition: TrigCompositeUtilsRoot.cxx:180
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Run2ToRun3TrigNavConverterV2::m_teIDPrinter
std::function< void(const ConvProxy *)> m_teIDPrinter
Definition: Run2ToRun3TrigNavConverterV2.h:151
ConvProxy::parents
std::set< ConvProxy * > parents
Definition: Run2ToRun3TrigNavConverterV2.h:45
test_pyathena.counter
counter
Definition: test_pyathena.py:15
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
Run2ToRun3TrigNavConverterV2::m_TrigEMClusterCLID
CLID m_TrigEMClusterCLID
Definition: Run2ToRun3TrigNavConverterV2.h:185
TrigCompositeUtils::inputMakerNodeName
const std::string & inputMakerNodeName()
Definition: TrigCompositeUtils.h:425
python.compressB64.c
def c
Definition: compressB64.py:93
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Run2ToRun3TrigNavConverterV2::m_chainsToSave
Gaudi::Property< std::vector< std::string > > m_chainsToSave
Definition: Run2ToRun3TrigNavConverterV2.h:90
Run2ToRun3TrigNavConverterV2::m_TrackParticleContainerCLID
CLID m_TrackParticleContainerCLID
Definition: Run2ToRun3TrigNavConverterV2.h:189
SpecialCases::egammaCombinedWithEtcut
const std::regex egammaCombinedWithEtcut
Definition: SpecialCases.h:32
ConvProxy::isChild
bool isChild(const ConvProxy *other) const
Definition: Run2ToRun3TrigNavConverterV2.cxx:29
python.handimod.cc
int cc
Definition: handimod.py:522
Run2ToRun3TrigNavConverterV2::m_doSelfValidation
Gaudi::Property< bool > m_doSelfValidation
Definition: Run2ToRun3TrigNavConverterV2.h:85
TrigCompositeUtils::decisionToElementLink
ElementLink< DecisionContainer > decisionToElementLink(const Decision *d, const EventContext &ctx)
Takes a raw pointer to a Decision and returns an ElementLink to the Decision.
Definition: TrigCompositeUtilsRoot.cxx:123
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
HLT::te_id_type
uint32_t te_id_type
Definition: Trigger/TrigEvent/TrigNavStructure/TrigNavStructure/Types.h:11