ATLAS Offline Software
Loading...
Searching...
No Matches
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
9TrigTauInfo::TrigTauInfo(const std::string& trigger)
10 : m_trigger{trigger}
11{
13}
14
15TrigTauInfo::TrigTauInfo(const std::string& trigger, const std::map<std::string, float>& L1Phase1_thresholds)
16 : m_trigger{trigger}
17{
18 parseTriggerString(L1Phase1_thresholds);
19}
20
21TrigTauInfo::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
27TrigTauInfo::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
33void 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
185void 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
198void 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
212void 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}
std::vector< std::string > m_tauL1Iso
Definition TrigTauInfo.h:86
std::vector< float > m_HLTMuonThr
Definition TrigTauInfo.h:90
bool m_isStreamer
Definition TrigTauInfo.h:76
std::vector< float > m_HLTGammaThr
Definition TrigTauInfo.h:91
std::string m_L1Item
Definition TrigTauInfo.h:81
std::vector< std::string > m_L1Items
Definition TrigTauInfo.h:82
std::vector< std::string > m_HLTBoostedDitauName
Definition TrigTauInfo.h:95
std::string m_trigger
Definition TrigTauInfo.h:75
std::vector< float > m_HLTElecThr
Definition TrigTauInfo.h:89
std::vector< std::string > m_tauL1Type
Definition TrigTauInfo.h:85
std::vector< std::string > m_tauL1Items
Definition TrigTauInfo.h:84
std::vector< std::string > m_HLTTauTypes
Definition TrigTauInfo.h:78
void parseTriggerString(bool remove_L1_phase1_thresholds=true)
std::vector< std::string > m_HLTTauIDs
Definition TrigTauInfo.h:79
std::vector< int64_t > m_tauL1ThresholdPattern
Definition TrigTauInfo.h:87
std::vector< float > m_tauL1Thr
Definition TrigTauInfo.h:83
std::vector< float > m_HLTJetThr
Definition TrigTauInfo.h:92
std::vector< float > m_HLTMETThr
Definition TrigTauInfo.h:93
std::vector< float > m_HLTThr
Definition TrigTauInfo.h:77
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