ATLAS Offline Software
Loading...
Searching...
No Matches
TrigSignatureMoni.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "TrigSignatureMoni.h"
6
9
10#include <algorithm>
11#include <regex>
12#include <format>
13#include <chrono>
14
16enum BINS {
17 INPUT = 1,
19 OUTPUT = 3,
22};
23
24
26 ATH_CHECK(m_l1DecisionsKey.initialize());
27 ATH_CHECK(m_finalDecisionKey.initialize());
28 ATH_CHECK(m_HLTMenuKey.initialize());
29 ATH_CHECK(m_L1MenuKey.initialize());
32 ATH_CHECK(m_histSvc.retrieve());
33
34 ATH_CHECK(m_incidentSvc.retrieve());
36
37 return StatusCode::SUCCESS;
38}
39
43 ATH_CHECK(hltMenuHandle.isValid());
44
45 // Retrieve chain information from menus
46 m_groupToChainMap.clear();
47 m_streamToChainMap.clear();
48 m_expressChainMap.clear();
49
50 std::unordered_map<std::string,std::string> mapStrNameToTypeName; // e.g. {Main -> physics_Main}
51 try {
52 const std::string nameStr{"name"};
53 const std::string typeStr{"type"};
54 for (const TrigConf::DataStructure& stream : hltMenuHandle->streams()) {
55 mapStrNameToTypeName.insert({stream.getAttribute(nameStr), stream.getAttribute(typeStr)+"_"+stream.getAttribute(nameStr)});
56 }
57 } catch (const std::exception& ex) {
58 ATH_MSG_ERROR("Exception reading stream tag configuration from the HLT menu: " << ex.what());
59 return StatusCode::FAILURE;
60 }
61
62 for (const TrigConf::Chain& chain : *hltMenuHandle) {
63 for (const std::string& group : chain.groups()) {
64 // Save chains per RATE group
65 if (group.starts_with( "RATE")){
66 m_groupToChainMap[group].insert(HLT::Identifier(chain.name()));
67 }
68 }
69
70 // Save chain to stream map
71 for (const std::string& streamName : chain.streams()){
72 const auto it = mapStrNameToTypeName.find(streamName);
73 if (it==mapStrNameToTypeName.cend()) {
74 ATH_MSG_ERROR("Stream name " << streamName << " assigned to chain " << chain.name()
75 << " is missing from menu streams definition");
76 return StatusCode::FAILURE;
77 }
78 if (it->second == "express_express") {
79 m_expressChainMap[it->second].insert(HLT::Identifier(chain.name()));
80 } else {
81 m_streamToChainMap[it->second].insert(HLT::Identifier(chain.name()));
82 }
83 }
84 }
85
86 // Prepare the histograms
87
88 // Initialize SignatureAcceptance and DecisionCount histograms that will monitor
89 // chains, groups and sequences per each step
90 const int x {nBinsX(hltMenuHandle)};
91 const int y {nSteps() + N_BINS};
92 ATH_MSG_DEBUG( "Histogram " << x << " x " << y << " bins");
93 std::unique_ptr<TH2> hSA = std::make_unique<TH2I>("SignatureAcceptance", "Raw acceptance of signatures in;chain;step", x, 1, x + 1, y, 1, y + 1);
94 std::unique_ptr<TH2> hDC = std::make_unique<TH2I>("DecisionCount", "Positive decisions count per step;chain;step", x, 1, x + 1, y, 1, y + 1);
95
96 ATH_CHECK(m_histSvc->regShared(m_bookingPath + "/" + name() + "/SignatureAcceptance", std::move(hSA), m_passHistogram));
97 ATH_CHECK(m_histSvc->regShared(m_bookingPath + "/" + name() + "/DecisionCount", std::move(hDC), m_countHistogram));
98
99 ATH_CHECK(initHist(m_passHistogram, hltMenuHandle));
100 ATH_CHECK(initHist(m_countHistogram, hltMenuHandle));
101
102 // Initialize Rate histogram to save the rates of positive decisions in given interval
103 // per chain/group/sequence per in, after ps, out steps
104 if ( x > 0 ){
105 const std::string outputRateName = std::format("Rate{:d}s", m_duration.value());
106 m_rateHistogram.init(outputRateName, "Rate of positive decisions;chain;step", x, N_BINS,
107 std::format("{}/{}/{}", m_bookingPath.value(), name(), outputRateName), m_histSvc).ignore();
108 ATH_CHECK(initHist(m_rateHistogram.getHistogram(), hltMenuHandle, false));
109 ATH_CHECK(initHist(m_rateHistogram.getBuffer(), hltMenuHandle, false));
110 }
111
112 // Initialize SequencesExecutionRate histogram to save the rates of sequences execution
113 // Save sequences names to be monitored
114 std::set<std::string> sequencesSet;
115 for (auto& ctool: m_decisionCollectorTools){
116 ctool->getSequencesNames(sequencesSet);
117 }
118 const int xc = sequencesSet.size();
119 const int yc {1}; // Only rate, this histogram is really 1 D
120 if (xc > 0){
121 const std::string outputSequenceName = std::format("SequencesExecutionRate{:d}s", m_duration.value());
122 m_sequenceHistogram.init(outputSequenceName, "Rate of sequences execution;sequence;rate", xc, yc,
123 std::format("{}/{}/{}", m_bookingPath.value(), name(), outputSequenceName), m_histSvc).ignore();
124
125 ATH_CHECK(initSeqHist(m_sequenceHistogram.getHistogram(), sequencesSet));
126 ATH_CHECK(initSeqHist(m_sequenceHistogram.getBuffer(), sequencesSet));
127 }
128
129 return StatusCode::SUCCESS;
130}
131
133 m_rateHistogram.stopTimer();
134 m_sequenceHistogram.stopTimer();
135
136 if (m_chainIDToBinMap.empty()) {
137 ATH_MSG_INFO( "No chains configured, no counts to print" );
138 return StatusCode::SUCCESS;
139 }
140
142 ATH_CHECK(hltMenuHandle.isValid());
143
144 // Retrieve information whether chain was active in Step
145 std::unordered_map<std::string, std::set<int>> chainToStepsId;
146 for (const TrigConf::Chain& chain : *hltMenuHandle){
147 int nstep {1}; // Start from step=1
148 for (const std::string& seqName : chain.sequencers()){
149 // Example sequencer name is "Step1_FastCalo_electron", we need only information about Step + number
150 std::smatch stepNameMatch;
151 std::regex_search(seqName.begin(), seqName.end(), stepNameMatch, std::regex("[Ss]tep[0-9]+"));
152
153 std::string stepName = stepNameMatch[0];
154 stepName[0] = std::toupper(stepName[0]); // Fix "stepX" -> "StepX"
155 // Check that the step name is set with the same position in the execution (empty steps support)
156 if (std::format("Step{:d}", nstep) == stepName) {
157 chainToStepsId[chain.name()].insert(nstep);
158 if(m_countLegFeatures && chain.legMultiplicities().size()>1) {
159 for (size_t legID = 0; legID < chain.legMultiplicities().size(); ++ legID) {
160 const std::string legName = ( TrigCompositeUtils::createLegName(HLT::Identifier(chain.name()), legID).name() );
161 chainToStepsId[legName].insert(nstep);
162 }
163 }
164 } else {
165 ATH_MSG_DEBUG("Missing counts for step" << nstep << " in chain " << chain.name());
166 }
167 nstep++;
168 }
169 }
170
171 auto collToString = [&](int xbin, const LockedHandle<TH2>& hist, int startOfset=0, int endOffset=0){
172 std::string v;
173 const int stepsSize = hist->GetYaxis()->GetNbins() - N_BINS;
174 for (int ybin = 1; ybin <= hist->GetYaxis()->GetNbins()-endOffset; ++ybin) {
175 if (ybin > startOfset) {
176 // Skip steps where chain wasn't active
177 // ybins are for all axis labes, steps are in bins from 3 to stepsSize + 2
178 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(xbin);
179
180 if (ybin < 3 || ybin > stepsSize + 2 || chainToStepsId[chainName].contains(ybin - 2)) {
181 v += std::format("{:<11d}", static_cast<int>(hist->GetBinContent(xbin, ybin)));
182 } else {
183 v += std::format("{:<11s}", "-");
184 }
185 } else {
186 v += std::format("{:<11s}", " ");
187 }
188 }
189 return v;
190 };
191
192 std::string v;
193 v += std::format("{:<11s}", "L1");
194 v += std::format("{:<11s}", "AfterPS");
195 for (int bin = 1; bin <= m_passHistogram->GetYaxis()->GetNbins()-N_BINS; ++bin) {
196 v += std::format("Step{:<7d}", bin);
197 }
198 v += std::format("{:<11s}", "Output");
199 v += std::format("{:<11s}", "Express");
200
201 ATH_MSG_INFO("Chains passing step (1st row events & 2nd row decision counts):");
202 ATH_MSG_INFO(" Feature counts reflect the number of unique objects contributing to a positive chain decision (0 if step fails), including L1RoI for empty steps.");
204 ATH_MSG_INFO(" Leg feature counts indicate the number of unique objects that pass the leg's step selection (regardless of multiplicity), which may overlap with other legs.");
205 ATH_MSG_INFO(" 'PROBE' L1 RoIs are counted separately.");
206 }
207
208 ATH_MSG_INFO(std::format("{:<30s}", "ChainName") << v);
209
210
211 for (int bin = 1; bin <= (*m_passHistogram)->GetXaxis()->GetNbins(); ++bin) {
212 const std::string chainName = m_passHistogram->GetXaxis()->GetBinLabel(bin);
213 const std::string chainID = std::to_string(HLT::Identifier(chainName));
214 if (chainName.starts_with( "HLT")) { // print only for chains
215 ATH_MSG_INFO( std::format("{:s} #{:s}", chainName, chainID) );
216 ATH_MSG_INFO( std::format("{:<30s}", std::format("-- #{} Events", chainID)) << collToString( bin, m_passHistogram) );
217 ATH_MSG_INFO( std::format("{:<30s}", std::format("-- #{} Features", chainID)) << collToString( bin, m_countHistogram , 2, 1 ) );
218 }
219 if (chainName.starts_with( "All")){
220 ATH_MSG_INFO( std::format("{:<30s}", chainName) << collToString( bin, m_passHistogram) );
221 }
222 if (chainName.starts_with("leg")) { // print features only for legs
223 const std::string legID = chainName.substr(0,6);
224 ATH_MSG_INFO( std::format("{:<30s}", std::format("-- #{} Features", legID)) << collToString( bin, m_countHistogram , 2, 1 ) );
225 }
226 }
227
228 return StatusCode::SUCCESS;
229}
230
231StatusCode TrigSignatureMoni::fillHistogram(const TrigCompositeUtils::DecisionIDContainer& dc, int row, LockedHandle<TH2>& histogram) const {
232
233 // This locks the histogram handle for the entire duration of the function,
234 // which is faster than (un)locking the handle many times during the loop.
235 auto lockedHist = *histogram;
236
237 for (TrigCompositeUtils::DecisionID id : dc) {
238 auto id2bin = m_chainIDToBinMap.find( id );
239 // Can ignore leg IDs if we are not explicitly saving their counts
240 if ( id2bin == m_chainIDToBinMap.end() ) {
242 ATH_MSG_WARNING( "HLT chain " << HLT::Identifier(id) << " not configured to be monitored" );
243 }
244 } else {
245 ATH_MSG_VERBOSE( "Filling histogram for " << HLT::Identifier(id).name() << " ==> bin " << id2bin->second );
246 lockedHist->Fill( id2bin->second, static_cast<double>(row) );
247 }
248 }
249 return StatusCode::SUCCESS;
250}
251
253 return fillHistogram(dc, row, m_rateHistogram.getBuffer());
254}
255
257 return fillHistogram(dc, row, m_passHistogram);
258}
259
260StatusCode TrigSignatureMoni::fillDecisionCount(const std::vector<TrigCompositeUtils::DecisionID>& dc, int row) const {
261 for (TrigCompositeUtils::DecisionID id : dc) {
263 auto id2bin = m_chainIDToBinMap.find( id );
264 if ( id2bin == m_chainIDToBinMap.end()) {
265 ATH_MSG_WARNING("HLT chain " << HLT::Identifier(id) << " not configured to be monitored");
266 } else {
267 ATH_MSG_VERBOSE( "Filling histogram for " << HLT::Identifier(id).name() << " ==> bin " << id2bin->second);
268 m_countHistogram->Fill(id2bin->second, static_cast<double>(row));
269 }
270 }
271
272 return StatusCode::SUCCESS;
273}
274
275StatusCode TrigSignatureMoni::fillSequences(const std::set<std::string>& sequences) const {
276 for (const std::string& seq : sequences) {
278 }
279
280 return StatusCode::SUCCESS;
281}
282
283StatusCode TrigSignatureMoni::fillStreamsAndGroups(const std::map<std::string, TrigCompositeUtils::DecisionIDContainer>& nameToChainsMap, const TrigCompositeUtils::DecisionIDContainer& dc, int row) const {
284
285 // Adjust bin index for those histograms that monitor all steps
286 int rowWithSteps = row;
287 if (row==OUTPUT || row==EXPRESS) rowWithSteps += m_decisionCollectorTools.size();
288
289 for (const auto& [name, decisions] : nameToChainsMap) {
290 for (TrigCompositeUtils::DecisionID id : dc) {
291 if (decisions.contains(id)) {
292 const double bin = m_nameToBinMap.at(name);
293 m_rateHistogram.fill(bin, row);
294 m_countHistogram->Fill(bin, rowWithSteps);
295 m_passHistogram->Fill(bin, rowWithSteps);
296 break;
297 }
298 }
299 }
300 return StatusCode::SUCCESS;
301}
302
303void TrigSignatureMoni::handle( const Incident& incident ) {
304 // Create and start timer after fork
305 if (incident.type() == AthenaInterprocess::UpdateAfterFork::type()) {
306 if (m_rateHistogram.getTimer() || m_sequenceHistogram.getTimer()) {
307 ATH_MSG_WARNING("Timer is already running. UpdateAfterFork incident called more than once?");
308 return;
309 }
310
311 // Prevent from publishing empty histograms
312 if (nBinsX() > 0) {
314 }
315
316 if (!m_sequenceToBinMap.empty()) {
318 }
319
320 ATH_MSG_DEBUG("Started rate timer");
321 }
322}
323
324StatusCode TrigSignatureMoni::execute( const EventContext& context ) const {
325
327
328 [[maybe_unused]] static const bool sanityCheckDone = [&] {
329 if (l1Decisions->at(INPUT-1)->name() == "l1seeded" &&
330 l1Decisions->at(AFTER_PS-1)->name() == "unprescaled") {
331 return true;
332 }
333 throw GaudiException(m_l1DecisionsKey.key() + " does not contain the expected entries",
334 name(), StatusCode::FAILURE);
335 }();
336
337 auto fillL1 = [&](int index) -> StatusCode {
339 TrigCompositeUtils::decisionIDs(l1Decisions->at(index-1), ids);
340 ATH_MSG_DEBUG( "L1 " << index-1 << " N positive decisions " << ids.size() );
343 ATH_CHECK(fillRate(ids, index));
344 if (!ids.empty()){
345 m_passHistogram->Fill(1, static_cast<double>(index));
346 m_rateHistogram.fill(1, static_cast<double>(index));
347 }
348 return StatusCode::SUCCESS;
349 };
350
351 // Fill histograms with L1 decisions in and after prescale
352 ATH_CHECK(fillL1(INPUT));
353 ATH_CHECK(fillL1(AFTER_PS));
354
355 // Fill HLT steps
356 int step = 0;
357 std::vector<TrigCompositeUtils::DecisionID> stepSum;
358 std::set<std::string> stepSequences;
359 for ( auto& ctool: m_decisionCollectorTools ) {
360 ctool->getDecisions( stepSum, stepSequences, context );
361 ATH_MSG_DEBUG( " Step " << step << " decisions (for decisions): " << stepSum.size() );
362 TrigCompositeUtils::DecisionIDContainer stepUniqueSum( stepSum.begin(), stepSum.end() );
363 ATH_CHECK( fillPassEvents( stepUniqueSum, 3+step ) );
364 ATH_CHECK( fillSequences( stepSequences ) );
365 ++step;
366 stepSum.clear();
367 stepSequences.clear();
368 }
369
370 step = 0;
371 for ( auto& ctool: m_featureCollectorTools ) {
372 stepSum.clear();
373 ctool->getDecisions( stepSum, context );
374 ATH_MSG_DEBUG( " Step " << step << " decisions (for features): " << stepSum.size() );
375 ATH_CHECK( fillDecisionCount( stepSum, 3+step ) );
376 ++step;
377 }
378
379 // Collect the final decisions
381 ATH_CHECK( finalDecisionsHandle.isValid() );
383 const TrigCompositeUtils::Decision* decisionObject = TrigCompositeUtils::getTerminusNode(*finalDecisionsHandle);
384 if (!decisionObject) {
385 ATH_MSG_WARNING("Unable to locate trigger navigation terminus node. Cannot tell which chains passed the event.");
386 } else {
387 TrigCompositeUtils::decisionIDs(decisionObject, finalIDs);
388 }
389
390 // Collect the express stream decisions
392 const TrigCompositeUtils::Decision* expressDecisionObject = TrigCompositeUtils::getExpressTerminusNode(*finalDecisionsHandle);
393 if (!expressDecisionObject) {
394 ATH_MSG_WARNING("Unable to locate trigger navigation express terminus node. Cannot tell which chains passed the express stream in this event.");
395 } else {
396 TrigCompositeUtils::decisionIDs(expressDecisionObject, expressFinalIDs);
397 }
398
399 // Fill the histograms with output counts/rate
400 const int countOutputRow {nSteps() + OUTPUT};
403 ATH_CHECK( fillPassEvents(finalIDs, countOutputRow));
404 ATH_CHECK( fillRate(finalIDs, OUTPUT));
405
406 // Fill the histograms with express counts/rate
407 const int countExpressRow {nSteps() + EXPRESS};
408 // express stream rate is filled into OUTPUT bin on purpose
411 ATH_CHECK( fillPassEvents(expressFinalIDs, countExpressRow));
412 ATH_CHECK( fillRate(expressFinalIDs, EXPRESS));
413
414 // Fill the "All" column in counts/rate histograms
415 if (!finalIDs.empty()) {
416 m_passHistogram->Fill(1, static_cast<double>(countOutputRow));
417 m_rateHistogram.fill(1, static_cast<double>(OUTPUT));
418 }
419 if (!expressFinalIDs.empty()) {
420 m_passHistogram->Fill(1, static_cast<double>(countExpressRow));
421 m_rateHistogram.fill(1, static_cast<double>(EXPRESS));
422 }
423
424 return StatusCode::SUCCESS;
425}
426
428 return nChains(hltMenuHandle) + m_groupToChainMap.size() + m_streamToChainMap.size() + m_expressChainMap.size();
429}
430
432 return m_chainIDToBinMap.size() + m_groupToChainMap.size() + m_streamToChainMap.size() + m_expressChainMap.size() + 1;
433}
434
436 int nchains = hltMenuHandle->size();
437 // If we want the leg counts, need to accumulate the multiplicities from each chain
439 for (const TrigConf::Chain& chain : *hltMenuHandle){
440 std::vector<size_t> legs = chain.legMultiplicities();
441 if(legs.size()>1) {nchains += legs.size();}
442 }
443 }
444 return nchains + 1; // Chains + "All"
445}
446
448 return m_decisionCollectorTools.size();
449}
450
451StatusCode TrigSignatureMoni::initHist(LockedHandle<TH2>& hist, SG::ReadHandle<TrigConf::HLTMenu>& hltMenuHandle, bool steps) {
452 TAxis* x = hist->GetXaxis();
453 x->SetBinLabel(1, "All");
454 int bin = 2; // 1 is for total count, (remember bin numbering in ROOT starts from 1)
455
456 std::set<std::string> sortedChainsList;
457 std::map<unsigned int,size_t> chainMultiplicities;
458 for ( const TrigConf::Chain& chain: *hltMenuHandle ) {
459 sortedChainsList.insert( chain.name() );
460 // if counting features, record the number of legs for later
462 std::vector<size_t> legs = chain.legMultiplicities();
463 chainMultiplicities.emplace( HLT::Identifier(chain.name()).numeric() ,legs.size());
464 if(legs.size()>1) {
465 ATH_MSG_DEBUG("For chain " << chain.name() << ", also recording feature counts for " << legs.size() << " legs.");
466 }
467 }
468 }
469
470 for ( const std::string& chainName: sortedChainsList ) {
471 x->SetBinLabel( bin, chainName.c_str() );
472 unsigned int chainID = HLT::Identifier( chainName ).numeric();
473 m_chainIDToBinMap[ chainID ] = bin;
474 ATH_MSG_VERBOSE(chainName << " --> bin " << bin );
475 ++bin;
476 if(m_countLegFeatures && chainMultiplicities[chainID]>1) {
477 size_t nlegs = chainMultiplicities[chainID];
478 // n.b. we don't care about the content of this vector (the required multiplicity per leg), just its size
479 for (size_t legID = 0; legID < nlegs; ++ legID) {
480 const std::string legName = ( TrigCompositeUtils::createLegName(HLT::Identifier(chainName), legID).name() );
481 ATH_MSG_VERBOSE(" " << legName << " --> bin " << bin );
482 x->SetBinLabel( bin, legName.c_str() );
484 ++bin;
485 }
486 }
487 }
488
489
490 for ( const auto& stream : m_streamToChainMap){
491 x->SetBinLabel( bin, ("str_"+stream.first).c_str());
492 m_nameToBinMap[ stream.first ] = bin;
493 bin++;
494 }
495
496 for ( const auto& stream : m_expressChainMap){
497 x->SetBinLabel( bin, ("str_"+stream.first).c_str());
498 m_nameToBinMap[ stream.first ] = bin;
499 bin++;
500 }
501
502 for ( const auto& group : m_groupToChainMap){
503 x->SetBinLabel( bin, ("grp_"+group.first.substr(group.first.find(':')+1)).c_str() );
504 m_nameToBinMap[ group.first ] = bin;
505 bin++;
506 }
507
508
509 TAxis* y = hist->GetYaxis();
510 y->SetBinLabel(INPUT, steps ? "L1" : "Input");
511 y->SetBinLabel(AFTER_PS, "AfterPS");
512 for ( size_t i = 0; steps && i < m_decisionCollectorTools.size(); ++i) {
513 y->SetBinLabel(3 + i, std::format("Step {:d}", i).c_str());
514 }
515 y->SetBinLabel(y->GetNbins()-1, "Output"); // Second to last bin
516 y->SetBinLabel(y->GetNbins(), "Express"); // Last bin
517
518 return StatusCode::SUCCESS;
519}
520
521StatusCode TrigSignatureMoni::initSeqHist(LockedHandle<TH2>& hist, std::set<std::string>& sequenceSet) {
522 TAxis* x = hist->GetXaxis();
523 int bin = 1;
524
525 // Set bin labels
526 for (const std::string& seqName : sequenceSet) {
527 x->SetBinLabel(bin, seqName.c_str());
528 m_sequenceToBinMap[seqName] = bin;
529 ++bin;
530 }
531
532 TAxis* y = hist->GetYaxis();
533 y->SetBinLabel(1, "Rate");
534
535 return StatusCode::SUCCESS;
536}
537
538
540 delete m_bufferHistogram.get();
541}
542
543StatusCode TrigSignatureMoni::RateHistogram::init( const std::string& histoName, const std::string& histoTitle,
544 const int x, const int y, const std::string& registerPath, const ServiceHandle<ITHistSvc>& histSvc ){
545 std::unique_ptr<TH2> h = std::make_unique<TH2F>(histoName.c_str(), histoTitle.c_str(), x, 1, x + 1, y, 1, y + 1);
546 ATH_CHECK( histSvc->regShared( registerPath.c_str(), std::move(h), m_histogram));
547
548 TH2I * hB = new TH2I( (histoName + "Buffer").c_str(), histoTitle.c_str(), x, 1, x + 1, y, 1, y + 1);
549 m_bufferHistogram.set(hB, &m_mutex);
550 m_bufferHistogram->SetDirectory(0);
551
552 return StatusCode::SUCCESS;
553}
554
555LockedHandle<TH2> & TrigSignatureMoni::RateHistogram::getHistogram ATLAS_NOT_CONST_THREAD_SAFE () const {
556 return m_histogram;
557}
558
559LockedHandle<TH2> & TrigSignatureMoni::RateHistogram::getBuffer ATLAS_NOT_CONST_THREAD_SAFE () const {
560 return m_bufferHistogram;
561}
562
563std::unique_ptr<Gaudi::Utils::PeriodicAction> & TrigSignatureMoni::RateHistogram::getTimer() {
564 return m_timer;
565}
566
567void TrigSignatureMoni::RateHistogram::fill(const double x, const double y) const {
568 m_bufferHistogram->Fill(x, y);
569}
570
571void TrigSignatureMoni::RateHistogram::startTimer(unsigned int duration, unsigned int intervals) {
572 m_duration = duration;
573 m_timeDivider = std::make_unique<TimeDivider>(intervals, duration, TimeDivider::seconds);
574 // Periodic timer with 1/20 of the integration period
575 m_timer = std::make_unique<Gaudi::Utils::PeriodicAction>(std::bind(&RateHistogram::callback, this),
576 std::chrono::milliseconds(duration*1000/20));
577}
578
580 if (m_timer) {
581 m_timer->stop();
582 time_t t = time(0);
583 unsigned int interval;
584 unsigned int duration = m_timeDivider->forcePassed(t, interval);
585 updatePublished(duration); // Divide by time that really passed not by interval duration
586 }
587
588}
589
590void TrigSignatureMoni::RateHistogram::updatePublished(unsigned int duration) const {
591 m_histogram->Reset("ICES");
592 m_histogram->Add(m_bufferHistogram.get(), 1./duration);
593 m_bufferHistogram->Reset("ICES");
594}
595
596
598 // Ask time divider if we need to switch to new interval
599 time_t t = time(0);
600 unsigned int newinterval;
601 unsigned int oldinterval;
602 if (m_timeDivider->isPassed(t, newinterval, oldinterval)) {
604 }
605}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
size_t size() const
Number of registered mappings.
BINS
Default bin numbers.
#define y
#define x
std::string histogram
Definition chains.cxx:52
#define ATLAS_NOT_CONST_THREAD_SAFE
Header file for AthHistogramAlgorithm.
static const std::string & type()
Incident type.
Definition Incidents.h:49
TrigCompositeUtils::DecisionID numeric() const
numeric ID
std::string name() const
reports human redable name
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Base class for Trigger configuration data and wrapper around underlying representation.
void updatePublished(unsigned int duration) const
std::unique_ptr< Gaudi::Utils::PeriodicAction > m_timer
void startTimer(unsigned int duration, unsigned int intervals)
void fill(const double x, const double y) const
StatusCode init(const std::string &histoName, const std::string &histoTitle, const int x, const int y, const std::string &registerPath, const ServiceHandle< ITHistSvc > &histSvc)
std::unique_ptr< Gaudi::Utils::PeriodicAction > & getTimer()
std::unique_ptr< TimeDivider > m_timeDivider
std::unordered_map< std::string, int > m_sequenceToBinMap
Sequence to bin map for sequence histogram.
int nChains(SG::ReadHandle< TrigConf::HLTMenu > &) const
StatusCode initHist(LockedHandle< TH2 > &, SG::ReadHandle< TrigConf::HLTMenu > &, bool=true)
Gaudi::Property< unsigned int > m_intervals
StatusCode fillPassEvents(const TrigCompositeUtils::DecisionIDContainer &, int) const
Gaudi::Property< unsigned int > m_duration
StatusCode initSeqHist(LockedHandle< TH2 > &, std::set< std::string > &)
virtual StatusCode start() override
StatusCode fillRate(const TrigCompositeUtils::DecisionIDContainer &, int) const
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_streamToChainMap
Stream name to chain objects map, excluding express.
virtual StatusCode initialize() override
StatusCode fillDecisionCount(const std::vector< TrigCompositeUtils::DecisionID > &, int) const
virtual StatusCode execute(const EventContext &context) const override
RateHistogram m_sequenceHistogram
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_l1DecisionsKey
ServiceHandle< ITHistSvc > m_histSvc
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_expressChainMap
Stream name to chain objects map, including only express.
StatusCode fillHistogram(const TrigCompositeUtils::DecisionIDContainer &, int, LockedHandle< TH2 > &) const
std::map< std::string, TrigCompositeUtils::DecisionIDContainer > m_groupToChainMap
Group name to chain objects map.
SG::ReadHandleKey< TrigConf::L1Menu > m_L1MenuKey
StatusCode fillSequences(const std::set< std::string > &) const
ServiceHandle< IIncidentSvc > m_incidentSvc
RateHistogram m_rateHistogram
SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_finalDecisionKey
Gaudi::Property< bool > m_countLegFeatures
Gaudi::Property< std::string > m_bookingPath
std::unordered_map< std::string, int > m_nameToBinMap
Sequence/group/bunchgroup name to bin map.
SG::ReadHandleKey< TrigConf::HLTMenu > m_HLTMenuKey
StatusCode fillStreamsAndGroups(const std::map< std::string, TrigCompositeUtils::DecisionIDContainer > &, const TrigCompositeUtils::DecisionIDContainer &, int) const
virtual StatusCode stop() override
virtual void handle(const Incident &incident) override
ToolHandleArray< DecisionCollectorTool > m_decisionCollectorTools
ToolHandleArray< DecisionCollectorTool > m_featureCollectorTools
std::unordered_map< unsigned int, int > m_chainIDToBinMap
Chain id to histogram bin map.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
HLT::Identifier createLegName(const HLT::Identifier &chainIdentifier, size_t counter)
Generate the HLT::Identifier which corresponds to a specific leg of a given chain.
unsigned int DecisionID
xAOD::TrigComposite Decision
const Decision * getExpressTerminusNode(const DecisionContainer &container)
Returns the express-accept navigation node from a collection or nullptr if missing.
std::set< DecisionID > DecisionIDContainer
const Decision * getTerminusNode(SG::ReadHandle< DecisionContainer > &container)
void decisionIDs(const Decision *d, DecisionIDContainer &destination)
Extracts DecisionIDs stored in the Decision object.
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
Definition index.py:1