CMS 3D CMS Logo

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