ATLAS Offline Software
Loading...
Searching...
No Matches
TrigInDetRoadPredictorTool.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
6
13
16
19
20#include "TrkSurfaces/Surface.h"
22#include "GaudiKernel/SystemOfUnits.h"
23
24#include <array>
25#include <cmath>
26#include <memory>
27
28
30 const std::string& n,
31 const IInterface* p ): AthAlgTool(t,n,p)
32{
33 declareInterface< ITrigInDetRoadPredictorTool >( this );
34}
35
37
38 StatusCode sc = m_layerNumberTool.retrieve();
39 if(sc.isFailure()) {
40 ATH_MSG_ERROR("Could not retrieve "<<m_layerNumberTool);
41 return sc;
42 } else {
43 ATH_MSG_INFO("Detector layer structure has "<<m_layerNumberTool->maxNumberOfUniqueLayers()<<" unique layers");
44 }
45
46
47 ATH_CHECK( m_fieldCondObjInputKey.initialize());
48 ATH_CHECK( detStore()->retrieve(m_pixelManager, "ITkPixel") );
49 ATH_CHECK( detStore()->retrieve(m_stripManager, "ITkStrip") );
50 ATH_CHECK( detStore()->retrieve(m_pixelId, "PixelID") );
51 ATH_CHECK( detStore()->retrieve(m_stripId, "SCT_ID") );
52
54
55
56 return StatusCode::SUCCESS;
57}
58
59void TrigInDetRoadPredictorTool::addNewElement(unsigned int layerID, short phi_idx, short eta_idx, const InDetDD::SiDetectorElement* p) {
60
61 unsigned int hash = p->identifyHash();
62
64
65 //find corners in the global c.s.
66
67 float de_len = 0.5*p->design().length();
68 float de_wmax = 0.5*p->design().maxWidth();
69 float de_wmin = 0.5*p->design().minWidth();
70
71 float dPhi[4] = {de_wmax, de_wmin, -de_wmin, -de_wmax};//locX
72 float dEta[4] = {de_len, -de_len, -de_len, de_len}; //locY
73
74 const Amg::Vector3D& C = p->center();
75 const Amg::Vector3D& PhiAx = p->phiAxis();
76 const Amg::Vector3D& EtaAx = p->etaAxis();
77
78 for(int ic=0; ic<4; ic++) {
79 float x = C.x() + PhiAx.x()*dPhi[ic] + EtaAx.x()*dEta[ic];
80 float y = C.y() + PhiAx.y()*dPhi[ic] + EtaAx.y()*dEta[ic];
81 float z = C.z() + PhiAx.z()*dPhi[ic] + EtaAx.z()*dEta[ic];
82 ded.m_c[ic][0] = std::sqrt(x*x+y*y);//r
83 ded.m_c[ic][1] = z;
84 ded.m_c[ic][2] = std::atan2(y,x);//phi
85 }
86 const auto pPair = m_layerMap.find(layerID);
87 if (pPair == m_layerMap.end())[[unlikely]]{
88 ATH_MSG_WARNING("addNewElement: Layer ID not found in map.");
89 return;
90 }
91 auto& L = pPair->second;
92
93 short prim_idx = L.m_mappingType != 2 ? phi_idx : eta_idx;
94 short sec_idx = L.m_mappingType != 2 ? eta_idx : phi_idx;
95
96 if(L.m_mappingType == 0) {//barrel: primary index is phi, eta/z is secondary
97 ded.m_ref = C.z();
98 ded.m_index = sec_idx;
99 ded.m_minBound = ded.m_c[0][1];
100 ded.m_maxBound = ded.m_c[0][1];
101 for(int ic=1;ic<4;ic++) {
102 if(ded.m_minBound > ded.m_c[ic][1]) ded.m_minBound = ded.m_c[ic][1];
103 if(ded.m_maxBound < ded.m_c[ic][1]) ded.m_maxBound = ded.m_c[ic][1];
104 }
105 }
106
107 if(L.m_mappingType == 1) {//pixel endcap layers : primary index is phi, eta/R is secondary
108 ded.m_ref = C.perp();
109 ded.m_index = sec_idx;
110 ded.m_minBound = ded.m_c[0][0];
111 ded.m_maxBound = ded.m_c[0][0];
112 for(int ic=1;ic<4;ic++) {
113 if(ded.m_minBound > ded.m_c[ic][0]) ded.m_minBound = ded.m_c[ic][0];
114 if(ded.m_maxBound < ded.m_c[ic][0]) ded.m_maxBound = ded.m_c[ic][0];
115 }
116 }
117
118 if(L.m_mappingType == 2) {//strip endcaps: primary index is R, phi is secondary, layers are double
119 ded.m_ref = std::atan2(C.y(),C.x());
120 ded.m_index = sec_idx;
121 ded.m_minBound = ded.m_c[0][2];
122 ded.m_maxBound = ded.m_c[0][2];
123 for(int ic=1;ic<4;ic++) {
124 if(ded.m_minBound > ded.m_c[ic][2]) ded.m_minBound = ded.m_c[ic][2];
125 if(ded.m_maxBound < ded.m_c[ic][2]) ded.m_maxBound = ded.m_c[ic][2];
126 }
127 }
128
129 //put DetEl description into the corresponding collection
130
131 int detColIdx = 0;
132
133 if(L.m_nSubLayers == 2 && (hash % 2) != 0) {//double layer, odd detector elements
134 detColIdx = 1;
135 }
136
137 if(L.m_colls[ detColIdx].find(prim_idx) == L.m_colls[ detColIdx].end()) {
138
139 float primBounds[2] = {0,0};
140 if(L.m_mappingType == 2) {
141 primBounds[0] = p->rMin();
142 primBounds[1] = p->rMax();
143 }
144 else {
145 primBounds[0] = p->phiMin();
146 primBounds[1] = p->phiMax();
147 }
148
149 DetectorElementsCollection dc(prim_idx, primBounds[0], primBounds[1]);
150 L.m_colls[ detColIdx].insert(std::make_pair(prim_idx, dc));
151 }
152
153 (*L.m_colls[detColIdx].find(prim_idx)).second.m_vDE.push_back(ded);
154
155}
156
157
159
160 const std::vector<short>& vPixelL = *(m_layerNumberTool->pixelLayers());
161 const std::vector<TrigInDetSiLayer>& SiL = *(m_layerNumberTool->layerGeometry());
162
163 for(int hash = 0; hash<static_cast<int>(m_pixelId->wafer_hash_max()); hash++) {
164
165 Identifier offlineId = m_pixelId->wafer_id(hash);
166 short barrel_ec = m_pixelId->barrel_ec(offlineId);
167 if(std::abs(barrel_ec)>2) continue;//no DBM needed
168
169 unsigned int layerID = SiL.at(vPixelL.at(hash)).m_subdet;
170 unsigned int volumeID = layerID / 1000;
171
172 if(m_layerMap.find(layerID) == m_layerMap.end()) {
173
174 int nSubLayers = 1;
175 unsigned int mappingType = 1;
176
177 if(barrel_ec == 0) mappingType = 0;
178 else {
179 if(volumeID == 12 || volumeID == 14) mappingType = 2;
180 }
181 m_layerMap.try_emplace(layerID, layerID, nSubLayers, mappingType);
182 }
183
184 short phi_index = m_pixelId->phi_module(offlineId);
185 short eta_index = m_pixelId->eta_module(offlineId);
186
187 addNewElement(layerID, phi_index, eta_index, m_pixelManager->getDetectorElement(hash));
188 }
189
190 const std::vector<short>& vStripL = *(m_layerNumberTool->sctLayers());
191
192 for(int hash = 0; hash<static_cast<int>(m_stripId->wafer_hash_max()); hash++) {
193
194 Identifier offlineId = m_stripId->wafer_id(hash);
195 short barrel_ec = m_stripId->barrel_ec(offlineId);
196 if(std::abs(barrel_ec)>2) continue;
197
198 unsigned int layerID = SiL.at(vStripL.at(hash)).m_subdet;
199 unsigned int volumeID = layerID / 1000;
200
201 if(m_layerMap.find(layerID) == m_layerMap.end()) {
202 int nSubLayers = 2;//strip layers are double
203 unsigned int mappingType = 1;
204
205 if(barrel_ec == 0) mappingType = 0;
206 else {
207 if(volumeID == 12 || volumeID == 14) mappingType = 2;
208 }
209 m_layerMap.try_emplace(layerID, layerID, nSubLayers, mappingType);
210 }
211
212 short phi_index = m_stripId->phi_module(offlineId);
213 short eta_index = m_stripId->eta_module(offlineId);
214
215 addNewElement(layerID, phi_index, eta_index, m_stripManager->getDetectorElement(hash));
216 }
217
218 //building hit boxes
219
221
222}
223
225
226 const float margin_r = 3.0;
227 const float margin_z = 3.0;
228
229 for(const auto& l : m_layerMap) {
230
231 unsigned int layerID = l.first;
232 unsigned int volumeID = layerID / 1000;
233
234 const auto& L = l.second;
235
236 float minR = 1e8;// vert0
237 float minZ = 1e8;// vert1
238 float maxR = -1e8;// vert2
239 float maxZ = -1e8;// vert3
240
241 float vert[4][2]; //z,r
242
243 memset(&vert[0][0],0,sizeof(vert));
244
245 for(int iSL = 0; iSL < L.m_nSubLayers;iSL++) {
246 for(const auto& deColl : L.m_colls[iSL]) {
247 for(const auto& de : deColl.second.m_vDE) {
248 for(int ic=0;ic<4;ic++) {
249 float r = de.m_c[ic][0];
250 float z = de.m_c[ic][1];
251 if(r < minR) {
252 minR = r;
253 vert[0][0] = z;
254 vert[0][1] = r;
255 }
256 if(z < minZ) {
257 minZ = z;
258 vert[1][0] = z;
259 vert[1][1] = r;
260 }
261 if(r > maxR) {
262 maxR = r;
263 vert[2][0] = z;
264 vert[2][1] = r;
265 }
266 if(z > maxZ) {
267 maxZ = z;
268 vert[3][0] = z;
269 vert[3][1] = r;
270 }
271 }
272 }
273 }
274 }
275 minR -= margin_r;
276 vert[0][1] -= margin_r;
277 minZ -= margin_z;
278 vert[1][0] -= margin_z;
279 maxR += margin_r;
280 vert[2][1] += margin_r;
281 maxZ += margin_z;
282 vert[3][0] += margin_z;
283
284 int new_layer_index = -1;
286 new_layer_index = m_lBoundaries.size();
287 lb.m_index = new_layer_index;
288 lb.m_lay_id = layerID;
289 lb.m_nVertices = 5;
290
291 if(volumeID == 73 || volumeID == 75 || volumeID == 77) {//negative inclined
292 lb.m_z = {vert[3][0], vert[2][0], vert[1][0], vert[0][0], vert[3][0]};
293 lb.m_r = {vert[3][1], vert[2][1], vert[1][1], vert[0][1], vert[3][1]};
294 }
295 else if(volumeID == 93 || volumeID == 95 || volumeID == 97) {//positive inclined
296 lb.m_z = {vert[2][0], vert[1][0], vert[0][0], vert[3][0], vert[2][0]};
297 lb.m_r = {vert[2][1], vert[1][1], vert[0][1], vert[3][1], vert[2][1]};
298 }
299 else {//all other layers
300 lb.m_z = {maxZ, minZ, minZ, maxZ, maxZ};
301 lb.m_r = {maxR, maxR, minR, minR, maxR};
302 }
303
304 m_lBoundaries.push_back(std::move(lb));
305
306 bool volExists = false;
307
308 for(auto& v : m_vBoundaries) {
309 if(v.m_vol_id == (int)volumeID) {
310 volExists = true;//update corners
311 if(v.m_zr[0] > minZ) v.m_zr[0] = minZ;
312 if(v.m_zr[1] < maxZ) v.m_zr[1] = maxZ;
313 if(v.m_zr[2] > minR) v.m_zr[2] = minR;
314 if(v.m_zr[3] < maxR) v.m_zr[3] = maxR;
315 v.m_layers.push_back(new_layer_index);
316 break;
317 }
318 }
319 if(!volExists) {//add a new volume with 4 corners
321 vb.m_layers.push_back(new_layer_index);
322 vb.m_index = m_vBoundaries.size();
323 vb.m_vol_id = volumeID;
324 vb.m_zr[0] = minZ;
325 vb.m_zr[1] = maxZ;
326 vb.m_zr[2] = minR;
327 vb.m_zr[3] = maxR;
328 m_vBoundaries.push_back(std::move(vb));
329 }
330 }
331}
332
333void TrigInDetRoadPredictorTool::findDetectorElements(unsigned int layerID, const SearchInterval& searchArea,
334 std::vector<unsigned int>& vIDs, bool hasHit) const {
335
336 const float road_width_rz = hasHit ? m_min_rz_rw : m_max_rz_rw;
337 const float road_width_rphi = hasHit ? m_min_rphi_rw : m_max_rphi_rw;
338
339 float phi_test = searchArea.m_phi;
340 float phi_res = road_width_rphi/searchArea.m_r;
341
342 if(phi_res > m_max_phi_rw) phi_res = m_max_phi_rw;
343 if(phi_res < m_min_phi_rw) phi_res = m_min_phi_rw;
344
345 float phi_min = phi_test - phi_res;
346 float phi_max = phi_test + phi_res;
347 const auto pPair = m_layerMap.find(layerID);
348 if (pPair == m_layerMap.end())[[unlikely]]{
349 ATH_MSG_WARNING("findDetectorElements: layerID not found.");
350 return;
351 }
352 const auto& L = pPair->second;
353
354 if(L.m_mappingType != 2) { // primary index is Phi, secondary is Z or R
355
356 float rz_test_m = searchArea.getMinR();
357 float rz_test_p = searchArea.getMaxR();
358
359 if(L.m_mappingType == 0) {
360 rz_test_m = searchArea.getMinZ();
361 rz_test_p = searchArea.getMaxZ();
362 }
363
364 rz_test_m -= road_width_rz;
365 rz_test_p += road_width_rz;
366
367 for(int iSubL = 0; iSubL < L.m_nSubLayers;iSubL++) {
368
369 for(const auto& prim : L.m_colls[iSubL]) {
370
371 const auto& slice = prim.second;
372
373 float f1 = slice.m_minCoord;
374 float f2 = slice.m_maxCoord;
375
376 if(std::abs(f2 - f1) < M_PI) {
377 if(phi_max < f1) continue;
378 if(phi_min > f2) continue;
379 }
380 else {// +/- pi boundary
381 std::swap(f2, f1);
382 if(phi_test < 0 && phi_min > f1) continue;
383 if(phi_test > 0 && phi_max < f2) continue;
384 }
385
386 for(const auto& de : slice.m_vDE) {
387
388 float p1 = de.m_minBound;
389 float p2 = de.m_maxBound;
390
391 if(rz_test_p < p1) break;
392 if(rz_test_m > p2) continue;
393
394 if (! (rz_test_p < p1 || rz_test_m > p2)) vIDs.push_back(de.m_hash);
395 }
396 }
397 }
398 }
399 else { //Strip endcaps: primary R, secondary Phi
400
401 float r_test_m = searchArea.getMinR() - road_width_rz;
402 float r_test_p = searchArea.getMaxR() + road_width_rz;
403
404 for(int iSubL = 0; iSubL < L.m_nSubLayers;iSubL++) {
405
406 for(const auto& prim : L.m_colls[iSubL]) {
407
408 const auto& slice = prim.second;
409
410 float r1 = slice.m_minCoord;
411 float r2 = slice.m_maxCoord;
412
413 if(r_test_p < r1) break;
414 if(r_test_m > r2) continue;
415
416 if (! (r_test_p < r1 || r_test_m > r2)) {
417
418 for(const auto& de : slice.m_vDE) {
419
420 float f1 = de.m_minBound;
421 float f2 = de.m_maxBound;
422
423 if(f2 - f1 < M_PI) {
424 if(phi_max < f1) continue;
425 if(phi_min > f2) continue;
426 }
427 else {// +/- pi boundary
428 if(phi_test < 0 && phi_min > f1) continue;
429 if(phi_test > 0 && phi_max < f2) continue;
430 }
431 vIDs.push_back(de.m_hash);
432 }
433 }
434 }
435 }
436 }
437
438}
439
440
441
442
443int TrigInDetRoadPredictorTool::getRoad(const std::vector<const Trk::SpacePoint*>& seed,
444 std::vector<const InDetDD::SiDetectorElement*>& road,
445 const EventContext& ctx) const {
446
447
448 const float MAX_R = 1030.0;//detector envelope
449 const float MAX_Z = 3000.0;//detector envelope
450 const float maxCornerDist = 15.0;
451
452 //1. get magnetic field
453
454 MagField::AtlasFieldCache fieldCache;
455
457 if (!fieldCondObj.isValid()) {
458 ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
459 return -1;
460 }
461
462 fieldCondObj->getInitializedCache (fieldCache);
463
464 road.clear();
465
466 unsigned int nSP = seed.size();
467
468 if(nSP < 3) return -2;
469
470 std::vector<unsigned int> seedHashes;
471
472 for(unsigned int spIdx=0;spIdx<nSP;spIdx++) {
473 const auto& sp = seed.at(spIdx);
474 const Trk::PrepRawData* prd = sp->clusterList().first;
475 const InDet::PixelCluster* pPixelHit = static_cast<const InDet::PixelCluster*>(prd);
476 unsigned int hash = pPixelHit->detectorElement()->identifyHash();
477 seedHashes.push_back(hash);
478 }
479
480 std::vector<std::array<float,2> > zr;
481 zr.resize(nSP+2);
482
483 for(unsigned int spIdx=0;spIdx<nSP;spIdx++) {
484 const auto& sp = seed.at(spIdx);
485 zr[spIdx+1][0] = sp->globalPosition().z();
486 zr[spIdx+1][1] = sp->globalPosition().perp();
487 }
488
489 //adding the first point at beamline
490
491 zr[0][0] = zr[1][0] - zr[1][1]*(zr[2][0]-zr[1][0])/(zr[2][1]-zr[1][1]);
492 zr[0][1] = 0;
493
494 //adding the last point at detector exit
495 float zlast = zr[nSP-1][0] + (MAX_R - zr[nSP-1][1])*(zr[nSP][0]-zr[nSP-1][0])/(zr[nSP][1]-zr[nSP-1][1]);
496 float rlast = MAX_R;
497
498 if (std::fabs(zlast) > MAX_Z) {
499 if(zlast > 0) zlast = MAX_Z;
500 else zlast = -MAX_Z;
501 rlast = zr[nSP-1][1] + (zlast - zr[nSP-1][0])*(zr[nSP][1]-zr[nSP-1][1])/(zr[nSP][0]-zr[nSP-1][0]);
502 }
503 zr[nSP+1][0] = zlast;
504 zr[nSP+1][1] = rlast;
505
506 std::map<unsigned int, SearchInterval> rzIntervals;
507
508 for(unsigned int k1 = 0;k1<zr.size()-1;k1++) {//loop over trajectory segments
509
510 unsigned int k2 = k1+1;
511
512 float z1 = zr[k1][0];
513 float r1 = zr[k1][1];
514 float z2 = zr[k2][0];
515 float r2 = zr[k2][1];
516 float dz21 = z2-z1;
517 float dr21 = r2-r1;
518 float L = std::sqrt(dz21*dz21 + dr21*dr21);
519 float invL = 1.0/L;
520 float sinF = dr21*invL;
521 float cosF = dz21*invL;
522
523 for(const auto& vb : m_vBoundaries) {
524
525 if (z1 < vb.m_zr[0] && z2 < vb.m_zr[0]) continue;
526 if (z1 > vb.m_zr[1] && z2 > vb.m_zr[1]) continue;
527 if (r1 < vb.m_zr[2] && r2 < vb.m_zr[2]) continue;
528 if (r1 > vb.m_zr[3] && r2 > vb.m_zr[3]) continue;
529
530 //corners:
531
532 float zc[4] = {vb.m_zr[0], vb.m_zr[1], vb.m_zr[1], vb.m_zr[0]};
533 float rc[4] = {vb.m_zr[2], vb.m_zr[2], vb.m_zr[3], vb.m_zr[3]};
534
535 int nUp(0), nDn(0);
536
537 float minDistances[4];
538
539 for (int ic=0;ic<4;ic++) {
540 minDistances[ic] = (rc[ic] - r1)*cosF - (zc[ic] - z1)*sinF;
541 }
542
543 float minH = std::abs(minDistances[0]);
544
545 for (int ic=0;ic<4;ic++) {
546 float h = minDistances[ic];
547 if (h <=0) nDn += 1;
548 else nUp += 1;
549 if(std::abs(h) < minH) minH = std::abs(h);
550 }
551
552 if (nUp == 4 || nDn == 4) {
553 if(minH > maxCornerDist) {//the closest corner is still too far
554 continue;
555 }
556 }
557
558 //search through layers inside the volume
559
560 for(auto lIdx : vb.m_layers) {
561 const auto& lb = m_lBoundaries.at(lIdx);
562 for(int s1=0;s1<lb.m_nVertices-1;s1++) {
563 int s2 = s1 + 1;
564
565 float h1 = (lb.m_r[s1] - r1)*cosF - (lb.m_z[s1] - z1)*sinF;
566 float h2 = (lb.m_r[s2] - r1)*cosF - (lb.m_z[s2] - z1)*sinF;
567 if (h1*h2 > 0) continue;
568 float l1 = (lb.m_z[s1] - z1)*cosF + (lb.m_r[s1] - r1)*sinF;
569 float l2 = (lb.m_z[s2] - z1)*cosF + (lb.m_r[s2] - r1)*sinF;
570 if (l1 < 0 && l2 < 0) continue;
571 if (l1 > L && l2 > L) continue;
572 float lx = (l1 + (l2-l1)*h1/(h1-h2))*invL;
573
574 if (lx < 0 || lx > 1) continue;
575 float zx = z2*lx + (1-lx)*z1;
576 float rx = r2*lx + (1-lx)*r1;
577
578 auto radItr = rzIntervals.find(lb.m_lay_id);
579
580 if(radItr == rzIntervals.end()) {
581 rzIntervals.insert(std::make_pair(lb.m_lay_id, SearchInterval(zx, rx)));
582 }
583 else {
584 (*radItr).second.addPoint(zx, rx);
585 }
586 }
587 }
588 }
589 }
590
591 //3. parabolic extrapolation in r-phi
592
593 unsigned int sp1Idx = 0;
594 unsigned int sp3Idx = nSP-1;
595 unsigned int sp2Idx = (sp3Idx+sp1Idx)/2;
596
597 //3a. Converting XY coords to UV coords
598
599 float uv_coords[2][2];
600
601 float dx = seed.at(sp3Idx)->globalPosition().x() - seed.at(sp2Idx)->globalPosition().x();
602 float dy = seed.at(sp3Idx)->globalPosition().y() - seed.at(sp2Idx)->globalPosition().y();
603
604 uv_coords[1][0] = -std::sqrt(dx*dx + dy*dy);
605 uv_coords[1][1] = 0.0;
606
607 float cos_theta = dx/(-uv_coords[1][0]);
608 float sin_theta = dy/(-uv_coords[1][0]);
609
610 float rot_matrix[2][2];
611 float inv_rot_matrix[2][2];
612
613 rot_matrix[0][0] = cos_theta;
614 rot_matrix[0][1] = sin_theta;
615 rot_matrix[1][0] = -sin_theta;
616 rot_matrix[1][1] = cos_theta;
617
618 inv_rot_matrix[0][0] = cos_theta;
619 inv_rot_matrix[0][1] = -sin_theta;
620 inv_rot_matrix[1][0] = sin_theta;
621 inv_rot_matrix[1][1] = cos_theta;
622
623 float sp3_coords[3];
624 sp3_coords[0] = seed.at(sp3Idx)->globalPosition().x();
625 sp3_coords[1] = seed.at(sp3Idx)->globalPosition().y();
626 sp3_coords[2] = seed.at(sp3Idx)->globalPosition().z();
627
628 //UV-coordinates of the XY origin (0,0)
629
630 float u_c = rot_matrix[0][0]*(0-sp3_coords[0]) + rot_matrix[0][1]*(0-sp3_coords[1]);
631 float v_c = rot_matrix[1][0]*(0-sp3_coords[0]) + rot_matrix[1][1]*(0-sp3_coords[1]);
632
633 int sign_up = u_c < 0 ? 1 : -1;
634
635 //transforming SP1
636
637 float dR1[2];
638
639 dR1[0] = seed.at(sp1Idx)->globalPosition().x() - sp3_coords[0];
640 dR1[1] = seed.at(sp1Idx)->globalPosition().y() - sp3_coords[1];
641
642 uv_coords[0][0] = rot_matrix[0][0]*dR1[0] + rot_matrix[0][1]*dR1[1];
643 uv_coords[0][1] = rot_matrix[1][0]*dR1[0] + rot_matrix[1][1]*dR1[1];
644
645 //3b. parameters of the parabola in the u-v c.s.
646
647 float a = uv_coords[0][1]/(uv_coords[0][0]*(uv_coords[0][0]-uv_coords[1][0]));
648 float b = -a*uv_coords[1][0]; // b = -a*x2
649
650 //3c. calculate impact point radii
651
652 std::vector<unsigned int> pixelHashIds;
653 std::vector<unsigned int> stripHashIds;
654
655 for(auto& ip : rzIntervals) {
656
657 float R = ip.second.getAverageRadius();
658
659 float R2 = R*R;
660
661 float dRv = R2-v_c*v_c;
662
663 if(dRv < 0) continue;//no intersection with the circle
664
665 float u_p = u_c + sign_up*std::sqrt(dRv);
666
667 float v_p = b*u_p + a*u_p*u_p;
668 float dv2 = (v_p-v_c)*(v_p-v_c);
669
670 if (R2-dv2<0) continue; // check for intersection between v=v_p and the circle
671
672 float u_star = u_c + sign_up*std::sqrt(R2-dv2);
673 float v_star = b*u_star + a*u_star*u_star;
674
675 float x_star = inv_rot_matrix[0][0]*u_star + inv_rot_matrix[0][1]*v_star + sp3_coords[0];
676 float y_star = inv_rot_matrix[1][0]*u_star + inv_rot_matrix[1][1]*v_star + sp3_coords[1];
677
678 ip.second.m_r = std::sqrt(x_star*x_star + y_star*y_star);
679 ip.second.m_phi = std::atan2(y_star, x_star);
680
681 if(ip.first > 15000) {//assuming Pixel-only seeds
682
683 bool hasHit = false;
684
685 for(unsigned int i=1;i<nSP-1;i++) {
686
687 float dpr = ip.second.m_r - zr[i][1];
688 float dpz = ip.second.m_z - zr[i][0];
689 float dist = std::sqrt(dpr*dpr + dpz*dpz);
690 if(dist < maxCornerDist) {
691 hasHit = true;
692 break;
693 }
694 }
695 findDetectorElements(ip.first, ip.second, pixelHashIds, hasHit);
696 }
697 else {
698 findDetectorElements(ip.first, ip.second, stripHashIds, false);
699 }
700 }
701
702 std::set<unsigned int> pixelHashSet(pixelHashIds.begin(), pixelHashIds.end());
703
704 for(auto id : seedHashes) {
705 if(pixelHashSet.find(id) == pixelHashSet.end()) pixelHashIds.push_back(id);
706 }
707
708 std::vector<std::pair<float, const InDetDD::SiDetectorElement*> > theRoad;
709
710 for(auto hash_id : pixelHashIds) {
711 const InDetDD::SiDetectorElement *p = m_pixelManager->getDetectorElement(hash_id);
712 if(p == nullptr) continue;
713 const Amg::Vector3D& C = p->center();
714 float dist = std::sqrt(C(0)*C(0) + C(1)*C(1) + C(2)*C(2));
715 theRoad.push_back(std::make_pair(dist,p));
716 }
717
718 for(auto hash_id : stripHashIds) {
719 const InDetDD::SiDetectorElement *p = m_stripManager->getDetectorElement(hash_id);
720 if(p == nullptr) continue;
721 const Amg::Vector3D& C = p->center();
722 float dist = std::sqrt(C(0)*C(0) + C(1)*C(1) + C(2)*C(2));
723 theRoad.push_back(std::make_pair(dist,p));
724 }
725
726 std::sort(theRoad.begin(), theRoad.end());
727
728 for(const auto & dp : theRoad) {
729 road.push_back(dp.second);
730 }
731
732 return (int)theRoad.size();
733}
#define M_PI
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
static Double_t sp
static Double_t a
static Double_t sc
static Double_t rc
This is an Identifier helper class for the Pixel subdetector.
#define y
#define x
#define z
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
Class to hold geometrical description of a silicon detector element.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
void addNewElement(unsigned int, short, short, const InDetDD::SiDetectorElement *)
std::vector< VolumeBoundary > m_vBoundaries
std::vector< LayerBoundary > m_lBoundaries
std::map< unsigned int, LayerDescription > m_layerMap
Gaudi::Property< float > m_max_rphi_rw
void findDetectorElements(unsigned int, const SearchInterval &, std::vector< unsigned int > &, bool) const
virtual StatusCode initialize() override
Gaudi::Property< float > m_min_phi_rw
const InDetDD::SCT_DetectorManager * m_stripManager
Gaudi::Property< float > m_max_phi_rw
TrigInDetRoadPredictorTool(const std::string &, const std::string &, const IInterface *)
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Gaudi::Property< float > m_min_rphi_rw
const InDetDD::PixelDetectorManager * m_pixelManager
ToolHandle< ITrigL2LayerNumberTool > m_layerNumberTool
virtual int getRoad(const std::vector< const Trk::SpacePoint * > &, std::vector< const InDetDD::SiDetectorElement * > &, const EventContext &) const override
int lb
Definition globals.cxx:23
int r
Definition globals.cxx:22
struct color C
Eigen::Matrix< double, 3, 1 > Vector3D
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
#define unlikely(x)