ATLAS Offline Software
ChainGroup.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /**********************************************************************************
6  * @Project: TrigDecisionTool
7  * @Package: TrigDecisionTool
8  * @Class : ChainGroup
9  *
10  * @brief simple container to hold trigger chains
11  *
12  * @author Michael Begel <michael.begel@cern.ch> - Brookhaven National Laboratory
13  * @author Alexander Mann <mann@cern.ch> - University of Goettingen
14  *
15  ***********************************************************************************/
16 #include <limits>
17 #include "boost/regex.hpp"
18 #include "boost/range/adaptor/reversed.hpp"
19 
20 #include "CxxUtils/bitmask.h"
32 
36 
37 
38 
39 using namespace std;
40 
41 Trig::ChainGroup::ChainGroup(const std::vector< std::string >& triggerNames,
43  :
44  m_patterns(triggerNames),
45  m_cgm(parent)
46 {}
47 
49  std::vector< std::string > v;
50  v.resize(patterns().size()+rhs.patterns().size());
51  merge(patterns().begin(), patterns().end(),
52  rhs.patterns().begin(), rhs.patterns().end(),
53  v.begin());
54  return *(cgm().createChainGroup(v));
55 }
56 
57 
59  return Trig::keyWrap(names())==Trig::keyWrap(rhs.names());
60 }
61 
63  return !(*this==rhs);
64 }
65 
66 void Trig::ChainGroup::addAlias(const std::string& alias) {
67  cgm().createChainGroup(patterns(),alias);
68 }
69 
71  // thread-safe because assert_decision is locked
72  auto nonconst_cgm ATLAS_THREAD_SAFE = const_cast<Trig::CacheGlobalMemory*>(&cgm());
73  nonconst_cgm->assert_decision();
74 
75  return cgm();
76 }
77 
78 bool Trig::ChainGroup::HLTResult(const std::string& chain, unsigned int condition) const {
79  bool chainRESULT = false;
80  if (chain.empty()) return chainRESULT;
81  const HLT::Chain* fchain=cgm_assert().chain(chain);
82  if (fchain==nullptr) return chainRESULT;
83 
84 
85  bool RAW = fchain->chainPassedRaw();
86  const bool PASSTHROUGH = fchain->isPassedThrough();
87  const bool PRESCALED = fchain->isPrescaled();
88  const bool RESURRECTED = fchain->isResurrected();
89 
90  // Resurrection overwrites the value in RAW but sets the RESURRECTED flag
91  // we should therefore fix RAW appropriately
92  if (~condition & TrigDefs::allowResurrectedDecision) {
93  if (RESURRECTED) {
94  RAW=false;
95  }
96  }
97  //
98  // Do we accept the result?
99  //
100  if (condition & TrigDefs::passedThrough) {
101  if (PASSTHROUGH) {chainRESULT=true;}
102  }
103  if (condition & TrigDefs::requireDecision) {
104  if (RAW && !PRESCALED) {chainRESULT=true;}
105  if ( condition & TrigDefs::allowResurrectedDecision ) { // prescaling does not matter for RR (it runs in fact because of that
106  if (RAW) {chainRESULT=true;}
107  }
108 
109  }
110  // respects resurrection -- is this the appropriate behavior???
111  if (condition & TrigDefs::eventAccepted) {
112  if ( (RAW && !PRESCALED) || PASSTHROUGH) {chainRESULT=true;}
113  }
114  ATH_MSG_DEBUG("ChainGroup::HLTResult Counter = " << std::setw(4) << fchain->getChainCounter()
115  << " name = " << fchain->getChainName()
116  << " level = " << fchain->getConfigChain()->level()
117  << " success (raw) = " << fchain->chainPassedRaw()
118  << " pass-through = " << fchain->isPassedThrough()
119  << " prescaled = " << fchain->isPrescaled()
120  << " rerun = " << fchain->isResurrected()
121  << " lastActiveStep = " << fchain->getChainStep()
122  << " name = " << std::setw(35) << fchain->getChainName()
123  << " result = " << chainRESULT);
124 
125  return chainRESULT;
126 }
127 
128 // this logic fails for passthrough especially with enforceLogicalFlow!!!!
129 bool Trig::ChainGroup::L1Result(const std::string& item, unsigned int condition) const {
130  bool r = false;
131  if (item.empty()) return r;
132  if (item.find(',')!=std::string::npos) {
133  for(const std::string& item : convertStringToVector(item)) {
134  if(L1Result(item,condition)) return true;
135  }
136  return false;
137  }
138  const LVL1CTP::Lvl1Item* fitem=cgm_assert().item(item);
139  if (fitem==nullptr) {
140  return r;
141  }
142  ATH_MSG_DEBUG(" success (raw) = " << fitem->isPassedBeforePrescale()
143  << " prescaled = " << fitem->isPrescaled()
144  << " vetoed = " << fitem->isVeto()
145  << " name = " << std::setw(35) << fitem->name());
146 
147  r = fitem->isPassedAfterVeto();
148 
149  if (condition & TrigDefs::allowResurrectedDecision)
150  r = fitem->isPassedBeforePrescale();
151 
152  //if (condition & TrigDefs::eventAccepted)
153  // r = fitem->isPassedAfterVeto();
154  //else
155  // r = fitem->isPassedBeforePrescale();
156  return r;
157 }
158 
159 
160 std::string Trig::ChainGroup::getLowerName(const std::string& name) const {
161  if ( name.empty() )
162  return name;
163  const TrigConf::HLTChain* cchain = cgm().config_chain(name);
164  if (cchain==nullptr){
165  ATH_MSG_WARNING(" Lower chain name used by: " << name << " is not in the configuration ");
166  return "BAD NAME";
167  }
168  return cchain->lower_chain_name();
169 }
170 
171 // Helper to get decision of a single chain (private)
173 {
174  bool result = HLTResult(chain.chain_name(),condition);
175  if (result && (condition & TrigDefs::enforceLogicalFlow)) {
176  // enforceLogicalFlow
177  if (chain.level()=="EF") {
178  const std::string& nexttwo = getLowerName(chain.chain_name());
179  result = result && HLTResult(nexttwo,condition);
180  result = result && L1Result(getLowerName(nexttwo),condition);
181 
182  } else if (chain.level()=="L2") {
183  result = result && L1Result(getLowerName(chain.chain_name()),condition);
184 
185  } else if (chain.level()=="HLT"){
186  result = result && L1Result(getLowerName(chain.chain_name()),condition);
187  }
188  }
189 
190  return result;
191 }
192 
193 std::vector<bool> Trig::ChainGroup::isPassedForEach(unsigned int condition) const
194 {
195  std::vector<bool> result;
196  result.reserve(m_confChains.size() + m_confItems.size());
197 
198  for (const TrigConf::HLTChain* ch : m_confChains) {
199  result.push_back( isPassed(*ch, condition) );
200  }
201  for (const TrigConf::TriggerItem* item : m_confItems) {
202  result.push_back( L1Result(item->name(), condition) );
203  }
204 
205  return result;
206 }
207 
208 bool Trig::ChainGroup::isPassed(unsigned int condition) const
209 {
210  if (condition & TrigDefs::Express_passed) {
211  ATH_MSG_ERROR("Incorrect use of Express_passed bit. Please use isPassedBits() and test for TrigDefs::Express_passed in the returned bit-map.");
212  }
213 
214  // True if any HLT or L1 item passed
215  return ( std::any_of(m_confChains.cbegin(), m_confChains.cend(),
216  [&](const TrigConf::HLTChain* ch) {return isPassed(*ch, condition);}) ||
217  std::any_of(m_confItems.cbegin(), m_confItems.cend(),
218  [&](const TrigConf::TriggerItem* item) {return L1Result(item->name(), condition);}) );
219 }
220 
221 unsigned int Trig::ChainGroup::HLTBits(const std::string& chain, const std::string& level, const TrigCompositeUtils::DecisionIDContainer& passExpress) const {
222  unsigned int chainRESULT = 0;
223  if (chain.empty()) return chainRESULT;
224  const HLT::Chain* fchain = cgm_assert().chain(chain);
225  if (fchain==nullptr) return chainRESULT;
226  if (level=="L2") {
227  if (fchain->chainPassedRaw()) chainRESULT = chainRESULT | TrigDefs::L2_passedRaw;
228  if (fchain->isPassedThrough()) chainRESULT = chainRESULT | TrigDefs::L2_passThrough;
229  if (fchain->isPrescaled()) chainRESULT = chainRESULT | TrigDefs::L2_prescaled;
230  if (fchain->isResurrected()) chainRESULT = chainRESULT | TrigDefs::L2_resurrected;
231  } else {//L2EF merged use same EF bits
232  if (fchain->chainPassedRaw()) chainRESULT = chainRESULT | TrigDefs::EF_passedRaw;
233  if (fchain->isPassedThrough()) chainRESULT = chainRESULT | TrigDefs::EF_passThrough;
234  if (fchain->isPrescaled()) chainRESULT = chainRESULT | TrigDefs::EF_prescaled;
235  if (fchain->isResurrected()) chainRESULT = chainRESULT | TrigDefs::EF_resurrected;
236 
237  if (passExpress.count( HLT::Identifier(chain).numeric() ) == 1) {
238  chainRESULT = chainRESULT | TrigDefs::Express_passed;
239  }
240  }
241  return chainRESULT;
242 }
243 
244 unsigned int Trig::ChainGroup::L1Bits(const std::string& item) const {
245  unsigned int r = 0;
246  if (item.empty()) return r;
247  if (item.find(',')!=std::string::npos) {
248  for(const std::string& item : convertStringToVector(item)) {
249  r |= L1Bits(item);
250  }
251  return r;
252  }
253  const LVL1CTP::Lvl1Item* fitem = cgm_assert().item(item);
254  if (fitem==nullptr) return r;
255  if (fitem->isPassedBeforePrescale()) r = r | TrigDefs::L1_isPassedBeforePrescale;
256  if (fitem->isPassedAfterPrescale()) r = r | TrigDefs::L1_isPassedAfterPrescale;
257  if (fitem->isPassedAfterVeto()) r = r | TrigDefs::L1_isPassedAfterVeto;
258  return r;
259 }
260 
261 std::vector<unsigned int> Trig::ChainGroup::isPassedBitsForEach() const
262 {
263  // This is for the express decision (R3 only), we read this directly from the navigation (not from bits)
264  const SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer>* navRHK = cgm().getRun3NavigationKeyPtr();
266  if (navRHK && !navRHK->empty()) {
267  SG::ReadHandle<TrigCompositeUtils::DecisionContainer> navRH(*navRHK); // No good way to pass in the context here?
268  if (navRH.isValid()) {
270  if (expressTerminusNode) {
271  TrigCompositeUtils::decisionIDs(expressTerminusNode, passExpress);
272  }
273  }
274  }
275 
276  std::vector<unsigned int> all;
277  all.reserve(m_confChains.size() + m_confItems.size());
278 
279  for ( const TrigConf::HLTChain* ch : m_confChains ) {
280 
281  unsigned int RESULT = HLTBits(ch->chain_name(), ch->level(), passExpress);
282 
283  if (ch->level()=="EF") {
284  const std::string& nexttwo = getLowerName(ch->chain_name());
285  RESULT = RESULT | HLTBits(nexttwo,"L2", passExpress);
286  RESULT = RESULT | L1Bits(getLowerName(nexttwo));
287 
288  } else if (ch->level()=="L2") {
289  RESULT = RESULT | L1Bits(getLowerName(ch->chain_name()));
290 
291  } else if (ch->level()=="HLT") {
292  RESULT = RESULT | L1Bits(getLowerName(ch->chain_name()));
293  }
294 
295  all.push_back(RESULT);
296  }
297 
298  for ( const TrigConf::TriggerItem* item : m_confItems ) {
299  all.push_back( L1Bits(item->name()) );
300  }
301 
302  return all;
303 }
304 
305 unsigned int Trig::ChainGroup::isPassedBits() const
306 {
307  const std::vector<unsigned int> all = isPassedBitsForEach();
308  unsigned int result = 0;
309  for (unsigned int r : all) {
310  result = result | r;
311  }
312  return result;
313 }
314 
316  HLT::ErrorCode errorCode = HLT::OK;
317  for ( const TrigConf::HLTChain* ch : m_confChains ) {
318  const HLT::Chain* fchain = cgm_assert().chain(ch->chain_name());
319  if (fchain==nullptr) continue;
320  HLT::ErrorCode ec = fchain->getErrorCode();
321  errorCode = errorCode > ec ? errorCode : ec;
322  }
323  return errorCode;
324 }
325 
326 float Trig::ChainGroup::HLTPrescale(const std::string& chain, unsigned int /*condition*/) const {
327  if (chain=="") return 0.;
328 
329  const TrigConf::HLTChain* fchain=cgm().config_chain(chain);
330  if (fchain==0) { // this is error condition, we always need configuration of the chains in the chaon group!
331  ATH_MSG_WARNING("Configuration for the chain: " << chain << " not known");
332  return std::numeric_limits<float>::quiet_NaN();
333  }
334  float chainRESULT = fchain->prescale();
335 
336  if (chainRESULT < 1)
337  chainRESULT = 0.;
338 
339  return chainRESULT;
340 }
341 
342 
343 bool Trig::ChainGroup::isCorrelatedL1items(const std::string& item) const {
344  if( (item == "L1_MU20,L1_MU21") || (item == "L1_MU21,L1_MU20") ) return true;
345  return false;
346 }
347 
348 float Trig::ChainGroup::correlatedL1Prescale(const std::string& item) const {
349  if( (item == "L1_MU20,L1_MU21") || (item == "L1_MU21,L1_MU20") ) {
350  //see discussion in ATR-16612
351  auto l1mu20 = cgm().config_item("L1_MU20");
352  if (l1mu20==nullptr) {
353  ATH_MSG_WARNING("Configuration for the item L1_MU20 not known");
354  return std::numeric_limits<float>::quiet_NaN();
355  }
356  float l1mu20ps = cgm().item_prescale(l1mu20->ctpId());
357 
358  auto l1mu21 = cgm().config_item("L1_MU21");
359  if (l1mu21==nullptr) {
360  ATH_MSG_WARNING("Configuration for the item L1_MU21 not known");
361  return std::numeric_limits<float>::quiet_NaN();
362  }
363  float l1mu21ps = cgm().item_prescale(l1mu21->ctpId());
364 
365  if( (l1mu20ps < 1.0) && (l1mu21ps < 1.0) ) return 0.0;
366  if( (l1mu20ps < 1.0) ) return l1mu21ps;
367  if( (l1mu21ps < 1.0) ) return l1mu20ps;
368  if(l1mu20ps == 1.0) return 1.0;
369  return 0.0;
370  }
371  return 0.0;
372 }
373 
374 float Trig::ChainGroup::L1Prescale(const std::string& item, unsigned int /*condition*/) const {
375  if (item.empty()) return 0;
376 
377  if(item.find(',')==std::string::npos) {
378  const TrigConf::TriggerItem* fitem=cgm().config_item(item);
379  if (fitem==nullptr) {
380  ATH_MSG_WARNING("Configuration for the item: " << item << " not known");
381  return std::numeric_limits<float>::quiet_NaN();
382  }
383  // now we can;t access the prescale value because this information doe not come togehther as in HLT
384  // we need to go to the cache of L1 items and get it from there
385  float itemprescale = cgm().item_prescale(fitem->ctpId());
386  if ( itemprescale < 1) itemprescale = 0;
387  return itemprescale;
388  } else if(isCorrelatedL1items(item)) {
389  return correlatedL1Prescale(item);
390  } else {
391  float minprescale=0;
392  for(const std::string& item : convertStringToVector(item)) {
393 
394  const TrigConf::TriggerItem* fitem=cgm().config_item(item);
395  if (fitem==nullptr) {
396  ATH_MSG_WARNING("Configuration for the item: " << item << " not known");
397  return std::numeric_limits<float>::quiet_NaN();
398  }
399  float itemprescale = cgm().item_prescale(fitem->ctpId());
400  if ( itemprescale < 1) itemprescale = 0;
401  minprescale = (minprescale&&(minprescale<itemprescale)?minprescale:itemprescale); // takes min, except the first time
402  }
403  return minprescale;
404  }
405 }
406 
407 float Trig::ChainGroup::getPrescale(unsigned int condition) const {
408  if ( condition != TrigDefs::Physics )
409  return 0.0;
410  return m_prescale;
411 }
412 
414 {
415  bool singleTrigger = (m_confChains.size()+m_confItems.size()==1);
416 
417  for ( const TrigConf::HLTChain* ch : m_confChains ) {
418 
419  const std::string& hltChainName = ch->chain_name();
420  float chainRESULT = HLTPrescale(hltChainName,condition);
421 
422  if (condition & TrigDefs::enforceLogicalFlow) {
423  // enforceLogicalFlow
424  if (ch->level()=="EF") {
425  const std::string& hltChainNameL2 = getLowerName(hltChainName);
426  const std::string& l1ItemName = getLowerName(hltChainNameL2);
427  chainRESULT *= HLTPrescale(hltChainNameL2,condition);
428  chainRESULT *= L1Prescale(l1ItemName,condition);
429  if(l1ItemName.find(',')!=std::string::npos) singleTrigger=false;
430 
431  } else if (ch->level()=="L2") {
432  const std::string& l1ItemName = getLowerName(hltChainName);
433  chainRESULT *= L1Prescale(l1ItemName,condition);
434  if(l1ItemName.find(',')!=std::string::npos) singleTrigger=false;
435 
436  } else if (ch->level()=="HLT") {
437  const std::string& l1ItemName = getLowerName(hltChainName);
438  chainRESULT *= L1Prescale(l1ItemName,condition);
439  if(l1ItemName.find(',')!=std::string::npos and !isCorrelatedL1items(l1ItemName) ) singleTrigger=false;
440  }
441  }
442 
443  if (singleTrigger) return chainRESULT; // for a single trigger we are done
444 
445  const bool UNPRESCALED = (fabs(chainRESULT-1.0)<1e-5);
446 
447  if (UNPRESCALED) return 1.0; // any unprescaled trigger and we are done too
448  }
449 
450 
451  for ( const TrigConf::TriggerItem* item : m_confItems ) {
452  const std::string& l1ItemName = item->name();
453  const float itemRESULT = L1Prescale(l1ItemName, condition);
454  if(l1ItemName.find(',')!=std::string::npos) singleTrigger=false;
455 
456  if (singleTrigger) return itemRESULT; // for a single trigger we are done
457 
458  const bool UNPRESCALED = (itemRESULT==1);
459 
460  if (UNPRESCALED) return 1.0; // any unprescaled trigger and we are done too
461  }
462 
463  return 0.0; // multiple triggers and all are prescaled
464 }
465 
466 
467 std::vector< std::string > Trig::ChainGroup::getListOfTriggers() const {
468  return m_names;
469 }
470 
471 
472 std::vector< std::string > Trig::ChainGroup::getListOfStreams() const {
473  std::set< std::string > streams;
474  for ( const TrigConf::HLTChain* ch : m_confChains ) {
475  for ( const TrigConf::HLTStreamTag* s : ch->streams() ) {
476  streams.insert(s->stream());
477  }
478  }
479  return {streams.begin(), streams.end()};
480 }
481 
482 //
483 // Groups
484 //
485 
486 vector<string>
488 
489  vector< string > v;
490 
491  for( const TrigConf::HLTChain* ch : m_confChains )
492  v.assign( ch->groups().begin(), ch->groups().end() );
493 
494  return v;
495 }
496 
497 //
498 // Signatures
499 //
500 
501 std::vector< std::string > Trig::ChainGroup::getListOfSignatures() const {
502  std::set< std::string > sig;
503  for ( const TrigConf::HLTChain* ch : m_confChains ) {
504  for ( const TrigConf::HLTSignature* s : ch->signatureList() ) {
505  sig.insert(s->label());
506  }
507  }
508  return {sig.begin(), sig.end()};
509 }
510 
511 
512 //
513 // Return level 1 thresholds
514 //
515 
516 vector<string>
518 
519  set<string> s; // using a set makes the items in the result vector unique
520  std::stack<const TrigConf::TriggerItemNode*> nodes;
522 
523  for( const TrigConf::TriggerItem* item : m_confItems ) {
524  nodes.push( item->topNode() );
525  while (!nodes.empty()) {
526  node = nodes.top(); nodes.pop();
527  if (node == NULL)
528  continue;
529  if (node->isThreshold()) {
530  if (node->triggerThreshold()) {
531  // available if thresholds have been read in
532  if (!node->triggerThreshold()->name().empty())
533  s.insert(node->triggerThreshold()->name());
534  } else if (!node->thresholdName().empty()) {
535  // fall back solution
536  s.insert(node->thresholdName());
537  }
538  } else {
539  for(TrigConf::TriggerItemNode* childnode : node->children()) {
540  nodes.push(childnode);
541  }
542  }
543  }
544  // I am not using (*it)->topNode()->getAllThresholds() here, because it returns nothing when only ItemDef (and not the thresholds themselves) are defined
545  }
546 
547  return {s.begin(), s.end()};
548 }
549 
550 
551 //
552 // Trigger Elements
553 //
554 
555 std::vector< std::vector< std::string > > Trig::ChainGroup::getListOfTriggerElements() const {
556 
557  std::set< std::vector< std::string > > tes;
558  std::vector< std::string > t;
559 
560  for( const TrigConf::HLTChain* ch : m_confChains ) {
561  for ( const TrigConf::HLTSignature* s : ch->signatureList() ) {
562  t.clear();
563  for ( const TrigConf::HLTTriggerElement* te : s->outputTEs() ) {
564  t.push_back( te->name());
565  }
566  tes.insert(t);
567  }
568  }
569  return {tes.begin(), tes.end()};
570 }
571 
572 
573 //
574 // get vector of vector with all Trigger Elements
575 //
576 
577 std::vector< std::vector< TrigConf::HLTTriggerElement* > > Trig::ChainGroup::getHLTTriggerElements() const {
578 
579  std::set< std::vector< TrigConf::HLTTriggerElement* > > tes;
580 
581  for( const TrigConf::HLTChain* ch : m_confChains ) {
582  for ( const TrigConf::HLTSignature* s : ch->signatureList() ) {
583  tes.insert(s->outputTEs());
584  }
585  }
586  return {tes.begin(), tes.end()};
587 }
588 
589 
590 void
592  const TrigConf::ItemContainer* confItems,
593  TrigDefs::Group prop) {
594 
595  m_confChains.clear();
596  m_confItems.clear();
597  m_names.clear();
598 
599  // protect against genConf failure
600  if (!(confChains && confItems) ) return;
601 
603 
604  for(const std::string& pat : m_patterns) {
605  // find chains matching pattern
606  boost::regex compiled(pat);
607  boost::cmatch what;
608 
609  for(TrigConf::HLTChain* ch : *confChains) {
610  if ( boost::regex_match(ch->chain_name().c_str(), what, compiled) ) {
611  m_confChains.push_back(ch);
612  }
613  }
614 
615  for(TrigConf::TriggerItem* item : *confItems) {
616  if ( boost::regex_match( item->name().c_str(), what, compiled) ) {
617  m_confItems.push_back(item);
618  }
619  }
620  }
621 
622  } else { // Do not parse as regex
623 
624  for(const std::string& what : m_patterns) {
625 
626  bool found_it = false;
627 
628  for(TrigConf::HLTChain* ch : *confChains) {
629  if (ch->chain_name() == what) {
630  m_confChains.push_back(ch);
631  found_it = true;
632  break;
633  }
634  }
635 
636  if (found_it) {
637  continue;
638  }
639 
640  for(TrigConf::TriggerItem* item : *confItems) {
641  if (item->name() == what) {
642  m_confItems.push_back(item);
643  found_it = true;
644  break;
645  }
646  }
647 
648  if (found_it) {
649  continue;
650  }
651 
652  ATH_MSG_WARNING("Explicitly requested '" << what << "' be added to a ChainGroup"
653  << " but this item or chain could not be found in the menu");
654  }
655 
656  } // parseAsRegex
657 
658  // Cache the names of all triggers
659  m_names.reserve(m_confChains.size() + m_confItems.size());
660  for (const TrigConf::HLTChain* ch : m_confChains) m_names.push_back(ch->chain_name());
661  for (const TrigConf::TriggerItem* item : m_confItems) m_names.push_back(item->name());
662 
663  m_prescale = calculatePrescale(TrigDefs::Physics);
664 }
665 
667 // features
668 
669 namespace ChainGroup_impl {
670  using namespace HLT;
671  using namespace Trig;
672 
673  bool allActive(const std::vector<TriggerElement*>& tes) {
674  for(TriggerElement* te : tes){
675  if (te->getActiveState() == false)
676  return false;
677  }
678  return true;
679  }
680 
681 
682 
684  // go over the steps of the chain and collecte TEs combinations for each of the chain step (signature)
685  bool last_step=true;
686  const TrigConf::HLTSignature* previous_sig(0);
687  for(const TrigConf::HLTSignature* sig : boost::adaptors::reverse(conf->signatureList())) {
688  // chain without signatures
689  if (!sig) break;
690 
691  // the signatures size changes from step to step, this needs custom treatement and the iteration eeds to be stoped here
692  if ( previous_sig && previous_sig->outputTEs().size() != sig->outputTEs().size() )
693  break;
694  previous_sig = sig;
695 
696  std::vector<std::vector<HLT::TriggerElement*> > tes(sig->outputTEs().size()); // preallocate
697  size_t idx = 0;
698  for(const TrigConf::HLTTriggerElement* confte : sig->outputTEs() ) {
699 
700  // here the condition enters; if we take only accepted objects we need to pick only the active TEs
701  cgm.navigation()->getAllOfType(confte->id(), tes[idx], condition & TrigDefs::Physics );
702  idx++;
703  }
704  HLT::ComboIterator combination(tes, cgm.navigation());
705 
706  // build the combinations, sometimes a huge list
707  while (combination.isValid()) {
708  // very very tricky, if all TEs in the combination are active then it means they were already picked up by previous combinations
709  // but we can not do this for the last chain step, (we woudl be unable to pick objects whcih made trigger passing)
710  //std::cerr << "emitting new combination last_step: "<< last_step << std::endl;
711  if (!allActive(*combination) || last_step) {
712  fc.addWithChecking(Combination(*combination, &cgm));
713  }
714  ++combination;
715  }
716 
717  if ( condition & TrigDefs::Physics ) // here again athe condition calls for the loop breaking
718  break;
719  else
720  last_step = false; // and go deeper
721  }
722  }
723 }// eof namespace
724 
727  using namespace ChainGroup_impl;
728  FeatureContainer f(&cgm_assert());
729 
730  // this loop only applies to L2 and EF chain groups
731  for (const TrigConf::HLTChain* ch : m_confChains) {
732  const HLT::Chain* fchain = cgm_assert().chain(*ch);
733  if (fchain) {
734  collectCombinations(fchain->getConfigChain(), cgm_assert(), f, condition);
735  }
736  }
737 
738  // this part only applies to L1 chain groups
739  std::vector< std::vector< HLT::TriggerElement*> > tes;
740  std::vector< std::vector< HLT::TriggerElement*> >::iterator tesit;
741 
742  for(const TrigConf::TriggerItem* item : m_confItems) {
743 
744  std::set< std::string > threshold_names;
745  std::stack<const TrigConf::TriggerItemNode*> nodes;
746 
747  nodes.push( item->topNode() );
748 
749  // collect unique list (= set) of threshold names for this item
750  while (!nodes.empty()) {
751  const TrigConf::TriggerItemNode* node = nodes.top();
752  nodes.pop();
753  if (node == nullptr)
754  continue;
755  if (node->isThreshold()) {
756  if (node->triggerThreshold()) {
757  // available if thresholds have been read in
758  if (!node->triggerThreshold()->name().empty())
759  threshold_names.insert(node->triggerThreshold()->name());
760  } else if (!node->thresholdName().empty()) {
761  // fall back solution
762  threshold_names.insert(node->thresholdName());
763  }
764  }
765  for(TrigConf::TriggerItemNode* childnode : node->children()) {
766  nodes.push(childnode);
767  }
768  }
769 
770  // collect corresponding TEs and add them using appendFeatures()
771  tes.clear();
772  tes.resize(threshold_names.size());
773  tesit = tes.begin();
775 
776  for (setstrit = threshold_names.begin(); setstrit != threshold_names.end(); ++setstrit, ++tesit) {
777  cgm_assert().navigation()->getAllOfType(TrigConf::HLTUtils::string2hash(*setstrit), *tesit, true);
778  }
779 
780  appendFeatures(tes, f);
781  }
782 
783  ATH_MSG_DEBUG("features: features container size: "<< f.getCombinations().size());
784  return f;
785 }
786 
787 
788 void Trig::ChainGroup::appendFeatures(std::vector< std::vector< HLT::TriggerElement*> >& tes, Trig::FeatureContainer& fc) const {
789 
790  // appends (combinations of) TriggerElements to FeatureContainer
791  if (tes.empty()) // ComboIterator::isValid would return true in this case
792  return;
793 
794  HLT::ComboIterator combination(tes, cgm_assert().navigation());
795  while (combination.isValid()) {
796  fc.addWithChecking(Combination(*combination, &cgm_assert()));
797 
798  ATH_MSG_VERBOSE(" adding combination" << Combination(*combination, &cgm_assert()));
799 
800  ++combination;
801  }
802 }
HLT::Chain::getChainCounter
unsigned int getChainCounter() const
return the unique identifier of this Chain (uint)
Definition: Chain.h:93
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trig::ChainGroup::isPassedBitsForEach
std::vector< unsigned int > isPassedBitsForEach() const
return result of isPassedBits for each chain in the group
Definition: ChainGroup.cxx:261
beamspotman.r
def r
Definition: beamspotman.py:676
TriggerItem.h
Trig::ChainGroup::update
void update(const TrigConf::HLTChainList *confChains, const TrigConf::ItemContainer *confItems, TrigDefs::Group prop=TrigDefs::Group::Default)
Definition: ChainGroup.cxx:591
Trig::ChainGroup::getListOfSignatures
std::vector< std::string > getListOfSignatures() const
Definition: ChainGroup.cxx:501
Trig::ChainGroup::correlatedL1Prescale
float correlatedL1Prescale(const std::string &item) const
Definition: ChainGroup.cxx:348
TrigConf::TriggerItem::ctpId
int ctpId() const
Definition: TriggerItem.h:34
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
TrigDefs::Group
Group
Properties of a chain group.
Definition: GroupProperties.h:13
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Trig::ChainGroup::getLowerName
std::string getLowerName(const std::string &EFname) const
Definition: ChainGroup.cxx:160
get_generator_info.result
result
Definition: get_generator_info.py:21
Trig::ChainGroup::addAlias
void addAlias(const std::string &alias)
adds alias (sort understandabel name) to the group
Definition: ChainGroup.cxx:66
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
TrigConf::HLTChain::level
const std::string & level() const
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:75
Trig::ChainGroup::operator!=
bool operator!=(const Trig::ChainGroup &rhs)
Definition: ChainGroup.cxx:62
HLT::TrigNavStructure::getAllOfType
void getAllOfType(const te_id_type id, std::vector< TriggerElement * > &output, const bool activeOnly=true) const
The query returning a collection of all TriggerElements if name is given.
Definition: TrigNavStructure.cxx:344
HLT::Identifier::numeric
TrigCompositeUtils::DecisionID numeric() const
numeric ID
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:47
Trig
The common trigger namespace for trigger analysis tools.
Definition: LArCellMonAlg.h:33
python.outputTest_v2.streams
streams
Definition: outputTest_v2.py:55
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
patterns
std::vector< std::string > patterns
Definition: listroot.cxx:187
HLT::ErrorCode
The definition of error codes in HLT. This is a class (note; before was simple enum) to enable safer ...
Definition: Trigger/TrigEvent/TrigSteeringEvent/TrigSteeringEvent/Enums.h:80
TrigConf::HLTChain::prescale
float prescale() const
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:141
HLTChain.h
TrigConf::HLTChain::lower_chain_name
const std::string & lower_chain_name() const
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:77
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
Cut::all
@ all
Definition: SUSYToolsAlg.cxx:67
Trig::ChainGroup::HLTResult
bool HLTResult(const std::string &chain, unsigned int condition) const
Definition: ChainGroup.cxx:78
Trig::ChainGroup::ChainGroup
ChainGroup(const std::vector< std::string > &triggerNames, Trig::CacheGlobalMemory &parent)
Definition: ChainGroup.cxx:41
HLT::Chain::getConfigChain
const TrigConf::HLTChain * getConfigChain() const
get underlying ConfigChain
Definition: Chain.h:78
Trig::ChainGroup::getListOfThresholds
std::vector< std::string > getListOfThresholds() const
Definition: ChainGroup.cxx:517
Trig::ChainGroup::HLTBits
unsigned int HLTBits(const std::string &chain, const std::string &level, const TrigCompositeUtils::DecisionIDContainer &passExpress) const
Definition: ChainGroup.cxx:221
LArG4GenerateShowerLib.condition
condition
Definition: LArG4GenerateShowerLib.py:19
Trig::ChainGroup::calculatePrescale
float calculatePrescale(unsigned int condition=TrigDefs::Physics)
Definition: ChainGroup.cxx:413
TrigConf::TriggerItemNode
Definition: TriggerItemNode.h:22
Trig::CacheGlobalMemory
Definition: CacheGlobalMemory.h:67
HLT::Chain::isPrescaled
bool isPrescaled() const
is chain prescaled ?
Definition: Chain.h:86
ChainGroup.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::ReadHandleKey
Property holding a SG store/key/clid from which a ReadHandle is made.
Definition: StoreGate/StoreGate/ReadHandleKey.h:39
TrigConf::HLTChain
HLT chain configuration information.
Definition: TrigConfHLTData/TrigConfHLTData/HLTChain.h:35
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
TDTUtilities.h
Trig::ChainGroup::operator==
bool operator==(const Trig::ChainGroup &rhs)
Definition: ChainGroup.cxx:58
LVL1CTP::Lvl1Item::isVeto
bool isVeto() const
Definition: Lvl1Item.h:56
Trig::ChainGroup::operator+
const Trig::ChainGroup & operator+(const Trig::ChainGroup &rhs)
Definition: ChainGroup.cxx:48
ChainGroup_impl::allActive
bool allActive(const std::vector< TriggerElement * > &tes)
Definition: ChainGroup.cxx:673
ComboIterator.h
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
Trig::convertStringToVector
std::vector< std::string > convertStringToVector(const std::string &triggerNames)
makes a split of list of chains into the vector of chains
Definition: TDTUtilities.cxx:41
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
ChainGroup_impl
Definition: ChainGroup.cxx:669
Trig::ChainGroup::features
const FeatureContainer features(unsigned int condition=TrigDefs::Physics) const
returns all features related to given chain group of HLT chains or L1 items Note: This does not yet w...
Definition: ChainGroup.cxx:726
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
Trig::FeatureContainer
Definition: FeatureContainer.h:54
Lvl1Item.h
LVL1CTP::Lvl1Item::isPassedAfterPrescale
bool isPassedAfterPrescale() const
Definition: Lvl1Item.h:50
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Trig::CacheGlobalMemory::navigation
const HLT::TrigNavStructure * navigation() const
Definition: CacheGlobalMemory.h:104
TrigConf::HLTSignature
HLT signature configuration information.
Definition: HLTSignature.h:29
LVL1CTP::Lvl1Item
Definition: Lvl1Item.h:37
python.ConfigurableDb.conf
def conf
Definition: ConfigurableDb.py:282
Trig::ChainGroup::getListOfGroups
std::vector< std::string > getListOfGroups() const
Definition: ChainGroup.cxx:487
Trig::ChainGroup::getListOfStreams
std::vector< std::string > getListOfStreams() const
Definition: ChainGroup.cxx:472
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
HLTUtils.h
TrigConf::HLTUtils::string2hash
static HLTHash string2hash(const std::string &, const std::string &category="TE")
hash function translating TE names into identifiers
Trig::ChainGroup::HLTPrescale
float HLTPrescale(const std::string &chain, unsigned int condition) const
Definition: ChainGroup.cxx:326
HLT
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
Definition: HLTResultReader.h:26
Trig::CacheGlobalMemory::assert_decision
bool assert_decision() const
checks if new event arrived with the decision Need to use before any call to CacheGlobalMemory.
Definition: CacheGlobalMemory.cxx:266
TrigConf::HLTChainList
list of all HLT chains in a trigger menu
Definition: HLTChainList.h:56
HLTStreamTag.h
TrigCompositeUtils::getExpressTerminusNode
const Decision * getExpressTerminusNode(const DecisionContainer &container)
Returns the express-accept navigation node from a collection or nullptr if missing.
Definition: TrigCompositeUtilsRoot.cxx:251
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.subdetectors.mmg.names
names
Definition: mmg.py:8
Trig::Combination
Definition: Trigger/TrigAnalysis/TrigDecisionTool/TrigDecisionTool/Combination.h:55
HLT::TriggerElement
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
Definition: TrigNavStructure/TrigNavStructure/TriggerElement.h:27
COOLRates.alias
alias
Definition: COOLRates.py:1172
Trig::ChainGroup::L1Prescale
float L1Prescale(const std::string &item, unsigned int condition) const
Definition: ChainGroup.cxx:374
HLTSignature.h
HLT::ComboIterator
Iterator used to loop over multi-particle combinations.
Definition: ComboIterator.h:74
python.BuildSignatureFlags.sig
sig
Definition: BuildSignatureFlags.py:218
HLT::Chain::getChainStep
int getChainStep() const
return the current step of execution
Definition: Chain.h:103
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TrigDefs::Group::NoRegex
@ NoRegex
Do not use regular expressions.
Logger.h
hist_file_dump.f
f
Definition: hist_file_dump.py:135
Trig::ChainGroup::L1Result
bool L1Result(const std::string &item, unsigned int condition) const
Definition: ChainGroup.cxx:129
Trig::keyWrap
std::vector< std::string > keyWrap(const std::vector< std::string > &triggerNames)
normalizes the list of triggers (patterns) by sorting and uniquing them
Definition: TDTUtilities.cxx:52
bitmask.h
Helpers for treating a class enum as a bitmask.
PyPoolBrowser.node
node
Definition: PyPoolBrowser.py:131
xAOD::TrigComposite_v1
Class used to describe composite objects in the HLT.
Definition: TrigComposite_v1.h:52
HLT::Chain::getErrorCode
HLT::ErrorCode getErrorCode() const
return this Chain's most severe error code (from execution)
Definition: Chain.h:102
Trig::ChainGroup::patterns
const std::vector< std::string > & patterns() const
Definition: ChainGroup.h:152
HLT::Identifier
Definition: TrigCompositeUtils/TrigCompositeUtils/HLTIdentifier.h:20
Chain.h
HLT::Chain
Definition: Chain.h:64
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Trig::ChainGroup::appendFeatures
void appendFeatures(std::vector< std::vector< HLT::TriggerElement * > > &tes, FeatureContainer &fc) const
Definition: ChainGroup.cxx:788
TrigCompositeContainer.h
TrigConf::HLTSignature::outputTEs
std::vector< HLTTriggerElement * > & outputTEs()
accessor to the list of trigger elements
Definition: HLTSignature.h:60
Trig::ChainGroup
Definition: ChainGroup.h:51
Trig::ChainGroup::getHLTTriggerElements
std::vector< std::vector< TrigConf::HLTTriggerElement * > > getHLTTriggerElements() const
Definition: ChainGroup.cxx:577
node::name
void name(const std::string &n)
Definition: node.h:37
dso-stats.pat
pat
Definition: dso-stats.py:39
CxxUtils::test
constexpr std::enable_if_t< is_bitmask_v< E >, bool > test(E lhs, E rhs)
Convenience function to test bits in a class enum bitmask.
Definition: bitmask.h:270
Trig::ChainGroup::isPassed
bool isPassed(unsigned int condition=TrigDefs::Physics) const
tells if chain group passed
Definition: ChainGroup.cxx:208
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
HLT::Chain::isResurrected
bool isResurrected() const
is chain resurrected ?
Definition: Chain.h:87
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
TrigConf::HLTTriggerElement
HLT trigger element configuration information.
Definition: HLTTriggerElement.h:26
HLTTriggerElement.h
item
Definition: ItemListSvc.h:43
Trig::ChainGroup::cgm_assert
const Trig::CacheGlobalMemory & cgm_assert() const
Definition: ChainGroup.cxx:70
TrigConf::HLTStreamTag
HLT stream configuration information.
Definition: HLTStreamTag.h:23
TrigConf::ItemContainer
boost::multi_index::multi_index_container< TriggerItem *, boost::multi_index::indexed_by< boost::multi_index::random_access<>, boost::multi_index::ordered_unique< boost::multi_index::identity< TriggerItem > >, boost::multi_index::ordered_unique< boost::multi_index::tag< tag_ctpid >, boost::multi_index::const_mem_fun< TriggerItem, int, &TriggerItem::ctpId > >, boost::multi_index::hashed_unique< boost::multi_index::tag< tag_name_hash >, boost::multi_index::const_mem_fun< TrigConfData, const std::string &, &TrigConfData::name > > > > ItemContainer
Definition: Menu.h:39
Trig::ChainGroup::names
const std::vector< std::string > & names() const
names of triggers within chain group
Definition: ChainGroup.h:165
python.PyAthena.v
v
Definition: PyAthena.py:154
Trig::ChainGroup::isPassedBits
unsigned int isPassedBits() const
returns bits (OR ed) of the chain group Meaning of the returned bits can be understood by using masks...
Definition: ChainGroup.cxx:305
TrigCompositeUtils::DecisionIDContainer
std::set< DecisionID > DecisionIDContainer
Definition: TrigComposite_v1.h:28
ChainGroup_impl::collectCombinations
void collectCombinations(const TrigConf::HLTChain *conf, const CacheGlobalMemory &cgm, FeatureContainer &fc, unsigned int condition)
Definition: ChainGroup.cxx:683
Trig::ChainGroup::isCorrelatedL1items
bool isCorrelatedL1items(const std::string &item) const
Definition: ChainGroup.cxx:343
LVL1CTP::Lvl1Item::isPassedAfterVeto
bool isPassedAfterVeto() const
Definition: Lvl1Item.h:51
LVL1CTP::Lvl1Item::isPassedBeforePrescale
bool isPassedBeforePrescale() const
Definition: Lvl1Item.h:49
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trig::FeatureContainer::addWithChecking
void addWithChecking(const Combination &newComb)
add new combination to the container checking for overlap
Definition: FeatureContainer.cxx:19
Trig::ChainGroup::getPrescale
float getPrescale(unsigned int condition=TrigDefs::Physics) const
returns prescale factor for chain group with single chain in returns real prescale factor for real ch...
Definition: ChainGroup.cxx:407
Trig::ChainGroup::isPassedForEach
std::vector< bool > isPassedForEach(unsigned int condition=TrigDefs::Physics) const
return vector with isPassed decision for each chain
Definition: ChainGroup.cxx:193
TrigCompositeUtils::decisionIDs
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
Definition: TrigCompositeUtilsRoot.cxx:67
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
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
HLT::Chain::getChainName
const std::string & getChainName() const
return the Chain name (string)
Definition: Chain.h:94
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
Trig::ChainGroup::getListOfTriggerElements
std::vector< std::vector< std::string > > getListOfTriggerElements() const
Definition: ChainGroup.cxx:555
Trig::ChainGroup::error
HLT::ErrorCode error() const
returns most severe error in the chains composing that chain group for L1 it is just OK If there is s...
Definition: ChainGroup.cxx:315
Trig::ChainGroup::getListOfTriggers
std::vector< std::string > getListOfTriggers() const
Definition: ChainGroup.cxx:467
LVL1CTP::Lvl1Item::isPrescaled
bool isPrescaled() const
Definition: Lvl1Item.h:55
HLT::ComboIterator::isValid
bool isValid() const
Validity check for the iterator.
Definition: ComboIterator.h:95
L1Bits
Definition: TrigMonL1Item.cxx:12
Trig::ChainGroup::L1Bits
unsigned int L1Bits(const std::string &item) const
Definition: ChainGroup.cxx:244
LVL1CTP::Lvl1Item::name
const std::string & name() const
Definition: Lvl1Item.h:46
HLT::Chain::chainPassedRaw
bool chainPassedRaw() const
Definition: Chain.h:81
node
Definition: memory_hooks-stdcmalloc.h:74
TrigConf::TriggerItem
Definition: TriggerItem.h:25
HLT::Chain::isPassedThrough
bool isPassedThrough() const
is chain passed through ?
Definition: Chain.h:85
TriggerItemNode.h