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