ATLAS Offline Software
Loading...
Searching...
No Matches
CvtPerigee.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Convert TrkTrack parameters to internal VKalVrt parameters
6// and sets up common reference system for ALL tracks
7// even if in the beginning in was different
8
9//------------------------------------------------------------------
10// Header include
13
14#include <iostream>
15
16namespace Trk{
17
18 //--------------------------------------------------------------------
19 //
20 // Use perigee ONLY!!!
21 // Then in normal conditions reference frame is always (0,0,0)
22 //
23
25 TrkVKalVrtFitter::CvtPerigee(const std::vector<const Perigee*>& InpPerigee,
26 int& ntrk,
27 State& state) const
28 {
29
30 double tmp_refFrameX = 0, tmp_refFrameY = 0, tmp_refFrameZ = 0;
31
32 //
33 // ----- Set reference frame to (0.,0.,0.) == ATLAS frame
34 // ----- Magnetic field is taken in reference point
35 //
36 state.m_refFrameX = state.m_refFrameY = state.m_refFrameZ = 0.;
37 state.m_fitField.setAtlasMagRefFrame( 0., 0., 0.);
38
39 //
40 // Cycle to determine common reference point for the fit
41 //
42 int counter =0;
43 state.m_trkControl.clear();
44 for (const auto& mPer : InpPerigee) {
45 if( mPer == nullptr ){ continue; }
46
47 // Global position of perigee point
48 Amg::Vector3D perGlobalPos = mPer->position();
49 // Crazy user protection
50 if(!(state.m_allowUltraDisplaced) && std::abs(perGlobalPos.z()) > m_IDsizeZ) return StatusCode::FAILURE;
51 if(!(state.m_allowUltraDisplaced) && perGlobalPos.perp() > m_IDsizeR) return StatusCode::FAILURE;
52
53 // Reference system calculation
54 // Use hit position itself to get more precise magnetic field
55 tmp_refFrameX += perGlobalPos.x() ;
56 tmp_refFrameY += perGlobalPos.y() ;
57 tmp_refFrameZ += perGlobalPos.z() ;
58
59 TrkMatControl tmpMat;
60 tmpMat.trkRefGlobPos = Amg::Vector3D(perGlobalPos.x(),
61 perGlobalPos.y(),
62 perGlobalPos.z());
63 // Perigee point strategy
64 tmpMat.extrapolationType = 2;
65 tmpMat.TrkPnt = mPer;
67 if(counter < static_cast<int>(state.m_MassInputParticles.size())){
68 tmpMat.prtMass = state.m_MassInputParticles[counter];
69 }
70 tmpMat.trkSavedLocalVertex.setZero();
71 tmpMat.TrkID=counter;
72 state.m_trkControl.push_back(tmpMat);
73 counter++;
74 }
75
76 if(counter == 0) return StatusCode::FAILURE;
77
78 // Reference frame for the fit
79 tmp_refFrameX /= counter;
80 tmp_refFrameY /= counter;
81 tmp_refFrameZ /= counter;
82
83 //
84 // Common reference frame is ready. Start extraction of parameters for fit.
85 //
86 double fx = 0., fy = 0., fz = 0.;
87 for (const auto& mPer : InpPerigee) {
88 if(mPer == nullptr){ continue; }
89 AmgVector(5) VectPerig = mPer->parameters();
90 // Global position of perigee point
91 Amg::Vector3D perGlobalPos = mPer->position();
92 // Global position of reference point
93 Amg::Vector3D perGlobalVrt = mPer->associatedSurface().center();
94 // Restore ATLAS frame
95 state.m_refFrameX = state.m_refFrameY = state.m_refFrameZ = 0.;
96 state.m_fitField.setAtlasMagRefFrame(0., 0., 0.);
97 // Magnetic field at perigee point
98 state.m_fitField.getMagFld(perGlobalPos.x(),
99 perGlobalPos.y(),
100 perGlobalPos.z(),
101 fx, fy, fz);
102 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, VectPerig[2], VectPerig[3]);
103 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG = 0.01;
104
105 double CovVertTrk[15];
106 std::fill(CovVertTrk,CovVertTrk+15,0.);
107 // No good covariance matrix!
108 if(!convertAmg5SymMtx(mPer->covariance(), CovVertTrk)) return StatusCode::FAILURE;
109 VKalTransform(effectiveBMAG,
110 static_cast<double>(VectPerig(0)),
111 static_cast<double>(VectPerig(1)),
112 static_cast<double>(VectPerig(2)),
113 static_cast<double>(VectPerig(3)),
114 static_cast<double>(VectPerig(4)),
115 CovVertTrk,
116 state.m_ich[ntrk], &state.m_apar[ntrk][0],
117 &state.m_awgt[ntrk][0]);
118
119 // Check if propagation to common reference point is needed and make it
120 // initial track reference position
121 state.m_refFrameX=perGlobalVrt.x();
122 state.m_refFrameY=perGlobalVrt.y();
123 state.m_refFrameZ=perGlobalVrt.z();
125 state.m_refFrameY,
126 state.m_refFrameZ);
127 double dX = tmp_refFrameX-perGlobalVrt.x();
128 double dY = tmp_refFrameY-perGlobalVrt.y();
129 double dZ = tmp_refFrameZ-perGlobalVrt.z();
130 if(std::abs(dX)+std::abs(dY)+std::abs(dZ) != 0.) {
131 double pari[5], covi[15];
132 double vrtini[3] = {0.,0.,0.};
133 double vrtend[3] = {dX,dY,dZ};
134 for(int i=0; i<5; i++) pari[i] = state.m_apar[ntrk][i];
135 for(int i=0; i<15;i++) covi[i] = state.m_awgt[ntrk][i];
136 long int Charge = (long int) mPer->charge();
137 long int TrkID = ntrk;
138 Trk::vkalPropagator::Propagate(TrkID, Charge, pari, covi,
139 vrtini, vrtend, &state.m_apar[ntrk][0],
140 &state.m_awgt[ntrk][0],
141 &state.m_vkalFitControl);
142 }
143
144 ntrk++;
145 if(ntrk>=NTrMaxVFit) return StatusCode::FAILURE;
146 }
147
148 //-------------- Finally setting new reference frame common for ALL tracks
149 state.m_refFrameX = tmp_refFrameX;
150 state.m_refFrameY = tmp_refFrameY;
151 state.m_refFrameZ = tmp_refFrameZ;
153 state.m_refFrameY,
154 state.m_refFrameZ);
155
156 return StatusCode::SUCCESS;
157 }
158
159 std::unique_ptr<Perigee>
160 TrkVKalVrtFitter::CreatePerigee(const std::vector<double>& VKPerigee,
161 const std::vector<double>& VKCov,
162 IVKalState& istate) const
163 {
164 assert(dynamic_cast<const State*> (&istate)!=nullptr);
165 State& state = static_cast<State&> (istate);
166 return CreatePerigee(0., 0., 0., VKPerigee, VKCov, state);
167 }
168
169 // Function creates a Trk::Perigee on the heap
170 // Don't forget to remove it after use
171 // vX,vY,vZ are in LOCAL SYSTEM with respect to refGVertex
172 std::unique_ptr<Perigee>
173 TrkVKalVrtFitter::CreatePerigee(double vX, double vY, double vZ,
174 const std::vector<double>& VKPerigee,
175 const std::vector<double>& VKCov,
176 State& state) const
177 {
178
179 // ------ Magnetic field access
180 double fx = 0., fy = 0., fz = 0.;
181 state.m_fitField.getMagFld(vX,vY,vZ,fx,fy,fz);
182 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, VKPerigee[3], VKPerigee[2]);
183 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG=0.01; //safety
184
185 double TrkP3 = 0., TrkP4 = 0., TrkP5 = 0.;
186 VKalToTrkTrack(effectiveBMAG, VKPerigee[2], VKPerigee[3], VKPerigee[4],
187 TrkP3, TrkP4, TrkP5);
188 double TrkP1 = -VKPerigee[0];
189 double TrkP2 = VKPerigee[1];
190 TrkP5 = -TrkP5;
191
192 AmgSymMatrix(5) CovMtx;
193 double Deriv[5][5],CovMtxOld[5][5];
194 for(int i=0; i<5; i++){
195 for(int j=0; j<5; j++){
196 Deriv[i][j]=0.;
197 CovMtxOld[i][j]=0.;
198 }
199 }
200 Deriv[0][0] = -1.;
201 Deriv[1][1] = 1.;
202 Deriv[2][3] = 1.;
203 Deriv[3][2] = 1.;
204 Deriv[4][2] = (std::cos(VKPerigee[2])/(m_CNVMAG*effectiveBMAG)) * VKPerigee[4];
205 Deriv[4][4] = -(std::sin(VKPerigee[2])/(m_CNVMAG*effectiveBMAG));
206
207 CovMtxOld[0][0] = VKCov[0];
208 CovMtxOld[0][1] = CovMtxOld[1][0] = VKCov[1];
209 CovMtxOld[1][1] = VKCov[2];
210 CovMtxOld[0][2] = CovMtxOld[2][0] = VKCov[3];
211 CovMtxOld[1][2] = CovMtxOld[2][1] = VKCov[4];
212 CovMtxOld[2][2] = VKCov[5];
213 CovMtxOld[0][3] = CovMtxOld[3][0] = VKCov[6];
214 CovMtxOld[1][3] = CovMtxOld[3][1] = VKCov[7];
215 CovMtxOld[2][3] = CovMtxOld[3][2] = VKCov[8];
216 CovMtxOld[3][3] = VKCov[9];
217 CovMtxOld[0][4] = CovMtxOld[4][0] = VKCov[10];
218 CovMtxOld[1][4] = CovMtxOld[4][1] = VKCov[11];
219 CovMtxOld[2][4] = CovMtxOld[4][2] = VKCov[12];
220 CovMtxOld[3][4] = CovMtxOld[4][3] = VKCov[13];
221 CovMtxOld[4][4] = VKCov[14];
222
223 for(int i=0; i<5; i++){
224 for(int j=i; j<5; j++){
225 double tmp=0.;
226 for(int ik=4; ik>=0; ik--){
227 if(Deriv[i][ik]==0.)continue;
228 for(int jk=4; jk>=0; jk--){
229 if(Deriv[j][jk]==0.)continue;
230 tmp += Deriv[i][ik]*CovMtxOld[ik][jk]*Deriv[j][jk];
231 }
232 }
233 CovMtx(i,j) = CovMtx(j,i)=tmp;
234 }
235 }
236
237 auto surface = PerigeeSurface(Amg::Vector3D(state.m_refFrameX+vX,
238 state.m_refFrameY+vY,
239 state.m_refFrameZ+vZ));
240
241 return std::make_unique<Perigee>(TrkP1, TrkP2, TrkP3, TrkP4, TrkP5,
242 surface,
243 std::move(CovMtx));
244 }
245
246} // end of namespace
247
248
249
#define AmgSymMatrix(dim)
#define AmgVector(rows)
Class describing the Line to which the Perigee refers to.
std::vector< double > m_MassInputParticles
double m_apar[NTrMaxVFit][5]
double m_awgt[NTrMaxVFit][15]
std::vector< TrkMatControl > m_trkControl
virtual std::unique_ptr< Trk::Perigee > CreatePerigee(const std::vector< double > &VKPerigee, const std::vector< double > &VKCov, IVKalState &istate) const override final
bool convertAmg5SymMtx(const AmgSymMatrix(5) *, double[15]) const
StatusCode CvtPerigee(const std::vector< const Perigee * > &list, int &ntrk, State &state) const
void VKalTransform(double MAG, double A0V, double ZV, double PhiV, double ThetaV, double PInv, const double[15], long int &Charge, double[5], double[15]) const
Gaudi::Property< double > m_IDsizeZ
Gaudi::Property< double > m_IDsizeR
void VKalToTrkTrack(double curBMAG, double vp1, double vp2, double vp3, double &tp1, double &tp2, double &tp3) const
virtual void getMagFld(const double, const double, const double, double &, double &, double &) override
void setAtlasMagRefFrame(double, double, double)
double getEffField(double bx, double by, double bz, double phi, double theta)
Definition VKalVrtBMag.h:41
static void Propagate(long int TrkID, long int Charge, double *ParOld, double *CovOld, double *RefStart, double *RefEnd, double *ParNew, double *CovNew, VKalVrtControlBase *FitControl=0)
Eigen::Matrix< double, 3, 1 > Vector3D
::StatusCode StatusCode
StatusCode definition for legacy code.
constexpr double chargedPionMassInMeV
the mass of the charged pion (in MeV)
Ensure that the ATLAS eigen extensions are properly loaded.