ATLAS Offline Software
Loading...
Searching...
No Matches
L1TopoRatesCalculator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
8#include <tuple>
9#include "TH1.h"
10#include "GaudiKernel/ITHistSvc.h"
11#include <nlohmann/json.hpp>
12
13L1TopoRatesCalculator::L1TopoRatesCalculator( const std::string& name, ISvcLocator* pSvcLocator ) : RatesAnalysisAlg(name, pSvcLocator) {
14}
15
17
18 ATH_MSG_ALWAYS("Initializing L1TopoRatesCalculator");
19
20 ATH_CHECK( RatesAnalysisAlg::initialize() ); // Initialise my parent class first
21
22 ATH_CHECK( m_trigDecisionKey.initialize() ); // Then initialise my fields afterwards
23
24 ATH_CHECK(m_l1topoKey.initialize()); //L1Topo
25
26 //Accessing L1Menu----------------------------------------------
27
28 const TrigConf::L1Menu * l1menu = nullptr;
29 ATH_CHECK( detStore()->retrieve(l1menu)); //detStore() returns m_detStore. detStore() from AthCommonDataStore.h
30
31 for (size_t i = 0; i < m_userDefinedNames.value().size(); ++i) {
33 }
34 for (const std::string& L1_item : m_L1_items_json) {
35 bool found = false;
36 for (const TrigConf::L1Item& L1item : *l1menu) {
37 const std::string& L1name = L1item.name();
38 if (L1name == L1_item){
39 const std::string& L1definition = L1item.definition();
40 m_L1_item_definitions.push_back(L1definition);
41 m_L1_items.push_back(L1_item);
42 found = true;
43 break;
44 }
45 }
46 if (!found) {
47 ATH_MSG_DEBUG("Warning: L1 item '" << L1_item << "' not found in the L1 menu!");
48 }
49 }
50
51 for (const auto& pair : m_userDefinedMap) {
52 m_L1_items.push_back(pair.first);
53 m_L1_item_definitions.push_back(pair.second);
54 }
55 // Filling trigger map --------------
56
57 std::map<std::string, TriggerInfo> triggerMap;
58 for (size_t i = 0; i < m_L1_items.size(); ++i){
59 TriggerInfo info;
60
61 // Regular expression to capture the name of the trigger and the number in square brackets
62 std::regex re(R"(([\w\d_-]+)\[x(\d+)\])");
63 std::sregex_iterator iter((m_L1_item_definitions[i]).begin(), (m_L1_item_definitions[i]).end(), re);
64 std::sregex_iterator end;
65 std::vector<size_t> triggerPositions;
66
67 // Extract all triggers and their positions
68 while (iter != end) {
69 std::smatch match = *iter;
70 std::string triggerName = match.str(1);
71 std::string triggerCount = match.str(2);
72 info.triggers.push_back(triggerCount + triggerName);
73
74 // Store the position of the end of the trigger in the original chain to identify the operations between them
75 triggerPositions.push_back(match.position(0) + match.length(0));
76 ++iter;
77 }
78 // Capturing operations using the positions between triggers
79 size_t prevPos = 0;
80 for (size_t j = 0; j < triggerPositions.size(); ++j) {
81 size_t pos = triggerPositions[j];
82 std::string part = (m_L1_item_definitions[i]).substr(prevPos, pos - prevPos);
83
84 // Eliminate unnecessary spaces
85 part.erase(std::remove_if(part.begin(), part.end(),
86 [](unsigned char c) { return std::isspace(c); }),
87 part.end());
88
89 // Si la parte contiene un operador &, |, guardamos esa operación
90 if (part.find("&") != std::string::npos) {
91 info.operations.push_back("&");
92 } else if (part.find("|") != std::string::npos) {
93 info.operations.push_back("|");
94 }
95
96 prevPos = pos;
97 }
98 // Handling of final operation if there is only one trigger
99 std::string lastPart = (m_L1_item_definitions[i]).substr(prevPos);
100 lastPart.erase(std::remove_if(lastPart.begin(), lastPart.end(),
101 [](unsigned char c) { return std::isspace(c); }),
102 lastPart.end());
103 triggerMap[m_L1_items[i]] = info;
104 }
105
106 m_triggerMap = triggerMap;
107 //--------------------------------
108 for (const auto& pair : triggerMap) {
109 ATH_MSG_DEBUG("Key: " << pair.first);
110 for (size_t i = 0; i < pair.second.triggers.size(); ++i) {
111 ATH_MSG_DEBUG("Trigger " << i + 1 << ": " << pair.second.triggers[i]);
112 if (i < pair.second.operations.size()) {
113 ATH_MSG_DEBUG("Operation: " << pair.second.operations[i]);
114 }
115 }
116 }
117
118 // Listing the triggers needed for the L1 items (w/o the multiplicities)-----------
119
120 std::vector<std::string> beforeCTP_triggers;
121 std::vector<std::string> beforeCTP_triggers_mult;
122
123 for (const auto& pair : triggerMap) {
124 for (size_t i = 0; i < pair.second.triggers.size(); ++i) {
125 beforeCTP_triggers_mult.push_back(pair.second.triggers[i]);
126 size_t pos_number = 0;
127 while (pos_number < (pair.second.triggers[i]).size() && std::isdigit((pair.second.triggers[i])[pos_number])) {
128 ++pos_number;
129 }
130 beforeCTP_triggers.push_back((pair.second.triggers[i]).substr(pos_number));
131 }
132 }
133
134 std::unordered_set<std::string> seen_mult;
135 std::vector<std::string> beforeCTP_triggers_mult_unique;
136
137 for (const auto& str_mult : beforeCTP_triggers_mult) {
138 auto [it, inserted] = seen_mult.insert(str_mult);
139 if (inserted) {
140 beforeCTP_triggers_mult_unique.push_back(str_mult);
141 }
142 }
143
144 std::sort(beforeCTP_triggers.begin(), beforeCTP_triggers.end());
145 auto beforeCTP_triggers_unique = std::unique(beforeCTP_triggers.begin(), beforeCTP_triggers.end());
146 beforeCTP_triggers.erase(beforeCTP_triggers_unique, beforeCTP_triggers.end());
147
148 m_beforeCTP_triggers = beforeCTP_triggers;
149 m_beforeCTP_triggers_mult = beforeCTP_triggers_mult_unique;
150
151 // --------------------------------
152
153 for (size_t i = 0; i < beforeCTP_triggers.size(); ++i){
154 ATH_MSG_DEBUG("Filling L1menu parameters from item: " << beforeCTP_triggers[i]);
155 ResultDefinition definition;
156 definition.flatindex = 0;
157 definition.clock = 0;
158 definition.nBit = 0;
159 definition.fromSim = true;
160 definition.overflow = true;
161 ATH_MSG_DEBUG("Item being analyzed: " << beforeCTP_triggers[i]);
162 for( const auto & connName : l1menu->connectorNames() ) {
163 auto & conn = l1menu->connector(connName);
164 for( auto & tl : conn.triggerLines() ) {
165 //For electrical connectors from the L1Topo boards a triggerline vector holds up to 16 signals
166 if ((connName == "Topo2El") || (connName == "Topo3El")){
167 for (size_t fpga = 0; fpga < 2; ++fpga){ //run over fpgas
168 for (size_t clock = 0; clock < 2; ++clock){ //run over clocks
169 for (auto & tl : conn.triggerLines(fpga,clock)){
170 if (tl.name() == beforeCTP_triggers[i]){
171 definition.flatindex = tl.flatindex();
172 definition.nBit = tl.nbits();
173 definition.clock = tl.clock();
174 if (connName == "Topo2El") definition.conID = 2;
175 if (connName == "Topo3El") definition.conID = 3;
176 }
177 else{
178 continue;
179 }
180 }
181 }
182 }
183 }else{
184 if (tl.name() == beforeCTP_triggers[i]){
185 definition.flatindex = tl.flatindex();
186 definition.nBit = tl.nbits();
187 definition.clock = 0;
188 if (connName == "Topo1Opt0") definition.conID = 4;
189 if (connName == "Topo1Opt1") definition.conID = 5;
190 if (connName == "Topo1Opt2") definition.conID = 6;
191 if (connName == "Topo1Opt3") definition.conID = 7;
192 }else{
193 continue;
194 }
195 }
196 }
197 }
198 m_definitions.push_back(definition);
199 }
200
201 //-----------------------------------------------------
202 return StatusCode::SUCCESS;
203}
204
206 ATH_MSG_DEBUG("In ratesInitialize()");
207
208 if (m_doHistograms){
209 ATH_MSG_DEBUG("################## Registering rates matrix:");
210 m_ratesMatrixHist = new TH2D("rates_matrix","L1item Rates matrix",150,-3,3,150,-3,3);
211 m_countsMatrixHist = new TH2D("counts_matrix","L1item Counts matrix",150,-3,3,150,-3,3);
212 m_L1TopoScoreMatrixHist = new TH2D("L1TopoScore_matrix","L1TopoScore matrix",150,-3,3,150,-3,3);
213 ATH_CHECK( histSvc()->regHist("/RATESTREAM/rates_matrix", m_ratesMatrixHist) );
214 ATH_CHECK( histSvc()->regHist("/RATESTREAM/counts_matrix", m_countsMatrixHist) );
215 ATH_CHECK( histSvc()->regHist("/RATESTREAM/L1TopoScore_matrix", m_L1TopoScoreMatrixHist) );
216 }
217 // Here we assume a full-ring, other functions are available to change this assumption.
218 // @see setTargetLumiMu(const double lumi, const double mu);
219 // @see setTargetLumiBunches(const double lumi, const int32_t bunches);
220 // @see setTargetMuBunches(const double mu, const int32_t bunches);
222
223 //-------------------
224
225 // Define triggers to emulate
226 // TDT can be used instead by ATH_CHECK(addAllExisting());
227
228 // name, prescale, expressPrescale, seedName, seedPrescale, groups
229 std::set<std::string> triggerGroup {"RATE_SingleElectron"};
230
231 // Initialize rates matrix of zeros and right size ----------------------------------------
232
233 std::vector<double> vector_zeros(m_L1_items.size(), 0);
234 for (size_t i = 0; i < m_L1_items.size(); ++i){
235 m_rates_matrix.push_back(vector_zeros);
236 m_rates_matrix2.push_back(vector_zeros);
237 m_rates_matrix_TDT.push_back(vector_zeros);
238 m_rates_matrix2_TDT.push_back(vector_zeros);
239 m_counts_matrix_TDT.push_back(vector_zeros);
240 m_count_matrix.push_back(vector_zeros);
241 m_L1TopoScore_matrix.push_back(vector_zeros);
242 m_L1TopoScore_errors.push_back(vector_zeros);
243
244 }
245 // Set labels of Rates matrix
246
247 for (size_t i = 1; i <= m_L1_items.size(); ++i){
248 int j = i-1;
249 m_ratesMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
250 m_ratesMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
251 m_countsMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
252 m_countsMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
253 m_L1TopoScoreMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
254 m_L1TopoScoreMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
255 }
256 //-----------------------------------------------------------------------------------------
257 ATH_MSG_ALWAYS("Add Existing");
258
259 for (const std::string& L1_item : m_L1_items_json) {
260 ATH_CHECK( addExisting(L1_item));
261 }
262
263 return StatusCode::SUCCESS;
264}
265
267// Decoding L1TopoSimResults
268
269 uint32_t resultValue = 999;
270
271 if (definition.fromSim) {
272 std::vector<uint32_t>result_vector(2,0);
273 xAOD::L1TopoSimResultsContainer const* resultCont = cont.cptr();
274 for (const xAOD::L1TopoSimResults* result : *resultCont) {
275 long long topoWordPrint = result->topoWord64();
276 std::bitset<64> wordPrint(topoWordPrint);
277 if (result->connectionId() != definition.conID) continue;
278
279 std::vector<uint32_t> connectorWords(4); //4 x 32 = 128 bits should be enough
280 unsigned int bitWidth = result->bitWidth();
281 long long topoWord64 = result->topoWord64();
282 std::bitset<64> word(topoWord64);
283 if (bitWidth==32) {
284 ATH_MSG_DEBUG("Electrical connector ");
285
286 long long topoWord = result->topoWord();
287 std::bitset<32> word(topoWord);
288 if (definition.overflow == 1){
289 long long topoWordOverflow = result->topoWordOverflow();
290
291 std::bitset<32> wordRes(topoWord);
292 std::bitset<32> wordOver(topoWordOverflow);
293 word = wordRes | wordOver;
294 }
295 connectorWords[result->clock()] = static_cast<uint32_t>(word.to_ullong());
296 } else {
297 ATH_MSG_DEBUG("Optical connector ");
298
299 if (definition.overflow == 1){
300 long long topoWord64Overflow = result->topoWord64Overflow();
301
302 std::bitset<64> wordRes(topoWord64);
303 std::bitset<64> wordOver(topoWord64Overflow);
304 word = wordRes | wordOver;
305 }
306 // May be used to have enough space for the 96 bits on optical connectors
307 connectorWords[2*result->clock() + 0] = static_cast<uint32_t>(word.to_ullong()); //first 32 bits
308 connectorWords[2*result->clock() + 1] = static_cast<uint32_t>(word.to_ullong() >> 32); //second 32 bits
309 }
310
311 //startOffset: for extraction of HW results to account for two fibers worth of data in one readout "TOB" block
312
313 unsigned int startOffset = 0;
314
315 if (result->connectionId() == 5 || result->connectionId() == 7){ // if Topo1Opt1 or Topo1Opt3
316 startOffset = 96;
317 }else{ // All other connectors
318 startOffset = 0;
319 }
320 resultValue = extractResult(connectorWords, definition, startOffset);
321 result_vector[result->clock()] = resultValue; //Saving the result from the loop over result->clock
322 }
323
324 if ((result_vector[0]>1)||(result_vector[1]>1)){
325 if (result_vector[0]>1) resultValue = result_vector[0];
326 if (result_vector[1]>1) resultValue = result_vector[1];
327 }else{
328 resultValue = result_vector[0] || result_vector[1]; //OR between the results from the two result->clock iterations
329 }
330
331 return resultValue;
332
333 }else{
334 ATH_MSG_ERROR("definition.fromSim set to false");
335 return 999;
336 }
337}
338
339
340// Decoding L1Topo item (fromSim = true)
341uint32_t L1TopoRatesCalculator::extractResult(const std::vector<uint32_t>& connectorContents, const L1TopoRatesCalculator::ResultDefinition& definition, unsigned int startOffset) {
342
343 uint32_t result = 0;
344 unsigned int startindex = definition.flatindex + startOffset; //for optical clock is 0, for electrical account for structure of argument
345 unsigned int endindex = startindex + definition.nBit - 1;
346 unsigned int firstWord = startindex / 32; //integer division on purpose
347 unsigned int lastWord = endindex / 32; //integer division on purpose
348 unsigned int nBitAdded = 0;
349 uint32_t word = 0; //buffer
350
351 if ((firstWord>1) | (lastWord>1)){
352 firstWord = firstWord%3;
353 lastWord = lastWord%3;
354 }
355
356 std::vector<uint32_t>result_vec(lastWord,0);
357 uint32_t mask = 0;
358
359 for (unsigned int wordIndex=firstWord; wordIndex <= lastWord; wordIndex++) {
360 unsigned int startPosInWord = (wordIndex == firstWord) ? (startindex % 32) : 0 ;
361 unsigned int endPosInWord = (wordIndex == lastWord) ? (endindex % 32) : 31;
362 // might be %3 (3words/fiber)
363 mask = ( ( 1u<< (endPosInWord+1) ) - 1 );
364 word = connectorContents[wordIndex] & mask;
365 word >>= startPosInWord;
366 result |= word << nBitAdded; //account for bits already accumulated from previous word(s)
367 nBitAdded += endPosInWord - startPosInWord + 1;
368 result_vec.push_back(result);
369 }
370 if (result_vec.size()>1){
371 result = result_vec[0] || result_vec[1];
372 }
373 return result;
374
375}
376
378
379 ATH_MSG_DEBUG("In ratesExecute");
380
382
383 const xAOD::TrigDecision* trigDecision = trigDecisionHandle.get();
384 const std::vector<uint32_t> l1Triggers = trigDecision->tbp();
386
387 if(!cont.isValid()){
388 ATH_MSG_FATAL("Could not retrieve L1Topo EDM Container from the Simulation.");
389 return StatusCode::FAILURE;
390 }
391
392 std::vector<std::string> l1Items_vector;
393 l1Items_vector = m_beforeCTP_triggers;
394 std::vector<uint32_t> resultValue(l1Items_vector.size(), 0);
395 //---------------------------------------Mult Items
396
397 // Main loop to fill matrix and trigger rates
398 // It loops over m_l1items_mult (mult) and l1Items_vector (no mult) to fill the correct decision in the matrix and in the trigger rate
399 std::map<std::string, bool> beforeCTP_result_Map;
400 for (size_t j = 0; j < m_beforeCTP_triggers_mult.size(); ++j){
401 beforeCTP_result_Map[m_beforeCTP_triggers_mult[j]] = false;
402 }
403 for (size_t i = 0; i < m_beforeCTP_triggers.size(); ++i) {
404
405 resultValue[i] = L1TopoSimResultsContainer_decoder(m_definitions[i],cont);
406 ATH_MSG_DEBUG("Trigger item: " << m_beforeCTP_triggers[i]);
407 ATH_MSG_DEBUG("Decision from the decoder first (L1TopoResultsContainer): " << resultValue[i]);
408
409 //Decision of the trigger item
410
411 ATH_MSG_DEBUG("Trigger item: " << m_beforeCTP_triggers[i]);
412 ATH_MSG_DEBUG("Decision from the decoder (L1TopoResultsContainer): " << resultValue[i]);
413
414 //m_l1items_mult includes the 4 multiplicity items
415 for (size_t j = 0; j < m_beforeCTP_triggers_mult.size(); ++j){
416 ATH_MSG_DEBUG("Loop over multiplicity array, analysing: " << m_beforeCTP_triggers_mult[j]);
417 const auto& mult_item = m_beforeCTP_triggers_mult[j];
418 size_t pos = 0;
419 while (pos < mult_item.size() && std::isdigit(mult_item[pos])) {
420 ++pos;
421 }
422 std::string leading_number = mult_item.substr(0, pos);
423 std::string item_name = mult_item.substr(pos);
424
425 //Compares the name of the trigger item of the l1Items_vector with the multiplicities vector
426 if (item_name == l1Items_vector[i]) {
427 if (leading_number <= std::to_string(resultValue[i])) {
428 if (resultValue[i] >= 1){
429 beforeCTP_result_Map[mult_item] = true;
430 break;
431 }
432
433 }
434 }
435
436 }
437 }
438
439 // Applying L1items operations-------
440
441 std::map<std::string, bool> L1_result_Map;
442 std::vector<bool> isPassed_L1item;
443
444 for (const auto& pair : m_triggerMap) {
445 const std::string& key = pair.first;
446 const TriggerInfo& info = pair.second;
447 if (info.triggers.empty()) continue;
448
449 std::vector<bool> triggerResults;
450 std::vector<std::string> newTriggers;
451
452 std::vector<std::string> muTriggers;
453 std::vector<size_t> muIndices;
454
455 for (size_t i = 0; i < info.triggers.size(); ++i) {
456 if (info.triggers[i].find("MU") != std::string::npos && info.triggers[i].find("TOPO") == std::string::npos) {
457 muTriggers.push_back(info.triggers[i]);
458 muIndices.push_back(i);
459 }
460 }
461
462 std::map<size_t, bool> customResults;
463
464 if (!muTriggers.empty()) {
465 std::string muCombinedName = "L1";
466 for (const auto& trig : muTriggers) {
467 size_t start = 0;
468 while (start < trig.size() && std::isdigit(trig[start])) ++start;
469 std::string mult = trig.substr(0, start);
470 std::string name = trig.substr(start);
471 if (mult.empty() || mult == "1") {
472 muCombinedName += "_" + name;
473 } else {
474 muCombinedName += "_" + mult + name;
475 }
476 }
477
478 auto it = getTriggerMap().find(muCombinedName);
479 if (it != getTriggerMap().end()) {
480 double weight = it->second->getTotalPrescaleWeight();
481 for (size_t idx : muIndices) {
482 customResults[idx] = static_cast<bool>(weight);
483 }
484 } else {
485 std::cerr << " [Warning] Combined MU not found: " << muCombinedName << std::endl;
486 for (size_t idx : muIndices) {
487 customResults[idx] = false;
488 }
489 }
490 }
491
492 for (size_t i = 0; i < info.triggers.size(); ++i) {
493 bool result = false;
494 const std::string& trig = info.triggers[i];
495
496 if (customResults.count(i)) {
497 result = customResults[i];
498 newTriggers.push_back("<<MU>>");
499 } else {
500 auto it = beforeCTP_result_Map.find(trig);
501 if (it != beforeCTP_result_Map.end()) {
502 result = it->second;
503 } else {
504 std::cerr << " [Warning] Trigger not found in beforeCTP_result_Map: " << trig << std::endl;
505 result = false;
506 }
507 newTriggers.push_back(trig);
508 }
509 triggerResults.push_back(result);
510 }
511
512 bool finalResult = triggerResults[0];
513 for (size_t i = 1; i < triggerResults.size(); ++i) {
514 const std::string& op = info.operations[i - 1];
515 if (op == "&") {
516 finalResult &= triggerResults[i];
517 } else if (op == "|") {
518 finalResult |= triggerResults[i];
519 } else {
520 std::cerr << " [Warning] Unknown operation: " << op << std::endl;
521 }
522 }
523
524 L1_result_Map[key] = finalResult;
525 isPassed_L1item.push_back(finalResult);
526 }
527
528 //Rates Matrix-------------------------------------------
529
530 int bin = 1;
531 for (const auto& pair : L1_result_Map) {
532 const std::string& label = pair.first;
533 m_ratesMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
534 m_ratesMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
535 m_countsMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
536 m_countsMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
537 m_L1TopoScoreMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
538 m_L1TopoScoreMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
539 ++bin;
540 }
541
543 double weight=0;
544 double count=0;
545 m_weighted_sum += m_weightingValues.m_enhancedBiasWeight;
546 m_EB_weight.push_back(m_weightingValues.m_enhancedBiasWeight);
547 for (size_t i = 0; i < m_rates_matrix.size(); ++i){
548 for (size_t j = 0; j < m_rates_matrix.size(); ++j){
549 bool flag = (isPassed_L1item[i] && isPassed_L1item[j]);
550 weight=static_cast<double>((isPassed_L1item[i] && isPassed_L1item[j])*(m_weightingValues.m_enhancedBiasWeight)*(m_weightingValues.m_linearLumiFactor));
551 if (flag) {
552 count = 1;
553 }else{
554 count = 0;
555 }
556 (m_count_matrix[i])[j] += count;
557 (m_rates_matrix[i])[j] += weight;
558 (m_rates_matrix2[i])[j] += weight*weight;
559 }
560 }
561 //------------------------------------------------------
562
563 std::vector<std::string> triggerNames;
564 for (const auto& [key, trigger] : getTriggerMap()) {
565 triggerNames.push_back(key);
566 }
567
568 const size_t nTriggers = triggerNames.size();
569
570 for (size_t i = 0; i < nTriggers; ++i) {
571 for (size_t j = 0; j < nTriggers; ++j) {
572 double w_i = getTriggerMap().at(triggerNames[i])->getTotalPrescaleWeight();
573 double w_j = getTriggerMap().at(triggerNames[j])->getTotalPrescaleWeight();
574 double weight_result_tdt = w_i * w_j;
575 double weight_TDT = weight_result_tdt*(m_weightingValues.m_enhancedBiasWeight)*(m_weightingValues.m_linearLumiFactor);
576 m_counts_matrix_TDT[i][j] += weight_result_tdt;
577 m_rates_matrix_TDT[i][j] += weight_TDT;
578 m_rates_matrix2_TDT[i][j] += weight_TDT*weight_TDT;
579 }
580 }
581
582
583 //-------------------------------------------------------
584
585 return StatusCode::SUCCESS;
586}
587
589 ATH_MSG_DEBUG("In ratesFinalize()");
590
591 //Fill rates from TDT-----------------
592
593 std::vector<std::string> triggerNames;
594 for (const auto& [key, trigger] : getTriggerMap()) {
595 triggerNames.push_back(key);
596 }
597
598 const size_t nTriggers = triggerNames.size();
599 for (size_t i = 0; i < m_rates_matrix_TDT.size(); ++i) {
600 for (size_t j = 0; j < m_rates_matrix_TDT.size(); ++j) {
602 m_rates_matrix2_TDT[i][j] = std::sqrt(((m_rates_matrix2_TDT[i])[j]))/(m_ratesDenominator);
603 }
604 }
605
606 ATH_MSG_DEBUG("\nTDT Rates matrix:\n");
607 for (size_t i = 0; i < nTriggers; ++i) {
608 for (size_t j = 0; j < nTriggers; ++j) {
609 ATH_MSG_DEBUG("Triggers (" << triggerNames[i] << ", " << triggerNames[j] << ") -> Value: " << m_rates_matrix_TDT[i][j] <<" +- " << m_rates_matrix2_TDT[i][j]);
610 }
611 }
612
613 for (const auto& pair : m_triggerMap) {
614 const std::string& label = pair.first;
615 m_RCM_nameOrder.push_back(label.c_str());
616 }
617
618 //-----------------
619
620 //Compare the trigger rates btw TDT and Rates Correlation matrix (RCM). The RCM do not include MU multiplicities so for those triggers we'll use the TDT results.
621
622 // m_RCM_nameOrder: names in order of m_rates_matrix
623 // triggerNames: names in order of m_rates_matrix_TDT
624
625 for (size_t i = 0; i < m_rates_matrix.size(); ++i) {
626 for (size_t j = 0; j < m_rates_matrix.size(); ++j) {
628 (m_rates_matrix2[i])[j] = std::sqrt((m_rates_matrix2[i])[j])/(m_ratesDenominator);
629 }
630 }
631
632 for (size_t i = 0; i < m_RCM_nameOrder.size(); ++i) {
633 const std::string& name = m_RCM_nameOrder[i];
634
635 auto it = std::find(triggerNames.begin(), triggerNames.end(), name);
636 if (it == triggerNames.end()) {
637 std::cerr << "Trigger not found in TDT: " << name << std::endl;
638 continue;
639 }
640 size_t idxTDT = std::distance(triggerNames.begin(), it);
641
642 double original = (m_rates_matrix[i][i]);
643 double tdt = m_rates_matrix_TDT[idxTDT][idxTDT];
644 if (original != tdt) {
645
646 for (size_t j = 0; j < m_RCM_nameOrder.size(); ++j) {
647
648 auto jt = std::find(triggerNames.begin(), triggerNames.end(), m_RCM_nameOrder[j]);
649 if (jt == triggerNames.end()) continue;
650 size_t jTDT = std::distance(triggerNames.begin(), jt);
651 m_rates_matrix[i][j] = m_rates_matrix_TDT[idxTDT][jTDT];
652 m_rates_matrix[j][i] = m_rates_matrix_TDT[jTDT][idxTDT];
653 m_count_matrix[i][j] = m_counts_matrix_TDT[idxTDT][jTDT];
654 m_count_matrix[j][i] = m_counts_matrix_TDT[jTDT][idxTDT];
655 m_rates_matrix2[i][j] = m_rates_matrix2_TDT[idxTDT][jTDT];
656 m_rates_matrix2[j][i] = m_rates_matrix2_TDT[jTDT][idxTDT];
657
658 }
659 ATH_MSG_DEBUG("Trigger rates replaced from TDT: " << name << ", TDT rate: " << tdt << ", RCM rate: " << original);
660 }
661 }
662
663 for (size_t i = 0; i < m_L1TopoScore_matrix.size(); ++i) {
664 for (size_t j = 0; j < m_L1TopoScore_matrix.size(); ++j) {
665 if (i == j) {
666 m_L1TopoScore_matrix[i][j] = 1.0;
667 m_L1TopoScore_errors[i][j] = 0.0;
668 } else {
669 double A = m_rates_matrix[i][i];
670 double B = m_rates_matrix[j][j];
671 double AB = m_rates_matrix[i][j];
672 double sigma_A = m_rates_matrix2[i][i];
673 double sigma_B = m_rates_matrix2[j][j];
674 double sigma_AB = m_rates_matrix2[i][j];
675
676 double denom = AB * (A + B - AB);
677 if (AB == 0 || (A + B - AB) == 0 || denom == 0) {
678 m_L1TopoScore_matrix[i][j] = 0.0;
679 m_L1TopoScore_errors[i][j] = 0.0;
680 continue;
681 }
682
683 double topoScore = (A * B) / denom;
684 m_L1TopoScore_matrix[i][j] = topoScore;
685
686 double dfdA = (B * (A + B - AB) - A * B) / (AB * pow(A + B - AB, 2));
687 double dfdB = (A * (A + B - AB) - A * B) / (AB * pow(A + B - AB, 2));
688 double dfdAB = -(A + B - 2 * AB) / (pow(AB, 2) * pow(A + B - AB, 2));
689 double sigma2 = pow(dfdA * sigma_A, 2)
690 + pow(dfdB * sigma_B, 2)
691 + pow(dfdAB * sigma_AB, 2);
692
693 m_L1TopoScore_errors[i][j] = std::sqrt(sigma2);
694
695 }
696 }
697 }
698
699 //Fill rates matrix----------
700
701 for (size_t i = 0; i < m_rates_matrix.size(); ++i) {
702 for (size_t j = 0; j < m_rates_matrix.size(); ++j) {
703 m_ratesMatrixHist->SetBinContent(j+1, i+1, ((m_rates_matrix[i])[j]));
704 m_ratesMatrixHist->SetBinError(j+1, i+1,((m_rates_matrix2[i])[j]));
705 m_countsMatrixHist->SetBinContent(j+1, i+1, ((m_count_matrix[i])[j]));
706 m_L1TopoScoreMatrixHist->SetBinContent(j+1, i+1, ((m_L1TopoScore_matrix[i])[j]));
707 m_L1TopoScoreMatrixHist->SetBinError(j+1, i+1,((m_L1TopoScore_errors[i])[j]));
708 }
709 }
710
711 //--------------------------
712 return StatusCode::SUCCESS;
713}
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_ALWAYS(x)
#define ATH_MSG_DEBUG(x)
constexpr int pow(int base, int exp) noexcept
const ServiceHandle< StoreGateSvc > & detStore() const
const ServiceHandle< ITHistSvc > & histSvc() const
The standard THistSvc (for writing histograms and TTrees and more to a root file) Returns (kind of) a...
virtual StatusCode ratesInitialize() override
To be implemented by the user.
std::vector< std::string > m_L1_items
L1TopoRatesCalculator(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< xAOD::TrigDecision > m_trigDecisionKey
std::vector< std::vector< double > > m_rates_matrix
Gaudi::Property< std::vector< std::string > > m_userDefinedDefinitions
Gaudi::Property< float > m_lumi
SG::ReadHandleKey< xAOD::L1TopoSimResultsContainer > m_l1topoKey
std::vector< double > m_EB_weight
virtual StatusCode initialize() override
Get the trigger decision tool and set up global groups.
std::map< std::string, TriggerInfo > m_triggerMap
std::vector< ResultDefinition > m_definitions
std::vector< std::string > m_RCM_nameOrder
std::vector< std::string > m_L1_item_definitions
virtual StatusCode ratesExecute() override
To be implemented by the user.
std::vector< std::vector< double > > m_count_matrix
std::vector< std::vector< double > > m_L1TopoScore_matrix
std::vector< std::vector< double > > m_counts_matrix_TDT
uint32_t extractResult(const std::vector< uint32_t > &connectorContents, const L1TopoRatesCalculator::ResultDefinition &definition, unsigned int startOffset)
virtual StatusCode ratesFinalize() override
To be implemented by the user.
std::vector< std::vector< double > > m_rates_matrix2_TDT
Gaudi::Property< std::vector< std::string > > m_userDefinedNames
std::vector< std::vector< double > > m_rates_matrix_TDT
Gaudi::Property< std::vector< std::string > > m_L1_items_json
std::vector< std::string > m_beforeCTP_triggers
uint32_t L1TopoSimResultsContainer_decoder(const L1TopoRatesCalculator::ResultDefinition &definition, SG::ReadHandle< xAOD::L1TopoSimResultsContainer > &cont)
std::vector< std::vector< double > > m_rates_matrix2
std::vector< std::string > m_beforeCTP_triggers_mult
std::vector< std::vector< double > > m_L1TopoScore_errors
std::vector< double > m_denominator
std::unordered_map< std::string, std::string > m_userDefinedMap
RatesAnalysisAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_doHistograms
double m_ratesDenominator
How much walltime is seen by the algorithm.
const std::unordered_map< std::string, std::unique_ptr< RatesTrigger > > & getTriggerMap() const
WeightingValuesSummary_t m_weightingValues
Possible weighting & lumi extrapolation values for the current event.
virtual StatusCode initialize()
Get the trigger decision tool and set up global groups.
void setTargetLumi(const double lumi)
Set the target instantaneous luminosity.
StatusCode addExisting(const std::string &pattern)
Register some existing triggers based on wild-card match, e.g.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
L1 threshold configuration.
Definition L1Item.h:18
L1 menu configuration.
Definition L1Menu.h:28
STL class.
const std::vector< uint32_t > & tbp() const
Get the Trigger Before Prescale bits.
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
std::string label(const std::string &format, int i)
Definition label.h:19
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
L1TopoSimResultsContainer_v1 L1TopoSimResultsContainer
TrigDecision_v1 TrigDecision
Define the latest version of the trigger decision class.
L1TopoSimResults_v1 L1TopoSimResults
Define the latest version of the L1TopoSimResults class.
hold the test vectors and ease the comparison