ATLAS Offline Software
Loading...
Searching...
No Matches
SimpleMMClusterBuilderTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
8
9#define DEFINE_VECTOR(dType, varName, nEles) \
10 std::vector<dType> varName{}; \
11 varName.reserve(nEles);
12
13namespace Muon{
14
16
18 ATH_CHECK(m_idHelperSvc.retrieve());
19 ATH_CHECK(m_uncertCalibKey.initialize());
20 return StatusCode::SUCCESS;
21}
22
23StatusCode SimpleMMClusterBuilderTool::getClusters(const EventContext& ctx,
24 std::vector<MMPrepData>&& MMprds,
25 std::vector<std::unique_ptr<MMPrepData>>& clustersVect) const {
26 ATH_MSG_DEBUG("Size of the input vector: " << MMprds.size());
27 ATH_MSG_DEBUG("Size of the output vector: " << clustersVect.size());
28
29 if (MMprds.empty()) {
30 ATH_MSG_DEBUG("Empty PRD collection: no clusterization");
31 return StatusCode::SUCCESS;
32 }
33 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
34 std::ranges::sort(MMprds,
35 [&](const MMPrepData& a, const MMPrepData& b){
36 const Identifier ida{a.identify()};
37 const Identifier idb{b.identify()};
38 const int mla = idHelper.multilayer(ida);
39 const int mlb = idHelper.multilayer(idb);
40 if (mla!=mlb) {
41 return mla < mlb;
42 }
43 const int gga = idHelper.gasGap(ida);
44 const int ggb = idHelper.gasGap(idb);
45 if (gga!=ggb) {
46 return gga < ggb;
47 }
48 return idHelper.channel(ida) < idHelper.channel(idb);
49 });
50
51
52 const IdentifierHash hash = MMprds.at(0).collectionHash();
53 const unsigned int n_input_prds = MMprds.size();
54 for (unsigned int mergeI = 0; mergeI < n_input_prds; ) {
55 const MMPrepData& primary_prd = MMprds[mergeI];
56 const Identifier id_prd = primary_prd.identify();
57 const Identifier gasGapId = m_idHelperSvc->gasGapId(id_prd);
58
59 ATH_MSG_VERBOSE(" PrepData "<<m_idHelperSvc->toString(id_prd)<<" index: "<<mergeI<< " / " << n_input_prds
60 << " z " << primary_prd.globalPosition().z());
62 unsigned mergeJ{mergeI+1};
63
64 while (mergeJ < n_input_prds &&
65 gasGapId == m_idHelperSvc->gasGapId(MMprds[mergeJ].identify()) &&
66 std::abs(idHelper.channel(MMprds[mergeJ].identify()) -
67 idHelper.channel(MMprds[mergeJ -1].identify()) ) <= static_cast<int>(m_maxHoleSize) + 1) {
68 ++mergeJ;
69 }
70 unsigned int clustSize = mergeJ - mergeI;
71 if (clustSize > m_maxClusSize) {
72 mergeI = mergeJ;
73 continue;
74 }
75 DEFINE_VECTOR(uint16_t, mergeStrips, clustSize);
76 DEFINE_VECTOR(Identifier, rdoList, clustSize);
77 DEFINE_VECTOR(short int, mergeStripsTime, clustSize);
78 DEFINE_VECTOR(int, mergeStripsCharge, clustSize);
79 DEFINE_VECTOR(float, mergeStripsDriftDists, clustSize);
80 DEFINE_VECTOR(AmgVector(2), mergeStripsDriftDistErrors, clustSize);
81 double totalCharge{0.0};
83 for (unsigned int mergeMe = mergeI; mergeMe < mergeJ; ++mergeMe) {
84 const MMPrepData& mergePrd = MMprds[mergeMe];
85 const Identifier mergedId = mergePrd.identify();
86 rdoList.push_back(mergedId);
87 mergeStrips.push_back(idHelper.channel(mergedId));
88 mergeStripsTime.push_back(mergePrd.time());
89 mergeStripsCharge.push_back(mergePrd.charge());
90 mergeStripsDriftDists.push_back(mergePrd.driftDist());
91 const Amg::MatrixX& cov{mergePrd.localCovariance()};
92 mergeStripsDriftDistErrors.emplace_back(cov(0,0), cov(1,1));
93
94 totalCharge += mergePrd.charge();
95 }
96
97 ATH_MSG_VERBOSE(" add merged MMprds nmerge " << clustSize );
98
99
100
101 // start off from strip in the middle
102 unsigned int stripSum = 0;
103 for (unsigned short strip : mergeStrips) stripSum += strip;
104 stripSum /= mergeStrips.size();
105
106 unsigned int centralIdx{mergeI};
107 for (unsigned int k = 0; k < mergeStrips.size(); ++k) {
108 ++centralIdx;
109 if (mergeStrips[k] == stripSum) break;
110 }
111 const Identifier clusterId = MMprds[centralIdx < mergeJ ? centralIdx : mergeI].identify();
112 ATH_MSG_VERBOSE(" Look for strip nr " << stripSum << " found at index " << centralIdx);
113
117
118 DEFINE_VECTOR(MMPrepData, stripsVec, clustSize);
119
120 stripsVec.insert(stripsVec.begin(),std::make_move_iterator(MMprds.begin() + mergeI),
121 std::make_move_iterator(MMprds.begin() + mergeJ));
122
124 mergeI = mergeJ;
125 Amg::MatrixX covMatrix(1,1);
126 Amg::Vector2D clusterLocalPosition{Amg::Vector2D::Zero()};
127 ATH_CHECK(getClusterPosition(ctx, clusterId, stripsVec, clusterLocalPosition, covMatrix));
128
132 if (!m_writeStripProperties) mergeStrips.clear();
133 std::unique_ptr<MMPrepData> prdN = std::make_unique<MMPrepData>(clusterId,
134 hash,
135 std::move(clusterLocalPosition),
136 std::move(rdoList),
137 std::move(covMatrix),
138 stripsVec.front().detectorElement(),
139 0,
140 totalCharge,
141 0.f,
142 std::move(mergeStrips),
143 std::move(mergeStripsTime),
144 std::move(mergeStripsCharge));
145
146 prdN->setDriftDist(std::move(mergeStripsDriftDists), std::move(mergeStripsDriftDistErrors));
148 clustersVect.push_back(std::move(prdN));
149 } // end loop MMprds[i]
150 return StatusCode::SUCCESS;
151}
152
154StatusCode SimpleMMClusterBuilderTool::getClusterPosition(const EventContext& ctx,
155 const Identifier& clustId,
156 std::vector<MMPrepData>& stripsVec,
157 Amg::Vector2D& clusterLocalPosition,
158 Amg::MatrixX& covMatrix) const {
159
161 if (!errorCalibDB.isValid()) {
162 ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
163 return StatusCode::FAILURE;
164 }
165 covMatrix.setIdentity();
166 double weightedPosX{0.}, posY{0.}, totalCharge{0.};
167 Amg::Vector3D clusDir{Amg::Vector3D::Zero()};
168
170 posY = stripsVec[0].localPosition().y();
171 for (const MMPrepData& strip : stripsVec) {
172 const double posX = strip.localPosition().x();
173 const double charge = strip.charge();
174 weightedPosX += posX * charge;
175 totalCharge += charge;
177 clusDir+= charge * lDir;
178 ATH_MSG_VERBOSE("Adding a strip to the centroid calculation "<<m_idHelperSvc->toString(strip.identify())
179 <<", charge=" << charge<<" global position: "<<Amg::toString(strip.globalPosition(), 2)
180 <<", theta: "<<strip.globalPosition().theta()
181 <<", eta: "<<strip.globalPosition().eta()
182 <<", phi: "<<strip.globalPosition().phi()
183 <<" -- local direction theta: "<<lDir.theta()<<", eta: "<<lDir.eta()
184 <<", phi: "<<lDir.phi());
185 }
186 weightedPosX = weightedPosX / totalCharge;
187 clusterLocalPosition = Amg::Vector2D(weightedPosX, posY);
188
189 NswErrorCalibData::Input errorCalibIn{};
190 errorCalibIn.stripId = clustId;
191 errorCalibIn.clusterAuthor = static_cast<unsigned>(MMPrepData::Author::SimpleClusterBuilder);
192 errorCalibIn.locPhi = clusDir.phi();
193 errorCalibIn.locTheta = clusDir.theta();
194 errorCalibIn.localPos = clusterLocalPosition;
195 errorCalibIn.clusterSize = stripsVec.size();
196
197 ATH_MSG_VERBOSE(m_idHelperSvc->toString(clustId)<< " - local track direction: "<<errorCalibIn.locTheta);
198
199 const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
200 covMatrix(0, 0) = localUncertainty * localUncertainty;
201 return StatusCode::SUCCESS;
202}
203
205 const std::vector<NSWCalib::CalibratedStrip>& calibratedStrips,
206 const Amg::Vector3D& dirEstimate,
207 Amg::Vector2D& clusterLocalPosition,
208 Amg::MatrixX& covMatrix) const {
210 double xPosCalib{0.}, totalCharge{0.};
211 for (const NSWCalib::CalibratedStrip& it : calibratedStrips) {
212 xPosCalib += it.charge * it.dx;
213 totalCharge += it.charge;
214 }
215 if (std::abs(totalCharge) < std::numeric_limits<float>::epsilon()) {
216 return RIO_Author::unKnownAuthor;
217 }
218
219 xPosCalib /= totalCharge;
220
221 ATH_MSG_DEBUG("position before calibration and correction: " << clusterLocalPosition[Trk::locX] << " " << xPosCalib);
222
223 clusterLocalPosition[Trk::locX] = clusterLocalPosition[Trk::locX] + xPosCalib;
225 if (!errorCalibDB.isValid()) {
226 ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
227 return RIO_Author::unKnownAuthor;
228 }
229
230 NswErrorCalibData::Input errorCalibIn{};
231 errorCalibIn.clusterSize = calibratedStrips.size();
232 errorCalibIn.clusterAuthor = RIO_Author::SimpleClusterBuilder;
233 errorCalibIn.locPhi = dirEstimate.phi();
234 errorCalibIn.locTheta = dirEstimate.theta();
235 errorCalibIn.localPos = clusterLocalPosition;
236 errorCalibIn.stripId = calibratedStrips[errorCalibIn.clusterSize/2].identifier;
237
238 const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
239
240 covMatrix(0, 0) = localUncertainty * localUncertainty;
241
242
243 return RIO_Author::SimpleClusterBuilder;
244}
245}
246#undef DEFINE_VECTOR
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
double charge(const T &p)
Definition AtlasPID.h:997
#define DEFINE_VECTOR(dType, varName, nEles)
#define AmgVector(rows)
static Double_t a
This is a "hash" representation of an Identifier.
int channel(const Identifier &id) const override
int gasGap(const Identifier &id) const override
get the hashes
int multilayer(const Identifier &id) const
MMClusterOnTrack::Author RIO_Author
Refinement of the cluster position after the cluster calibration loop is ran with a complete external...
Class to represent MM measurements.
Definition MMPrepData.h:22
float driftDist() const
Returns the Drift Distance.
Definition MMPrepData.h:232
short int time() const
Returns the time (in ns)
Definition MMPrepData.h:222
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
Definition MMPrepData.h:211
int charge() const
Returns the AD.
Definition MMPrepData.h:227
StatusCode getClusters(const EventContext &ctx, std::vector< Muon::MMPrepData > &&stripsVect, std::vector< std::unique_ptr< Muon::MMPrepData > > &clustersVect) const override
StatusCode getClusterPosition(const EventContext &ctx, const Identifier &clustId, std::vector< Muon::MMPrepData > &stripsVect, Amg::Vector2D &clusterLocalPosition, Amg::MatrixX &covMatrix) const
get cluster local position and covariance matrix
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::ReadCondHandleKey< NswErrorCalibData > m_uncertCalibKey
RIO_Author getCalibratedClusterPosition(const EventContext &ctx, const std::vector< NSWCalib::CalibratedStrip > &calibratedStrips, const Amg::Vector3D &directionEstimate, Amg::Vector2D &clusterLocalPosition, Amg::MatrixX &covMatrix) const override
Gaudi::Property< unsigned int > m_maxClusSize
Identifier identify() const
return the identifier
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Vector3D toLocal(const Amg::Transform3D &toLocalTrans, const Amg::Vector3D &dir)
Rotates a direction vector into a local frame: x-axis : Parallell to the radial direction of the dete...
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
IMMClusterBuilderTool::RIO_Author RIO_Author
@ locX
Definition ParamDefs.h:37
Helper struct to be parsed to the object to derive the specific error of the cluster.
unsigned int clusterSize
Cluster size.
double locTheta
Direction of the muon in the local coordinate frame.
Amg::Vector2D localPos
Local position on the surface.
Identifier stripId
Identifier of the strip.
uint8_t clusterAuthor
Author of the cluster.
double locPhi
Azimuthal angle in the local frame.