ATLAS Offline Software
TrigTauInfo.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include <ranges>
7 #include <cstdint>
8 
9 TrigTauInfo::TrigTauInfo(const std::string& trigger)
10  : m_trigger{trigger}
11 {
12  parseTriggerString();
13 }
14 
15 TrigTauInfo::TrigTauInfo(const std::string& trigger, const std::map<std::string, float>& L1Phase1_thresholds)
16  : m_trigger{trigger}
17 {
18  parseTriggerString(L1Phase1_thresholds);
19 }
20 
21 TrigTauInfo::TrigTauInfo(const std::string& trigger, const std::map<std::string, float>& L1Phase1_thresholds, const std::map<std::string, uint64_t>& L1Phase1_threshold_patterns)
22  : m_trigger{trigger}
23 {
24  parseTriggerString(L1Phase1_thresholds, L1Phase1_threshold_patterns);
25 }
26 
27 TrigTauInfo::TrigTauInfo(const std::string& trigger, const std::map<int, int>& L1Phase1ThrMap_eTAU, const std::map<int, int>& L1Phase1ThrMap_jTAU)
28  : m_trigger{trigger}
29 {
30  parseTriggerString(L1Phase1ThrMap_eTAU, L1Phase1ThrMap_jTAU);
31 }
32 
33 void TrigTauInfo::parseTriggerString(bool remove_L1_phase1_thresholds)
34 {
35  std::string clean_trigger = m_trigger;
36 
37  // Change the "L1_" prefix to "L1" internally, in case the trigger being parsed is a pure L1 trigger with the usual L1 standalone naming scheme
38  if(clean_trigger.size() > 3 && clean_trigger.rfind("L1_", 0) == 0) {
39  clean_trigger = "L1" + clean_trigger.substr(3);
40  }
41 
42  std::vector<std::string> sections;
43  for (auto&& subrange : std::views::split(m_trigger, '_')) sections.emplace_back(subrange.begin(), subrange.end());
44 
45  std::regex tau_rgx("^(\\d*)tau(\\d+)$");
46  std::regex elec_rgx("^(\\d*)e(\\d+)$");
47  std::regex muon_rgx("^(\\d*)mu(\\d+)$");
48  std::regex gamma_rgx("^(\\d*)g(\\d+)$");
49  std::regex jet_rgx("^(\\d*)j(\\d+)$");
50  std::regex met_rgx("^xe(\\d+)$");
51  std::regex noalg_rgx("^noalg$");
52  std::regex l1_rgx("^L1.*$");
53  std::regex l1_tau_rgx("(\\d*)(e|j|c|)TAU(\\d+)(L|M|T|HL|HM|HT|H|IM|I|)");
54  std::regex l1_toposeparate_rgx("^(\\d{0,2})(DETA|DPHI)(\\d{0,2})$");
55  std::regex topo_rgx("^.*(invm|dR|deta|dphi)AB.*$");
56  std::regex ditauomni_rgx("^ditauOmni(\\d)+Trk(\\d)+$");
57  std::vector<std::regex*> all_regexes = {&tau_rgx, &elec_rgx, &muon_rgx, &gamma_rgx, &jet_rgx, &met_rgx, &l1_rgx, &ditauomni_rgx};
58 
59  std::regex tau_type_rgx("^(ptonly|tracktwoMVA|tracktwoMVABDT|tracktwoLLP|trackLRT)$");
60  std::regex tau_ID_rgx("^(perf|idperf|veryloose.*|loose.*|medium.*|tight.*)$");
61 
62  std::smatch match;
63  std::regex_token_iterator<std::string::iterator> rend;
64 
65  // Check each leg
66  std::vector<std::string> leg;
67  for(size_t i = 0; i < sections.size(); i++) {
68  leg.push_back(sections[i]); // Attach to the current leg
69  //Match the beginning of a new leg, or the end of the chain
70  if(i == sections.size() - 1 || (std::any_of(all_regexes.begin(), all_regexes.end(), [&sections, i](const std::regex* rgx) { return std::regex_match(sections[i+1], *rgx); }))) {
71  // Process the previous leg, which starts with the item, multiplicity, and threshold
72  if(std::regex_match(leg[0], match, tau_rgx)) {
73  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
74  unsigned int threshold = std::stoi(match[2].str());
75 
76  // HLT Tau sequence
77  auto itr = find_if(leg.begin(), leg.end(), [tau_type_rgx](const std::string& s) { return std::regex_match(s, tau_type_rgx); });
78  std::string type = itr != leg.end() ? *itr : "tracktwoMVA"; // Default to the tracktwoMVA sequence
79 
80  // HLT Tau ID
81  itr = find_if(leg.begin(), leg.end(), [tau_ID_rgx](const std::string& s) { return std::regex_match(s, tau_ID_rgx); });
82  std::string tau_id = itr != leg.end() ? *itr : "";
83  if(tau_id.starts_with( "veryloose")) tau_id = tau_id.substr(9);
84  else if(tau_id.starts_with( "loose")) tau_id = tau_id.substr(5);
85  else if(tau_id.starts_with( "medium")) tau_id = tau_id.substr(6);
86  else if(tau_id.starts_with( "tight")) tau_id = tau_id.substr(5);
87 
88  // Override for the old trigger names
89  if(tau_id == "RNN") {
90  if(type == "tracktwoMVA") tau_id = "DeepSet";
91  if(type == "tracktwoLLP" || type == "trackLRT") tau_id = "RNNLLP";
92  }
93 
94  // Replacements (this is temprary, the entire TrigTauInfo class will be removed soon, and all this will be handled centrally in Python using the already available infrastructure)
95  if(tau_id == "DS") tau_id = "DeepSet";
96  else if(tau_id == "GNT") tau_id = "GNTau";
97 
98  for(size_t j = 0; j < multiplicity; j++) {
99  m_HLTThr.push_back(threshold);
100  m_HLTTauTypes.push_back(type);
101  m_HLTTauIDs.push_back(tau_id);
102  }
103  } else if(std::regex_match(leg[0], match, elec_rgx)) {
104  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
105  unsigned int threshold = std::stoi(match[2].str());
106  for(size_t j = 0; j < multiplicity; j++) m_HLTElecThr.push_back(threshold);
107  } else if(std::regex_match(leg[0], match, muon_rgx)) {
108  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
109  unsigned int threshold = std::stoi(match[2].str());
110  for(size_t j = 0; j < multiplicity; j++) m_HLTMuonThr.push_back(threshold);
111  } else if(std::regex_match(leg[0], match, gamma_rgx)) {
112  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
113  unsigned int threshold = std::stoi(match[2].str());
114  for(size_t j = 0; j < multiplicity; j++) m_HLTGammaThr.push_back(threshold);
115  } else if(std::regex_match(leg[0], match, jet_rgx)) {
116  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
117  unsigned int threshold = std::stoi(match[2].str());
118  for(size_t j = 0; j < multiplicity; j++) m_HLTJetThr.push_back(threshold);
119  } else if(std::regex_match(leg[0], match, met_rgx)) {
120  unsigned int threshold = std::stoi(match[2].str());
121  m_HLTMETThr.push_back(threshold);
122  } else if(std::regex_match(leg[0], match, noalg_rgx)) {
123  m_isStreamer = true;
124  } else if (std::regex_match(leg[0], match, ditauomni_rgx)) {
125  m_HLTBoostedDitauName.push_back(leg[0]);
126  } else if(std::regex_match(leg[0], l1_rgx)){ // Treat the L1 items as a leg
127  for(size_t j = 0; j < leg.size(); j++) {
128  if(std::regex_match(leg[j], topo_rgx)) continue; // Remove HLT topo sections, not part of the L1 item
129 
130  // L1Topo items (they all include a "-" in the name, or have a separate "##DETA/PHI##_" prefix):
131  if(leg[j].find('-') != std::string::npos || std::regex_match(leg[j], l1_toposeparate_rgx)) {
132  // We only keep information from the legacy L1Topo item, from which we will not always use all thresholds
133  // Since we won't be adding any more Legacy thresholds, let's hard-code it...
134  if(leg[0] == "L1TAU60" && leg[j] == "DR-TAU12ITAU12I") leg[j] = "TAU12IM"; // L1_TAU60_DR-TAU20ITAU12I, uses "TAU12IM" threshold from the L1Topo item
135  else if(leg.size() == 1 && (leg[0] == "L1DR-TAU20ITAU12I" || leg[0] == "L1DR-TAU20ITAU12I-J25")) {
136  // Uses both TAU items, in the M isolation threshold
137  leg[0] = "L1TAU20IM";
138  leg.push_back("TAU12IM");
139  // Even on combined chains using jets, we don't use the jets threshold
140  }
141  else continue; // Remove the Phase 1 L1Topo items, since we always use a multiplicity threshold
142  }
143 
144  m_L1Items.push_back(j == 0 ? leg[j].substr(2, leg[j].size()) : leg[j]); // Remove the "L1" prefix on the first L1 item
145  }
146  }
147 
148  // Start a new leg
149  leg = {};
150  }
151  }
152 
153  if(!m_L1Items.empty()) {
154  // Build the full L1 string
155  m_L1Item = m_L1Items[0];
156  for(size_t j = 1; j < m_L1Items.size(); j++) m_L1Item += "_" + m_L1Items[j];
157 
158  // Get all individual L1 TAU items
159  std::regex_token_iterator<std::string::iterator> rgx_iter(m_L1Item.begin(), m_L1Item.end(), l1_tau_rgx);
160  while(rgx_iter != rend) {
161  std::string s = *rgx_iter;
162  std::regex_match(s, match, l1_tau_rgx);
163  size_t multiplicity = match[1].str() == "" ? 1 : std::stoi(match[1].str());
164  std::string item_type = match[2].str(); // e, j, c, or ""
165  int threshold = std::stoi(match[3].str());
166  std::string item_isolation = match[4].str(); // "", L, M, T, HL, HM, HT, IM, H
167 
168  // Set the Phase 1 thresholds to -1
169  if(remove_L1_phase1_thresholds && (item_type == "e" || item_type == "j" || item_type == "c")) threshold = -1;
170 
171  for(size_t j = 0; j < multiplicity; j++) {
172  m_tauL1Items.push_back(s.substr(match[1].str().size()));
173  m_tauL1Thr.push_back(threshold);
174  m_tauL1Type.push_back(item_type + "TAU");
175  m_tauL1Iso.push_back(item_isolation);
176  m_tauL1ThresholdPattern.push_back(-1);
177  }
178  rgx_iter++;
179  }
180 
181  m_L1Item = "L1" + m_L1Items[0];
182  }
183 }
184 
185 void TrigTauInfo::parseTriggerString(const std::map<std::string, float>& L1Phase1_thresholds)
186 {
188 
189  for(size_t i = 0; i < m_tauL1Items.size(); i++) {
190  if(m_tauL1Type.at(i) == "TAU") continue; // Skip the legacy items
191 
192  const std::string& item = m_tauL1Items.at(i);
193 
194  m_tauL1Thr[i] = L1Phase1_thresholds.at(item);
195  }
196 }
197 
198 void TrigTauInfo::parseTriggerString(const std::map<std::string, float>& L1Phase1_thresholds, const std::map<std::string, uint64_t>& L1Phase1_threshold_patterns)
199 {
201 
202  for(size_t i = 0; i < m_tauL1Items.size(); i++) {
203  if(m_tauL1Type.at(i) == "TAU") continue; // Skip the legacy items
204 
205  const std::string& item = m_tauL1Items.at(i);
206 
207  m_tauL1Thr[i] = L1Phase1_thresholds.at(item);
208  m_tauL1ThresholdPattern[i] = L1Phase1_threshold_patterns.at(item);
209  }
210 }
211 
212 void TrigTauInfo::parseTriggerString(const std::map<int, int>& L1Phase1ThrMap_eTAU, const std::map<int, int>& L1Phase1ThrMap_jTAU)
213 {
214  parseTriggerString(false);
215 
216  // Correct the Phase 1 thresholds:
217  for(size_t i = 0; i < m_tauL1Items.size(); i++) {
218  const std::string& item_type = m_tauL1Type.at(i);
219  if(item_type == "eTAU" || item_type == "cTAU") {
220  m_tauL1Thr[i] = L1Phase1ThrMap_eTAU.at(m_tauL1Thr.at(i));
221  } else if(item_type == "jTAU") {
222  m_tauL1Thr[i] = L1Phase1ThrMap_jTAU.at(m_tauL1Thr.at(i));
223  }
224  }
225 }
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
TrigTauInfo::m_HLTElecThr
std::vector< float > m_HLTElecThr
Definition: TrigTauInfo.h:89
TrigTauInfo::m_HLTTauIDs
std::vector< std::string > m_HLTTauIDs
Definition: TrigTauInfo.h:79
TrigTauInfo::m_L1Item
std::string m_L1Item
Definition: TrigTauInfo.h:81
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
TrigTauInfo::m_HLTMETThr
std::vector< float > m_HLTMETThr
Definition: TrigTauInfo.h:93
TrigTauInfo::m_isStreamer
bool m_isStreamer
Definition: TrigTauInfo.h:76
TrigTauInfo::m_L1Items
std::vector< std::string > m_L1Items
Definition: TrigTauInfo.h:82
TrigTauInfo::m_HLTMuonThr
std::vector< float > m_HLTMuonThr
Definition: TrigTauInfo.h:90
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
columnar::rend
auto rend() const noexcept
Definition: ObjectRange.h:160
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
lumiFormat.i
int i
Definition: lumiFormat.py:85
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
TrigTauInfo::m_tauL1ThresholdPattern
std::vector< int64_t > m_tauL1ThresholdPattern
Definition: TrigTauInfo.h:87
TrigTauInfo::m_trigger
std::string m_trigger
Definition: TrigTauInfo.h:75
compute_lumi.leg
leg
Definition: compute_lumi.py:95
TrigTauInfo::m_HLTJetThr
std::vector< float > m_HLTJetThr
Definition: TrigTauInfo.h:92
TrigTauInfo::m_tauL1Items
std::vector< std::string > m_tauL1Items
Definition: TrigTauInfo.h:84
TrigTauInfo::m_HLTTauTypes
std::vector< std::string > m_HLTTauTypes
Definition: TrigTauInfo.h:78
threshold
Definition: chainparser.cxx:74
TrigTauInfo::TrigTauInfo
TrigTauInfo()
Definition: TrigTauInfo.h:16
TrigTauInfo::m_HLTGammaThr
std::vector< float > m_HLTGammaThr
Definition: TrigTauInfo.h:91
TrigTauInfo::m_HLTBoostedDitauName
std::vector< std::string > m_HLTBoostedDitauName
Definition: TrigTauInfo.h:95
TrigTauInfo::m_tauL1Type
std::vector< std::string > m_tauL1Type
Definition: TrigTauInfo.h:85
TrigTauInfo.h
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
TrigTauInfo::m_tauL1Iso
std::vector< std::string > m_tauL1Iso
Definition: TrigTauInfo.h:86
python.prefilter_mask.rgx
rgx
Definition: prefilter_mask.py:14
TrigTauInfo::m_tauL1Thr
std::vector< float > m_tauL1Thr
Definition: TrigTauInfo.h:83
TrigTauInfo::parseTriggerString
void parseTriggerString(bool remove_L1_phase1_thresholds=true)
Definition: TrigTauInfo.cxx:33
TrigTauInfo::m_HLTThr
std::vector< float > m_HLTThr
Definition: TrigTauInfo.h:77
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356