ATLAS Offline Software
Loading...
Searching...
No Matches
RpcTrackAnaAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5// C/C++
6#include <fstream>
7#include <iostream>
8#include <set>
9#include <sstream>
10#include <string>
11#include <typeinfo>
12
13// root
14#include "TObjArray.h"
15
16// Athena
21
22// Boost package to read XML
23#include <boost/property_tree/ptree.hpp>
24#include <boost/property_tree/xml_parser.hpp>
25
26// Local
27#include "RpcTrackAnaAlg.h"
28
29//================================================================================================
30RpcTrackAnaAlg::RpcTrackAnaAlg(const std::string& name,
31 ISvcLocator* pSvcLocator)
32 : AthMonitorAlgorithm(name, pSvcLocator) {}
33
34//================================================================================================
36
37//================================================================================================
39 ATH_MSG_INFO(" RpcTrackAnaAlg initialize begin ");
41
42 ATH_CHECK(m_idHelperSvc.retrieve());
43 ATH_CHECK(m_beamSigmaX.initialize());
44 ATH_CHECK(m_beamSigmaY.initialize());
45 ATH_CHECK(m_beamSigmaXY.initialize());
46
48 ATH_CHECK(m_MuonContainerKey.initialize());
49 ATH_CHECK(m_rpcPrdKey.initialize());
51
54
56
57 std::vector<std::string> sectorStr = {
58 "sector1", "sector2", "sector3", "sector4", "sector5", "sector6",
59 "sector7", "sector8", "sector9", "sector10", "sector11", "sector12",
60 "sector13", "sector14", "sector15", "sector16"};
62 Monitored::buildToolMap<int>(m_tools, "RpcTrackAnaAlg", sectorStr);
63
64 std::vector<std::string> triggerThrs = {"thr1", "thr2", "thr3",
65 "thr4", "thr5", "thr6"};
67 Monitored::buildToolMap<int>(m_tools, "RpcTrackAnaAlg", triggerThrs);
68
69 ATH_MSG_INFO(" initialize extrapolator ");
70 ATH_CHECK(m_extrapolator.retrieve());
71
72 ATH_MSG_INFO(" RpcTrackAnaAlg initialize END ");
73 return StatusCode::SUCCESS;
74}
75
76//========================================================================================================
78 /*
79 Iterate over all RpcDetectorElements and RpcReadoutElements
80 and cache locally all panel
81 */
82 ATH_MSG_INFO(name() << " - RpcTrackAnaAlg::initRpcPanel - start");
83
84 unsigned int nValidPanel = 0, nTriedPanel{0};
85 const RpcIdHelper& rpcIdHelper = m_idHelperSvc->rpcIdHelper();
86 const MuonGM::MuonDetectorManager* muonMgr{nullptr};
87 ATH_CHECK(detStore()->retrieve(muonMgr));
88
89 ATH_MSG_INFO("MuonGM::MuonDetectorManager::RpcDetElMaxHash= "
90 << rpcIdHelper.module_hash_max());
91
92 m_StationNames[BI] = {};
93 m_StationNames[BM1] = {2, 3, 8, 53}; // doubletR = 1
94 m_StationNames[BM2] = {2, 3, 8, 53}; // doubletR = 2
95 m_StationNames[BO1] = {4, 5, 9, 10}; // doubletR = 1
96 m_StationNames[BO2] = {4, 5, 9, 10}; // doubletR = 2
97
98 std::vector<int> BMBO_StationNames = {2, 3, 4, 5, 8, 9, 10, 53};
99 for (auto idetEl = rpcIdHelper.detectorElement_begin();
100 idetEl != rpcIdHelper.detectorElement_end(); ++idetEl) {
101 const MuonGM::RpcReadoutElement* readoutEl = muonMgr->getRpcReadoutElement(*idetEl);
102 if (!readoutEl)
103 continue;
104
105 const unsigned int ngasgap = 2;
106 const unsigned int doubletZ = readoutEl->getDoubletZ();
107 if (readoutEl->getDoubletPhi() != 1) {
108 continue;
109 }
110
111 const Identifier readEl_id = readoutEl->identify();
112
113 int stName = rpcIdHelper.stationName(readEl_id);
114
115 if (!std::count(BMBO_StationNames.begin(), BMBO_StationNames.end(),
116 stName)) {
117 continue; // Will be changed to include BIS
118 }
119
120 if (!std::count(BMBO_StationNames.begin(), BMBO_StationNames.end(),
121 stName)) {
122 continue; // Will be changed to include BIS
123 }
124
125 for (unsigned doubletPhi = 1; doubletPhi <= 2; ++doubletPhi) {
126 for (unsigned gasgap = 1; gasgap <= ngasgap; ++gasgap) {
127 std::shared_ptr<GasGapData> gap = std::make_shared<GasGapData>(
128 *m_idHelperSvc, readoutEl, doubletZ, doubletPhi, gasgap);
129
130 std::pair<int, int> st_dbR = std::make_pair(stName, gap->doubletR);
131 m_gasGapData[st_dbR].push_back(gap);
132
133 std::shared_ptr<RpcPanel> rpcPanel_eta = std::make_shared<RpcPanel>(
134 *m_idHelperSvc, readoutEl, doubletZ, doubletPhi, gasgap, 0);
135 ATH_CHECK(setPanelIndex(rpcPanel_eta));
136
137 std::shared_ptr<RpcPanel> rpcPanel_phi = std::make_shared<RpcPanel>(
138 *m_idHelperSvc, readoutEl, doubletZ, doubletPhi, gasgap, 1);
139 ATH_CHECK(setPanelIndex(rpcPanel_phi));
140
141 if (rpcPanel_eta->panel_valid) {
142 ATH_MSG_DEBUG(" Panel stationName:"
143 << rpcPanel_eta->stationName
144 << " stationEta:" << rpcPanel_eta->stationEta
145 << " stationPhi:" << rpcPanel_eta->stationPhi
146 << " doubletR:" << rpcPanel_eta->doubletR
147 << "doubletZ:" << rpcPanel_eta->doubletZ
148 << " doubletPhi:" << rpcPanel_eta->doubletPhi
149 << " gasGap:" << rpcPanel_eta->gasGap
150 << " measPhi:" << rpcPanel_eta->measPhi);
151
152 m_rpcPanelMap.insert(
153 std::map<Identifier, std::shared_ptr<RpcPanel>>::value_type(
154 rpcPanel_eta->panelId, rpcPanel_eta));
155 nValidPanel++;
156 }
157
158 if (rpcPanel_phi->panel_valid) {
159 ATH_MSG_DEBUG(" Panel stationName:"
160 << rpcPanel_phi->stationName
161 << " stationEta:" << rpcPanel_phi->stationEta
162 << " stationPhi:" << rpcPanel_phi->stationPhi
163 << " doubletR:" << rpcPanel_phi->doubletR
164 << "doubletZ:" << rpcPanel_phi->doubletZ
165 << " doubletPhi:" << rpcPanel_phi->doubletPhi
166 << " gasGap:" << rpcPanel_phi->gasGap
167 << " measPhi:" << rpcPanel_phi->measPhi);
168
169 m_rpcPanelMap.insert(
170 std::map<Identifier, std::shared_ptr<RpcPanel>>::value_type(
171 rpcPanel_phi->panelId, rpcPanel_phi));
172 nValidPanel++;
173 }
174
175 gap->RpcPanel_eta_phi = std::make_pair(rpcPanel_eta, rpcPanel_phi);
176 ++nTriedPanel;
177 }
178 }
179 }
180
181 ATH_MSG_INFO("Number of valid panels = " << nValidPanel << " tried panels "
182 << nTriedPanel);
183 return StatusCode::SUCCESS;
184}
185
186//========================================================================================================
187StatusCode RpcTrackAnaAlg::setPanelIndex(std::shared_ptr<RpcPanel> panel) {
188 /*
189 Specify every panel with a unique index according the information in xml
190 */
191 std::string ele_str = panel->getElementStr();
192
193 std::map<std::string, int>::iterator it_eleInd =
194 m_elementIndex.find(ele_str);
195
196 if (it_eleInd == m_elementIndex.end()) {
197 ATH_MSG_ERROR("Can not find element: stationName = "
198 << panel->stationName
199 << ", stationEta = " << panel->stationEta
200 << ", stationPhi = " << panel->stationPhi
201 << ", doubletR = " << panel->doubletR
202 << ", doubletZ = " << panel->doubletZ);
203 return StatusCode::FAILURE;
204 }
205
206 int ele_index = it_eleInd->second;
207 int panel_index = (ele_index - 1) * 8 + (panel->doubletPhi - 1) * 4 +
208 (panel->gasGap - 1) * 2 + panel->measPhi;
209
210 panel->SetPanelIndex(panel_index);
211
212 return StatusCode::SUCCESS;
213}
214
215//========================================================================================================
217 /*
218 Read xml file in share/Element.xml to give each element(in the afterwards,
219 for panel) a index
220 */
221 ATH_MSG_INFO(name() << " - read element index ");
222
223 //
224 // Read xml file
225 //
226 const std::string xml_file =
228 if (xml_file.empty()) {
229 ATH_MSG_ERROR(m_elementsFileName << " not found!");
230 return StatusCode::FAILURE;
231 }
232
233 ATH_MSG_INFO(name() << " - read xml file: " << xml_file);
234
235 boost::property_tree::ptree pt;
236 read_xml(xml_file, pt);
237
238 for (boost::property_tree::ptree::value_type& child:
239 pt.get_child("Elements")) {
240 if (child.first == "Element") {
241 int index = child.second.get<int>("<xmlattr>.index");
242 int stName = child.second.get<int>("<xmlattr>.stationName");
243 int stEta = child.second.get<int>("<xmlattr>.stationEta");
244 int stPhi = child.second.get<int>("<xmlattr>.stationPhi");
245 int dbR = child.second.get<int>("<xmlattr>.doubletR");
246 int dbZ = child.second.get<int>("<xmlattr>.doubletZ");
247
248 ATH_MSG_DEBUG(" index = " << index << ", stationName = " << stName
249 << ", stationEta = " << stEta
250 << ", stationPhi = " << stPhi
251 << ", doubletR = " << dbR
252 << ", doubletZ = " << dbZ);
253 std::ostringstream ele_key;
254
255 ele_key << stName << "_" << stEta << "_" << stPhi << "_" << dbR
256 << "_" << dbZ;
257
258 std::map<std::string, int>::iterator it_eleInd =
259 m_elementIndex.find(ele_key.str());
260 if (it_eleInd == m_elementIndex.end()) {
261 m_elementIndex.insert(std::map<std::string, int>::value_type(
262 ele_key.str(), index));
263 } else {
264 ATH_MSG_ERROR("These is duplicated elements");
265 }
266 } else {
267 ATH_MSG_ERROR(" node key != Element");
268 }
269 }
270
272 "Total number of elements: "
273 << m_elementIndex.size()
274 << ", should be consistent with the number of elements in xml file!");
275
276 return StatusCode::SUCCESS;
277}
278
279//========================================================================================================
281 TString trigStr = m_trigTagList.value();
282 std::unique_ptr<TObjArray> tagList(trigStr.Tokenize(";"));
283
284 // TObjArray* tagList = TString(m_trigTagList.value()).Tokenize(",");
285 std::set<TString> alllist;
286 for (int i = 0; i < tagList->GetEntries(); i++) {
287 TString tagTrig = tagList->At(i)->GetName();
288 if (alllist.find(tagTrig) != alllist.end())
289 continue;
290 alllist.insert(tagTrig);
291 std::unique_ptr<TObjArray> arr(tagTrig.Tokenize(";"));
292 if (arr->GetEntries() == 0)
293 continue;
294 TagDef def;
295 def.eventTrig = TString(arr->At(0)->GetName());
296 def.tagTrig = def.eventTrig;
297 if (arr->GetEntries() == 2)
298 def.tagTrig = TString(arr->At(1)->GetName());
299 m_trigTagDefs.push_back(def);
300 }
301
302 return StatusCode::SUCCESS;
303}
304
305//================================================================================================
306StatusCode RpcTrackAnaAlg::fillHistograms(const EventContext& ctx) const {
307 using namespace Monitored;
308
309 if (m_plotMuonEff) {
311 }
312
313 if (m_plotPRD) {
315 }
316
317 auto tool = getGroup(m_packageName);
318 auto evtLB = Scalar<int>("evtLB", ctx.eventID().lumi_block());
319 auto run = Scalar<int>("run", ctx.eventID().run_number());
320 fill(tool, evtLB, run);
321
322 return StatusCode::SUCCESS;
323}
324
325//================================================================================================
327 const EventContext& ctx) const {
328 using namespace Monitored;
329 auto tool = getGroup(m_packageName);
330
331 //
332 // read PrimaryVertex Z
333 //
334 const xAOD::Vertex* primVertex = nullptr;
335 if (!m_PrimaryVertexContainerKey.empty()) {
338 if (primVtxContainer.isValid()) {
339 for (const auto vtx : *primVtxContainer) {
340 if (vtx->vertexType() == xAOD::VxType::VertexType::PriVtx) {
341 primVertex = vtx;
342 break;
343 }
344 }
345 }
346 }
347 const double primaryVertexZ = primVertex ? (primVertex->z()) : (-999);
348
349 //
350 // read beam position sigma from eventinfo
351 //
355
356 const float beamPosSigmaX = beamSigmaX(0);
357 const float beamPosSigmaY = beamSigmaY(0);
358 const float beamPosSigmaXY = beamSigmaXY(0);
359
360 //
361 // read muon
362 //
364 ATH_MSG_DEBUG(" muons size = " << muons->size());
365
366 if (!muons.isValid()) {
367 ATH_MSG_ERROR("evtStore() does not contain muon Collection with name "
369 return StatusCode::FAILURE;
370 }
371
372 //
373 // select out tag and probe muons
374 //
375 std::vector<std::shared_ptr<MyMuon>> tagmuons;
376 std::vector<std::shared_ptr<MyMuon>> probemuons;
377 for (const xAOD::Muon* muon : *muons) {
378 if (std::abs(muon->eta()) > m_maxEta)
379 continue;
380
381 auto mymuon = std::make_shared<MyMuon>();
382 mymuon->muon = muon;
383 mymuon->fourvec.SetPtEtaPhiM(muon->pt(), muon->eta(), muon->phi(),
384 m_muonMass.value());
385 mymuon->tagged =
386 triggerMatching(muon, m_trigTagDefs) == StatusCode::SUCCESS;
387
388 // muon quality
389 if (muon->quality() > xAOD::Muon::Medium)
390 continue;
391
392 //
393 // calculate muon z0sin(\theta) and d0significance
394 auto track = muon->primaryTrackParticle();
395 const double z0 = track->z0() + track->vz() - primaryVertexZ;
396
397 double z0sin = z0 * std::sin(track->theta());
399 track, beamPosSigmaX, beamPosSigmaY, beamPosSigmaXY);
400
401 // select probe muons
402 if (std::abs(z0sin) < 0.5 && std::abs(d0sig) < 3.0) {
403 mymuon->tagProbeOK = true;
404 }
405 probemuons.push_back(mymuon);
406
407 // select tag muons
408 if (muon->pt() > 27.0e3 && std::abs(z0sin) < 1.0 &&
409 std::abs(d0sig) < 5.0) {
410 tagmuons.push_back(mymuon);
411 }
412 }
413
414 //
415 // Z tag & probe
416 //
417 for (const auto& tag_muon : tagmuons) {
418 if (!(tag_muon->tagged))
419 continue;
420
421 for (const auto& probe_muon : probemuons) {
422 if (tag_muon->muon == probe_muon->muon)
423 continue;
424
425 // probe muon
426 if (!probe_muon->tagProbeOK)
427 continue;
428
429 // Opposite charge
430 if (tag_muon->muon->charge() == probe_muon->muon->charge())
431 continue;
432
433 // Z mass window
434 float dimuon_mass = (tag_muon->fourvec + probe_muon->fourvec).M();
435 if (dimuon_mass < m_zMass_lowLimit || dimuon_mass > m_zMass_upLimit)
436 continue;
437
438 // angular separation
439 float dr = (tag_muon->fourvec).DeltaR(probe_muon->fourvec);
440 if (dr < m_isolationWindow)
441 continue;
442
443 probe_muon->tagProbeAndZmumuOK = true;
444 }
445 }
446
447 //
448 // read rois: raw LVL1MuonRoIs
449 //
450 std::vector<const xAOD::MuonRoI*> roisBarrel;
451 if (!m_MuonRoIContainerKey.empty()) {
453 ctx);
454
455 if (!muonRoIs.isValid()) {
457 "evtStore() does not contain muon L1 ROI Collection with name "
459 return StatusCode::FAILURE;
460 }
461 const xAOD::MuonRoIContainer* rois = muonRoIs.cptr();
462
463 std::vector<float> roiEtaVec{}, roiBarrelEtaVec{};
464 std::vector<int> roiBarrelThrVec{};
465
466 roiEtaVec.reserve(muonRoIs->size());
467 roiBarrelEtaVec.reserve(muonRoIs->size());
468 roiBarrelThrVec.reserve(muonRoIs->size());
469 roisBarrel.reserve(muonRoIs->size());
470 for (const xAOD::MuonRoI* roi : *rois) {
471 roiEtaVec.push_back(roi->eta());
472 if (roi->getSource() != xAOD::MuonRoI::RoISource::Barrel)
473 continue;
474
475 roiBarrelEtaVec.push_back(roi->eta());
476 roiBarrelThrVec.push_back(roi->getThrNumber());
477 roisBarrel.push_back(roi);
478 }
479
480 auto roiEtaCollection = Collection("roiEta", roiEtaVec);
481 auto roiBarrelEtaCollection =
482 Collection("roiBarrelEta", roiBarrelEtaVec);
483 auto roiBarrelThrCollection =
484 Collection("roiBarrelThr", roiBarrelThrVec);
485 fill(tool, roiEtaCollection);
486 fill(tool, roiBarrelEtaCollection);
487 fill(tool, roiBarrelThrCollection);
488 }
489
490 //
491 // Fill Lv1 trigger efficiency
492 // Fill muon detection efficiency
493 auto i_pt_allMu = Scalar<double>("muPt_allMu", 0.);
494 auto i_eta_allMu = Scalar<double>("muEta_allMu", 0.);
495 auto i_phi_allMu = Scalar<double>("muPhi_allMu", 0.);
496 auto i_pt_zMu = Scalar<double>("muPt_MuonFromZ", 0.);
497 auto i_eta_zMu = Scalar<double>("muEta_MuonFromZ", 0.);
498 auto i_phi_zMu = Scalar<double>("muPhi_MuonFromZ", 0.);
499 auto i_eta_zMu_p =
500 Scalar<double>("muEta_p_MuonFromZ",
501 0.); // kine variable at the plateau of pt turn-on curve
502 auto i_phi_zMu_p =
503 Scalar<double>("muPhi_p_MuonFromZ",
504 0.); // kine variable at the plateau of pt turn-on curve
505
506 std::vector<GasGapResult> results;
507 int nmuon{0}, nmuon_barrel{0};
508 for (const auto& probe_muon : probemuons) {
509 nmuon++;
510 double pt = probe_muon->muon->pt();
511 double eta = probe_muon->muon->eta();
512 double phi = probe_muon->muon->phi();
513
514 // barrel muon
515 if (std::abs(eta) < m_barrelMinEta || std::abs(eta) > m_barrelMaxEta)
516 continue;
517 nmuon_barrel++;
518
519 // has MuonSpectrometerTrackParticle
520 const xAOD::TrackParticle* track = probe_muon->muon->trackParticle(
521 xAOD::Muon::MuonSpectrometerTrackParticle);
522 if (track) {
523 results.clear();
524
526 ATH_CHECK(readHitsPerGasgap(ctx, results, AllMuon));
527 }
528
529 // fill kine variables for probe muons
530 i_pt_allMu = pt;
531 i_eta_allMu = eta;
532 i_phi_allMu = phi;
533 fill(tool, i_pt_allMu, i_eta_allMu, i_phi_allMu);
534
535 //
536 // Probe muons with Z tag&probe method
537 // 1) Plot L1 trigger efficiency use probe muons
538 // 2) Plot muon detection efficiency use probe muons
539 if (probe_muon->tagProbeAndZmumuOK) {
540 //
541 // do match muon with ROI
542 std::vector<bool> isMatcheds(6, 0);
543 for (const xAOD::MuonRoI* roi : roisBarrel) {
544 const double dphi = TVector2::Phi_mpi_pi(roi->phi() - phi);
545 const double deta = roi->eta() - eta;
546 const double dr = std::hypot(dphi, deta);
547
548 if (dr > m_l1trigMatchWindow)
549 continue;
550
551 int thr = std::min(7, roi->getThrNumber());
552 for (int i_thr = 1; i_thr <= thr; i_thr++) {
553 isMatcheds[i_thr - 1] = true;
554 }
555 }
556
557 //
558 // fill L1 trigger Efficiency
559 auto i_pt = Scalar<double>("muPt_l1", pt);
560 auto i_eta = Scalar<double>("muEta_l1", eta);
561 auto i_phi = Scalar<double>("muPhi_l1", phi);
562 auto i_passTrigger = Scalar<bool>("passTrigger", false);
563 auto i_passTrigger_1 = Scalar<bool>("passTrigger_plateau", false);
564
565 for (int i_thr = 1; i_thr < 7; i_thr++) {
566 i_passTrigger = isMatcheds[i_thr - 1];
567 i_passTrigger_1 = isMatcheds[i_thr - 1];
568
569 // plot L1 trigger pt turn-on curve
571 std::to_string(i_thr))],
572 i_pt, i_passTrigger);
573
574 // plot L1 trigger efficiency on the plateau of pt turn-on curve
575 if (std::abs(pt) > m_minPt) {
577 std::to_string(i_thr))],
578 i_eta, i_phi, i_passTrigger_1);
579 }
580 }
581
582 //
583 // muon track
584 // fill muon detection Efficiency
585 //
586 if (track) {
587 ATH_CHECK(readHitsPerGasgap(ctx, results, ZCand));
588 }
589
590 // fill kine variables for probe muons in ZTP
591 i_pt_zMu = pt;
592 i_eta_zMu = eta;
593 i_phi_zMu = phi;
594 fill(tool, i_pt_zMu, i_eta_zMu, i_phi_zMu);
595
596 if (std::abs(pt) > m_minPt) {
597 i_eta_zMu_p = eta;
598 i_phi_zMu_p = phi;
599 fill(tool, i_eta_zMu_p, i_phi_zMu_p);
600 }
601 } // tagProbeAndZmumuOK
602 } // probemuons
603
604 auto Nmuon = Scalar<int>("nMu", nmuon);
605 auto Nmuon_barrel = Scalar<int>("nMuBarrel", nmuon_barrel);
606
607 //
608 // Fill histograms
609 //
610 fill(tool, Nmuon, Nmuon_barrel);
611
612 return StatusCode::SUCCESS;
613}
614
615//================================================================================================
616StatusCode RpcTrackAnaAlg::fillHistPRD(const EventContext& ctx) const {
617 using namespace Monitored;
618 //
619 // Read RPC Prepare data
620 //
621
623 const RpcIdHelper& rpcIdHelper = m_idHelperSvc->rpcIdHelper();
624
625 const int i_lb = ctx.eventID().lumi_block();
626 std::vector<double> v_prdTime = {};
627
628 auto prd_sec_all = Scalar<int>("prd_sec", 0);
629 auto prd_layer_all = Scalar<int>("prd_layer", 0);
630 auto prd_sec_1214 = Scalar<int>("prd_sec_1214", 0);
631 auto prd_layer_1214 = Scalar<int>("prd_layer_1214", 0);
632
633 auto prd_sec_all_eta = Scalar<int>("prd_sec_eta", 0);
634 auto prd_layer_all_eta = Scalar<int>("prd_layer_eta", 0);
635 auto prd_sec_all_phi = Scalar<int>("prd_sec_phi", 0);
636 auto prd_layer_all_phi = Scalar<int>("prd_layer_phi", 0);
637
638 auto i_prd_LB = Scalar<int>("LB", i_lb);
639 auto i_panelIndex = Scalar<int>("panelInd", -1);
640
641 auto tool = getGroup(m_packageName);
642
643 int panel_index;
644 std::pair<int, int> sec_layer;
645
646 //
647 // loop on RpcPrepData container
648 //
649 for (const Muon::RpcPrepDataCollection* rpcCollection : *rpcContainer) {
650 //
651 // loop on RpcPrepData
652 //
653 for (const Muon::RpcPrepData* rpcData : *rpcCollection) {
654
655 Identifier id = rpcData->identify();
656 const int measphi = rpcIdHelper.measuresPhi(id);
657
658 auto temp_panel = std::make_unique<RpcPanel>(
659 *m_idHelperSvc, rpcData->detectorElement(),
660 rpcIdHelper.doubletZ(id), rpcIdHelper.doubletPhi(id),
661 rpcIdHelper.gasGap(id), rpcIdHelper.measuresPhi(id));
662
663 std::map<Identifier, std::shared_ptr<RpcPanel>>::const_iterator
664 i_panel = m_rpcPanelMap.find(temp_panel->panelId);
665 if (i_panel == m_rpcPanelMap.end()) {
667 "The panelID corresponding prd hit does NOT link to a "
668 "known Panel "
669 << m_idHelperSvc->toString(id) << " <"
670 << m_idHelperSvc->toString(
671 rpcData->detectorElement()->identify())
672 << "> !!!");
673 continue;
674 } else {
675 panel_index = i_panel->second->panel_index;
676 }
677
678 sec_layer = temp_panel->getSectorLayer();
679 prd_sec_all = sec_layer.first;
680 prd_layer_all = sec_layer.second;
681
682 if (std::abs(sec_layer.first) == 12 ||
683 std::abs(sec_layer.first) == 14) {
684 prd_sec_1214 = sec_layer.first;
685 prd_layer_1214 = sec_layer.second;
686 }
687
688 fill(tool, prd_sec_all, prd_layer_all, prd_sec_1214,
689 prd_layer_1214);
690
691 if (measphi == 0) {
692 prd_sec_all_eta = sec_layer.first;
693 prd_layer_all_eta = sec_layer.second;
694 fill(tool, prd_sec_all_eta, prd_layer_all_eta);
695 } else {
696 prd_sec_all_phi = sec_layer.first;
697 prd_layer_all_phi = sec_layer.second;
698 fill(tool, prd_sec_all_phi, prd_layer_all_phi);
699 }
700
701 i_panelIndex = panel_index;
702 fill(tool, i_prd_LB, i_panelIndex);
703
704 v_prdTime.push_back(rpcData->time());
705 } // loop on RpcPrepData
706 } // loop on RpcPrepData container
707
708 auto prdTimeCollection = Collection("prdTime", v_prdTime);
709 fill(tool, prdTimeCollection);
710
711 ATH_MSG_DEBUG(" fillHistPRD finished ");
712 return StatusCode::SUCCESS;
713}
714
715//================================================================================================
717 const xAOD::Muon* offline_muon,
718 const std::vector<TagDef>& list_of_triggers) const {
719 if (!m_TagAndProbe.value())
720 return StatusCode::SUCCESS;
722 return StatusCode::SUCCESS;
723 TVector3 muonvec;
724 muonvec.SetPtEtaPhi(offline_muon->pt(), offline_muon->eta(),
725 offline_muon->phi());
726
727 for (const auto& tagTrig : list_of_triggers) {
728 if (!getTrigDecisionTool()->isPassed(tagTrig.eventTrig.Data()))
729 continue;
730
731 ATH_MSG_DEBUG("tagTrig.eventTrig = " << tagTrig.eventTrig
732 << "; tagTrig.tagTrig = "
733 << tagTrig.tagTrig);
734 // ATH_MSG_DEBUG("m_MuonEFContainerName.value() = "<<
735 // m_MuonEFContainerName.value());
736
737 std::vector<TrigCompositeUtils::LinkInfo<xAOD::MuonContainer>>
738 features = getTrigDecisionTool()->features<xAOD::MuonContainer>(
739 tagTrig.tagTrig.Data(), TrigDefs::Physics);
740
741 for (const auto& aaa : features) {
742 ATH_CHECK(aaa.isValid());
743 auto trigmuon_link = aaa.link;
744 auto trigmuon = *trigmuon_link;
745 TVector3 trigvec;
746 trigvec.SetPtEtaPhi(trigmuon->pt(), trigmuon->eta(),
747 trigmuon->phi());
748 if (trigvec.DeltaR(muonvec) < m_trigMatchWindow.value())
749 return StatusCode::SUCCESS;
750 }
751 }
752 return StatusCode::FAILURE;
753}
754
755//========================================================================================================
757 const Trk::PropDirection direction,
758 std::vector<GasGapResult>& results,
759 BarrelDL barrelDL) const {
760 /*
761 get intersections of the muon with the RPC planes
762
763 Iterate over all valid RPCDetectorElements and RPCReadoutElements:
764 1) compute DR distance between track and center of ReadoutElement
765 if this distance within tolerance - proceed
766 2) Next, compute:
767 -- min DR distance between track and strips within this gas gap
768 -- number of valid eta and phi strips within this gas gap
769 if both results within their tolerances - proceed
770 3) Extrapolate track to the surface of this gas gap:
771 -- Check that extrapolation result valid
772 -- Check that extrapolated position is in the gas gap surface bounds
773 if both within checks valid - then save RPC extrapolation result
774 */
775 int doubletR = 1;
776 if (barrelDL >= OUT) {
777 return StatusCode::SUCCESS;
778 } else if (barrelDL == BM2 || barrelDL == BO2) {
779 doubletR = 2;
780 }
781
782 using namespace Monitored;
783 auto tool = getGroup(m_packageName);
784
785 if (!track) {
786 return StatusCode::FAILURE;
787 }
788
789 std::map<BarrelDL, std::vector<int>>::const_iterator dl_vec_it =
790 m_StationNames.find(barrelDL);
791 if (dl_vec_it == m_StationNames.end()) {
792 return StatusCode::FAILURE;
793 }
794
795 std::unique_ptr<Trk::TrackParameters> trackParamLayer{};
796 double minDR = 1.0; // A intial value
797
798 const std::vector<int> dl_vec = dl_vec_it->second;
799 std::vector<int>::const_iterator it_dl = dl_vec.begin();
800 for (; it_dl != dl_vec.end(); ++it_dl) {
801 int stName = *it_dl;
802 std::pair<int, int> st_dbR = std::make_pair(stName, doubletR);
803 std::map<std::pair<int, int>,
804 std::vector<std::shared_ptr<GasGapData>>>::const_iterator
805 gasgapIt = m_gasGapData.find(st_dbR);
806 if (gasgapIt == m_gasGapData.end()) {
807 continue;
808 }
809
810 //
811 // Iterate over RPC readout elements and compute intersections with each
812 // gas gap
813 //
814 for (const std::shared_ptr<GasGapData>& gap : gasgapIt->second) {
815 ExResult result(gap->gapid, direction);
816
817 // Compute track distance to the gas gap surface
818 gap->computeTrackDistanceToGasGap(result, *track);
819
820 if (result.minTrackGasGapDR > m_minDRTrackToGasGap) {
821 continue;
822 }
823
824 //
825 // Extrapolate track to the gas gap surface and check whether the
826 // track position is in bounds returns new object
827 auto trackParamInGap =
829
830 if (!trackParamInGap) {
831 continue;
832 }
833
834 if (!result.localTrackPosInBoundsTight) {
835 continue;
836 }
837
838 if (result.minTrackGasGapDR < minDR) {
839 minDR = result.minTrackGasGapDR;
840 // new object moved to trackParamLayer; previous trackParamLayer
841 // gets destroyed
842 trackParamLayer = std::move(trackParamInGap);
843 }
844 ATH_MSG_DEBUG(name() << " extrapolated gasgap: " << gap->gapid_str);
845
846 results.push_back(std::make_pair(result, gap));
847 }
848 }
849
850 // Go to next layer of doublet
851 BarrelDL nextDL = BarrelDL(barrelDL + 1);
852
853 // propgate the track parameter of the last doublet
854 // if no track paramater, use the input track
855 if (trackParamLayer != nullptr) {
856 // trackParamLayer used and then goes out of scope to destroy the object
857 return extrapolate2RPC(std::move(trackParamLayer), direction, results,
858 nextDL);
859 } else {
860 return extrapolate2RPC(track, direction, results, nextDL);
861 }
862}
863
864//========================================================================================================
865std::unique_ptr<Trk::TrackParameters>
867 ExResult& result, const xAOD::TrackParticle* track_particle,
868 const std::shared_ptr<GasGapData>& gap) const {
869 const EventContext& ctx = Gaudi::Hive::currentContext();
870 /*
871 This function:
872 - constructs Identifier for specific gasgap
873 - extrapolates muon to this gas gap
874 */
875
876 // Get surface of this gas gap and extrapolate track to this surface
877 const Trk::SurfaceBounds& bounds = gap->readoutEl->bounds(gap->gapid);
878 const Trk::PlaneSurface& gapSurface = gap->readoutEl->surface(gap->gapid);
879 std::unique_ptr<Trk::TrackParameters> detParameters{};
880
881 if (m_useAODParticle) {
882 detParameters = m_extrapolator->extrapolate(
883 ctx, track_particle->perigeeParameters(), gapSurface,
884 result.direction, false, Trk::muon);
885 } else if (track_particle->track()) {
886 detParameters = m_extrapolator->extrapolateTrack(
887 ctx, *(track_particle->track()), gapSurface, result.direction, true,
888 Trk::muon);
889 } else {
890 return detParameters;
891 }
892
893 if (!detParameters) {
894 return detParameters;
895 }
896
897 //
898 // Transform global extrapolated track position on surface to local
899 // coordinates
900 //
901 const Amg::Vector3D local3dTrackPosition =
902 gap->readoutEl->globalToLocalCoords(detParameters->position(),
903 gap->gapid);
904 const Amg::Vector2D local2dTrackPosition(local3dTrackPosition.y(),
905 local3dTrackPosition.z());
906
907 //
908 // Check if the track position on surface is within tolerable bounds
909 //
910 const bool inbounds =
911 bounds.inside(local2dTrackPosition, m_boundsToleranceReadoutElement,
913 const bool inbounds_tight = bounds.inside(
914 local2dTrackPosition, m_boundsToleranceReadoutElementTight,
916
917 result.localTrackPosInBounds = inbounds;
918 result.localTrackPosInBoundsTight = inbounds_tight;
919 result.localPos = local3dTrackPosition;
920 result.globalPos = detParameters->position();
921
922 return detParameters;
923}
924
925//========================================================================================================
927 std::unique_ptr<Trk::TrackParameters> trackParam,
928 const Trk::PropDirection direction, std::vector<GasGapResult>& results,
929 BarrelDL barrelDL) const {
930 /*
931 get intersections of the muon with the RPC planes
932
933 Iterate over all valid RPCDetectorElements and RPCReadoutElements:
934 1) compute DR distance between track and center of ReadoutElement
935 if this distance within tolerance - proceed
936 2) Next, compute:
937 -- min DR distance between track and strips within this gas gap
938 -- number of valid eta and phi strips within this gas gap
939 if both results within their tolerances - proceed
940 3) Extrapolate track to the surface of this gas gap:
941 -- Check that extrapolation result valid
942 -- Check that extrapolated position is in the gas gap surface bounds
943 if both within checks valid - then save RPC extrapolation result
944 */
945 int doubletR = 1;
946 if (barrelDL >= OUT) {
947 return StatusCode::SUCCESS;
948 } else if (barrelDL == BM2 || barrelDL == BO2) {
949 doubletR = 2;
950 }
951
952 using namespace Monitored;
953 auto tool = getGroup(m_packageName);
954
955 if (!trackParam) {
956 return StatusCode::FAILURE;
957 }
958
959 std::map<BarrelDL, std::vector<int>>::const_iterator dl_vec_it =
960 m_StationNames.find(barrelDL);
961 if (dl_vec_it == m_StationNames.end()) {
962 return StatusCode::FAILURE;
963 }
964
965 std::unique_ptr<Trk::TrackParameters> trackParamLayer{};
966 double minDR = 1.0; // A intial value
967
968 const std::vector<int> dl_vec = dl_vec_it->second;
969
970 std::vector<int>::const_iterator it_dl = dl_vec.begin();
971 for (; it_dl != dl_vec.end(); ++it_dl) {
972 int stName = *it_dl;
973 std::pair<int, int> st_dbR = std::make_pair(stName, doubletR);
974 std::map<std::pair<int, int>,
975 std::vector<std::shared_ptr<GasGapData>>>::const_iterator
976 gasgapIt = m_gasGapData.find(st_dbR);
977
978 if (gasgapIt == m_gasGapData.end()) {
979 continue;
980 }
981
982 //
983 // Iterate over RPC readout elements and compute intersections with each
984 // gas gap
985 //
986 for (const std::shared_ptr<GasGapData>& gap : gasgapIt->second) {
987 ExResult result(gap->gapid, direction);
988
989 // Compute track distance to the gas gap surface; doesnt take
990 // ownership
991 gap->computeTrackDistanceToGasGap(result, trackParam.get());
992
993 if (result.minTrackGasGapDR > m_minDRTrackToGasGap) {
994 continue;
995 }
996
997 //
998 // Extrapolate track to the gas gap surface and check whether the
999 // track position is in bounds; doesnt take ownership but returns a
1000 // new object
1001 auto trackParamInGap = computeTrackIntersectionWithGasGap(
1002 result, trackParam.get(), gap);
1003 if (trackParamInGap == nullptr) {
1004 continue;
1005 }
1006
1007 if (!result.localTrackPosInBoundsTight) {
1008 continue;
1009 }
1010
1011 ATH_MSG_DEBUG(name() << " extrapolated gasgap: " << gap->gapid_str);
1012
1013 if (result.minTrackGasGapDR < minDR) {
1014 minDR = result.minTrackGasGapDR;
1015 // previously created trackParamInGap moved to trackParamLayer;
1016 // previous trackParamLayer deleted
1017 trackParamLayer = std::move(trackParamInGap);
1018 }
1019
1020 results.push_back(std::make_pair(result, gap));
1021 }
1022 }
1023
1024 if (trackParamLayer == nullptr) {
1025 trackParamLayer = std::move(trackParam);
1026 }
1027 BarrelDL nextDL = BarrelDL(barrelDL + 1);
1028 // trackParamLayer used and then goes out of scope, destroying the object
1029 return extrapolate2RPC(std::move(trackParamLayer), direction, results,
1030 nextDL);
1031}
1032
1033//========================================================================================================
1034std::unique_ptr<Trk::TrackParameters>
1036 ExResult& result, const Trk::TrackParameters* trackParam,
1037 const std::shared_ptr<GasGapData>& gap) const {
1038 const EventContext& ctx = Gaudi::Hive::currentContext();
1039 /*
1040 This function:
1041 - constructs Identifier for specific gasgap
1042 - extrapolates muon to this gas gap
1043 */
1044
1045 // Get surface of this gas gap and extrapolate track to this surface
1046 const Trk::SurfaceBounds& bounds = gap->readoutEl->bounds(gap->gapid);
1047 const Trk::PlaneSurface& gapSurface = gap->readoutEl->surface(gap->gapid);
1048 auto detParameters = m_extrapolator->extrapolate(
1049 ctx, *trackParam, gapSurface, result.direction, true, Trk::muon);
1050
1051 if (!detParameters) {
1052 return detParameters;
1053 }
1054
1055 //
1056 // Transform global extrapolated track position on surface to local
1057 // coordinates
1058 //
1059 const Amg::Vector3D local3dTrackPosition =
1060 gap->readoutEl->globalToLocalCoords(detParameters->position(),
1061 gap->gapid);
1062 const Amg::Vector2D local2dTrackPosition(local3dTrackPosition.y(),
1063 local3dTrackPosition.z());
1064
1065 //
1066 // Check if the track position on surface is within tolerable bounds
1067 //
1068 const bool inbounds =
1069 bounds.inside(local2dTrackPosition, m_boundsToleranceReadoutElement,
1071 const bool inbounds_tight = bounds.inside(
1072 local2dTrackPosition, m_boundsToleranceReadoutElementTight,
1074
1075 result.localTrackPosInBounds = inbounds;
1076 result.localTrackPosInBoundsTight = inbounds_tight;
1077 result.localPos = local3dTrackPosition;
1078 result.globalPos = detParameters->position();
1079
1080 return detParameters;
1081}
1082
1083//========================================================================================================
1084StatusCode RpcTrackAnaAlg::readHitsPerGasgap(const EventContext& ctx,
1085 std::vector<GasGapResult>& results,
1086 MuonSource muon_source) const {
1087 using namespace Monitored;
1088 auto tool = getGroup(m_packageName);
1089
1090 int lumiBlock = ctx.eventID().lumi_block();
1091
1093 const RpcIdHelper& rpcIdHelper = m_idHelperSvc->rpcIdHelper();
1094
1095 ATH_MSG_DEBUG(" RpcPrepDataContainer size = " << rpcContainer->size());
1096 ATH_MSG_DEBUG(" results size = " << results.size());
1097
1098 auto i_hitTime_sec = Scalar<int>("hitTime_sec", 0);
1099
1100 auto isOutTime_prd = Scalar<bool>("isOutTime_prd", false);
1101 auto isOutTime_onTrack = Scalar<bool>("isOutTime_prd_onTrack", false);
1102 auto i_panelIndex = Scalar<int>("panelInd_prd", -1);
1103 auto i_panelIndex_onTrack = Scalar<int>("panelInd_prd_onTrack", -1);
1104
1105 auto res_eta = Scalar<int>("residual_eta", 0);
1106 auto res_phi = Scalar<int>("residual_phi", 0);
1107 auto closest_res_eta = Scalar<int>("closest_residual_eta", 0);
1108 auto closest_res_phi = Scalar<int>("closest_residual_phi", 0);
1109
1110 auto res_panel = Scalar<int>("residual_panel", 0);
1111 auto i_panelInd_res = Scalar<int>("panelInd_res_inTime", -1);
1112
1113 for (GasGapResult& exr : results) {
1114 const std::shared_ptr<GasGapData> gap = exr.second;
1115
1116 int sector = (gap->RpcPanel_eta_phi.first->getSectorLayer()).first;
1117
1118 float clo_res_eta = 1001.; // initial value; no sense
1119 float clo_res_phi = 1001.;
1120 int NHitwithCut_perMuon_eta = 0;
1121 int NHitwithCut_perMuon_phi = 0;
1122 int NHitnoCut_perMuon_eta = 0;
1123 int NHitnoCut_perMuon_phi = 0;
1124 std::vector<const Muon::RpcPrepData*> view_hits_eta;
1125 std::vector<const Muon::RpcPrepData*> view_hits_phi;
1126
1127 // loop on RpcPrepDataCollection
1128 for (const Muon::RpcPrepDataCollection* rpcCollection : *rpcContainer) {
1129 if (!rpcCollection) {
1130 continue;
1131 }
1132
1133 // loop on RpcPrepData
1134 for (const Muon::RpcPrepData* rpcData : *rpcCollection) {
1135 if (!rpcData) {
1136 continue;
1137 }
1138
1139 const Identifier id = rpcData->identify();
1140 const int stationName = rpcIdHelper.stationName(id);
1141 const int stationEta = rpcIdHelper.stationEta(id);
1142 const int stationPhi = rpcIdHelper.stationPhi(id);
1143
1144 const int doubletR = rpcIdHelper.doubletR(id);
1145 const int doubletZ = rpcIdHelper.doubletZ(id);
1146 const int doubletPhi = rpcIdHelper.doubletPhi(id);
1147 const unsigned gasGap = rpcIdHelper.gasGap(id);
1148 const int measuresPhi = rpcIdHelper.measuresPhi(id);
1149
1150 // match hit to the gasgap
1151 if (stationName == gap->stationName &&
1152 stationPhi == gap->stationPhi &&
1153 stationEta == gap->stationEta &&
1154 doubletR == gap->doubletR && gasGap == gap->gasgap &&
1155 doubletPhi == gap->doubletPhi &&
1156 doubletZ == gap->doubletZ) {
1157
1158
1159 i_hitTime_sec = rpcData->time();
1161 "sector" + std::to_string(std::abs(sector)))],
1162 i_hitTime_sec);
1163
1164 // ---------------------------------
1165 // Calculate distance between extrapolated muon track position and hit
1166 float hit_local_x = rpcData->localPosition().x();
1167 float trackPos_localY = exr.first.localPos.y();
1168 float trackPos_localZ = exr.first.localPos.z();
1169
1170 float residual_phi = trackPos_localY-hit_local_x;
1171 float residual_eta = trackPos_localZ-hit_local_x;
1172
1173 // If hit is out-of-time
1174 bool isOutTime = (std::abs(i_hitTime_sec+50.) > m_outtime); // for run 3
1175 int i_panel = measuresPhi ? gap->RpcPanel_eta_phi.second->panel_index :
1176 gap->RpcPanel_eta_phi.first->panel_index;
1177
1178 // Fill histograms of out-of-time hit fraction
1179 if (muon_source == ZCand) {
1180
1181 isOutTime_prd = isOutTime;
1182 isOutTime_onTrack = isOutTime;
1183
1184 if (measuresPhi) {
1185 i_panelIndex = i_panel;
1186 fill(tool, i_panelIndex, isOutTime_prd);
1187 if (std::abs(residual_phi) < m_diffHitTrackPostion) {
1188 i_panelIndex_onTrack = i_panel;
1189 fill(tool, i_panelIndex_onTrack, isOutTime_onTrack);
1190 }
1191 } else {
1192 i_panelIndex = i_panel;
1193 fill(tool, i_panelIndex, isOutTime_prd);
1194 if (std::abs(residual_eta) < m_diffHitTrackPostion) {
1195 i_panelIndex_onTrack = i_panel;
1196 fill(tool, i_panelIndex_onTrack, isOutTime_onTrack);
1197 }
1198 }
1199 }
1200
1201 if (measuresPhi) {
1202 NHitnoCut_perMuon_phi++;
1203 } else {
1204 NHitnoCut_perMuon_eta++;
1205 }
1206
1207 // process hit within |time| < 12.5 ns && on Track
1208 if (isOutTime){
1209 continue;
1210 }
1211 i_panelInd_res = i_panel;
1212
1213 if (measuresPhi) {
1214 res_phi = residual_phi;
1215 res_panel = residual_phi;
1216 clo_res_phi = std::min(clo_res_phi, residual_phi);
1217
1218 fill(tool, res_phi, res_panel, i_panelInd_res);
1219
1220 if (std::abs(residual_phi) < m_diffHitTrackPostion) {
1221 NHitwithCut_perMuon_phi++;
1222 view_hits_phi.push_back(rpcData);
1223 }
1224 } else {
1225 res_eta = residual_eta;
1226 res_panel = residual_eta;
1227 clo_res_eta = std::min(clo_res_eta, residual_eta);
1228
1229 fill(tool, res_eta, res_panel, i_panelInd_res);
1230
1231 if (std::abs(residual_eta) < m_diffHitTrackPostion){
1232 NHitwithCut_perMuon_eta++;
1233 view_hits_eta.push_back(rpcData);
1234 }
1235 }
1236 }
1237 }
1238 }
1239
1240 int etaPanel_ind = -1;
1241 int phiPanel_ind = -1;
1242
1243 etaPanel_ind = gap->RpcPanel_eta_phi.first->panel_index;
1244 phiPanel_ind = gap->RpcPanel_eta_phi.second->panel_index;
1245
1246 // Declare the quantities which should be monitored
1247 if (muon_source == ZCand) {
1248 auto hitMulti_eta = Scalar<int>("hitMulti_eta", NHitwithCut_perMuon_eta);
1249 auto hitMulti_phi = Scalar<int>("hitMulti_phi", NHitwithCut_perMuon_phi);
1250 auto hitMulti = Scalar<int>("hitMulti", 0);
1251 auto i_panelIndex = Scalar<int>("panelInd_hM", -1);
1252 auto i_passExtrap = Scalar<bool>("muon_passExtrap", false);
1253 auto i_passExtrap_or = Scalar<bool>("muon_passExtrap_or", false);
1254 auto i_passExtrap_and = Scalar<bool>("muon_passExtrap_and", false);
1255 auto i_passExtrap_sig_or = Scalar<bool>("muon_passExtrap_signalhit_or", false);
1256 auto i_passExtrap_sig_and = Scalar<bool>("muon_passExtrap_signalhit_and", false);
1257 auto i_passExtrap_sig = Scalar<bool>("muon_passExtrap_signalhit", false);
1258 auto i_LB = Scalar<int>("LB_detEff", lumiBlock);
1259
1260 fill(tool, hitMulti_eta, hitMulti_phi);
1261
1262 //
1263 // Eta OR Phi panel
1264 if (NHitnoCut_perMuon_eta > 0 || NHitnoCut_perMuon_phi > 0)
1265 i_passExtrap_or = true;
1266 if (NHitwithCut_perMuon_eta > 0 || NHitwithCut_perMuon_phi > 0)
1267 i_passExtrap_sig_or = true;
1268
1269 //
1270 // Eta AND Phi panel
1271 if (NHitnoCut_perMuon_eta > 0 && NHitnoCut_perMuon_phi > 0)
1272 i_passExtrap_and = true;
1273 if (NHitwithCut_perMuon_eta > 0 && NHitwithCut_perMuon_phi > 0)
1274 i_passExtrap_sig_and = true;
1275 //
1276 // Eta panel
1277 hitMulti = NHitwithCut_perMuon_eta;
1278 i_panelIndex = etaPanel_ind;
1279
1280 if (NHitnoCut_perMuon_eta > 0)
1281 i_passExtrap = true;
1282
1283 if (NHitwithCut_perMuon_eta > 0)
1284 i_passExtrap_sig = true;
1285
1286 fill(tool, hitMulti, i_panelIndex, i_passExtrap, i_passExtrap_sig,
1287 i_passExtrap_or, i_passExtrap_and, i_passExtrap_sig_or, i_passExtrap_sig_and, i_LB);
1288 ATH_CHECK(fillClusterSize(view_hits_eta, etaPanel_ind, lumiBlock,
1289 sector, 0)); // isPhi = 0
1290
1291 if (clo_res_eta < 1000.) {
1292 closest_res_eta = clo_res_eta;
1293 fill(tool, closest_res_eta);
1294 }
1295
1296 //
1297 // Phi panel
1298 hitMulti = NHitwithCut_perMuon_phi;
1299 i_panelIndex = phiPanel_ind;
1300 if (NHitnoCut_perMuon_phi > 0)
1301 i_passExtrap = true;
1302
1303 if (NHitwithCut_perMuon_phi > 0)
1304 i_passExtrap_sig = true;
1305
1306 fill(tool, hitMulti, i_panelIndex, i_passExtrap, i_passExtrap_sig,
1307 i_passExtrap_or, i_passExtrap_and, i_passExtrap_sig_or, i_passExtrap_sig_and, i_LB);
1308 ATH_CHECK(fillClusterSize(view_hits_phi, phiPanel_ind, lumiBlock,
1309 sector, 1)); // isPhi = 1
1310
1311 if (clo_res_phi < 1000.) {
1312 closest_res_phi = clo_res_phi;
1313 fill(tool, closest_res_phi);
1314 }
1315 }
1316
1317 //
1318 // All muon
1319 //
1320 auto i_panelIndex_allMu = Scalar<int>("panelInd_hM_allMu", -1);
1321 auto i_passExtrap_allMu = Scalar<bool>("muon_passExtrap_allMu", false);
1322
1323 //
1324 // Eta panel
1325 i_panelIndex_allMu = etaPanel_ind;
1326 if (NHitwithCut_perMuon_eta > 0)
1327 i_passExtrap_allMu = true;
1328 fill(tool, i_panelIndex_allMu, i_passExtrap_allMu);
1329
1330 //
1331 // Phi panel
1332 i_panelIndex_allMu = phiPanel_ind;
1333 if (NHitwithCut_perMuon_phi > 0)
1334 i_passExtrap_allMu = true;
1335
1336 fill(tool, i_panelIndex_allMu, i_passExtrap_allMu);
1337 }
1338
1339 return StatusCode::SUCCESS;
1340}
1341
1342//==================================================================================
1344 std::vector<const Muon::RpcPrepData*>& view_hits, const int panel_index,
1345 int LB, int phiSector, int isPhi) const {
1346 using namespace Monitored;
1347
1348 auto tool = getGroup(m_packageName);
1349 auto i_LB = Scalar<int>("LB_nrpchit", LB);
1350
1351 // Make clusters from hits that are close together in space and time
1352 std::vector<const Muon::RpcPrepData*> cluster_hits;
1353 while (!view_hits.empty()) {
1354 cluster_hits.clear();
1355
1356 // Seed cluster with first (random) hit
1357 cluster_hits.push_back(view_hits.back());
1358
1359 // Erase the selected first hit from the list
1360 view_hits.pop_back();
1361
1362 // Collect all other hits which are close to the selected hit in time
1363 // and space
1364 std::vector<const Muon::RpcPrepData*>::const_iterator hit =
1365 view_hits.begin();
1366
1367 while (hit != view_hits.end()) {
1368 const Muon::RpcPrepData* hit_ptr = *hit;
1369
1370 if (IsNearbyHit(cluster_hits, hit_ptr)) {
1371 cluster_hits.push_back(*hit);
1372 view_hits.erase(hit);
1373
1374 // Start loop from the beginning since we have increased cluster
1375 // size
1376 hit = view_hits.begin();
1377 } else {
1378 ++hit;
1379 }
1380 }
1381
1382 int cluster_size = cluster_hits.size();
1383 for (int i_hit = 0; i_hit < cluster_size; i_hit++) {
1384 auto i_phiSector = Scalar<int>("PhiSector", phiSector);
1385 fill(tool, i_LB, i_phiSector);
1386 }
1387
1388 auto i_panelIndex = Scalar<int>("panelInd_clust", panel_index);
1389 auto i_clusterSize = Scalar<int>("clusterSize", cluster_size);
1390 fill(tool, i_panelIndex, i_clusterSize);
1391
1392 auto i_cs_sec = Scalar<int>("cs_sec", cluster_size);
1393 fill(m_tools[m_SectorGroup.at("sector" +
1394 std::to_string(std::abs(phiSector)))],
1395 i_cs_sec);
1396
1397 if (isPhi == 1) {
1398 auto i_clusterSize_view =
1399 Scalar<int>("clusterSize_phi", cluster_size);
1400 fill(tool, i_clusterSize_view);
1401 } else {
1402 auto i_clusterSize_view =
1403 Scalar<int>("clusterSize_eta", cluster_size);
1404 fill(tool, i_clusterSize_view);
1405 }
1406 }
1407
1408 return StatusCode::SUCCESS;
1409}
1410
1411//====================================================================================
1413 const std::vector<const Muon::RpcPrepData*>& cluster_hits,
1414 const Muon::RpcPrepData* hit) const {
1415 const RpcIdHelper& rpcIdHelper = m_idHelperSvc->rpcIdHelper();
1416
1417 // Check whether this hit is close to any hits in the cluster
1418 for (const Muon::RpcPrepData* it_hit : cluster_hits) {
1419 if (abs(rpcIdHelper.strip(it_hit->identify()) -
1420 rpcIdHelper.strip(hit->identify())) < 2 &&
1421 std::abs(it_hit->time() - hit->time()) < 6.5) {
1422 return true;
1423 }
1424 }
1425
1426 return false;
1427}
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)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Handle class for reading a decoration on an object.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
virtual StatusCode initialize() override
initialize
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
Declare a monitored scalar variable.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const RpcReadoutElement * getRpcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
int getDoubletPhi() const
return DoubletPhi value for the given readout element, be aware that one RE can contain two DoubletPh...
int getDoubletZ() const
return DoubletZ value for the given readout element
int stationEta(const Identifier &id) const
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
size_type module_hash_max() const
the maximum hash value
int stationPhi(const Identifier &id) const
int stationName(const Identifier &id) const
const_id_iterator detectorElement_end() const
Class to represent RPC measurements.
Definition RpcPrepData.h:35
float time() const
Returns the time.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
int gasGap(const Identifier &id) const override
get the hashes
int doubletPhi(const Identifier &id) const
int doubletR(const Identifier &id) const
int strip(const Identifier &id) const
bool measuresPhi(const Identifier &id) const override
int doubletZ(const Identifier &id) const
std::map< std::string, int > m_elementIndex
BooleanProperty m_TagAndProbe
StatusCode initRpcPanel()
BooleanProperty m_plotMuonEff
FloatProperty m_minDRTrackToGasGap
StatusCode fillClusterSize(std::vector< const Muon::RpcPrepData * > &view_hits, const int panel_index, int LB, int phiSector, int isPhi) const
virtual StatusCode initialize() override
initialize
std::map< std::pair< int, int >, std::vector< std::shared_ptr< GasGapData > > > m_gasGapData
FloatProperty m_l1trigMatchWindow
FloatProperty m_outtime
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beamSigmaX
FloatProperty m_muonMass
FloatProperty m_diffHitTrackPostion
std::map< std::string, int > m_SectorGroup
StatusCode fillHistPRD(const EventContext &ctx) const
StatusCode triggerMatching(const xAOD::Muon *, const std::vector< TagDef > &) const
StatusCode setPanelIndex(std::shared_ptr< RpcPanel > panel)
std::vector< TagDef > m_trigTagDefs
FloatProperty m_maxEta
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
std::pair< ExResult, const std::shared_ptr< GasGapData > > GasGapResult
FloatProperty m_trigMatchWindow
virtual ~RpcTrackAnaAlg()
StatusCode initTrigTag()
virtual StatusCode fillHistograms(const EventContext &ctx) const override
adds event to the monitoring histograms
FloatProperty m_barrelMaxEta
RpcPanelMap m_rpcPanelMap
FloatProperty m_barrelMinEta
SG::ReadHandleKey< xAOD::MuonContainer > m_MuonContainerKey
SG::ReadHandleKey< Muon::RpcPrepDataContainer > m_rpcPrdKey
StatusCode readElIndexFromXML()
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beamSigmaXY
FloatProperty m_isolationWindow
FloatProperty m_boundsToleranceReadoutElement
BooleanProperty m_plotPRD
ToolHandle< Trk::IExtrapolator > m_extrapolator
std::map< std::string, int > m_TriggerThrGroup
bool IsNearbyHit(const std::vector< const Muon::RpcPrepData * > &cluster_hits, const Muon::RpcPrepData *hit) const
FloatProperty m_minPt
StringProperty m_elementsFileName
SG::ReadDecorHandleKey< xAOD::EventInfo > m_beamSigmaY
StatusCode fillMuonExtrapolateEff(const EventContext &ctx) const
std::unique_ptr< Trk::TrackParameters > computeTrackIntersectionWithGasGap(ExResult &result, const xAOD::TrackParticle *track_particle, const std::shared_ptr< GasGapData > &gap) const
StatusCode extrapolate2RPC(const xAOD::TrackParticle *track, const Trk::PropDirection direction, std::vector< GasGapResult > &results, BarrelDL barrelDL) const
FloatProperty m_zMass_upLimit
StringProperty m_packageName
SG::ReadHandleKey< xAOD::MuonRoIContainer > m_MuonRoIContainerKey
RpcTrackAnaAlg(const std::string &name, ISvcLocator *pSvcLocator)
std::map< BarrelDL, std::vector< int > > m_StationNames
StatusCode readHitsPerGasgap(const EventContext &ctx, std::vector< GasGapResult > &results, MuonSource muon_source) const
SG::ReadHandleKey< xAOD::VertexContainer > m_PrimaryVertexContainerKey
FloatProperty m_boundsToleranceReadoutElementTight
StringProperty m_trigTagList
BooleanProperty m_useAODParticle
Handle class for reading a decoration on an object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Identifier identify() const
return the identifier
Abstract base class for surface bounds to be specified.
virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const =0
Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds.
@ Barrel
The muon candidate was detected in the barrel region.
Definition MuonRoI_v1.h:34
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
const Trk::Track * track() const
Returns a pointer (which can be NULL) to the Trk::Track which was used to make this TrackParticle.
float z() const
Returns the z position.
std::string res_panel[4][6]
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Generic monitoring tool for athena components.
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
MuonPrepDataCollection< RpcPrepData > RpcPrepDataCollection
PropDirection
PropDirection, enum for direction of the propagation.
@ anyDirection
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
Definition run.py:1
double d0significance(const xAOD::TrackParticle *tp, double d0_uncert_beam_spot_2)
@ PriVtx
Primary vertex.
MuonRoIContainer_v1 MuonRoIContainer
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
Muon_v1 Muon
Reference the current persistent version:
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
MuonRoI_v1 MuonRoI
Definition MuonRoI.h:15
TString tagTrig
Definition RPCDQUtils.h:63
TString eventTrig
Definition RPCDQUtils.h:62