8#include "GaudiKernel/SystemOfUnits.h"
38#include <unordered_map>
42 for(
int i=0;i<5;i++)
m_Xk[i] =
m_Xk[i+5] =
P[i];
55 for(
int i=0;i<5;i++) {
64 m_track.emplace_front(
nullptr,
nullptr,
nullptr, 0, -1);
67 m_track.emplace_back(
nullptr,
nullptr,
nullptr, 0, -1);
92 cov[idx++] =
m_Gk[i][j];
95 m_track.emplace_front(pPRD,
m_Xk, &cov[0], dchi2, ndof);
98 m_track.emplace_back(pPRD,
m_Xk, &cov[0], dchi2, ndof);
114 memcpy(&tmpX[0], &
m_Xk[0],
sizeof(tmpX));
116 for(
int i=0;i<5;i++) {
122 memcpy(&tmpG[0][0], &
m_Gk[0][0],
sizeof(tmpG));
126 for(
int i=0;i<5;i++) {
127 for(
int j=0;j<5;j++) {
128 m_Gk[i+5][j+5] = tmpG[i][j];
129 m_Gk[i][j] = tmpG[i+5][j+5];
130 m_Gk[i][j+5] = tmpG[i+5][j];
131 m_Gk[i+5][j] = tmpG[i][j+5];
138 for(
int i=0;i<4;i++) std::cout<<
m_Xk[i]<<
" ";
139 std::cout<<1/
m_Xk[4]<<
" "<<std::sin(
m_Xk[3])/
m_Xk[4]<<std::endl;
142 std::cout<<
"Covariance at last point:"<<std::endl;
144 for(
int i=0;i<5;i++) {
145 for(
int j=0;j<5;j++) std::cout<<
m_Gk[i][j]<<
" ";
146 std::cout<<std::endl;
150 for(
int i=0;i<4;i++) std::cout<<
m_Xk[i+5]<<
" ";
151 std::cout<<1/
m_Xk[4+5]<<
" "<<std::sin(
m_Xk[3+5])/
m_Xk[4+5]<<std::endl;
152 std::cout<<std::endl;
154 std::cout<<
"Covariance at the first point:"<<std::endl;
156 for(
int i=0;i<5;i++) {
157 for(
int j=0;j<5;j++) std::cout<<
m_Gk[i+5][j+5]<<
" ";
158 std::cout<<std::endl;
167 const std::string& n,
170 declareInterface< ITrigInDetTrackFollowingTool >(
this );
187 return StatusCode::SUCCESS;
191 return StatusCode::SUCCESS;
199 double bestDist = 1e8;
201 for(
const auto pPRD : *pColl) {
203 double rx = std::fabs(pPRD->localPosition().x() - TP[0]);
206 double ry = std::fabs(pPRD->localPosition().y() - TP[1]);
209 double dist = std::pow(5*rx,2) + std::pow(ry,2);
211 if(dist < bestDist) {
217 if(bestHit !=
nullptr) {
218 hitLinks.emplace_back(std::make_tuple(bestDist, bestHit, moduleIdx));
225 float bestDist = 1e8;
227 for(
const auto pPRD : *pColl) {
232 rx = std::fabs(pPRD->localPosition().x() - TP[0]);
236 double meas_x = pPRD->localPosition().x();
237 double meas_y = pPRD->localPosition().y();
239 double e00 = pPRD->localCovariance()(0, 0);
240 double e01 = pPRD->localCovariance()(0, 1);
241 double e11 = pPRD->localCovariance()(1, 1);
243 double beta = 0.5*std::atan(2*e01/(e00-e11));
245 sincos(beta, &sinB, &cosB);
247 rx = std::fabs((meas_x - TP[0])*cosB + (meas_y - TP[1])*sinB);
257 if(bestHit !=
nullptr) {
258 hitLinks.emplace_back(std::make_tuple(bestDist, bestHit, moduleIdx));
264 double cluster_cov[2];
272 cluster_cov[1] = pPRD->
width().
z();
273 for(
int i=0;i<2;i++) cluster_cov[i] *= cluster_cov[i]/12.0;
276 double covsum[2][2] = {{ets.
m_Gk[0][0] + cluster_cov[0], ets.
m_Gk[0][1]}, {ets.
m_Gk[0][1], ets.
m_Gk[1][1] + cluster_cov[1]}};
278 double detr = 1/(covsum[0][0]*covsum[1][1] - covsum[0][1]*covsum[1][0]);
280 invcov[0] = detr*covsum[1][1];
281 invcov[1] = -detr*covsum[1][0];
282 invcov[2] = detr*covsum[0][0];
287 return (resid[0]*(resid[0]*invcov[0] + resid[1]*invcov[1]) + resid[1]*(resid[0]*invcov[1] + resid[1]*invcov[2]));
304 invcov = 1/(ets.
m_Gk[0][0] + covX);
318 double beta = 0.5*std::atan(2*e01/(e00-e11));
320 sincos(beta, &sinB, &cosB);
322 resid = (meas_x - ets.
m_Xk[0])*cosB + (meas_y - ets.
m_Xk[1])*sinB;
327 double track_cov = cosB*cosB*(ets.
m_Gk[0][0]+e00) + 2*cosB*sinB*(ets.
m_Gk[0][1]+e01) + sinB*sinB*(ets.
m_Gk[1][1]+e11);
329 invcov = 1/track_cov;
332 return (resid * resid * invcov);
342 double dchi2 =
processHit(pInputHit, resid, invcov, ets);
350 for(
int i=0;i<10;i++) {
351 CHT[i][0] = ets.
m_Gk[i][0];
352 CHT[i][1] = ets.
m_Gk[i][1];
356 double V[2][2] = {{invcov[0], invcov[1]}, {invcov[1], invcov[2]}};
358 for(
int i=0;i<10;i++)
359 for(
int j=0;j<2;j++) Gain[i][j] = CHT[i][0]*V[0][j] + CHT[i][1]*V[1][j];
361 for(
int i=0;i<10;i++) {
362 ets.
m_Xk[i] += Gain[i][0]*resid[0] + Gain[i][1]*resid[1];
364 for(
int j=0;j<=i;j++) {
365 ets.
m_Gk[i][j] = ets.
m_Gk[i][j] - (Gain[i][0]*CHT[j][0] + Gain[i][1]*CHT[j][1]);
370 ets.
AddHit(pInputHit, dchi2, 2);
378 double resid, invcov;
385 dchi2 =
processHit(pInputHit, shape, resid, invcov,
H, ets);
389 double CHT[10], Gain[10];
391 for(
int i=0;i<10;i++) {
392 CHT[i] = ets.
m_Gk[i][0];
393 Gain[i] = CHT[i] * invcov;
396 for(
int i=0;i<10;i++) {
397 ets.
m_Xk[i] += Gain[i]*resid;
398 for(
int j=0;j<=i;j++) {
399 ets.
m_Gk[i][j] = ets.
m_Gk[i][j] - Gain[i]*CHT[j];
408 double stripHalfLength = std::sqrt(3*covY);
410 double dY = ets.
m_Xk[1] - stripCentre;
412 if(dY > stripHalfLength) {
413 ets.
m_Xk[1] = stripCentre + stripHalfLength;
416 if(dY < -stripHalfLength) {
417 ets.
m_Xk[1] = stripCentre - stripHalfLength;
422 dchi2 =
processHit(pInputHit, shape, resid, invcov,
H, ets);
426 double CHT[10], Gain[10];
428 for(
int i=0;i<10;i++) {
429 CHT[i] =
H[0]*ets.
m_Gk[i][0] +
H[1]*ets.
m_Gk[i][1];
430 Gain[i] = CHT[i] * invcov;
433 for(
int i=0;i<10;i++) {
434 ets.
m_Xk[i] += Gain[i]*resid;
435 for(
int j=0;j<=i;j++) {
436 ets.
m_Gk[i][j] = ets.
m_Gk[i][j] - Gain[i]*CHT[j];
442 ets.
AddHit(pInputHit, dchi2, 1);
459 double dsp[2] = {pe[0]-pb[0], pe[1]-pb[1]};
460 double Lsp = std::sqrt(dsp[0]*dsp[0] + dsp[1]*dsp[1]);
461 double cosA = dsp[0]/Lsp;
462 double sinA = dsp[1]/Lsp;
465 double dxm = pm[0] - pb[0];
466 double dym = pm[1] - pb[1];
468 double x1 = dxm*cosA + dym*sinA;
469 double m1 = -dxm*sinA + dym*cosA;
471 double a_parab = -2*m1/(x1*(Lsp-x1));
472 double b_parab = -0.5*a_parab*Lsp;
474 double Rx[3] = {0,b_parab,a_parab};
475 double Ry[2] = {pb[2],
tau0};
480 memset(&Cx[0][0],0,
sizeof(Cx));
485 memset(&Cy[0][0],0,
sizeof(Cy));
496 memset(&Fx[0][0],0,
sizeof(Fx));
501 memset(&Fy[0][0],0,
sizeof(Fy));
505 double sigma_x2 = std::pow(0.08,2);
506 double sigma_y2 = std::pow(0.3,2);
508 for(
const auto&
sp : seed) {
512 double pk[3] = {
sp->globalPosition().x(),
sp->globalPosition().y(),
sp->globalPosition().z()};
514 double dx = pk[0] - pb[0];
515 double dy = pk[1] - pb[1];
517 double dist = dx*cosA + dy*sinA;
518 double measx =-dx*sinA + dy*cosA;
519 double measy = pk[2];
521 double ds = dist - path;
525 double rk =
sp->globalPosition().perp();
526 double dr = rk - radius;
531 Fx[0][2] = 0.5*ds*ds;
539 double Rex[3] = {Rx[0], Rx[1], Rx[2]};
541 Rex[0] += Fx[0][1]*Rx[1] + Fx[0][2]*Rx[2];
542 Rex[1] += Fx[1][2]*Rx[2];
544 double Cex[3][3], CFT[3][3];
546 for(
int i=0;i<3;i++) {
547 for(
int j=0;j<3;j++) {
549 for(
int m=0;m<3;m++) CFT[i][j] += Cx[i][m]*Fx[j][m];
552 for(
int i=0;i<3;i++) {
553 for(
int j=0;j<3;j++) {
555 for(
int m=0;m<3;m++) Cex[i][j] += Fx[i][m]*CFT[m][j];
559 double Rey[2] = {Ry[0], Ry[1]};
561 Rey[0] += Fy[0][1]*Ry[1];
565 for(
int i=0;i<2;i++) {
566 for(
int j=0;j<2;j++) {
568 for(
int m=0;m<2;m++) CFT[i][j] += Cy[i][m]*Fy[j][m];
571 for(
int i=0;i<2;i++) {
572 for(
int j=0;j<2;j++) {
574 for(
int m=0;m<2;m++) Cey[i][j] += Fy[i][m]*CFT[m][j];
580 double CHTx[3] = {Cex[0][0], Cex[0][1], Cex[0][2]};
581 double Dx = 1/(Cex[0][0] + sigma_x2);
583 double resid = measx - Rex[0];
585 double Kx[3] = {Dx*CHTx[0], Dx*CHTx[1], Dx*CHTx[2]};
587 for(
int i=0;i<3;i++) Rx[i] = Rex[i] + Kx[i]*resid;
588 for(
int i=0;i<3;i++) {
589 for(
int j=0;j<3;j++) {
590 Cx[i][j] = Cex[i][j] - Kx[i]*CHTx[j];
594 double CHTy[2] = {Cey[0][0], Cey[0][1]};
595 double Dy = 1/(Cey[0][0] + sigma_y2);
597 resid = measy - Rey[0];
599 double Ky[2] = {Dy*CHTy[0], Dy*CHTy[1]};
601 for(
int i=0;i<2;i++) Ry[i] = Rey[i] + Ky[i]*resid;
602 for(
int i=0;i<2;i++) {
603 for(
int j=0;j<2;j++) {
604 Cy[i][j] = Cey[i][j] - Ky[i]*CHTy[j];
621 if(thePlane ==
nullptr)
return nullptr;
625 P0[2] = std::atan2(sinA + Rx[1]*cosA, cosA - Rx[1]*sinA);
626 P0[3] = std::atan2(1, Ry[1]);
627 double coeff = 1.0/(300.0*
B0[2]*std::sqrt(1+Ry[1]*Ry[1]));
628 P0[4] = -Rx[2]*coeff;
629 P0[5] = Cx[2][2]*coeff*coeff;
631 return std::make_unique<TrigFTF_ExtendedTrackState>(P0, thePlane);
647 fieldCondObj->getInitializedCache (fieldCache);
658 const InDet::PixelClusterContainer* p_pixcontainer = pixcontainer.
ptr();
667 const InDet::SCT_ClusterContainer* p_sctcontainer = sctcontainer.
ptr();
671 int nModules = road.size();
673 std::vector<const Trk::PrepRawData*> assignedHits(nModules,
nullptr);
675 std::vector<int> moduleStatus(nModules, 0);
677 std::vector<Identifier> seedIdents;
678 std::vector<const Trk::PrepRawData*> seedHits;
680 for(
const auto&
sp : seed) {
683 seedHits.push_back(prd);
684 prd =
sp->clusterList().second;
685 if(prd ==
nullptr)
continue;
687 seedHits.push_back(prd);
692 unsigned int seedSize = seedIdents.size();
693 int nUnassigned = seedSize;
695 int startModuleIdx = -1;
697 for(
int moduleIdx = 0;moduleIdx<nModules;moduleIdx++) {
699 Identifier ident = road.at(moduleIdx)->identify();
701 for(
unsigned int clIdx=0;clIdx<seedSize;clIdx++) {
703 if(seedIdents[clIdx] != ident)
continue;
705 assignedHits[moduleIdx] = seedHits[clIdx];
706 moduleStatus[moduleIdx] = 1;
708 startModuleIdx = moduleIdx;
713 if(nUnassigned == 0)
break;
716 if(nUnassigned > 0)
return nullptr;
718 std::unique_ptr<TrigFTF_ExtendedTrackState> initialState =
fitTheSeed(seed, fieldCache);
720 if(initialState ==
nullptr)
return nullptr;
722 initialState->correctAngles();
728 std::vector<int> layerSequence[2];
729 std::unordered_map<int, std::vector<int> > layerMap[2];
734 for(
int passIdx=0;passIdx<2;passIdx++) {
736 int start = passIdx==0 ? startModuleIdx + 1 : startModuleIdx;
737 int end = passIdx==0 ? nModules : -1;
738 int step = passIdx==0 ? 1 : -1;
740 for(
int moduleIdx = start;moduleIdx!=end;moduleIdx+=step) {
743 int l = de->
isPixel() ? vPixelL.at(
h) : vStripL.at(
h);
750 auto it = layerMap[passIdx].find(l);
751 if(it != layerMap[passIdx].end()) (*it).second.push_back(moduleIdx);
753 layerSequence[passIdx].push_back(l);
754 std::vector<int> v = {moduleIdx};
755 layerMap[passIdx].insert(std::make_pair(l,v));
762 for(
int passIdx=0;passIdx<2;passIdx++) {
764 for(
const auto& lkey : layerSequence[passIdx]) {
770 const auto& lp = (*layerMap[passIdx].find(lkey));
774 std::vector<std::tuple<double, const Trk::PrepRawData*, int> > hitLinks;
776 for(
const auto& moduleIdx : lp.second) {
778 if(moduleIdx == startModuleIdx) {
782 if(moduleStatus[moduleIdx] < 0)
continue;
784 if (assignedHits[moduleIdx] !=
nullptr) {
785 hitLinks.emplace_back(std::make_tuple(-1.0,assignedHits[moduleIdx],moduleIdx));
800 noHits = (p_pixcontainer ==
nullptr) || ((*p_pixcontainer).indexFindPtr(moduleHash) ==
nullptr);
802 noHits = (p_sctcontainer ==
nullptr) || ((*p_sctcontainer).indexFindPtr(moduleHash) ==
nullptr);
806 moduleStatus[moduleIdx] = -3;
814 double trackParams[2];
817 moduleStatus[moduleIdx] = -2;
821 const double bound_tol = 0.2;
826 moduleStatus[moduleIdx] = -2;
832 moduleStatus[moduleIdx] = -4;
835 findNearestHit(moduleIdx, (*p_pixcontainer).indexFindPtr(moduleHash), trackParams, hitLinks);
844 if(hitLinks.empty()) {
851 std::sort(hitLinks.begin(), hitLinks.end());
855 for(
const auto& hl : hitLinks) {
857 int moduleIdx =
get<2>(hl);
870 moduleStatus[moduleIdx] = -2;
885 if(acceptedHit ==
nullptr) {
889 assignedHits[moduleIdx] = acceptedHit;
890 moduleStatus[moduleIdx] = de->
isPixel() ? 2 : 3;
900 double chi2tot = theState.
m_chi2;
916 int ndoftot = theState.
m_ndof;
917 double qOverP = theState.
m_Xk[4];
918 double pt = std::sin(theState.
m_Xk[3])/qOverP;
919 double phi0 = theState.
m_Xk[2];
922 double z0 = theState.
m_Xk[1];
923 double d0 = theState.
m_Xk[0];
925 bool bad_cov =
false;
929 for(
int i=0;i<5;i++) {
930 for(
int j=0;j<=i;j++) {
931 double c = theState.
m_Gk[i][j];
932 if (i == j && c < 0) {
934 ATH_MSG_DEBUG(
"REGTEST: cov(" << i <<
"," << i <<
") =" << c <<
" < 0, reject track");
937 cov.fillSymmetric(i,j, c);
941 if((ndoftot<0) || (fabs(pt)<100.0) || (std::isnan(pt)) || bad_cov) {
942 ATH_MSG_DEBUG(
"Track following failed - possibly floating point problem");
950 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> perType;
953 auto pParVec = std::make_unique<Trk::TrackStates>();
955 pParVec->reserve(50);
958 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> rioType(0);
962 for(
const auto& ha : theState.
m_track) {
966 if(pPRD ==
nullptr)
continue;
970 int ndof = ha.m_ndof;
974 if(pPS==
nullptr)
continue;
984 std::unique_ptr<Trk::MeasurementBase> pRIO{};
989 pRIO = std::make_unique<InDet::PixelClusterOnTrack>(pPixel, std::move(locPos),
Amg::MatrixX(cov),
996 pRIO = std::make_unique<InDet::SCT_ClusterOnTrack>(pStrip, std::move(locPos),
Amg::MatrixX(cov),
1004 for(
int i=0;i<5;i++) {
1005 for(
int j=0;j<=i;j++) {
1006 pM.fillSymmetric(i,j,ha.m_Ck[idx++]);
1010 std::unique_ptr<Trk::TrackParameters> pTP = pPS->
createUniqueTrackParameters(ha.m_Xk[0], ha.m_Xk[1], ha.m_Xk[2], ha.m_Xk[3], ha.m_Xk[4], pM);
1016 pParVec->push_back(pTSS);
1019 auto pFQ = std::make_unique<Trk::FitQuality>(chi2tot, ndoftot);
1035 memcpy(&Re[0], &ETS.
m_Xk[0],
sizeof(Re));
1040 memset(&
P[0],0,
sizeof(
P));
1043 double Ax[3] = {Trf(0,0),Trf(1,0),Trf(2,0)};
1044 double Ay[3] = {Trf(0,1),Trf(1,1),Trf(2,1)};
1047 gP[0] = Trf(0,3) + Ax[0]*Re[0] + Ay[0]*Re[1];
1048 gP[1] = Trf(1,3) + Ax[1]*Re[0] + Ay[1]*Re[1];
1049 gP[2] = Trf(2,3) + Ax[2]*Re[0] + Ay[2]*Re[1];
1054 sincos(Re[2], &sinf, &cosf);
1055 sincos(Re[3], &sint, &
cost);
1057 double gV[3] = {cosf*sint, sinf*sint,
cost};
1059 memset(&Jm[0],0,
sizeof(Jm));
1066 for(
int i=0;i<3;i++) {
1082 if(code!=0)
return code;
1085 memset(&J[0],0,
sizeof(J));
1088 memset(&BigP[0],0,
sizeof(BigP));
1090 for(
int i=0;i<7;i++) BigP[i] =
P[i];
1091 for(
int i=0;i<35;i++) BigP[i+7] = Jm[i];
1101 const double* Az = Trf.matrix().col(2).data();
1105 double lV = Az[0]*gV[0] + Az[1]*gV[1] + Az[2]*gV[2];
1115 if(pDE->
isPixel() && std::abs(Trf(2,2)) >= 1.0) xOverX0 = 0.05;
1119 double lenCorr = 1/std::fabs(lV);
1121 double radLength = xOverX0*lenCorr;
1123 double qpCorr = Re[4]*(1.0 + 0.038 * std::log(radLength));
1124 double sigmaMS2 = 185.0 * radLength * qpCorr*qpCorr;
1128 ETS.
m_Gk[2][2] += sigmaMS2/(sint*sint);
1129 ETS.
m_Gk[3][3] += sigmaMS2;
1135 memset(&Be[0][0],0,
sizeof(Be));
1137 for(
int i=0;i<4;i++) {
1138 for(
int j=0;j<5;j++) {
1139 for(
int k=0;k<5;k++) Be[i][j] += J[k+i*5]*ETS.
m_Gk[k][j+5];
1142 for(
int j=0;j<5;j++) {
1143 Be[4][j] = ETS.
m_Gk[4][j+5];
1149 memset(&JC[0][0],0,
sizeof(JC));
1150 memset(&Ce[0][0],0,
sizeof(Ce));
1152 for(
int i=0;i<4;i++) {
1153 for(
int j=0;j<5;j++) {
1154 for(
int k=0;k<5;k++) JC[i][j] += J[k+i*5]*ETS.
m_Gk[k][j];
1157 for(
int j=0;j<5;j++) {
1158 JC[4][j] = ETS.
m_Gk[4][j];
1161 for(
int i=0;i<5;i++) {
1162 for(
int j=0;j<=i;j++) {
1164 for(
int k=0;k<5;k++) Ce[i][j] += JC[i][k]*J[k+j*5];
1165 Ce[j][i] = Ce[i][j];
1168 Ce[i][4] = Ce[4][i] = JC[i][4];
1177 for(
int i=0;i<5;i++) {
1178 ETS.
m_Xk[i] = Re[i];
1179 for(
int j=0;j<5;j++) {
1180 ETS.
m_Gk[i][j] = Ce[i][j];
1181 ETS.
m_Gk[i][j+5] = Be[i][j];
1182 ETS.
m_Gk[j+5][i] = Be[i][j];
1190 const double C = 299.9975;
1191 const double minStep = 100.0;
1195 memcpy(&Re[0], &Rk[0],
sizeof(Re));
1199 double Ax[3] = {Trf(0,0),Trf(1,0),Trf(2,0)};
1201 double Ay[3] = {Trf(0,1),Trf(1,1),Trf(2,1)};
1205 gP[0] = Trf(0,3) + Ax[0]*Re[0] + Ay[0]*Re[1];
1206 gP[1] = Trf(1,3) + Ax[1]*Re[0] + Ay[1]*Re[1];
1207 gP[2] = Trf(2,3) + Ax[2]*Re[0] + Ay[2]*Re[1];
1212 sincos(Re[2], &sinf, &cosf);
1213 sincos(Re[3], &sint, &
cost);
1215 double gV[3] = {cosf*sint, sinf*sint,
cost};
1220 double D[4] = {normal[0], normal[1], normal[2], 0.0};
1222 for(
int i=0;i<3;i++) D[3] += -normal[i]*center[i];
1224 double CQ =
C*Re[4];
1230 double c = D[0]*gP[0] + D[1]*gP[1] + D[2]*gP[2] + D[3];
1231 double b = D[0]*gV[0] + D[1]*gV[1] + D[2]*gV[2];
1232 double a = 0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1]) + gB[1]*(D[2]*gV[0]-D[0]*gV[2]) + gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
1234 double ratio = 4*
a*c/(b*b);
1236 bool useExpansion = std::fabs(ratio)<0.1;
1246 double discr = b*b-4.0*
a*c;
1252 int signb = (b<0.0)?-1:1;
1253 sl = (-b + signb*std::sqrt(discr))/(2*
a);
1258 if(std::fabs(sl)>=minStep) {
1259 nStepMax = (int)(std::fabs(sl)/minStep)+1;
1262 if((nStepMax<0)||(nStepMax>100)) {
1267 double Ac = 0.5*sl*Av;
1268 double DVx = gV[1]*gB[2] - gV[2]*gB[1];
1269 double DVy = gV[2]*gB[0] - gV[0]*gB[2];
1270 double DVz = gV[0]*gB[1] - gV[1]*gB[0];
1272 double E[3] = {gP[0]+gV[0]*sl+Ac*DVx, gP[1]+gV[1]*sl+Ac*DVy, gP[2]+gV[2]*sl+Ac*DVz};
1275 for(
int i=0;i<3;i++) gP[i] = E[i];
1282 double inv_step = 1/sl;
1284 double dBds[3] = {inv_step*(gBe[0]-gB[0]),inv_step*(gBe[1]-gB[1]),inv_step*(gBe[2]-gB[2])};
1286 int nStep = nStepMax;
1290 c = D[0]*gP[0] + D[1]*gP[1] + D[2]*gP[2] + D[3];
1291 b = D[0]*gV[0] + D[1]*gV[1] + D[2]*gV[2];
1292 a = 0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+gB[1]*(D[2]*gV[0]-D[0]*gV[2])+gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
1294 ratio = 4*
a*c/(b*b);
1295 useExpansion = std::fabs(ratio) < 0.1;
1302 double discr=b*b-4.0*
a*c;
1306 int signb = (b<0.0)?-1:1;
1307 sl = (-b+signb*std::sqrt(discr))/(2*
a);
1310 double ds = sl/nStep;
1314 DVx = gV[1]*gB[2] - gV[2]*gB[1];
1315 DVy = gV[2]*gB[0] - gV[0]*gB[2];
1316 DVz = gV[0]*gB[1] - gV[1]*gB[0];
1318 E[0] = gP[0] + gV[0]*ds + Ac*DVx;
1319 E[1] = gP[1] + gV[1]*ds + Ac*DVy;
1320 E[2] = gP[2] + gV[2]*ds + Ac*DVz;
1324 V[0] = gV[0] + Av*DVx;
1325 V[1] = gV[1] + Av*DVy;
1326 V[2] = gV[2] + Av*DVz;
1328 for(
int i=0;i<3;i++) {
1329 gV[i] = V[i];gP[i] = E[i];
1332 for(
int i=0;i<3;i++) gB[i] += dBds[i]*ds;
1342 const double* Ax2 = Trf2.matrix().col(0).data();
1343 const double* Ay2 = Trf2.matrix().col(1).data();
1345 const double d[3] = { gP[0] - Trf2(0, 3), gP[1] - Trf2(1, 3), gP[2] - Trf2(2, 3) };
1347 TP[0] = d[0] * Ax2[0] + d[1] * Ax2[1] + d[2] * Ax2[2];
1348 TP[1] = d[0] * Ay2[0] + d[1] * Ay2[1] + d[2] * Ay2[2];
1359 Step = -(
P[0]*
P[3] +
P[1]*
P[4])/(1 -
P[5]*
P[5]);
1368 for(
int i=0;i<3;i++) D += -normal[i]*center[i];
1373 for(
int i=0;i<3;i++) {
1374 a += normal[i]*
P[i+3];
1375 Sum += normal[i]*
P[i];
1377 if(
a==0.0)
return Step;
1386 const double coeff = 299.7;
1387 const double min_step = 3.0;
1388 const double const_field_step = 30.0;
1389 const double maxPath = 3000.0;
1390 const double minQp = 0.01;
1391 const double minRad = 300.0;
1393 const int maxIter = 10;
1395 double exStep = 0.0;
1397 if(std::fabs(
P[6]) > minQp)
return -1;
1401 if(Step > 1e7)
return -2;
1403 double absStep = fabs(Step);
1405 if(absStep <= min_step) {
1406 for(
int i=0;i<3;i++)
P[i] += Step*
P[i+3];
1411 if(fabs(
P[6]*Step) > minRad) {
1412 Step = (Step > 0.0 ? minRad : -minRad)/fabs(
P[6]);
1421 memcpy(&Y[0],
P,
sizeof(Y));
1427 for(
int i=0;i<3;i++) B[i] *= coeff;
1430 if(absStep > fabs(exStep))
1434 for(
int iter=0;iter<maxIter;iter++) {
1436 bool useConstField = fabs(Step) < const_field_step;
1438 if(!useConstField) {
1440 for(
int i=0;i<3;i++) B[i] *= coeff;
1443 double B2[3], B3[3];
1451 double H3mom = mom*H3;
1452 double H23mom = mom*H23;
1453 double H4mom = mom*H4;
1454 double H34mom = mom*H34;
1464 for(
int i=0;i<3;i++) Y2[i] = Y[i] + H3*Y[i+3];
1465 for(
int i=3;i<6;i++) Y2[i] = Y[i] + H3mom*YB[i-3];
1474 for(
int i=0;i<3;i++) B2[i] *= coeff;
1482 for(
int i=0;i<3;i++) Y3[i] = Y[i] + H23*Y2[i+3];
1483 for(
int i=3;i<6;i++) Y3[i] = Y[i] + H23mom*YB2[i-3];
1492 for(
int i=0;i<3;i++) B3[i] *= coeff;
1498 for(
int i=3;i<6;i++) Y1[i-3] = Y[i-3] + H4*(Y[i] + 3*Y3[i]);
1499 for(
int i=0;i<3;i++) Y1[i+3] = Y[i+3] + H4mom*(YB[i] + 3*YB3[i]);
1501 if(fabs(Y1[5])>1)
return -10;
1507 double J1C[9], L2C[9], J2C[9], L3C[9], J3C[9];
1513 if(!useConstField) {
1514 for(
int i=0;i<3;i++) CqBH3[i] = H3mom*B[i];
1515 for(
int i=0;i<3;i++) CqB2H23[i] = H23mom*B2[i];
1516 for(
int i=0;i<3;i++) CqB3H34[i] = H34mom*B3[i];
1519 for(
int i=0;i<3;i++) CqBH3[i] = H3mom*B[i];
1520 for(
int i=0;i<3;i++) CqB2H23[i] = H23mom*B[i];
1521 for(
int i=0;i<3;i++) CqB3H34[i] = H34mom*B[i];
1532 L2C[0] = J[17] + J1C[0];
1533 L2C[1] = J[18] + J1C[1];
1534 L2C[2] = J[19] + J1C[2];
1536 L2C[3] = J[24] + J1C[3];
1537 L2C[4] = J[25] + J1C[4];
1538 L2C[5] = J[26] + J1C[5];
1540 L2C[6] = J[31] + J1C[6];
1541 L2C[7] = J[32] + J1C[7];
1542 L2C[8] = J[33] + J1C[8];
1548 J2C[6] += H23*YB2[0];
1549 J2C[7] += H23*YB2[1];
1550 J2C[8] += H23*YB2[2];
1552 L3C[0] = J[17] + J2C[0];
1553 L3C[1] = J[18] + J2C[1];
1554 L3C[2] = J[19] + J2C[2];
1556 L3C[3] = J[24] + J2C[3];
1557 L3C[4] = J[25] + J2C[4];
1558 L3C[5] = J[26] + J2C[5];
1560 L3C[6] = J[31] + J2C[6];
1561 L3C[7] = J[32] + J2C[7];
1562 L3C[8] = J[33] + J2C[8];
1568 J3C[6] += H34*YB3[0];
1569 J3C[7] += H34*YB3[1];
1570 J3C[8] += H34*YB3[2];
1572 for(
int i=0;i<9;i++) J1C[i] = 0.75*J1C[i] + J3C[i];
1574 for(
int i=0;i<9;i++) J2C[i] *= H34;
1616 if(fabs(
P[7]) > maxPath)
return -3;
1618 double norm = 1/std::sqrt(Y1[3]*Y1[3]+Y1[4]*Y1[4]+Y1[5]*Y1[5]);
1620 Y1[3] *= norm; Y1[4] *= norm; Y1[5] *= norm;
1624 if(newStep > 1e7)
return -4;
1626 double absNewStep = fabs(newStep);
1628 if(absNewStep <= min_step) {
1631 if(!useConstField) {
1639 for(
int i=0;i<3;i++) {
1641 P[i] = Y1[i] + newStep*Y1[i+3];
1648 double absStep = fabs(Step);
1650 if(Step*newStep < 0.0) {
1651 if(++nFlips > 2)
return -5;
1652 Step = absNewStep < absStep ? newStep : -Step;
1655 if(absNewStep < absStep) Step = newStep;
1658 for(
int i=0;i<6;i++) Y[i] = Y1[i];
1666 A[0] = -B[1]*V[2] + B[2]*V[1];
1667 A[1] = B[0]*V[2] - B[2]*V[0];
1668 A[2] = -B[0]*V[1] + B[1]*V[0];
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define AmgSymMatrix(dim)
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
virtual DetectorShape shape() const
Shape of element.
double thickness() const
Method which returns thickness of the silicon wafer.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
class to run intersection tests
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
Trk::Surface & surface()
Element Surface.
const Amg::Vector3D & globalPosition() const
return global position reference
bool gangedPixel() const
return the flag of this cluster containing a gangedPixel
const InDet::SiWidth & width() const
return width class reference
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Class describing the Line to which the Perigee refers to.
virtual Surface::ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - charged.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual Surface::ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - charged.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
const Amg::Vector2D & localPosition() const
return the local position reference
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
virtual const Amg::Vector3D & globalPosition() const override final
Interface method to get the global Position.
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Contains information about the 'fitter' of this track.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
virtual IdentifierHash identifyHash() const =0
Identifier hash.
virtual Identifier identify() const =0
Identifier.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
int cost(std::vector< std::string > &files, node &n, const std::string &directory="", bool deleteref=false, bool relocate=false)
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
void transformGlobalToLocal(double *ATH_RESTRICT, double *ATH_RESTRICT)
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)
hold the test vectors and ease the comparison
const Trk::PlaneSurface * m_pO
TrigFTF_ExtendedTrackState()=delete
const Trk::PlaneSurface * m_pS
void AddHit(const Trk::PrepRawData *, double, int)
std::list< TrigFTF_HitAssignment > m_track