22 #include "GaudiKernel/SystemOfUnits.h"
33 declareInterface< ITrigInDetRoadPredictorTool >(
this );
56 return StatusCode::SUCCESS;
61 unsigned int hash =
p->identifyHash();
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();
71 float dPhi[4] = {de_wmax, de_wmin, -de_wmin, -de_wmax};
72 float dEta[4] = {de_len, -de_len, -de_len, de_len};
78 for(
int ic=0;
ic<4;
ic++) {
84 ded.
m_c[
ic][2] = std::atan2(
y,
x);
89 short prim_idx = L.m_mappingType != 2 ? phi_idx : eta_idx;
90 short sec_idx = L.m_mappingType != 2 ? eta_idx : phi_idx;
92 if(L.m_mappingType == 0) {
103 if(L.m_mappingType == 1) {
114 if(L.m_mappingType == 2) {
115 ded.
m_ref = std::atan2(
C.y(),
C.x());
129 if(L.m_nSubLayers == 2 && (
hash % 2) != 0) {
133 if(L.m_colls[ detColIdx].find(prim_idx) == L.m_colls[ detColIdx].end()) {
135 float primBounds[2] = {0,0};
136 if(L.m_mappingType == 2) {
137 primBounds[0] =
p->rMin();
138 primBounds[1] =
p->rMax();
141 primBounds[0] =
p->phiMin();
142 primBounds[1] =
p->phiMax();
146 L.m_colls[ detColIdx].insert(std::make_pair(prim_idx, dc));
149 (*L.m_colls[detColIdx].find(prim_idx)).
second.m_vDE.push_back(ded);
157 const std::vector<TrigInDetSiLayer>& SiL = *(
m_layerNumberTool->layerGeometry());
163 if(std::abs(barrel_ec)>2)
continue;
165 unsigned int layerID = SiL.at(vPixelL.at(
hash)).m_subdet;
166 unsigned int volumeID = layerID / 1000;
171 unsigned int mappingType = 1;
173 if(barrel_ec == 0) mappingType = 0;
175 if(volumeID == 12 || volumeID == 14) mappingType = 2;
177 m_layerMap.try_emplace(layerID, layerID, nSubLayers, mappingType);
192 if(std::abs(barrel_ec)>2)
continue;
194 unsigned int layerID = SiL.at(vStripL.at(
hash)).m_subdet;
195 unsigned int volumeID = layerID / 1000;
199 unsigned int mappingType = 1;
201 if(barrel_ec == 0) mappingType = 0;
203 if(volumeID == 12 || volumeID == 14) mappingType = 2;
205 m_layerMap.try_emplace(layerID, layerID, nSubLayers, mappingType);
222 const float margin_r = 3.0;
223 const float margin_z = 3.0;
227 unsigned int layerID =
l.first;
228 unsigned int volumeID = layerID / 1000;
230 const auto& L =
l.second;
239 memset(&vert[0][0],0,
sizeof(vert));
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) {
245 float r = de.m_c[
ic][0];
246 float z = de.m_c[
ic][1];
272 vert[0][1] -= margin_r;
274 vert[1][0] -= margin_z;
276 vert[2][1] += margin_r;
278 vert[3][0] += margin_z;
280 int new_layer_index = -1;
283 lb.m_index = new_layer_index;
284 lb.m_lay_id = layerID;
287 if(volumeID == 73 || volumeID == 75 || volumeID == 77) {
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]};
291 else if(volumeID == 93 || volumeID == 95 || volumeID == 97) {
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]};
296 lb.m_z = {maxZ, minZ, minZ, maxZ, maxZ};
297 lb.m_r = {maxR, maxR, minR, minR, maxR};
302 bool volExists =
false;
305 if(
v.m_vol_id == (
int)volumeID) {
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);
317 vb.
m_layers.push_back(new_layer_index);
330 std::vector<unsigned int>& vIDs,
bool hasHit)
const {
335 float phi_test = searchArea.
m_phi;
336 float phi_res = road_width_rphi/searchArea.
m_r;
341 float phi_min = phi_test - phi_res;
342 float phi_max = phi_test + phi_res;
346 if(L.m_mappingType != 2) {
348 float rz_test_m = searchArea.
getMinR();
349 float rz_test_p = searchArea.
getMaxR();
351 if(L.m_mappingType == 0) {
352 rz_test_m = searchArea.
getMinZ();
353 rz_test_p = searchArea.
getMaxZ();
356 rz_test_m -= road_width_rz;
357 rz_test_p += road_width_rz;
359 for(
int iSubL = 0; iSubL < L.m_nSubLayers;iSubL++) {
361 for(
const auto& prim : L.m_colls[iSubL]) {
363 const auto&
slice = prim.second;
369 if(phi_max <
f1)
continue;
370 if(phi_min >
f2)
continue;
374 if(phi_test < 0 && phi_min >
f1)
continue;
375 if(phi_test > 0 && phi_max <
f2)
continue;
378 for(
const auto& de :
slice.m_vDE) {
380 float p1 = de.m_minBound;
381 float p2 = de.m_maxBound;
383 if(rz_test_p <
p1)
break;
384 if(rz_test_m >
p2)
continue;
386 if (! (rz_test_p < p1 || rz_test_m >
p2)) vIDs.push_back(de.m_hash);
393 float r_test_m = searchArea.
getMinR() - road_width_rz;
394 float r_test_p = searchArea.
getMaxR() + road_width_rz;
396 for(
int iSubL = 0; iSubL < L.m_nSubLayers;iSubL++) {
398 for(
const auto& prim : L.m_colls[iSubL]) {
400 const auto&
slice = prim.second;
402 float r1 =
slice.m_minCoord;
403 float r2 =
slice.m_maxCoord;
405 if(r_test_p < r1)
break;
406 if(r_test_m > r2)
continue;
408 if (! (r_test_p < r1 || r_test_m > r2)) {
410 for(
const auto& de :
slice.m_vDE) {
412 float f1 = de.m_minBound;
413 float f2 = de.m_maxBound;
416 if(phi_max <
f1)
continue;
417 if(phi_min >
f2)
continue;
420 if(phi_test < 0 && phi_min >
f1)
continue;
421 if(phi_test > 0 && phi_max <
f2)
continue;
423 vIDs.push_back(de.m_hash);
436 std::vector<const InDetDD::SiDetectorElement*>& road,
437 const EventContext& ctx)
const {
440 const float MAX_R = 1030.0;
441 const float MAX_Z = 3000.0;
442 const float maxCornerDist = 15.0;
449 if (!fieldCondObj.isValid()) {
454 fieldCondObj->getInitializedCache (fieldCache);
458 unsigned int nSP = seed.size();
460 if(nSP < 3)
return -2;
462 std::vector<unsigned int> seedHashes;
464 for(
unsigned int spIdx=0;spIdx<nSP;spIdx++) {
465 const auto& sp = seed.at(spIdx);
469 seedHashes.push_back(
hash);
472 std::vector<std::array<float,2> > zr;
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();
483 zr[0][0] = zr[1][0] - zr[1][1]*(zr[2][0]-zr[1][0])/(zr[2][1]-zr[1][1]);
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]);
490 if (std::fabs(zlast) > MAX_Z) {
491 if(zlast > 0) 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]);
495 zr[nSP+1][0] = zlast;
496 zr[nSP+1][1] = rlast;
498 std::map<unsigned int, SearchInterval> rzIntervals;
500 for(
unsigned int k1 = 0;k1<zr.size()-1;k1++) {
502 unsigned int k2 = k1+1;
504 float z1 = zr[k1][0];
505 float r1 = zr[k1][1];
506 float z2 = zr[k2][0];
507 float r2 = zr[k2][1];
510 float L = std::sqrt(dz21*dz21 + dr21*dr21);
512 float sinF = dr21*invL;
513 float cosF = dz21*invL;
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;
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]};
529 float minDistances[4];
531 for (
int ic=0;
ic<4;
ic++) {
532 minDistances[
ic] = (rc[
ic] - r1)*cosF - (zc[
ic] - z1)*sinF;
535 float minH = std::abs(minDistances[0]);
537 for (
int ic=0;
ic<4;
ic++) {
538 float h = minDistances[
ic];
541 if(std::abs(
h) < minH) minH = std::abs(
h);
544 if (nUp == 4 || nDn == 4) {
545 if(minH > maxCornerDist) {
552 for(
auto lIdx : vb.m_layers) {
554 for(
int s1=0;
s1<
lb.m_nVertices-1;
s1++) {
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;
566 if (lx < 0 || lx > 1)
continue;
567 float zx = z2*lx + (1-lx)*z1;
568 float rx = r2*lx + (1-lx)*r1;
570 auto radItr = rzIntervals.find(
lb.m_lay_id);
572 if(radItr == rzIntervals.end()) {
576 (*radItr).second.addPoint(zx, rx);
585 unsigned int sp1Idx = 0;
586 unsigned int sp3Idx = nSP-1;
587 unsigned int sp2Idx = (sp3Idx+sp1Idx)/2;
591 float uv_coords[2][2];
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();
596 uv_coords[1][0] = -std::sqrt(
dx*
dx +
dy*
dy);
597 uv_coords[1][1] = 0.0;
599 float cos_theta =
dx/(-uv_coords[1][0]);
600 float sin_theta =
dy/(-uv_coords[1][0]);
602 float rot_matrix[2][2];
603 float inv_rot_matrix[2][2];
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;
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;
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();
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]);
625 int sign_up = u_c < 0 ? 1 : -1;
631 dR1[0] = seed.at(sp1Idx)->globalPosition().x() - sp3_coords[0];
632 dR1[1] = seed.at(sp1Idx)->globalPosition().y() - sp3_coords[1];
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];
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];
644 std::vector<unsigned int> pixelHashIds;
645 std::vector<unsigned int> stripHashIds;
647 for(
auto&
ip : rzIntervals) {
649 float R =
ip.second.getAverageRadius();
653 float dRv = R2-v_c*v_c;
655 if(dRv < 0)
continue;
657 float u_p = u_c + sign_up*std::sqrt(dRv);
659 float v_p =
b*u_p +
a*u_p*u_p;
660 float dv2 = (v_p-v_c)*(v_p-v_c);
662 if (R2-dv2<0)
continue;
664 float u_star = u_c + sign_up*std::sqrt(R2-dv2);
665 float v_star =
b*u_star +
a*u_star*u_star;
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];
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);
673 if(
ip.first > 15000) {
677 for(
unsigned int i=1;
i<nSP-1;
i++) {
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) {
694 std::set<unsigned int> pixelHashSet(pixelHashIds.begin(), pixelHashIds.end());
696 for(
auto id : seedHashes) {
697 if(pixelHashSet.find(
id) == pixelHashSet.end()) pixelHashIds.push_back(
id);
700 std::vector<std::pair<float, const InDetDD::SiDetectorElement*> > theRoad;
702 for(
auto hash_id : pixelHashIds) {
704 if(
p ==
nullptr)
continue;
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));
710 for(
auto hash_id : stripHashIds) {
712 if(
p ==
nullptr)
continue;
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));
718 std::sort(theRoad.begin(), theRoad.end());
720 for(
const auto &
dp : theRoad) {
721 road.push_back(
dp.second);
724 return (
int)theRoad.size();