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 Amg::Vector3D tmp_refFrame = Amg::Vector3D::Zero();
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_refFrame += perGlobalPos;
56
57 TrkMatControl tmpMat;
58 tmpMat.trkRefGlobPos = perGlobalPos;
59 // Perigee point strategy
60 tmpMat.extrapolationType = 2;
61 tmpMat.TrkPnt = mPer;
63 if(counter < static_cast<int>(state.m_MassInputParticles.size())){
64 tmpMat.prtMass = state.m_MassInputParticles[counter];
65 }
66 tmpMat.trkSavedLocalVertex.setZero();
67 tmpMat.TrkID=counter;
68 state.m_trkControl.push_back(tmpMat);
69 counter++;
70 }
71
72 if(counter == 0) return StatusCode::FAILURE;
73
74 // Reference frame for the fit
75 tmp_refFrame /= counter;
76
77 //
78 // Common reference frame is ready. Start extraction of parameters for fit.
79 //
80 double fx = 0., fy = 0., fz = 0.;
81 for (const auto& mPer : InpPerigee) {
82 if(mPer == nullptr){ continue; }
83 AmgVector(5) VectPerig = mPer->parameters();
84 // Global position of perigee point
85 Amg::Vector3D perGlobalPos = mPer->position();
86 // Global position of reference point
87 Amg::Vector3D perGlobalVrt = mPer->associatedSurface().center();
88 // Restore ATLAS frame
89 state.m_refFrameX = state.m_refFrameY = state.m_refFrameZ = 0.;
90 state.m_fitField.setAtlasMagRefFrame(0., 0., 0.);
91 // Magnetic field at perigee point
92 state.m_fitField.getMagFld(perGlobalPos.x(),
93 perGlobalPos.y(),
94 perGlobalPos.z(),
95 fx, fy, fz);
96 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, VectPerig[2], VectPerig[3]);
97 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG = 0.01;
98
99 double CovVertTrk[15];
100 std::fill(CovVertTrk,CovVertTrk+15,0.);
101 // No good covariance matrix!
102 if(!convertAmg5SymMtx(mPer->covariance(), CovVertTrk)) return StatusCode::FAILURE;
103 VKalTransform(effectiveBMAG,
104 static_cast<double>(VectPerig(0)),
105 static_cast<double>(VectPerig(1)),
106 static_cast<double>(VectPerig(2)),
107 static_cast<double>(VectPerig(3)),
108 static_cast<double>(VectPerig(4)),
109 CovVertTrk,
110 state.m_ich[ntrk], &state.m_apar[ntrk][0],
111 &state.m_awgt[ntrk][0]);
112
113 // Check if propagation to common reference point is needed and make it
114 // initial track reference position
115 state.m_refFrameX=perGlobalVrt.x();
116 state.m_refFrameY=perGlobalVrt.y();
117 state.m_refFrameZ=perGlobalVrt.z();
119 state.m_refFrameY,
120 state.m_refFrameZ);
121 Amg::Vector3D dref = tmp_refFrame - perGlobalVrt;
122 if(dref != Amg::Vector3D::Zero()) {
123 double pari[5], covi[15];
124 double vrtini[3] = {0.,0.,0.};
125 for(int i=0; i<5; i++) pari[i] = state.m_apar[ntrk][i];
126 for(int i=0; i<15;i++) covi[i] = state.m_awgt[ntrk][i];
127 long int Charge = (long int) mPer->charge();
128 long int TrkID = ntrk;
129 Trk::vkalPropagator::Propagate(TrkID, Charge, pari, covi,
130 vrtini, dref.data(), &state.m_apar[ntrk][0],
131 &state.m_awgt[ntrk][0],
132 &state.m_vkalFitControl);
133 }
134
135 ntrk++;
136 if(ntrk>=NTrMaxVFit) return StatusCode::FAILURE;
137 }
138
139 //-------------- Finally setting new reference frame common for ALL tracks
140 state.m_refFrameX = tmp_refFrame.x();
141 state.m_refFrameY = tmp_refFrame.y();
142 state.m_refFrameZ = tmp_refFrame.z();
144 state.m_refFrameY,
145 state.m_refFrameZ);
146
147 return StatusCode::SUCCESS;
148 }
149
150 std::unique_ptr<Perigee>
151 TrkVKalVrtFitter::CreatePerigee(const std::span<const double, 5> VKPerigee,
152 const std::span<const double, 15> VKCov,
153 IVKalState& istate) const
154 {
155 assert(dynamic_cast<const State*> (&istate)!=nullptr);
156 State& state = static_cast<State&> (istate);
157 return CreatePerigee(0., 0., 0., VKPerigee, VKCov, state);
158 }
159
160 // Function creates a Trk::Perigee on the heap
161 // Don't forget to remove it after use
162 // vX,vY,vZ are in LOCAL SYSTEM with respect to refGVertex
163 std::unique_ptr<Perigee>
164 TrkVKalVrtFitter::CreatePerigee(double vX, double vY, double vZ,
165 const std::span<const double, 5> VKPerigee,
166 const std::span<const double, 15> VKCov,
167 State& state) const
168 {
169 // ------ Magnetic field access
170 double fx = 0., fy = 0., fz = 0.;
171 state.m_fitField.getMagFld(vX,vY,vZ,fx,fy,fz);
172 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, VKPerigee[3], VKPerigee[2]);
173 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG=0.01; //safety
174
175 double TrkP3 = 0., TrkP4 = 0., TrkP5 = 0.;
176 VKalToTrkTrack(effectiveBMAG, VKPerigee[2], VKPerigee[3], VKPerigee[4],
177 TrkP3, TrkP4, TrkP5);
178 double TrkP1 = -VKPerigee[0];
179 double TrkP2 = VKPerigee[1];
180 TrkP5 = -TrkP5;
181
182 AmgSymMatrix(5) CovMtx;
183 double Deriv[5][5],CovMtxOld[5][5];
184 for(int i=0; i<5; i++){
185 for(int j=0; j<5; j++){
186 Deriv[i][j]=0.;
187 CovMtxOld[i][j]=0.;
188 }
189 }
190 Deriv[0][0] = -1.;
191 Deriv[1][1] = 1.;
192 Deriv[2][3] = 1.;
193 Deriv[3][2] = 1.;
194 Deriv[4][2] = (std::cos(VKPerigee[2])/(m_CNVMAG*effectiveBMAG)) * VKPerigee[4];
195 Deriv[4][4] = -(std::sin(VKPerigee[2])/(m_CNVMAG*effectiveBMAG));
196
197 CovMtxOld[0][0] = VKCov[0];
198 CovMtxOld[0][1] = CovMtxOld[1][0] = VKCov[1];
199 CovMtxOld[1][1] = VKCov[2];
200 CovMtxOld[0][2] = CovMtxOld[2][0] = VKCov[3];
201 CovMtxOld[1][2] = CovMtxOld[2][1] = VKCov[4];
202 CovMtxOld[2][2] = VKCov[5];
203 CovMtxOld[0][3] = CovMtxOld[3][0] = VKCov[6];
204 CovMtxOld[1][3] = CovMtxOld[3][1] = VKCov[7];
205 CovMtxOld[2][3] = CovMtxOld[3][2] = VKCov[8];
206 CovMtxOld[3][3] = VKCov[9];
207 CovMtxOld[0][4] = CovMtxOld[4][0] = VKCov[10];
208 CovMtxOld[1][4] = CovMtxOld[4][1] = VKCov[11];
209 CovMtxOld[2][4] = CovMtxOld[4][2] = VKCov[12];
210 CovMtxOld[3][4] = CovMtxOld[4][3] = VKCov[13];
211 CovMtxOld[4][4] = VKCov[14];
212
213 for(int i=0; i<5; i++){
214 for(int j=i; j<5; j++){
215 double tmp=0.;
216 for(int ik=4; ik>=0; ik--){
217 if(Deriv[i][ik]==0.)continue;
218 for(int jk=4; jk>=0; jk--){
219 if(Deriv[j][jk]==0.)continue;
220 tmp += Deriv[i][ik]*CovMtxOld[ik][jk]*Deriv[j][jk];
221 }
222 }
223 CovMtx(i,j) = CovMtx(j,i)=tmp;
224 }
225 }
226
227 auto surface = PerigeeSurface(Amg::Vector3D(state.m_refFrameX+vX,
228 state.m_refFrameY+vY,
229 state.m_refFrameZ+vZ));
230
231 return std::make_unique<Perigee>(TrkP1, TrkP2, TrkP3, TrkP4, TrkP5,
232 surface,
233 std::move(CovMtx));
234
235 }
236
237}
#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
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
virtual std::unique_ptr< Trk::Perigee > CreatePerigee(const std::span< const double, 5 > VKPerigee, const std::span< const double, 15 > VKCov, IVKalState &istate) const override final
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, const double *ParOld, const double *CovOld, const double *RefOld, double *RefNew, 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.