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