ATLAS Offline Software
KalmanVertexTrackUpdator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 
10 namespace Trk
11 {
13  {
14  //uploading the corresponding tools
15  //updator
16  if ( m_Updator.retrieve().isFailure() )
17  {
18  ATH_MSG_FATAL("Failed to retrieve tool " << m_Updator);
19  return StatusCode::FAILURE;
20  }
21  ATH_MSG_INFO("Retrieved tool " << m_Updator);
22 
23 
24  return StatusCode::SUCCESS;
25  }
26 
27  KalmanVertexTrackUpdator::KalmanVertexTrackUpdator(const std::string& t, const std::string& n, const IInterface* p):
28  AthAlgTool(t,n,p)
29  {
30  declareInterface<IVertexTrackUpdator>(this);
31  }
32 
34  {
35  const Amg::Vector3D & fit_vrt_pos = vtx.position();
36  Trk::LinearizedTrack * linTrack = trk.linState();
37 
38  //protection check
39  if(linTrack == nullptr)
40  {
41  if(trk.weight() > m_maxWeight)
42  {
43  //actual error case
44  msg(MSG::INFO) << "The VxTrackAtVertex passed does not have a Linearized Track" << endmsg;
45  msg(MSG::INFO) << "Please produce one with corresponding LinearizedTrackFactory"<< endmsg;
46  msg(MSG::INFO) << "The VxTrackAtVertex returned not refitted"<< endmsg;
47  // std::cout<<"Weight of the track: "<<trk.weight()<<std::endl;
48  }else{
49  if (msgLvl(MSG::DEBUG))
50  {
51  msg(MSG::DEBUG) << "The VxTrackAtVertex passed does not have a Linearized Track" << endmsg;
52  msg(MSG::DEBUG) << "However the weight of this track is less than " << m_maxWeight << endmsg;
53  msg(MSG::DEBUG) << "The VxTrackAtVertex returned not refitted"<< endmsg;
54  }
55  }//end of absent linTrack case
56 
57  return;
58  }//end of no lintrack check
59 
60  //getting Jacobians and track information
61  const AmgMatrix(5,3) & A = linTrack->positionJacobian();
62  const AmgMatrix(5,3) & B = linTrack->momentumJacobian();
63  const AmgVector(5) & trkParameters = linTrack->expectedParametersAtPCA();
64  // std::cout << "Perigee before refit " << trkParameters << std::endl;
65  // std::cout << "Track covariance before refit " << linTrack->expectedPerigeeCovarianceAtPCA() << std::endl;
66 
67  const AmgSymMatrix(5) & trkParametersWeight = linTrack->expectedWeightAtPCA();
68 
69  //calculation of S matrix
70  AmgSymMatrix(3) Sm = B.transpose()*(trkParametersWeight*B);
71 
72  if (Sm.determinant() == 0.0) {
73  ATH_MSG_WARNING("Matrix can not be inverted, new type of check as part of Eigen, please monitor."
74  << endmsg << "Matrix Sm = " << Sm);
75  return;
76  }
77  Sm = Sm.inverse().eval();
78  const AmgVector(5) & theResidual = linTrack->constantTerm();
79 
80  //refitted track momentum
81  Amg::Vector3D newTrackMomentum = Sm*B.transpose() * trkParametersWeight
82  * (trkParameters - theResidual - A*fit_vrt_pos);
83 
84  //refitted track parameters
85  AmgVector(5) refTrkPar; refTrkPar.setZero();
86  refTrkPar(Trk::phi) = newTrackMomentum(0);//phi
87  refTrkPar(Trk::theta) = newTrackMomentum(1);//theta
88  refTrkPar(Trk::qOverP)= newTrackMomentum(2);//qoverP
89 
90  //bring parameter phi again in the limits, if
91  //phi is slightly outside (as can be expected
92  //due to refitting)
93  // if (refTrkPar[2]<-M_PI) {
94  // refTrkPar[2] = refTrkPar[2]+M_PI;
95  // } else if (refTrkPar[2]>M_PI) {
96  // refTrkPar[2] = refTrkPar[2]-M_PI;
97  // }
98 
99  if (refTrkPar[Trk::phi0] > M_PI)
100  {
101  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< "-U- phi = " << refTrkPar[Trk::phi0];
102  refTrkPar[Trk::phi0] = fmod(refTrkPar[Trk::phi0]+M_PI,2*M_PI)-M_PI;
103  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " out of range, now "
104  << "corrected to " << refTrkPar[Trk::phi0] << endmsg;
105  } else if(refTrkPar[Trk::phi0]<-M_PI) {
106  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< "-U- phi = " << refTrkPar[Trk::phi0];
107  refTrkPar[Trk::phi0] = fmod(refTrkPar[Trk::phi0]-M_PI,2*M_PI)+M_PI;
108  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " out of range, now "
109  << "corrected to " << refTrkPar[Trk::phi0] << endmsg;
110  }
111 
112  if (refTrkPar[Trk::theta] > M_PI)
113  {
114  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " Theta out of range: correcting theta: " << refTrkPar[Trk::theta];
115  refTrkPar[Trk::theta]=fmod(refTrkPar[Trk::theta]+M_PI,2*M_PI)-M_PI;
116  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " to: " << refTrkPar[Trk::theta] << endmsg;
117  }
118  else if (refTrkPar[Trk::theta]<0)
119  {
120  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " Theta out of range: correcting theta: " << refTrkPar[Trk::theta];
121  refTrkPar[Trk::theta]=fmod(refTrkPar[Trk::theta]-M_PI,2*M_PI)+M_PI;
122  if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG)<< " to: " << refTrkPar[Trk::theta] << endmsg;
123  }
124 
125  if (refTrkPar[Trk::theta] < 0)
126  {
127  refTrkPar[Trk::theta] =
128  - refTrkPar[Trk::theta];
129  refTrkPar[Trk::phi0] +=
130  (refTrkPar[Trk::phi0] > 0 ? -M_PI : M_PI);
131  } else if (refTrkPar[Trk::theta] > M_PI) {//this in principle should not be needed anymore
132  refTrkPar[Trk::theta] =
133  2*M_PI - refTrkPar[Trk::theta];
134  refTrkPar[Trk::phi0] +=
135  (refTrkPar[Trk::phi0] > 0 ? -M_PI : M_PI);
136  }
137 
138  //temporary hack to check the consistence of the frame
139  // std::cout<<"New track parameters "<<refTrkPar<<std::endl;
140 
141  //vertex covariance and weight
142  const AmgSymMatrix(3)& vrt_cov = vtx.covariancePosition();
143  if (vrt_cov.determinant() == 0.0) {
144  ATH_MSG_WARNING("Matrix can not be inverted, new type of check as part of Eigen, please monitor."
145  << endmsg << "Matrix vrt_cov = " << vrt_cov);
146  return;
147  }
148  AmgSymMatrix(3) vrt_weight;
149  bool invertible;
151  vrt_weight = vtx.covariancePosition().inverse();
152  invertible = true;
153  } else
154  vtx.covariancePosition().computeInverseWithCheck(vrt_weight,invertible);
155 
156  if(!invertible) {
157  ATH_MSG_VERBOSE ("The vertex's cov is not invertible, quit updating the track.");
158  return;
159  }
160 
161  //making a new track covariance matrix
162  AmgSymMatrix(3) posMomentumCovariance = -vrt_cov * A.transpose() * trkParametersWeight * B *Sm;
163 
164  //--------------------------------------------------------------------------------------------------------
165  //correction to what was forgotten before: making the smoothed chi2 of track
166  //this operation invokes removing of the track from the vertex
167  const IVertexUpdator::positionUpdateOutcome & reducedVrt = m_Updator->positionUpdate( vtx, linTrack, trk.weight(), IVertexUpdator::removeTrack );
168 
169  AmgSymMatrix(3) reduced_vrt_weight;
171  reduced_vrt_weight = reducedVrt.covariancePosition.inverse();
172  } else
173  reducedVrt.covariancePosition.computeInverseWithCheck(reduced_vrt_weight,invertible);
174  if(!invertible) {
175  ATH_MSG_VERBOSE ("The vertex's cov is not invertible, quit updating the track.");
176  return;
177  }
178  // const CLHEP::HepSymMatrix & reduced_vrt_cov = reducedVrt.covariancePosition();
179 
180  Amg::Vector3D posDifference = vtx.position() - reducedVrt.position;
181 
182  //now making the second part of the chi2 calculation: smoothed parameters
183  AmgVector(5) smRes = trkParameters - (theResidual + A*vtx.position() + B*newTrackMomentum);
184 
185  double chi2 = posDifference.dot(reduced_vrt_weight*posDifference) + smRes.dot(trkParametersWeight*smRes);
186 
187  // std::cout<<"Smoothed chi2 in the fit "<<chi2<<std::endl;
188  //-------------------------------------------------------------------------------------
189  //new momentum covariance
190  AmgSymMatrix(3) momentumCovariance = Sm + posMomentumCovariance.transpose()*(vrt_weight*posMomentumCovariance);
191 
192  //full (x,y,z,phi, theta, q/p) covariance matrix
193  AmgSymMatrix (6) fullTrkCov;
194  fullTrkCov.setZero();
195 
196  fullTrkCov.block<3,3>(0,0) = vrt_cov;
197  fullTrkCov.block<3,3>(0,3) = posMomentumCovariance;
198  fullTrkCov.block<3,3>(3,0) = posMomentumCovariance.transpose();
199  fullTrkCov.block<3,3>(3,3) = momentumCovariance;
200 
201  //debug hacking
202  AmgMatrix(5,6) trJac;
203  trJac.setZero();
204  trJac(4,5) = 1.;
205  trJac(3,4) = 1.;
206  trJac(2,3) = 1.;
207 
208  //first row
209  trJac(0,0) = - sin(refTrkPar[2]);
210  trJac(0,1) = cos(refTrkPar[2]);
211 
212  //second row
213  trJac(1,0) = -cos(refTrkPar[2])/tan(refTrkPar[3]);
214  trJac(1,1) = -sin(refTrkPar[2])/tan(refTrkPar[3]);
215  trJac(1,2) = 1.;
216 
217  AmgSymMatrix(5) perFullTrkCov = AmgSymMatrix(5)(trJac*(fullTrkCov*trJac.transpose()));
218 
219  //temporary hack: returning the state with incorrect covariance matrix, to see
220  //how general infrastructure works.
221 
222 
223  Trk::Perigee * refittedPerigee = new Trk::Perigee(refTrkPar[0],
224  refTrkPar[1],
225  refTrkPar[2],
226  refTrkPar[3],
227  refTrkPar[4],
228  fit_vrt_pos,
229  std::move(perFullTrkCov));
230 
231  trk.setPerigeeAtVertex(refittedPerigee);
232  const FitQuality trkQuality(chi2,2*trk.weight());
233  // std::cout<<"Tracks at vertex are assigned with chi2 "<<trkQuality.chiSquared()<<std::endl;
234  // std::cout<<"Tracks at vertex are assigned with ndf "<<trkQuality.numberDoF()<<std::endl;
235  trk.setTrackQuality(trkQuality);
236 
237  }//end of update method
238 
239 }//end of namespace definitions
Trk::AmgMatrix
AmgMatrix(3, 3) NeutralParticleParameterCalculator
Definition: NeutralParticleParameterCalculator.cxx:233
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::KalmanVertexTrackUpdator::m_Updator
ToolHandle< IVertexUpdator > m_Updator
Definition: KalmanVertexTrackUpdator.h:63
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Trk::VxTrackAtVertex
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
Definition: VxTrackAtVertex.h:77
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::Perigee
ParametersT< 5, Charged, PerigeeSurface > Perigee
Definition: Tracking/TrkEvent/TrkParameters/TrkParameters/TrackParameters.h:29
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Trk::VxTrackAtVertex::weight
double weight(void) const
Information about the weight of track in fit (given back by annealing): weight=ndf/2.
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
Trk::KalmanVertexTrackUpdator::KalmanVertexTrackUpdator
KalmanVertexTrackUpdator(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
Definition: KalmanVertexTrackUpdator.cxx:27
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
Trk::KalmanVertexTrackUpdator::update
virtual void update(VxTrackAtVertex &trk, const xAOD::Vertex &vtx) const override
Update method
Definition: KalmanVertexTrackUpdator.cxx:33
Trk::KalmanVertexTrackUpdator::m_maxWeight
DoubleProperty m_maxWeight
Definition: KalmanVertexTrackUpdator.h:66
beamspotman.n
n
Definition: beamspotman.py:731
Trk::VxTrackAtVertex::setTrackQuality
void setTrackQuality(const FitQuality &trkQuality)
Set methods for various components.
Trk::theta
@ theta
Definition: ParamDefs.h:72
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
VxTrackAtVertex.h
Trk::KalmanVertexTrackUpdator::initialize
virtual StatusCode initialize() override
Definition: KalmanVertexTrackUpdator.cxx:12
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
Trk::FitQuality
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition: FitQuality.h:97
Trk::IVertexUpdator::positionUpdateOutcome::position
Amg::Vector3D position
Definition: IVertexUpdator.h:61
Trk::VxTrackAtVertex::linState
LinearizedTrack * linState(void)
Access method for the perigee linearized track.
KalmanVertexTrackUpdator.h
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::KalmanVertexTrackUpdator::m_skipInvertibleCheck
BooleanProperty m_skipInvertibleCheck
Definition: KalmanVertexTrackUpdator.h:68
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::IVertexUpdator::positionUpdateOutcome
Definition: IVertexUpdator.h:60
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::IVertexUpdator::removeTrack
@ removeTrack
Definition: IVertexUpdator.h:69
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
Trk::phi
@ phi
Definition: ParamDefs.h:81
LinearizedTrack.h
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
FitQuality.h
Trk::VxTrackAtVertex::setPerigeeAtVertex
void setPerigeeAtVertex(TrackParameters *perigee)
Setting up parameters at vertex.
Definition: VxTrackAtVertex.cxx:396
Trk::phi0
@ phi0
Definition: ParamDefs.h:71
Trk::LinearizedTrack
Definition: LinearizedTrack.h:43