ATLAS Offline Software
Loading...
Searching...
No Matches
L0MuonSmearingAlg.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#include "L0MuonSmearingAlg.h"
6
8
9#include "TruthTrackSmearer.h"
10
11#include "TH1.h"
12
13namespace L0Muon {
14
15L0MuonSmearingAlg::L0MuonSmearingAlg(const std::string& name, ISvcLocator* pSvcLocator)
16: AthReentrantAlgorithm(name, pSvcLocator) {}
17
18
20
21
23 ATH_MSG_INFO("Initializing " << name() << "...");
24
26 ATH_CHECK(m_outputMuonRoIKey.initialize());
27
28 ATH_CHECK(m_rndmSvc.retrieve());
29
30 ATH_MSG_INFO("########## L0MuonSmearingAlg Configurations are ########## ");
31 ATH_MSG_INFO("------- InputTruthParticleKey: " << m_inputTruthParticleKey.key());
32 ATH_MSG_INFO("------- OutputMuonRoIKey: "<< m_outputMuonRoIKey.key());
33 ATH_MSG_INFO("########## L0MuonSmearingAlg Configurations: That's it. ########## ");
34
35 // configure the Smearer
36 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this);
37 m_mySmearer = std::make_unique<TruthTrackSmearer>(rngWrapper);
38
39 if (!m_monTool.empty()) ATH_CHECK(m_monTool.retrieve());
40 return StatusCode::SUCCESS;
41}
42
43
45 ATH_MSG_INFO ("Finalizing " << name() << "...");
46 return StatusCode::SUCCESS;
47}
48
49
50StatusCode L0MuonSmearingAlg::execute(const EventContext& ctx) const {
51 ATH_MSG_DEBUG ("Executing " << name() << "...");
52
54 const xAOD::TruthParticleContainer* inputTruth = inputTruth_handle.cptr();
55 if (not inputTruth) {
56 ATH_MSG_FATAL("Unable to retrieve input truth particle of " << m_inputTruthParticleKey.key());
57 return StatusCode::FAILURE;
58 }
59
61 ATH_CHECK(outputRoI_handle.record(std::make_unique<xAOD::MuonRoIContainer>(), std::make_unique<xAOD::MuonRoIAuxContainer>()));
62 auto outputRoIs = outputRoI_handle.ptr();
63
64 int n_input_tracks=0;
65 int n_output_tracks=0;
66 ATH_MSG_DEBUG("Found " << inputTruth->size() << " input truth particles of " << m_inputTruthParticleKey.key());
67
68 for (const auto* part : *inputTruth) {
69 // only muon is used
70 if (part->pdgId() != 13 && part->pdgId() != -13) continue;
71 // Minimum pT cut for 2 GeV
72 if (part->pt() < 2000.) continue; // MeV
73 // only undecayed physical particle
74 if (part->status() != 1) continue;
75 // eta within 3.0
76 if (std::abs(part->eta()) > 3.0) continue;
77
78 ATH_MSG_DEBUG("New Truth Muon: phi=" << part->phi()
79 << " eta=" << part->eta()
80 << " pT=" << part->pt() / 1000.
81 << "(GeV) q/pT=" << part->charge() * 1000. / part->pt()
82 << "(1/GeV) PDGID=" << part->pdgId()
83 << " status=" << part->status());
84 n_input_tracks++;
85
86 if (!m_monTool.empty()) {
87 auto track_input_eta = Monitored::Scalar<float>("track_input_eta", part->eta());
88 auto track_input_pt = Monitored::Scalar<float>("track_input_pt", part->pt() / 1000.);
89 auto track_input_phi = Monitored::Scalar<float>("track_input_phi", part->phi());
90 auto track_input_curv = Monitored::Scalar<float>("track_input_curv", part->charge() * 1000. / part->pt());
91 auto monitorIt = Monitored::Group(m_monTool, track_input_eta, track_input_pt, track_input_phi, track_input_curv);
92 }
93
94 float qoverPt = part->charge() / part->pt(); // in MeV
95 L0MuonTrack otrack;
96 if (m_mySmearer->emulateL0MuonTrack(qoverPt, part->eta(), part->phi(), otrack) == false) { // smearing here
97 ATH_MSG_DEBUG("Killed by the efficiency: q/pt=" << qoverPt * 1000. << " (1/GeV)");
98 continue; // false means the truth muon is killed by the emulated efficiency
99 }
100
101 n_output_tracks++;
102
103 ATH_MSG_DEBUG("L0Muon Track: phi=" << otrack.phi()
104 << " eta=" << otrack.eta()
105 << " pT=" << 1. / std::abs(otrack.invpt() * 1000.)
106 << "(GeV) q/pT=" << 1000. * otrack.invpt() << "(1/GeV)");
107
108 if (!m_monTool.empty()) {
109 auto track_output_eta = Monitored::Scalar<float>("track_output_eta", otrack.eta());
110 auto track_output_pt = Monitored::Scalar<float>("track_output_pt", 1./ std::abs(otrack.invpt() * 1000.));
111 auto track_output_phi = Monitored::Scalar<float>("track_output_phi", otrack.phi());
112 auto track_output_curv = Monitored::Scalar<float>("track_output_curv", otrack.invpt() * 1000.);
113 auto monitorIt = Monitored::Group(m_monTool, track_output_eta, track_output_pt, track_output_phi, track_output_curv);
114 }
115
116 // RoI creation
117 outputRoIs->push_back(std::make_unique<xAOD::MuonRoI>());
118
119 // To fill RoI contents, below converts from floating to bit-wise values.
120 static constexpr float PHI_ROISIZE = TMath::TwoPi() / static_cast<float>(xAOD::MuonRoI::PHI_MASK); // phi divided by 9 bits
121 static constexpr float ETA_ROISIZE = 5.4 / static_cast<float>(xAOD::MuonRoI::ETA_MASK); // eta divided by 14 bits
122 static constexpr float PT_ROISIZE = 127.5 / static_cast<float>(xAOD::MuonRoI::PT_MASK); // 0.5 GeV width for 0-128 GeV (8 bits)
123
124 uint32_t phiword = uint32_t((otrack.phi()+TMath::Pi()) / PHI_ROISIZE); // phi defined from 0 to 2pi in MuonRoI, instead of -pi to pi
125 uint32_t etaword = uint32_t((otrack.eta() + 2.7) / ETA_ROISIZE); // -2.7 to 2.7 in MuonRoI.
126 uint32_t ptword = static_cast<uint32_t>(1. / std::abs(otrack.invpt() * 1000.) / PT_ROISIZE);
127 if (ptword > 0xff) ptword = 0xff;
128
129 // to still input eta and phi for initialize, not calculated from RoIword
130 float roi_eta = etaword * ETA_ROISIZE - 2.7;
131 float roi_phi = phiword * PHI_ROISIZE - TMath::Pi();
132
133 // construct roiWord (23th bit is charge information.)
134 uint32_t roiword = (ptword<<24) | ((otrack.invpt() > 0)<<23) | (phiword<<14) | etaword;
135
136 uint32_t extraword = (static_cast<uint32_t>(0x1)<<31) | (((ptword>>1) + 0x2) & 0xf); // for the time being...
137
138 std::string emu_thr_name = "L0_MUx";
139 float thrvalue = static_cast<float>(((ptword>>1) + 0x2) & 0xf);
140 outputRoIs->back()->initialize(roiword, roi_eta, roi_phi, emu_thr_name, thrvalue, extraword);
141
142 ATH_MSG_DEBUG("L0MuonRoI: phi = " << roi_phi << " (0x" << std::hex << phiword << std::dec << "), "
143 << "eta = " << roi_eta << " (0x" << std::hex << etaword << std::dec << "), "
144 << "pT = " << outputRoIs->back()->pt() << " (GeV) (0x" << std::hex << ptword << std::dec << "), "
145 << "q/pT= " << ((otrack.invpt() > 0) ? 1. : -1.) / outputRoIs->back()->pt());
146
147 if (!m_monTool.empty()) {
148 auto roi_output_eta = Monitored::Scalar<float>("roi_output_eta", outputRoIs->back()->eta());
149 auto roi_output_phi = Monitored::Scalar<float>("roi_output_phi", outputRoIs->back()->phi());
150 auto roi_output_pt = Monitored::Scalar<float>("roi_output_pt", outputRoIs->back()->pt());
151 auto roi_output_curv = Monitored::Scalar<float>("roi_output_curv", (outputRoIs->back()->getCharge() > 0 ? 1. : -1.)/outputRoIs->back()->pt());
152
153 auto delta_eta = Monitored::Scalar<float>("delta_eta", outputRoIs->back()->eta() - part->eta());
154 auto delta_phi = Monitored::Scalar<float>("delta_phi", TVector2::Phi_mpi_pi(outputRoIs->back()->phi() - (part->phi())));
155 auto delta_pt = Monitored::Scalar<float>("delta_pt", (outputRoIs->back()->pt() - part->pt()/1000.) / (part->pt()/1000.));
156 auto delta_curv = Monitored::Scalar<float>("delta_curv", ((outputRoIs->back()->getCharge() == 1 ? 1. : -1.)/outputRoIs->back()->pt() - (part->charge()*1000./part->pt())) / (part->charge()*1000./part->pt()));
157
158 auto monitorIt = Monitored::Group(m_monTool, roi_output_eta, roi_output_pt, roi_output_phi, roi_output_curv,
159 delta_eta, delta_phi, delta_pt, delta_curv);
160 }
161 }
162
163 ATH_MSG_DEBUG ("Result: Number of input truth muons= " << n_input_tracks << " , smeared tracks= "<< n_output_tracks);
164
165 return StatusCode::SUCCESS;
166}
167
168
169} // end of namespace
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
An algorithm that can be simultaneously executed in multiple threads.
size_type size() const noexcept
Returns the number of elements in the collection.
SG::WriteHandleKey< xAOD::MuonRoIContainer > m_outputMuonRoIKey
std::unique_ptr< TruthTrackSmearer > m_mySmearer
ToolHandle< GenericMonitoringTool > m_monTool
virtual StatusCode execute(const EventContext &ctx) const override
virtual StatusCode initialize() override
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number generator engine.
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_inputTruthParticleKey
virtual StatusCode finalize() override
L0MuonSmearingAlg(const std::string &name, ISvcLocator *pSvcLocator)
float phi() const
Definition L0MuonTrack.h:20
double invpt() const
Definition L0MuonTrack.h:18
float eta() const
Definition L0MuonTrack.h:19
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
pointer_type ptr()
Dereference the pointer.
static constexpr uint32_t ETA_MASK
constants to decode RoI word for Run 4+
Definition MuonRoI_v1.h:147
static constexpr uint32_t PT_MASK
Definition MuonRoI_v1.h:149
static constexpr uint32_t PHI_MASK
Definition MuonRoI_v1.h:148
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.