Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:28

0001 #ifndef CommonDet_Propagator_H
0002 #define CommonDet_Propagator_H
0003 
0004 #include "DataFormats/TrajectorySeed/interface/PropagationDirection.h"
0005 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
0006 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0007 
0008 #include <utility>
0009 #include <memory>
0010 
0011 class Plane;
0012 class Cylinder;
0013 class Surface;
0014 class MagneticField;
0015 
0016 namespace reco {
0017   class BeamSpot;
0018 }
0019 
0020 /** Basic tool for "propagation" of trajectory states to surfaces.
0021  *  If the starting state has an error matrix the errors will be also
0022  *  propagated. If you want to propagate just the parameters,
0023  *  construct a starting state that does not have errors.
0024  *  In case of propagation failure (e.g. when the trajectory does
0025  *  not cross the destination surface) and invalid state is returned.
0026  *  Always check the returned state with isValid() before using it!
0027  *
0028  *  The propagation can be "alongMomentum" or "oppositeToMomentum"
0029  *  (see setPropagationDirection() below). The difference between the two
0030  *  is the sign of energy loss: the trajectory momentum decreases
0031  *  "alongMomentum" and increases "oppositeToMomentum".
0032  *  In both directions extrapolation errors and multiple scattering errors
0033  *  increase. Propagation "oppositeToMomentum" is convenient for
0034  *  fitting a track "backwards", sterting from the last measurement.
0035  *
0036  *  The propagator interface promises to take you to "any surface"
0037  *  but you should check the concrete propagator you are using for
0038  *  additional limitations.
0039  *
0040  *  derived classes have to implement the PropagateWithPath for Plane and Cylinder
0041  *
0042  */
0043 
0044 class Propagator {
0045 public:
0046   explicit Propagator(PropagationDirection dir = alongMomentum) : theDir(dir) {}
0047   virtual ~Propagator();
0048 
0049   template <typename STA, typename SUR>
0050   TrajectoryStateOnSurface propagate(STA const& state, SUR const& surface) const {
0051     return propagateWithPath(state, surface).first;
0052   }
0053 
0054 public:
0055   /** The methods propagateWithPath() are identical to the corresponding
0056    *  methods propagate() in what concerns the resulting
0057    *  TrajectoryStateOnSurface, but they provide in addition the
0058    *  exact path length along the trajectory.
0059    */
0060 
0061   /** Only use the generic method if the surface type (plane or cylinder)
0062    *  is not known at the calling point.
0063    */
0064   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const FreeTrajectoryState&,
0065                                                                         const Surface&) const final;
0066 
0067   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const FreeTrajectoryState&,
0068                                                                         const Plane&) const = 0;
0069 
0070   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const FreeTrajectoryState&,
0071                                                                         const Cylinder&) const = 0;
0072 
0073   /** The following three methods are equivalent to the corresponding
0074    *  methods above,
0075    *  but if the starting state is a TrajectoryStateOnSurface, it's better
0076    *  to use it as such rather than use just the FreeTrajectoryState
0077    *  part. It may help some concrete propagators.
0078    */
0079 
0080   /** Only use the generic method if the surface type (plane or cylinder)
0081    *  is not known at the calling point.
0082    */
0083   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const TrajectoryStateOnSurface& tsos,
0084                                                                         const Surface& sur) const final;
0085 
0086   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const TrajectoryStateOnSurface& tsos,
0087                                                                         const Plane& sur) const {
0088     return propagateWithPath(*tsos.freeState(), sur);
0089   }
0090 
0091   virtual std::pair<TrajectoryStateOnSurface, double> propagateWithPath(const TrajectoryStateOnSurface& tsos,
0092                                                                         const Cylinder& sur) const {
0093     return propagateWithPath(*tsos.freeState(), sur);
0094   }
0095 
0096   /// implemented by Stepping Helix
0097   //! Propagate to PCA to point given a starting point
0098   virtual std::pair<FreeTrajectoryState, double> propagateWithPath(const FreeTrajectoryState& ftsStart,
0099                                                                    const GlobalPoint& pDest) const;
0100   //! Propagate to PCA to a line (given by 2 points) given a starting point
0101   virtual std::pair<FreeTrajectoryState, double> propagateWithPath(const FreeTrajectoryState& ftsStart,
0102                                                                    const GlobalPoint& pDest1,
0103                                                                    const GlobalPoint& pDest2) const;
0104   //! Propagate to PCA to a line (given by beamSpot position and slope) given a starting point
0105   virtual std::pair<FreeTrajectoryState, double> propagateWithPath(const FreeTrajectoryState& ftsStart,
0106                                                                    const reco::BeamSpot& beamSpot) const;
0107 
0108   // this is a mess...
0109   virtual FreeTrajectoryState propagate(const FreeTrajectoryState& ftsStart, const GlobalPoint& pDest) const final {
0110     return propagateWithPath(ftsStart, pDest).first;
0111   }
0112   virtual FreeTrajectoryState propagate(const FreeTrajectoryState& ftsStart,
0113                                         const GlobalPoint& pDest1,
0114                                         const GlobalPoint& pDest2) const final {
0115     return propagateWithPath(ftsStart, pDest1, pDest2).first;
0116   }
0117   virtual FreeTrajectoryState propagate(const FreeTrajectoryState& ftsStart,
0118                                         const reco::BeamSpot& beamSpot) const final {
0119     return propagateWithPath(ftsStart, beamSpot).first;
0120   }
0121 
0122 public:
0123   /** The propagation direction can now be set for every propagator.
0124    *  There is no more distinction between unidirectional and bidirectional
0125    *  at class level. The value "anyDiriction" for PropagationDirection
0126    *  provides the functionality of the ex-BidirectionalPropagator.
0127    *  The values "alongMomentum" and "oppositeToMomentum" provide the
0128    *  functionality of the ex-UnidirectionalPropagator.
0129    */
0130   virtual void setPropagationDirection(PropagationDirection dir) { theDir = dir; }
0131 
0132   /** Returns the current value of the propagation direction.
0133    *  If you need to know the actual direction used for a given propagation
0134    *  in case "propagationDirection() == anyDirection",
0135    *  you should use propagateWithPath. A positive sign of
0136    *  path lengt means "alongMomentum", an egeative sign means
0137    *  "oppositeToMomentum".
0138    */
0139   virtual PropagationDirection propagationDirection() const final { return theDir; }
0140 
0141   /** Set the maximal change of direction (integrated along the path)
0142    *  for any single propagation.
0143    *  If reaching of the destination surface requires change of direction that exceeds
0144    *  this value the Propagator returns an invalid state.
0145    *  For example, a track may reach a forward plane after many spirals,
0146    *  which may be undesirable for a track reconstructor. Setting this value
0147    *  to pi will force the propagation to fail.
0148    *  The default value is "no limit". The method returnd true if the concrete propagator
0149    *  respects the limit, false otherwise.
0150    */
0151   virtual bool setMaxDirectionChange(float phiMax) { return false; }
0152 
0153   virtual Propagator* clone() const = 0;
0154 
0155   virtual const MagneticField* magneticField() const = 0;
0156 
0157 private:
0158   PropagationDirection theDir;
0159 };
0160 
0161 // Put here declaration of helper function, so that it is
0162 // automatically included in all proper places w/o having to add an
0163 // additional include file. Keep implementation separate, to avoid
0164 // multiple definition of the same symbol in all cc inlcuding this
0165 // file.
0166 std::unique_ptr<Propagator> SetPropagationDirection(Propagator const& iprop, PropagationDirection dir);
0167 
0168 #endif  // CommonDet_Propagator_H