ATLAS Offline Software
Loading...
Searching...
No Matches
SiSpacePointMakerTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7// Cluster and space point collections
10
11// For processing clusters
16
17// Space points
20#include <cmath>
21
22namespace InDet {
23
24 static const InterfaceID IID_ISiSpacePointMakerTool
25 ("SiSpacePointMakerTool", 252891434, 0);
26
29 }
30
31 // Constructor with parameters:
33 const std::string& name,
34 const IInterface* parent) :
35 AthAlgTool(type, name, parent) {
36 declareInterface< SiSpacePointMakerTool>(this);
37 }
38 //--------------------------------------------------------------------------
40 // Get the SCT Helper
41 ATH_CHECK(detStore()->retrieve(m_idHelper, "SCT_ID"));
43 if (m_SCTgapParameter > 0.002) m_SCTgapParameter = 0.002;
44 return StatusCode::SUCCESS;
45 }
46 //--------------------------------------------------------------------------
48 return StatusCode::SUCCESS;
49 }
50
51 //--------------------------------------------------------------------------
52 void SiSpacePointMakerTool::fillPixelSpacePointCollection(const InDet::PixelClusterCollection* clusters,
53 SpacePointCollection* spacepointCollection,
54 DataPool<PixelSpacePoint>* dataItemsPixel) {
55
56 InDet::PixelClusterCollection::const_iterator clusStart = clusters->begin();
57 InDet::PixelClusterCollection::const_iterator clusFinish = clusters->end();
58
59 if ((*clusStart)->detectorElement()) {
60 IdentifierHash idHash = clusters->identifyHash();
61 const Amg::Transform3D& T = (*clusStart)->detectorElement()->surface().transform();
62 double Ax[3] = {T(0,0),T(1,0),T(2,0)};
63 double Ay[3] = {T(0,1),T(1,1),T(2,1)};
64 double Az[3] = {T(0,2),T(1,2),T(2,2)};
65
66 spacepointCollection->reserve(spacepointCollection->size()+clusters->size());
67
68 for(; clusStart!=clusFinish; ++clusStart){
69 const InDet::SiCluster* c = (*clusStart);
70 const Amg::MatrixX& V = c->localCovariance();
71
72 // Global position is already computed during pixel cluster creation and cached in the SiCluster object
73 const Amg::Vector3D& pos = c->globalPosition();
74
75 double B0[2] = {Ax[0]*V(0,0)+Ax[1]*V(1,0),Ax[0]*V(1,0)+Ax[1]*V(1,1)};
76 double B1[2] = {Ay[0]*V(0,0)+Ay[1]*V(1,0),Ay[0]*V(1,0)+Ay[1]*V(1,1)};
77 double B2[2] = {Az[0]*V(0,0)+Az[1]*V(1,0),Az[0]*V(1,0)+Az[1]*V(1,1)};
78
79 double C01 = B1[0]*Ax[0]+B1[1]*Ax[1];
80 double C02 = B2[0]*Ax[0]+B2[1]*Ax[1];
81 double C12 = B2[0]*Ay[0]+B2[1]*Ay[1];
82
83 AmgSymMatrix(3) cov;
84 cov << B0[0] * Ax[0] + B0[1] * Ax[1], C01, C02, C01,
85 B1[0] * Ay[0] + B1[1] * Ay[1], C12,
86 // cppcheck-suppress constStatement
87 C02, C12, B2[0] * Az[0] + B2[1] * Az[1];
88
89 if (dataItemsPixel) {
90 PixelSpacePoint* pix = dataItemsPixel->nextElementPtr();
91 (*pix) = InDet::PixelSpacePoint(idHash, c, pos, cov);
92 spacepointCollection->push_back(pix);
93
94 } else {
95 spacepointCollection->push_back(
96 new InDet::PixelSpacePoint(idHash, c, pos, cov));
97 }
98 }
99 }
100 }
101
103 // Possible offset estimation in Z or R direction due to gap size
105
107 (const InDetDD::SiDetectorElement* element1, const InDetDD::SiDetectorElement* element2, double& stripLengthGapTolerance) const
108 {
109 const Amg::Transform3D& T1 = element1->transform();
110 const Amg::Transform3D& T2 = element2->transform();
111 Amg::Vector3D C = element1->center() ;
112 bool isAnnulus = (element1->design().shape() == InDetDD::Annulus);
113 // bool isPolar = (element1->design().shape() == InDetDD::PolarAnnulus);
114
115 double x12 = T1(0,0)*T2(0,0)+T1(1,0)*T2(1,0)+T1(2,0)*T2(2,0) ;
116 double r = isAnnulus ? std::sqrt(C[0]*C[0]+C[1]*C[1]) : std::sqrt(T1(0,3)*T1(0,3)+T1(1,3)*T1(1,3));
117 double s = (T1(0,3)-T2(0,3))*T1(0,2)+(T1(1,3)-T2(1,3))*T1(1,2)+(T1(2,3)-T2(2,3))*T1(2,2);
118
119 double dm = (m_SCTgapParameter*r)*std::abs(s*x12);
120 double d = isAnnulus ? dm/.04 : dm/std::sqrt((1.-x12)*(1.+x12));
121
122 if (std::abs(T1(2,2)) > 0.7) d*=(r/std::abs(T1(2,3))); // endcap d = d*R/Z
123
124 stripLengthGapTolerance = d;
125
126 return dm;
127 }
128
130 // Updating the range used to search for overlaps
132
134 const InDetDD::SiDetectorElement* element2,
135 double& stripLengthGapTolerance,
136 double& min, double& max) const {
137 double dm = offset(element1, element2, stripLengthGapTolerance);
138 min -= dm;
139 max += dm;
140 }
141
142
144 // New methods for sct space points production
146
147 void SiSpacePointMakerTool::fillSCT_SpacePointCollection (std::array<const InDetDD::SiDetectorElement*, nNeighbours>& elements,
148 std::array<const SCT_ClusterCollection*, nNeighbours>& clusters,
149 std::array<double, 14>& overlapExtents,
150 bool allClusters,
151 const Amg::Vector3D& vertexVec,
152 SpacePointCollection* spacepointCollection,
153 SpacePointOverlapCollection* spacepointoverlapCollection,
154 DataPool<SCT_SpacePoint>* dataItemsSCT) const
155 {
156
157 // This function is called once all the needed quantities are collected.
158 // It is used to build space points checking the compatibility of clusters on pairs of detector elements.
159 // Detector elements and cluster collections are elements and clusters, respectively.
160 // [0] is the trigger element
161 // [1] is the opposite element
162 // [2]-[3] are the elements tested for eta overlaps
163 // [4]-[5] are the elements tested for phi overlaps
164 //
165 // To build space points:
166 // - For the opposite element and the ones tested for eta overlaps, you have to check
167 // if clusters are compatible with the local position of the trigger cluster
168 // requiring that the distance between the two clusters in phi is withing a specified range.
169 // - overlapExtents[0], overlapExtents[1] are filled for the opposite element
170 // - overlapExtents[2], overlapExtents[3], overlapExtents[4], overlapExtents[5] are filled for the eta overlapping elements
171 // - For the elements tested for phi overlaps, you have to check
172 // if clusters are compatible with the local position of the trigger cluster.
173 // This needs that the trigger cluster is at the edge of the trigger module
174 // and that the other cluster is on the compatible edge of its module
175 // - overlapExtents[6], overlapExtents[7], overlapExtents[10], overlapExtents[11]
176 // overlapExtents[8], overlapExtents[9], overlapExtents[12], overlapExtents[13] are filled for the phi overlapping elements
177
178 constexpr int otherSideIndex{1};
179 constexpr int maxEtaIndex{3};
180 std::array<int, nNeighbours-1> elementIndex{};
181 int nElements = 0;
182
183 // For the nNeighbours sides, fill elementIndex with the indices of the existing elements.
184 // Same the number of elements in nElements to loop on the later on
185 for(int n=1; n!=nNeighbours; ++n) {
186 if(elements[n]) {
187 elementIndex[nElements++] = n;
188 }
189 }
190 // return if all detector elements are nullptr
191 if(!nElements) return;
192
193 // trigger element and clusters
194 const InDetDD::SiDetectorElement* element = elements[0];
195 IdentifierHash Id = clusters[0]->identifyHash();
196
197 std::vector<SCTinformation> sctInfos;
198 sctInfos.reserve(clusters[0]->size());
199
200 // loop on all clusters on the trigger detector element and save the related information
201 for (const auto *const cluster : *clusters[0]) {
202 Amg::Vector2D locpos = cluster->localPosition();
203 std::pair<Amg::Vector3D, Amg::Vector3D > ends(element->endsOfStrip(InDetDD::SiLocalPosition(locpos.y(),locpos.x(),0.)));
204 InDet::SCTinformation sct(cluster,ends.first, ends.second, vertexVec,locpos.x());
205 sctInfos.push_back(sct);
206 }
207
208 double limit = 1. + m_stripLengthTolerance;
209 double slimit = 0. ;
210 std::vector<Trk::SpacePoint*> tmpSpacePoints;
211 tmpSpacePoints.reserve(sctInfos.size());
212
213 if(!allClusters) {
214
215 // Start processing the opposite side and the eta overlapping elements
216 int n = 0;
217 for(; n < nElements; ++n) {
218
219 int currentIndex = elementIndex[n];
220
221 if(currentIndex > maxEtaIndex) break;
222
223 // get the detector element and the IdentifierHash
224 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
225 IdentifierHash currentId = clusters[currentIndex]->identifyHash();
226
227 // retrieve the range
228 double min = overlapExtents[currentIndex*2-2];
229 double max = overlapExtents[currentIndex*2-1];
230
231 if (m_SCTgapParameter != 0.) {
232 updateRange(element, currentElement, slimit, min, max);
233 }
234
235 // Eta overlap in the endcap between rows 9 and 10 (stereo element in eta row 10):
236 // The phi module granularity changes from 1 to 2 modules,
237 // and introduces an offset of ~31.4 mm on the local x values for row 10 wrt. row 9
238 // in a positive or negative direction depending on the phi position of the eta 10 row,
239 // stored as neighbours 2 or 3.
240 // This has to be taken into account when computing "diff" below
241 double lx1_offset = 0.;
242 if (m_idHelper->barrel_ec(currentElement->identify())!=0 &&
243 m_idHelper->eta_module(currentElement->identify())==10) {
244 if (currentIndex==2) lx1_offset = -1.*m_locXOffset_ECEtaOvlpRaws9n10;
245 else if (currentIndex==3) lx1_offset = m_locXOffset_ECEtaOvlpRaws9n10;
246 }
247
248 // Loop on all clusters of the stereo element
249 InDet::SCTinformation sctInfo;
250 for (const auto *const cluster : *clusters[currentIndex]) {
251
252 bool processed = false;
253 const Amg::Vector2D& locpos = cluster->localPosition();
254 double lx1 = locpos.x();
255
256 // Loop on all clusters of the trigger element
257 for(auto& sct : sctInfos) {
258
259 double diff = lx1+lx1_offset-sct.locX();
260
261 // In negative endcap, local x is opposite of positive endcap
262 // need to invert the difference for proper comparison
263 if( m_idHelper->barrel_ec(currentElement->identify())<0 ) diff = -diff;
264
265 if(diff < min || diff > max) continue;
266
267 if (not processed) {
268 processed = true;
269 std::pair<Amg::Vector3D, Amg::Vector3D > ends(currentElement->endsOfStrip(InDetDD::SiLocalPosition(locpos.y(),locpos.x(),0.)));
270 sctInfo.set(cluster,ends.first, ends.second, vertexVec,lx1);
271 }
272
274 sct, sctInfo, Id, currentId, limit, slimit, dataItemsSCT);
275 if (sp) {
276 tmpSpacePoints.push_back(sp);
277 }
278 }
279 }
280 // If you are processing the opposite element, save the space points into
281 // the spacepointCollection and clear the temporary collection
282 if( currentIndex==otherSideIndex && !tmpSpacePoints.empty() ) {
283 spacepointCollection->reserve(tmpSpacePoints.size()+spacepointCollection->size());
284 for (Trk::SpacePoint* sp: tmpSpacePoints) {
285 spacepointCollection->push_back(sp);
286 }
287 tmpSpacePoints.clear();
288 }
289 }
290
291 // process the phi overlapping elements
292 // if possible n starts from 4
293 for(; n < nElements; ++n) {
294
295 int currentIndex = elementIndex[n];
296 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
297
298 double min = overlapExtents[4*currentIndex-10];
299 double max = overlapExtents[4*currentIndex- 9];
300
301 if (m_SCTgapParameter != 0.) {
302 updateRange(element, currentElement, slimit, min, max);
303 }
304
305 std::vector<SCTinformation*> sctPhiInfos;
306 sctPhiInfos.reserve(sctInfos.size());
307
308 for(auto& sct : sctInfos) {
309 double lx0 = sct.locX();
310 if (min <= lx0 && lx0 <= max) {
311 sctPhiInfos.push_back(&sct);
312 }
313 }
314 // continue if you have no cluster from the phi overlapping region of the trigger element
315 if(sctPhiInfos.empty()) continue;
316
317 IdentifierHash currentId = clusters[currentIndex]->identifyHash();
318
319 min = overlapExtents[4*currentIndex-8];
320 max = overlapExtents[4*currentIndex-7];
321
322 if (m_SCTgapParameter != 0.) {
323 updateRange(element, currentElement, slimit, min, max);
324 }
325
326 for (const auto *const cluster : *clusters[currentIndex]) {
327
328 const Amg::Vector2D& locpos = cluster->localPosition();
329 double lx1 = locpos.x();
330 if(lx1 < min || lx1 > max ) continue;
331
332 std::pair<Amg::Vector3D, Amg::Vector3D > ends(currentElement->endsOfStrip(InDetDD::SiLocalPosition(locpos.y(),locpos.x(),0.)));
333 InDet::SCTinformation sctInfo(cluster,ends.first, ends.second, vertexVec,lx1);
334
335 for(auto& sct : sctPhiInfos) {
337 *sct, sctInfo, Id, currentId, limit, slimit, dataItemsSCT);
338 if (sp) {
339 tmpSpacePoints.push_back(sp);
340 }
341 }
342 }
343 }
344
345 // fill the space point collection for eta/phi overlapping clusters
346 if(!tmpSpacePoints.empty()) {
347 spacepointoverlapCollection->reserve(tmpSpacePoints.size()+spacepointoverlapCollection->size());
348 for (Trk::SpacePoint* sp: tmpSpacePoints) {
349 spacepointoverlapCollection->push_back(sp);
350 }
351 }
352 return;
353 }
354
355 // the following code is used to create spacepoints processing all clusters without limits
356
357 for(int n=0; n!=nElements; ++n) {
358
359 int currentIndex = elementIndex[n];
360 const InDetDD::SiDetectorElement* currentElement = elements[currentIndex];
361 IdentifierHash currentId = clusters[currentIndex]->identifyHash();
362
363 if (m_SCTgapParameter != 0.) {
364 offset(element, currentElement, slimit);
365 }
366
367 for (const auto *const cluster : *clusters[currentIndex]) {
368
369 const Amg::Vector2D& locpos = cluster->localPosition();
370 std::pair<Amg::Vector3D, Amg::Vector3D > ends(currentElement->endsOfStrip(InDetDD::SiLocalPosition(locpos.y(),locpos.x(),0.)));
371 InDet::SCTinformation sctInfo(cluster,ends.first, ends.second,vertexVec,locpos.x());
372
373 for(auto& sct : sctInfos) {
374 Trk::SpacePoint* sp = makeSCT_SpacePoint(sct,sctInfo,Id,currentId,limit,slimit,dataItemsSCT);
375 if(sp) {
376 tmpSpacePoints.push_back(sp);
377 }
378 }
379 }
380 // If you are processing the opposite element, save the space points into
381 // the spacepointCollection and clear the temporary collection
382 if( currentIndex==otherSideIndex && !tmpSpacePoints.empty() ) {
383 spacepointCollection->reserve(tmpSpacePoints.size()+spacepointCollection->size());
384 for (Trk::SpacePoint* sp: tmpSpacePoints) {
385 spacepointCollection->push_back(sp);
386 }
387 tmpSpacePoints.clear();
388 }
389 }
390 // fill the space point collection for eta/phi overlapping clusters
391 if(!tmpSpacePoints.empty()) {
392 spacepointoverlapCollection->reserve(tmpSpacePoints.size()+spacepointoverlapCollection->size());
393 for (Trk::SpacePoint* sp: tmpSpacePoints) {
394 spacepointoverlapCollection->push_back(sp);
395 }
396 }
397 }
398
399 //--------------------------------------------------------------------------
400 //
403 IdentifierHash ID0, IdentifierHash ID1, double limit, double slimit,
404 DataPool<SCT_SpacePoint>* dataItemsSCT) {
405
406 double a =-In0.traj_direction().dot(In1.normal());
407 double b = In0.strip_direction().dot(In1.normal());
408 double l0 = In0.oneOverStrip()*slimit+limit ;
409
410 if(std::abs(a) > (std::abs(b)*l0)) return nullptr;
411
412 double c =-In1.traj_direction().dot(In0.normal());
413 double d = In1.strip_direction().dot(In0.normal());
414 double l1 = In1.oneOverStrip()*slimit+limit ;
415
416 if(std::abs(c) > (std::abs(d)*l1)) return nullptr;
417
418 double m = a/b;
419
420 if(slimit!=0.) {
421
422 double n = c/d;
423
424 if (m > limit || n > limit) {
425
426 double cs = In0.strip_direction().dot(In1.strip_direction())*(In0.oneOverStrip()*In0.oneOverStrip());
427 double dm = (m-1);
428 double dmn = (n-1.)*cs;
429 if(dmn > dm) dm = dmn;
430 m-=dm; n-=(dm/cs);
431 if(std::abs(m) > limit || std::abs(n) > limit) return nullptr;
432 } else if(m < -limit || n < -limit) {
433
434 double cs = In0.strip_direction().dot(In1.strip_direction())*(In0.oneOverStrip()*In0.oneOverStrip());
435 double dm = -(1.+m);
436 double dmn = -(1.+n)*cs;
437 if(dmn > dm) dm = dmn;
438 m+=dm; n+=(dm/cs);
439 if(std::abs(m) > limit || std::abs(n) > limit) return nullptr;
440 }
441 }
442 Amg::Vector3D point(In0.position(m));
443
444 const std::pair<IdentifierHash,IdentifierHash> elementIdList(ID0,ID1);
445 //if we have a DataPool use it
446 if (dataItemsSCT) {
447 SCT_SpacePoint* sp = dataItemsSCT->nextElementPtr();
448 (*sp) = InDet::SCT_SpacePoint(elementIdList, point,
449 {In0.cluster(), In1.cluster()});
450 return sp;
451 }
452 return new InDet::SCT_SpacePoint(elementIdList, point,
453 {In0.cluster(), In1.cluster()});
454 }
455}
#define ATH_CHECK
Evaluate an expression and check for errors.
static const int B0
Definition AtlasPID.h:122
#define AmgSymMatrix(dim)
static Double_t sp
static Double_t a
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
This is an Identifier helper class for the SCT subdetector.
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
a typed memory pool that saves time spent allocation small object.
Definition DataPool.h:63
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
std::pair< Amg::Vector3D, Amg::Vector3D > endsOfStrip(const Amg::Vector2D &position) const
Special method for SCT to retrieve the two ends of a "strip" Returned coordinates are in global frame...
Class to represent a position in the natural frame of a silicon sensor, for Pixel and SCT For Pixel: ...
virtual const Amg::Transform3D & transform() const override final
Return local to global transform.
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
virtual Identifier identify() const override final
identifier of this detector element (inline)
A PixelSpacePoint is created from a PixelCluster.
An SCT_SpacePoint is created from two SCT_Cluster's from two different wafers.
Amg::Vector3D position(const double &s) const
const InDet::SiCluster * cluster() const
const Amg::Vector3D & normal() const
void set(const InDet::SiCluster *CL, const Amg::Vector3D &strip_start, const Amg::Vector3D &strip_end, const Amg::Vector3D &vec, const double &locx)
const Amg::Vector3D & strip_direction() const
const Amg::Vector3D & traj_direction() const
const double & oneOverStrip() const
virtual StatusCode initialize() override
Initialize.
virtual StatusCode finalize() override
Finalize.
SiSpacePointMakerTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
void fillSCT_SpacePointCollection(std::array< const InDetDD::SiDetectorElement *, nNeighbours > &, std::array< const SCT_ClusterCollection *, nNeighbours > &, std::array< double, 14 > &, bool, const Amg::Vector3D &, SpacePointCollection *, SpacePointOverlapCollection *, DataPool< SCT_SpacePoint > *dataItemsSCT) const
static void fillPixelSpacePointCollection(const InDet::PixelClusterCollection *clusters, SpacePointCollection *spacepointCollection, DataPool< PixelSpacePoint > *dataItemsPixel)
Convert clusters to space points: PixelClusters -> PixelSpacePoints.
static const InterfaceID & interfaceID()
Return interfaceID.
double offset(const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance) const
Get stripLengthGapTolerance and return offset value for two SiDetectorElement's.
void updateRange(const InDetDD::SiDetectorElement *element1, const InDetDD::SiDetectorElement *element2, double &stripLengthGapTolerance, double &min, double &max) const
update range accordingly to the gap between the stereo modules
static Trk::SpacePoint * makeSCT_SpacePoint(InDet::SCTinformation &, InDet::SCTinformation &, IdentifierHash, IdentifierHash, double, double, DataPool< SCT_SpacePoint > *dataItemsSCT)
Convert clusters to space points: SCT_Clusters -> SCT_SpacePoints.
int r
Definition globals.cxx:22
struct color C
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Primary Vertex Finder.
static const InterfaceID IID_ISiSpacePointMakerTool("SiSpacePointMakerTool", 252891434, 0)