118 {
120 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
121
122 MagField::AtlasFieldCache fieldCache;
124
125 double magnFieldVect[3];
127 if(magnFieldVect[2] == 0 ){
128 ATH_MSG_DEBUG(
"Magnetic field in the Z direction is 0 -- propagate like a straight line");
130 }
131
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 =
141 Gaudi::Hive::currentContext(), *trackPerigee, perigeeSurface);
144 }
145 if (thePerigee == nullptr){
146 return nullptr;
147 }
148 }
149
150 ATH_MSG_VERBOSE(
" Now running ImpactPoint3dEstimator::Estimate3dIP" );
152 double dCosPhi0=-std::sin(
phi0);
153 double dSinPhi0=std::cos(
phi0);
156 double d0=thePerigee->parameters()[
Trk::d0];
157
158
159 double Bz=magnFieldVect[2]*299.792;
161
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;
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;
231#ifdef IMPACTPOINT3DESTIMATOR_DEBUG
233#endif
235 }
236
237 } while (!isok);
238
239
240
244 if (distance==0.){
245 ATH_MSG_WARNING(
"DeltaR is zero in ImpactPoint3dEstimator::Estimate3dIP, returning nullptr");
246 return nullptr;
247 }
249
250
251
252
254
255 if ((DeltaR-DeltaRcorrected).
mag()>1e-4)
256 {
258 ATH_MSG_DEBUG( std::setprecision(10) <<
" DeltaR-DeltaRcorrected: " << (DeltaR-DeltaRcorrected).
mag() );
259 }
260
262
263
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
271
272
273
274 ATH_MSG_VERBOSE(
"plane to which to extrapolate X " << DeltaRcorrected <<
" Y " << YDir <<
" Z " << MomentumDir );
275
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 }
Scalar mag() const
mag method
#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