CMS 3D CMS Logo

AnalyticalPropagator.cc
Go to the documentation of this file.
2 
6 
8 
18 
20 
21 #include <cmath>
22 
23 using namespace SurfaceSideDefinition;
24 
25 std::pair<TrajectoryStateOnSurface,double>
27  const Plane& plane) const
28 {
29  // check curvature
30  float rho = fts.transverseCurvature();
31 
32  // propagate parameters
33  GlobalPoint x;
35  double s;
36 
37  // check if already on plane
38  if likely (plane.localZclamped(fts.position()) !=0) {
39  // propagate
40  bool parametersOK = this->propagateParametersOnPlane(fts, plane, x, p, s);
41  // check status and deltaPhi limit
42  float dphi2 = float(s)*rho;
43  dphi2 = dphi2*dphi2*fts.momentum().perp2();
44  if unlikely( !parametersOK || dphi2>theMaxDPhi2*fts.momentum().mag2() ) return TsosWP(TrajectoryStateOnSurface(),0.);
45  }
46  else {
47  LogDebug("AnalyticalPropagator")<<"not going anywhere. Already on surface.\n"
48  <<"plane.localZ(fts.position()): "<<plane.localZ(fts.position())<<"\n"
49  <<"plane.position().mag(): "<<plane.position().mag() <<"\n"
50  <<"plane.posPrec: "<<plane.posPrec();
51  x = fts.position();
52  p = fts.momentum();
53  s = 0;
54  }
55  //
56  // Compute propagated state and check change in curvature
57  //
58  GlobalTrajectoryParameters gtp(x,p,fts.charge(),theField);
59  if unlikely(std::abs(gtp.transverseCurvature()-rho)>theMaxDBzRatio*std::abs(rho) )
60  return TsosWP(TrajectoryStateOnSurface(),0.);
61  //
62  // construct TrajectoryStateOnSurface
63  //
64  return propagatedStateWithPath(fts,plane,gtp,s);
65 }
66 
67 
68 std::pair<TrajectoryStateOnSurface,double>
70  const Cylinder& cylinder) const
71 {
72  // check curvature
73  auto rho = fts.transverseCurvature();
74 
75  // propagate parameters
76  GlobalPoint x;
78  double s = 0;
79 
80  bool parametersOK = this->propagateParametersOnCylinder(fts, cylinder, x, p, s);
81  // check status and deltaPhi limit
82  float dphi2 = s*rho;
83  dphi2 = dphi2*dphi2*fts.momentum().perp2();
84  if unlikely( !parametersOK || dphi2>theMaxDPhi2*fts.momentum().mag2() ) return TsosWP(TrajectoryStateOnSurface(),0.);
85  //
86  // Compute propagated state and check change in curvature
87  //
88  GlobalTrajectoryParameters gtp(x,p,fts.charge(),theField);
89  if unlikely( std::abs(gtp.transverseCurvature()-rho)>theMaxDBzRatio*std::abs(rho) )
90  return TsosWP(TrajectoryStateOnSurface(),0.);
91  //
92  // create result TSOS on TangentPlane (local parameters & errors are better defined)
93  //
94 
95  //try {
96  ConstReferenceCountingPointer<TangentPlane> plane(cylinder.tangentPlane(x)); // need to be here until tsos is created!
97  return propagatedStateWithPath(fts,*plane,gtp,s);
98  /*
99  } catch(...) {
100  std::cout << "wrong tangent to cylinder " << x
101  << " pos, rad " << cylinder.position() << " " << cylinder.radius()
102  << std::endl;
103  return TsosWP(TrajectoryStateOnSurface(),0.);
104  }
105  */
106 }
107 
108 std::pair<TrajectoryStateOnSurface,double>
110  const Surface& surface,
111  const GlobalTrajectoryParameters& gtp,
112  const double& s) const
113 {
114  //
115  // for forward propagation: state is before surface,
116  // for backward propagation: state is after surface
117  //
118  SurfaceSide side = PropagationDirectionFromPath()(s,propagationDirection())==alongMomentum
120  //
121  //
122  // error propagation (if needed) and conversion to a TrajectoryStateOnSurface
123  //
124  if (fts.hasError()) {
125  //
126  // compute jacobian
127  //
128  AnalyticalCurvilinearJacobian analyticalJacobian(fts.parameters(), gtp.position(), gtp.momentum(), s);
129  const AlgebraicMatrix55 &jacobian = analyticalJacobian.jacobian();
130  // CurvilinearTrajectoryError cte(ROOT::Math::Similarity(jacobian, fts.curvilinearError().matrix()));
131  return TsosWP(TrajectoryStateOnSurface(gtp,
132  ROOT::Math::Similarity(jacobian, fts.curvilinearError().matrix()),
133  surface,side),s);
134  }
135  else {
136  //
137  // return state without errors
138  //
139  return TsosWP(TrajectoryStateOnSurface(gtp,surface,side),s);
140  }
141 }
142 
144  const FreeTrajectoryState& fts, const Cylinder& cylinder,
145  GlobalPoint& x, GlobalVector& p, double& s) const
146 {
147 
148  GlobalPoint const & sp = cylinder.position();
149  if unlikely(sp.x()!=0. || sp.y()!=0.) {
150  throw PropagationException("Cannot propagate to an arbitrary cylinder");
151  }
152  // preset output
153  x = fts.position();
154  p = fts.momentum();
155  s = 0;
156  // (transverse) curvature
157  auto rho = fts.transverseCurvature();
158  //
159  // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um
160  // difference in transversal position at 10m.
161  //
162  if unlikely( std::abs(rho)<1.e-10f )
163  return propagateWithLineCrossing(fts.position(),p,cylinder,x,s);
164  //
165  // Helix case
166  //
167  // check for possible intersection
168  constexpr float tolerance = 1.e-4; // 1 micron distance
169  auto rdiff = x.perp() - cylinder.radius();
170  if ( std::abs(rdiff) < tolerance ) return true;
171  //
172  // Instantiate HelixBarrelCylinderCrossing and get solutions
173  //
174  HelixBarrelCylinderCrossing cylinderCrossing(fts.position(),fts.momentum(),rho,
175  propagationDirection(),cylinder);
176  if unlikely( !cylinderCrossing.hasSolution() ) return false;
177  // path length
178  s = cylinderCrossing.pathLength();
179  // point
180  x = cylinderCrossing.position();
181  // direction (renormalised)
182  p = cylinderCrossing.direction().unit()*fts.momentum().mag();
183  return true;
184 }
185 
186 bool
188  const Plane& plane,
189  GlobalPoint& x,
190  GlobalVector& p,
191  double& s) const
192 {
193  // initialisation of position, momentum and path length
194  x = fts.position();
195  p = fts.momentum();
196  s = 0;
197  // (transverse) curvature
198  auto rho = fts.transverseCurvature();
199  //
200  // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um
201  // difference in transversal position at 10m.
202  //
203  if unlikely( std::abs(rho)<1.e-10f )
204  return propagateWithLineCrossing(fts.position(),p,plane,x,s);
205  //
206  // Helix case
207  //
208 
209  //
210  // Frame-independant point and vector are created explicitely to
211  // avoid confusing gcc (refuses to compile with temporary objects
212  // in the constructor).
213  //
216  if likely(isOldPropagationType) {
217  OptimalHelixPlaneCrossing planeCrossing(plane,helixPos,helixDir,rho,propagationDirection());
218  return propagateWithHelixCrossing(*planeCrossing,plane,fts.momentum().mag(),x,p,s);
219  }
220 
221 
222 
223 
224  //--- Alternative implementation to be used for the propagation of the parameters of looping
225  // particles that cross twice the (infinite) surface of the plane. It is not trivial to determine
226  // which of the two intersections has to be returned.
227 
228  //---- FIXME: WHAT FOLLOWS HAS TO BE REWRITTEN IN A CLEANER (AND CPU-OPTIMIZED) WAY ---------
229  LogDebug("AnalyticalPropagator") << "In AnaliticalProp, calling HAPC " << "\n"
230  << "plane is centered in xyz: "
231  << plane.position().x() << " , "
232  << plane.position().y() << " , "
233  << plane.position().z() << "\n";
234 
235 
236  GlobalPoint gp1 = fts.position();
237  GlobalVector gm1 = fts.momentum();
238  double s1 = 0;
239  double rho1 = fts.transverseCurvature();
240  HelixPlaneCrossing::PositionType helixPos1(gp1);
241  HelixPlaneCrossing::DirectionType helixDir1(gm1);
242  LogDebug("AnalyticalPropagator") << "gp1 before calling planeCrossing1: " << gp1 << "\n";
243  OptimalHelixPlaneCrossing planeCrossing1(plane,helixPos1,helixDir1,rho1,propagationDirection());
244 
247 
248  double tolerance(0.0050);
249  if(propagationDirection()==oppositeToMomentum)
250  tolerance *=-1;
251 
252  bool check1 = propagateWithHelixCrossing(*planeCrossing1,plane,fts.momentum().mag(),gp1,gm1,s1);
253  double dphi1 = fabs(fts.momentum().phi()-gm1.phi());
254  LogDebug("AnalyticalPropagator") << "check1, s1, dphi, gp1: "
255  << check1 << " , "
256  << s1 << " , "
257  << dphi1 << " , "
258  << gp1 << "\n";
259 
260  //move forward a bit to avoid that the propagator doesn't propagate because the state is already on surface.
261  //we want to go to the other point of intersection between the helix and the plane
262  xGen = (*planeCrossing1).position(s1+tolerance);
263  pGen = (*planeCrossing1).direction(s1+tolerance);
264 
265  /*
266  if(!check1 || s1>170 ){
267  //PropagationDirection newDir = (propagationDirection() == alongMomentum) ? oppositeToMomentum : alongMomentum;
268  PropagationDirection newDir = anyDirection;
269  HelixArbitraryPlaneCrossing planeCrossing1B(helixPos1,helixDir1,rho1,newDir);
270  check1 = propagateWithHelixCrossing(planeCrossing1B,plane,fts.momentum().mag(),gp1,gm1,s1);
271  LogDebug("AnalyticalPropagator") << "after second attempt, check1, s1,gp1: "
272  << check1 << " , "
273  << s1 << " , " << gp1 << "\n";
274 
275  xGen = planeCrossing1B.position(s1+tolerance);
276  pGen = planeCrossing1B.direction(s1+tolerance);
277  }
278  */
279 
280  if(!check1){
281  LogDebug("AnalyticalPropagator") << "failed also second attempt. No idea what to do, then bailout" << "\n";
282  }
283 
284 
285  pGen *= gm1.mag()/pGen.mag();
286  GlobalPoint gp2(xGen);
287  GlobalVector gm2(pGen);
288  double s2 = 0;
289  double rho2 = rho1;
290  HelixPlaneCrossing::PositionType helixPos2(gp2);
291  HelixPlaneCrossing::DirectionType helixDir2(gm2);
292  OptimalHelixPlaneCrossing planeCrossing2(plane,helixPos2,helixDir2,rho2,propagationDirection());
293 
294  bool check2 = propagateWithHelixCrossing(*planeCrossing2,plane,gm2.mag(),gp2,gm2,s2);
295 
296  if(!check2){
297  x = gp1;
298  p = gm1;
299  s = s1;
300  return check1;
301  }
302 
303  if(!check1){
304  edm::LogError("AnalyticalPropagator") << "LOGIC ERROR: I should not have entered here!" << "\n";
305  return false;
306  }
307 
308 
309  LogDebug("AnalyticalPropagator") << "check2, s2, gp2: "
310  << check2 << " , "
311  << s2 << " , " << gp2 << "\n";
312 
313 
314  double dist1 = (plane.position()-gp1).perp();
315  double dist2 = (plane.position()-gp2).perp();
316 
317 
318  LogDebug("AnalyticalPropagator") << "propDir, dist1, dist2: "
319  << propagationDirection() << " , "
320  << dist1 << " , "
321  << dist2 << "\n";
322 
323  //If there are two solutions, the one which is the closest to the module's center is chosen
324  if(dist1<2*dist2){
325  x = gp1;
326  p = gm1;
327  s = s1;
328  return check1;
329  }else if(dist2<2*dist1){
330  x = gp2;
331  p = gm2;
332  s = s1+s2+tolerance;
333  return check2;
334  }else{
335  if(fabs(s1)<fabs(s2)){
336  x = gp1;
337  p = gm1;
338  s = s1;
339  return check1;
340  }else{
341  x = gp2;
342  p = gm2;
343  s = s1+s2+tolerance;
344  return check2;
345  }
346  }
347 
348  //-------- END of ugly piece of code ---------------
349 
350 }
351 
352 bool
354  const GlobalVector& p0,
355  const Plane& plane,
356  GlobalPoint& x, double& s) const {
357  //
358  // Instantiate auxiliary object for finding intersection.
359  // Frame-independant point and vector are created explicitely to
360  // avoid confusing gcc (refuses to compile with temporary objects
361  // in the constructor).
362  //
365  StraightLinePlaneCrossing planeCrossing(pos,dir,propagationDirection());
366  //
367  // get solution
368  //
369  std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
370  if ( !propResult.first ) return false;
371  s = propResult.second;
372  // point (reconverted to GlobalPoint)
373  x = GlobalPoint(planeCrossing.position(s));
374  //
375  return true;
376 }
377 
378 bool
380  const GlobalVector& p0,
381  const Cylinder& cylinder,
382  GlobalPoint& x, double& s) const {
383  //
384  // Instantiate auxiliary object for finding intersection.
385  // Frame-independant point and vector are created explicitely to
386  // avoid confusing gcc (refuses to compile with temporary objects
387  // in the constructor).
388  //
389  StraightLineBarrelCylinderCrossing cylCrossing(x0,p0,propagationDirection());
390  //
391  // get solution
392  //
393  std::pair<bool,double> propResult = cylCrossing.pathLength(cylinder);
394  if ( !propResult.first ) return false;
395  s = propResult.second;
396  // point (reconverted to GlobalPoint)
397  x = cylCrossing.position(s);
398  //
399  return true;
400 }
401 
402 bool
404  const Plane& plane,
405  const float pmag,
406  GlobalPoint& x,
407  GlobalVector& p,
408  double& s) const {
409  // get solution
410  std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
411  if unlikely( !propResult.first ) return false;
412 
413  s = propResult.second;
414  x = GlobalPoint(planeCrossing.position(s));
415  // direction (reconverted to GlobalVector, renormalised)
416  GlobalVector pGen = GlobalVector(planeCrossing.direction(s));
417  pGen *= pmag/pGen.mag();
418  p = pGen;
419  //
420  return true;
421 }
#define LogDebug(id)
T mag2() const
Definition: PV3DBase.h:66
ConstReferenceCountingPointer< TangentPlane > tangentPlane(const GlobalPoint &) const override
tangent plane to surface from global point
Definition: Cylinder.cc:23
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
const GlobalTrajectoryParameters & parameters() const
const AlgebraicMatrix55 & jacobian() const
virtual PositionType position(double s) const =0
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
float localZ(const GlobalPoint &gp) const
Definition: Plane.h:45
float posPrec() const
Definition: Plane.h:60
bool propagateWithLineCrossing(const GlobalPoint &, const GlobalVector &, const Plane &, GlobalPoint &, double &) const
straight line parameter propagation to a plane
T perp2() const
Definition: PV3DBase.h:71
TrackCharge charge() const
const CurvilinearTrajectoryError & curvilinearError() const
Definition: Plane.h:17
#define constexpr
bool propagateParametersOnPlane(const FreeTrajectoryState &fts, const Plane &plane, GlobalPoint &x, GlobalVector &p, double &s) const
parameter propagation to plane (returns position, momentum and path length)
#define unlikely(x)
#define likely(x)
std::pair< TrajectoryStateOnSurface, double > propagatedStateWithPath(const FreeTrajectoryState &fts, const Surface &surface, const GlobalTrajectoryParameters &gtp, const double &s) const
propagation of errors (if needed) and generation of a new TSOS
T mag() const
Definition: PV3DBase.h:67
T phi() const
Definition: Phi.h:41
virtual DirectionType direction(double s) const =0
bool propagateWithHelixCrossing(HelixPlaneCrossing &, const Plane &, const float, GlobalPoint &, GlobalVector &, double &s) const
helix parameter propagation to a plane using HelixPlaneCrossing
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
PositionType position(float s) const
double f[11][100]
Common base class.
GlobalVector momentum() const
std::pair< bool, double > pathLength(const Plane &plane) const
Vector3DBase unit() const
Definition: Vector3DBase.h:57
bool propagateParametersOnCylinder(const FreeTrajectoryState &fts, const Cylinder &cylinder, GlobalPoint &x, GlobalVector &p, double &s) const
parameter propagation to cylinder (returns position, momentum and path length)
GlobalPoint position() const
float localZclamped(const GlobalPoint &gp) const
Definition: Plane.h:49
virtual std::pair< bool, double > pathLength(const Plane &)=0
double transverseCurvature() const
T perp() const
Magnitude of transverse component.
const AlgebraicSymMatrix55 & matrix() const
std::pair< TrajectoryStateOnSurface, double > TsosWP
dbl *** dir
Definition: mlp_gen.cc:35
std::pair< bool, double > pathLength(const Cylinder &cyl) const
T x() const
Definition: PV3DBase.h:62
const PositionType & position() const
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepStd< double, 5, 5 > > AlgebraicMatrix55
Global3DVector GlobalVector
Definition: GlobalVector.h:10
std::pair< TrajectoryStateOnSurface, double > propagateWithPath(const FreeTrajectoryState &fts, const Plane &plane) const override
propagation to plane with path length