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
16SimpleMMClusterBuilderTool::SimpleMMClusterBuilderTool(const std::string& t, const std::string& n, const IInterface* p) :
17 AthAlgTool(t, n, p) {
18 declareInterface<IMMClusterBuilderTool>(this);
19}
20
22 ATH_CHECK(m_idHelperSvc.retrieve());
23 ATH_CHECK(m_uncertCalibKey.initialize());
24 return StatusCode::SUCCESS;
25}
26
27StatusCode SimpleMMClusterBuilderTool::getClusters(const EventContext& ctx,
28 std::vector<MMPrepData>&& MMprds,
29 std::vector<std::unique_ptr<MMPrepData>>& clustersVect) const {
30 ATH_MSG_DEBUG("Size of the input vector: " << MMprds.size());
31 ATH_MSG_DEBUG("Size of the output vector: " << clustersVect.size());
32
33 if (MMprds.empty()) {
34 ATH_MSG_DEBUG("Empty PRD collection: no clusterization");
35 return StatusCode::SUCCESS;
36 }
37 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
38 std::sort(MMprds.begin(), MMprds.end(),
39 [&](const MMPrepData& a, const MMPrepData& b){
40 const Identifier ida = a.identify(), idb = b.identify();
41 const int mla = idHelper.multilayer(ida);
42 const int mlb = idHelper.multilayer(idb);
43 if (mla!=mlb) return mla<mlb;
44 const int gga = idHelper.gasGap(ida);
45 const int ggb = idHelper.gasGap(idb);
46 if (gga!=ggb) return gga<ggb;
47 return idHelper.channel(ida) < idHelper.channel(idb);
48 });
49
50
51 const IdentifierHash hash = MMprds.at(0).collectionHash();
52 const unsigned int n_input_prds = MMprds.size();
53 for (unsigned int mergeI = 0; mergeI < n_input_prds; ) {
54 const MMPrepData& primary_prd = MMprds[mergeI];
55 const Identifier id_prd = primary_prd.identify();
56 const Identifier gasGapId = m_idHelperSvc->gasGapId(id_prd);
57
58 ATH_MSG_VERBOSE(" PrepData "<<m_idHelperSvc->toString(id_prd)<<" index: "<<mergeI<< " / " << n_input_prds
59 << " z " << primary_prd.globalPosition().z());
61 unsigned mergeJ{mergeI+1};
62
63 while (mergeJ < n_input_prds &&
64 gasGapId == m_idHelperSvc->gasGapId(MMprds[mergeJ].identify()) &&
65 std::abs(idHelper.channel(MMprds[mergeJ].identify()) -
66 idHelper.channel(MMprds[mergeJ -1].identify()) ) <= static_cast<int>(m_maxHoleSize) + 1) {
67 ++mergeJ;
68 }
69 unsigned int clustSize = mergeJ - mergeI;
70 if (clustSize > m_maxClusSize) {
71 mergeI = mergeJ;
72 continue;
73 }
74 DEFINE_VECTOR(uint16_t, mergeStrips, clustSize);
75 DEFINE_VECTOR(Identifier, rdoList, clustSize);
76 DEFINE_VECTOR(short int, mergeStripsTime, clustSize);
77 DEFINE_VECTOR(int, mergeStripsCharge, clustSize);
78 DEFINE_VECTOR(float, mergeStripsDriftDists, clustSize);
79 DEFINE_VECTOR(AmgVector(2), mergeStripsDriftDistErrors, clustSize);
80 double totalCharge{0.0};
82 for (unsigned int mergeMe = mergeI; mergeMe < mergeJ; ++mergeMe) {
83 const MMPrepData& mergePrd = MMprds[mergeMe];
84 const Identifier mergedId = mergePrd.identify();
85 rdoList.push_back(mergedId);
86 mergeStrips.push_back(idHelper.channel(mergedId));
87 mergeStripsTime.push_back(mergePrd.time());
88 mergeStripsCharge.push_back(mergePrd.charge());
89 mergeStripsDriftDists.push_back(mergePrd.driftDist());
90 const Amg::MatrixX& cov{mergePrd.localCovariance()};
91 mergeStripsDriftDistErrors.emplace_back(cov(0,0), cov(1,1));
92
93 totalCharge += mergePrd.charge();
94 }
95
96 ATH_MSG_VERBOSE(" add merged MMprds nmerge " << clustSize );
97
98
99
100 // start off from strip in the middle
101 unsigned int stripSum = 0;
102 for (unsigned short strip : mergeStrips) stripSum += strip;
103 stripSum /= mergeStrips.size();
104
105 unsigned int centralIdx{mergeI};
106 for (unsigned int k = 0; k < mergeStrips.size(); ++k) {
107 ++centralIdx;
108 if (mergeStrips[k] == stripSum) break;
109 }
110 const Identifier clusterId = MMprds[centralIdx < mergeJ ? centralIdx : mergeI].identify();
111 ATH_MSG_VERBOSE(" Look for strip nr " << stripSum << " found at index " << centralIdx);
112
116
117 DEFINE_VECTOR(MMPrepData, stripsVec, clustSize);
118
119 stripsVec.insert(stripsVec.begin(),std::make_move_iterator(MMprds.begin() + mergeI),
120 std::make_move_iterator(MMprds.begin() + mergeJ));
121
123 mergeI = mergeJ;
124 Amg::MatrixX covMatrix(1,1);
125 Amg::Vector2D clusterLocalPosition{Amg::Vector2D::Zero()};
126 ATH_CHECK(getClusterPosition(ctx, clusterId, stripsVec, clusterLocalPosition, covMatrix));
127
131 if (!m_writeStripProperties) mergeStrips.clear();
132 std::unique_ptr<MMPrepData> prdN = std::make_unique<MMPrepData>(clusterId,
133 hash,
134 std::move(clusterLocalPosition),
135 std::move(rdoList),
136 std::move(covMatrix),
137 stripsVec.front().detectorElement(),
138 0,
139 totalCharge,
140 0.f,
141 std::move(mergeStrips),
142 std::move(mergeStripsTime),
143 std::move(mergeStripsCharge));
144
145 prdN->setDriftDist(std::move(mergeStripsDriftDists), std::move(mergeStripsDriftDistErrors));
147 clustersVect.push_back(std::move(prdN));
148 } // end loop MMprds[i]
149 return StatusCode::SUCCESS;
150}
151
153StatusCode SimpleMMClusterBuilderTool::getClusterPosition(const EventContext& ctx,
154 const Identifier& clustId,
155 std::vector<MMPrepData>& stripsVec,
156 Amg::Vector2D& clusterLocalPosition,
157 Amg::MatrixX& covMatrix) const {
158
160 if (!errorCalibDB.isValid()) {
161 ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
162 return StatusCode::FAILURE;
163 }
164 covMatrix.setIdentity();
165 double weightedPosX{0.}, posY{0.}, totalCharge{0.};
166 Amg::Vector3D clusDir{Amg::Vector3D::Zero()};
167
169 posY = stripsVec[0].localPosition().y();
170 for (const MMPrepData& strip : stripsVec) {
171 const double posX = strip.localPosition().x();
172 const double charge = strip.charge();
173 weightedPosX += posX * charge;
174 totalCharge += charge;
176 clusDir+= charge * lDir;
177 const Amg::Vector3D& globPos{strip.globalPosition()};
178 ATH_MSG_VERBOSE("Adding a strip to the centroid calculation "<<m_idHelperSvc->toString(strip.identify())
179 <<", charge=" << charge<<" global position: "<<Amg::toString(globPos, 2)
180 <<", theta: "<<globPos.theta()<<", eta: "<<globPos.eta()<<", phi: "<<globPos.phi()
181 <<" -- local direction theta: "<<lDir.theta()<<", eta: "<<lDir.eta()
182 <<", phi: "<<lDir.phi());
183 }
184 weightedPosX = weightedPosX / totalCharge;
185 clusterLocalPosition = Amg::Vector2D(weightedPosX, posY);
186
187 NswErrorCalibData::Input errorCalibIn{};
188 errorCalibIn.stripId = clustId;
189 errorCalibIn.clusterAuthor = static_cast<unsigned>(MMPrepData::Author::SimpleClusterBuilder);
190 errorCalibIn.locPhi = clusDir.phi();
191 errorCalibIn.locTheta = clusDir.theta();
192 errorCalibIn.localPos = clusterLocalPosition;
193 errorCalibIn.clusterSize = stripsVec.size();
194
195 ATH_MSG_VERBOSE(m_idHelperSvc->toString(clustId)<< " - local track direction: "<<errorCalibIn.locTheta);
196
197 const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
198 covMatrix(0, 0) = localUncertainty * localUncertainty;
199 return StatusCode::SUCCESS;
200}
201
203 const std::vector<NSWCalib::CalibratedStrip>& calibratedStrips,
204 const Amg::Vector3D& dirEstimate,
205 Amg::Vector2D& clusterLocalPosition,
206 Amg::MatrixX& covMatrix) const {
208 double xPosCalib{0.}, totalCharge{0.};
209 for (const NSWCalib::CalibratedStrip& it : calibratedStrips) {
210 xPosCalib += it.charge * it.dx;
211 totalCharge += it.charge;
212 }
213 if (std::abs(totalCharge) < std::numeric_limits<float>::epsilon()) {
214 return RIO_Author::unKnownAuthor;
215 }
216
217 xPosCalib /= totalCharge;
218
219 ATH_MSG_DEBUG("position before calibration and correction: " << clusterLocalPosition[Trk::locX] << " " << xPosCalib);
220
221 clusterLocalPosition[Trk::locX] = clusterLocalPosition[Trk::locX] + xPosCalib;
223 if (!errorCalibDB.isValid()) {
224 ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
225 return RIO_Author::unKnownAuthor;
226 }
227
228 NswErrorCalibData::Input errorCalibIn{};
229 errorCalibIn.clusterSize = calibratedStrips.size();
230 errorCalibIn.clusterAuthor = RIO_Author::SimpleClusterBuilder;
231 errorCalibIn.locPhi = dirEstimate.phi();
232 errorCalibIn.locTheta = dirEstimate.theta();
233 errorCalibIn.localPos = clusterLocalPosition;
234 errorCalibIn.stripId = calibratedStrips[errorCalibIn.clusterSize/2].identifier;
235
236 const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
237
238 covMatrix(0, 0) = localUncertainty * localUncertainty;
239
240
241 return RIO_Author::SimpleClusterBuilder;
242}
243}
244#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
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
This is a "hash" representation of an Identifier.
int channel(const Identifier &id) const override
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
Standard Interface to produce Micromega clusters from raw Input hits without external contstaint.
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
SimpleMMClusterBuilderTool(const std::string &, const std::string &, const IInterface *)
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
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
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.