ATLAS Offline Software
Loading...
Searching...
No Matches
TrackPropagationHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7 // //
8 // Implementation of class TrackPropagationHelper //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial extrapolation code by Thijs Cornelissen //
12 // Initial version: February 2008 //
13 // //
15
18#include "TrkTrack/Track.h"
21#include <stdexcept>
24#include "TrkVolumes/Volume.h"
27
28#include "CLHEP/Units/PhysicalConstants.h"
29
30#include "VP1Base/VP1QtUtils.h"
31#include "VP1Base/VP1Msg.h"
32#include <limits>
33#include <memory>
34
35//____________________________________________________________________
37public:
39 : theclass(tc),
40 tracksanity(new VP1TrackSanity(tc?tc->systemBase():nullptr)),
41 maxInDetr(1.1*CLHEP::m),
43 maxz(3.5*CLHEP::m),
45 showExtrapSurfaces(VP1QtUtils::environmentVariableIsOn("VP1_TRKSYS_SHOWEXTRAPSURFACES"))
46 {
47 }
48
50 std::unique_ptr<VP1TrackSanity> tracksanity{};
51 const double maxInDetr{};
52 const double maxInDetrsq{};
53 const double maxz{};
54 const double fallback_flydist{};
55
56 bool outsideIDVolume(const Amg::Vector3D& p) const {
57 return fabs(p.z())>maxz||p.perp2()>maxInDetrsq;
58 }
59
60 //Fixme: These are similar to internal methods in InDetProjHelper in guideline system!!:
61 void movePoint1ToZPlaneAndPoint2( Amg::Vector3D& p1, const Amg::Vector3D& p2, const double& z ) const;
62 void movePoint1ToInfiniteCylinderAndPoint2( Amg::Vector3D&p1, const Amg::Vector3D&p2, const double& r ) const;
63
64 bool makePointsNeutral_SinglePar( std::vector<Amg::Vector3D >& points, const Trk::Track* );
65 bool makePointsCharged_SinglePar( std::vector<Amg::Vector3D >& points, const Trk::Track*,
66 Trk::IExtrapolator * extrapolator, Trk::ParticleHypothesis hypo );
67 bool addPointsBetweenParameters_Charged( std::vector<Amg::Vector3D >& points, const Trk::Track*,
68 const Trk::TrackParameters * par1, const Trk::TrackParameters * par2,
69 Trk::IExtrapolator * extrapolator, Trk::ParticleHypothesis hypo );
70
71 //Will create new track par:
73 const Trk::Track* trk,
74 const Trk::TrackParameters * prevpars,
76 const double& dist );
77 //Granularity:
78 static double maxPointDistSq(const Amg::Vector3D& /* p */){
79 //Vertex region:
89 return 2*CLHEP::cm;//Outside ID
90 }
91
92 std::vector<Trk::PlaneSurface> surfaces;
94};
95
96std::vector<Trk::PlaneSurface>& TrackPropagationHelper::getExtrapolationSurfaces() const {
97 return m_d->surfaces;
98}
99
100//____________________________________________________________________
102{
103 double dx(p2.x()-p1.x()), dy(p2.y()-p1.y()), dz(p2.z()-p1.z());
104 if (dz==0.0) {
105 theclass->message("movePoint1ToZPlaneAndPoint2 Error: Points have same z!!");
106 return;
107 }
108 double s( (z-p1.z())/dz );
109 // p1.set( p1.x()+dx*s, p1.y()+dy*s, z );
110 p1[0]= p1.x()+dx*s;
111 p1[1]= p1.y()+dy*s;
112 p1[2]= z;
113
114}
115
116 //____________________________________________________________________
118{
119 //Fixme: what happens here if we don't cross? And how can we be sure
120 //that we don't move FURTHER than the other point? (i.e. if the
121 //infinite line with p1 and p2 crosses, but the segment p1p2 does
122 //not!?
123 double p1r(p1.perp());
124 double dr(p2.perp()-p1r);
125 if (dr==0.0) {
126 theclass->message("movePoint1ToInfiniteCylinderAndPoint2 Error: Points have same r!!");
127 return;
128 }
129 double s((r-p1r)/dr);
130 double t(1.0-s);
131 // p1.set( p1.x()*t + p2.x()*s, p1.y()*t + p2.y()*s, p1.z()*t + p2.z()*s );
132 p1[0]= p1.x()*t + p2.x()*s;
133 //p1[1]= p2.y()*s, p1.z()*t; original
134 p1[1]= p1.y()*t + p2.y()*s; //sroe, compiler warning fix
135 p1[2]= p1.z()*t + p2.z()*s;
136}
137
138 //____________________________________________________________________
140 : VP1HelperClassBase(sys,"TrackPropagationHelper"), m_d(new Imp(this))
141{
142}
143
144 //____________________________________________________________________
149
150 //____________________________________________________________________
151bool TrackPropagationHelper::makePointsNeutral( std::vector<Amg::Vector3D >& points, const Trk::Track* track )
152{
153 if (VP1Msg::verbose())
154 messageVerbose("makePointsNeutral start");
155
156 points.clear();
157 if (!track) {
158 message("makePointsNeutral called with null track pointer");
159 return false;
160 }
161 const unsigned npars = track->trackParameters()->size();
162 if (npars==0) {
163 message("makePointsNeutral Error: No TrackParameters on track!");
164 return false;
165 }
166 if (npars==1)
167 return m_d->makePointsNeutral_SinglePar(points,track);
168
169 points.reserve(track->trackParameters()->size());
170
171
172 Trk::TrackStates::const_iterator tsos_iter = track->trackStateOnSurfaces()->begin();
173 Trk::TrackStates::const_iterator tsos_end = track->trackStateOnSurfaces()->end();
174 bool problems(false);
175 for (; tsos_iter != tsos_end; ++tsos_iter) {
176 if (!m_d->tracksanity->isSafe(*tsos_iter)) {
177 problems = true;
178 continue;
179 }
180 //if ((*tsos_iter)->materialEffectsOnTrack())
181 // continue;
182 const Trk::TrackParameters* trackParam = (*tsos_iter)->trackParameters();
183 if (!m_d->tracksanity->isSafe(trackParam)) {
184 problems = true;
185 continue;
186 }
187 points.push_back(trackParam->position());
188 }
189 if (problems) {
190 messageDebug("makePointsNeutral WARNING: Track had one or more track parameters which is unsafe to use in job.");
191 if (points.size()<2) {
192 messageDebug("makePointsNeutral ERROR: Track did not have at least two safe parameters.");
193 points.clear();
194 return false;
195 }
196 }
197
198 if (VP1Msg::verbose())
199 messageVerbose("makePointsNeutral_SinglePar end");
200 return true;
201}
202
203 //____________________________________________________________________
204bool TrackPropagationHelper::Imp::makePointsNeutral_SinglePar( std::vector<Amg::Vector3D >& points, const Trk::Track* track )
205{
206 if (VP1Msg::verbose())
207 theclass->messageVerbose("makePointsNeutral_SinglePar start");
208 points.clear();
209 const Trk::TrackParameters * par = *(track->trackParameters()->begin());
210 if (!tracksanity->isSafe(par)) {
211 theclass->messageDebug("makePointsNeutral_SinglePar called with unsafe track parameter");
212 return false;
213 }
214 Amg::Vector3D u(par->momentum().unit());
215 Amg::Vector3D a(par->position()),b;
216 if (outsideIDVolume(a)) {
217 //We start outside. We just add fallback_flydist. (fixme: warn?)
218 b = a +fallback_flydist*u;
219 } else {
220 //Make a second point, where trajectory hits maxInDetr,maxz
221 b = a +999*CLHEP::m*u;
222 if (b.z()<-maxz)
224 else
225 if (b.z()>maxz)
227 if (b.perp2()>maxInDetrsq)
229 }
230 points.reserve(2);
231 points.push_back(a);
232 points.push_back(b);
233 if (VP1Msg::verbose())
234 theclass->messageVerbose("makePointsNeutral_SinglePar (single track parameter) end");
235 return true;
236}
237
238 //____________________________________________________________________
239bool TrackPropagationHelper::makePointsCharged( std::vector<Amg::Vector3D >& points, const Trk::Track* track,
240 Trk::IExtrapolator * extrapolator, Trk::ParticleHypothesis hypo, bool useMEOT,const Trk::Volume* volume )
241{
242 if (VP1Msg::verbose())
243 messageVerbose("makePointsCharged start with hypo="+str(hypo)+", useMEOT="+str(useMEOT)+", volume=" +str(volume));
244 // if (volume) std::cout<<volume->volumeBounds()<<std::endl;
246 // Clear input points, check/sanitise input and initialise //
248
249 points.clear();
250 if (!extrapolator) {
251 message("makePointsCharged ERROR: Null extrapolator tool provided!");
252 return false;
253 }
254 if (!track) {
255 message("makePointsCharged ERROR: Called with null track pointer");
256 return false;
257 }
258 const unsigned npars = track->trackParameters()->size();
259 if (npars==0) {
260 message("makePointsCharged ERROR: No TrackParameters on track!");
261 return false;
262 }
263 if (npars==1)
264 return m_d->makePointsCharged_SinglePar(points,track,extrapolator,hypo);
265
266 points.reserve(npars);//At least we need this.
267 const EventContext& ctx = Gaudi::Hive::currentContext();
268 //Add a point for each parameter, and add extra points between them where appropriate.
269 Trk::TrackStates::const_iterator tsos_iter = track->trackStateOnSurfaces()->begin();
270 Trk::TrackStates::const_iterator tsos_end = track->trackStateOnSurfaces()->end();
271 const Trk::TrackParameters* prevpar(nullptr);
272 const Trk::TrackParameters* trackParam(nullptr);
273 bool problems(false);
274 for (; tsos_iter != tsos_end; ++tsos_iter) {
275 if (!m_d->tracksanity->isSafe(*tsos_iter))
276 continue;
277 if ((*tsos_iter)->measurementOnTrack()==nullptr && ( (*tsos_iter)->materialEffectsOnTrack()&&!useMEOT ) )
278 continue;
279 trackParam = (*tsos_iter)->trackParameters();
280 if (!m_d->tracksanity->isSafe(trackParam))
281 continue;
282 if (!prevpar) {
283 //first time.
284 prevpar = trackParam;
285 points.push_back(prevpar->position());
286 continue;
287 }
288 if (!m_d->addPointsBetweenParameters_Charged(points,track,prevpar,trackParam,extrapolator,hypo))
289 problems = true;
290 points.push_back(trackParam->position());
291 prevpar = trackParam;
292 }
293
294 if (problems)
295 messageDebug("WARNING: Problems encountered adding point(s) between track parameters");
296
297// restrict to ID tracks for now.
298 if (volume && trackParam && !m_d->outsideIDVolume(trackParam->position())) {
299 messageVerbose("Extending to Volume");
300 //get individual surfaces
301
302 // TODO - optimise this!
303 const std::vector<std::unique_ptr<Trk::Surface>> bsurfs =
304 const_cast<Trk::VolumeBounds&>(volume->volumeBounds())
305 .decomposeToSurfaces(volume->transform());
306
307 if (!bsurfs.empty()){
308 messageVerbose("Has this many surfaces:"+str(bsurfs.size()));
309
310 auto bSurfsIt = bsurfs.begin();
311 for (;bSurfsIt!= bsurfs.end(); ++bSurfsIt){
312
313 messageVerbose("Extrap value:"+str((extrapolator)));
314 messageVerbose("trackParam:"+str((trackParam)));
315 const Trk::TrackParameters* trackPar = extrapolator->extrapolate(ctx,
316 *trackParam,
317 **bSurfsIt,
318 Trk::alongMomentum,true,hypo).release(); // change this to extrapolate current param to surface.
319
320 if (trackPar){
321 messageVerbose("Extrapolation succeeded");
322
323 if (!m_d->addPointsBetweenParameters_Charged(points,track,trackParam,trackPar,extrapolator,hypo))
324 messageDebug("WARNING: Problems encountered adding point(s) between track parameters in extending to Volume");
325 }
326 }
327 } else {
328 messageDebug("WARNING: Problems encountered getting boundary surfaces from Volume");
329 }
330 }
331 if (VP1Msg::verbose())
332 messageVerbose("makePointsCharged end with "+str(points.size())+"points");
333 return true;
334}
335
336 //____________________________________________________________________
338 const Trk::Track* trk,
339 const Trk::TrackParameters * prevpars,
341 const double& dist )
342{
343 if (!trk||!prevpars||!extrapolator)
344 return nullptr;
345
346 Trk::CurvilinearUVT uvt(prevpars->momentum().unit());
347
348
349 Amg::Transform3D t(uvt.curvU(),uvt.curvV(),uvt.curvT(), prevpars->position()+(prevpars->momentum().unit()*dist));
350
351 Trk::PlaneSurface surf(t);
352
353
354 if (showExtrapSurfaces) surfaces.push_back(surf);
355
356
357 const Trk::TrackParameters *newpars(nullptr);
358 try {
359 newpars = extrapolator->extrapolate(Gaudi::Hive::currentContext(),
360 *prevpars,
361 surf,
362 Trk::alongMomentum,false,hypo).release(); // change this to extrapolate current param to surface.
363 } catch (const std::runtime_error& e) {
364 theclass->message("Failure trying to use extrapolator for track (Exception thrown: " + QString(e.what())+")");
365 return nullptr;
366 }
367 if (!newpars) {
368 theclass->message("Failure trying to use extrapolator for track");
369 return nullptr;
370 }
371 if (!newpars) {
372 theclass->message("Failure trying to use extrapolator for track");
373 return nullptr;
374 }
375 return newpars;
376}
377
379 return m_d->showExtrapSurfaces;
380}
381
382
383 //____________________________________________________________________
384bool TrackPropagationHelper::Imp::makePointsCharged_SinglePar( std::vector<Amg::Vector3D >& points, const Trk::Track* track,
385 Trk::IExtrapolator * extrapolator, Trk::ParticleHypothesis hypo )
386{
387 if (VP1Msg::verbose())
388 theclass->messageVerbose("makePointsCharged_SinglePar start");
389 points.clear();
390 if (!extrapolator) {
391 theclass->message("makePointsCharged_SinglePar ERROR: Null extrapolator tool provided!");
392 return false;
393 }
394 const Trk::TrackParameters * par = *(track->trackParameters()->begin());
395 if (!tracksanity->isSafe(par)) {
396 theclass->messageDebug("makePointsCharged_SinglePar called with unsafe track parameter");
397 return false;
398 }
399
400 Amg::Vector3D p0(par->position());
401 points.push_back(p0);
402 const bool startoutsideID(outsideIDVolume(p0));
403
404 double distadded(0);
405 const double maxdistadded = 2*CLHEP::m;
406 points.reserve(20);//skip a few reallocs
407 const Trk::TrackParameters * prevpars = par;
408 const Trk::TrackParameters * temppars(nullptr);
409
410 while (distadded<maxdistadded) {
411 temppars = extrapolateToNewPar( extrapolator, track, prevpars, hypo, maxPointDistSq(prevpars->position()));
412 if (temppars)
413 distadded += (temppars->position()-prevpars->position()).mag();
414 if (prevpars!=par)
415 delete prevpars;
416 prevpars = nullptr;
417 if (!temppars) {
418 theclass->messageDebug("makePointsCharged_SinglePar ERROR: Failed to use extrapolator for next point");
419 if (points.size()<2) {
420 points.clear();
421 return false;
422 }
423 return true;//Fixme??
424 }
425 Amg::Vector3D p(temppars->position());
426 points.push_back(p);
427 prevpars = temppars;
428 temppars = nullptr;
429 if (!startoutsideID && outsideIDVolume(p)) {
430 if (prevpars!=par)
431 delete prevpars;
432 prevpars = nullptr;
433 break;
434 }
435 }
436 if (prevpars!=par)
437 delete prevpars;
438
439 if (VP1Msg::verbose())
440 theclass->messageVerbose("makePointsCharged_SinglePar end");
441 return true;
442
443}
444
445 //____________________________________________________________________
446bool TrackPropagationHelper::Imp::addPointsBetweenParameters_Charged( std::vector<Amg::Vector3D >& points, const Trk::Track* trk,
447 const Trk::TrackParameters * par1, const Trk::TrackParameters * par2,
448 Trk::IExtrapolator * extrapolator, Trk::ParticleHypothesis hypo )
449{
450 double distbetween = sqrt((par2->position()-par1->position()).mag2());
451 if (distbetween<0.001) {
452 theclass->messageVerbose("TrackPropagationHelper::Imp::addPointsBetweenParameters_Charged: parameters on top of each other. Skip, but no error.");
453 return true;
454 }
455 // theclass->messageVerbose("TrackPropagationHelper::Imp::addPointsBetweenParameters_Charged: par1="
456 // +str(par1->position())+", par2=" +str(par2->position())+", dist="+str(distbetween));
457
458 Amg::Vector3D p2(par2->position());
459 const Trk::TrackParameters * prevpars = par1;
460
461 double olddistsq(1.0e99);
462 double distadded(0);
463 const double maxdistadded = std::max(2*CLHEP::m,(par1->position()-p2).mag()*1.5);
464 while ( (prevpars->position()-p2).mag()> maxPointDistSq(prevpars->position()) && distadded<maxdistadded ) {
465
466 // theclass->messageVerbose("distadded: "+str(distadded)+", distance left="+str(sqrt((prevpars->position()-p2).mag2()))+", jump="+str(maxPointDistSq(prevpars->position())));
467 const Trk::TrackParameters * newpars = extrapolateToNewPar( extrapolator, trk, prevpars, hypo, maxPointDistSq(prevpars->position()) );
468 if (!newpars){
469 if (VP1Msg::verbose())
470 theclass->messageVerbose("TrackPropagationHelper::Imp::addPointsBetweenParameters_Charged: Extrapolation failed.");
471 return false;
472 }
473 const double distsq = (par2->position()-newpars->position()).mag2();
474 if (distsq>olddistsq) {
475 delete newpars;
476 if (VP1Msg::verbose())
477 theclass->messageVerbose("TrackPropagationHelper::Imp::addPointsBetweenParameters_Charged: distq("+str(distsq)+")>olddistsq ("+str(olddistsq)+") so overshot?");
478 return false;
479 }
480 olddistsq = distsq;
481 // if ((prevpars->position()-newpars->position()).mag2() > 4*maxpointdistsq) {
482 // delete newpars;
483 // return false;
484 // }
485 points.push_back(newpars->position());
486 distadded += (newpars->position()-prevpars->position()).mag();
487 if (prevpars!=par1)
488 delete prevpars;
489 prevpars = newpars;
490 }
491 if (prevpars!=par1)
492 delete prevpars;
493 return (distadded<maxdistadded);
494}
static Double_t a
static Double_t tc
#define z
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const Trk::TrackParameters * extrapolateToNewPar(Trk::IExtrapolator *extrapolator, const Trk::Track *trk, const Trk::TrackParameters *prevpars, Trk::ParticleHypothesis hypo, const double &dist)
std::vector< Trk::PlaneSurface > surfaces
For debugging.
bool addPointsBetweenParameters_Charged(std::vector< Amg::Vector3D > &points, const Trk::Track *, const Trk::TrackParameters *par1, const Trk::TrackParameters *par2, Trk::IExtrapolator *extrapolator, Trk::ParticleHypothesis hypo)
bool makePointsCharged_SinglePar(std::vector< Amg::Vector3D > &points, const Trk::Track *, Trk::IExtrapolator *extrapolator, Trk::ParticleHypothesis hypo)
TrackPropagationHelper * theclass
void movePoint1ToZPlaneAndPoint2(Amg::Vector3D &p1, const Amg::Vector3D &p2, const double &z) const
bool outsideIDVolume(const Amg::Vector3D &p) const
Imp(TrackPropagationHelper *tc)
std::unique_ptr< VP1TrackSanity > tracksanity
bool makePointsNeutral_SinglePar(std::vector< Amg::Vector3D > &points, const Trk::Track *)
static double maxPointDistSq(const Amg::Vector3D &)
void movePoint1ToInfiniteCylinderAndPoint2(Amg::Vector3D &p1, const Amg::Vector3D &p2, const double &r) const
bool makePointsCharged(std::vector< Amg::Vector3D > &points, const Trk::Track *, Trk::IExtrapolator *extrapolator, Trk::ParticleHypothesis hypo=Trk::nonInteracting, bool useMEOT=false, const Trk::Volume *volume=0)
bool makePointsNeutral(std::vector< Amg::Vector3D > &points, const Trk::Track *)
std::vector< Trk::PlaneSurface > & getExtrapolationSurfaces() const
simple class that constructs the curvilinear vectors curvU and curvV from a given momentum direction ...
const Amg::Vector3D & curvU() const
Access methods.
const Amg::Vector3D & curvT() const
const Amg::Vector3D & curvV() const
Interface class for the extrapolation AlgTool, it inherits from IAlgTool Detailed information about p...
virtual std::unique_ptr< NeutralParameters > extrapolate(const NeutralParameters &parameters, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true) const =0
Main extrapolation Interface starting from neutral parameters and aiming at surface.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Pure Absract Base Class for Volume bounds.
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform)=0
Method to decompose the Bounds into Surfaces, the Volume can turn them into BoundarySurfaces.
Base class for all volumes inside the tracking realm, it defines the interface for inherited Volume c...
Definition Volume.h:36
const Amg::Transform3D & transform() const
Return methods for geometry transform.
Definition Volume.h:83
const VolumeBounds & volumeBounds() const
returns the volumeBounds()
Definition Volume.h:96
VP1HelperClassBase(IVP1System *sys=0, QString helpername="")
void messageVerbose(const QString &) const
void message(const QString &) const
IVP1System * systemBase() const
void messageDebug(const QString &) const
static bool verbose()
Definition VP1Msg.h:31
int r
Definition globals.cxx:22
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
@ alongMomentum
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters