ATLAS Offline Software
Loading...
Searching...
No Matches
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 <ranges>
19
20#include "CxxUtils/bitmask.h"
32
36
37
38
39using namespace std;
40
41Trig::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
61
63 return !(*this==rhs);
64}
65
66void 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
78bool 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!!!!
129bool 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
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
160std::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)
172bool Trig::ChainGroup::isPassed(const TrigConf::HLTChain& chain, unsigned int condition) const
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
193std::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
208bool 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
221unsigned 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
244unsigned 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;
258 return r;
259}
260
261std::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
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
326float 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
343bool 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
348float 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
374float 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
407float Trig::ChainGroup::getPrescale(unsigned int condition) const {
408 if ( condition != TrigDefs::Physics )
409 return 0.0;
410 return m_prescale;
411}
412
413float Trig::ChainGroup::calculatePrescale(unsigned int condition)
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
467std::vector< std::string > Trig::ChainGroup::getListOfTriggers() const {
468 return m_names;
469}
470
471
472std::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
486vector<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
501std::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
516vector<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
555std::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
577std::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
590void
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
664}
665
667// features
668
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
683 void collectCombinations( const TrigConf::HLTChain* conf, const CacheGlobalMemory& cgm, FeatureContainer& fc, unsigned int condition ){
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 : std::views::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
725const Trig::FeatureContainer
726Trig::ChainGroup::features(unsigned int condition) const {
727 using namespace ChainGroup_impl;
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();
774 std::set< std::string >::iterator setstrit;
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
788void 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}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helpers for treating a class enum as a bitmask.
This class represents one chain of signatures, i.e.
Definition Chain.h:64
const TrigConf::HLTChain * getConfigChain() const
get underlying ConfigChain
Definition Chain.h:78
HLT::ErrorCode getErrorCode() const
return this Chain's most severe error code (from execution)
Definition Chain.h:102
unsigned int getChainCounter() const
return the unique identifier of this Chain (uint)
Definition Chain.h:93
int getChainStep() const
return the current step of execution
Definition Chain.h:103
bool isPassedThrough() const
is chain passed through ?
Definition Chain.h:85
bool isPrescaled() const
is chain prescaled ?
Definition Chain.h:86
const std::string & getChainName() const
return the Chain name (string)
Definition Chain.h:94
bool isResurrected() const
is chain resurrected ?
Definition Chain.h:87
bool chainPassedRaw() const
Definition Chain.h:81
Iterator used to loop over multi-particle combinations.
bool isValid() const
Validity check for the iterator.
TrigCompositeUtils::DecisionID numeric() const
numeric ID
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.
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
bool isPassedAfterPrescale() const
Definition Lvl1Item.h:50
bool isPassedBeforePrescale() const
Definition Lvl1Item.h:49
const std::string & name() const
Definition Lvl1Item.h:46
bool isPassedAfterVeto() const
Definition Lvl1Item.h:51
bool isPrescaled() const
Definition Lvl1Item.h:55
bool isVeto() const
Definition Lvl1Item.h:56
Property holding a SG store/key/clid from which a ReadHandle is made.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
bool empty() const
Test if the key is blank.
list of all HLT chains in a trigger menu
HLT chain configuration information.
const std::string & lower_chain_name() const
HLT signature configuration information.
std::vector< HLTTriggerElement * > & outputTEs()
accessor to the list of trigger elements
HLT stream configuration information.
HLT trigger element configuration information.
static HLTHash string2hash(const std::string &, const std::string &category="TE")
hash function translating TE names into identifiers
bool assert_decision() const
checks if new event arrived with the decision Need to use before any call to CacheGlobalMemory.
const HLT::TrigNavStructure * navigation() const
float correlatedL1Prescale(const std::string &item) const
const std::vector< std::string > & patterns() const
Definition ChainGroup.h:152
std::vector< std::string > getListOfStreams() const
std::vector< std::string > getListOfThresholds() const
const Trig::CacheGlobalMemory & cgm() const
Definition ChainGroup.h:190
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...
std::vector< std::string > getListOfGroups() const
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...
unsigned int isPassedBits() const
returns bits (OR ed) of the chain group Meaning of the returned bits can be understood by using masks...
std::vector< bool > isPassedForEach(unsigned int condition=TrigDefs::Physics) const
return vector with isPassed decision for each chain
bool isCorrelatedL1items(const std::string &item) const
ChainGroup(const std::vector< std::string > &triggerNames, Trig::CacheGlobalMemory &parent)
void addAlias(const std::string &alias)
adds alias (sort understandabel name) to the group
std::vector< std::string > m_names
names of trigger derived from patterns & current configuration
Definition ChainGroup.h:187
void update(const TrigConf::HLTChainList *confChains, const TrigConf::ItemContainer *confItems, TrigDefs::Group prop=TrigDefs::Group::Default)
float HLTPrescale(const std::string &chain, unsigned int condition) const
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...
const Trig::ChainGroup & operator+(const Trig::ChainGroup &rhs)
bool L1Result(const std::string &item, unsigned int condition) const
unsigned int L1Bits(const std::string &item) const
bool operator!=(const Trig::ChainGroup &rhs)
float calculatePrescale(unsigned int condition=TrigDefs::Physics)
std::vector< const TrigConf::HLTChain * > m_confChains
Definition ChainGroup.h:180
unsigned int HLTBits(const std::string &chain, const std::string &level, const TrigCompositeUtils::DecisionIDContainer &passExpress) const
const std::vector< std::string > & names() const
names of triggers within chain group
Definition ChainGroup.h:165
std::vector< std::vector< std::string > > getListOfTriggerElements() const
std::vector< std::string > m_patterns
patterns with which the CG was constructed
Definition ChainGroup.h:178
bool isPassed(unsigned int condition=TrigDefs::Physics) const
tells if chain group passed
Trig::CacheGlobalMemory & m_cgm
Definition ChainGroup.h:185
void appendFeatures(std::vector< std::vector< HLT::TriggerElement * > > &tes, FeatureContainer &fc) const
float L1Prescale(const std::string &item, unsigned int condition) const
std::vector< unsigned int > isPassedBitsForEach() const
return result of isPassedBits for each chain in the group
const Trig::CacheGlobalMemory & cgm_assert() const
bool operator==(const Trig::ChainGroup &rhs)
std::vector< std::string > getListOfSignatures() const
std::string getLowerName(const std::string &EFname) const
std::vector< std::vector< TrigConf::HLTTriggerElement * > > getHLTTriggerElements() const
bool HLTResult(const std::string &chain, unsigned int condition) const
std::vector< const TrigConf::TriggerItem * > m_confItems
Definition ChainGroup.h:181
std::vector< std::string > getListOfTriggers() const
is a connector between chains and object It store single combination of trigger elements.
void addWithChecking(const Combination &newComb)
add new combination to the container checking for overlap
Definition node.h:24
void name(const std::string &n)
Definition node.h:40
int r
Definition globals.cxx:22
std::vector< std::string > patterns
Definition listroot.cxx:187
void collectCombinations(const TrigConf::HLTChain *conf, const CacheGlobalMemory &cgm, FeatureContainer &fc, unsigned int condition)
bool allActive(const std::vector< TriggerElement * > &tes)
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
It used to be useful piece of code for replacing actual SG with other store of similar functionality ...
static const ErrorCode OK(Action::CONTINUE)
const Decision * getExpressTerminusNode(const DecisionContainer &container)
Returns the express-accept navigation node from a collection or nullptr if missing.
std::set< DecisionID > DecisionIDContainer
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
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
Group
Properties of a chain group.
@ NoRegex
Do not use regular expressions.
The common trigger namespace for trigger analysis tools.
std::vector< std::string > convertStringToVector(const std::string &triggerNames)
makes a split of list of chains into the vector of chains
std::vector< std::string > keyWrap(const std::vector< std::string > &triggerNames)
normalizes the list of triggers (patterns) by sorting and uniquing them
Definition merge.py:1
STL namespace.