ATLAS Offline Software
Loading...
Searching...
No Matches
FullLinearizedTrackFactory.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*********************************************************************
6 FullPerigeeLinearizedTrackFactory.cxx - Description in header file
7*********************************************************************/
8
10
13
16
20#include <TMath.h>
21
22namespace Trk
23{
24
25 FullLinearizedTrackFactory::FullLinearizedTrackFactory(const std::string& t, const std::string& n, const IInterface* p) :
26 AthAlgTool(t,n,p),m_extrapolator("Trk::Extrapolator", this)
27 {
28 declareProperty("Extrapolator", m_extrapolator);
29 declareInterface<IVertexLinearizedTrackFactory>(this);
30 }
31
33
35 {
36
37 ATH_CHECK( m_extrapolator.retrieve() );
39
40 return StatusCode::SUCCESS;
41 }
42
44 {
45 if (theTrack.initialPerigee())
46 theTrack.setLinTrack(linearizedTrack(theTrack.initialPerigee(),linPoint));
47 else
48 theTrack.setLinTrack(linearizedTrack(theTrack.initialNeutralPerigee(),linPoint));
49 }
50
52 const Amg::Vector3D& linPoint) const {
53 if (!trackPars) return nullptr;
54 //perigee surface
55 Amg::Vector3D lp =linPoint;
56 const PerigeeSurface perigeeSurface(lp);
57
58//Remove matherial changes. Trying to understand where the perigee currently is and
59//whether we need to add or remove material during extrapolation.
60//Obvious case is the extrapolation form the perigee point: add in the direction
61//opposite to momentum; remove along the momentum.
62
63 const Amg::Vector3D gMomentum = trackPars->momentum();
64 const Amg::Vector3D gDirection = trackPars->position() - lp;
65 const double extrapolationDirection = gMomentum.dot( gDirection);
66 MaterialUpdateMode mode = (extrapolationDirection < 0) ?
67 Trk::addNoise : // parameters upstream of vertex
68 Trk::removeNoise ; // parameters downstream of vertex -> go back
69
70 const TrackParameters* parsAtVertex =
71 m_extrapolator->extrapolate(
72 Gaudi::Hive::currentContext(),
73 *trackPars,
74 perigeeSurface, Trk::anyDirection, true, Trk::pion, mode).release();
75
76 if (dynamic_cast<const Trk::Perigee*>(parsAtVertex)==nullptr ||
77 parsAtVertex->covariance()==nullptr ) {
78 ATH_MSG_INFO ("Could not extrapolate Perigee to vertex pos: x " << lp.x() << " y " <<
79 lp.y() << " z " << lp.z() << ". Normal if outside ID acceptance ");
80
81 if (dynamic_cast<const Trk::Perigee*>(trackPars) && trackPars->covariance()) {
82 if (parsAtVertex) delete parsAtVertex; // in case extrapolation made other parameters
83 parsAtVertex = trackPars->clone();
84 } else {
85 delete parsAtVertex; return nullptr;
86 }
87 }
88
89 if (parsAtVertex && parsAtVertex->covariance() && parsAtVertex->covariance()->determinant()<=0)
90 {
91 ATH_MSG_DEBUG ("The track covariance matrix det after extrapolation is: " << parsAtVertex->covariance()->determinant() <<
92 " --> Using non extrapolated track parameters");
93 delete parsAtVertex;
94 parsAtVertex=trackPars->clone();
95 }
96
97 // positions
98 AmgVector(5) param = parsAtVertex->parameters();
99 Amg::Vector3D expPoint = parsAtVertex->position();
100
101 //phi_v and functions
102 double phi_v = param(Trk::phi);
103 double sin_phi_v = sin(phi_v);
104 double cos_phi_v = cos(phi_v);
105
106 //theta and functions
107 double th = param(Trk::theta);
108 double sin_th = sin(th);
109 double tan_th = tan(th);
110
111 //q over p
112 double q_ov_p = param(Trk::qOverP);
113 int sgn_h = (q_ov_p<0.)? -1:1;
114 Amg::Vector3D expMomentum(phi_v, th, q_ov_p);
115
116 // magnetic field
117
118 SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCacheCondObjInputKey, Gaudi::Hive::currentContext()};
119 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
120
121 MagField::AtlasFieldCache fieldCache;
122 fieldCondObj->getInitializedCache (fieldCache);
123
124 double mField[3];
125 fieldCache.getField(expPoint.data(),mField);
126
127 double B_z=mField[2]*299.792;//Magnetic field is returned in kT.
128 //The scaling is a factor of c needed for computing rho.
129
130 // signed radius and rotation variables
131 // (if momentum or mag field is absent, the curvature radius is infinite)
132
133 double rho;
134 if(mField[2] == 0. || fabs(q_ov_p) <= 1e-15) rho = 1e+15 ;
135 else rho = sin_th / (q_ov_p * B_z);
136
137 // std:: cout<<"calculated rho "<< rho<<std::endl;
138 double X = expPoint(0) - lp.x() + rho*sin_phi_v;
139 double Y = expPoint(1) - lp.y() - rho*cos_phi_v;
140 double SS = (X * X + Y * Y);
141 double S = sqrt(SS);
142
143 //calculated parameters at expansion point
144 //q_over_p and theta stay constant along trajectory
145 AmgVector(5) parAtExpansionPoint; parAtExpansionPoint.setZero();
146 parAtExpansionPoint[0] = rho - sgn_h * S;
147
148//calculation of phi at expansion point
149 double phiAtEp;
150 int sgnY = (Y<0)? -1:1;
151 int sgnX = (X<0)? -1:1;
152 double pi = TMath::Pi();//acos(-1.);
153
154 if(fabs(X)>fabs(Y)) phiAtEp = sgn_h*sgnX* acos(-sgn_h * Y / S);
155 else
156 {
157 phiAtEp = asin(sgn_h * X / S);
158 if( (sgn_h * sgnY)> 0) phiAtEp = sgn_h * sgnX * pi - phiAtEp;
159 }
160
161 parAtExpansionPoint[2] = phiAtEp;
162 parAtExpansionPoint[1] = expPoint(2) - lp.z() + rho*(phi_v - parAtExpansionPoint[2])/tan_th;
163 parAtExpansionPoint[3] = th;
164 parAtExpansionPoint[4] = q_ov_p;
165// std::cout<<"Calculated parameters at expansion point: "<<parAtExpansionPoint<<std::endl;
166// std::cout<<"Difference: "<<predStateParameters-parAtExpansionPoint<<std::endl;
167
168 //jacobian elements
169 AmgMatrix(5,3) positionJacobian; positionJacobian.setZero();
170
171 //first row
172 positionJacobian(0,0) = -sgn_h * X / S;
173 positionJacobian(0,1) = -sgn_h * Y / S;
174
175 //second row
176 positionJacobian(1,0) = rho * Y / (tan_th * SS);
177 positionJacobian(1,1) = -rho * X / (tan_th * SS);
178 positionJacobian(1,2) = 1.;
179
180 //third row
181 positionJacobian(2,0) = -Y / SS;
182 positionJacobian(2,1) = X / SS;
183// std::cout<<"My position Jacobian: "<<positionJacobian<<std::endl;
184
185 //momentum jacobian and related stuff
186 AmgMatrix(5,3) momentumJacobian; momentumJacobian.setZero();
187 double R = X*cos_phi_v + Y * sin_phi_v;
188 double Q = X*sin_phi_v - Y * cos_phi_v;
189 double d_phi = parAtExpansionPoint[2] - phi_v;
190
191 //first row
192 momentumJacobian(0,0) = -sgn_h * rho * R / S ;
193
194 double qOvS_red = 1 - sgn_h * Q / S;
195 momentumJacobian(0,1) = qOvS_red * rho / tan_th;
196 momentumJacobian(0,2) = - qOvS_red * rho / q_ov_p;
197
198 //second row
199 momentumJacobian(1,0) = (1 - rho*Q/SS )*rho/tan_th;
200 momentumJacobian(1,1) = (d_phi + rho * R / (SS * tan_th * tan_th) ) * rho;
201 momentumJacobian(1,2) = (d_phi - rho * R /SS ) * rho / (q_ov_p*tan_th);
202
203 //third row
204 momentumJacobian(2,0) = rho * Q / SS;
205 momentumJacobian(2,1) = -rho * R / (SS*tan_th);
206 momentumJacobian(2,2) = rho * R / (q_ov_p*SS);
207
208 //last two rows:
209 momentumJacobian(3,1) = 1.;
210 momentumJacobian(4,2) = 1.;
211// std::cout<<"My momentum Jacobian "<<momentumJacobian<<std::endl;
212
213 AmgVector(5) constantTerm = parAtExpansionPoint - positionJacobian*expPoint - momentumJacobian*expMomentum;
214// std::cout<<"My constant term: "<<constantTerm<<std::endl;
215
216 LinearizedTrack* toreturn=new LinearizedTrack(parsAtVertex->parameters(),
217 *parsAtVertex->covariance(),
218 lp,
219 positionJacobian,
220 momentumJacobian,
221 expPoint,
222 expMomentum,
223 constantTerm);
224
225 //delete Perigee object created by the Extrapolator
226 delete parsAtVertex;
227 //return new linearized track
228 return toreturn;
229 }
230
232 const Amg::Vector3D& linPoint) const
233 {
234 if (!neutralPars) return nullptr;
235 Amg::Vector3D lp =linPoint;
236 PerigeeSurface perigeeSurface(lp);
237
238 //no material effects for neutral particles
239 /*
240 const Amg::Vector3D gMomentum = neutralPars->momentum();
241 const Amg::Vector3D gDirection = neutralPars->position() - lp;
242 const double extrapolationDirection = gMomentum.dot( gDirection);
243 MaterialUpdateMode mode = (extrapolationDirection < 0) ?
244 Trk::addNoise : // parameters upstream of vertex
245 Trk::removeNoise ; // parameters downstream of vertex -> go back
246 */
247 const NeutralParameters* parsAtVertex =
248 m_extrapolator->extrapolate(*neutralPars,
249 perigeeSurface, Trk::anyDirection, true).release();
250
251 if (dynamic_cast<const Trk::NeutralPerigee*>(parsAtVertex)==nullptr ||
252 parsAtVertex->covariance()==nullptr ) {
253 ATH_MSG_INFO ("Could not extrapolate Perigee to vertex pos: x " << lp.x() << " y " <<
254 lp.y() << " z " << lp.z() << ". Should not happen. ");
255
256 if (dynamic_cast<const Trk::NeutralPerigee*>(neutralPars) && neutralPars->covariance()) {
257 if (parsAtVertex) delete parsAtVertex; // in case extrapolation made other parameters
258 parsAtVertex = neutralPars->clone();
259 } else {
260 delete parsAtVertex; return nullptr;
261 }
262 }
263
264 // positions, phi, theta
265 AmgVector(5) param = parsAtVertex->parameters();
266 Amg::Vector3D expPoint = parsAtVertex->position();
267
268 double phi_v = param(Trk::phi);
269 double sin_phi_v = sin(phi_v);
270 double cos_phi_v = cos(phi_v);
271 double th = param(Trk::theta);
272 double tan_th = tan(th);
273 double q_ov_p = param(Trk::qOverP);
274
275 //momentum
276 Amg::Vector3D expMomentum(phi_v, th, q_ov_p);
277 double X = expPoint(0) - lp.x();
278 double Y = expPoint(1) - lp.y();
279
280 AmgVector(5) parAtExpansionPoint; parAtExpansionPoint.setZero();
281 parAtExpansionPoint[0] = Y*cos_phi_v-X*sin_phi_v;
282
283 //very easy for a neutral track!
284 //phi doesn't change...
285
286 double phiAtEp=phi_v;
287 parAtExpansionPoint[2] = phiAtEp;
288 parAtExpansionPoint[1] = expPoint[2] - lp.z() - 1./tan_th*(X*cos_phi_v+Y*sin_phi_v);
289 parAtExpansionPoint[3] = th;
290 parAtExpansionPoint[4] = q_ov_p;
291
292 //jacobian elements
293 AmgMatrix(5,3) positionJacobian; positionJacobian.setZero();
294
295 //first row
296 positionJacobian(0,0) = -sin_phi_v;
297 positionJacobian(0,1) = +cos_phi_v;
298
299 //second raw
300 positionJacobian(1,0) = -cos_phi_v/tan_th;
301 positionJacobian(1,1) = -sin_phi_v/tan_th;
302 positionJacobian(1,2) = 1.;
303
304// std::cout<<"My position Jacobian: "<<positionJacobian<<std::endl;
305
306 //momentum jacobian and related stuff
307 AmgMatrix(5,3) momentumJacobian; momentumJacobian.setZero();
308 momentumJacobian(2,0) = 1.;
309 momentumJacobian(3,1) = 1.;
310 momentumJacobian(4,2) = 1.;
311// std::cout<<"My momentum Jacobian "<<momentumJacobian<<std::endl;
312
313 AmgVector(5) constantTerm = parAtExpansionPoint - positionJacobian*expPoint - momentumJacobian*expMomentum;
314// std::cout<<"My constant term: "<<constantTerm<<std::endl;
315
316 LinearizedTrack* toreturn=new LinearizedTrack(parsAtVertex->parameters(),
317 *parsAtVertex->covariance(),
318 lp,
319 positionJacobian,
320 momentumJacobian,
321 expPoint,
322 expMomentum,
323 constantTerm);
324
325 //delete MeasuredPerigee object created by the Extrapolator
326 delete parsAtVertex;
327 //return new linearized track
328 return toreturn;
329 }
330
331
332}//end of namespace definitions
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define AmgVector(rows)
#define AmgMatrix(rows, cols)
#define pi
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
virtual LinearizedTrack * linearizedTrack(const TrackParameters *param, const Amg::Vector3D &linPoint) const override
Linearization method: Takes a MeasuredPerigee and a LinearizationPoint.
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
~FullLinearizedTrackFactory()
Destructor.
virtual void linearize(VxTrackAtVertex &theTrack, const Amg::Vector3D &linPoint) const override
Interface for VxTrackAtVertex: Takes a MeasuredPerigee from VxTrackAtVertex and a Lineariztion point.
ToolHandle< Trk::IExtrapolator > m_extrapolator
virtual StatusCode initialize() override
Standard AlgToolMethods.
FullLinearizedTrackFactory(const std::string &t, const std::string &n, const IInterface *p)
Default constructor due to Athena interface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy
const Amg::Vector3D & position() const
Access method for the position.
Class describing the Line to which the Perigee refers to.
The VxTrackAtVertex is a common class for all present TrkVertexFitters The VxTrackAtVertex is designe...
const NeutralParameters * initialNeutralPerigee(void) const
Access to the initial perigee parameters of trajectory.
const TrackParameters * initialPerigee(void) const
Access to the initial perigee parameters of trajectory.
void setLinTrack(LinearizedTrack *myLinTrack)
Setting up the linearized track.
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
@ anyDirection
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
ParametersBase< NeutralParametersDim, Neutral > NeutralParameters
ParametersT< NeutralParametersDim, Neutral, PerigeeSurface > NeutralPerigee
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
MaterialUpdateMode
This is a steering enum to force the material update it can be: (1) addNoise (-1) removeNoise Second ...
ParametersBase< TrackParametersDim, Charged > TrackParameters