22 #include "GaudiKernel/SystemOfUnits.h"
61 m_trackMaker(
"TrigDkfTrackMakerTool")
63 declareInterface< ITrigInDetTrackFitter >(
this );
87 return StatusCode::SUCCESS;
93 ATH_MSG_INFO(
"==============================================================");
94 ATH_MSG_INFO(
"TrigInDetTrackFitter::finalize() - LVL2 Track fit Statistics: ");
100 ATH_MSG_INFO(
"==============================================================");
101 return StatusCode::SUCCESS;
105 B[0]=0.0;
B[1]=0.0;
B[2]=0.0;
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;
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;
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;
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;
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));
385 double coeff[3], dadVx,dadVy,dadVz,dadQ,dsdx,dsdy,dsdz,dsdVx,dsdVy,dsdVz,dsdQ;
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);
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];
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);
580 if (!fieldCondObj.isValid()) {
585 fieldCondObj->getInitializedCache (fieldCache);
591 std::tie(fittedTrack,fittedTrackwTP) =
fitTrack(**trIt, fieldCache, ctx, matEffects, addTPtoTSoS);
592 if (fittedTrack!=
nullptr) {
595 if (addTPtoTSoS && fittedTrackwTP!=
nullptr) {
596 fittedTrackswTP.
push_back(fittedTrackwTP);
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");
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());
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);
824 std::unique_ptr<Trk::TrackParameters> pTP{};
825 if(
type==0)
return pTSS;
830 for(
int i=0;
i<5;
i++) {
831 for(
int j=0;j<5;j++) {
841 if(pPS==
nullptr)
return pTSS;
854 if(pLS==
nullptr)
return pTSS;
857 ATH_MSG_WARNING(
"Phi out of range when correcting Trk::TrackStateOnSurface");
861 pTP=std::make_unique<Trk::AtaStraightLine>(pTS->
getTrackState(0),
869 if(pTP==
nullptr)
return nullptr;
870 std::unique_ptr<Trk::RIO_OnTrack> pRIO{
m_ROTcreator->correct(*pPRD,*pTP,ctx)};
874 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
879 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePatternwTP;
892 std::vector<TrigL2HitResidual>& vResid,
const EventContext& ctx)
const {
895 if(trackPars==
nullptr) {
897 return StatusCode::FAILURE;
903 if (!fieldCondObj.isValid()) {
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;
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);
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 ");
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;