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