ATLAS Offline Software
Loading...
Searching...
No Matches
Trk::ImpactPoint3dEstimator Class Reference

This object calculates the point of minimum distance to the vertex in 3d. More...

#include <ImpactPoint3dEstimator.h>

Inheritance diagram for Trk::ImpactPoint3dEstimator:
Collaboration diagram for Trk::ImpactPoint3dEstimator:

Public Member Functions

virtual StatusCode initialize () override
virtual StatusCode finalize () override
 ImpactPoint3dEstimator (const std::string &t, const std::string &n, const IInterface *p)
 Default constructor due to Athena interface.
virtual ~ImpactPoint3dEstimator ()
virtual std::unique_ptr< PlaneSurfaceEstimate3dIP (const Trk::TrackParameters *trackPerigee, const Amg::Vector3D *theVertex, double &distance) const override
virtual std::unique_ptr< PlaneSurfaceEstimate3dIP (const Trk::NeutralParameters *neutralPerigee, const Amg::Vector3D *theVertex, double &distance) const override
virtual bool addIP3dAtaPlane (VxTrackAtVertex &, const Amg::Vector3D &vertex) const override
 Actual estimate method, changing the state of Trk::VxTrackAtVertex.
virtual const Trk::AtaPlaneIP3dAtaPlane (VxTrackAtVertex &vtxTrack, const Amg::Vector3D &vertex) const override
 This method creates the ImpactPoint3dAtaPlane as the parameters of the track at the point of closest approach in 3d to the given vertex.
virtual const Trk::NeutralAtaPlaneIP3dNeutralAtaPlane (const NeutralParameters *initNeutPerigee, const Amg::Vector3D &vertex) const override

Private Member Functions

template<typename T>
std::unique_ptr< PlaneSurfaceEstimate3dIPNoCurvature (const T *, const Amg::Vector3D *theVertex, double &distance) const

Private Attributes

ToolHandle< Trk::IExtrapolatorm_extrapolator
SG::ReadCondHandleKey< AtlasFieldCacheCondObjm_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}
int m_maxiterations
double m_precision

Detailed Description

This object calculates the point of minimum distance to the vertex in 3d.

Consider that this point is different from the usually used point of closest approach on the transverse plane.

This algorithm makes use of a simple iterative Newton process

Author
N. Giacinto Piacquadio (for the Freiburg Group)

Changes:

David Shope david.nosp@m..ric.nosp@m.hard..nosp@m.shop.nosp@m.e@cer.nosp@m.n.ch (2016-03-18)

EDM Migration to xAOD - move Trk::Vertex to Amg::Vector3D

Definition at line 39 of file ImpactPoint3dEstimator.h.

Constructor & Destructor Documentation

◆ ImpactPoint3dEstimator()

Trk::ImpactPoint3dEstimator::ImpactPoint3dEstimator ( const std::string & t,
const std::string & n,
const IInterface * p )

Default constructor due to Athena interface.

Definition at line 26 of file ImpactPoint3dEstimator.cxx.

26 :
27 base_class(t,n,p),
30 m_precision(1e-10)//DeltaPhi
31 {
32 declareProperty("Extrapolator",m_extrapolator);
33 declareProperty("MaxIterations",m_maxiterations);
34 declareProperty("Precision",m_precision);
35 }
ToolHandle< Trk::IExtrapolator > m_extrapolator

◆ ~ImpactPoint3dEstimator()

Trk::ImpactPoint3dEstimator::~ImpactPoint3dEstimator ( )
virtualdefault

Member Function Documentation

◆ addIP3dAtaPlane()

bool Trk::ImpactPoint3dEstimator::addIP3dAtaPlane ( VxTrackAtVertex & vtxTrack,
const Amg::Vector3D & vertex ) const
overridevirtual

Actual estimate method, changing the state of Trk::VxTrackAtVertex.

Definition at line 285 of file ImpactPoint3dEstimator.cxx.

286 {
287 if (vtxTrack.initialPerigee()) {
288 const AtaPlane* myPlane=IP3dAtaPlane(vtxTrack,vertex);
289 if (myPlane)
290 {
291 vtxTrack.setImpactPoint3dAtaPlane(myPlane);
292 return true;
293 }
294 } else { //for neutrals
295 const NeutralAtaPlane* myPlane=IP3dNeutralAtaPlane(vtxTrack.initialNeutralPerigee(),vertex);
296 if (myPlane) {
297 ATH_MSG_VERBOSE ("Adding plane: " << myPlane->associatedSurface() );
298 vtxTrack.setImpactPoint3dNeutralAtaPlane(myPlane);
299 return true;
300 }
301 }
302 return false;
303 }
#define ATH_MSG_VERBOSE(x)
virtual const Trk::AtaPlane * IP3dAtaPlane(VxTrackAtVertex &vtxTrack, const Amg::Vector3D &vertex) const override
This method creates the ImpactPoint3dAtaPlane as the parameters of the track at the point of closest ...
virtual const Trk::NeutralAtaPlane * IP3dNeutralAtaPlane(const NeutralParameters *initNeutPerigee, const Amg::Vector3D &vertex) const override
ParametersT< NeutralParametersDim, Neutral, PlaneSurface > NeutralAtaPlane
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane

◆ Estimate3dIP() [1/2]

std::unique_ptr< PlaneSurface > Trk::ImpactPoint3dEstimator::Estimate3dIP ( const Trk::NeutralParameters * neutralPerigee,
const Amg::Vector3D * theVertex,
double & distance ) const
overridevirtual

Definition at line 106 of file ImpactPoint3dEstimator.cxx.

109 {
110 ATH_MSG_DEBUG("Neutral particle -- propagate like a straight line");
111 return Estimate3dIPNoCurvature(neutralPerigee, theVertex, distance);
112 }
#define ATH_MSG_DEBUG(x)
std::unique_ptr< PlaneSurface > Estimate3dIPNoCurvature(const T *, const Amg::Vector3D *theVertex, double &distance) const

◆ Estimate3dIP() [2/2]

std::unique_ptr< PlaneSurface > Trk::ImpactPoint3dEstimator::Estimate3dIP ( const Trk::TrackParameters * trackPerigee,
const Amg::Vector3D * theVertex,
double & distance ) const
overridevirtual

Definition at line 115 of file ImpactPoint3dEstimator.cxx.

118 {
119 SG::ReadCondHandle<AtlasFieldCacheCondObj> readHandle{m_fieldCacheCondObjInputKey, Gaudi::Hive::currentContext()};
120 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
121
122 MagField::AtlasFieldCache fieldCache;
123 fieldCondObj->getInitializedCache (fieldCache);
124
125 double magnFieldVect[3];
126 fieldCache.getField(trackPerigee->associatedSurface().center().data(),magnFieldVect);
127 if(magnFieldVect[2] == 0 ){
128 ATH_MSG_DEBUG("Magnetic field in the Z direction is 0 -- propagate like a straight line");
129 return Estimate3dIPNoCurvature(trackPerigee, theVertex, distance);
130 }
131
132 const Trk::Perigee* thePerigee=dynamic_cast<const Trk::Perigee*>(trackPerigee);
133 if (thePerigee==nullptr)
134 {
136 " ImpactPoint3dEstimator didn't get a Perigee* as ParametersBase*: "
137 "cast not possible. Need to EXTRAPOLATE...");
138 Trk::PerigeeSurface perigeeSurface(*theVertex);
139 std::unique_ptr<const Trk::TrackParameters> tmp =
140 m_extrapolator->extrapolateDirectly(
141 Gaudi::Hive::currentContext(), *trackPerigee, perigeeSurface);
142 if (tmp && tmp->associatedSurface().type() == Trk::SurfaceType::Perigee) {
143 thePerigee = static_cast<const Trk::Perigee*>(tmp.release());
144 }
145 if (thePerigee == nullptr){
146 return nullptr;
147 }
148 }
149
150 ATH_MSG_VERBOSE( " Now running ImpactPoint3dEstimator::Estimate3dIP" );
151 double phi0=thePerigee->parameters()[Trk::phi0];
152 double dCosPhi0=-std::sin(phi0);
153 double dSinPhi0=std::cos(phi0);
154 double theta=thePerigee->parameters()[Trk::theta];
155 double cotTheta=1./std::tan(thePerigee->parameters()[Trk::theta]);
156 double d0=thePerigee->parameters()[Trk::d0];
157
158 //I need the radius (magnetic field...)
159 double Bz=magnFieldVect[2]*299.792;
160 double Rt=std::sin(theta)/(Bz*thePerigee->parameters()[Trk::qOverP]);
161
162 double x0=thePerigee->associatedSurface().center().x()+(d0-Rt)*dCosPhi0;
163 double y0=thePerigee->associatedSurface().center().y()+(d0-Rt)*dSinPhi0;
164 double z0=thePerigee->associatedSurface().center().z()+thePerigee->parameters()[Trk::z0]+Rt*phi0*cotTheta;
165
166 if (thePerigee!=trackPerigee) {
167 delete thePerigee;
168 thePerigee=nullptr;
169 }
170
171 double xc=theVertex->x();
172 double yc=theVertex->y();
173 double zc=theVertex->z();
174
175 double phiActual=phi0;
176 double dCosPhiActual=-std::sin(phiActual);
177 double dSinPhiActual=std::cos(phiActual);
178
179 double secderivative=0.;
180 double derivative=0.;
181
182 int ncycle=0;
183 bool isok=false;
184
185 double deltaphi=0.;
186
187#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
188 std::cout << std::setprecision(25) << "actual distance before cycle is: " << std::hypot(x0-xc+Rt*dCosPhiActual,
189 y0-yc+Rt*dSinPhiActual,
190 z0-zc-Rt*cotTheta*phiActual) << std::endl;
191#endif
192
193 do {
194
195#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
196 ATH_MSG_VERBOSE( "Cycle number: " << ncycle << " old phi: " << phiActual );
197#endif
198
199
200 derivative=(x0-xc)*(-Rt*dSinPhiActual)+(y0-yc)*Rt*dCosPhiActual+(z0-zc-Rt*phiActual*cotTheta)*(-Rt*cotTheta);
201 secderivative=Rt*(-(x0-xc)*dCosPhiActual-(y0-yc)*dSinPhiActual+Rt*cotTheta*cotTheta);
202#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
203 ATH_MSG_VERBOSE( "derivative is: " << derivative << " sec derivative is: " << secderivative );
204#endif
205
206 deltaphi=-derivative/secderivative;
207
208#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
209 std::cout << std::setprecision(25) << "deltaphi: " << deltaphi << std::endl;
210#endif
211
212 phiActual+=deltaphi;
213 dCosPhiActual=-std::sin(phiActual);
214 dSinPhiActual=std::cos(phiActual);
215
216#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
217 ATH_MSG_VERBOSE( "derivative is: " << derivative << " sec derivative is: " << secderivative );
218 std::cout << std::setprecision(25) << std::hypot(x0-xc+Rt*dCosPhiActual, y0-yc+Rt*dSinPhiActual,
219 z0-zc-Rt*cotTheta*phiActual) << std::endl;
220 ATH_MSG_VERBOSE( "actual distance is: " << std::hypot(x0-xc+Rt*dCosPhiActual,
221 y0-yc+Rt*dSinPhiActual,
222 z0-zc-Rt*cotTheta*phiActual));
223#endif
224
225 if (secderivative<0) throw error::ImpactPoint3dEstimatorProblem("Second derivative is negative");
226
227 if (ncycle>m_maxiterations) throw error::ImpactPoint3dEstimatorProblem("Too many loops: could not find minimum distance to vertex");
228
229 ncycle+=1;
230 if (ncycle>m_maxiterations||std::abs(deltaphi)<m_precision) {
231#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
232 ATH_MSG_VERBOSE( "found minimum at: " << phiActual );
233#endif
234 isok=true;
235 }
236
237 } while (!isok);
238
239 //now you have to construct the plane with PlaneSurface
240 //first vector at 3d impact point
241 Amg::Vector3D MomentumDir(std::cos(phiActual)*std::sin(theta),std::sin(phiActual)*std::sin(theta),std::cos(theta));
242 Amg::Vector3D DeltaR(x0-xc+Rt*dCosPhiActual,y0-yc+Rt*dSinPhiActual,z0-zc-Rt*cotTheta*phiActual);
243 distance=DeltaR.mag();
244 if (distance==0.){
245 ATH_MSG_WARNING("DeltaR is zero in ImpactPoint3dEstimator::Estimate3dIP, returning nullptr");
246 return nullptr;
247 }
248 DeltaR=DeltaR.unit();
249
250
251 //correct DeltaR from small deviations from orthogonality to DeltaR
252
253 Amg::Vector3D DeltaRcorrected=DeltaR-(DeltaR.dot(MomentumDir))*MomentumDir;
254
255 if ((DeltaR-DeltaRcorrected).mag()>1e-4)
256 {
257 ATH_MSG_WARNING( " DeltaR and MomentumDir are not orthogonal " );
258 ATH_MSG_DEBUG( std::setprecision(10) << " DeltaR-DeltaRcorrected: " << (DeltaR-DeltaRcorrected).mag() );
259 }
260
261 Amg::Vector3D YDir=MomentumDir.cross(DeltaRcorrected);
262
263 //store the impact 3d point
264 Amg::Vector3D vertex(x0+Rt*dCosPhiActual,y0+Rt*dSinPhiActual,z0-Rt*cotTheta*phiActual);
265
266 ATH_MSG_VERBOSE( "final minimal distance is: " << std::hypot(x0-xc+Rt*dCosPhiActual,
267 y0-yc+Rt*dSinPhiActual,
268 z0-zc-Rt*cotTheta*phiActual));
269
270 ATH_MSG_DEBUG( "POCA in 3D is: " << vertex );
271
272
273 //store the plane...
274 ATH_MSG_VERBOSE( "plane to which to extrapolate X " << DeltaRcorrected << " Y " << YDir << " Z " << MomentumDir );
275
276 Amg::Transform3D thePlane(DeltaRcorrected, YDir, MomentumDir, *theVertex);
277
278#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
279 std::cout << "the translation is, directly from Transform3d: " << thePlane.getTranslation() << endmsg;
280#endif
281 return std::make_unique<PlaneSurface>(thePlane);
282 }//end of estimate 3dIP method
Scalar mag() const
mag method
#define endmsg
#define ATH_MSG_WARNING(x)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
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,...
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual const S & associatedSurface() const override final
Access to the Surface method.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Eigen::Affine3d Transform3D
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Eigen::Matrix< double, 3, 1 > Vector3D
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64

◆ Estimate3dIPNoCurvature()

template<typename T>
std::unique_ptr< PlaneSurface > Trk::ImpactPoint3dEstimator::Estimate3dIPNoCurvature ( const T * thePerigee,
const Amg::Vector3D * theVertex,
double & distance ) const
private

Definition at line 61 of file ImpactPoint3dEstimator.cxx.

64 {
65 const Amg::Vector3D momentumUnit = thePerigee->momentum().unit();
66 double pathLength = ( *theVertex - thePerigee->position() ).dot( momentumUnit )
67 / ( momentumUnit.dot( momentumUnit )) ;
68 //first vector at 3d impact point
69
70
71 Amg::Vector3D POCA = thePerigee->position() + pathLength * momentumUnit;// Position of closest approach
72 Amg::Vector3D DeltaR = *theVertex - POCA;
73 distance=DeltaR.mag();
74 DeltaR=DeltaR.unit();
75
76
77 //correct DeltaR from small deviations from orthogonality to DeltaR -- DeltaR.dot(momentumUnit) should equal 0 if the above is correct
78
79 Amg::Vector3D DeltaRcorrected=DeltaR-(DeltaR.dot(momentumUnit))*momentumUnit;
80
81 if ((DeltaR-DeltaRcorrected).mag()>1e-4)
82 {
83 ATH_MSG_WARNING( " DeltaR and MomentumDir are not orthogonal " );
84 ATH_MSG_DEBUG( std::setprecision(10) << " DeltaR-DeltaRcorrected: " << (DeltaR-DeltaRcorrected).mag() );
85 }
86
87 Amg::Vector3D YDir=momentumUnit.cross(DeltaRcorrected);
88
89 ATH_MSG_VERBOSE( "final minimal distance is: " << distance);
90 ATH_MSG_DEBUG( "POCA in 3D is: " << POCA );
91
92 //store the plane...
93 ATH_MSG_VERBOSE( "plane to which to extrapolate X " << DeltaRcorrected << " Y " << YDir << " Z " << momentumUnit);
94
95 Amg::Transform3D thePlane(DeltaRcorrected, YDir, momentumUnit, *theVertex);
96
97#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
98 std::cout << "the translation is, directly from Transform3d: " << thePlane->getTranslation() << endmsg;
99#endif
100
101 return std::make_unique<PlaneSurface>(thePlane);
102
103 }

◆ finalize()

StatusCode Trk::ImpactPoint3dEstimator::finalize ( )
overridevirtual

Definition at line 52 of file ImpactPoint3dEstimator.cxx.

53 {
54 ATH_MSG_DEBUG( "Finalize successful" );
55 return StatusCode::SUCCESS;
56 }

◆ initialize()

StatusCode Trk::ImpactPoint3dEstimator::initialize ( )
overridevirtual

Definition at line 39 of file ImpactPoint3dEstimator.cxx.

40 {
41 if (!m_extrapolator.empty()) {
42 ATH_CHECK( m_extrapolator.retrieve() );
43 } else {
44 m_extrapolator.disable();
45 }
47
48 ATH_MSG_DEBUG( "Initialize successful" );
49 return StatusCode::SUCCESS;
50 }
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ IP3dAtaPlane()

const Trk::AtaPlane * Trk::ImpactPoint3dEstimator::IP3dAtaPlane ( VxTrackAtVertex & vtxTrack,
const Amg::Vector3D & vertex ) const
overridevirtual

This method creates the ImpactPoint3dAtaPlane as the parameters of the track at the point of closest approach in 3d to the given vertex.

The parameters and errors are defined on the plane intersecting the track at point of closest approach, with track ortogonal to the plane and center of the plane defined as the given vertex.

Definition at line 307 of file ImpactPoint3dEstimator.cxx.

308 {
309 if (!vtxTrack.initialPerigee() && vtxTrack.initialNeutralPerigee())
310 ATH_MSG_WARNING( "Calling ImpactPoint3dEstimator::IP3dAtaPlane cannot return NeutralAtaPlane" );
311 std::unique_ptr<PlaneSurface> theSurfaceAtIP;
312 try
313 {
314 double distance = 0;
315 theSurfaceAtIP = Estimate3dIP(vtxTrack.initialPerigee(),&vertex,distance);
316 }
317 catch (error::ImpactPoint3dEstimatorProblem err)
318 {
319 ATH_MSG_WARNING( " ImpactPoint3dEstimator failed to find minimum distance between track and vertex seed: " << err.p );
320 return nullptr;
321 }
322 if(!theSurfaceAtIP){
323 ATH_MSG_WARNING( " ImpactPoint3dEstimator failed to find minimum distance and returned 0 " );
324 return nullptr;
325 }
326#ifdef ImpactPoint3dAtaPlaneFactory_DEBUG
327 ATH_MSG_VERBOSE( "Original perigee was: " << *(vtxTrack.initialPerigee()) );
328 ATH_MSG_VERBOSE( "The resulting surface is: " << *theSurfaceAtIP );
329#endif
330 const auto* pTrackPar = m_extrapolator->extrapolate(
331 Gaudi::Hive::currentContext(),
332 *(vtxTrack.initialPerigee()),
333 *theSurfaceAtIP).release();
334 if (const Trk::AtaPlane* res = dynamic_cast<const Trk::AtaPlane *>(pTrackPar); res){
335 return res;
336 }
337 ATH_MSG_DEBUG("TrackParameters ptr returned from extrapolate could not be cast to Trk::AtaPlane* in IP3dAtaPlane(..)");
338 return nullptr;
339 }
std::pair< std::vector< unsigned int >, bool > res
virtual std::unique_ptr< PlaneSurface > Estimate3dIP(const Trk::TrackParameters *trackPerigee, const Amg::Vector3D *theVertex, double &distance) const override

◆ IP3dNeutralAtaPlane()

const Trk::NeutralAtaPlane * Trk::ImpactPoint3dEstimator::IP3dNeutralAtaPlane ( const NeutralParameters * initNeutPerigee,
const Amg::Vector3D & vertex ) const
overridevirtual

Definition at line 343 of file ImpactPoint3dEstimator.cxx.

344 {
345 std::unique_ptr<PlaneSurface> theSurfaceAtIP;
346
347 try
348 {
349 double distance = 0;
350 theSurfaceAtIP = Estimate3dIP(initNeutPerigee,&vertex,distance);
351 }
352 catch (error::ImpactPoint3dEstimatorProblem err)
353 {
354 ATH_MSG_WARNING( " ImpactPoint3dEstimator failed to find minimum distance between track and vertex seed: " << err.p );
355 return nullptr;
356 }
357 if(!theSurfaceAtIP){
358 ATH_MSG_WARNING( " ImpactPoint3dEstimator failed to find minimum distance and returned 0 " );
359 return nullptr;
360 }
361#ifdef ImpactPoint3dAtaPlaneFactory_DEBUG
362 ATH_MSG_VERBOSE( "Original neutral perigee was: " << *initNeutPerigee );
363 ATH_MSG_VERBOSE( "The resulting surface is: " << *theSurfaceAtIP );
364#endif
365
366 const Trk::NeutralAtaPlane* res = nullptr;
367 std::unique_ptr<const Trk::NeutralParameters> tmp = m_extrapolator->extrapolate(*initNeutPerigee,*theSurfaceAtIP);
368 if(dynamic_cast<const Trk::NeutralAtaPlane*> (tmp.get())){
369 res = static_cast<const Trk::NeutralAtaPlane*> (tmp.release());
370 }
371 return res;
372 }

Member Data Documentation

◆ m_extrapolator

ToolHandle< Trk::IExtrapolator > Trk::ImpactPoint3dEstimator::m_extrapolator
private

Definition at line 88 of file ImpactPoint3dEstimator.h.

◆ m_fieldCacheCondObjInputKey

SG::ReadCondHandleKey<AtlasFieldCacheCondObj> Trk::ImpactPoint3dEstimator::m_fieldCacheCondObjInputKey {this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}
private

Definition at line 89 of file ImpactPoint3dEstimator.h.

90{this, "AtlasFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"};

◆ m_maxiterations

int Trk::ImpactPoint3dEstimator::m_maxiterations
private

Definition at line 92 of file ImpactPoint3dEstimator.h.

◆ m_precision

double Trk::ImpactPoint3dEstimator::m_precision
private

Definition at line 93 of file ImpactPoint3dEstimator.h.


The documentation for this class was generated from the following files: