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_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)
341 uint32_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;
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 }
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:138
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:83
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:76
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
skel.it
it
Definition: skel.GENtoEVGEN.py:407
ReadBchFromCrest.begin
begin
Definition: ReadBchFromCrest.py:80
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:138
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:341
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
MuonR4::to_string
std::string to_string(const SectorProjector proj)
Definition: MsTrackSeeder.cxx:66
xAOD::topoWord64
setTopoWord topoWord64
Definition: L1TopoSimResults_v1.cxx:36
L1TopoRatesCalculator::m_count_matrix
std::vector< std::vector< double > > m_count_matrix
Definition: L1TopoRatesCalculator.h:73
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:75
L1TopoRatesCalculator::m_lumi
Gaudi::Property< float > m_lumi
Definition: L1TopoRatesCalculator.h:88
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:78
ElectronContainer.h
L1TopoRatesCalculator::L1TopoSimResultsContainer_decoder
uint32_t L1TopoSimResultsContainer_decoder(const L1TopoRatesCalculator::ResultDefinition &definition, SG::ReadHandle< xAOD::L1TopoSimResultsContainer > &cont)
Definition: L1TopoRatesCalculator.cxx:266
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:588
L1TopoRatesCalculator::m_L1TopoScore_matrix
std::vector< std::vector< double > > m_L1TopoScore_matrix
Definition: L1TopoRatesCalculator.h:74
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:795
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
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:377
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
L1TopoRatesCalculator::m_counts_matrix_TDT
std::vector< std::vector< double > > m_counts_matrix_TDT
Definition: L1TopoRatesCalculator.h:72
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:357
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:77
L1TopoRatesCalculator::ResultDefinition::conID
unsigned int conID
Definition: L1TopoRatesCalculator.h:50