CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RKPropagatorInS.cc
Go to the documentation of this file.
2 #include "RKCartesianDistance.h"
4 #include "RKLocalFieldProvider.h"
7 #include "RKAdaptiveSolver.h"
8 #include "RKOne4OrderStep.h"
9 #include "RKOneCashKarpStep.h"
10 #include "PathToPlane2Order.h"
11 #include "CartesianStateAdaptor.h"
16 #include "FrameChanger.h"
21 
24 
25 
26 std::pair<TrajectoryStateOnSurface,double>
27 RKPropagatorInS::propagateWithPath(const FreeTrajectoryState& fts,
28  const Plane& plane) const
29 {
30  GlobalParametersWithPath gp = propagateParametersOnPlane( fts, plane);
31  if unlikely(!gp) return TsosWP(TrajectoryStateOnSurface(),0.);
32 
33  SurfaceSideDefinition::SurfaceSide side = PropagationDirectionFromPath()(gp.s(),propagationDirection())==alongMomentum
34  ? SurfaceSideDefinition::beforeSurface : SurfaceSideDefinition::afterSurface;
36  return errorprop( fts, plane, side, gp.parameters(),gp.s());
37 }
38 
39 std::pair< TrajectoryStateOnSurface, double>
40 RKPropagatorInS::propagateWithPath (const FreeTrajectoryState& fts, const Cylinder& cyl) const
41 {
42  GlobalParametersWithPath gp = propagateParametersOnCylinder( fts, cyl);
43  if unlikely(!gp) return TsosWP(TrajectoryStateOnSurface(),0.);
44 
45  SurfaceSideDefinition::SurfaceSide side = PropagationDirectionFromPath()(gp.s(),propagationDirection())==alongMomentum
46  ? SurfaceSideDefinition::beforeSurface : SurfaceSideDefinition::afterSurface;
48  return errorprop( fts, cyl, side, gp.parameters(),gp.s());
49 
50 }
51 
53 RKPropagatorInS::propagateParametersOnPlane( const FreeTrajectoryState& ts,
54  const Plane& plane) const
55 {
56 
57  GlobalPoint gpos( ts.position());
58  GlobalVector gmom( ts.momentum());
59  double startZ = plane.localZ(gpos);
60  // (transverse) curvature
61  double rho = ts.transverseCurvature();
62  //
63  // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um
64  // difference in transversal position at 10m.
65  //
66  if unlikely( fabs(rho)<1.e-10 ) {
67  //
68  // Instantiate auxiliary object for finding intersection.
69  // Frame-independant point and vector are created explicitely to
70  // avoid confusing gcc (refuses to compile with temporary objects
71  // in the constructor).
72  //
73  LogDebug("RKPropagatorInS")<<" startZ = "<<startZ;
74 
75  if unlikely(fabs(startZ) < 1e-5){
76  LogDebug("RKPropagatorInS")<< "Propagation is not performed: state is already on final surface.";
77  GlobalTrajectoryParameters res( gpos, gmom, ts.charge(),
78  theVolume);
79  return GlobalParametersWithPath( res, 0.0);
80  }
81 
84  StraightLinePlaneCrossing planeCrossing(pos,dir, propagationDirection());
85  //
86  // get solution
87  //
88  std::pair<bool,double> propResult = planeCrossing.pathLength(plane);
89  if likely( propResult.first && theVolume !=0) {
90  double s = propResult.second;
91  // point (reconverted to GlobalPoint)
92  GlobalPoint x (planeCrossing.position(s));
93  GlobalTrajectoryParameters res( x, gmom, ts.charge(), theVolume);
94  return GlobalParametersWithPath( res, s);
95  }
96  //do someting
97  LogDebug("RKPropagatorInS")<< "Straight line propgation to plane failed !!";
98  return GlobalParametersWithPath( );
99 
100  }
101 
102 
103 #ifdef EDM_LM_DEBUG
104  if (theVolume != 0) {
105  LogDebug("RKPropagatorInS") << "RKPropagatorInS: starting prop to plane in volume with pos " << theVolume->position()
106  << " Z axis " << theVolume->toGlobal( LocalVector(0,0,1)) ;
107 
108  LogDebug("RKPropagatorInS") << "The starting position is " << ts.position() << " (global) "
109  << theVolume->toLocal(ts.position()) << " (local) " ;
110 
111  FrameChanger changer;
112  FrameChanger::PlanePtr localPlane = changer.transformPlane( plane, *theVolume);
113  LogDebug("RKPropagatorInS") << "The plane position is " << plane.position() << " (global) "
114  << localPlane->position() << " (local) " ;
115 
116  LogDebug("RKPropagatorInS") << "The initial distance to plane is " << plane.localZ( ts.position()) ;
117 
118  StraightLinePlaneCrossing cross( ts.position().basicVector(), ts.momentum().basicVector());
119  std::pair<bool,double> res3 = cross.pathLength(plane);
120  LogDebug("RKPropagatorInS") << "straight line distance " << res3.first << " " << res3.second ;
121  }
122 #endif
123 
124  typedef RKAdaptiveSolver<double,RKOneCashKarpStep, 6> Solver;
125  typedef Solver::Vector RKVector;
126 
127  RKLocalFieldProvider field( fieldProvider());
128  PathToPlane2Order pathLength( field, &field.frame());
129  CartesianLorentzForce deriv(field, ts.charge());
130 
131  RKCartesianDistance dist;
132  double eps = theTolerance;
133  Solver solver;
134  double stot = 0;
135  PropagationDirection currentDirection = propagationDirection();
136 
137  // in magVolume frame
138  RKVector start( CartesianStateAdaptor::rkstate( rkPosition(gpos), rkMomentum(gmom)));
139  int safeGuard = 0;
140  while (safeGuard++<100) {
141  CartesianStateAdaptor startState(start);
142 
143  std::pair<bool,double> path = pathLength( plane, startState.position(),
144  startState.momentum(),
145  (double) ts.charge(), currentDirection);
146  if unlikely(!path.first) {
147  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Path length calculation to plane failed!"
148  << "...distance to plane " << plane.localZ( globalPosition(startState.position()))
149  << "...Local starting position in volume " << startState.position()
150  << "...Magnetic field " << field.inTesla( startState.position()) ;
151 
152 
153  return GlobalParametersWithPath();
154  }
155 
156  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Path lenght to plane is " << path.second ;
157 
158 
159  double sstep = path.second;
160  if unlikely( std::abs(sstep) < eps) {
161  LogDebug("RKPropagatorInS") << "On-surface accuracy not reached, but pathLength calculation says we are there! "
162  << "path " << path.second << " distance to plane is " << startZ ;
163  GlobalTrajectoryParameters res( gtpFromVolumeLocal( startState, ts.charge()));
164  return GlobalParametersWithPath( res, stot);
165  }
166 
167  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Solving for " << sstep
168  << " current distance to plane is " << startZ ;
169 
170  RKVector rkresult = solver( 0, start, sstep, deriv, dist, eps);
171  stot += sstep;
172  CartesianStateAdaptor cur( rkresult);
173  double remainingZ = plane.localZ( globalPosition(cur.position()));
174 
175  if ( fabs(remainingZ) < eps) {
176  LogDebug("RKPropagatorInS") << "On-surface accuracy reached! " << remainingZ ;
177  GlobalTrajectoryParameters res( gtpFromVolumeLocal( cur, ts.charge()));
178  return GlobalParametersWithPath( res, stot);
179  }
180 
181  start = rkresult;
182 
183  if (remainingZ * startZ > 0) {
184  LogDebug("RKPropagatorInS") << "Accuracy not reached yet, trying in same direction again "
185  << remainingZ ;
186  }
187  else {
188  LogDebug("RKPropagatorInS") << "Accuracy not reached yet, trying in opposite direction "
189  << remainingZ ;
190  currentDirection = invertDirection( currentDirection);
191  }
192  startZ = remainingZ;
193  }
194 
195  edm::LogError("FailedPropagation") << " too many iterations trying to reach plane ";
196  return GlobalParametersWithPath();
197 }
198 
200 RKPropagatorInS::propagateParametersOnCylinder( const FreeTrajectoryState& ts,
201  const Cylinder& cyl) const {
202 
203  typedef RKAdaptiveSolver<double,RKOneCashKarpStep, 6> Solver;
204  typedef Solver::Vector RKVector;
205 
206 
207  GlobalPoint sp = cyl.position();
208  if unlikely(sp.x()!=0. || sp.y()!=0.) {
209  throw PropagationException("Cannot propagate to an arbitrary cylinder");
210  }
211 
212  GlobalPoint gpos( ts.position());
213  GlobalVector gmom( ts.momentum());
214  LocalPoint pos(cyl.toLocal(gpos));
215  LocalVector mom(cyl.toLocal(gmom));
216  double startR = cyl.radius() - pos.perp();
217 
218  // LogDebug("RKPropagatorInS") << "RKPropagatorInS: starting from FTS " << ts ;
219 
220 
221  // (transverse) curvature
222  double rho = ts.transverseCurvature();
223  //
224  // Straight line approximation? |rho|<1.e-10 equivalent to ~ 1um
225  // difference in transversal position at 10m.
226  //
227  if unlikely( fabs(rho)<1.e-10 ) {
228  //
229  // Instantiate auxiliary object for finding intersection.
230  // Frame-independant point and vector are created explicitely to
231  // avoid confusing gcc (refuses to compile with temporary objects
232  // in the constructor).
233  //
234 
235  StraightLineBarrelCylinderCrossing cylCrossing(gpos,gmom,propagationDirection());
236 
237  //
238  // get solution
239  //
240  std::pair<bool,double> propResult = cylCrossing.pathLength(cyl);
241  if likely( propResult.first && theVolume !=0) {
242  double s = propResult.second;
243  // point (reconverted to GlobalPoint)
244  GlobalPoint x (cylCrossing.position(s));
245  GlobalTrajectoryParameters res( x, gmom, ts.charge(), theVolume);
246  LogDebug("RKPropagatorInS") << "Straight line propagation to cylinder succeeded !!";
247  return GlobalParametersWithPath( res, s);
248  }
249 
250  //do someting
251  edm::LogError("RKPropagatorInS") <<"Straight line propagation to cylinder failed !!";
252  return GlobalParametersWithPath( );
253 
254  }
255 
256 
257  RKLocalFieldProvider field( fieldProvider(cyl));
258  // StraightLineCylinderCrossing pathLength( pos, mom, propagationDirection());
259  CartesianLorentzForce deriv(field, ts.charge());
260 
261  RKCartesianDistance dist;
262  double eps = theTolerance;
263  Solver solver;
264  double stot = 0;
265  PropagationDirection currentDirection = propagationDirection();
266 
267  RKVector start( CartesianStateAdaptor::rkstate( pos.basicVector(), mom.basicVector()));
268  int safeGuard = 0;
269  while (safeGuard++<100) {
270  CartesianStateAdaptor startState(start);
271  StraightLineCylinderCrossing pathLength( LocalPoint(startState.position()),
272  LocalVector(startState.momentum()),
273  currentDirection, eps);
274 
275  std::pair<bool,double> path = pathLength.pathLength( cyl);
276  if unlikely(!path.first) {
277  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Path length calculation to cylinder failed!"
278  << "Radius " << cyl.radius() << " pos.perp() " << LocalPoint(startState.position()).perp() ;
279  return GlobalParametersWithPath();
280  }
281 
282  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Path lenght to cylinder is " << path.second
283  << " from point (R,z) " << startState.position().perp()
284  << ", " << startState.position().z()
285  << " to R " << cyl.radius()
286  ;
287 
288 
289  double sstep = path.second;
290  if unlikely( std::abs(sstep) < eps) {
291  LogDebug("RKPropagatorInS") << "accuracy not reached, but pathLength calculation says we are there! "
292  << path.second ;
293 
294  GlobalTrajectoryParameters res( gtpFromLocal( startState.position(),
295  startState.momentum(),
296  ts.charge(), cyl));
297  return GlobalParametersWithPath( res, stot);
298  }
299 
300  LogDebug("RKPropagatorInS") << "RKPropagatorInS: Solving for " << sstep
301  << " current distance to cylinder is " << startR ;
302 
303  RKVector rkresult = solver( 0, start, sstep, deriv, dist, eps);
304  stot += sstep;
305  CartesianStateAdaptor cur( rkresult);
306  double remainingR = cyl.radius() - cur.position().perp();
307 
308  if ( fabs(remainingR) < eps) {
309  LogDebug("RKPropagatorInS") << "Accuracy reached! " << remainingR ;
310  GlobalTrajectoryParameters res( gtpFromLocal( cur.position(),
311  cur.momentum(),
312  ts.charge(), cyl));
313  return GlobalParametersWithPath( res, stot);
314  }
315 
316  start = rkresult;
317  if (remainingR * startR > 0) {
318  LogDebug("RKPropagatorInS") << "Accuracy not reached yet, trying in same direction again "
319  << remainingR ;
320  }
321  else {
322  LogDebug("RKPropagatorInS") << "Accuracy not reached yet, trying in opposite direction "
323  << remainingR ;
324  currentDirection = invertDirection( currentDirection);
325  }
326  startR = remainingR;
327  }
328 
329  edm::LogError("FailedPropagation") << " too many iterations trying to reach cylinder ";
330  return GlobalParametersWithPath();
331 }
332 
333 TrajectoryStateOnSurface
334 RKPropagatorInS::propagate(const FreeTrajectoryState& fts, const Plane& plane) const
335 {
336  return propagateWithPath( fts, plane).first;
337 }
338 
339 TrajectoryStateOnSurface
340 RKPropagatorInS::propagate( const FreeTrajectoryState& fts, const Cylinder& cyl) const
341 {
342  return propagateWithPath( fts, cyl).first;
343 }
344 
346 {
347  return new RKPropagatorInS(*this);
348 }
349 
350 GlobalTrajectoryParameters RKPropagatorInS::gtpFromLocal( const Basic3DVector<double>& lpos,
351  const Basic3DVector<double>& lmom,
352  TrackCharge ch, const Surface& surf) const
353 {
354  return GlobalTrajectoryParameters( surf.toGlobal( LocalPoint( lpos)),
355  surf.toGlobal( LocalVector( lmom)), ch, theVolume);
356 }
357 
358 RKLocalFieldProvider RKPropagatorInS::fieldProvider() const
359 {
360  return RKLocalFieldProvider( *theVolume);
361 }
362 
363 RKLocalFieldProvider RKPropagatorInS::fieldProvider( const Cylinder& cyl) const
364 {
365  return RKLocalFieldProvider( *theVolume, cyl);
366 }
367 
368 PropagationDirection RKPropagatorInS::invertDirection( PropagationDirection dir) const
369 {
370  if (dir == anyDirection) return dir;
371  return ( dir == alongMomentum ? oppositeToMomentum : alongMomentum);
372 }
373 
374 Basic3DVector<double> RKPropagatorInS::rkPosition( const GlobalPoint& pos) const
375 {
376  if (theVolume != 0) return theVolume->toLocal( pos).basicVector();
377  else return pos.basicVector();
378 }
379 
380 Basic3DVector<double> RKPropagatorInS::rkMomentum( const GlobalVector& mom) const
381 {
382  if (theVolume != 0) return theVolume->toLocal( mom).basicVector();
383  else return mom.basicVector();
384 }
385 
386 GlobalPoint RKPropagatorInS::globalPosition( const Basic3DVector<double>& pos) const
387 {
388  if (theVolume != 0) return theVolume->toGlobal( LocalPoint(pos));
389  else return GlobalPoint(pos);
390 }
391 
392 GlobalVector RKPropagatorInS::globalMomentum( const Basic3DVector<double>& mom) const
393 
394 {
395  if (theVolume != 0) return theVolume->toGlobal( LocalVector(mom));
396  else return GlobalVector(mom);
397 }
398 
400 RKPropagatorInS::gtpFromVolumeLocal( const CartesianStateAdaptor& state,
401  TrackCharge charge) const
402 {
403  return GlobalTrajectoryParameters( globalPosition(state.position()),
404  globalMomentum(state.momentum()),
405  charge, theVolume);
406 }
#define LogDebug(id)
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:114
dictionary parameters
Definition: Parameters.py:2
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
Local3DVector LocalVector
Definition: LocalVector.h:12
ROOT::Math::Plane3D::Vector Vector
Definition: EcalHitMaker.cc:29
Definition: DDAxes.h:10
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
T y() const
Definition: PV3DBase.h:63
PropagationDirection
TrackCharge charge() const
double charge(const std::vector< uint8_t > &Ampls)
Definition: Plane.h:17
tuple field
Definition: statics.py:62
#define unlikely(x)
Definition: Likely.h:21
int TrackCharge
Definition: TrackCharge.h:4
static RKSmallVector< double, 6 > rkstate(const Vector3D &pos, const Vector3D &mom)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const Vector3D & momentum() const
GlobalVector momentum() const
GlobalPoint position() const
static Plane transformPlane(const Plane &plane, const GloballyPositioned< T > &frame)
Definition: FrameChanger.h:15
string const
Definition: compareJSON.py:14
double transverseCurvature() const
return(e1-e2)*(e1-e2)+dp *dp
T perp() const
Magnitude of transverse component.
#define likely(x)
Definition: Likely.h:20
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
tuple clone
Definition: statics.py:58
dbl *** dir
Definition: mlp_gen.cc:35
Definition: DDAxes.h:10
const Vector3D & position() const
T x() const
Definition: PV3DBase.h:62
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:56
Global3DVector GlobalVector
Definition: GlobalVector.h:10
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or &quot;cross&quot; product, with a vector of same type.