8 #include "GaudiKernel/SystemOfUnits.h"
38 #include <unordered_map>
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);
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]<<
" ";
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]<<
" ";
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]);
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);
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);
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++) {
364 for(
int j=0;j<=
i;j++) {
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++) {
393 Gain[
i] = CHT[
i] * invcov;
396 for(
int i=0;
i<10;
i++) {
398 for(
int j=0;j<=
i;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++) {
430 Gain[
i] = CHT[
i] * invcov;
433 for(
int i=0;
i<10;
i++) {
435 for(
int j=0;j<=
i;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));
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];
525 double rk = sp->globalPosition().perp();
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;
631 return std::make_unique<TrigFTF_ExtendedTrackState>(P0, thePlane);
642 if (!fieldCondObj.isValid()) {
647 fieldCondObj->getInitializedCache (fieldCache);
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++) {
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;
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;
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;
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);
966 if(pPRD ==
nullptr)
continue;
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++]);
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++) {
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++) {
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]));
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]));
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));
1430 if(absStep > fabs(exStep))
1434 for(
int iter=0;iter<maxIter;iter++) {
1436 bool useConstField = fabs(Step) < const_field_step;
1438 if(!useConstField) {
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];
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];
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]);
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];