CMS 3D CMS Logo

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