ATLAS Offline Software
Loading...
Searching...
No Matches
MDTSimulation.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MDTSimulation.h"
9#include <cmath>
10
11
12namespace L0Muon {
13
15 ATH_MSG_DEBUG("Initializing " << name() << "...");
16 ATH_CHECK(m_mdtDriftCircleKey.initialize());
17 ATH_CHECK(m_barrelCandidateKey.initialize());
18 ATH_CHECK(m_regionSelector.retrieve());
19 ATH_CHECK(m_idHelperSvc.retrieve());
20 ATH_CHECK(m_calibrationTool.retrieve());
21 ATH_CHECK(m_geoCtxKey.initialize());
22
23
24 return StatusCode::SUCCESS;
25 }
26
27 StatusCode MDTSimulation::execute(const EventContext& ctx) const {
28
29 const RPCCandDataContainer* barrelCandidates{nullptr};
30 ATH_CHECK(SG::get(barrelCandidates, m_barrelCandidateKey, ctx));
31
32 const xAOD::MdtDriftCircleContainer* driftCircles{nullptr};
33 ATH_CHECK(SG::get(driftCircles, m_mdtDriftCircleKey, ctx));
34
35 const ActsTrk::GeometryContext* geoCtx{nullptr};
36 ATH_CHECK(SG::get(geoCtx, m_geoCtxKey, ctx));
37
38
39 const ActsTrk::GeometryContext& gctx = *geoCtx;
40 std::vector<float> z_positions, r_positions;
41
42 for(const auto& cand : *barrelCandidates) {
43
44 float m=0, b=0;
45 z_positions.clear();
46 r_positions.clear();
47 if (!fitRPC(*cand, m, b, z_positions, r_positions)) {
48 ATH_MSG_DEBUG("RPC fit failed for this candidate");
49 continue; // do NOT abort event
50 }
51
52
53 std::vector<const xAOD::MdtDriftCircle*> mdtHits;
54
55 ATH_CHECK(collectMDTHits(ctx, gctx, cand->eta(), cand->phi(), mdtHits, m, b));
56
57 }
58
59 return StatusCode::SUCCESS;
60 }
61
62
63 bool MDTSimulation::fitRPC(const L0Muon::RPCCandData& cand,float& m, float& b, std::vector<float>& z_positions, std::vector<float>& r_positions) const {
64
65 float theta = 2.f * std::atan(std::exp(-cand.eta()));
66 float tanTheta = std::tan(theta);
67
68 z_positions.clear();
69 r_positions.clear();
70
71
72 for (int i = 0; i < 4; ++i) {
73 const uint16_t z_bits = cand.zPos(i);
74 if (!z_bits) continue;
75 const float z_norm = static_cast<float>(z_bits) / RPCCandData::s_zPosBitRange;
76 const float z_mm = z_norm * RPCCandData::s_zPosRange;
77
78 z_positions.push_back(z_mm);
79 r_positions.push_back(z_mm * tanTheta);
80 }
81
82 size_t N = z_positions.size();
83 if (N < 1) return false; // nothing to fit
84
85 float sumZ=0, sumR=0, sumZZ=0, sumZR=0;
86 for (size_t i=0;i<N;++i) {
87 sumZ += z_positions[i];
88 sumR += r_positions[i];
89 sumZZ += z_positions[i]*z_positions[i];
90 sumZR += z_positions[i]*r_positions[i];
91 }
92
93 if (N>=2) {
94 float den = N*sumZZ - sumZ*sumZ;
95 if (den != 0) {
96 m = (N*sumZR - sumZ*sumR) / den;
97 b = (sumR - m*sumZ) / N;
98 }
99 } else {//if the RPC candidate has only one z position we provide the fit using IP
100 m = tanTheta;
101 b = 0.f;
102 }
103
104 return true;
105 }
106
107 StatusCode MDTSimulation::collectMDTHits(const EventContext& ctx, const ActsTrk::GeometryContext& gctx, float eta, float phi, std::vector<const xAOD::MdtDriftCircle*>& hits, float m, float b) const {
108
109 hits.clear();
110
111 const float dEta = 0.01f, dPhi = 0.01f;
112
113
114 RoiDescriptor roi(eta, eta-dEta, eta+dEta,
115 phi, phi-dPhi, phi+dPhi);
116 TrigRoiDescriptor trigROI(roi);
117
118
119 auto regSel = m_regionSelector->lookup(ctx);
120 if (!regSel) return StatusCode::FAILURE;
121
122 std::vector<IdentifierHash> hashList;
123 regSel->HashIDList(trigROI, hashList);
124
125
126 const xAOD::MdtDriftCircleContainer* driftCircles{};
127 ATH_CHECK(SG::get(driftCircles, m_mdtDriftCircleKey, ctx));
128
129 float windowSize = 5;
130
131 ATH_MSG_DEBUG("found n chamber hashes " << hashList.size());
133 IdContext modContext = m_idHelperSvc->mdtIdHelper().module_context();
134 for (const IdentifierHash& h : hashList) {
135 Identifier mId;
136 m_idHelperSvc->mdtIdHelper().get_id(h, mId, &modContext);
137 ATH_MSG_DEBUG("looking at chamber " << m_idHelperSvc->toString(mId));
138
139 if(!viewer.loadView(mId)){
140 continue;
141 }
142 for(const xAOD::MdtDriftCircle* dc : viewer){
143 const MuonGMR4::MdtReadoutElement* detEl = viewer.at(0)->readoutElement();
144 const float pitch = detEl->tubePitch();
145 const Amg::Transform3D& locToGlob= detEl->localToGlobalTransform(gctx,dc->measurementHash());
146 const Amg::Vector3D gpos = locToGlob* dc->localMeasurementPos() ;
147
148 float resZ = computeResidual(gpos, m, b);
149
150 if (std::abs(resZ) > windowSize * pitch) continue;
151
152 hits.push_back(dc);
153
154 }
155 }
156 return StatusCode::SUCCESS;
157 }
158
159
160
161 float MDTSimulation::computeResidual(const Amg::Vector3D& gpos, float m, float b) const {
162 float z_pred = (m!=0.f ? (gpos.perp() - b)/m : 0.f);
163 return gpos.z() - z_pred;
164 }
165
166
167
168} // namespace L0Muon
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x)
Header file for AthHistogramAlgorithm.
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
This is a "hash" representation of an Identifier.
float eta() const
get the kinematic parameters
Definition ICandData.cxx:29
virtual StatusCode initialize() override
float computeResidual(const Amg::Vector3D &gpos, float m, float b) const
virtual StatusCode execute(const EventContext &ctx) const override
ToolHandle< IRegSelTool > m_regionSelector
ToolHandle< IMdtCalibrationTool > m_calibrationTool
StatusCode collectMDTHits(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, float eta, float phi, std::vector< const xAOD::MdtDriftCircle * > &hits, float m, float b) const
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
SG::ReadHandleKey< xAOD::MdtDriftCircleContainer > m_mdtDriftCircleKey
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
bool fitRPC(const L0Muon::RPCCandData &cand, float &m, float &b, std::vector< float > &z_positions, std::vector< float > &r_positions) const
SG::ReadHandleKey< L0Muon::RPCCandDataContainer > m_barrelCandidateKey
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
float zPos(int index) const
Readout element to describe the Monitored Drift Tube (Mdt) chambers Mdt chambers usually comrpise out...
double tubePitch() const
Returns the pitch between 2 tubes in a layer.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
Describes the Region of Ineterest geometry It has basically 9 parameters.
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
bool loadView(const Identifier &chamberId)
Loads the view matching the parsed identifier.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
DataVector< RPCCandData > RPCCandDataContainer
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
@ Chamber
View ends if the moduleHash changes.
MdtDriftCircle_v1 MdtDriftCircle
MdtDriftCircleContainer_v1 MdtDriftCircleContainer