138 const double C=0.02999975/1000.0;
139 const double minStep=30.0;
141 double J[5][5],Rf[5],AG[5][5],Gf[5][5],
A[5][5];
144 bool samePlane=
false;
158 double gP[3],gPi[3],lP[3],gV[3],
a,b,c,s,J0[7][5],descr,CQ,Ac,Av,Cc;
159 double V[3],
P[3],M[3][3],D[4],Jm[7][7],
160 J1[5][7],gB[3],gBi[3],gBf[3],dBds[3],Buf[5][7],DVx,DVy,DVz;
164 double sint,
cost,sinf,cosf;
169 memset(&J0[0][0],0,
sizeof(J0));
178 J0[0][0]=L[0][0];J0[0][1]=L[0][1];
179 J0[1][0]=L[1][0];J0[1][1]=L[1][1];
180 J0[2][0]=L[2][0];J0[2][1]=L[2][1];
181 J0[3][2]=-sinf*sint;J0[3][3]=cosf*
cost;
182 J0[4][2]= cosf*sint;J0[4][3]=sinf*
cost;
194 J0[3][2]=-sinf*sint;J0[3][3]=cosf*
cost;
195 J0[4][2]= cosf*sint;J0[4][3]=sinf*
cost;
199 for(i=0;i<4;i++) D[i]=pSE->
getPar(i);
200 for(i=0;i<3;i++) gPi[i]=gP[i];
204 for(i=0;i<3;i++) gBi[i]=gB[i];
206 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
207 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
208 a=0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
209 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
210 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
220 bool useExpansion=
true;
221 double ratio = 4*
a*c/(b*b);
224 useExpansion =
false;
231 int signb = (b<0.0)?-1:1;
232 sl = (-b+signb*sqrt(descr))/(2*
a);
235 if(fabs(sl)<minStep) nStepMax=1;
238 nStepMax=(int)(fabs(sl)/minStep)+1;
240 if((nStepMax<0)||(nStepMax>1000))
246 DVx=gV[1]*gB[2]-gV[2]*gB[1];
247 DVy=gV[2]*gB[0]-gV[0]*gB[2];
248 DVz=gV[0]*gB[1]-gV[1]*gB[0];
250 P[0]=gP[0]+gV[0]*sl+Ac*DVx;
251 P[1]=gP[1]+gV[1]*sl+Ac*DVy;
252 P[2]=gP[2]+gV[2]*sl+Ac*DVz;
259 for(i=0;i<3;i++) gBf[i]=gB[i];
262 dBds[i]=(gBf[i]-gBi[i])/sl;
268 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
269 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
270 a=0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
271 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
272 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
276 useExpansion =
false;
277 else useExpansion =
true;
290 int signb = (b<0.0)?-1:1;
291 sl = (-b+signb*sqrt(descr))/(2*
a);
297 DVx=gV[1]*gB[2]-gV[2]*gB[1];
298 DVy=gV[2]*gB[0]-gV[0]*gB[2];
299 DVz=gV[0]*gB[1]-gV[1]*gB[0];
301 P[0]=gP[0]+gV[0]*ds+Ac*DVx;
302 P[1]=gP[1]+gV[1]*ds+Ac*DVy;
303 P[2]=gP[2]+gV[2]*ds+Ac*DVz;
309 gV[i]=V[i];gP[i]=
P[i];
311 for(i=0;i<3;i++) gB[i]+=dBds[i]*ds;
315 Rf[0]=lP[0];Rf[1]=lP[1];
316 Rf[2]=atan2(V[1],V[0]);
326 gV[0]=sint*cosf;gV[1]=sint*sinf;gV[2]=
cost;
328 for(i=0;i<4;i++) D[i]=pSE->
getPar(i);
329 for(i=0;i<3;i++) gP[i]=gPi[i];
333 gB[i]=0.5*(gBi[i]+gBf[i]);
336 c=D[0]*gP[0]+D[1]*gP[1]+D[2]*gP[2]+D[3];
337 b=D[0]*gV[0]+D[1]*gV[1]+D[2]*gV[2];
338 a=CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+
339 gB[1]*(D[2]*gV[0]-D[0]*gV[2])+
340 gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
344 useExpansion =
false;
345 else useExpansion =
true;
358 int signb = (b<0.0)?-1:1;
359 s = (-b+signb*sqrt(descr))/(2*
a);
366 DVx=gV[1]*gB[2]-gV[2]*gB[1];
367 DVy=gV[2]*gB[0]-gV[0]*gB[2];
368 DVz=gV[0]*gB[1]-gV[1]*gB[0];
370 P[0]=gP[0]+gV[0]*s+Ac*DVx;
371 P[1]=gP[1]+gV[1]*s+Ac*DVy;
372 P[2]=gP[2]+gV[2]*s+Ac*DVz;
374 V[0]=gV[0]+Av*DVx;V[1]=gV[1]+Av*DVy;V[2]=gV[2]+Av*DVz;
375 if (std::abs(V[2]) > 1.0) {
381 memset(&Jm[0][0],0,
sizeof(Jm));
383 for(i=0;i<3;i++)
for(j=0;j<3;j++) M[i][j]=pSE->
getRotMatrix(i,j);
385 double coeff[3], dadVx,dadVy,dadVz,dadQ,dsdx,dsdy,dsdz,dsdVx,dsdVy,dsdVz,dsdQ;
386 coeff[0]=-c*c/(b*b*b);
387 coeff[1]=c*(1.0+3.0*c*
a/(b*b))/(b*b);
388 coeff[2]=-(1.0+2.0*c*
a/(b*b))/b;
390 dadVx=0.5*CQ*(-D[1]*gB[2]+D[2]*gB[1]);
391 dadVy=0.5*CQ*( D[0]*gB[2]-D[2]*gB[0]);
392 dadVz=0.5*CQ*(-D[0]*gB[1]+D[1]*gB[0]);
393 dadQ=0.5*
C*(D[0]*DVx+D[1]*DVy+D[2]*DVz);
398 dsdVx=coeff[0]*dadVx+coeff[1]*D[0];
399 dsdVy=coeff[0]*dadVy+coeff[1]*D[1];
400 dsdVz=coeff[0]*dadVz+coeff[1]*D[2];
403 Jm[0][0]=1.0+V[0]*dsdx;
407 Jm[0][3]= s+V[0]*dsdVx;
408 Jm[0][4]= V[0]*dsdVy+Ac*gB[2];
409 Jm[0][5]= V[0]*dsdVz-Ac*gB[1];
410 Jm[0][6]= V[0]*dsdQ+Cc*DVx;
413 Jm[1][1]=1.0+V[1]*dsdy;
416 Jm[1][3]= V[1]*dsdVx-Ac*gB[2];
417 Jm[1][4]= s+V[1]*dsdVy;
418 Jm[1][5]= V[1]*dsdVz+Ac*gB[0];
419 Jm[1][6]= V[1]*dsdQ+Cc*DVy;
423 Jm[2][2]=1.0+V[2]*dsdz;
424 Jm[2][3]= V[2]*dsdVx+Ac*gB[1];
425 Jm[2][4]= V[2]*dsdVy-Ac*gB[0];
426 Jm[2][5]= s+V[2]*dsdVz;
427 Jm[2][6]= V[2]*dsdQ+Cc*DVz;
429 Jm[3][0]=dsdx*CQ*DVx;
430 Jm[3][1]=dsdy*CQ*DVx;
431 Jm[3][2]=dsdz*CQ*DVx;
433 Jm[3][3]=1.0+dsdVx*CQ*DVx;
434 Jm[3][4]=CQ*(dsdVy*DVx+s*gB[2]);
435 Jm[3][5]=CQ*(dsdVz*DVx-s*gB[1]);
437 Jm[3][6]=(CQ*dsdQ+
C*s)*DVx;
439 Jm[4][0]=dsdx*CQ*DVy;
440 Jm[4][1]=dsdy*CQ*DVy;
441 Jm[4][2]=dsdz*CQ*DVy;
443 Jm[4][3]=CQ*(dsdVx*DVy-s*gB[2]);
444 Jm[4][4]=1.0+dsdVy*CQ*DVy;
445 Jm[4][5]=CQ*(dsdVz*DVy+s*gB[0]);
447 Jm[4][6]=(CQ*dsdQ+
C*s)*DVy;
449 Jm[5][0]=dsdx*CQ*DVz;
450 Jm[5][1]=dsdy*CQ*DVz;
451 Jm[5][2]=dsdz*CQ*DVz;
452 Jm[5][3]=CQ*(dsdVx*DVz+s*gB[1]);
453 Jm[5][4]=CQ*(dsdVy*DVz-s*gB[0]);
454 Jm[5][5]=1.0+dsdVz*CQ*DVz;
455 Jm[5][6]=(CQ*dsdQ+
C*s)*DVz;
459 memset(&J1[0][0],0,
sizeof(J1));
461 J1[0][0]=M[0][0];J1[0][1]=M[0][1];J1[0][2]=M[0][2];
462 J1[1][0]=M[1][0];J1[1][1]=M[1][1];J1[1][2]=M[1][2];
463 J1[2][3]=-V[1]/(V[0]*V[0]+V[1]*V[1]);
464 J1[2][4]= V[0]/(V[0]*V[0]+V[1]*V[1]);
465 J1[3][5]=-1.0/sqrt(1-V[2]*V[2]);
471 Buf[j][i]=J1[j][0]*Jm[0][i]+J1[j][1]*Jm[1][i]+J1[j][2]*Jm[2][i];
472 Buf[2][i]=J1[2][3]*Jm[3][i]+J1[2][4]*Jm[4][i];
473 Buf[3][i]=J1[3][5]*Jm[5][i];
481 J[i][0]=Buf[i][0]*J0[0][0]+Buf[i][1]*J0[1][0]+Buf[i][2]*J0[2][0];
482 J[i][1]=Buf[i][0]*J0[0][1]+Buf[i][1]*J0[1][1]+Buf[i][2]*J0[2][1];
483 J[i][2]=Buf[i][3]*J0[3][2]+Buf[i][4]*J0[4][2];
484 J[i][3]=Buf[i][3]*J0[3][3]+Buf[i][4]*J0[4][3]+Buf[i][5]*J0[5][3];
492 J[i][0]=Buf[i][0]*J0[0][0]+Buf[i][1]*J0[1][0];
494 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];
495 J[i][3]=Buf[i][3]*J0[3][3]+Buf[i][4]*J0[4][3]+Buf[i][5]*J0[5][3];
506 memset(&J[0][0],0,
sizeof(J));
507 for(i=0;i<5;i++) J[i][i]=1.0;
510 for(i=0;i<5;i++)
for(j=0;j<5;j++)
514 for(i=0;i<5;i++)
for(j=i;j<5;j++)
517 for(m=0;m<5;m++) Gf[i][j]+=AG[i][m]*J[j][m];
526 for(i=0;i<4;i++) Rtmp[i] = Rf[i];
527 Rtmp[4] = 0.001*Rf[4];
543 for(
int idx=0;idx<5;idx++) {
552 for(i=0;i<5;i++)
for(j=i;j<5;j++)
558 for(i=0;i<5;i++)
for(j=0;j<5;j++)
561 for(m=0;m<5;m++)
A[i][j]+=AG[m][i]*Gi(m,j);
604 if(trackPars==
nullptr) {
606 return std::make_pair(
nullptr,
nullptr);
611 Rk[0] = trackPars->parameters()[
Trk::d0];
612 Rk[1] = trackPars->parameters()[
Trk::z0];
613 Rk[2] = trackPars->parameters()[
Trk::phi0];
616 double trk_theta = trackPars->parameters()[
Trk::theta];
618 double trk_qOverP = trackPars->parameters()[
Trk::qOverP];
619 Rk[4] = 1000.0*trk_qOverP;
620 double trk_Pt = sin(trk_theta)/trk_qOverP;
622 if(fabs(trk_Pt)<100.0)
624 ATH_MSG_DEBUG(
"Estimated Pt is too low "<<trk_Pt<<
" - skipping fit");
625 return std::make_pair(
nullptr,
nullptr);
630 std::vector<Trk::TrkBaseNode*> vpTrkNodes;
631 std::vector<Trk::TrkTrackState*> vpTrackStates;
632 vpTrackStates.reserve(vpTrkNodes.size() + 1);
634 int nHits=vpTrkNodes.size();
637 if(!trackResult)
return std::make_pair(
nullptr,
nullptr);
642 double Gk[5][5] = {{100.0, 0, 0, 0, 0},
652 vpTrackStates.push_back(pTS);
655 ATH_MSG_VERBOSE(
"Initial params: locT="<<Rk[0]<<
" locL="<<Rk[1]<<
" phi="<<Rk[2]
656 <<
" theta="<<Rk[3]<<
" Q="<<Rk[4]<<
" pT="<<sin(Rk[3])/Rk[4]<<
" GeV");
665 for(
auto pnIt = vpTrkNodes.begin(); pnIt!=vpTrkNodes.end(); ++pnIt) {
666 pSE=(*pnIt)->getSurface();
671 vpTrackStates.push_back(pNS);
673 (*pnIt)->validateMeasurement(pNS);
675 if((*pnIt)->isValidated())
677 chi2tot+=(*pnIt)->getChi2();
678 ndoftot+=(*pnIt)->getNdof();
680 (*pnIt)->updateTrackState(pNS);
683 if(fabs(est_Pt)<200.0)
685 ATH_MSG_VERBOSE(
"Estimated Pt is too low "<<est_Pt<<
" - skipping fit");
700 for(
auto ptsIt = vpTrackStates.rbegin();ptsIt!=vpTrackStates.rend();++ptsIt)
702 (*ptsIt)->runSmoother();
704 pTS=(*vpTrackStates.begin());
717 bool bad_cov =
false;
719 for(
int i=0;i<5;i++) {
723 ATH_MSG_DEBUG(
"REGTEST: cov(" << i <<
"," << i <<
") =" << cov_diag <<
" < 0, reject track");
727 for(
int j=i+1;j<5;j++) {
732 if((ndoftot<0) || (fabs(pt)<100.0) || (std::isnan(pt)) || bad_cov)
734 ATH_MSG_DEBUG(
"Fit failed - possibly floating point problem");
739 auto perigee = std::make_unique<Trk::Perigee>(d0, z0, phi0,
theta, qOverP, perigeeSurface, cov);
741 std::unique_ptr<Trk::Perigee> perigeewTP = (addTPtoTSoS) ? std::make_unique<Trk::Perigee>(d0, z0, phi0,
theta, qOverP, perigeeSurface, cov) :
nullptr;
743 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
745 auto pParVec = std::make_unique<Trk::TrackStates>();
746 auto pParVecwTP = std::make_unique<Trk::TrackStates>();
748 pParVec->reserve(vpTrkNodes.size()+1);
755 pParVecwTP->reserve(vpTrkNodes.size() + 1);
756 pParVecwTP->push_back(
759 for (
auto pnIt = vpTrkNodes.begin(); pnIt != vpTrkNodes.end(); ++pnIt) {
760 if((*pnIt)->isValidated()) {
765 pParVec->push_back(pTSS);
767 if(pTSSwTP!=
nullptr) {
768 pParVecwTP->push_back(pTSSwTP);
780 pParVec->push_back((*tSOS)->clone());
785 if(
msgLvl(MSG::VERBOSE)) {
787 ATH_MSG_VERBOSE(
"Fitted parameters: d0="<<d0<<
" phi0="<<phi0<<
" z0="<<z0
788 <<
" eta0="<<
eta<<
" pt="<<pt);
790 auto pFQ= std::make_unique<Trk::FitQuality>(chi2tot,ndoftot);
792 info.setParticleHypothesis(matEffects);
793 fittedTrack =
new Trk::Track(info, std::move(pParVec), std::move(pFQ));
795 auto pFQwTP=std::make_unique<Trk::FitQuality>(chi2tot,ndoftot);
798 fittedTrackwTP =
new Trk::Track(infowTP, std::move(pParVecwTP), std::move(pFQwTP));
804 ATH_MSG_DEBUG(
"Forward Kalman filter: extrapolation failure ");
807 for(
auto pnIt = vpTrkNodes.begin(); pnIt!=vpTrkNodes.end(); ++pnIt) {
808 delete((*pnIt)->getSurface());
812 for(
auto ptsIt = vpTrackStates.begin();ptsIt!=vpTrackStates.end();++ptsIt) {
815 vpTrackStates.clear();
817 return std::make_pair(fittedTrack,fittedTrackwTP);
892 std::vector<TrigL2HitResidual>& vResid,
const EventContext& ctx)
const {
895 if(trackPars==
nullptr) {
897 return StatusCode::FAILURE;
905 return StatusCode::FAILURE;
908 fieldCondObj->getInitializedCache (fieldCache);
909 std::vector<Trk::TrkBaseNode*> vpTrkNodes;
910 std::vector<Trk::TrkTrackState*> vpTrackStates;
912 double trk_theta = trackPars->parameters()[
Trk::theta];
913 double trk_qOverP = trackPars->parameters()[
Trk::qOverP];
914 double Pt = sin(trk_theta)/trk_qOverP;
917 ATH_MSG_DEBUG(
"TrigL2ResidualCalculator failed -- Estimated Pt is too low "<<Pt);
918 return StatusCode::FAILURE;
927 return StatusCode::FAILURE;
931 std::vector<Trk::TrkBaseNode*>::iterator pnIt,pnEnd(vpTrkNodes.end());
933 for(std::vector<Trk::TrkBaseNode*>::iterator pNodeIt=vpTrkNodes.begin();pNodeIt!=vpTrkNodes.end();
942 Rk[0] = trackPars->parameters()[
Trk::d0];
943 Rk[1] = trackPars->parameters()[
Trk::z0];
944 Rk[2] = trackPars->parameters()[
Trk::phi0];
947 trk_theta = trackPars->parameters()[
Trk::theta];
949 Rk[4] = 1000.0*trackPars->parameters()[
Trk::qOverP];
955 double Gk[5][5] = {{100.0, 0, 0, 0, 0},
965 vpTrackStates.push_back(pTS);
967 ATH_MSG_DEBUG(
"Initial params: locT="<<Rk[0]<<
" locL="<<Rk[1]<<
" phi="<<Rk[2]
968 <<
" theta="<<Rk[3]<<
" Q="<<Rk[4]<<
" pT="<<sin(Rk[3])/Rk[4]);
973 for(pnIt=vpTrkNodes.begin();pnIt!=pnEnd;++pnIt)
975 pSE=(*pnIt)->getSurface();
981 vpTrackStates.push_back(pNS);
983 (*pnIt)->validateMeasurement(pNS);
985 if((*pnIt)!=pMaskedNode)
987 (*pnIt)->updateTrackState(pNS);
997 ATH_MSG_DEBUG(
"Estimated Pt is too low "<<Pt<<
" - skipping fit");
1008 std::vector<Trk::TrkTrackState*>::reverse_iterator ptsrIt(vpTrackStates.rbegin()),
1009 ptsrEnd(vpTrackStates.rend());
1011 for(;ptsrIt!=ptsrEnd;++ptsrIt)
1013 (*ptsrIt)->runSmoother();
1018 double r[2],V[2][2];
1048 if((V[0][0]>0.0) && (V[1][1]>0.0)) {
1050 r[1],
r[1]*sqrt(V[1][1])));
1060 ATH_MSG_DEBUG(
"Forward Kalman filter: extrapolation failure ");
1063 for(std::vector<Trk::TrkTrackState*>::iterator ptsIt=vpTrackStates.begin();
1064 ptsIt!=vpTrackStates.end();++ptsIt)
delete (*ptsIt);
1065 vpTrackStates.clear();
1068 pnIt=vpTrkNodes.begin();pnEnd=vpTrkNodes.end();
1069 for(;pnIt!=pnEnd;++pnIt)
1071 delete((*pnIt)->getSurface());
1076 if(OK)
return StatusCode::SUCCESS;
1077 else return StatusCode::FAILURE;