ATLAS Offline Software
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 
13 L1TopoRatesCalculator::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){
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_count_matrix.push_back(vector_zeros);
240  m_L1TopoScore_matrix.push_back(vector_zeros);
241  m_L1TopoScore_errors.push_back(vector_zeros);
242 
243  }
244  // Set labels of Rates matrix
245 
246  for (size_t i = 1; i <= m_L1_items.size(); ++i){
247  int j = i-1;
248  m_ratesMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
249  m_ratesMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
250  m_countsMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
251  m_countsMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
252  m_L1TopoScoreMatrixHist ->GetXaxis()->SetBinLabel(i, m_L1_items[j].c_str());
253  m_L1TopoScoreMatrixHist ->GetYaxis()->SetBinLabel(i, m_L1_items[j].c_str());
254  }
255  //-----------------------------------------------------------------------------------------
256  ATH_MSG_ALWAYS("Add Existing");
257 
258  for (const std::string& L1_item : m_L1_items_json) {
259  ATH_CHECK( addExisting(L1_item));
260  }
261 
262  return StatusCode::SUCCESS;
263 }
264 
266 // Decoding L1TopoSimResults
267 
268  uint32_t resultValue = 999;
269 
270  if (definition.fromSim) {
271  std::vector<uint32_t>result_vector(2,0);
272  xAOD::L1TopoSimResultsContainer const* resultCont = cont.cptr();
273  for (const xAOD::L1TopoSimResults* result : *resultCont) {
274  long long topoWordPrint = result->topoWord64();
275  std::bitset<64> wordPrint(topoWordPrint);
276  if (result->connectionId() != definition.conID) continue;
277 
278  std::vector<uint32_t> connectorWords(4); //4 x 32 = 128 bits should be enough
279  unsigned int bitWidth = result->bitWidth();
280  long long topoWord64 = result->topoWord64();
281  std::bitset<64> word(topoWord64);
282  if (bitWidth==32) {
283  ATH_MSG_DEBUG("Electrical connector ");
284 
285  long long topoWord = result->topoWord();
286  std::bitset<32> word(topoWord);
287  if (definition.overflow == 1){
288  long long topoWordOverflow = result->topoWordOverflow();
289 
290  std::bitset<32> wordRes(topoWord);
291  std::bitset<32> wordOver(topoWordOverflow);
292  word = wordRes | wordOver;
293  }
294  connectorWords[result->clock()] = static_cast<uint32_t>(word.to_ullong());
295  } else {
296  ATH_MSG_DEBUG("Optical connector ");
297 
298  if (definition.overflow == 1){
299  long long topoWord64Overflow = result->topoWord64Overflow();
300 
301  std::bitset<64> wordRes(topoWord64);
302  std::bitset<64> wordOver(topoWord64Overflow);
303  word = wordRes | wordOver;
304  }
305  // May be used to have enough space for the 96 bits on optical connectors
306  connectorWords[2*result->clock() + 0] = static_cast<uint32_t>(word.to_ullong()); //first 32 bits
307  connectorWords[2*result->clock() + 1] = static_cast<uint32_t>(word.to_ullong() >> 32); //second 32 bits
308  }
309 
310  //startOffset: for extraction of HW results to account for two fibers worth of data in one readout "TOB" block
311 
312  unsigned int startOffset = 0;
313 
314  if (result->connectionId() == 5 || result->connectionId() == 7){ // if Topo1Opt1 or Topo1Opt3
315  startOffset = 96;
316  }else{ // All other connectors
317  startOffset = 0;
318  }
319  resultValue = extractResult(connectorWords, definition, startOffset);
320  result_vector[result->clock()] = resultValue; //Saving the result from the loop over result->clock
321  }
322 
323  if ((result_vector[0]>1)||(result_vector[1]>1)){
324  if (result_vector[0]>1) resultValue = result_vector[0];
325  if (result_vector[1]>1) resultValue = result_vector[1];
326  }else{
327  resultValue = result_vector[0] || result_vector[1]; //OR between the results from the two result->clock iterations
328  }
329 
330  return resultValue;
331 
332  }else{
333  ATH_MSG_ERROR("definition.fromSim set to false");
334  return 999;
335  }
336 }
337 
338 
339 // Decoding L1Topo item (fromSim = true)
340 uint32_t L1TopoRatesCalculator::extractResult(const std::vector<uint32_t>& connectorContents, const L1TopoRatesCalculator::ResultDefinition& definition, unsigned int startOffset) {
341 
342  uint32_t result = 0;
343  unsigned int startindex = definition.flatindex + startOffset; //for optical clock is 0, for electrical account for structure of argument
344  unsigned int endindex = startindex + definition.nBit - 1;
345  unsigned int firstWord = startindex / 32; //integer division on purpose
346  unsigned int lastWord = endindex / 32; //integer division on purpose
347  unsigned int nBitAdded = 0;
348  uint32_t word = 0; //buffer
349 
350  if ((firstWord>1) | (lastWord>1)){
351  firstWord = firstWord%3;
352  lastWord = lastWord%3;
353  }
354 
355  std::vector<uint32_t>result_vec(lastWord,0);
356  uint32_t mask = 0;
357 
358  for (unsigned int wordIndex=firstWord; wordIndex <= lastWord; wordIndex++) {
359  unsigned int startPosInWord = (wordIndex == firstWord) ? (startindex % 32) : 0 ;
360  unsigned int endPosInWord = (wordIndex == lastWord) ? (endindex % 32) : 31;
361  // might be %3 (3words/fiber)
362  mask = ( ( 1u<< (endPosInWord+1) ) - 1 );
363  word = connectorContents[wordIndex] & mask;
364  word >>= startPosInWord;
365  result |= word << nBitAdded; //account for bits already accumulated from previous word(s)
366  nBitAdded += endPosInWord - startPosInWord + 1;
367  result_vec.push_back(result);
368  }
369  if (result_vec.size()>1){
370  result = result_vec[0] || result_vec[1];
371  }
372  return result;
373 
374 }
375 
377 
378  ATH_MSG_DEBUG("In ratesExecute");
379 
381 
382  const xAOD::TrigDecision* trigDecision = trigDecisionHandle.get();
383  const std::vector<uint32_t> l1Triggers = trigDecision->tbp();
385 
386  if(!cont.isValid()){
387  ATH_MSG_FATAL("Could not retrieve L1Topo EDM Container from the Simulation.");
388  return StatusCode::FAILURE;
389  }
390 
391  std::vector<std::string> l1Items_vector;
392  l1Items_vector = m_beforeCTP_triggers;
393  std::vector<uint32_t> resultValue(l1Items_vector.size(), 0);
394  //---------------------------------------Mult Items
395 
396  // Main loop to fill matrix and trigger rates
397  // 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
398  std::map<std::string, bool> beforeCTP_result_Map;
399  for (size_t j = 0; j < m_beforeCTP_triggers_mult.size(); ++j){
400  beforeCTP_result_Map[m_beforeCTP_triggers_mult[j]] = false;
401  }
402  for (size_t i = 0; i < m_beforeCTP_triggers.size(); ++i) {
403 
404  resultValue[i] = L1TopoSimResultsContainer_decoder(m_definitions[i],cont);
405  ATH_MSG_DEBUG("Trigger item: " << m_beforeCTP_triggers[i]);
406  ATH_MSG_DEBUG("Decision from the decoder first (L1TopoResultsContainer): " << resultValue[i]);
407 
408  //Decision of the trigger item
409 
410  ATH_MSG_DEBUG("Trigger item: " << m_beforeCTP_triggers[i]);
411  ATH_MSG_DEBUG("Decision from the decoder (L1TopoResultsContainer): " << resultValue[i]);
412 
413  //m_l1items_mult includes the 4 multiplicity items
414  for (size_t j = 0; j < m_beforeCTP_triggers_mult.size(); ++j){
415  ATH_MSG_DEBUG("Loop over multiplicity array, analysing: " << m_beforeCTP_triggers_mult[j]);
416  const auto& mult_item = m_beforeCTP_triggers_mult[j];
417  size_t pos = 0;
418  while (pos < mult_item.size() && std::isdigit(mult_item[pos])) {
419  ++pos;
420  }
421  std::string leading_number = mult_item.substr(0, pos);
422  std::string item_name = mult_item.substr(pos);
423 
424  //Compares the name of the trigger item of the l1Items_vector with the multiplicities vector
425  if (item_name == l1Items_vector[i]) {
426  if (leading_number <= std::to_string(resultValue[i])) {
427  if (resultValue[i] >= 1){
428  beforeCTP_result_Map[mult_item] = true;
429  break;
430  }
431 
432  }
433  }
434 
435  }
436  }
437 
438  // Applying L1items operations-------
439 
440  std::map<std::string, bool> L1_result_Map;
441  std::vector<bool> isPassed_L1item;
442 
443  for (const auto& pair : m_triggerMap) {
444  const std::string& key = pair.first;
445  const TriggerInfo& info = pair.second;
446  if (info.triggers.empty()) continue;
447 
448  std::vector<bool> triggerResults;
449  std::vector<std::string> newTriggers;
450 
451  std::vector<std::string> muTriggers;
452  std::vector<size_t> muIndices;
453 
454  for (size_t i = 0; i < info.triggers.size(); ++i) {
455  if (info.triggers[i].find("MU") != std::string::npos && info.triggers[i].find("TOPO") == std::string::npos) {
456  muTriggers.push_back(info.triggers[i]);
457  muIndices.push_back(i);
458  }
459  }
460 
461  std::map<size_t, bool> customResults;
462 
463  if (!muTriggers.empty()) {
464  std::string muCombinedName = "L1";
465  for (const auto& trig : muTriggers) {
466  size_t start = 0;
467  while (start < trig.size() && std::isdigit(trig[start])) ++start;
468  std::string mult = trig.substr(0, start);
469  std::string name = trig.substr(start);
470  if (mult.empty() || mult == "1") {
471  muCombinedName += "_" + name;
472  } else {
473  muCombinedName += "_" + mult + name;
474  }
475  }
476 
477  auto it = getTriggerMap().find(muCombinedName);
478  if (it != getTriggerMap().end()) {
479  double weight = it->second->getTotalPrescaleWeight();
480  for (size_t idx : muIndices) {
481  customResults[idx] = static_cast<bool>(weight);
482  }
483  } else {
484  std::cerr << " [Warning] Combined MU not found: " << muCombinedName << std::endl;
485  for (size_t idx : muIndices) {
486  customResults[idx] = false;
487  }
488  }
489  }
490 
491  for (size_t i = 0; i < info.triggers.size(); ++i) {
492  bool result = false;
493  const std::string& trig = info.triggers[i];
494 
495  if (customResults.count(i)) {
496  result = customResults[i];
497  newTriggers.push_back("<<MU>>");
498  } else {
499  auto it = beforeCTP_result_Map.find(trig);
500  if (it != beforeCTP_result_Map.end()) {
501  result = it->second;
502  } else {
503  std::cerr << " [Warning] Trigger not found in beforeCTP_result_Map: " << trig << std::endl;
504  result = false;
505  }
506  newTriggers.push_back(trig);
507  }
508  triggerResults.push_back(result);
509  }
510 
511  bool finalResult = triggerResults[0];
512  for (size_t i = 1; i < triggerResults.size(); ++i) {
513  const std::string& op = info.operations[i - 1];
514  if (op == "&") {
515  finalResult &= triggerResults[i];
516  } else if (op == "|") {
517  finalResult |= triggerResults[i];
518  } else {
519  std::cerr << " [Warning] Unknown operation: " << op << std::endl;
520  }
521  }
522 
523  L1_result_Map[key] = finalResult;
524  isPassed_L1item.push_back(finalResult);
525  }
526 
527  //Rates Matrix-------------------------------------------
528 
529  int bin = 1;
530  for (const auto& pair : L1_result_Map) {
531  const std::string& label = pair.first;
532  m_ratesMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
533  m_ratesMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
534  m_countsMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
535  m_countsMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
536  m_L1TopoScoreMatrixHist->GetXaxis()->SetBinLabel(bin, label.c_str());
537  m_L1TopoScoreMatrixHist->GetYaxis()->SetBinLabel(bin, label.c_str());
538  ++bin;
539  }
540 
542  double weight=0;
543  double count=0;
546  for (size_t i = 0; i < m_rates_matrix.size(); ++i){
547  for (size_t j = 0; j < m_rates_matrix.size(); ++j){
548  bool flag = (isPassed_L1item[i] && isPassed_L1item[j]);
549  weight=static_cast<double>((isPassed_L1item[i] && isPassed_L1item[j])*(m_weightingValues.m_enhancedBiasWeight)*(m_weightingValues.m_linearLumiFactor));
550  if (flag) {
551  count = 1;
552  }else{
553  count = 0;
554  }
555  (m_count_matrix[i])[j] += count;
556  (m_rates_matrix[i])[j] += weight;
557  (m_rates_matrix2[i])[j] += weight*weight;
558  }
559  }
560  //------------------------------------------------------
561 
562  std::vector<std::string> triggerNames;
563  for (const auto& [key, trigger] : getTriggerMap()) {
564  triggerNames.push_back(key);
565  }
566 
567  const size_t nTriggers = triggerNames.size();
568 
569  for (size_t i = 0; i < nTriggers; ++i) {
570  for (size_t j = 0; j < nTriggers; ++j) {
571  double w_i = getTriggerMap().at(triggerNames[i])->getTotalPrescaleWeight();
572  double w_j = getTriggerMap().at(triggerNames[j])->getTotalPrescaleWeight();
573  double weight_result_tdt = w_i * w_j;
574  double weight_TDT = weight_result_tdt*(m_weightingValues.m_enhancedBiasWeight)*(m_weightingValues.m_linearLumiFactor);
575  m_rates_matrix_TDT[i][j] += weight_TDT;
576  m_rates_matrix2_TDT[i][j] += weight_TDT*weight_TDT;
577  }
578  }
579 
580 
581  //-------------------------------------------------------
582 
583  return StatusCode::SUCCESS;
584 }
585 
587  ATH_MSG_DEBUG("In ratesFinalize()");
588 
589  //Fill rates from TDT-----------------
590 
591  std::vector<std::string> triggerNames;
592  for (const auto& [key, trigger] : getTriggerMap()) {
593  triggerNames.push_back(key);
594  }
595 
596  const size_t nTriggers = triggerNames.size();
597  for (size_t i = 0; i < m_rates_matrix_TDT.size(); ++i) {
598  for (size_t j = 0; j < m_rates_matrix_TDT.size(); ++j) {
600  m_rates_matrix2_TDT[i][j] = std::sqrt(((m_rates_matrix2_TDT[i])[j]))/(m_ratesDenominator);
601  }
602  }
603 
604  ATH_MSG_DEBUG("\nTDT Rates matrix:\n");
605  for (size_t i = 0; i < nTriggers; ++i) {
606  for (size_t j = 0; j < nTriggers; ++j) {
607  ATH_MSG_DEBUG("Triggers (" << triggerNames[i] << ", " << triggerNames[j] << ") -> Value: " << m_rates_matrix_TDT[i][j] <<" +- " << m_rates_matrix2_TDT[i][j]);
608  }
609  }
610 
611  for (const auto& pair : m_triggerMap) {
612  const std::string& label = pair.first;
613  m_RCM_nameOrder.push_back(label.c_str());
614  }
615 
616  //-----------------
617 
618  //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.
619 
620  // m_RCM_nameOrder: names in order of m_rates_matrix
621  // triggerNames: names in order of m_rates_matrix_TDT
622 
623  for (size_t i = 0; i < m_rates_matrix.size(); ++i) {
624  for (size_t j = 0; j < m_rates_matrix.size(); ++j) {
626  (m_rates_matrix2[i])[j] = std::sqrt((m_rates_matrix2[i])[j])/(m_ratesDenominator);
627  }
628  }
629 
630  for (size_t i = 0; i < m_RCM_nameOrder.size(); ++i) {
631  const std::string& name = m_RCM_nameOrder[i];
632 
633  auto it = std::find(triggerNames.begin(), triggerNames.end(), name);
634  if (it == triggerNames.end()) {
635  std::cerr << "Trigger not found in TDT: " << name << std::endl;
636  continue;
637  }
638  size_t idxTDT = std::distance(triggerNames.begin(), it);
639 
640  double original = (m_rates_matrix[i][i]);
641  double tdt = m_rates_matrix_TDT[idxTDT][idxTDT];
642  if (original != tdt) {
643 
644  for (size_t j = 0; j < m_RCM_nameOrder.size(); ++j) {
645 
646  auto jt = std::find(triggerNames.begin(), triggerNames.end(), m_RCM_nameOrder[j]);
647  if (jt == triggerNames.end()) continue;
648  size_t jTDT = std::distance(triggerNames.begin(), jt);
649  m_rates_matrix[i][j] = m_rates_matrix_TDT[idxTDT][jTDT];
650  m_rates_matrix[j][i] = m_rates_matrix_TDT[jTDT][idxTDT];
651  m_rates_matrix2[i][j] = m_rates_matrix2_TDT[idxTDT][jTDT];
652  m_rates_matrix2[j][i] = m_rates_matrix2_TDT[jTDT][idxTDT];
653 
654  }
655  ATH_MSG_DEBUG("Trigger rates replaced from TDT: " << name << ", TDT rate: " << tdt << ", RCM rate: " << original);
656  }
657  }
658 
659  for (size_t i = 0; i < m_L1TopoScore_matrix.size(); ++i) {
660  for (size_t j = 0; j < m_L1TopoScore_matrix.size(); ++j) {
661  if (i == j) {
662  m_L1TopoScore_matrix[i][j] = 1.0;
663  m_L1TopoScore_errors[i][j] = 0.0;
664  } else {
665  double A = m_rates_matrix[i][i];
666  double B = m_rates_matrix[j][j];
667  double AB = m_rates_matrix[i][j];
668 
669  double sigma_A = m_rates_matrix2[i][i];
670  double sigma_B = m_rates_matrix2[j][j];
671  double sigma_AB = m_rates_matrix2[i][j];
672 
673  double denom = AB * (A + B - AB);
674  if (AB == 0 || (A + B - AB) == 0 || denom == 0) {
675  m_L1TopoScore_matrix[i][j] = 0.0;
676  m_L1TopoScore_errors[i][j] = 0.0;
677  continue;
678  }
679 
680  double topoScore = (A * B) / denom;
681  m_L1TopoScore_matrix[i][j] = topoScore;
682 
683  double dfdA = (B * (A + B - AB) - A * B) / (AB * pow(A + B - AB, 2));
684  double dfdB = (A * (A + B - AB) - A * B) / (AB * pow(A + B - AB, 2));
685  double dfdAB = -A * B * (A + B) / (pow(AB, 2) * pow(A + B - AB, 2));
686 
687  double sigma2 = pow(dfdA * sigma_A, 2)
688  + pow(dfdB * sigma_B, 2)
689  + pow(dfdAB * sigma_AB, 2);
690 
691  m_L1TopoScore_errors[i][j] = std::sqrt(sigma2);
692 
693  }
694  }
695  }
696 
697  //Fill rates matrix----------
698 
699  for (size_t i = 0; i < m_rates_matrix.size(); ++i) {
700  for (size_t j = 0; j < m_rates_matrix.size(); ++j) {
701  m_ratesMatrixHist->SetBinContent(j+1, i+1, ((m_rates_matrix[i])[j]));
702  m_ratesMatrixHist->SetBinError(j+1, i+1,((m_rates_matrix2[i])[j]));
703  m_countsMatrixHist->SetBinContent(j+1, i+1, ((m_count_matrix[i])[j]));
704  m_L1TopoScoreMatrixHist->SetBinContent(j+1, i+1, ((m_L1TopoScore_matrix[i])[j]));
705  m_L1TopoScoreMatrixHist->SetBinError(j+1, i+1,((m_L1TopoScore_errors[i])[j]));
706  }
707  }
708 
709  //--------------------------
710  return StatusCode::SUCCESS;
711 }
LArG4FSStartPointFilter.part
part
Definition: LArG4FSStartPointFilter.py:21
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
AthHistogramAlgorithm::histSvc
const ServiceHandle< ITHistSvc > & histSvc() const
The standard THistSvc (for writing histograms and TTrees and more to a root file) Returns (kind of) a...
Definition: AthHistogramAlgorithm.h:113
L1TopoRatesCalculator::L1TopoRatesCalculator
L1TopoRatesCalculator(const std::string &name, ISvcLocator *pSvcLocator)
Definition: L1TopoRatesCalculator.cxx:13
L1TopoRatesCalculator::m_trigDecisionKey
SG::ReadHandleKey< xAOD::TrigDecision > m_trigDecisionKey
Definition: L1TopoRatesCalculator.h:35
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
checkCorrelInHIST.conn
conn
Definition: checkCorrelInHIST.py:25
get_generator_info.result
result
Definition: get_generator_info.py:21
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
RatesTrigger.h
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
L1TopoRatesCalculator::m_L1_items_json
Gaudi::Property< std::vector< std::string > > m_L1_items_json
Definition: L1TopoRatesCalculator.h:58
L1TopoRatesCalculator::m_triggerMap
std::map< std::string, TriggerInfo > m_triggerMap
Definition: L1TopoRatesCalculator.h:82
L1TopoRatesCalculator::m_userDefinedNames
Gaudi::Property< std::vector< std::string > > m_userDefinedNames
Definition: L1TopoRatesCalculator.h:59
L1TopoRatesCalculator::m_denominator
std::vector< double > m_denominator
Definition: L1TopoRatesCalculator.h:75
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
L1TopoRatesCalculator::m_rates_matrix_TDT
std::vector< std::vector< double > > m_rates_matrix_TDT
Definition: L1TopoRatesCalculator.h:70
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
skel.it
it
Definition: skel.GENtoEVGEN.py:407
bin
Definition: BinsDiffFromStripMedian.h:43
RatesAnalysisAlg::m_ratesDenominator
double m_ratesDenominator
How much walltime is seen by the algorithm.
Definition: RatesAnalysisAlg.h:190
WeightingValuesSummary_t::m_linearLumiFactor
double m_linearLumiFactor
What weight needs to be applied to extrapolate rates linear in mu and bunches.
Definition: RatesHistoBase.h:66
LArDigits2NtupleDumper.tdt
tdt
Definition: LArDigits2NtupleDumper.py:137
L1TopoRatesCalculator::ratesInitialize
virtual StatusCode ratesInitialize() override
To be implemented by the user.
Definition: L1TopoRatesCalculator.cxx:205
L1TopoRatesCalculator::extractResult
uint32_t extractResult(const std::vector< uint32_t > &connectorContents, const L1TopoRatesCalculator::ResultDefinition &definition, unsigned int startOffset)
Definition: L1TopoRatesCalculator.cxx:340
TrigConf::L1Menu
L1 menu configuration.
Definition: L1Menu.h:28
L1TopoRatesCalculator::m_userDefinedMap
std::unordered_map< std::string, std::string > m_userDefinedMap
Definition: L1TopoRatesCalculator.h:61
xAOD::topoWord64
setTopoWord topoWord64
Definition: L1TopoSimResults_v1.cxx:36
L1TopoRatesCalculator::m_count_matrix
std::vector< std::vector< double > > m_count_matrix
Definition: L1TopoRatesCalculator.h:72
xAOD::topoWord
topoWord
Definition: L1TopoSimResults_v1.cxx:28
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
L1TopoRatesCalculator::initialize
virtual StatusCode initialize() override
Get the trigger decision tool and set up global groups.
Definition: L1TopoRatesCalculator.cxx:16
XMLtoHeader.count
count
Definition: XMLtoHeader.py:84
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:459
L1TopoRatesCalculator::ResultDefinition
Definition: L1TopoRatesCalculator.h:49
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:92
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
L1TopoRatesCalculator::m_L1_item_definitions
std::vector< std::string > m_L1_item_definitions
Definition: L1TopoRatesCalculator.h:64
L1TopoRatesCalculator::m_L1TopoScore_errors
std::vector< std::vector< double > > m_L1TopoScore_errors
Definition: L1TopoRatesCalculator.h:74
L1TopoRatesCalculator::m_lumi
Gaudi::Property< float > m_lumi
Definition: L1TopoRatesCalculator.h:87
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:190
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
RatesAnalysisAlg::initialize
virtual StatusCode initialize()
Get the trigger decision tool and set up global groups.
Definition: RatesAnalysisAlg.cxx:377
L1TopoRatesCalculator::ResultDefinition::clock
unsigned int clock
Definition: L1TopoRatesCalculator.h:53
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
L1TopoRatesCalculator::m_l1topoKey
SG::ReadHandleKey< xAOD::L1TopoSimResultsContainer > m_l1topoKey
Definition: L1TopoRatesCalculator.h:36
WeightingValuesSummary_t::m_enhancedBiasWeight
double m_enhancedBiasWeight
A property of the event derived from online enhanced bias prescales.
Definition: RatesHistoBase.h:57
L1TopoRatesCalculator::m_EB_weight
std::vector< double > m_EB_weight
Definition: L1TopoRatesCalculator.h:43
A
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
L1TopoRatesCalculator::TriggerInfo
Definition: L1TopoRatesCalculator.h:77
ElectronContainer.h
L1TopoRatesCalculator::L1TopoSimResultsContainer_decoder
uint32_t L1TopoSimResultsContainer_decoder(const L1TopoRatesCalculator::ResultDefinition &definition, SG::ReadHandle< xAOD::L1TopoSimResultsContainer > &cont)
Definition: L1TopoRatesCalculator.cxx:265
lumiFormat.i
int i
Definition: lumiFormat.py:85
RunTileMonitoring.l1Triggers
l1Triggers
Definition: RunTileMonitoring.py:329
L1TopoRatesCalculator::m_RCM_nameOrder
std::vector< std::string > m_RCM_nameOrder
Definition: L1TopoRatesCalculator.h:44
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::ReadHandle::get
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
master.flag
bool flag
Definition: master.py:29
add-xsec-uncert-quadrature-N.label
label
Definition: add-xsec-uncert-quadrature-N.py:104
L1TopoRatesCalculator::ratesFinalize
virtual StatusCode ratesFinalize() override
To be implemented by the user.
Definition: L1TopoRatesCalculator.cxx:586
L1TopoRatesCalculator::m_L1TopoScore_matrix
std::vector< std::vector< double > > m_L1TopoScore_matrix
Definition: L1TopoRatesCalculator.h:73
L1TopoRatesCalculator::m_ratesMatrixHist
TH2D * m_ratesMatrixHist
Definition: L1TopoRatesCalculator.h:46
RatesAnalysisAlg::m_weightingValues
WeightingValuesSummary_t m_weightingValues
Possible weighting & lumi extrapolation values for the current event.
Definition: RatesAnalysisAlg.h:189
ATH_MSG_ALWAYS
#define ATH_MSG_ALWAYS(x)
Definition: AthMsgStreamMacros.h:35
RatesAnalysisAlg::addExisting
StatusCode addExisting(const std::string &pattern)
Register some existing triggers based on wild-card match, e.g.
Definition: RatesAnalysisAlg.cxx:198
TrigConf::L1Item
L1 threshold configuration.
Definition: L1Item.h:18
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
RatesAnalysisAlg::m_doHistograms
Gaudi::Property< bool > m_doHistograms
Definition: RatesAnalysisAlg.h:191
xAOD::bitWidth
setTopoWord setTopoWord64 unsigned bitWidth
Definition: L1TopoSimResults_v1.cxx:44
L1Connector.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
compute_lumi.denom
denom
Definition: compute_lumi.py:76
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
RatesAnalysisAlg::getTriggerMap
const std::unordered_map< std::string, std::unique_ptr< RatesTrigger > > & getTriggerMap() const
Definition: RatesAnalysisAlg.cxx:194
L1TopoRatesCalculator::m_beforeCTP_triggers
std::vector< std::string > m_beforeCTP_triggers
Definition: L1TopoRatesCalculator.h:65
L1TopoRatesCalculator::m_beforeCTP_triggers_mult
std::vector< std::string > m_beforeCTP_triggers_mult
Definition: L1TopoRatesCalculator.h:66
L1TopoRatesCalculator::ResultDefinition::overflow
bool overflow
Definition: L1TopoRatesCalculator.h:55
L1TopoRatesCalculator.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:82
L1TopoRatesCalculator::m_userDefinedDefinitions
Gaudi::Property< std::vector< std::string > > m_userDefinedDefinitions
Definition: L1TopoRatesCalculator.h:60
RatesAnalysisAlg::setTargetLumi
void setTargetLumi(const double lumi)
Set the target instantaneous luminosity.
Definition: RatesAnalysisAlg.h:172
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
L1TopoRatesCalculator::ratesExecute
virtual StatusCode ratesExecute() override
To be implemented by the user.
Definition: L1TopoRatesCalculator.cxx:376
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
L1TopoRatesCalculator::m_definitions
std::vector< ResultDefinition > m_definitions
Definition: L1TopoRatesCalculator.h:67
re
const boost::regex re(r_e)
python.XMLReader.l1menu
l1menu
Definition: XMLReader.py:73
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
L1TopoRatesCalculator::m_countsMatrixHist
TH2D * m_countsMatrixHist
Definition: L1TopoRatesCalculator.h:47
L1TopoRatesCalculator::m_L1TopoScoreMatrixHist
TH2D * m_L1TopoScoreMatrixHist
Definition: L1TopoRatesCalculator.h:48
L1TopoRatesCalculator::m_rates_matrix2
std::vector< std::vector< double > > m_rates_matrix2
Definition: L1TopoRatesCalculator.h:69
xAOD::TrigDecision_v1::tbp
const std::vector< uint32_t > & tbp() const
Get the Trigger Before Prescale bits.
dqt_zlumi_alleff_HIST.tl
tl
Definition: dqt_zlumi_alleff_HIST.py:73
L1TopoRatesCalculator::m_rates_matrix
std::vector< std::vector< double > > m_rates_matrix
Definition: L1TopoRatesCalculator.h:68
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
L1TopoRatesCalculator::m_L1_items
std::vector< std::string > m_L1_items
Definition: L1TopoRatesCalculator.h:63
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
L1TopoRatesCalculator::ResultDefinition::flatindex
unsigned int flatindex
Definition: L1TopoRatesCalculator.h:51
xAOD::L1TopoSimResults_v1
Definition: L1TopoSimResults_v1.h:30
python.compressB64.c
def c
Definition: compressB64.py:93
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
L1TopoRatesCalculator::m_rates_matrix2_TDT
std::vector< std::vector< double > > m_rates_matrix2_TDT
Definition: L1TopoRatesCalculator.h:71
L1TopoRatesCalculator::ResultDefinition::nBit
unsigned int nBit
Definition: L1TopoRatesCalculator.h:52
xAOD::TrigDecision_v1
Interface to the raw trigger decision information of the event.
Definition: TrigDecision_v1.h:44
RatesAnalysisAlg
virtual analysis class for performing rates studies on AOD Pure virtual base class for trigger rate s...
Definition: RatesAnalysisAlg.h:37
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
L1TopoRatesCalculator::ResultDefinition::fromSim
bool fromSim
Definition: L1TopoRatesCalculator.h:54
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
L1TopoRatesCalculator::m_weighted_sum
double m_weighted_sum
Definition: L1TopoRatesCalculator.h:76
L1TopoRatesCalculator::ResultDefinition::conID
unsigned int conID
Definition: L1TopoRatesCalculator.h:50