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