135 const double C=0.02999975/1000.0;
136 const double minStep=30.0;
138 double J[5][5],Rf[5],AG[5][5],Gf[5][5],
A[5][5];
141 bool samePlane=
false;
155 double gP[3],gPi[3],lP[3],gV[3],
a,b,c,s,J0[7][5],descr,CQ,Ac,Av,Cc;
156 double V[3],
P[3],M[3][3],D[4],Jm[7][7],
157 J1[5][7],gB[3],gBi[3],gBf[3],dBds[3],Buf[5][7],DVx,DVy,DVz;
161 double sint,
cost,sinf,cosf;
166 memset(&J0[0][0],0,
sizeof(J0));
175 J0[0][0]=L[0][0];J0[0][1]=L[0][1];
176 J0[1][0]=L[1][0];J0[1][1]=L[1][1];
177 J0[2][0]=L[2][0];J0[2][1]=L[2][1];
178 J0[3][2]=-sinf*sint;J0[3][3]=cosf*
cost;
179 J0[4][2]= cosf*sint;J0[4][3]=sinf*
cost;
191 J0[3][2]=-sinf*sint;J0[3][3]=cosf*
cost;
192 J0[4][2]= cosf*sint;J0[4][3]=sinf*
cost;
196 for(i=0;i<4;i++) D[i]=pSE->
getPar(i);
197 for(i=0;i<3;i++) gPi[i]=gP[i];
201 for(i=0;i<3;i++) gBi[i]=gB[i];
203 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
204 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
205 a=0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
206 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
207 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
217 bool useExpansion=
true;
218 double ratio = 4*
a*c/(b*b);
221 useExpansion =
false;
228 int signb = (b<0.0)?-1:1;
229 sl = (-b+signb*sqrt(descr))/(2*
a);
232 if(fabs(sl)<minStep) nStepMax=1;
235 nStepMax=(int)(fabs(sl)/minStep)+1;
237 if((nStepMax<0)||(nStepMax>1000))
243 DVx=gV[1]*gB[2]-gV[2]*gB[1];
244 DVy=gV[2]*gB[0]-gV[0]*gB[2];
245 DVz=gV[0]*gB[1]-gV[1]*gB[0];
247 P[0]=gP[0]+gV[0]*sl+Ac*DVx;
248 P[1]=gP[1]+gV[1]*sl+Ac*DVy;
249 P[2]=gP[2]+gV[2]*sl+Ac*DVz;
256 for(i=0;i<3;i++) gBf[i]=gB[i];
259 dBds[i]=(gBf[i]-gBi[i])/sl;
265 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
266 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
267 a=0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
268 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
269 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
273 useExpansion =
false;
274 else useExpansion =
true;
287 int signb = (b<0.0)?-1:1;
288 sl = (-b+signb*sqrt(descr))/(2*
a);
294 DVx=gV[1]*gB[2]-gV[2]*gB[1];
295 DVy=gV[2]*gB[0]-gV[0]*gB[2];
296 DVz=gV[0]*gB[1]-gV[1]*gB[0];
298 P[0]=gP[0]+gV[0]*ds+Ac*DVx;
299 P[1]=gP[1]+gV[1]*ds+Ac*DVy;
300 P[2]=gP[2]+gV[2]*ds+Ac*DVz;
306 gV[i]=V[i];gP[i]=
P[i];
308 for(i=0;i<3;i++) gB[i]+=dBds[i]*ds;
312 Rf[0]=lP[0];Rf[1]=lP[1];
313 Rf[2]=atan2(V[1],V[0]);
323 gV[0]=sint*cosf;gV[1]=sint*sinf;gV[2]=
cost;
325 for(i=0;i<4;i++) D[i]=pSE->
getPar(i);
326 for(i=0;i<3;i++) gP[i]=gPi[i];
330 gB[i]=0.5*(gBi[i]+gBf[i]);
333 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
334 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
335 a=CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
336 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
337 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
341 useExpansion =
false;
342 else useExpansion =
true;
355 int signb = (b<0.0)?-1:1;
356 s = (-b+signb*sqrt(descr))/(2*
a);
363 DVx=gV[1]*gB[2]-gV[2]*gB[1];
364 DVy=gV[2]*gB[0]-gV[0]*gB[2];
365 DVz=gV[0]*gB[1]-gV[1]*gB[0];
367 P[0]=gP[0]+gV[0]*s+Ac*DVx;
368 P[1]=gP[1]+gV[1]*s+Ac*DVy;
369 P[2]=gP[2]+gV[2]*s+Ac*DVz;
371 V[0]=gV[0]+Av*DVx;V[1]=gV[1]+Av*DVy;V[2]=gV[2]+Av*DVz;
372 if (std::abs(V[2]) > 1.0) {
378 memset(&Jm[0][0],0,
sizeof(Jm));
380 for(i=0;i<3;i++)
for(j=0;j<3;j++) M[i][j]=pSE->
getRotMatrix(i,j);
382 double coeff[3], dadVx,dadVy,dadVz,dadQ,dsdx,dsdy,dsdz,dsdVx,dsdVy,dsdVz,dsdQ;
383 coeff[0]=-c*c/(b*b*b);
384 coeff[1]=c*(1.0+3.0*c*
a/(b*b))/(b*b);
385 coeff[2]=-(1.0+2.0*c*
a/(b*b))/b;
387 dadVx=0.5*CQ*(-D[1]*gB[2]+D[2]*gB[1]);
388 dadVy=0.5*CQ*( D[0]*gB[2]-D[2]*gB[0]);
389 dadVz=0.5*CQ*(-D[0]*gB[1]+D[1]*gB[0]);
390 dadQ=0.5*
C*(D[0]*DVx+D[1]*DVy+D[2]*DVz);
395 dsdVx=coeff[0]*dadVx+coeff[1]*D[0];
396 dsdVy=coeff[0]*dadVy+coeff[1]*D[1];
397 dsdVz=coeff[0]*dadVz+coeff[1]*D[2];
400 Jm[0][0]=1.0+V[0]*dsdx;
404 Jm[0][3]= s+V[0]*dsdVx;
405 Jm[0][4]= V[0]*dsdVy+Ac*gB[2];
406 Jm[0][5]= V[0]*dsdVz-Ac*gB[1];
407 Jm[0][6]= V[0]*dsdQ+Cc*DVx;
410 Jm[1][1]=1.0+V[1]*dsdy;
413 Jm[1][3]= V[1]*dsdVx-Ac*gB[2];
414 Jm[1][4]= s+V[1]*dsdVy;
415 Jm[1][5]= V[1]*dsdVz+Ac*gB[0];
416 Jm[1][6]= V[1]*dsdQ+Cc*DVy;
420 Jm[2][2]=1.0+V[2]*dsdz;
421 Jm[2][3]= V[2]*dsdVx+Ac*gB[1];
422 Jm[2][4]= V[2]*dsdVy-Ac*gB[0];
423 Jm[2][5]= s+V[2]*dsdVz;
424 Jm[2][6]= V[2]*dsdQ+Cc*DVz;
426 Jm[3][0]=dsdx*CQ*DVx;
427 Jm[3][1]=dsdy*CQ*DVx;
428 Jm[3][2]=dsdz*CQ*DVx;
430 Jm[3][3]=1.0+dsdVx*CQ*DVx;
431 Jm[3][4]=CQ*(dsdVy*DVx+s*gB[2]);
432 Jm[3][5]=CQ*(dsdVz*DVx-s*gB[1]);
434 Jm[3][6]=(CQ*dsdQ+
C*s)*DVx;
436 Jm[4][0]=dsdx*CQ*DVy;
437 Jm[4][1]=dsdy*CQ*DVy;
438 Jm[4][2]=dsdz*CQ*DVy;
440 Jm[4][3]=CQ*(dsdVx*DVy-s*gB[2]);
441 Jm[4][4]=1.0+dsdVy*CQ*DVy;
442 Jm[4][5]=CQ*(dsdVz*DVy+s*gB[0]);
444 Jm[4][6]=(CQ*dsdQ+
C*s)*DVy;
446 Jm[5][0]=dsdx*CQ*DVz;
447 Jm[5][1]=dsdy*CQ*DVz;
448 Jm[5][2]=dsdz*CQ*DVz;
449 Jm[5][3]=CQ*(dsdVx*DVz+s*gB[1]);
450 Jm[5][4]=CQ*(dsdVy*DVz-s*gB[0]);
451 Jm[5][5]=1.0+dsdVz*CQ*DVz;
452 Jm[5][6]=(CQ*dsdQ+
C*s)*DVz;
456 memset(&J1[0][0],0,
sizeof(J1));
458 J1[0][0]=M[0][0];J1[0][1]=M[0][1];J1[0][2]=M[0][2];
459 J1[1][0]=M[1][0];J1[1][1]=M[1][1];J1[1][2]=M[1][2];
460 J1[2][3]=-V[1]/(V[0]*V[0]+V[1]*V[1]);
461 J1[2][4]= V[0]/(V[0]*V[0]+V[1]*V[1]);
462 J1[3][5]=-1.0/sqrt(1-V[2]*V[2]);
468 Buf[j][i]=J1[j][0]*Jm[0][i]+J1[j][1]*Jm[1][i]+J1[j][2]*Jm[2][i];
469 Buf[2][i]=J1[2][3]*Jm[3][i]+J1[2][4]*Jm[4][i];
470 Buf[3][i]=J1[3][5]*Jm[5][i];
478 J[i][0]=Buf[i][0]*J0[0][0]+Buf[i][1]*J0[1][0]+Buf[i][2]*J0[2][0];
479 J[i][1]=Buf[i][0]*J0[0][1]+Buf[i][1]*J0[1][1]+Buf[i][2]*J0[2][1];
480 J[i][2]=Buf[i][3]*J0[3][2]+Buf[i][4]*J0[4][2];
481 J[i][3]=Buf[i][3]*J0[3][3]+Buf[i][4]*J0[4][3]+Buf[i][5]*J0[5][3];
489 J[i][0]=Buf[i][0]*J0[0][0]+Buf[i][1]*J0[1][0];
491 J[i][2]=Buf[i][0]*J0[0][2]+Buf[i][1]*J0[1][2]+Buf[i][3]*J0[3][2]+Buf[i][4]*J0[4][2];
492 J[i][3]=Buf[i][3]*J0[3][3]+Buf[i][4]*J0[4][3]+Buf[i][5]*J0[5][3];
503 memset(&J[0][0],0,
sizeof(J));
504 for(i=0;i<5;i++) J[i][i]=1.0;
507 for(i=0;i<5;i++)
for(j=0;j<5;j++)
511 for(i=0;i<5;i++)
for(j=i;j<5;j++)
514 for(m=0;m<5;m++) Gf[i][j]+=AG[i][m]*J[j][m];
523 for(i=0;i<4;i++) Rtmp[i] = Rf[i];
524 Rtmp[4] = 0.001*Rf[4];
540 for(
int idx=0;idx<5;idx++) {
549 for(i=0;i<5;i++)
for(j=i;j<5;j++)
555 for(i=0;i<5;i++)
for(j=0;j<5;j++)
558 for(m=0;m<5;m++)
A[i][j]+=AG[m][i]*Gi(m,j);
601 if(trackPars==
nullptr) {
603 return std::make_pair(
nullptr,
nullptr);
608 Rk[0] = trackPars->parameters()[
Trk::d0];
609 Rk[1] = trackPars->parameters()[
Trk::z0];
610 Rk[2] = trackPars->parameters()[
Trk::phi0];
613 double trk_theta = trackPars->parameters()[
Trk::theta];
615 double trk_qOverP = trackPars->parameters()[
Trk::qOverP];
616 Rk[4] = 1000.0*trk_qOverP;
617 double trk_Pt = sin(trk_theta)/trk_qOverP;
619 if(fabs(trk_Pt)<100.0)
621 ATH_MSG_DEBUG(
"Estimated Pt is too low "<<trk_Pt<<
" - skipping fit");
622 return std::make_pair(
nullptr,
nullptr);
627 std::vector<Trk::TrkBaseNode*> vpTrkNodes;
628 std::vector<Trk::TrkTrackState*> vpTrackStates;
629 vpTrackStates.reserve(vpTrkNodes.size() + 1);
631 int nHits=vpTrkNodes.size();
634 if(!trackResult)
return std::make_pair(
nullptr,
nullptr);
639 double Gk[5][5] = {{100.0, 0, 0, 0, 0},
649 vpTrackStates.push_back(pTS);
652 ATH_MSG_VERBOSE(
"Initial params: locT="<<Rk[0]<<
" locL="<<Rk[1]<<
" phi="<<Rk[2]
653 <<
" theta="<<Rk[3]<<
" Q="<<Rk[4]<<
" pT="<<sin(Rk[3])/Rk[4]<<
" GeV");
662 for(
auto pnIt = vpTrkNodes.begin(); pnIt!=vpTrkNodes.end(); ++pnIt) {
663 pSE=(*pnIt)->getSurface();
668 vpTrackStates.push_back(pNS);
670 (*pnIt)->validateMeasurement(pNS);
672 if((*pnIt)->isValidated())
674 chi2tot+=(*pnIt)->getChi2();
675 ndoftot+=(*pnIt)->getNdof();
677 (*pnIt)->updateTrackState(pNS);
680 if(fabs(est_Pt)<200.0)
682 ATH_MSG_VERBOSE(
"Estimated Pt is too low "<<est_Pt<<
" - skipping fit");
697 for(
auto ptsIt = vpTrackStates.rbegin();ptsIt!=vpTrackStates.rend();++ptsIt)
699 (*ptsIt)->runSmoother();
701 pTS=(*vpTrackStates.begin());
714 bool bad_cov =
false;
716 for(
int i=0;i<5;i++) {
720 ATH_MSG_DEBUG(
"REGTEST: cov(" << i <<
"," << i <<
") =" << cov_diag <<
" < 0, reject track");
724 for(
int j=i+1;j<5;j++) {
729 if((ndoftot<0) || (fabs(pt)<100.0) || (std::isnan(pt)) || bad_cov)
731 ATH_MSG_DEBUG(
"Fit failed - possibly floating point problem");
736 auto perigee = std::make_unique<Trk::Perigee>(d0, z0, phi0,
theta, qOverP, perigeeSurface, cov);
738 std::unique_ptr<Trk::Perigee> perigeewTP = (addTPtoTSoS) ? std::make_unique<Trk::Perigee>(d0, z0, phi0,
theta, qOverP, perigeeSurface, cov) :
nullptr;
740 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
742 auto pParVec = std::make_unique<Trk::TrackStates>();
743 auto pParVecwTP = std::make_unique<Trk::TrackStates>();
745 pParVec->reserve(vpTrkNodes.size()+1);
752 pParVecwTP->reserve(vpTrkNodes.size() + 1);
753 pParVecwTP->push_back(
756 for (
auto pnIt = vpTrkNodes.begin(); pnIt != vpTrkNodes.end(); ++pnIt) {
757 if((*pnIt)->isValidated()) {
762 pParVec->push_back(pTSS);
764 if(pTSSwTP!=
nullptr) {
765 pParVecwTP->push_back(pTSSwTP);
777 pParVec->push_back((*tSOS)->clone());
782 if(
msgLvl(MSG::VERBOSE)) {
784 ATH_MSG_VERBOSE(
"Fitted parameters: d0="<<d0<<
" phi0="<<phi0<<
" z0="<<z0
785 <<
" eta0="<<
eta<<
" pt="<<pt);
787 auto pFQ= std::make_unique<Trk::FitQuality>(chi2tot,ndoftot);
789 info.setParticleHypothesis(matEffects);
790 fittedTrack =
new Trk::Track(info, std::move(pParVec), std::move(pFQ));
792 auto pFQwTP=std::make_unique<Trk::FitQuality>(chi2tot,ndoftot);
795 fittedTrackwTP =
new Trk::Track(infowTP, std::move(pParVecwTP), std::move(pFQwTP));
801 ATH_MSG_DEBUG(
"Forward Kalman filter: extrapolation failure ");
804 for(
auto pnIt = vpTrkNodes.begin(); pnIt!=vpTrkNodes.end(); ++pnIt) {
805 delete((*pnIt)->getSurface());
809 for(
auto ptsIt = vpTrackStates.begin();ptsIt!=vpTrackStates.end();++ptsIt) {
812 vpTrackStates.clear();
814 return std::make_pair(fittedTrack,fittedTrackwTP);
889 std::vector<TrigL2HitResidual>& vResid,
const EventContext& ctx)
const {
892 if(trackPars==
nullptr) {
894 return StatusCode::FAILURE;
902 return StatusCode::FAILURE;
905 fieldCondObj->getInitializedCache (fieldCache);
906 std::vector<Trk::TrkBaseNode*> vpTrkNodes;
907 std::vector<Trk::TrkTrackState*> vpTrackStates;
909 double trk_theta = trackPars->parameters()[
Trk::theta];
910 double trk_qOverP = trackPars->parameters()[
Trk::qOverP];
911 double Pt = sin(trk_theta)/trk_qOverP;
914 ATH_MSG_DEBUG(
"TrigL2ResidualCalculator failed -- Estimated Pt is too low "<<Pt);
915 return StatusCode::FAILURE;
924 return StatusCode::FAILURE;
928 std::vector<Trk::TrkBaseNode*>::iterator pnIt,pnEnd(vpTrkNodes.end());
930 for(std::vector<Trk::TrkBaseNode*>::iterator pNodeIt=vpTrkNodes.begin();pNodeIt!=vpTrkNodes.end();
939 Rk[0] = trackPars->parameters()[
Trk::d0];
940 Rk[1] = trackPars->parameters()[
Trk::z0];
941 Rk[2] = trackPars->parameters()[
Trk::phi0];
944 trk_theta = trackPars->parameters()[
Trk::theta];
946 Rk[4] = 1000.0*trackPars->parameters()[
Trk::qOverP];
952 double Gk[5][5] = {{100.0, 0, 0, 0, 0},
962 vpTrackStates.push_back(pTS);
964 ATH_MSG_DEBUG(
"Initial params: locT="<<Rk[0]<<
" locL="<<Rk[1]<<
" phi="<<Rk[2]
965 <<
" theta="<<Rk[3]<<
" Q="<<Rk[4]<<
" pT="<<sin(Rk[3])/Rk[4]);
970 for(pnIt=vpTrkNodes.begin();pnIt!=pnEnd;++pnIt)
972 pSE=(*pnIt)->getSurface();
978 vpTrackStates.push_back(pNS);
980 (*pnIt)->validateMeasurement(pNS);
982 if((*pnIt)!=pMaskedNode)
984 (*pnIt)->updateTrackState(pNS);
994 ATH_MSG_DEBUG(
"Estimated Pt is too low "<<Pt<<
" - skipping fit");
1005 std::vector<Trk::TrkTrackState*>::reverse_iterator ptsrIt(vpTrackStates.rbegin()),
1006 ptsrEnd(vpTrackStates.rend());
1008 for(;ptsrIt!=ptsrEnd;++ptsrIt)
1010 (*ptsrIt)->runSmoother();
1015 double r[2],V[2][2];
1045 if((V[0][0]>0.0) && (V[1][1]>0.0)) {
1047 r[1],
r[1]*sqrt(V[1][1])));
1057 ATH_MSG_DEBUG(
"Forward Kalman filter: extrapolation failure ");
1060 for(std::vector<Trk::TrkTrackState*>::iterator ptsIt=vpTrackStates.begin();
1061 ptsIt!=vpTrackStates.end();++ptsIt)
delete (*ptsIt);
1062 vpTrackStates.clear();
1065 pnIt=vpTrkNodes.begin();pnEnd=vpTrkNodes.end();
1066 for(;pnIt!=pnEnd;++pnIt)
1068 delete((*pnIt)->getSurface());
1073 if(OK)
return StatusCode::SUCCESS;
1074 else return StatusCode::FAILURE;