26 m_cov0{250., 250.,0.25, 0.25, 0.000001},
27 m_projectionMatrices(5),
31 declareProperty(
"InitialCovariances",m_cov0,
"default covariance to be used at start of filter");
32 declareProperty(
"FastTrackStateCovCalculation",m_useFruehwirth8a=
false,
"toggles which formula to use for updated cov");
33 declareInterface<IUpdator>(
this );
45 if (m_cov0.size() < 5) {
46 ATH_MSG_WARNING(
"Wrong-sized initial covariance given, so set to default: " );
47 m_cov0 = {250.,250,0.25,0.25, 0.000001};
49 return StatusCode::SUCCESS;
55 return StatusCode::SUCCESS;
62 if (m_outputlevel <= 0) logStart(
"addToState(TP,LPOS,ERR)",trkPar);
64 return calculateFilterStep (trkPar, measmtPos, measmtErr,1,fitQoS,
false);
71 if (m_outputlevel <= 0) logStart(
"addToState(TP,LPAR,ERR)",trkPar);
73 return calculateFilterStep (trkPar, measmtPar, measmtErr,1,fitQoS,
false);
80 if (m_outputlevel <= 0) logStart(
"addToState(TP,LPOS,ERR,FQ)",trkPar);
82 ATH_MSG_WARNING(
"expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
85 return calculateFilterStep (trkPar, measmtPos, measmtErr, 1, fitQoS,
true);
94 if (m_outputlevel <= 0) logStart(
"addToState(TP,LPAR,ERR,FQ)",trkPar);
96 ATH_MSG_WARNING(
"expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
99 return calculateFilterStep (trkPar, measmtPar, measmtErr, 1, fitQoS,
true);
107 if (m_outputlevel<=0) logStart(
"removeFromState(TP,LPOS,ERR)",trkPar);
109 return calculateFilterStep (trkPar, measmtPos, measmtErr,-1,fitQoS,
false);
116 if (m_outputlevel) logStart(
"removeFromState(TP,LPAR,ERR)",trkPar);
118 return calculateFilterStep (trkPar, measmtPar, measmtErr,-1,fitQoS,
false);
126 if (m_outputlevel<=0) logStart(
"removeFromState(TP,LPOS,ERR,FQ)",trkPar);
129 <<
" avoid mem leak!" );
132 return calculateFilterStep (trkPar, measmtPos, measmtErr, -1, fitQoS,
true);
141 if (m_outputlevel<=0) logStart(
"removeFromState(TP,LPAR,ERR,FQ)",trkPar);
144 <<
" avoid mem leak!" );
147 return calculateFilterStep (trkPar, measmtPar, measmtErr, -1, fitQoS,
true);
151 std::unique_ptr<Trk::TrackParameters>
156 if (!
one.covariance() && !
two.covariance()) {
158 <<
"use of Updator::combineStates()" );
162 if (!
one.covariance()) {
163 if (m_outputlevel<=0) logResult(
"combineStates(TP,TP)",
two.parameters(),
165 return std::unique_ptr<Trk::TrackParameters>(
two.clone());
167 if (!
two.covariance()) {
168 if (m_outputlevel<=0) logResult(
"combineStates(TP,TP)",
one.parameters(),
170 return std::unique_ptr<Trk::TrackParameters>(
one.clone());
184 if (!diffThetaPhiWithinRange(
r)) correctThetaPhiRange(
r,sumCov,
true);
187 if ( (!thetaPhiWithinRange(
par)) ? !correctThetaPhiRange(
par,covPar,
false) : false ) {
188 ATH_MSG_WARNING(
"combineStates(TP,TP): could not combine angular values." );
200 if (m_outputlevel <= 0){
201 logResult(
"combineStates(TP,TP)",
par, covPar);
212 if (!
one.covariance() && !
two.covariance()) {
213 ATH_MSG_WARNING(
"both parameters have no errors, invalid use of Updator::combineStates()" );
217 ATH_MSG_WARNING(
"expect nil FitQuality pointer, refuse operation to avoid mem leak!" );
221 if (!
one.covariance()) {
223 if (m_outputlevel<=0) logResult(
"combineStates(TP,TP,FQ)",
one.parameters(),
224 (*
two.covariance()));
225 return std::unique_ptr<Trk::TrackParameters>(
two.clone());
227 if (!
two.covariance()) {
229 if (m_outputlevel<=0) logResult(
"combineStates(TP,TP,FQ)",
one.parameters(),
230 (*
one.covariance()));
231 return std::unique_ptr<Trk::TrackParameters>(
one.clone());
242 if (!diffThetaPhiWithinRange(
r)) correctThetaPhiRange(
r,R,
true);
247 if ( (!thetaPhiWithinRange(
par)) ? !correctThetaPhiRange(
par,covPar) : false ) {
248 ATH_MSG_WARNING(
"combineStates(TP,TP,FQ): could not combine angular values." );
263 if (m_outputlevel <= 0){
264 logResult(
"combineStates(TP,TP,FQ)",
par, covPar);
276 ATH_MSG_DEBUG(
"--> entered KalmanUpdator::fullStateFitQuality(TP,LPOS,ERR)" );
279 if (!trkPar.covariance()) {
280 ATH_MSG_ERROR(
"updated smoother/trajectory has no error matrix" );
287 int nLocCoord = rioErr.cols();
289 for (
int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
290 rioPar[iLocCoord] = locPos[iLocCoord];
296 for (
int i=0;
i < nLocCoord;
i++)
H(
i,
i)=1.f;
302 return makeChi2Object(
r,covTrk,rioErr,-1,(nLocCoord==1?1:3));
311 ATH_MSG_VERBOSE(
"--> entered KalmanUpdator::fullStateFitQuality(TP,LPAR,ERR)" );
314 if (!trkPar.covariance()) {
315 ATH_MSG_ERROR(
"updated smoother/trajectory has no error matrix" );
318 if ( !consistentParamDimensions(rioPar,rioErr.cols()) )
return {};
329 else r -=
H*trkPar.parameters();
332 return makeChi2Object(
r,covTrk,rioErr,-1,rioPar.
parameterKey());
340 ATH_MSG_VERBOSE(
"--> entered KalmanUpdator::predictedStateFitQuality(TP,LPOS,ERR)" );
342 if (predPar.covariance() ==
nullptr) {
343 ATH_MSG_WARNING(
"input state has no error matrix in predictedStateFitQuality()" );
347 const AmgSymMatrix(5)& covPred = (*predPar.covariance());
350 int nLocCoord = rioLocErr.cols();
352 for (
int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
353 rioPar[iLocCoord] = rioLocPos[iLocCoord];
359 for (
int i=0;
i < nLocCoord;
i++)
H(
i,
i)=1.f;
365 return makeChi2Object(
r,covPred,rioLocErr,+1,(nLocCoord==1?1:3));
373 ATH_MSG_VERBOSE(
"--> entered KalmanUpdator::predictedStateFitQuality(TP,LPAR,ERR)" );
376 if (predPar.covariance() ==
nullptr) {
377 ATH_MSG_WARNING(
"input state has no error matrix in predictedStateFitQuality()" );
381 if ( ! consistentParamDimensions(rioPar,rioErr.cols()) )
return {};
384 const AmgSymMatrix(5)& covPred = (*predPar.covariance());
392 else r -=
H * predPar.parameters();
395 return makeChi2Object(
r,covPred,rioErr,+1,rioPar.
parameterKey());
402 ATH_MSG_VERBOSE(
"--> entered KalmanUpdator::predictedStateFitQuality(TP,TP)" );
404 if (!
one.covariance() && !
two.covariance()) {
406 <<
"use of Updator::fitQuality()" );
410 if (!
one.covariance() || !
two.covariance()) {
412 <<
"assume initial state and return chi2=0.0" );
427 std::vector<double>
E(5);
428 for (
int i=0;
i<5; ++
i)
E[
i] = std::sqrt(m_cov0[
i]);
433 std::unique_ptr<Trk::TrackParameters>
439 bool createFQoS)
const
444 if (!trkPar.covariance()) {
446 ATH_MSG_WARNING(
"MeasuredTrackParameters == Null, can not calculate updated parameter state" );
451 ATH_MSG_VERBOSE(
"-U- no covTrk at input - assign large error matrix for the time being." );
452 covTrk(0,0) = m_cov0[0];
453 covTrk(1,1) = m_cov0[1];
454 covTrk(2,2) = m_cov0[2];
455 covTrk(3,3) = m_cov0[3];
456 covTrk(4,4) = m_cov0[4];
459 covTrk = (*trkPar.covariance());
465 if (!thetaPhiWithinRange(parTrk)) {
467 <<
": undefined phi,theta range in input parameters." );
472 int nLocCoord = covRio.cols();
473 if ( (nLocCoord < 1) || (nLocCoord > 2 ) ) {
474 ATH_MSG_WARNING(
" number of local coordinates must be 1 or 2, but it is "
478 for (
int iLocCoord=0; iLocCoord < nLocCoord; iLocCoord++) {
479 rioPar[iLocCoord] = locPos[iLocCoord];
481 if (m_outputlevel<0) logInputCov(covTrk,rioPar,covRio);
486 for (
int i=0;
i < nLocCoord;
i++)
H(
i,
i)=1.f;
492 Amg::MatrixX R = (
sign * covRio) + projection(covTrk,(nLocCoord==1 ? 1 : 3) );
498 if (m_outputlevel<0) {logGainForm (nLocCoord,
r,R.inverse(),K,M);}
505 if (m_useFruehwirth8a) {
511 covPar =
AmgSymMatrix(5)(M*covTrk*M.transpose() +
sign*K*covRio*K.transpose());
513 if ( (!thetaPhiWithinRange(
par)) ? !correctThetaPhiRange(
par,covPar) : false ) {
514 ATH_MSG_WARNING(
"calculateFS(TP,LPOS,ERR): bad angles in filtered state!" );
517 if (m_outputlevel<=0) logResult(createFQoS?
518 (
sign>0?
"addToState(TP,LPOS,ERR,FQ)":
"removeFromState(TP,LPOS,ERR,FQ)"):
519 (
sign>0?
"addToState(TP,LPOS,ERR)":
"removeFromState(TP,LPOS,ERR)"),
530 fitQoS =
new FitQualityOnSurface(makeChi2Object(r_upd,covPar,covRio,-1,(nLocCoord==1?1:3)));
545 std::unique_ptr<Trk::TrackParameters>
551 bool createFQoS)
const
556 if (!trkPar.covariance()) {
559 <<
"updated parameter state." );
565 <<
"assign large error matrix for the time being." );
566 covTrk(0,0) = m_cov0[0];
567 covTrk(1,1) = m_cov0[1];
568 covTrk(2,2) = m_cov0[2];
569 covTrk(3,3) = m_cov0[3];
570 covTrk(4,4) = m_cov0[4];
573 covTrk = (*trkPar.covariance());
578 if (!thetaPhiWithinRange(parTrk)) {
580 <<
": undefined phi,theta range in input parameters." );
583 if (!thetaPhiWithinRange(rioPar,rioPar.
parameterKey())) {
585 <<
": undefined phi,theta range in input measurement !!" );
590 int nLocCoord = covRio.cols();
591 if ( ! consistentParamDimensions(rioPar,covRio.cols()) )
return nullptr;
592 if (m_outputlevel<0) logInputCov(covTrk,rioPar,covRio);
606 if (R.determinant()==0.)
return nullptr;
611 if (m_outputlevel<0) {logGainForm (nLocCoord,
r,R.inverse(),K,M);}
617 if (m_useFruehwirth8a) {
621 covPar =
AmgSymMatrix(5)(M*covTrk*M.transpose() +
sign*K*covRio*K.transpose());
623 if ( (!thetaPhiWithinRange(
par)) ? !correctThetaPhiRange(
par,covPar) : false ) {
624 ATH_MSG_WARNING(
"calculateFS(TP,LPAR,ERR): bad angles in filtered state!" );
627 if (m_outputlevel<=0) logResult(createFQoS?
628 (
sign>0?
"addToState(TP,LPAR,ERR,FQ)":
"removeFromState(TP,LPAR,ERR,FQ)"):
629 (
sign>0?
"addToState(TP,LPAR,ERR)":
"removeFromState(TP,LPAR,ERR)"),
656 if (
key == 31)
return M;
658 const Amg::MatrixX& redMatrix = m_projectionMatrices.reductionMatrix(
key);
668 if (
P.dimension() != dimCov ) {
669 ATH_MSG_WARNING(
"Inconsistency in dimension of local coord - problem with LocalParameters object?" );
670 ATH_MSG_WARNING(
"dim of local parameters: "<<
P.dimension()<<
" vs. dim of error matrix: "<<dimCov );
673 if ( (dimCov < 1) || (dimCov > 5 ) ) {
674 ATH_MSG_WARNING(
"invalid dimension for local coordinates: " << dimCov );
682 const bool isDifference,
const int key)
const
687 double thetaMin = (isDifference ? -
M_PI : 0);
690 for (
int itag = 0, ipos=1 ; itag<
Trk::phi; ++itag, ipos*=2)
if (
key & ipos) ++jphi;
694 for (
int itag = 0, ipos=1 ; itag<
Trk::theta; ++itag, ipos*=2)
if (
key & ipos) ++jtheta;
698 if ((jtheta>=0) && (V[jtheta]<thetaMin || V[jtheta]>
M_PI) ) {
699 if (m_outputlevel <= 0 ) {
701 msg() << MSG::WARNING <<
"-U- " << (isDifference?
"diff. ":
" ") <<
"angles out of range, phi = ";
702 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
703 msg() <<
" theta = " << V[jtheta] <<
endmsg;
707 if ( ( V(jtheta) < -
M_PI ) ||
708 ( V(jtheta) > (isDifference?
M_PI : 2*
M_PI) )
710 ATH_MSG_WARNING(
"-U- track theta too far from defined range, stop update." );
711 msg() << MSG::WARNING <<
"-U- " << (isDifference?
"diff. ":
" ") <<
"angles out of range, phi = ";
712 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
713 msg() <<
" theta = " << V[jtheta] <<
endmsg;
716 if (V[jtheta] >
M_PI) {
717 V[jtheta] = 2*
M_PI - V[jtheta];
718 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -
M_PI :
M_PI;
720 if (V[jtheta] < 0.0) {
721 V[jtheta] = -V[jtheta];
722 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -
M_PI :
M_PI;
724 if (jtheta==0 &&
key==24)
C(jtheta,1) = -
C(jtheta,1);
726 C(0,jtheta) = -
C(0,jtheta);
727 if (
key>15)
C(2,1) = -
C(2,1);
730 C(0,jtheta) = -
C(0,jtheta);
731 C(1,jtheta) = -
C(1,jtheta);
732 if (
key>15)
C(3,jtheta) = -
C(3,jtheta);
735 C(0,jtheta) = -
C(0,jtheta);
736 C(1,jtheta) = -
C(1,jtheta);
737 C(2,jtheta) = -
C(2,jtheta);
738 if (
key>15)
C(4,jtheta) = -
C(4,jtheta);
741 if (m_outputlevel <=0) {
742 msg() <<
MSG::DEBUG <<
"-U- now use corrected " << (isDifference?
"diff. ":
" ") <<
"value phi= ";
743 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
744 msg() <<
" theta = " << V[jtheta] <<
endmsg;
749 if ((jphi>=0) && (V[jphi] >
M_PI) ) {
752 ATH_MSG_DEBUG(
" out of range, now corrected to " << V[jphi]);
753 }
else if ((jphi>=0) && (V[jphi] < -
M_PI) ) {
756 ATH_MSG_DEBUG(
" out of range, now corrected to " << V[jphi] );
764 const bool isDifference,
const int key)
const
769 double thetaMin = (isDifference ? -
M_PI : 0);
772 for (
int itag = 0, ipos=1 ; itag<
Trk::phi; ++itag, ipos*=2)
if (
key & ipos) ++jphi;
776 for (
int itag = 0, ipos=1 ; itag<
Trk::theta; ++itag, ipos*=2)
if (
key & ipos) ++jtheta;
780 if ((jtheta>=0) && (V[jtheta]<thetaMin || V[jtheta]>
M_PI) ) {
781 if (m_outputlevel <= 0 ) {
783 msg() << MSG::WARNING <<
"-U- " << (isDifference?
"diff. ":
" ") <<
"angles out of range, phi = ";
784 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
785 msg() <<
" theta = " << V[jtheta] <<
endmsg;
789 if ( ( V(jtheta) < -
M_PI ) ||
790 ( V(jtheta) > (isDifference?
M_PI : 2*
M_PI) )
792 ATH_MSG_WARNING(
"-U- track theta too far from defined range, stop update." );
793 msg() << MSG::WARNING <<
"-U- " << (isDifference?
"diff. ":
" ") <<
"angles out of range, phi = ";
794 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
795 msg() <<
" theta = " << V[jtheta] <<
endmsg;
798 if (V[jtheta] >
M_PI) {
799 V[jtheta] = 2*
M_PI - V[jtheta];
800 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -
M_PI :
M_PI;
802 if (V[jtheta] < 0.0) {
803 V[jtheta] = -V[jtheta];
804 if (jphi>=0) V[jphi] += (V[jphi]>0.0) ? -
M_PI :
M_PI;
806 if (jtheta==0 &&
key==24) C(jtheta,1) = -C(jtheta,1);
808 C(0,jtheta) = -C(0,jtheta);
809 if (
key>15) C(2,1) = -C(2,1);
812 C(0,jtheta) = -C(0,jtheta);
813 C(1,jtheta) = -C(1,jtheta);
814 if (
key>15) C(3,jtheta) = -C(3,jtheta);
817 C(0,jtheta) = -C(0,jtheta);
818 C(1,jtheta) = -C(1,jtheta);
819 C(2,jtheta) = -C(2,jtheta);
820 if (
key>15) C(4,jtheta) = -C(4,jtheta);
823 if (m_outputlevel <=0) {
824 msg() <<
MSG::DEBUG <<
"-U- now use corrected " << (isDifference?
"diff. ":
" ") <<
"value phi= ";
825 if (jphi>=0)
msg() << V[jphi];
else msg() <<
"free";
826 msg() <<
" theta = " << V[jtheta] <<
endmsg;
831 if ((jphi>=0) && (V[jphi] >
M_PI) ) {
832 if (m_outputlevel <=0)
msg() <<
MSG::DEBUG <<
"-U- phi= " << V[jphi];
835 <<
"corrected to " << V[jphi] );
836 }
else if ((jphi>=0) && (V[jphi] < -
M_PI) ) {
837 if (m_outputlevel <=0)
msg() <<
MSG::DEBUG <<
"-U- phi= " << V[jphi];
840 <<
"corrected to " << V[jphi] );
849 ATH_MSG_VERBOSE(
"-U- TrkPar:" << std::setiosflags(std::ios::right)<<std::setprecision(4)
850 << std::setw( 9)<<
tp.parameters()[0]<< std::setw(10)<<
tp.parameters()[1]<<std::setprecision(5)
851 << std::setw(10)<<
tp.parameters()[2]<< std::setw(10)<<
tp.parameters()[3]<<std::setprecision(4)
852 << std::setw(10)<<
tp.parameters()[4] );
858 msg() <<
MSG::VERBOSE <<
"-U- cov "<<std::setiosflags(std::ios::right)<<std::setprecision(3)
859 << std::setw(9)<<covTrk(0,0)<<
" "<< std::setw(9)<<covTrk(0,1)<<
" "
860 << std::setw(9)<<covTrk(0,2)<<
" "<< std::setw(9)<<covTrk(0,3)<<
" "
861 << std::setw(9)<<covTrk(0,4)<<
"\n";
862 msg() <<
" " <<
" " <<
" "
863 << std::setw(9)<<covTrk(1,1)<<
" "<< std::setw(9)<<covTrk(1,2)<<
" "
864 << std::setw(9)<<covTrk(1,3)<<
" "<< std::setw(9)<<covTrk(1,4)<<
"\n";
865 msg() <<
" covariance matrix " <<
" " <<
" "
866 << std::setw(9)<<covTrk(2,2)<<
" "<< std::setw(9)<<covTrk(2,3)<<
" "
867 << std::setw(9)<<covTrk(2,4)<<
"\n" ;
868 msg() <<
" of the PREDICTED track pars " <<
" " <<
" "
869 << std::setw(9)<<covTrk(3,3)<<
" "<< std::setw(9)<<covTrk(3,4)<<
"\n" ;
870 msg() <<
" " <<
" " <<
" "
871 << std::setw(9)<<covTrk(4,4)<<std::setprecision(6)<<
endmsg;
873 int nLocCoord = covRio.cols();
875 for (
int i=0;
i<nLocCoord;
i++)
msg() << rioPar[
i] <<
" ";
877 msg() <<
MSG::VERBOSE <<
"-U- measurement (err)^2: " <<std::setprecision(4)<<covRio(0,0);
878 for (
int i=1;
i<nLocCoord;
i++)
msg() <<
", "<<covRio(
i,
i);
890 for (
int i=1;
i<
nc;
i++)
msg() <<
"," << R(
i,
i);
893 << (
i==0 ?
"-U- gain mtx K=(" :
" (" )
894 << std::setiosflags(std::ios::fixed | std::ios::showpoint | std::ios::right )
895 << std::setw(7) << std::setprecision(4) << K(0,
i)<<
", "
896 << std::setw(7) << std::setprecision(4) << K(1,
i)<<
", "
897 << std::setw(7) << std::setprecision(4) << K(2,
i)<<
", "
898 << std::setw(7) << std::setprecision(4) << K(3,
i)<<
", "
899 << std::setw(7) << std::setprecision(4) << K(4,
i)<<
")"
900 << std::resetiosflags(std::ios::fixed) <<
endmsg;
902 << M(0,0)<<
"," << M(1,1)<<
","
903 << M(2,2)<<
"," << M(3,3)<<
","
904 << M(4,4) <<
")" <<
endmsg;
912 msg() <<
MSG::VERBOSE <<
"-U- new par"<<std::setiosflags(std::ios::right)<<std::setprecision(4)
913 << std::setw( 9)<<
par[0]<< std::setw(10)<<
par[1]<<std::setprecision(5)
914 << std::setw(10)<<
par[2]<< std::setw(10)<<
par[3]<<std::setprecision(4)
916 msg() <<
MSG::VERBOSE <<
"-U- new cov" <<std::setiosflags(std::ios::right)<<std::setprecision(3)
917 << std::setw(9)<<(covPar)(0,0)<<
" "<< std::setw(9)<<(covPar)(0,1)<<
" "
918 << std::setw(9)<<(covPar)(0,2)<<
" "<< std::setw(9)<<(covPar)(0,3)
919 <<
" " << std::setw(9)<<(covPar)(0,4)<<
"\n";
920 msg() <<
" " <<
" " <<
" "
921 << std::setw(9)<<(covPar)(1,1)<<
" "<< std::setw(9)<<(covPar)(1,2)<<
" "
922 << std::setw(9)<<(covPar)(1,3)<<
" "<< std::setw(9)<<(covPar)(1,4)<<
"\n";
923 msg() <<
" covariance matrix " <<
" " <<
" "
924 << std::setw(9)<<(covPar)(2,2)<<
" "<< std::setw(9)<<(covPar)(2,3)<<
" "
925 << std::setw(9)<<(covPar)(2,4)<<
"\n";
926 msg() <<
" of the UPDATED track pars " <<
" "
927 <<
" " <<std::setw(9)<<(covPar)(3,3)<<
" "
928 << std::setw(9)<<(covPar)(3,4)<<
"\n";
931 << std::setw(9)<<(covPar)(4,4)<<std::setprecision(6)<<
endmsg;