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();