ATLAS Offline Software
Loading...
Searching...
No Matches
RPCSimulation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "RPCSimulation.h"
6
9
10
16
17#include <ranges>
18
19namespace L0Muon
20{
21
23 {
24 ATH_MSG_DEBUG("Initializing " << name() << "...");
25
26 ATH_CHECK(m_truthPartKey.initialize());
27 ATH_CHECK(m_segmentLinkKey.initialize());
28
29 ATH_CHECK(m_keyRpcRdo.initialize());
30 ATH_CHECK(m_geoCtxKey.initialize());
31 ATH_CHECK(detStore()->retrieve(m_detMgr));
32 ATH_CHECK(m_idHelperSvc.retrieve());
34 ATH_CHECK(m_outputCandKey.initialize());
35
37 if (!m_monTool.empty())
38 ATH_CHECK(m_monTool.retrieve());
39
40 return StatusCode::SUCCESS;
41 }
42
43 StatusCode RPCSimulation::execute(const EventContext &ctx) const
44 {
45 ATH_MSG_DEBUG("Executing " << name() << "...");
46
47 // output candidates container
48 SG::WriteHandle outputCands(m_outputCandKey, ctx);
49 ATH_CHECK(outputCands.record(std::make_unique<L0Muon::RPCCandDataContainer>()));
50
51 if (m_useTruth)
52 {
53 ATH_CHECK(buildFromTruth(*outputCands, ctx));
54 }
55 else if (m_usePatterns)
56 {
57 // ATH_CHECK(buildFromPatterns(outputCands, ctx));
58 }
59 else
60 {
61 ATH_MSG_ERROR("No valid option selected for building candidates.");
62 return StatusCode::FAILURE;
63 }
64
65 SG::ReadHandle inputRDO(m_keyRpcRdo, ctx);
66 ATH_CHECK(inputRDO.isPresent());
67 ATH_MSG_DEBUG("Number of RPC RDO: " << inputRDO->size());
68
70 if (!m_monTool.empty())
71 {
72 auto n_of_RDO = Monitored::Scalar<unsigned int>("n_of_RDO", inputRDO->size());
73 }
74
75 return StatusCode::SUCCESS;
76 }
77 std::vector<const xAOD::MuonSimHit*>
79 const EventContext& ctx) const {
80
82 using SegLinkVec_t = std::vector<SegLink_t>;
83
85 std::vector<const xAOD::MuonSimHit*> rpcHits{};
86
87 for (const SegLink_t& link : acc_link(truthPart)) {
88 const xAOD::MuonSegment* segment{*link};
90 continue;
91 }
92 auto simHits = MuonR4::getMatchingSimHits(*segment);
93 std::ranges::copy_if(simHits, std::back_inserter(rpcHits),
94 [this](const xAOD::MuonSimHit* hit){
95 return m_idHelperSvc->isRpc(hit->identify());
96 });
97 }
98 std::ranges::sort(rpcHits, [](const xAOD::MuonSimHit* a, const xAOD::MuonSimHit* b){
99 return a->identify() < b->identify();
100 });
101 return rpcHits;
102 }
103
105 const EventContext &ctx) const
106 {
107 const ActsTrk::GeometryContext* geoContextHandle{nullptr};
108 ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
109 const ActsTrk::GeometryContext& gctx{*geoContextHandle};
111 const RpcIdHelper& id_helper{m_idHelperSvc->rpcIdHelper()};
113 const xAOD::TruthParticleContainer *truthParticles = nullptr;
114 ATH_CHECK(SG::get(truthParticles, m_truthPartKey, ctx));
115
117 for (const xAOD::TruthParticle* truthMuon : *truthParticles) {
118 std::vector<const xAOD::MuonSimHit*> rpcHits = collectHits(*truthMuon, ctx);
119 if (rpcHits.empty()) {
120 continue;
121 }
122
123 ATH_MSG_DEBUG("Found a muon with pdgId: " << truthMuon->pdgId());
124 const auto muonP4 = truthMuon->p4();
125
126 // Create a new candidate
127 float eta = truthMuon->eta();
128 float phi = truthMuon->phi();
129 float pt = truthMuon->pt();
131 uint8_t charge = truthMuon->charge() < 0 ? 0 : 1;
132
135 uint16_t subdetectorId = eta > 0 ? 0x65 : 0x66;
136 auto cand = std::make_unique<L0Muon::RPCCandData>(subdetectorId, 0, 0);
137
138 cand->setEta(eta);
139 cand->setPhi(phi);
140 cand->setPt(pt);
141 cand->setThreshold(0);
142 cand->setCharge(charge);
143 cand->setMdtFlag(0);
144
145 std::array<float, 4> zPos{};
146 std::array<int, 4> nZPos{};
148 for (const xAOD::MuonSimHit* hit : rpcHits) {
150
151 // get the hit identifier and the strip position
152 const Identifier id = hit->identify();
153
154 const MuonGMR4::RpcReadoutElement* detEl = m_detMgr->getRpcReadoutElement(id);
155
156 float hitPosZ = detEl->stripPosition(gctx,id).z();
157 switch (m_idHelperSvc->stationIndex(id)) {
159 case BI: {
160 zPos[0] += hitPosZ;
161 ++nZPos[0];
162 break;
163 } case BM: {
164 const int dR = id_helper.doubletR(id);
165 zPos[dR] += hitPosZ;
166 ++nZPos[dR];
167 break;
168 } case BO: {
169 zPos[3] += hitPosZ;
170 ++nZPos[3];
171 break;
172 } default :{
173 ATH_MSG_WARNING("Unknown RPC station: " << m_idHelperSvc->toString(hit->identify()));
174 break;
175 }
176 }
177 }
178 // Set the Z positions in the candidate
179 for (int i = 0; i < 4; ++i) {
180 if (nZPos[i] > 0) {
181 zPos[i] = std::abs(zPos[i]); // Use absolute value for Z position
182 zPos[i] /= nZPos[i];
183 // Normalize the Z position to the range of 12 bits
184 // The range is from 0 to +12500, so we map it to 0-4095
185 cand->setZPos(static_cast<uint16_t>(zPos[i]/
187 }
188 }
189 cand->setQuality(L0Muon::RPCCandData::Quality::Q_BEST);
190 outputCands.push_back(std::move(cand));
191 }
192 // Implementation of building candidates from truth
193 return StatusCode::SUCCESS;
194 }
195
196
197} // end of namespace
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_WARNING(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
ATLAS-specific HepMC functions.
static Double_t a
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
const ServiceHandle< StoreGateSvc > & detStore() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
static constexpr float s_zPosRange
range of the RPC hits z positions
Definition RPCCandData.h:37
static constexpr uint16_t s_zPosBitRange
12 bits for z position
Definition RPCCandData.h:41
StatusCode buildFromTruth(L0Muon::RPCCandDataContainer &outputCands, const EventContext &ctx) const
build the candidates from the MC truth
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthPartKey
truth containers
virtual StatusCode initialize() override
Gaudi::Property< bool > m_usePatterns
Gaudi::Property< bool > m_useTruth
configuration options
std::vector< const xAOD::MuonSimHit * > collectHits(const xAOD::TruthParticle &truthPart, const EventContext &ctx) const
SG::WriteHandleKey< L0Muon::RPCCandDataContainer > m_outputCandKey
Output Trigger candidates.
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_segmentLinkKey
SG::ReadHandleKey< xAOD::NRPCRDOContainer > m_keyRpcRdo
RPC Rdo.
const MuonGMR4::MuonDetectorManager * m_detMgr
ToolHandle< GenericMonitoringTool > m_monTool
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
helper service
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
virtual StatusCode execute(const EventContext &ctx) const override
Declare a monitored scalar variable.
Amg::Vector3D stripPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
int doubletR(const Identifier &id) const
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced object present in SG?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
::Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index.
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
DataVector< RPCCandData > RPCCandDataContainer
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
StIndex
enum to classify the different station layers in the muon spectrometer
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
TruthParticle_v1 TruthParticle
Typedef to implementation.
MuonSegment_v1 MuonSegment
Reference the current persistent version:
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.