Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:31

0001 #ifndef Geom_GloballyPositioned_H
0002 #define Geom_GloballyPositioned_H
0003 
0004 #include "DataFormats/GeometryVector/interface/Point3DBase.h"
0005 #include "DataFormats/GeometryVector/interface/Vector3DBase.h"
0006 #include "DataFormats/GeometryVector/interface/LocalTag.h"
0007 #include "DataFormats/GeometryVector/interface/GlobalTag.h"
0008 #include "DataFormats/GeometrySurface/interface/TkRotation.h"
0009 
0010 /** Base class for surfaces and volumes positioned in global 3D space.
0011  *  This class defines a cartesian reference frame, called in the 
0012  *  following the local frame.
0013  *  It provides position, orientation, and frame transformations for
0014  *  points and vectors.
0015  */
0016 
0017 template <class T>
0018 class GloballyPositioned {
0019 public:
0020   typedef T Scalar;
0021   typedef Point3DBase<T, GlobalTag> PositionType;
0022   typedef TkRotation<T> RotationType;
0023   typedef Point3DBase<T, GlobalTag> GlobalPoint;
0024   typedef Point3DBase<T, LocalTag> LocalPoint;
0025   typedef Vector3DBase<T, GlobalTag> GlobalVector;
0026   typedef Vector3DBase<T, LocalTag> LocalVector;
0027 
0028   static T iniPhi() { return 999.9978; }
0029   static T iniEta() { return 999.9978; }
0030 
0031   GloballyPositioned() { setCache(); }
0032   GloballyPositioned(const PositionType& pos, const RotationType& rot) : thePos(pos), theRot(rot) { setCache(); }
0033 
0034   virtual ~GloballyPositioned() {}
0035 
0036   const PositionType& position() const { return thePos; }
0037 
0038   const RotationType& rotation() const { return theRot; }
0039 
0040   T phi() const { return thePhi; }
0041   T eta() const { return theEta; }
0042 
0043   // multiply inverse is faster
0044   class ToLocal {
0045   public:
0046     ToLocal(GloballyPositioned const& frame) : thePos(frame.position()), theRot(frame.rotation().transposed()) {}
0047 
0048     LocalPoint operator()(const GlobalPoint& gp) const { return toLocal(gp); }
0049 
0050     LocalVector operator()(const GlobalVector& gv) const { return toLocal(gv); }
0051 
0052     LocalPoint toLocal(const GlobalPoint& gp) const {
0053       return LocalPoint(theRot.multiplyInverse(gp.basicVector() - thePos.basicVector()));
0054     }
0055 
0056     LocalVector toLocal(const GlobalVector& gv) const { return LocalVector(theRot.multiplyInverse(gv.basicVector())); }
0057 
0058     // private:
0059     PositionType thePos;
0060     RotationType theRot;
0061   };
0062 
0063   /** Transform a local point (i.e. a point with coordinates in the
0064    *  local frame) to the global frame
0065    */
0066   GlobalPoint toGlobal(const LocalPoint& lp) const {
0067     return GlobalPoint(rotation().multiplyInverse(lp.basicVector()) + position().basicVector());
0068   }
0069 
0070   /** Transform a local point with different float precision from the
0071    *  one of the reference frame, and return a global point with the
0072    *  same precision as the input one.
0073    */
0074   template <class U>
0075   Point3DBase<U, GlobalTag> toGlobal(const Point3DBase<U, LocalTag>& lp) const {
0076     return Point3DBase<U, GlobalTag>(rotation().multiplyInverse(lp.basicVector()) + position().basicVector());
0077   }
0078 
0079   /** Transform a local vector (i.e. a vector with coordinates in the
0080    *  local frame) to the global frame
0081    */
0082   GlobalVector toGlobal(const LocalVector& lv) const {
0083     return GlobalVector(rotation().multiplyInverse(lv.basicVector()));
0084   }
0085 
0086   /** Transform a local vector with different float precision from the
0087    *  one of the reference frame, and return a global vector with the
0088    *  same precision as the input one.
0089    */
0090   template <class U>
0091   Vector3DBase<U, GlobalTag> toGlobal(const Vector3DBase<U, LocalTag>& lv) const {
0092     return Vector3DBase<U, GlobalTag>(rotation().multiplyInverse(lv.basicVector()));
0093   }
0094 
0095   /** Transform a global point (i.e. a point with coordinates in the
0096    *  global frame) to the local frame
0097    */
0098   LocalPoint toLocal(const GlobalPoint& gp) const {
0099     return LocalPoint(rotation() * (gp.basicVector() - position().basicVector()));
0100   }
0101 
0102   /** Transform a global point with different float precision from the
0103    *  one of the reference frame, and return a local point with the
0104    *  same precision as the input one.
0105    */
0106   template <class U>
0107   Point3DBase<U, LocalTag> toLocal(const Point3DBase<U, GlobalTag>& gp) const {
0108     return Point3DBase<U, LocalTag>(rotation() * (gp.basicVector() - position().basicVector()));
0109   }
0110 
0111   /** Transform a global vector (i.e. a vector with coordinates in the
0112    *  global frame) to the local frame
0113    */
0114   LocalVector toLocal(const GlobalVector& gv) const { return LocalVector(rotation() * gv.basicVector()); }
0115 
0116   /** Transform a global vector with different float precision from the
0117    *  one of the reference frame, and return a local vector with the
0118    *  same precision as the input one.
0119    */
0120   template <class U>
0121   Vector3DBase<U, LocalTag> toLocal(const Vector3DBase<U, GlobalTag>& gv) const {
0122     return Vector3DBase<U, LocalTag>(rotation() * gv.basicVector());
0123   }
0124 
0125   /** Move the position of the frame in the global frame.  
0126    *  Useful e.g. for alignment.
0127    */
0128   void move(const GlobalVector& displacement) {
0129     thePos += displacement;
0130     setCache();
0131   }
0132 
0133   /** Rotate the frame in the global frame.
0134    *  Useful e.g. for alignment.
0135    */
0136   void rotate(const RotationType& rotation) {
0137     theRot *= rotation;
0138     setCache();
0139   }
0140 
0141 private:
0142   PositionType thePos;
0143   RotationType theRot;
0144 
0145   /*
0146   void resetCache() {
0147     if ((thePos.x() == 0.) && (thePos.y() == 0.)) {
0148       thePhi = theEta = 0.; // avoid FPE
0149     } else {
0150       thePhi = iniPhi();
0151       theEta = iniEta();
0152     }
0153   }
0154  */
0155 
0156   void setCache() {
0157     if ((thePos.x() == 0.) & (thePos.y() == 0.)) {
0158       thePhi = theEta = 0.;  // avoid FPE
0159     } else {
0160       thePhi = thePos.barePhi();
0161       theEta = thePos.eta();
0162     }
0163   }
0164 
0165   T thePhi;
0166   T theEta;
0167 };
0168 
0169 #endif