ATLAS Offline Software
Loading...
Searching...
No Matches
TrigMuonMatching.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
7#ifdef ROOTCORE
11#endif // ROOTCORE
12
19
20#define MUONMASS ParticleConstants::muonMassInMeV
21
23
24namespace Trig {
25
26 TrigMuonMatching::TrigMuonMatching( const std::string& name )
27 : asg::AsgMetadataTool( name ),
28 m_trigDecTool("Trig::TrigDecisionTool/TrigDecisionTool")
29 {
30 declareProperty( "TriggerTool", m_trigDecTool);
31 }
32
35
37 // Greet the user:
38 ATH_MSG_INFO( "Initialising... " );
39
40 ATH_CHECK(m_trigDecTool.retrieve());
41
42 return StatusCode::SUCCESS;
43 }
44
46 std::string_view chain,
47 const double mindelR) const
48 {
49 return match(mu->eta(),mu->phi(),chain,mindelR);
50 }
51
53 std::string_view l1item,
54 const double DelR) const
55 {
56 return matchL1(mu->eta(),mu->phi(),l1item,DelR);
57 }
58
60 std::string_view chain,
61 const double mindelR) const
62 {
63 Double_t delmin = mindelR;
64 EFmuon efmuon,dummy;
65 return matchedTrackDetail(efmuon, dummy, mu->eta(), mu->phi(), delmin, chain);
66 }
67
69 std::string_view l1item,
70 const double DelR) const
71 {
72 Double_t l1dr = DelR;
73 const xAOD::MuonRoIContainer* muonrois = 0;
74 StatusCode sc = evtStore()->retrieve(muonrois,"LVL1MuonRoIs");
75 if(!sc){
76 ATH_MSG_ERROR("TrigMuonMatching::matchL1 : could not retrieve LVL1MuonRoIs");
77 return false;
78 }
79 Int_t threshold = getL1pt(l1item);
80 xAOD::MuonRoIContainer::const_iterator muroi_itr = muonrois->begin();
81 xAOD::MuonRoIContainer::const_iterator muroi_end = muonrois->end();
82 for( ; muroi_itr != muroi_end; ++muroi_itr ) {
83 if((*muroi_itr)->thrValue() >= threshold*1000){
84 Double_t dR = TrigMuonMatching::dR(mu->eta(), mu->phi(), (*muroi_itr)->eta(), (*muroi_itr)->phi());
85 if(dR < l1dr){
86 l1dr = dR;
87 }
88 }
89 }
90 return l1dr;
91 }
92
94 const xAOD::Muon* mu2,
95 const std::string& chain,
96 std::pair<Bool_t, Bool_t>& result1,
97 std::pair<Bool_t, Bool_t>& result2,
98 const Double_t& mindelR)
99 {
100 TLorentzVector mu_1, mu_2;
101 mu_1.SetPtEtaPhiM(mu1->pt(),mu1->eta(),mu1->phi(),MUONMASS);
102 mu_2.SetPtEtaPhiM(mu2->pt(),mu2->eta(),mu2->phi(),MUONMASS);
103 Bool_t valid = matchDimuon(mu_1,mu_2,chain,result1,result2,mindelR);
104 return valid;
105 }
106
107 Bool_t TrigMuonMatching::match(const double eta,
108 const double phi,
109 std::string_view chain,
110 const double mindelR) const
111 {
112 if(!m_trigDecTool->isPassed(chain)){
113 return false;
114 }
115 Double_t delmin = mindelR;
116 EFmuon efmuon,dummy;
117
118 matchedTrackDetail(efmuon, dummy, eta, phi, delmin, chain);
119 return efmuon.valid;
120 }
121
122 Bool_t TrigMuonMatching::matchL1(const double eta,
123 const double phi,
124 std::string_view l1item,
125 const double DelR) const
126 {
127 if(!m_trigDecTool->isPassed("L1_MU.*")){
128 return false;
129 }
130 Double_t l1dr = DelR;
131 const xAOD::MuonRoIContainer* muonrois = 0;
132 StatusCode sc = evtStore()->retrieve(muonrois,"LVL1MuonRoIs");
133 if(!sc){
134 ATH_MSG_ERROR("TrigMuonMatching::matchL1 : could not retrieve LVL1MuonRoIs");
135 return false;
136 }
137 Int_t threshold = getL1pt(l1item);
138 xAOD::MuonRoIContainer::const_iterator muroi_itr = muonrois->begin();
139 xAOD::MuonRoIContainer::const_iterator muroi_end = muonrois->end();
140 for( ; muroi_itr != muroi_end; ++muroi_itr ) {
141 if((*muroi_itr)->thrValue() >= threshold*1000){
142 Double_t dR = TrigMuonMatching::dR(eta, phi, (*muroi_itr)->eta(), (*muroi_itr)->phi());
143 if(dR < l1dr){
144 return true;
145 }
146 }
147 }
148 return false;
149 }
150
152 std::string_view l1item,
153 std::string_view chain,
154 const double DelR) const
155 {
156 if(!m_trigDecTool->isPassed("L1_MU.*")){
157 return false;
158 }
159 const xAOD::MuonRoIContainer* muonrois = 0;
160 StatusCode sc = evtStore()->retrieve(muonrois,"LVL1MuonRoIs");
161 if(!sc){
162 ATH_MSG_ERROR("TrigMuonMatching::matchL1 : could not retrieve LVL1MuonRoIs");
163 return false;
164 }
165 xAOD::MuonRoIContainer::const_iterator muroi_itr = muonrois->begin();
166 xAOD::MuonRoIContainer::const_iterator muroi_end = muonrois->end();
167 Int_t threshold = getL1pt(l1item);
168 unsigned int ROI = 0;
169 const std::string emptyStr;
170 for( ; muroi_itr != muroi_end; ++muroi_itr ) {
171 if(!((*muroi_itr)->thrValue() >= threshold*1000)) continue;
172 ROI = (*muroi_itr)->getRoI();
173 auto cg = m_trigDecTool->getChainGroup(chain);
174 auto fc = cg->features(TrigDefs::alsoDeactivateTEs);
175#if defined(XAOD_STANDALONE) || defined(XAOD_ANALYSIS)
176 auto MuFeatureContainers = fc.containerFeature<xAOD::L2StandAloneMuonContainer>(emptyStr,TrigDefs::alsoDeactivateTEs);
177#else
178 const std::vector< Trig::Feature<xAOD::L2StandAloneMuonContainer> > MuFeatureContainers = fc.get<xAOD::L2StandAloneMuonContainer>(emptyStr, TrigDefs::alsoDeactivateTEs);
179#endif
180 for(const auto & mucont : MuFeatureContainers){
181 for(auto muon : *mucont.cptr()){
182 if(muon->roiNumber() == ROI){
183 Double_t dR = TrigMuonMatching::dR(mu->eta(), mu->phi(), muon->eta(), muon->phi());
184 if(dR < DelR) return true;
185 }
186 }
187 }
188 }
189
190 return false;
191 }
192
194 std::string_view chain,
195 const double DelR) const
196 {
197 auto cg = m_trigDecTool->getChainGroup(chain);
198 auto fc = cg->features(TrigDefs::alsoDeactivateTEs);
199#if defined(XAOD_STANDALONE) || defined(XAOD_ANALYSIS)
200 auto MuFeatureContainers = fc.containerFeature<xAOD::L2CombinedMuonContainer>("",TrigDefs::alsoDeactivateTEs);
201#else
202 const std::vector< Trig::Feature<xAOD::L2CombinedMuonContainer> > MuFeatureContainers = fc.get<xAOD::L2CombinedMuonContainer>("", TrigDefs::alsoDeactivateTEs);
203#endif
204
205 for(const auto & mucont : MuFeatureContainers){
206 for(auto muon : *mucont.cptr()){
207 Double_t dR = TrigMuonMatching::dR(mu->eta(), mu->phi(), muon->eta(), muon->phi());
208 if(dR < DelR) return true;
209 }
210 }
211 return false;
212 }
213
214 Bool_t TrigMuonMatching::matchDimuon(const TLorentzVector& muon1,
215 const TLorentzVector& muon2,
216 const std::string& chain,
217 std::pair<Bool_t, Bool_t>& result1,
218 std::pair<Bool_t, Bool_t>& result2,
219 const Double_t& mindelR)
220 {
221 Double_t delmin = mindelR;
222 DimuonChainInfo chainInfo(chain);
223 if (not decodeDimuonChain(chainInfo)) {
224 ATH_MSG_ERROR("TrigMuonMatching : Failed to decode chain " << chain << " matchDimuon can accept only chains named HLT_2muXX and HLT_muXX_mu8noL1.");
225 return false;
226 }
227
228 std::pair<Bool_t, Bool_t> rc12, rc21;
229 rc12 = matchDimuon(muon1, muon2, chainInfo, delmin);
230 if(chainInfo.isSymmetric){
231 rc21.first = rc12.second; rc21.second = rc12.first;
232 }
233
234 else{
235 rc21 = matchDimuon(muon2, muon1, chainInfo, delmin);
236 }
237
238 result1.first = rc12.first; result1.second = rc21.second;
239 result2.first = rc21.first; result2.second = rc12.second;
240 return true;
241 }
242
243 Bool_t TrigMuonMatching::isPassedRerun(const std::string& trigger) const
244 {
245 const unsigned int bits = m_trigDecTool->isPassedBits(trigger);
246 if( (bits & TrigDefs::EF_passedRaw) && ! ( bits & TrigDefs::EF_passThrough) && ( bits & TrigDefs::EF_resurrected)){
247 return true;
248 }
249 return false;
250 }
251
252 std::pair<Bool_t, Bool_t> TrigMuonMatching::matchDimuon(const TLorentzVector& muon1,
253 const TLorentzVector& muon2,
254 const DimuonChainInfo& chainInfo,
255 const double mindelR)
256 {
257
258 EFmuon trkId1, trkId2, dummy;
259 const Double_t dr1 = matchedTrackDetail(trkId1, dummy, muon1.Eta(), muon1.Phi(), mindelR, chainInfo.thresholds.first);
260
261 // for full scan trigger.
262
263 const Double_t dr2 = matchedTrackDetail(trkId2, dummy, muon2.Eta(), muon2.Phi(), mindelR, chainInfo.thresholds.second);
264
265 if(trkId1.valid && trkId2.valid &&
266 isEqual(trkId1.pt, trkId2.pt) &&
267 isEqual(trkId1.eta, trkId2.eta) &&
268 isEqual(trkId1.phi, trkId2.phi)){
269 if(dr1 > dr2){
270 matchedTrackDetail(trkId1, trkId2, muon1.Eta(), muon1.Phi(), mindelR, chainInfo.thresholds.first);
271 }
272 else{
273 matchedTrackDetail(trkId2, trkId1, muon2.Eta(), muon2.Phi(), mindelR, chainInfo.thresholds.second);
274 }
275 }
276
277 return std::pair<Bool_t, Bool_t> (trkId1.valid, trkId2.valid);
278 }
279
280
281
282 double TrigMuonMatching::dR(const double eta1,
283 const double phi1,
284 const double eta2,
285 const double phi2) const
286 {
287 double deta = fabs(eta1 - eta2);
288 double dphi = fabs(phi1 - phi2) < TMath::Pi() ? fabs(phi1 - phi2) : 2*TMath:: \
289 Pi() - fabs(phi1 - phi2);
290 return sqrt(deta*deta + dphi*dphi);
291 }
292
293
294 int TrigMuonMatching::getL1pt(std::string_view l1item) const
295 {
296 int rc = -1;
297
298 std::vector<std::string> tokens = tokenize(l1item, '_');
299 std::string pt;
300 if (tokens.size() == 1) {
301 pt = tokens.front();
302
303 } else if ((tokens.size() == 2 ) and (tokens.front() == "L1")) {
304 pt = tokens[1];
305
306 } else {
307 ATH_MSG_ERROR("TrigMuonMatching::getL1pt : cannot parse " << l1item);
308 return rc;
309 }
310
311 const size_t index = pt.find("MU");
312 if (index != std::string::npos) {
313 std::istringstream iss(pt.substr(index + 2));
314 iss >> rc;
315 } else {
316 ATH_MSG_ERROR("TrigMuonMatching::getL1pt : cannot parse " << l1item);
317 }
318
319 return rc;
320 }
321
322
323
324
325
327 const EFmuon& usedEFMuonId,
328 const double eta,
329 const double phi,
330 const double mindelR,
331 std::string_view chainForEventTrigger) const
332 {
333 efMuonId.valid = false;
334 Double_t drmin = mindelR;
335
336 auto cg = m_trigDecTool->getChainGroup(chainForEventTrigger);
337 auto fc = cg->features();
338
339#if defined(XAOD_STANDALONE) || defined(XAOD_ANALYSIS)
340 auto MuFeatureContainers = fc.containerFeature<xAOD::MuonContainer>();
341#else
342 const std::vector< Trig::Feature<xAOD::MuonContainer> > MuFeatureContainers = fc.get<xAOD::MuonContainer>();
343#endif
344
345 for(const auto & mucont : MuFeatureContainers){
346 for(auto mu : *mucont.cptr()){
347
348 // l1 matching
349
350 if(isEqual(usedEFMuonId.pt, mu->pt()) &&
351 isEqual(usedEFMuonId.eta, mu->eta()) &&
352 isEqual(usedEFMuonId.phi, mu->phi())) continue;
353
354 Double_t dr = dR(eta,phi,mu->eta(),mu->phi());
355 if(drmin > dr){
356 drmin = dr;
357 efMuonId.pt = mu->pt();
358 efMuonId.eta = mu->eta();
359 efMuonId.phi = mu->phi();
360 efMuonId.valid = true;
361 }
362 }
363 }
364 return drmin;
365 }
366
367 /*
368 double TrigMuonMatching::matchedTrackDetail(const double eta,
369 const double phi,
370 const std::string chain,
371 const std::string l1item)
372 {
373 auto cg = m_trigDecTool->getChainGroup(chain);
374 auto fc = cg->features();
375 auto MuFeatureContainers = fc.containerFeature<xAOD::MuonContainer>();
376 double dR_min = m_matchingDr;
377 for(auto mucont : MuFeatureContainers){
378
379 // l1 item matching
380
381 for(auto mu : *mucont.cptr()){
382
383 // l1 item matching
384 double dr = dR(eta,phi,mu->eta(),mu->phi());
385 if(dr < dR_min ) dR_min = dr;
386 }
387 }
388 return dR_min;
389 }
390 */
391
393 {
394 chainInfo.isValid = false;
395 std::map<std::string, DimuonChainInfo >::const_iterator p = m_DimuonChainMap.find(chainInfo.chain);
396 if (p != m_DimuonChainMap.end()) {
397 chainInfo = p->second;
398 return chainInfo.isValid;
399 }
400 std::vector<std::string> tokens = tokenize(chainInfo.chain, '_');
401 if (tokens.size() < 2) return false;
402 if (tokens[0] != "HLT") return false;
403 chainInfo.isSymmetric = (tokens[1].substr(0, 3) == "2mu");
404
405 if(chainInfo.isSymmetric) {
406 std::string threshold = std::string("HLT_" + tokens[1].substr(1));
407 chainInfo.thresholds.first = threshold;
408 chainInfo.thresholds.second = std::move(threshold);
409 chainInfo.isValid = true;
410 }
411 else {
412 if(tokens.size() != 3) return false;
413
414 std::string high = std::string("HLT_" + tokens[1]);
415 chainInfo.thresholds.first = std::move(high);
416 chainInfo.thresholds.second = chainInfo.chain;
417 chainInfo.isValid = true;
418 return chainInfo.isValid;
419
420 }
421 m_DimuonChainMap[chainInfo.chain] = chainInfo;
422 return chainInfo.isValid;
423 }
424
425 bool TrigMuonMatching::isEqual(const double x, const double y) const
426 {
427 if (std::fabs(x - y) < std::numeric_limits<float>::epsilon()) return true;
428 return false;
429 }
430
431} // namespace CP
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
static Double_t sc
static Double_t rc
A number of constexpr particle constants to avoid hardcoding them directly in various places.
#define MUONMASS
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
#define y
#define x
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:837
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
int getL1pt(std::string_view l1item) const
TrigMuonMatching(const std::string &name)
std::map< std::string, DimuonChainInfo > m_DimuonChainMap
virtual Double_t minDelR(const xAOD::Muon *mu, std::string_view chain, const double mindelR=0.1) const override
bool isEqual(const double x, const double y) const
virtual Bool_t matchL1(const xAOD::Muon *mu, std::string_view l1item, const double DelR=0.2) const override
virtual Bool_t matchL2CB(const xAOD::Muon *mu, std::string_view chain, const double DelR=0.2) const override
ToolHandle< Trig::TrigDecisionTool > m_trigDecTool
virtual Double_t minDelRL1(const xAOD::Muon *mu, std::string_view l1item, const double DelR=0.2) const override
bool decodeDimuonChain(DimuonChainInfo &chainInfo)
virtual StatusCode initialize(void) override
Dummy implementation of the initialisation function.
Double_t matchedTrackDetail(EFmuon &efMuonId, const EFmuon &usedEFMuonId, const double eta, const double phi, const double mindelR, std::string_view chainEventTrigger) const
virtual Bool_t matchDimuon(const xAOD::Muon *mu1, const xAOD::Muon *mu2, const std::string &chain, std::pair< Bool_t, Bool_t > &result1, std::pair< Bool_t, Bool_t > &result2, const Double_t &mindelR=0.1) override
double dR(const double eta1, const double phi1, const double eta2, const double phi2) const
virtual Bool_t matchL2SA(const xAOD::Muon *mu, std::string_view l1item, std::string_view chain, const double DelR=0.2) const override
virtual Bool_t match(const xAOD::Muon *mu, std::string_view chain, const double mindelR=0.1) const override
virtual Bool_t isPassedRerun(const std::string &trigger) const override
AsgMetadataTool(const std::string &name)
Normal ASG tool constructor with a name.
virtual double pt() const override
The transverse momentum ( ) of the particle.
virtual double eta() const override
The pseudorapidity ( ) of the particle.
virtual double phi() const override
The azimuthal angle ( ) of the particle.
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
The common trigger namespace for trigger analysis tools.
Definition index.py:1
MuonRoIContainer_v1 MuonRoIContainer
L2CombinedMuonContainer_v1 L2CombinedMuonContainer
Define the latest version of the muon CB container.
L2StandAloneMuonContainer_v2 L2StandAloneMuonContainer
Define the latest version of the muon SA container.
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
std::pair< std::string, std::string > thresholds