diff --git a/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignablePlaneSurface.h b/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignablePlaneSurface.h old mode 100755 new mode 100644 index 6fd87d24b995da76445da4a5a35cf00796c64948..f23a2e9e756c2f4384c50cdb418f53b1002336f2 --- a/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignablePlaneSurface.h +++ b/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignablePlaneSurface.h @@ -18,114 +18,134 @@ #include "Identifier/Identifier.h" namespace Trk { - - class Surface; - class Layer; - class TrkDetElementBase; - - - /** - @class AlignablePlaneSurface - - see base classes for more desription - - Let's denote the nominal transform as @f$ T_n @f$ and the - transform describing the local frame with respect to the global frame as @f$ T @f$, - then the methods (1), (2) and (3) yield to : - - - <b>addAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T @f$ - - - <b>setAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T_n @f$ - - - <b>setAlignableTransform(@f$ T_a @f$)</b> : @f$ T = T_a @f$ - - To avoid dependencies on GeoModel and/or InnerDetector pure Amg::Transform3D objects are used. - - @author Andreas.Salzburger@cern.ch - */ - - class AlignablePlaneSurface : public PlaneSurface, - public AlignableSurface { - - public: - /** Default Constructor - needed for pool and inherited classes */ - AlignablePlaneSurface(); - - /** Constructor with already different transform from the nominal one */ - AlignablePlaneSurface(const PlaneSurface& psf, Amg::Transform3D* alignedTransf=0); - - /** Copy Constructor */ - AlignablePlaneSurface(const AlignablePlaneSurface& psf); - - /** Destructor */ - virtual ~AlignablePlaneSurface(); - - /** -------------------------- interface from Surface ------------------ */ - - /**Assignment operator */ - AlignablePlaneSurface& operator=(const AlignablePlaneSurface& sf); - /**Equality operator*/ - bool operator==(const Surface& sf) const; - /**Implicit constructor - uses the copy constructor */ - AlignablePlaneSurface* clone() const; - - /** return associated Detector Element - forwarded from nominal Surface */ - const TrkDetElementBase* associatedDetectorElement() const; - - /** return Identifier of the associated Detector Element - forwarded from nominal Surface */ - const Identifier associatedDetectorElementIdentifier() const; - - /** return the associated Layer - forwarded from nominal Surface */ - const Layer* associatedLayer() const; - - /** -------------------------- interface from AlignableSurface ------------------ */ - - /** Get the Surface representation */ - const PlaneSurface& surfaceRepresentation() const; - - /** Get the nominal surface */ - const PlaneSurface& nominalSurface() const; - - /** Get the nominal transformation */ - const Amg::Transform3D& nominalTransform() const; - - /** Add an alignment correction on top of the actual one */ - void addAlignmentCorrection(Amg::Transform3D& corr) ; - - /** Set an alignment correction on top of the nominal one */ - void setAlignmentCorrection(Amg::Transform3D& corr) ; - - /** Set an alignment correction on top of the nominal one */ - void setAlignableTransform(Amg::Transform3D& trans) ; - - protected: - /** The pointer ro the nominal Surface */ - const PlaneSurface* m_nominalSurface; - - }; - - inline AlignablePlaneSurface* AlignablePlaneSurface::clone() const - { return new AlignablePlaneSurface(*this); } - - inline const TrkDetElementBase* AlignablePlaneSurface::associatedDetectorElement() const - { return m_nominalSurface->associatedDetectorElement(); } - - inline const Identifier AlignablePlaneSurface::associatedDetectorElementIdentifier() const - { return m_nominalSurface->associatedDetectorElementIdentifier(); } - - inline const Trk::Layer* AlignablePlaneSurface::associatedLayer() const - { return m_nominalSurface->associatedLayer(); } - - inline const PlaneSurface& AlignablePlaneSurface::surfaceRepresentation() const - { return(*this); } - - inline const PlaneSurface& AlignablePlaneSurface::nominalSurface() const - { return(*m_nominalSurface); } - - inline const Amg::Transform3D& AlignablePlaneSurface::nominalTransform() const - { return m_nominalSurface->transform(); } + +class Surface; +class Layer; +class TrkDetElementBase; + +/** + @class AlignablePlaneSurface + + see base classes for more desription + + Let's denote the nominal transform as @f$ T_n @f$ and the + transform describing the local frame with respect to the global frame as @f$ T @f$, + then the methods (1), (2) and (3) yield to : + + - <b>addAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T @f$ + + - <b>setAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T_n @f$ + + - <b>setAlignableTransform(@f$ T_a @f$)</b> : @f$ T = T_a @f$ + + To avoid dependencies on GeoModel and/or InnerDetector pure Amg::Transform3D objects are used. + + @author Andreas.Salzburger@cern.ch +*/ + +class AlignablePlaneSurface + : public PlaneSurface + , public AlignableSurface +{ + +public: + /** Default Constructor - needed for pool and inherited classes */ + AlignablePlaneSurface(); + + /** Constructor with already different transform from the nominal one */ + AlignablePlaneSurface(const PlaneSurface& psf, Amg::Transform3D* alignedTransf = 0); + + /** Copy Constructor */ + AlignablePlaneSurface(const AlignablePlaneSurface& psf); + + /** Destructor */ + virtual ~AlignablePlaneSurface(); + + /** -------------------------- interface from Surface ------------------ */ + + /**Assignment operator */ + AlignablePlaneSurface& operator=(const AlignablePlaneSurface& sf); + /**Equality operator*/ + bool operator==(const Surface& sf) const; + /**Implicit constructor - uses the copy constructor */ + AlignablePlaneSurface* clone() const; + + /** return associated Detector Element - forwarded from nominal Surface */ + const TrkDetElementBase* associatedDetectorElement() const; + + /** return Identifier of the associated Detector Element - forwarded from nominal Surface */ + const Identifier associatedDetectorElementIdentifier() const; + + /** return the associated Layer - forwarded from nominal Surface */ + const Layer* associatedLayer() const; + + /** -------------------------- interface from AlignableSurface ------------------ */ + + /** Get the Surface representation */ + const PlaneSurface& surfaceRepresentation() const; + + /** Get the nominal surface */ + const PlaneSurface& nominalSurface() const; + + /** Get the nominal transformation */ + const Amg::Transform3D& nominalTransform() const; + + /** Add an alignment correction on top of the actual one */ + void addAlignmentCorrection(Amg::Transform3D& corr); + + /** Set an alignment correction on top of the nominal one */ + void setAlignmentCorrection(Amg::Transform3D& corr); + + /** Set an alignment correction on top of the nominal one */ + void setAlignableTransform(Amg::Transform3D& trans); + +protected: + /** The pointer ro the nominal Surface */ + const PlaneSurface* m_nominalSurface; +}; + +inline AlignablePlaneSurface* +AlignablePlaneSurface::clone() const +{ + return new AlignablePlaneSurface(*this); +} + +inline const TrkDetElementBase* +AlignablePlaneSurface::associatedDetectorElement() const +{ + return m_nominalSurface->associatedDetectorElement(); +} + +inline const Identifier +AlignablePlaneSurface::associatedDetectorElementIdentifier() const +{ + return m_nominalSurface->associatedDetectorElementIdentifier(); +} + +inline const Trk::Layer* +AlignablePlaneSurface::associatedLayer() const +{ + return m_nominalSurface->associatedLayer(); +} + +inline const PlaneSurface& +AlignablePlaneSurface::surfaceRepresentation() const +{ + return (*this); +} + +inline const PlaneSurface& +AlignablePlaneSurface::nominalSurface() const +{ + return (*m_nominalSurface); +} + +inline const Amg::Transform3D& +AlignablePlaneSurface::nominalTransform() const +{ + return m_nominalSurface->transform(); +} } // end of namespace Trk #endif // TRKALIGNABLESURFACES_ALGINABLESURFACE_H - diff --git a/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignableSurface.h b/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignableSurface.h old mode 100755 new mode 100644 index 96753610bd1d7e607265464d7fffda032afed09f..7b91c2ce771b43811ee259cfc226aebb04edcafb --- a/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignableSurface.h +++ b/Tracking/TrkDetDescr/TrkAlignableSurfaces/TrkAlignableSurfaces/AlignableSurface.h @@ -12,63 +12,61 @@ #include "GeoPrimitives/GeoPrimitives.h" namespace Trk { - - class Surface; - - /** - @class AlignableSurface - - Base class of all alignable surfaces. - An AlignableSurface extends a surface of concrete type - (and has to point back to the one it is created from). - Hence only public surfaces can be used to create AlignableSurfaces. - - Let's denote the nominal transform as @f$ T_n @f$ and the - transform describing the local frame with respect to the global frame as @f$ T @f$, - then the methods (1), (2) and (3) yield to : - - - <b>addAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T @f$ - - - <b>setAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T_n @f$ - - - <b>setAlignableTransform(@f$ T_a @f$)</b> : @f$ T = T_a @f$ - - To avoid dependencies on GeoModel and/or InnerDetector pure Amg::Transform3D objects are used. - - @author Andreas.Salzburger@cern.ch - */ - - class AlignableSurface { - - public: - /** Default Constructor - needed for pool and inherited classes */ - AlignableSurface(); - - /** Destructor */ - virtual ~AlignableSurface(); - - /** Get the Surface representation */ - virtual const Surface& surfaceRepresentation() const = 0; - - /** Get the nominal surface */ - virtual const Surface& nominalSurface() const = 0; - - /** Get the nominal transformation */ - virtual const Amg::Transform3D& nominalTransform() const = 0; - - /** Add an alignment correction on top of the actual one */ - virtual void addAlignmentCorrection(Amg::Transform3D& corr) = 0; - - /** Set an alignment correction on top of the nominal one */ - virtual void setAlignmentCorrection(Amg::Transform3D& corr) = 0; - - /** Set an alignment correction on top of the nominal one */ - virtual void setAlignableTransform(Amg::Transform3D& trans) = 0; - - - }; - + +class Surface; + +/** + @class AlignableSurface + + Base class of all alignable surfaces. + An AlignableSurface extends a surface of concrete type +(and has to point back to the one it is created from). + Hence only public surfaces can be used to create AlignableSurfaces. + + Let's denote the nominal transform as @f$ T_n @f$ and the + transform describing the local frame with respect to the global frame as @f$ T @f$, + then the methods (1), (2) and (3) yield to : + + - <b>addAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T @f$ + + - <b>setAlignmentCorrection(@f$ T_c @f$)</b> : @f$ T = T_c \cot T_n @f$ + + - <b>setAlignableTransform(@f$ T_a @f$)</b> : @f$ T = T_a @f$ + + To avoid dependencies on GeoModel and/or InnerDetector pure Amg::Transform3D objects are used. + + @author Andreas.Salzburger@cern.ch +*/ + +class AlignableSurface +{ + +public: + /** Default Constructor - needed for pool and inherited classes */ + AlignableSurface(); + + /** Destructor */ + virtual ~AlignableSurface(); + + /** Get the Surface representation */ + virtual const Surface& surfaceRepresentation() const = 0; + + /** Get the nominal surface */ + virtual const Surface& nominalSurface() const = 0; + + /** Get the nominal transformation */ + virtual const Amg::Transform3D& nominalTransform() const = 0; + + /** Add an alignment correction on top of the actual one */ + virtual void addAlignmentCorrection(Amg::Transform3D& corr) = 0; + + /** Set an alignment correction on top of the nominal one */ + virtual void setAlignmentCorrection(Amg::Transform3D& corr) = 0; + + /** Set an alignment correction on top of the nominal one */ + virtual void setAlignableTransform(Amg::Transform3D& trans) = 0; +}; + } // end of namespace Trk #endif // TRKALIGNABLESURFACES_ALGINABLESURFACE_H - diff --git a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx old mode 100755 new mode 100644 index 58cabea0f6ec17f998ed7d4e2d79af2034e9b827..9b013a499a477a743b45ae8810fb5961d0c48c58 --- a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx +++ b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignablePlaneSurface.cxx @@ -10,68 +10,74 @@ #include "TrkAlignableSurfaces/AlignablePlaneSurface.h" #include <iostream> -Trk::AlignablePlaneSurface::AlignablePlaneSurface() : - Trk::PlaneSurface(), - Trk::AlignableSurface(), - m_nominalSurface(nullptr) +Trk::AlignablePlaneSurface::AlignablePlaneSurface() + : Trk::PlaneSurface() + , Trk::AlignableSurface() + , m_nominalSurface(nullptr) {} -Trk::AlignablePlaneSurface::AlignablePlaneSurface(const Trk::PlaneSurface& psf, Amg::Transform3D* htrans) : - Trk::PlaneSurface(psf), - Trk::AlignableSurface(), - m_nominalSurface(&psf) +Trk::AlignablePlaneSurface::AlignablePlaneSurface(const Trk::PlaneSurface& psf, Amg::Transform3D* htrans) + : Trk::PlaneSurface(psf) + , Trk::AlignableSurface() + , m_nominalSurface(&psf) { - if (htrans) Surface::m_transform.store(std::unique_ptr<Amg::Transform3D>(htrans)); - else Surface::m_transform.store(std::make_unique<Amg::Transform3D>(m_nominalSurface->transform())); + if (htrans) + Surface::m_transform.store(std::unique_ptr<Amg::Transform3D>(htrans)); + else + Surface::m_transform.store(std::make_unique<Amg::Transform3D>(m_nominalSurface->transform())); } -Trk::AlignablePlaneSurface::AlignablePlaneSurface(const Trk::AlignablePlaneSurface& apsf) : - Trk::PlaneSurface(apsf), - Trk::AlignableSurface(), - m_nominalSurface(apsf.m_nominalSurface) +Trk::AlignablePlaneSurface::AlignablePlaneSurface(const Trk::AlignablePlaneSurface& apsf) + : Trk::PlaneSurface(apsf) + , Trk::AlignableSurface() + , m_nominalSurface(apsf.m_nominalSurface) {} -Trk::AlignablePlaneSurface::~AlignablePlaneSurface() -{} +Trk::AlignablePlaneSurface::~AlignablePlaneSurface() {} -Trk::AlignablePlaneSurface& Trk::AlignablePlaneSurface::operator=(const Trk::AlignablePlaneSurface& apsf) +Trk::AlignablePlaneSurface& +Trk::AlignablePlaneSurface::operator=(const Trk::AlignablePlaneSurface& apsf) { - - if (this!=&apsf){ + + if (this != &apsf) { Trk::PlaneSurface::operator=(apsf); - m_nominalSurface = apsf.m_nominalSurface; + m_nominalSurface = apsf.m_nominalSurface; } return *this; -} +} -bool Trk::AlignablePlaneSurface::operator==(const Trk::Surface& sf) const +bool +Trk::AlignablePlaneSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::AlignablePlaneSurface* apsf = dynamic_cast<const Trk::AlignablePlaneSurface*>(&sf); - if (!apsf) return false; - bool transfEqual = transform().isApprox(apsf->transform()); - bool boundsEqual = (transfEqual) ? (bounds() == apsf->bounds()) : false; + if (!apsf) + return false; + bool transfEqual = transform().isApprox(apsf->transform()); + bool boundsEqual = (transfEqual) ? (bounds() == apsf->bounds()) : false; return boundsEqual; } -void Trk::AlignablePlaneSurface::addAlignmentCorrection(Amg::Transform3D& corr) +void +Trk::AlignablePlaneSurface::addAlignmentCorrection(Amg::Transform3D& corr) { - Trk::Surface::m_transform=std::make_unique<Amg::Transform3D>((*Trk::Surface::m_transform)*corr); - m_center.store(nullptr); - m_normal.store(nullptr); + Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>((*Trk::Surface::m_transform) * corr); + m_center.store(nullptr); + m_normal.store(nullptr); } -void Trk::AlignablePlaneSurface::setAlignmentCorrection(Amg::Transform3D& corr) +void +Trk::AlignablePlaneSurface::setAlignmentCorrection(Amg::Transform3D& corr) { - Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>((m_nominalSurface->transform())*corr); + Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>((m_nominalSurface->transform()) * corr); m_center.store(nullptr); m_normal.store(nullptr); } -void Trk::AlignablePlaneSurface::setAlignableTransform(Amg::Transform3D& trans) +void +Trk::AlignablePlaneSurface::setAlignableTransform(Amg::Transform3D& trans) { - Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>(trans); + Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>(trans); m_center.store(nullptr); - m_normal.store(nullptr); + m_normal.store(nullptr); } - diff --git a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignableSurface.cxx b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignableSurface.cxx old mode 100755 new mode 100644 index 8e09bb29d824a5adfca1e9c0dee815605fcd0611..7a534c5197e44220ffc63de11c49430ce2a9f4e4 --- a/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignableSurface.cxx +++ b/Tracking/TrkDetDescr/TrkAlignableSurfaces/src/AlignableSurface.cxx @@ -9,9 +9,6 @@ // Trk #include "TrkAlignableSurfaces/AlignableSurface.h" -Trk::AlignableSurface::AlignableSurface() -{} - -Trk::AlignableSurface::~AlignableSurface() -{} +Trk::AlignableSurface::AlignableSurface() {} +Trk::AlignableSurface::~AlignableSurface() {} diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingCylinderSurface.h b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingCylinderSurface.h old mode 100755 new mode 100644 index aa9eb06d5ccd2498e16819f16e1124cfe8c95737..95f1ed4907510a62bfc486b490394a4250dbf246 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingCylinderSurface.h +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingCylinderSurface.h @@ -9,10 +9,10 @@ #ifndef TRKGEOMETRYSURFACES_SLIDINGCYLINDERSURFACE_H #define TRKGEOMETRYSURFACES_SLIDINGCYLINDERSURFACE_H -//Trk -#include "TrkSurfaces/CylinderSurface.h" +// Trk #include "TrkDetDescrUtils/BinUtility.h" #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/CylinderSurface.h" // Geometry & Math #include "GeoPrimitives/GeoPrimitives.h" @@ -21,73 +21,75 @@ class Identifier; namespace Trk { - /** - @class SlidingCylinderSurface - Class for a Calo CylinderSurface with variable depth in the ATLAS detector. - The variable depth is stored as a binned vector of radial corrections. - Local eta bin is defined by base curvature and z position in base transform ( corrected for misalignement ). - It inherits from CylinderSurface. - - @author Sarka.Todorova@cern.ch +/** + @class SlidingCylinderSurface + Class for a Calo CylinderSurface with variable depth in the ATLAS detector. + The variable depth is stored as a binned vector of radial corrections. + Local eta bin is defined by base curvature and z position in base transform ( corrected for misalignement ). + It inherits from CylinderSurface. + + @author Sarka.Todorova@cern.ch + */ + +class SlidingCylinderSurface : public CylinderSurface +{ +public: + /** Default Constructor - needed for persistency*/ + SlidingCylinderSurface(); + + /** Copy Constructor*/ + SlidingCylinderSurface(const SlidingCylinderSurface& psf); + + /** Copy Constructor with shift*/ + SlidingCylinderSurface(const SlidingCylinderSurface& psf, const Amg::Transform3D& transf); + + /**Constructor */ + SlidingCylinderSurface(const CylinderSurface& surf, + Trk::BinUtility* bu = 0, + const std::vector<float>* offset = 0, + Amg::Transform3D* align = 0); + + /**Destructor*/ + virtual ~SlidingCylinderSurface(); + + /**Assignment operator*/ + SlidingCylinderSurface& operator=(const SlidingCylinderSurface& psf); + + /**Equality operator*/ + bool operator==(const Surface& sf) const; + + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk = true, double tol1 = 0., double tol2 = 0.) const; + + /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ + void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const; + + /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ + bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const; - class SlidingCylinderSurface : public CylinderSurface { - public: - /** Default Constructor - needed for persistency*/ - SlidingCylinderSurface(); - - /** Copy Constructor*/ - SlidingCylinderSurface(const SlidingCylinderSurface& psf); - - /** Copy Constructor with shift*/ - SlidingCylinderSurface(const SlidingCylinderSurface& psf, const Amg::Transform3D& transf); - - /**Constructor */ - SlidingCylinderSurface(const CylinderSurface& surf, Trk::BinUtility* bu=0, const std::vector<float>* offset=0, - Amg::Transform3D* align=0); - - /**Destructor*/ - virtual ~SlidingCylinderSurface(); - - /**Assignment operator*/ - SlidingCylinderSurface& operator=(const SlidingCylinderSurface& psf); - - /**Equality operator*/ - bool operator==(const Surface& sf) const; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk=true, double tol1=0., double tol2=0.) const; - - /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ - void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const; - - /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const; - - /** fast straight line distance evaluation to Surface */ - DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const; - - /** fast straight line distance evaluation to Surface - with bound option*/ - DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const; - - /**This method allows access to the bin utility*/ - const Trk::BinUtility* binUtility() const { return m_etaBin; } - - /**This method allows access to the radial offset values*/ - const std::vector<float>* offset() const { return m_depth; } - - /** Return properly formatted class name for screen output */ - std::string name() const { return "Trk::SlidingCylinderSurface"; } - - protected: - const std::vector<float>* m_depth; - Trk::BinUtility* m_etaBin; - Amg::Transform3D* m_align; - }; - -} // end of namespace + /** fast straight line distance evaluation to Surface */ + DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const; -#endif // TRKGEOMETRYSURFACES_SLIDINGCYLINDERSURFACE_H + /** fast straight line distance evaluation to Surface - with bound option*/ + DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool Bound) const; + + /**This method allows access to the bin utility*/ + const Trk::BinUtility* binUtility() const { return m_etaBin; } + /**This method allows access to the radial offset values*/ + const std::vector<float>* offset() const { return m_depth; } + /** Return properly formatted class name for screen output */ + std::string name() const { return "Trk::SlidingCylinderSurface"; } + +protected: + const std::vector<float>* m_depth; + Trk::BinUtility* m_etaBin; + Amg::Transform3D* m_align; +}; + +} // end of namespace + +#endif // TRKGEOMETRYSURFACES_SLIDINGCYLINDERSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingDiscSurface.h b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingDiscSurface.h old mode 100755 new mode 100644 index 9f9bf6258af9c755042a050b6765a2d837c253fc..f58e29790d995020bd3f98ffb6263fd01d11e948 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingDiscSurface.h +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SlidingDiscSurface.h @@ -9,128 +9,134 @@ #ifndef TRKGEOMETRYSURFACES_SLIDINGDISCSURFACE_H #define TRKGEOMETRYSURFACES_SLIDINGDISCSURFACE_H -//Trk -#include "TrkSurfaces/DiscSurface.h" -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkSurfaces/NoBounds.h" +// Trk #include "TrkDetDescrUtils/BinUtility.h" #include "TrkEventPrimitives/LocalParameters.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/DiscSurface.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/SurfaceBounds.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; namespace Trk { - class DiscBounds; - class TrkDetElementBase; - class LocalParameters; - - template<int DIM, class T, class S> class ParametersT; - - /** - @class SlidingDiscSurface - Class for a Calo DiscSurface with variable depth in the ATLAS detector. - The variable depth is stored as a binned vector of shifts of the center along the normal. - Local eta bin is defined by locR and z position for base transform ( corrected for misalignement ). - Inherits from DiscSurface. - - @author sarka.todorova@cern.ch +class DiscBounds; +class TrkDetElementBase; +class LocalParameters; + +template<int DIM, class T, class S> +class ParametersT; + +/** + @class SlidingDiscSurface + Class for a Calo DiscSurface with variable depth in the ATLAS detector. + The variable depth is stored as a binned vector of shifts of the center along the normal. + Local eta bin is defined by locR and z position for base transform ( corrected for misalignement ). + Inherits from DiscSurface. + + @author sarka.todorova@cern.ch + */ + +class SlidingDiscSurface : public DiscSurface +{ + +public: + /**Default Constructor*/ + SlidingDiscSurface(); + + /**Constructor */ + SlidingDiscSurface(DiscSurface& surf, + Trk::BinUtility* bu = 0, + const std::vector<float>* offset = 0, + Amg::Transform3D* align = 0); + + /**Constructor for DiscSegment from DetectorElement*/ + // DiscSurface(const TrkDetElementBase& dmnt); + + /**Copy Constructor*/ + SlidingDiscSurface(const SlidingDiscSurface& psf); + + /**Copy Constructor with shift*/ + SlidingDiscSurface(const SlidingDiscSurface& psf, const Amg::Transform3D& transf); + + /**Constructor */ + SlidingDiscSurface(const DiscSurface& surf, + Trk::BinUtility* bu = 0, + const std::vector<float>* offset = 0, + Amg::Transform3D* align = 0); + + /**Destructor*/ + virtual ~SlidingDiscSurface(); + + /**Assignement operator*/ + SlidingDiscSurface& operator=(const SlidingDiscSurface& dsf); + + /**Equality operator*/ + bool operator==(const Surface& sf) const; + + /** Virtual constructor*/ + virtual SlidingDiscSurface* clone() const; + + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk = true, double tol1 = 0., double tol2 = 0.) const; + + /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ + void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const; + + /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ + bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const; - class SlidingDiscSurface : public DiscSurface { - - public: - /**Default Constructor*/ - SlidingDiscSurface(); - - /**Constructor */ - SlidingDiscSurface(DiscSurface& surf, Trk::BinUtility* bu=0, const std::vector<float>* offset=0, - Amg::Transform3D* align=0); - - /**Constructor for DiscSegment from DetectorElement*/ - //DiscSurface(const TrkDetElementBase& dmnt); - - /**Copy Constructor*/ - SlidingDiscSurface(const SlidingDiscSurface& psf); - - /**Copy Constructor with shift*/ - SlidingDiscSurface(const SlidingDiscSurface& psf, const Amg::Transform3D& transf); - - /**Constructor */ - SlidingDiscSurface(const DiscSurface& surf, Trk::BinUtility* bu=0, const std::vector<float>* offset=0, - Amg::Transform3D* align=0); - - /**Destructor*/ - virtual ~SlidingDiscSurface(); - - /**Assignement operator*/ - SlidingDiscSurface& operator=(const SlidingDiscSurface&dsf); - - /**Equality operator*/ - bool operator==(const Surface& sf) const; - - /** Virtual constructor*/ - virtual SlidingDiscSurface* clone() const; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk=true, double tol1=0., double tol2=0.) const; - - /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ - void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const; - - /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const; - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceDir is to provide the closest forward solution - - <b>mathematical motivation:</b> - - the equation of the plane is given by: <br> - @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> - where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, - @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible points - on the plane.<br> - Given a line with:<br> - @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> - the solution for @f$ u @f$ can be written: - @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> - If the denominator is 0 then the line lies: - - either in the plane - - perpenticular to the normal of the plane - */ - - /** fast straight line distance evaluation to Surface */ - DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const; - - /** fast straight line distance evaluation to Surface - with bound option*/ - DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const; - - /**This method allows access to the bin utility*/ - const Trk::BinUtility* binUtility() const { return m_etaBin; } - - /**This method allows access to the radial offset values*/ - const std::vector<float>* offset() const { return m_depth; } - - - /** Return properly formatted class name for screen output */ - std::string name() const { return "Trk::SlidingDiscSurface"; } - - protected: //!< data members - const std::vector<float>* m_depth; - Trk::BinUtility* m_etaBin; - Amg::Transform3D* m_align; - }; - - inline SlidingDiscSurface* SlidingDiscSurface::clone() const - { return new SlidingDiscSurface(*this); } - -} // end of namespace + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceDir is to provide the closest forward solution -#endif // TRKSURFACES_SLIDINGDISCSURFACE_H + <b>mathematical motivation:</b> + + the equation of the plane is given by: <br> + @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> + where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, + @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible + points on the plane.<br> Given a line with:<br> + @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> + the solution for @f$ u @f$ can be written: + @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> + If the denominator is 0 then the line lies: + - either in the plane + - perpenticular to the normal of the plane + */ + /** fast straight line distance evaluation to Surface */ + DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const; + /** fast straight line distance evaluation to Surface - with bound option*/ + DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool Bound) const; + + /**This method allows access to the bin utility*/ + const Trk::BinUtility* binUtility() const { return m_etaBin; } + + /**This method allows access to the radial offset values*/ + const std::vector<float>* offset() const { return m_depth; } + + /** Return properly formatted class name for screen output */ + std::string name() const { return "Trk::SlidingDiscSurface"; } + +protected: //!< data members + const std::vector<float>* m_depth; + Trk::BinUtility* m_etaBin; + Amg::Transform3D* m_align; +}; + +inline SlidingDiscSurface* +SlidingDiscSurface::clone() const +{ + return new SlidingDiscSurface(*this); +} + +} // end of namespace + +#endif // TRKSURFACES_SLIDINGDISCSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedCylinderSurface.h b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedCylinderSurface.h old mode 100755 new mode 100644 index 04ab57d6d2f242fc4ae211f9f005b0a8e10ee7cb..15c897631148786354e0b3a8f69f12892a1bc397 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedCylinderSurface.h +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedCylinderSurface.h @@ -9,10 +9,10 @@ #ifndef TRKGEOMETRYSURFACES_SUBTRACTEDCYLINDERSURFACE_H #define TRKGEOMETRYSURFACES_SUBTRACTEDCYLINDERSURFACE_H -//Trk -#include "TrkSurfaces/CylinderSurface.h" +// Trk #include "TrkDetDescrUtils/AreaExcluder.h" #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/CylinderSurface.h" // Geometry & Math #include "GeoPrimitives/GeoPrimitives.h" @@ -21,79 +21,86 @@ class Identifier; namespace Trk { - /** - @class SubtractedCylinderSurface - Class for a cylinder subtracted/shared surface in the ATLAS detector. - It owns its surface bounds and subtracted volume. - - @author Sarka.Todorova@cern.ch - */ - - class SubtractedCylinderSurface : public CylinderSurface { - public: - /** Default Constructor - needed for persistency*/ - SubtractedCylinderSurface(); - - /** Copy Constructor*/ - SubtractedCylinderSurface(const SubtractedCylinderSurface& psf); - - /** Copy Constructor with shift*/ - SubtractedCylinderSurface(const SubtractedCylinderSurface& psf, const Amg::Transform3D& transf); - - /** Constructor */ - SubtractedCylinderSurface(const CylinderSurface& cs, AreaExcluder* vol, bool shared); - - /**Destructor*/ - virtual ~SubtractedCylinderSurface(); - - /**Assignment operator*/ - SubtractedCylinderSurface& operator=(const SubtractedCylinderSurface& psf); - - /**Equality operator*/ - bool operator==(const Surface& sf) const; - - /** This method indicates the subtraction mode */ - bool shared() const; - - /**This method calls the inside() method of the Bounds*/ - bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const; - - /**This method allows access to the subtracted part*/ - SharedObject<AreaExcluder> subtractedVolume() const; - - /** Return properly formatted class name for screen output */ - std::string name() const { return "Trk::SubtractedCylinderSurface"; } - - protected: - SharedObject<AreaExcluder> m_subtrVol; - bool m_shared; - }; - - inline bool SubtractedCylinderSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const - { - // no subtracted volume exists - if (!m_subtrVol.get()) return (this->bounds().inside(locpos,tol1,tol2)); - // subtracted volume exists, needs to be checked - double rCyl = bounds().r(); - double phiPos = locpos[Trk::locRPhi]/rCyl; - const Amg::Vector3D gp(rCyl*cos(phiPos),rCyl*sin(phiPos),locpos[Trk::locZ]); - - bool inside_shared(this->bounds().inside(locpos,tol1,tol2) && m_subtrVol.get()->inside(gp,0.) ); - bool inside(this->bounds().inside(locpos,tol1,tol2) && !m_subtrVol.get()->inside(gp,0.) ); - - if (m_shared) return inside_shared; - return inside; - } - - inline bool SubtractedCylinderSurface::shared() const { return m_shared;} - - inline SharedObject< AreaExcluder> SubtractedCylinderSurface::subtractedVolume() const - { - return m_subtrVol; - } - -} // end of namespace +/** + @class SubtractedCylinderSurface + Class for a cylinder subtracted/shared surface in the ATLAS detector. + It owns its surface bounds and subtracted volume. -#endif // TRKGEOMETRYSURFACES_SUBTRACTEDCYLINDERSURFACE_H + @author Sarka.Todorova@cern.ch + */ + +class SubtractedCylinderSurface : public CylinderSurface +{ +public: + /** Default Constructor - needed for persistency*/ + SubtractedCylinderSurface(); + + /** Copy Constructor*/ + SubtractedCylinderSurface(const SubtractedCylinderSurface& psf); + + /** Copy Constructor with shift*/ + SubtractedCylinderSurface(const SubtractedCylinderSurface& psf, const Amg::Transform3D& transf); + + /** Constructor */ + SubtractedCylinderSurface(const CylinderSurface& cs, AreaExcluder* vol, bool shared); + + /**Destructor*/ + virtual ~SubtractedCylinderSurface(); + + /**Assignment operator*/ + SubtractedCylinderSurface& operator=(const SubtractedCylinderSurface& psf); + + /**Equality operator*/ + bool operator==(const Surface& sf) const; + + /** This method indicates the subtraction mode */ + bool shared() const; + /**This method calls the inside() method of the Bounds*/ + bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const; + /**This method allows access to the subtracted part*/ + SharedObject<AreaExcluder> subtractedVolume() const; + + /** Return properly formatted class name for screen output */ + std::string name() const { return "Trk::SubtractedCylinderSurface"; } + +protected: + SharedObject<AreaExcluder> m_subtrVol; + bool m_shared; +}; + +inline bool +SubtractedCylinderSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + // no subtracted volume exists + if (!m_subtrVol.get()) + return (this->bounds().inside(locpos, tol1, tol2)); + // subtracted volume exists, needs to be checked + double rCyl = bounds().r(); + double phiPos = locpos[Trk::locRPhi] / rCyl; + const Amg::Vector3D gp(rCyl * cos(phiPos), rCyl * sin(phiPos), locpos[Trk::locZ]); + + bool inside_shared(this->bounds().inside(locpos, tol1, tol2) && m_subtrVol.get()->inside(gp, 0.)); + bool inside(this->bounds().inside(locpos, tol1, tol2) && !m_subtrVol.get()->inside(gp, 0.)); + + if (m_shared) + return inside_shared; + return inside; +} + +inline bool +SubtractedCylinderSurface::shared() const +{ + return m_shared; +} + +inline SharedObject<AreaExcluder> +SubtractedCylinderSurface::subtractedVolume() const +{ + return m_subtrVol; +} + +} // end of namespace + +#endif // TRKGEOMETRYSURFACES_SUBTRACTEDCYLINDERSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedDiscSurface.h b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedDiscSurface.h old mode 100755 new mode 100644 index 7ee3baa0aa89192729728765a7ddb51d756b4b8c..7a9d79912ef656a566f87dd29bac8bd7d47fe2ff --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedDiscSurface.h +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedDiscSurface.h @@ -9,10 +9,10 @@ #ifndef TRKGEOMETRYSURFACES_SUBTRACTEDDISCSURFACE_H #define TRKGEOMETRYSURFACES_SUBTRACTEDDISCSURFACE_H -//Trk -#include "TrkSurfaces/DiscSurface.h" +// Trk #include "TrkDetDescrUtils/AreaExcluder.h" #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/DiscSurface.h" // Geometry & Maths #include "GeoPrimitives/GeoPrimitives.h" @@ -20,78 +20,85 @@ class MsgStream; namespace Trk { - - /** - @class SubtractedDiscSurface - Class for a planar subtracted/shared surface in the ATLAS detector. - It owns its surface bounds and subtracted volume. - - @author Sarka.Todorova@cern.ch - */ - - class SubtractedDiscSurface : public DiscSurface { - public: - /** Default Constructor - needed for persistency*/ - SubtractedDiscSurface(); - - /** Copy Constructor*/ - SubtractedDiscSurface(const SubtractedDiscSurface& psf); - - /** Copy Constructor*/ - SubtractedDiscSurface(const SubtractedDiscSurface& psf, const Amg::Transform3D& shift); - - /** Constructor */ - SubtractedDiscSurface(const DiscSurface& ps , AreaExcluder* vol, bool shared); - - /**Destructor*/ - virtual ~SubtractedDiscSurface(); - - /**Assignment operator*/ - SubtractedDiscSurface& operator=(const SubtractedDiscSurface& psf); - - /**Equality operator*/ - bool operator==(const Surface& sf) const; - - /** This method indicates the subtraction mode */ - bool shared() const; - - /**This method calls the inside() method of the Bounds*/ - bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const; - - /**This method allows access to the subtracted part*/ - SharedObject<AreaExcluder> subtractedVolume() const; - - /** Return properly formatted class name for screen output */ - std::string name() const { return "Trk::SubtractedDiscSurface"; } - - protected: - SharedObject<AreaExcluder> m_subtrVol; - bool m_shared; - }; - - inline bool SubtractedDiscSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const - { - // no subtracted Volume exists - if (!m_subtrVol.get()) return (this->bounds().inside(locpos,tol1,tol2)); - // subtracted Volume exists, needs to be checked - double rPos = locpos[Trk::locR]; - double phiPos = locpos[Trk::locPhi]; - Amg::Vector3D gp(rPos*cos(phiPos),rPos*sin(phiPos),0.); - if (m_shared) return (this->bounds().inside(locpos,tol1,tol2) && m_subtrVol.get()->inside(gp,0.) ); - bool in(this->bounds().inside(locpos,tol1,tol2) && !m_subtrVol.get()->inside(gp,0.)) ; - - return in; - } - - inline bool SubtractedDiscSurface::shared() const { return m_shared;} - - inline SharedObject<AreaExcluder> SubtractedDiscSurface::subtractedVolume() const - { - return m_subtrVol; - } - -} // end of namespace -#endif // TRKGEOMETRYSURFACES_SUBTRACTEDDISCSURFACE_H +/** + @class SubtractedDiscSurface + Class for a planar subtracted/shared surface in the ATLAS detector. + It owns its surface bounds and subtracted volume. + + @author Sarka.Todorova@cern.ch + */ + +class SubtractedDiscSurface : public DiscSurface +{ +public: + /** Default Constructor - needed for persistency*/ + SubtractedDiscSurface(); + + /** Copy Constructor*/ + SubtractedDiscSurface(const SubtractedDiscSurface& psf); + + /** Copy Constructor*/ + SubtractedDiscSurface(const SubtractedDiscSurface& psf, const Amg::Transform3D& shift); + + /** Constructor */ + SubtractedDiscSurface(const DiscSurface& ps, AreaExcluder* vol, bool shared); + + /**Destructor*/ + virtual ~SubtractedDiscSurface(); + + /**Assignment operator*/ + SubtractedDiscSurface& operator=(const SubtractedDiscSurface& psf); + + /**Equality operator*/ + bool operator==(const Surface& sf) const; + /** This method indicates the subtraction mode */ + bool shared() const; + /**This method calls the inside() method of the Bounds*/ + bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const; + + /**This method allows access to the subtracted part*/ + SharedObject<AreaExcluder> subtractedVolume() const; + + /** Return properly formatted class name for screen output */ + std::string name() const { return "Trk::SubtractedDiscSurface"; } + +protected: + SharedObject<AreaExcluder> m_subtrVol; + bool m_shared; +}; + +inline bool +SubtractedDiscSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + // no subtracted Volume exists + if (!m_subtrVol.get()) + return (this->bounds().inside(locpos, tol1, tol2)); + // subtracted Volume exists, needs to be checked + double rPos = locpos[Trk::locR]; + double phiPos = locpos[Trk::locPhi]; + Amg::Vector3D gp(rPos * cos(phiPos), rPos * sin(phiPos), 0.); + if (m_shared) + return (this->bounds().inside(locpos, tol1, tol2) && m_subtrVol.get()->inside(gp, 0.)); + bool in(this->bounds().inside(locpos, tol1, tol2) && !m_subtrVol.get()->inside(gp, 0.)); + + return in; +} + +inline bool +SubtractedDiscSurface::shared() const +{ + return m_shared; +} + +inline SharedObject<AreaExcluder> +SubtractedDiscSurface::subtractedVolume() const +{ + return m_subtrVol; +} + +} // end of namespace + +#endif // TRKGEOMETRYSURFACES_SUBTRACTEDDISCSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedPlaneSurface.h b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedPlaneSurface.h old mode 100755 new mode 100644 index 8f4f8e5cf2aedc2e5e4999e2fb11c776dd290e8b..f089c6e90529ed216b6af031556a993a32ed6375 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedPlaneSurface.h +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/TrkGeometrySurfaces/SubtractedPlaneSurface.h @@ -9,9 +9,9 @@ #ifndef TRKGEOMETRYSURFACES_SUBTRACTEDPLANESURFACE_H #define TRKGEOMETRYSURFACES_SUBTRACTEDPLANESURFACE_H -//Trk -#include "TrkSurfaces/PlaneSurface.h" +// Trk #include "TrkDetDescrUtils/AreaExcluder.h" +#include "TrkSurfaces/PlaneSurface.h" // Geometry & Maths #include "GeoPrimitives/GeoPrimitives.h" @@ -19,76 +19,83 @@ class MsgStream; class Identifier; namespace Trk { - - /** - @class SubtractedPlaneSurface - Class for a planar subtracted/shared surface in the ATLAS detector. - It owns its surface bounds and subtracted volume. - - @author Sarka.Todorova@cern.ch - */ - - class SubtractedPlaneSurface : public PlaneSurface { - public: - /** Default Constructor - needed for persistency*/ - SubtractedPlaneSurface(); - - /** Copy Constructor*/ - SubtractedPlaneSurface(const SubtractedPlaneSurface& psf); - - /** Copy Constructor with shift*/ - SubtractedPlaneSurface(const SubtractedPlaneSurface& psf, const Amg::Transform3D& transf); - - /** Constructor */ - SubtractedPlaneSurface(const PlaneSurface& ps , AreaExcluder* vol, bool shared); - - /**Destructor*/ - virtual ~SubtractedPlaneSurface(); - - /**Assignment operator*/ - SubtractedPlaneSurface& operator=(const SubtractedPlaneSurface& psf); - - /**Equality operator*/ - bool operator==(const Surface& sf) const; - - /** This method indicates the subtraction mode */ - bool shared() const; - - /**This method calls the inside() method of the Bounds*/ - bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const; - - /**This method allows access to the subtracted part*/ - SharedObject<AreaExcluder> subtractedVolume() const; - - /** Return properly formatted class name for screen output */ - std::string name() const { return "Trk::SubtractedPlaneSurface"; } - - protected: - SharedObject<AreaExcluder> m_subtrVol; - bool m_shared; - }; - - inline bool SubtractedPlaneSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const - { - // no subtracted volume exists - if (!m_subtrVol.get()) return (this->bounds().inside(locpos,tol1,tol2)); - // subtracted volume exists, needs to be checked - Amg::Vector3D gp(locpos.x(),locpos.y(),0.); - if (m_shared) return (this->bounds().inside(locpos,tol1,tol2) && m_subtrVol.get()->inside(gp,0.) ); - bool in(this->bounds().inside(locpos,tol1,tol2) && !m_subtrVol.get()->inside(gp,0.)) ; - - return in; - } - - inline bool SubtractedPlaneSurface::shared() const { return m_shared;} - - inline SharedObject<AreaExcluder> SubtractedPlaneSurface::subtractedVolume() const - { - return m_subtrVol; - } - -} // end of namespace -#endif // TRKGEOMETRYSURFACES_SUBTRACTEDPLANESURFACE_H +/** + @class SubtractedPlaneSurface + Class for a planar subtracted/shared surface in the ATLAS detector. + It owns its surface bounds and subtracted volume. + + @author Sarka.Todorova@cern.ch + */ + +class SubtractedPlaneSurface : public PlaneSurface +{ +public: + /** Default Constructor - needed for persistency*/ + SubtractedPlaneSurface(); + + /** Copy Constructor*/ + SubtractedPlaneSurface(const SubtractedPlaneSurface& psf); + + /** Copy Constructor with shift*/ + SubtractedPlaneSurface(const SubtractedPlaneSurface& psf, const Amg::Transform3D& transf); + + /** Constructor */ + SubtractedPlaneSurface(const PlaneSurface& ps, AreaExcluder* vol, bool shared); + + /**Destructor*/ + virtual ~SubtractedPlaneSurface(); + + /**Assignment operator*/ + SubtractedPlaneSurface& operator=(const SubtractedPlaneSurface& psf); + + /**Equality operator*/ + bool operator==(const Surface& sf) const; + /** This method indicates the subtraction mode */ + bool shared() const; + /**This method calls the inside() method of the Bounds*/ + bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const; + + /**This method allows access to the subtracted part*/ + SharedObject<AreaExcluder> subtractedVolume() const; + + /** Return properly formatted class name for screen output */ + std::string name() const { return "Trk::SubtractedPlaneSurface"; } + +protected: + SharedObject<AreaExcluder> m_subtrVol; + bool m_shared; +}; + +inline bool +SubtractedPlaneSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + // no subtracted volume exists + if (!m_subtrVol.get()) + return (this->bounds().inside(locpos, tol1, tol2)); + // subtracted volume exists, needs to be checked + Amg::Vector3D gp(locpos.x(), locpos.y(), 0.); + if (m_shared) + return (this->bounds().inside(locpos, tol1, tol2) && m_subtrVol.get()->inside(gp, 0.)); + bool in(this->bounds().inside(locpos, tol1, tol2) && !m_subtrVol.get()->inside(gp, 0.)); + + return in; +} + +inline bool +SubtractedPlaneSurface::shared() const +{ + return m_shared; +} + +inline SharedObject<AreaExcluder> +SubtractedPlaneSurface::subtractedVolume() const +{ + return m_subtrVol; +} + +} // end of namespace + +#endif // TRKGEOMETRYSURFACES_SUBTRACTEDPLANESURFACE_H diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx old mode 100755 new mode 100644 index 9054a8372f409ed851557fd0b9e84df25b8bf284..deea3f6f984cbc8889c333671b6deaaafa7c4d37 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingCylinderSurface.cxx @@ -8,50 +8,51 @@ // Trk #include "TrkGeometrySurfaces/SlidingCylinderSurface.h" -#include "TrkSurfaces/CylinderBounds.h" #include "TrkEventPrimitives/LocalParameters.h" +#include "TrkSurfaces/CylinderBounds.h" - -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -//Eigen +// Eigen #include "GeoPrimitives/GeoPrimitives.h" // default constructor -Trk::SlidingCylinderSurface::SlidingCylinderSurface() : - Trk::CylinderSurface(), - m_depth(), - m_etaBin(), - m_align() +Trk::SlidingCylinderSurface::SlidingCylinderSurface() + : Trk::CylinderSurface() + , m_depth() + , m_etaBin() + , m_align() {} // copy constructor -Trk::SlidingCylinderSurface::SlidingCylinderSurface(const SlidingCylinderSurface& dsf) : - Trk::CylinderSurface(dsf), - m_depth(new std::vector<float>(*(dsf.m_depth))), - m_etaBin(dsf.m_etaBin->clone()), - m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) +Trk::SlidingCylinderSurface::SlidingCylinderSurface(const SlidingCylinderSurface& dsf) + : Trk::CylinderSurface(dsf) + , m_depth(new std::vector<float>(*(dsf.m_depth))) + , m_etaBin(dsf.m_etaBin->clone()) + , m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) {} // copy constructor with shift -Trk::SlidingCylinderSurface::SlidingCylinderSurface(const SlidingCylinderSurface& dsf, const Amg::Transform3D& transf ) : - Trk::CylinderSurface(dsf, transf), - m_depth(new std::vector<float>(*(dsf.m_depth))), - m_etaBin(dsf.m_etaBin->clone()), - m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) +Trk::SlidingCylinderSurface::SlidingCylinderSurface(const SlidingCylinderSurface& dsf, const Amg::Transform3D& transf) + : Trk::CylinderSurface(dsf, transf) + , m_depth(new std::vector<float>(*(dsf.m_depth))) + , m_etaBin(dsf.m_etaBin->clone()) + , m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) {} // constructor -Trk::SlidingCylinderSurface::SlidingCylinderSurface(const Trk::CylinderSurface& dsf, Trk::BinUtility* bu, - const std::vector<float>* offset, Amg::Transform3D* align) : - Trk::CylinderSurface(dsf), - m_depth(offset), - m_etaBin(bu), - m_align(align) +Trk::SlidingCylinderSurface::SlidingCylinderSurface(const Trk::CylinderSurface& dsf, + Trk::BinUtility* bu, + const std::vector<float>* offset, + Amg::Transform3D* align) + : Trk::CylinderSurface(dsf) + , m_depth(offset) + , m_etaBin(bu) + , m_align(align) {} // destructor (will call destructor from base class which deletes objects) @@ -62,151 +63,163 @@ Trk::SlidingCylinderSurface::~SlidingCylinderSurface() delete m_align; } -Trk::SlidingCylinderSurface& Trk::SlidingCylinderSurface::operator=(const SlidingCylinderSurface& dsf) +Trk::SlidingCylinderSurface& +Trk::SlidingCylinderSurface::operator=(const SlidingCylinderSurface& dsf) { - if (this!=&dsf){ - Trk::CylinderSurface::operator=(dsf); - delete m_depth; - m_depth = new std::vector<float>(*(dsf.m_depth)); - delete m_etaBin; - m_etaBin = dsf.m_etaBin->clone(); - delete m_align; - m_align = (dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : nullptr); + if (this != &dsf) { + Trk::CylinderSurface::operator=(dsf); + delete m_depth; + m_depth = new std::vector<float>(*(dsf.m_depth)); + delete m_etaBin; + m_etaBin = dsf.m_etaBin->clone(); + delete m_align; + m_align = (dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : nullptr); } return *this; } -bool Trk::SlidingCylinderSurface::operator==(const Trk::Surface& sf) const +bool +Trk::SlidingCylinderSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::SlidingCylinderSurface* dsf = dynamic_cast<const Trk::SlidingCylinderSurface*>(&sf); - if (!dsf) return false; - if (this==dsf) return true; - bool transfEqual(transform().isApprox(dsf->transform(),10e-8)); + if (!dsf) + return false; + if (this == dsf) + return true; + bool transfEqual(transform().isApprox(dsf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == dsf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == dsf->bounds()) : false; return boundsEqual; } -void Trk::SlidingCylinderSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +void +Trk::SlidingCylinderSurface::localToGlobal(const Amg::Vector2D& locpos, + const Amg::Vector3D&, + Amg::Vector3D& glopos) const { // create the position in the local 3d frame - double r0 = bounds().r(); - double phi0 = locpos[Trk::locRPhi]/r0; - Amg::Vector3D loc3D0(r0*cos(phi0),r0*sin(phi0),locpos[Trk::locZ]); + double r0 = bounds().r(); + double phi0 = locpos[Trk::locRPhi] / r0; + Amg::Vector3D loc3D0(r0 * cos(phi0), r0 * sin(phi0), locpos[Trk::locZ]); // correct for alignment, retrieve offset correction - Amg::Transform3D t0 = m_align ? m_align->inverse()*transform() : transform(); - float offset = m_depth ? (*m_depth)[m_etaBin->bin(t0*loc3D0)] : 0.; - double r = r0+offset; - double phi = locpos[Trk::locRPhi]/r; - Amg::Vector3D loc3Dframe(r*cos(phi),r*sin(phi), locpos[Trk::locZ]); + Amg::Transform3D t0 = m_align ? m_align->inverse() * transform() : transform(); + float offset = m_depth ? (*m_depth)[m_etaBin->bin(t0 * loc3D0)] : 0.; + double r = r0 + offset; + double phi = locpos[Trk::locRPhi] / r; + Amg::Vector3D loc3Dframe(r * cos(phi), r * sin(phi), locpos[Trk::locZ]); // transport it to the globalframe - glopos = Trk::Surface::transform()*loc3Dframe; + glopos = Trk::Surface::transform() * loc3Dframe; } /** local<->global transformation in case of polar local coordinates */ -bool Trk::SlidingCylinderSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +bool +Trk::SlidingCylinderSurface::globalToLocal(const Amg::Vector3D& glopos, + const Amg::Vector3D&, + Amg::Vector2D& locpos) const { - // get the transform & transform global position into cylinder frame - // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform - double radius = 0.; - double inttol = bounds().r()*0.0001; - if ( inttol < 0.01) inttol = 0.01; - // realign to find local eta bin - Amg::Vector3D loc3D0= m_align ? (m_align->inverse()*glopos) : glopos; - float offset = (*m_depth)[m_etaBin->bin(loc3D0)]; - // do the transformation or not - if (Trk::Surface::m_transform) { - const Amg::Transform3D& surfaceTrans = transform(); - Amg::Transform3D inverseTrans(surfaceTrans.inverse()); - Amg::Vector3D loc3Dframe(inverseTrans*glopos); - locpos = Amg::Vector2D((bounds().r()+offset)*loc3Dframe.phi(), loc3Dframe.z()); - radius = loc3Dframe.perp(); - } else { - locpos = Amg::Vector2D((bounds().r()+offset)*glopos.phi(), glopos.z()); - radius = glopos.perp(); - } - // return true or false - return (( fabs(radius - bounds().r() - offset) > inttol) ? false : true ); + // get the transform & transform global position into cylinder frame + // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform + double radius = 0.; + double inttol = bounds().r() * 0.0001; + if (inttol < 0.01) + inttol = 0.01; + // realign to find local eta bin + Amg::Vector3D loc3D0 = m_align ? (m_align->inverse() * glopos) : glopos; + float offset = (*m_depth)[m_etaBin->bin(loc3D0)]; + // do the transformation or not + if (Trk::Surface::m_transform) { + const Amg::Transform3D& surfaceTrans = transform(); + Amg::Transform3D inverseTrans(surfaceTrans.inverse()); + Amg::Vector3D loc3Dframe(inverseTrans * glopos); + locpos = Amg::Vector2D((bounds().r() + offset) * loc3Dframe.phi(), loc3Dframe.z()); + radius = loc3Dframe.perp(); + } else { + locpos = Amg::Vector2D((bounds().r() + offset) * glopos.phi(), glopos.z()); + radius = glopos.perp(); + } + // return true or false + return ((fabs(radius - bounds().r() - offset) > inttol) ? false : true); } - -bool Trk::SlidingCylinderSurface::isOnSurface(const Amg::Vector3D& glopo, - Trk::BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::SlidingCylinderSurface::isOnSurface(const Amg::Vector3D& glopo, + Trk::BoundaryCheck bchk, + double tol1, + double tol2) const { - Amg::Vector3D loc3D0 = m_align ? m_align->inverse()*glopo : glopo; - Amg::Vector3D loc3Dframe = m_transform ? (transform().inverse())*glopo : glopo; + Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * glopo : glopo; + Amg::Vector3D loc3Dframe = m_transform ? (transform().inverse()) * glopo : glopo; float offset = (*m_depth)[m_etaBin->bin(loc3D0)]; // recalculate r to match bounds - Amg::Vector3D loc3Dbase((loc3Dframe.perp()-offset)*cos(loc3Dframe.phi()), - (loc3Dframe.perp()-offset)*sin(loc3Dframe.phi()), - loc3Dframe.z()); - - return ( bchk ? bounds().inside3D(loc3Dbase,tol1,tol2) : true ); + Amg::Vector3D loc3Dbase((loc3Dframe.perp() - offset) * cos(loc3Dframe.phi()), + (loc3Dframe.perp() - offset) * sin(loc3Dframe.phi()), + loc3Dframe.z()); + + return (bchk ? bounds().inside3D(loc3Dbase, tol1, tol2) : true); } /** distance to surface */ -Trk::DistanceSolution Trk::SlidingCylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::SlidingCylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { double tol = 0.001; // retrieve localEta bin using current position - Amg::Vector3D loc3D0 = m_align ? m_align->inverse()*pos : pos; // used to retrieve localEta bin + Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * pos : pos; // used to retrieve localEta bin float offset = m_depth ? (*m_depth)[m_etaBin->bin(loc3D0)] : 0.; - const Amg::Vector3D& X = center(); //point - const Amg::Vector3D& S = normal(); //vector + const Amg::Vector3D& X = center(); // point + const Amg::Vector3D& S = normal(); // vector - double radius = bounds().r()+offset; - double sp = pos.dot(S); - double sc = X.dot(S); - double dp = dir.dot(S); - Amg::Vector3D dx = X-pos-(sc-sp)*S ; //vector - Amg::Vector3D ax = dir-dp*S; //vector + double radius = bounds().r() + offset; + double sp = pos.dot(S); + double sc = X.dot(S); + double dp = dir.dot(S); + Amg::Vector3D dx = X - pos - (sc - sp) * S; // vector + Amg::Vector3D ax = dir - dp * S; // vector - double A = ax.dot(ax); // size of projected direction (squared) - double B = ax.dot(dx); // dot product (->cos angle) - double C = dx.dot(dx); // distance to axis (squared) - double currDist = radius-sqrt(C); + double A = ax.dot(ax); // size of projected direction (squared) + double B = ax.dot(dx); // dot product (->cos angle) + double C = dx.dot(dx); // distance to axis (squared) + double currDist = radius - sqrt(C); - if (A==0.) { // direction parallel to cylinder axis - if ( fabs(currDist) < tol ) { - return Trk::DistanceSolution(1,0.,true,0.); // solution at surface + if (A == 0.) { // direction parallel to cylinder axis + if (fabs(currDist) < tol) { + return Trk::DistanceSolution(1, 0., true, 0.); // solution at surface } else { - return Trk::DistanceSolution(0,currDist,true,0.); // point of closest approach without intersection + return Trk::DistanceSolution(0, currDist, true, 0.); // point of closest approach without intersection } } // minimal distance to cylinder axis - double rmin = C - B*B/A < 0. ? 0. : sqrt(C - B*B/A); + double rmin = C - B * B / A < 0. ? 0. : sqrt(C - B * B / A); - if ( rmin > radius ) { // no intersection - double first = B/A; - return Trk::DistanceSolution(0,currDist,true,first); // point of closest approach without intersection + if (rmin > radius) { // no intersection + double first = B / A; + return Trk::DistanceSolution(0, currDist, true, first); // point of closest approach without intersection } else { - if ( fabs(rmin - radius) < tol ) { // tangential 'intersection' - return double solution - double first = B/A; - return Trk::DistanceSolution(2, currDist,true,first,first); + if (fabs(rmin - radius) < tol) { // tangential 'intersection' - return double solution + double first = B / A; + return Trk::DistanceSolution(2, currDist, true, first, first); } else { - double first = B/A - sqrt((radius-rmin)*(radius+rmin)/A); - double second = B/A + sqrt((radius-rmin)*(radius+rmin)/A); - if ( first >= 0. ) { - return Trk::DistanceSolution(2,currDist,true,first,second); - } else if ( second <= 0. ) { - return Trk::DistanceSolution(2,currDist,true,second,first); - } else { // inside cylinder - return Trk::DistanceSolution(2,currDist,true,second,first); + double first = B / A - sqrt((radius - rmin) * (radius + rmin) / A); + double second = B / A + sqrt((radius - rmin) * (radius + rmin) / A); + if (first >= 0.) { + return Trk::DistanceSolution(2, currDist, true, first, second); + } else if (second <= 0.) { + return Trk::DistanceSolution(2, currDist, true, second, first); + } else { // inside cylinder + return Trk::DistanceSolution(2, currDist, true, second, first); } } } } -Trk::DistanceSolution Trk::SlidingCylinderSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool /*bound*/) const +Trk::DistanceSolution +Trk::SlidingCylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool /*bound*/) const { - return straightLineDistanceEstimate(pos,dir); + return straightLineDistanceEstimate(pos, dir); } - - diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingDiscSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingDiscSurface.cxx old mode 100755 new mode 100644 index a50827c4960939cb566e1c441c4f3ee548969ef9..bf04e137498982ced15a74b93ba9d63d09be132b --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingDiscSurface.cxx +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SlidingDiscSurface.cxx @@ -8,52 +8,53 @@ // Trk #include "TrkGeometrySurfaces/SlidingDiscSurface.h" -#include "TrkSurfaces/DiscBounds.h" #include "TrkEventPrimitives/LocalParameters.h" +#include "TrkSurfaces/DiscBounds.h" - -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -//Eigen +// Eigen #include "GeoPrimitives/GeoPrimitives.h" const Trk::NoBounds Trk::DiscSurface::s_boundless; // default constructor -Trk::SlidingDiscSurface::SlidingDiscSurface() : - Trk::DiscSurface(), - m_depth(), - m_etaBin(), - m_align() +Trk::SlidingDiscSurface::SlidingDiscSurface() + : Trk::DiscSurface() + , m_depth() + , m_etaBin() + , m_align() {} // copy constructor -Trk::SlidingDiscSurface::SlidingDiscSurface(const SlidingDiscSurface& dsf) : - Trk::DiscSurface(dsf), - m_depth(new std::vector<float>(*(dsf.m_depth))), - m_etaBin(dsf.m_etaBin->clone()), - m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) +Trk::SlidingDiscSurface::SlidingDiscSurface(const SlidingDiscSurface& dsf) + : Trk::DiscSurface(dsf) + , m_depth(new std::vector<float>(*(dsf.m_depth))) + , m_etaBin(dsf.m_etaBin->clone()) + , m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) {} // copy constructor with shift -Trk::SlidingDiscSurface::SlidingDiscSurface(const SlidingDiscSurface& dsf, const Amg::Transform3D& transf ) : - Trk::DiscSurface(dsf, transf), - m_depth(new std::vector<float>(*(dsf.m_depth))), - m_etaBin(dsf.m_etaBin->clone()), - m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) +Trk::SlidingDiscSurface::SlidingDiscSurface(const SlidingDiscSurface& dsf, const Amg::Transform3D& transf) + : Trk::DiscSurface(dsf, transf) + , m_depth(new std::vector<float>(*(dsf.m_depth))) + , m_etaBin(dsf.m_etaBin->clone()) + , m_align(dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : 0) {} // constructor -Trk::SlidingDiscSurface::SlidingDiscSurface(const Trk::DiscSurface& dsf, Trk::BinUtility* bu, - const std::vector<float>* offset, Amg::Transform3D* align) : - Trk::DiscSurface(dsf), - m_depth(offset), - m_etaBin(bu), - m_align(align) +Trk::SlidingDiscSurface::SlidingDiscSurface(const Trk::DiscSurface& dsf, + Trk::BinUtility* bu, + const std::vector<float>* offset, + Amg::Transform3D* align) + : Trk::DiscSurface(dsf) + , m_depth(offset) + , m_etaBin(bu) + , m_align(align) {} // destructor (will call destructor from base class which deletes objects) @@ -64,106 +65,110 @@ Trk::SlidingDiscSurface::~SlidingDiscSurface() delete m_align; } -Trk::SlidingDiscSurface& Trk::SlidingDiscSurface::operator=(const SlidingDiscSurface& dsf) +Trk::SlidingDiscSurface& +Trk::SlidingDiscSurface::operator=(const SlidingDiscSurface& dsf) { - if (this!=&dsf){ - Trk::DiscSurface::operator=(dsf); - delete m_depth; - m_depth = new std::vector<float>(*(dsf.m_depth)); - delete m_etaBin; - m_etaBin = dsf.m_etaBin->clone(); - delete m_align; - m_align = dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : nullptr; + if (this != &dsf) { + Trk::DiscSurface::operator=(dsf); + delete m_depth; + m_depth = new std::vector<float>(*(dsf.m_depth)); + delete m_etaBin; + m_etaBin = dsf.m_etaBin->clone(); + delete m_align; + m_align = dsf.m_align ? new Amg::Transform3D(*dsf.m_align) : nullptr; } return *this; } -bool Trk::SlidingDiscSurface::operator==(const Trk::Surface& sf) const +bool +Trk::SlidingDiscSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::SlidingDiscSurface* dsf = dynamic_cast<const Trk::SlidingDiscSurface*>(&sf); - if (!dsf) return false; - if (this==dsf) return true; - bool transfEqual(transform().isApprox(dsf->transform(),10e-8)); + if (!dsf) + return false; + if (this == dsf) + return true; + bool transfEqual(transform().isApprox(dsf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == dsf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == dsf->bounds()) : false; return boundsEqual; } -void Trk::SlidingDiscSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +void +Trk::SlidingDiscSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const { // create the position in the local 3d frame - Amg::Vector3D loc3D0(locpos[Trk::locR]*cos(locpos[Trk::locPhi]), - locpos[Trk::locR]*sin(locpos[Trk::locPhi]), - 0.); + Amg::Vector3D loc3D0(locpos[Trk::locR] * cos(locpos[Trk::locPhi]), locpos[Trk::locR] * sin(locpos[Trk::locPhi]), 0.); // correct for alignment, retrieve offset correction - Amg::Transform3D t0 = m_align ? m_align->inverse()*transform() : transform(); - float offset = m_depth ? (*m_depth)[m_etaBin->bin(t0*loc3D0)] : 0.; - Amg::Vector3D loc3Dframe(locpos[Trk::locR]*cos(locpos[Trk::locPhi]), - locpos[Trk::locR]*sin(locpos[Trk::locPhi]), - offset); + Amg::Transform3D t0 = m_align ? m_align->inverse() * transform() : transform(); + float offset = m_depth ? (*m_depth)[m_etaBin->bin(t0 * loc3D0)] : 0.; + Amg::Vector3D loc3Dframe( + locpos[Trk::locR] * cos(locpos[Trk::locPhi]), locpos[Trk::locR] * sin(locpos[Trk::locPhi]), offset); // transport it to the globalframe - glopos = Trk::Surface::transform()*loc3Dframe; + glopos = Trk::Surface::transform() * loc3Dframe; } /** local<->global transformation in case of polar local coordinates */ -bool Trk::SlidingDiscSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +bool +Trk::SlidingDiscSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const { - Amg::Vector3D loc3D0 = m_align ? m_align->inverse()*glopos : glopos; // used to retrieve localEta bin - Amg::Vector3D loc3Dframe(Trk::Surface::transform().inverse()*glopos); - locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi() ); - return ( ( fabs(loc3Dframe.z()-(*m_depth)[m_etaBin->bin(loc3D0)]) > s_onSurfaceTolerance ) ? false : true ); + Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * glopos : glopos; // used to retrieve localEta bin + Amg::Vector3D loc3Dframe(Trk::Surface::transform().inverse() * glopos); + locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()); + return ((fabs(loc3Dframe.z() - (*m_depth)[m_etaBin->bin(loc3D0)]) > s_onSurfaceTolerance) ? false : true); } - -bool Trk::SlidingDiscSurface::isOnSurface(const Amg::Vector3D& glopo, - Trk::BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::SlidingDiscSurface::isOnSurface(const Amg::Vector3D& glopo, + Trk::BoundaryCheck bchk, + double tol1, + double tol2) const { - Amg::Vector3D loc3D0 = m_align ? m_align->inverse()*glopo : glopo; // used to retrieve localEta bin - Amg::Vector3D loc3Dframe = (transform().inverse())*glopo; + Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * glopo : glopo; // used to retrieve localEta bin + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopo; float offset = (*m_depth)[m_etaBin->bin(loc3D0)]; - if ( fabs(loc3Dframe.z()-offset) > (s_onSurfaceTolerance+tol1) ) return false; - return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe.perp(),loc3Dframe.phi()),tol1,tol2) : true); + if (fabs(loc3Dframe.z() - offset) > (s_onSurfaceTolerance + tol1)) + return false; + return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()), tol1, tol2) : true); } /** distance to surface, calculated within localEta bin only */ -Trk::DistanceSolution Trk::SlidingDiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::SlidingDiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { double tol = 0.001; // retrieve localEta bin using current position - Amg::Vector3D loc3D0 = m_align ? m_align->inverse()*pos : pos; // used to retrieve localEta bin + Amg::Vector3D loc3D0 = m_align ? m_align->inverse() * pos : pos; // used to retrieve localEta bin float offset = (*m_depth)[m_etaBin->bin(loc3D0)]; // slide surface - Amg::Vector3D N = normal(); - Amg::Vector3D C = center()+ offset*N; + Amg::Vector3D N = normal(); + Amg::Vector3D C = center() + offset * N; double S = C.dot(N); - double b = S < 0. ? -1 : 1 ; - double A = b* dir.dot(N); - double d = (pos-C).dot(N); // distance to surface - - if(A==0.) { // direction parallel to surface - if ( fabs(d)<tol ) { - return Trk::DistanceSolution(1,0.,true,0.); + double b = S < 0. ? -1 : 1; + double A = b * dir.dot(N); + double d = (pos - C).dot(N); // distance to surface + + if (A == 0.) { // direction parallel to surface + if (fabs(d) < tol) { + return Trk::DistanceSolution(1, 0., true, 0.); } else { - return Trk::DistanceSolution(0,d,true,0.); + return Trk::DistanceSolution(0, d, true, 0.); } } - double D = b*(S-(pos.dot(N)))/A; - - return Trk::DistanceSolution(1,d,true,D); + double D = b * (S - (pos.dot(N))) / A; + + return Trk::DistanceSolution(1, d, true, D); } - -Trk::DistanceSolution Trk::SlidingDiscSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool /*bound*/) const +Trk::DistanceSolution +Trk::SlidingDiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool /*bound*/) const { - return straightLineDistanceEstimate(pos,dir); + return straightLineDistanceEstimate(pos, dir); } - - diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedCylinderSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedCylinderSurface.cxx old mode 100755 new mode 100644 index 79cdde3dddbf33d5a95af5b068516be903898ccd..204dd7d598b496b12e4e2e3e3690f654be294d93 --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedCylinderSurface.cxx +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedCylinderSurface.cxx @@ -8,60 +8,64 @@ // Trk #include "TrkGeometrySurfaces/SubtractedCylinderSurface.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> // default constructor -Trk::SubtractedCylinderSurface::SubtractedCylinderSurface() : - Trk::CylinderSurface(), - m_subtrVol(), - m_shared(true) +Trk::SubtractedCylinderSurface::SubtractedCylinderSurface() + : Trk::CylinderSurface() + , m_subtrVol() + , m_shared(true) {} // copy constructor -Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const SubtractedCylinderSurface& psf) : - Trk::CylinderSurface(psf), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const SubtractedCylinderSurface& psf) + : Trk::CylinderSurface(psf) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // copy constructor with shift -Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const SubtractedCylinderSurface& psf, const Amg::Transform3D& transf) : - Trk::CylinderSurface(psf, transf), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const SubtractedCylinderSurface& psf, + const Amg::Transform3D& transf) + : Trk::CylinderSurface(psf, transf) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // constructor -Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const Trk::CylinderSurface& ps, AreaExcluder* vol, bool shared) : - Trk::CylinderSurface(ps), - m_subtrVol(Trk::SharedObject<Trk::AreaExcluder>(vol)), - m_shared(shared) +Trk::SubtractedCylinderSurface::SubtractedCylinderSurface(const Trk::CylinderSurface& ps, + AreaExcluder* vol, + bool shared) + : Trk::CylinderSurface(ps) + , m_subtrVol(Trk::SharedObject<Trk::AreaExcluder>(vol)) + , m_shared(shared) {} // destructor (will call destructor from base class which deletes objects) -Trk::SubtractedCylinderSurface::~SubtractedCylinderSurface() -{} +Trk::SubtractedCylinderSurface::~SubtractedCylinderSurface() {} -Trk::SubtractedCylinderSurface& Trk::SubtractedCylinderSurface::operator=(const Trk::SubtractedCylinderSurface& psf){ +Trk::SubtractedCylinderSurface& +Trk::SubtractedCylinderSurface::operator=(const Trk::SubtractedCylinderSurface& psf) +{ - if (this!=&psf){ + if (this != &psf) { Trk::CylinderSurface::operator=(psf); m_subtrVol = psf.m_subtrVol; m_shared = psf.m_shared; } return *this; - } -bool Trk::SubtractedCylinderSurface::operator==(const Trk::Surface& sf) const +bool +Trk::SubtractedCylinderSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::SubtractedCylinderSurface* scsf = dynamic_cast<const Trk::SubtractedCylinderSurface*>(&sf); - if (!scsf) return false; + if (!scsf) + return false; bool surfaceEqual = Trk::CylinderSurface::operator==(sf); - bool sharedEqual = (surfaceEqual) ? (shared() == scsf->shared()) : false; + bool sharedEqual = (surfaceEqual) ? (shared() == scsf->shared()) : false; return sharedEqual; } - diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedDiscSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedDiscSurface.cxx old mode 100755 new mode 100644 index 7daaa066353dbaf6d70ccfa67b9671a8da2039cd..7e83811a55d24a26b9d4ad55267a8a9e13c6510d --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedDiscSurface.cxx +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedDiscSurface.cxx @@ -8,63 +8,63 @@ // Trk #include "TrkGeometrySurfaces/SubtractedDiscSurface.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> // default constructor -Trk::SubtractedDiscSurface::SubtractedDiscSurface() : - Trk::DiscSurface(), - m_subtrVol(), - m_shared(true) +Trk::SubtractedDiscSurface::SubtractedDiscSurface() + : Trk::DiscSurface() + , m_subtrVol() + , m_shared(true) {} // copy constructor -Trk::SubtractedDiscSurface::SubtractedDiscSurface(const SubtractedDiscSurface& psf) : - Trk::DiscSurface(psf), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedDiscSurface::SubtractedDiscSurface(const SubtractedDiscSurface& psf) + : Trk::DiscSurface(psf) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // copy constructor with shift -Trk::SubtractedDiscSurface::SubtractedDiscSurface(const SubtractedDiscSurface& psf, const Amg::Transform3D& shift) : - Trk::DiscSurface(psf,shift), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedDiscSurface::SubtractedDiscSurface(const SubtractedDiscSurface& psf, const Amg::Transform3D& shift) + : Trk::DiscSurface(psf, shift) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // constructor -Trk::SubtractedDiscSurface::SubtractedDiscSurface(const Trk::DiscSurface& ps, AreaExcluder* vol, bool shared) : - Trk::DiscSurface(ps), - m_subtrVol(Trk::SharedObject<AreaExcluder>(vol)), - m_shared(shared) +Trk::SubtractedDiscSurface::SubtractedDiscSurface(const Trk::DiscSurface& ps, AreaExcluder* vol, bool shared) + : Trk::DiscSurface(ps) + , m_subtrVol(Trk::SharedObject<AreaExcluder>(vol)) + , m_shared(shared) {} // destructor (will call destructor from base class which deletes objects) -Trk::SubtractedDiscSurface::~SubtractedDiscSurface() -{} +Trk::SubtractedDiscSurface::~SubtractedDiscSurface() {} + +Trk::SubtractedDiscSurface& +Trk::SubtractedDiscSurface::operator=(const Trk::SubtractedDiscSurface& psf) +{ -Trk::SubtractedDiscSurface& Trk::SubtractedDiscSurface::operator=(const Trk::SubtractedDiscSurface& psf){ - - if (this!=&psf){ + if (this != &psf) { Trk::DiscSurface::operator=(psf); m_subtrVol = psf.m_subtrVol; m_shared = psf.m_shared; } return *this; +} -} - -bool Trk::SubtractedDiscSurface::operator==(const Trk::Surface& sf) const +bool +Trk::SubtractedDiscSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::SubtractedDiscSurface* sdsf = dynamic_cast<const Trk::SubtractedDiscSurface*>(&sf); - if (!sdsf) return false; + if (!sdsf) + return false; bool surfaceEqual = Trk::DiscSurface::operator==(sf); - bool sharedEqual = (surfaceEqual) ? (shared() == sdsf->shared()) : false; + bool sharedEqual = (surfaceEqual) ? (shared() == sdsf->shared()) : false; return sharedEqual; } - - diff --git a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedPlaneSurface.cxx b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedPlaneSurface.cxx old mode 100755 new mode 100644 index 2093b9ca2b9ebbe110b5ea71208a216884996436..2863e3000431f4aa9c684c031ebb57bddfb6ad4b --- a/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedPlaneSurface.cxx +++ b/Tracking/TrkDetDescr/TrkGeometrySurfaces/src/SubtractedPlaneSurface.cxx @@ -8,63 +8,63 @@ // Trk #include "TrkGeometrySurfaces/SubtractedPlaneSurface.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> // default constructor -Trk::SubtractedPlaneSurface::SubtractedPlaneSurface() : - Trk::PlaneSurface(), - m_subtrVol(), - m_shared(true) +Trk::SubtractedPlaneSurface::SubtractedPlaneSurface() + : Trk::PlaneSurface() + , m_subtrVol() + , m_shared(true) {} // copy constructor -Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const SubtractedPlaneSurface& psf) : - Trk::PlaneSurface(psf), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const SubtractedPlaneSurface& psf) + : Trk::PlaneSurface(psf) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // copy constructor with shift -Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const SubtractedPlaneSurface& psf, const Amg::Transform3D& transf) : - Trk::PlaneSurface(psf, transf), - m_subtrVol(psf.m_subtrVol), - m_shared(psf.m_shared) +Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const SubtractedPlaneSurface& psf, const Amg::Transform3D& transf) + : Trk::PlaneSurface(psf, transf) + , m_subtrVol(psf.m_subtrVol) + , m_shared(psf.m_shared) {} // constructor -Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const Trk::PlaneSurface& ps, AreaExcluder* vol, bool shared) : - Trk::PlaneSurface(ps), - m_subtrVol(vol), - m_shared(shared) +Trk::SubtractedPlaneSurface::SubtractedPlaneSurface(const Trk::PlaneSurface& ps, AreaExcluder* vol, bool shared) + : Trk::PlaneSurface(ps) + , m_subtrVol(vol) + , m_shared(shared) {} // destructor (will call destructor from base class which deletes objects) -Trk::SubtractedPlaneSurface::~SubtractedPlaneSurface() -{} +Trk::SubtractedPlaneSurface::~SubtractedPlaneSurface() {} + +Trk::SubtractedPlaneSurface& +Trk::SubtractedPlaneSurface::operator=(const Trk::SubtractedPlaneSurface& psf) +{ -Trk::SubtractedPlaneSurface& Trk::SubtractedPlaneSurface::operator=(const Trk::SubtractedPlaneSurface& psf){ - - if (this!=&psf){ + if (this != &psf) { Trk::PlaneSurface::operator=(psf); m_subtrVol = psf.m_subtrVol; m_shared = psf.m_shared; } return *this; +} -} - -bool Trk::SubtractedPlaneSurface::operator==(const Trk::Surface& sf) const +bool +Trk::SubtractedPlaneSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::SubtractedPlaneSurface* spsf = dynamic_cast<const Trk::SubtractedPlaneSurface*>(&sf); - if (!spsf) return false; - bool surfaceEqual = Trk::PlaneSurface::operator==(sf); - bool sharedEqual = (surfaceEqual) ? (shared() == spsf->shared()) : false; - return sharedEqual; + if (!spsf) + return false; + bool surfaceEqual = Trk::PlaneSurface::operator==(sf); + bool sharedEqual = (surfaceEqual) ? (shared() == spsf->shared()) : false; + return sharedEqual; } - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/AnnulusBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/AnnulusBounds.h index b1d71864a4f86472f9e9a573c032d7bf1c139ef5..ec185ab0baf80d6f20dbf4a3f6cb9bdb25e91b76 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/AnnulusBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/AnnulusBounds.h @@ -9,8 +9,6 @@ #ifndef TRKSURFACES_ANNULUSBOUNDS_H #define TRKSURFACES_ANNULUSBOUNDS_H - - #include "TrkSurfaces/SurfaceBounds.h" //#include "TrkEventPrimitives/ParamDefs.h" //#include <math.h> @@ -21,246 +19,249 @@ class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON +#ifdef TRKDETDESCR_USEFLOATPRECISON typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class AnnulusBounds - Bounds for a annulus-like, planar Surface. - - @internal - @image html AnnulusBounds.gif - @endinternal - <br> - - @todo can be speed optimized, inner radius check in inside() can be optimized - - @author Marcin.Wolter@cern.ch - */ - - class AnnulusBounds : public SurfaceBounds { - - public: - /** @enum BoundValues - for readability */ - enum BoundValues { - bv_minR = 0, - bv_maxR = 1, - bv_R = 2, - bv_phi = 3, - bv_phiS = 4, - bv_length = 5 - }; - - /**Default Constructor, needed for persistency*/ - AnnulusBounds(); - - /**Constructor for AnnulusBounds*/ - AnnulusBounds(double minR, double maxR, double R, double phi, double phiS); - - - - /**Copy constructor*/ - AnnulusBounds(const AnnulusBounds& annbo) = default; - - /**Destructor*/ - virtual ~AnnulusBounds(); - - /**Virtual constructor*/ - virtual AnnulusBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::Annulus; } - - /**Assignment operator*/ - AnnulusBounds& operator=(const AnnulusBounds& sbo) = default; - - /**Equality operator*/ - bool operator==(const SurfaceBounds& annbo) const override; - - /**This method returns the smaller radius*/ - double minR() const; - - /**This method returns the bigger radius*/ - double maxR() const; - - /**This method returns the radius of a tilt*/ - double R() const; - - /**This method returns the opening angle*/ - double phi() const; - - /**This method returns the tilt angle*/ - double phiS() const; - - - - - /**This method returns the maximal extension on the local plane*/ - virtual double r() const override; - - /**This method returns the opening angle alpha in point A (negative local phi) */ -// double alpha() const; - - /**This method returns the opening angle beta in point B (positive local phi) */ -// double beta() const; - - /** The orientation of the Trapezoid is according to the figure above, - in words: the shorter of the two parallel sides of the trapezoid intersects - with the negative @f$ y @f$ - axis of the local frame. - - <br> - The cases are:<br> - (0) @f$ y @f$ or @f$ x @f$ bounds are 0 || 0<br> - (1) LocalPosition is outside @f$ y @f$ bounds <br> - (2) LocalPosition is inside @f$ y @f$ bounds, but outside maximum @f$ x @f$ bounds <br> - (3) LocalPosition is inside @f$ y @f$ bounds AND inside minimum @f$ x @f$ bounds <br> - (4) LocalPosition is inside @f$ y @f$ bounds AND inside maximum @f$ x @f$ bounds, so that - it depends on the @f$ eta @f$ coordinate - (5) LocalPosition fails test of (4) <br> - - The inside check is done using single equations of straight lines and one has to take care if a point - lies on the positive @f$ x @f$ half area(I) or the negative one(II). Denoting @f$ |x_{min}| @f$ and - @f$ | x_{max} | @f$ as \c minHalfX respectively \c maxHalfX, such as @f$ | y_{H} | @f$ as \c halfY, - the equations for the straing lines in (I) and (II) can be written as:<br> - <br> - - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> - - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> - <br> - where @f$ \kappa_{I} = - \kappa_{II} = 2 \frac{y_{H}}{x_{max} - x_{min}} @f$ <br> - and @f$ \delta_{I} = \delta_{II} = - \frac{1}{2}\kappa_{I}(x_{max} + x_{min}) @f$ */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! */ - - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - -// bool m_forceCovEllipse; - - - /** isAbove() method for checking whether a point lies above or under a straight line */ - - bool isAbove(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const; - - - bool isRight(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const; - - bool isLeft(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const; - - - // check whether an ellipse intersects a line - bool EllipseIntersectLine(const Amg::Vector2D& locpo, double h, double k, - double x1 , double y1 , double x2 , double y2) const; - - - /** Distance to line */ - double distanceToLine(const Amg::Vector2D& locpo, - std::vector<TDD_real_t> P1, - std::vector<TDD_real_t> P2) const; - - /** Distance to arc */ - double distanceToArc(const Amg::Vector2D& locpo, - double R, std::vector<TDD_real_t> sL, std::vector<TDD_real_t> sR ) const; - - /** Circle and line intersection **/ - std::vector<double> circleLineIntersection(double R, double k, double d) const; - - - - std::vector<TDD_real_t> m_boundValues; - - TDD_real_t m_maxYout; - TDD_real_t m_minYout; - TDD_real_t m_maxXout; - TDD_real_t m_minXout; - - TDD_real_t m_maxYin; - TDD_real_t m_minYin; - TDD_real_t m_maxXin; - TDD_real_t m_minXin; - - TDD_real_t m_k_L; - TDD_real_t m_k_R; - TDD_real_t m_d_L; - TDD_real_t m_d_R; - - std::vector<TDD_real_t> m_solution_L_min; - std::vector<TDD_real_t> m_solution_L_max; - std::vector<TDD_real_t> m_solution_R_min; - std::vector<TDD_real_t> m_solution_R_max; - - - +/** + @class AnnulusBounds + Bounds for a annulus-like, planar Surface. + + @internal + @image html AnnulusBounds.gif + @endinternal + <br> + + @todo can be speed optimized, inner radius check in inside() can be optimized + + @author Marcin.Wolter@cern.ch + */ + +class AnnulusBounds : public SurfaceBounds +{ + +public: + /** @enum BoundValues - for readability */ + enum BoundValues + { + bv_minR = 0, + bv_maxR = 1, + bv_R = 2, + bv_phi = 3, + bv_phiS = 4, + bv_length = 5 }; - inline AnnulusBounds* AnnulusBounds::clone() const { return new AnnulusBounds(*this); } - - inline double AnnulusBounds::minR() const { return m_boundValues[AnnulusBounds::bv_minR]; } - - inline double AnnulusBounds::maxR() const { return m_boundValues[AnnulusBounds::bv_maxR]; } + /**Default Constructor, needed for persistency*/ + AnnulusBounds(); + + /**Constructor for AnnulusBounds*/ + AnnulusBounds(double minR, double maxR, double R, double phi, double phiS); + + /**Copy constructor*/ + AnnulusBounds(const AnnulusBounds& annbo) = default; + + /**Destructor*/ + virtual ~AnnulusBounds(); + + /**Virtual constructor*/ + virtual AnnulusBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::Annulus; } + + /**Assignment operator*/ + AnnulusBounds& operator=(const AnnulusBounds& sbo) = default; + + /**Equality operator*/ + bool operator==(const SurfaceBounds& annbo) const override; + + /**This method returns the smaller radius*/ + double minR() const; + + /**This method returns the bigger radius*/ + double maxR() const; + + /**This method returns the radius of a tilt*/ + double R() const; + + /**This method returns the opening angle*/ + double phi() const; + + /**This method returns the tilt angle*/ + double phiS() const; + + /**This method returns the maximal extension on the local plane*/ + virtual double r() const override; + + /**This method returns the opening angle alpha in point A (negative local phi) */ + // double alpha() const; + + /**This method returns the opening angle beta in point B (positive local phi) */ + // double beta() const; + + /** The orientation of the Trapezoid is according to the figure above, + in words: the shorter of the two parallel sides of the trapezoid intersects + with the negative @f$ y @f$ - axis of the local frame. + + <br> + The cases are:<br> + (0) @f$ y @f$ or @f$ x @f$ bounds are 0 || 0<br> + (1) LocalPosition is outside @f$ y @f$ bounds <br> + (2) LocalPosition is inside @f$ y @f$ bounds, but outside maximum @f$ x @f$ bounds <br> + (3) LocalPosition is inside @f$ y @f$ bounds AND inside minimum @f$ x @f$ bounds <br> + (4) LocalPosition is inside @f$ y @f$ bounds AND inside maximum @f$ x @f$ bounds, so that + it depends on the @f$ eta @f$ coordinate + (5) LocalPosition fails test of (4) <br> + + The inside check is done using single equations of straight lines and one has to take care if a point + lies on the positive @f$ x @f$ half area(I) or the negative one(II). Denoting @f$ |x_{min}| @f$ and + @f$ | x_{max} | @f$ as \c minHalfX respectively \c maxHalfX, such as @f$ | y_{H} | @f$ as \c halfY, + the equations for the straing lines in (I) and (II) can be written as:<br> + <br> + - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> + - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> + <br> + where @f$ \kappa_{I} = - \kappa_{II} = 2 \frac{y_{H}}{x_{max} - x_{min}} @f$ <br> + and @f$ \delta_{I} = \delta_{II} = - \frac{1}{2}\kappa_{I}(x_{max} + x_{min}) @f$ */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - inline double AnnulusBounds::R() const { return m_boundValues[AnnulusBounds::bv_R]; } - - inline double AnnulusBounds::phi() const { return m_boundValues[AnnulusBounds::bv_phi]; } - - inline double AnnulusBounds::phiS() const { return m_boundValues[AnnulusBounds::bv_phiS]; } - + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! */ - - inline double AnnulusBounds::r() const + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; - { return AnnulusBounds::bv_maxR; } //MW to be fixed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; - + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; - inline bool AnnulusBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return ( locpo[locX] > std::min(m_solution_L_min[0],m_solution_L_max[0]) - tol1 && locpo[locX] < std::max(m_solution_R_min[0],m_solution_R_max[0]) + tol1 ); } - //MW Fix it + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; - inline bool AnnulusBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return ( locpo[locY] > std::min(m_solution_L_min[1],m_solution_L_max[1]) - tol2 && locpo[locY] < std::max(m_solution_R_min[1],m_solution_R_max[1]) + tol2 ); } - //MW Fix it + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + // bool m_forceCovEllipse; + + /** isAbove() method for checking whether a point lies above or under a straight line */ + + bool isAbove(const Amg::Vector2D& locpo, double tol1, double tol2, double x1, double y1, double x2, double y2) const; + + bool isRight(const Amg::Vector2D& locpo, double tol1, double tol2, double x1, double y1, double x2, double y2) const; + + bool isLeft(const Amg::Vector2D& locpo, double tol1, double tol2, double x1, double y1, double x2, double y2) const; + + // check whether an ellipse intersects a line + bool EllipseIntersectLine(const Amg::Vector2D& locpo, double h, double k, double x1, double y1, double x2, double y2) + const; + + /** Distance to line */ + double distanceToLine(const Amg::Vector2D& locpo, std::vector<TDD_real_t> P1, std::vector<TDD_real_t> P2) const; + + /** Distance to arc */ + double distanceToArc(const Amg::Vector2D& locpo, + double R, + std::vector<TDD_real_t> sL, + std::vector<TDD_real_t> sR) const; + + /** Circle and line intersection **/ + std::vector<double> circleLineIntersection(double R, double k, double d) const; + + std::vector<TDD_real_t> m_boundValues; + + TDD_real_t m_maxYout; + TDD_real_t m_minYout; + TDD_real_t m_maxXout; + TDD_real_t m_minXout; + + TDD_real_t m_maxYin; + TDD_real_t m_minYin; + TDD_real_t m_maxXin; + TDD_real_t m_minXin; + + TDD_real_t m_k_L; + TDD_real_t m_k_R; + TDD_real_t m_d_L; + TDD_real_t m_d_R; + + std::vector<TDD_real_t> m_solution_L_min; + std::vector<TDD_real_t> m_solution_L_max; + std::vector<TDD_real_t> m_solution_R_min; + std::vector<TDD_real_t> m_solution_R_max; +}; + +inline AnnulusBounds* +AnnulusBounds::clone() const +{ + return new AnnulusBounds(*this); +} + +inline double +AnnulusBounds::minR() const +{ + return m_boundValues[AnnulusBounds::bv_minR]; +} + +inline double +AnnulusBounds::maxR() const +{ + return m_boundValues[AnnulusBounds::bv_maxR]; +} + +inline double +AnnulusBounds::R() const +{ + return m_boundValues[AnnulusBounds::bv_R]; +} + +inline double +AnnulusBounds::phi() const +{ + return m_boundValues[AnnulusBounds::bv_phi]; +} + +inline double +AnnulusBounds::phiS() const +{ + return m_boundValues[AnnulusBounds::bv_phiS]; +} + +inline double +AnnulusBounds::r() const + +{ + return AnnulusBounds::bv_maxR; +} // MW to be fixed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +inline bool +AnnulusBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (locpo[locX] > std::min(m_solution_L_min[0], m_solution_L_max[0]) - tol1 && + locpo[locX] < std::max(m_solution_R_min[0], m_solution_R_max[0]) + tol1); +} +// MW Fix it + +inline bool +AnnulusBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return (locpo[locY] > std::min(m_solution_L_min[1], m_solution_L_max[1]) - tol2 && + locpo[locY] < std::max(m_solution_R_min[1], m_solution_R_max[1]) + tol2); +} +// MW Fix it - } // end of namespace #endif // TRKSURFACES_ANNULUSBOUNDS_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/BoundaryCheck.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/BoundaryCheck.h index 11a3074a3da5a1ceb4e9ae652232405da9eede93..2e27fa74ecdcdfeb438588f7e8aacade4b28f5e9 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/BoundaryCheck.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/BoundaryCheck.h @@ -9,278 +9,290 @@ #ifndef TRKSURFACES_BOUNDARYCHECK_H #define TRKSURFACES_BOUNDARYCHECK_H - #include "EventPrimitives/EventPrimitives.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" namespace Trk { - /** - @class BoundaryCheck - - The BoundaryCheck class allows to steer the way surface - boundaries are used for inside/outside checks of - parameters. - - These checks are performed in the local 2D frame of the - surface and can either be: - - inside/outside with and without tolerance - - inside/outside according to a given chi2 value - - It also provides all the necessary tools for the individual implementations in the different SurfaceBounds classes. - - @author Andreas.Salzburger@cern.ch & Roland.Jansky@cern.ch - */ - - // maint struct for comparing the extent of arbitrary convex polygons relative to prefixed axes - struct KDOP { - float min; - // Minimum distance (from origin) along axes - float max; - // Maximum distance (from origin) along axes - }; - - // struct needed for FastSinCos method (see below) - struct sincosCache { - double sinC; - double cosC; - }; - - class BoundaryCheck { - // saves us a lot of function calls in the EllipseToPoly method - static constexpr double s_cos22 = 0.923879532511286756128183189396788286822416625863642486115097; - static constexpr double s_cos45 = 0.707106781186547524400844362104849039284835937688474036588339; - static constexpr double s_cos67 = 0.382683432365089771728459984030398866761344562485627041433800; - public: - enum BoundaryCheckType { - absolute = 0, //!< absolute check including tolerances - chi2corr = 1 //!< relative (chi2 based) with full correlations - }; - - bool checkLoc1; //!< check local 1 coordinate - bool checkLoc2; //!< check local 2 coordinate - - double toleranceLoc1; //!< absolute tolerance in local 1 coordinate - double toleranceLoc2; //!< absolute tolerance in local 2 coordinate - - int nSigmas; //!< allowed sigmas for chi2 boundary check - AmgSymMatrix(2) lCovariance; //!< local covariance matrix - - BoundaryCheckType bcType; - - /** Constructor for single boolean behavious */ - BoundaryCheck(bool sCheck) : - checkLoc1(sCheck), - checkLoc2(sCheck), - toleranceLoc1(0.), - toleranceLoc2(0.), - nSigmas(-1), - lCovariance(AmgSymMatrix(2)::Identity()), - bcType(absolute) - {} - - /** Constructor for tolerance based check */ - BoundaryCheck(bool chkL1, bool chkL2, double tloc1=0., double tloc2=0.) : - checkLoc1(chkL1), - checkLoc2(chkL2), - toleranceLoc1(tloc1), - toleranceLoc2(tloc2), - nSigmas(-1), - lCovariance(AmgSymMatrix(2)::Identity()), - bcType(absolute) - {} - - /** Constructor for chi2 based check */ - BoundaryCheck(const AmgSymMatrix(2)& lCov, - int nsig=1, - bool chkL1=true, - bool chkL2=true) : - checkLoc1(chkL1), - checkLoc2(chkL2), - toleranceLoc1(0.), - toleranceLoc2(0.), - nSigmas(nsig), - lCovariance(lCov), - bcType(chi2corr) - {} - - /** Conversion operator to bool */ - operator bool() const { return (checkLoc1 || checkLoc2); } - - - /** Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds. - Inside can be called without/with boundary check */ - void ComputeKDOP(std::vector<Amg::Vector2D> v, std::vector<Amg::Vector2D> KDOPAxes, std::vector<KDOP> &kdop) const; - - std::vector<Amg::Vector2D> EllipseToPoly(int resolution = 3) const; - - bool TestKDOPKDOP(std::vector<KDOP> &a, std::vector<KDOP> &b) const; - - double FastArcTan(double x) const; - - sincosCache FastSinCos(double x) const; - }; - - // should have maximum (average) error of 0.0015 (0.00089) radians or 0.0859 (0.0509) degrees, fine for us and much faster (>4 times) - inline double BoundaryCheck::FastArcTan(double x) const - { - double y; - bool complement = false; // true if arg was >1 - bool sign = false; // true if arg was < 0 - if (x<0.){ - x = -x; - sign = true; // arctan(-x)=-arctan(x) - } - if (x>1.){ - x = 1./x; // keep arg between 0 and 1 - complement = true; - } - y = M_PI_4*x - x*(fabs(x) - 1)*(0.2447 + 0.0663*fabs(x)); - if (complement) y = M_PI_2 - y; // correct for 1/x if we did that - if (sign) y = -y; // correct for negative arg - return y; - } - - // should have maximum (average) error of 0.001 (0.0005) radians or 0.0573 (0.029) degrees, fine for us and much faster (>8 times) - inline sincosCache BoundaryCheck::FastSinCos(double x) const - { - sincosCache tmp; - //always wrap input angle to -PI..PI - if (x < -M_PI) - x += 2.*M_PI; - else - if (x > M_PI) - x -= 2.*M_PI; - - //compute sine - if (x < 0.) - { - tmp.sinC = 1.27323954 * x + .405284735 * x * x; - - if (tmp.sinC < 0.) - tmp.sinC = .225 * (tmp.sinC *-tmp.sinC - tmp.sinC) + tmp.sinC; - else - tmp.sinC = .225 * (tmp.sinC * tmp.sinC - tmp.sinC) + tmp.sinC; - } - else - { - tmp.sinC = 1.27323954 * x - 0.405284735 * x * x; - - if (tmp.sinC < 0.) - tmp.sinC = .225 * (tmp.sinC *-tmp.sinC - tmp.sinC) + tmp.sinC; - else - tmp.sinC = .225 * (tmp.sinC * tmp.sinC - tmp.sinC) + tmp.sinC; - } - - //compute cosine: sin(x + PI/2) = cos(x) - x += M_PI_2; - if (x > M_PI) - x -= 2.*M_PI; - - if (x < 0.) - { - tmp.cosC = 1.27323954 * x + 0.405284735 * x * x; - - if (tmp.cosC < 0.) - tmp.cosC = .225 * (tmp.cosC *-tmp.cosC - tmp.cosC) + tmp.cosC; - else - tmp.cosC = .225 * (tmp.cosC * tmp.cosC - tmp.cosC) + tmp.cosC; - } - else - { - tmp.cosC = 1.27323954 * x - 0.405284735 * x * x; - - if (tmp.cosC < 0.) - tmp.cosC = .225 * (tmp.cosC *-tmp.cosC - tmp.cosC) + tmp.cosC; - else - tmp.cosC = .225 * (tmp.cosC * tmp.cosC - tmp.cosC) + tmp.cosC; - } - return tmp; - } - - // does the conversion of an ellipse of height h and width w to an polygon with 4 + 4*resolution points - inline std::vector<Amg::Vector2D> BoundaryCheck::EllipseToPoly(int resolution) const - { - const double h = nSigmas*sqrt(lCovariance(1,1)); - const double w = nSigmas*sqrt(lCovariance(0,0)); - - // first add the four vertices - std::vector<Amg::Vector2D> v((1+resolution)*4); - Amg::Vector2D p; - p << w, 0; v[0] = p; - p << -w,0; v[1] = p; - p << 0, h; v[2] = p; - p << 0,-h; v[3] = p; - - // now add a number, equal to the resolution, of equidistant points in each quadrant - // resolution == 3 seems to be a solid working point, but possibility open to change to any number in the future - Amg::Vector2D t(1,1); - AmgSymMatrix(2) t1; t1 << 1,0,0,-1; - AmgSymMatrix(2) t2; t2 << -1,0,0,-1; - AmgSymMatrix(2) t3; t3 << -1,0,0,1; - if(resolution != 3){ - sincosCache scResult; - for(int i=1; i<=resolution; i++) { - scResult = FastSinCos(M_PI_2*i/(resolution+1)); - t << w*scResult.sinC,h*scResult.cosC; - v[i*4+0] = t; - v[i*4+1] = t1*t; - v[i*4+2] = t2*t; - v[i*4+3] = t3*t; - } - } - else{ - t << w*s_cos22,h*s_cos67; - v[4] = t; - v[5] = t1*t; - v[6] = t2*t; - v[7] = t3*t; - t << w*s_cos45,h*s_cos45; - v[8] = t; - v[9] = t1*t; - v[10] = t2*t; - v[11] = t3*t; - t << w*s_cos67,h*s_cos22; - v[12] = t; - v[13] = t1*t; - v[14] = t2*t; - v[15] = t3*t; - } - return v; - } - - // calculates KDOP object from given polygon and set of axes - inline void BoundaryCheck::ComputeKDOP(std::vector<Amg::Vector2D> v, std::vector<Amg::Vector2D> KDOPAxes, std::vector<KDOP> &kdop) const - { - // initialize KDOP to first point - unsigned int k = KDOPAxes.size(); - for(unsigned int i=0; i<k; i++) { - kdop[i].max = KDOPAxes[i](0,0)*v[0](0,0)+KDOPAxes[i](1,0)*v[0](1,0); - kdop[i].min = KDOPAxes[i](0,0)*v[0](0,0)+KDOPAxes[i](1,0)*v[0](1,0); - } - // now for each additional point, update KDOP bounds if necessary - float value; - for(unsigned int i=1; i<v.size(); i++) { - for(unsigned int j=0; j<k; j++) { - value = KDOPAxes[j](0,0)*v[i](0,0)+KDOPAxes[j](1,0)*v[i](1,0); - if (value < kdop[j].min) kdop[j].min = value; - else if (value > kdop[j].max) kdop[j].max = value; - } - } - } - - // this is the method to actually check if two KDOPs overlap - inline bool BoundaryCheck::TestKDOPKDOP(std::vector<KDOP> &a, std::vector<KDOP> &b) const - { - int k = a.size(); - // check if any intervals are non-overlapping, return if so - for(int i=0;i<k;i++) if(a[i].min > b[i].max || a[i].max < b[i].min) return false; - // all intervals are overlapping, so KDOPs must intersect - return true; - } - - - +/** + @class BoundaryCheck + + The BoundaryCheck class allows to steer the way surface + boundaries are used for inside/outside checks of + parameters. + + These checks are performed in the local 2D frame of the + surface and can either be: + - inside/outside with and without tolerance + - inside/outside according to a given chi2 value + + It also provides all the necessary tools for the individual implementations in the different SurfaceBounds classes. + + @author Andreas.Salzburger@cern.ch & Roland.Jansky@cern.ch + */ + +// maint struct for comparing the extent of arbitrary convex polygons relative to prefixed axes +struct KDOP +{ + float min; + // Minimum distance (from origin) along axes + float max; + // Maximum distance (from origin) along axes +}; + +// struct needed for FastSinCos method (see below) +struct sincosCache +{ + double sinC; + double cosC; +}; + +class BoundaryCheck +{ + // saves us a lot of function calls in the EllipseToPoly method + static constexpr double s_cos22 = 0.923879532511286756128183189396788286822416625863642486115097; + static constexpr double s_cos45 = 0.707106781186547524400844362104849039284835937688474036588339; + static constexpr double s_cos67 = 0.382683432365089771728459984030398866761344562485627041433800; + +public: + enum BoundaryCheckType + { + absolute = 0, //!< absolute check including tolerances + chi2corr = 1 //!< relative (chi2 based) with full correlations + }; + + bool checkLoc1; //!< check local 1 coordinate + bool checkLoc2; //!< check local 2 coordinate + + double toleranceLoc1; //!< absolute tolerance in local 1 coordinate + double toleranceLoc2; //!< absolute tolerance in local 2 coordinate + + int nSigmas; //!< allowed sigmas for chi2 boundary check + AmgSymMatrix(2) lCovariance; //!< local covariance matrix + + BoundaryCheckType bcType; + + /** Constructor for single boolean behavious */ + BoundaryCheck(bool sCheck) + : checkLoc1(sCheck) + , checkLoc2(sCheck) + , toleranceLoc1(0.) + , toleranceLoc2(0.) + , nSigmas(-1) + , lCovariance(AmgSymMatrix(2)::Identity()) + , bcType(absolute) + {} + + /** Constructor for tolerance based check */ + BoundaryCheck(bool chkL1, bool chkL2, double tloc1 = 0., double tloc2 = 0.) + : checkLoc1(chkL1) + , checkLoc2(chkL2) + , toleranceLoc1(tloc1) + , toleranceLoc2(tloc2) + , nSigmas(-1) + , lCovariance(AmgSymMatrix(2)::Identity()) + , bcType(absolute) + {} + + /** Constructor for chi2 based check */ + BoundaryCheck(const AmgSymMatrix(2) & lCov, int nsig = 1, bool chkL1 = true, bool chkL2 = true) + : checkLoc1(chkL1) + , checkLoc2(chkL2) + , toleranceLoc1(0.) + , toleranceLoc2(0.) + , nSigmas(nsig) + , lCovariance(lCov) + , bcType(chi2corr) + {} + + /** Conversion operator to bool */ + operator bool() const { return (checkLoc1 || checkLoc2); } + + /** Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds. + Inside can be called without/with boundary check */ + void ComputeKDOP(std::vector<Amg::Vector2D> v, std::vector<Amg::Vector2D> KDOPAxes, std::vector<KDOP>& kdop) const; + + std::vector<Amg::Vector2D> EllipseToPoly(int resolution = 3) const; + + bool TestKDOPKDOP(std::vector<KDOP>& a, std::vector<KDOP>& b) const; + + double FastArcTan(double x) const; + + sincosCache FastSinCos(double x) const; +}; + +// should have maximum (average) error of 0.0015 (0.00089) radians or 0.0859 (0.0509) degrees, fine for us and much +// faster (>4 times) +inline double +BoundaryCheck::FastArcTan(double x) const +{ + double y; + bool complement = false; // true if arg was >1 + bool sign = false; // true if arg was < 0 + if (x < 0.) { + x = -x; + sign = true; // arctan(-x)=-arctan(x) + } + if (x > 1.) { + x = 1. / x; // keep arg between 0 and 1 + complement = true; + } + y = M_PI_4 * x - x * (fabs(x) - 1) * (0.2447 + 0.0663 * fabs(x)); + if (complement) + y = M_PI_2 - y; // correct for 1/x if we did that + if (sign) + y = -y; // correct for negative arg + return y; +} + +// should have maximum (average) error of 0.001 (0.0005) radians or 0.0573 (0.029) degrees, fine for us and much faster +// (>8 times) +inline sincosCache +BoundaryCheck::FastSinCos(double x) const +{ + sincosCache tmp; + // always wrap input angle to -PI..PI + if (x < -M_PI) + x += 2. * M_PI; + else if (x > M_PI) + x -= 2. * M_PI; + + // compute sine + if (x < 0.) { + tmp.sinC = 1.27323954 * x + .405284735 * x * x; + + if (tmp.sinC < 0.) + tmp.sinC = .225 * (tmp.sinC * -tmp.sinC - tmp.sinC) + tmp.sinC; + else + tmp.sinC = .225 * (tmp.sinC * tmp.sinC - tmp.sinC) + tmp.sinC; + } else { + tmp.sinC = 1.27323954 * x - 0.405284735 * x * x; + + if (tmp.sinC < 0.) + tmp.sinC = .225 * (tmp.sinC * -tmp.sinC - tmp.sinC) + tmp.sinC; + else + tmp.sinC = .225 * (tmp.sinC * tmp.sinC - tmp.sinC) + tmp.sinC; + } + + // compute cosine: sin(x + PI/2) = cos(x) + x += M_PI_2; + if (x > M_PI) + x -= 2. * M_PI; + + if (x < 0.) { + tmp.cosC = 1.27323954 * x + 0.405284735 * x * x; + + if (tmp.cosC < 0.) + tmp.cosC = .225 * (tmp.cosC * -tmp.cosC - tmp.cosC) + tmp.cosC; + else + tmp.cosC = .225 * (tmp.cosC * tmp.cosC - tmp.cosC) + tmp.cosC; + } else { + tmp.cosC = 1.27323954 * x - 0.405284735 * x * x; + + if (tmp.cosC < 0.) + tmp.cosC = .225 * (tmp.cosC * -tmp.cosC - tmp.cosC) + tmp.cosC; + else + tmp.cosC = .225 * (tmp.cosC * tmp.cosC - tmp.cosC) + tmp.cosC; + } + return tmp; +} + +// does the conversion of an ellipse of height h and width w to an polygon with 4 + 4*resolution points +inline std::vector<Amg::Vector2D> +BoundaryCheck::EllipseToPoly(int resolution) const +{ + const double h = nSigmas * sqrt(lCovariance(1, 1)); + const double w = nSigmas * sqrt(lCovariance(0, 0)); + + // first add the four vertices + std::vector<Amg::Vector2D> v((1 + resolution) * 4); + Amg::Vector2D p; + p << w, 0; + v[0] = p; + p << -w, 0; + v[1] = p; + p << 0, h; + v[2] = p; + p << 0, -h; + v[3] = p; + + // now add a number, equal to the resolution, of equidistant points in each quadrant + // resolution == 3 seems to be a solid working point, but possibility open to change to any number in the future + Amg::Vector2D t(1, 1); + AmgSymMatrix(2) t1; + t1 << 1, 0, 0, -1; + AmgSymMatrix(2) t2; + t2 << -1, 0, 0, -1; + AmgSymMatrix(2) t3; + t3 << -1, 0, 0, 1; + if (resolution != 3) { + sincosCache scResult; + for (int i = 1; i <= resolution; i++) { + scResult = FastSinCos(M_PI_2 * i / (resolution + 1)); + t << w * scResult.sinC, h * scResult.cosC; + v[i * 4 + 0] = t; + v[i * 4 + 1] = t1 * t; + v[i * 4 + 2] = t2 * t; + v[i * 4 + 3] = t3 * t; + } + } else { + t << w * s_cos22, h * s_cos67; + v[4] = t; + v[5] = t1 * t; + v[6] = t2 * t; + v[7] = t3 * t; + t << w * s_cos45, h * s_cos45; + v[8] = t; + v[9] = t1 * t; + v[10] = t2 * t; + v[11] = t3 * t; + t << w * s_cos67, h * s_cos22; + v[12] = t; + v[13] = t1 * t; + v[14] = t2 * t; + v[15] = t3 * t; + } + return v; +} + +// calculates KDOP object from given polygon and set of axes +inline void +BoundaryCheck::ComputeKDOP(std::vector<Amg::Vector2D> v, + std::vector<Amg::Vector2D> KDOPAxes, + std::vector<KDOP>& kdop) const +{ + // initialize KDOP to first point + unsigned int k = KDOPAxes.size(); + for (unsigned int i = 0; i < k; i++) { + kdop[i].max = KDOPAxes[i](0, 0) * v[0](0, 0) + KDOPAxes[i](1, 0) * v[0](1, 0); + kdop[i].min = KDOPAxes[i](0, 0) * v[0](0, 0) + KDOPAxes[i](1, 0) * v[0](1, 0); + } + // now for each additional point, update KDOP bounds if necessary + float value; + for (unsigned int i = 1; i < v.size(); i++) { + for (unsigned int j = 0; j < k; j++) { + value = KDOPAxes[j](0, 0) * v[i](0, 0) + KDOPAxes[j](1, 0) * v[i](1, 0); + if (value < kdop[j].min) + kdop[j].min = value; + else if (value > kdop[j].max) + kdop[j].max = value; + } + } +} + +// this is the method to actually check if two KDOPs overlap +inline bool +BoundaryCheck::TestKDOPKDOP(std::vector<KDOP>& a, std::vector<KDOP>& b) const +{ + int k = a.size(); + // check if any intervals are non-overlapping, return if so + for (int i = 0; i < k; i++) + if (a[i].min > b[i].max || a[i].max < b[i].min) + return false; + // all intervals are overlapping, so KDOPs must intersect + return true; +} + } #endif // TRKSURFACES_BOUNDARYCHECK_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeBounds.h index fc71ef2fe3045f0baccabb8dc7719f74cbb37a3f..8cc3fce572442c916704e789fa94c1b99c5ba503 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeBounds.h @@ -8,18 +8,18 @@ #ifndef TRKSURFACES_ConeBounds_H #define TRKSURFACES_ConeBounds_H - -#include "TrkSurfaces/SurfaceBounds.h" + #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" -#include<cfloat> +#include <cfloat> #include "GeoPrimitives/GeoPrimitives.h" -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; const float MAXBOUNDVALUE = FLT_MAX; -#else +#else typedef double TDD_real_t; const double MAXBOUNDVALUE = DBL_MAX; #endif @@ -28,218 +28,268 @@ class MsgStream; namespace Trk { - /** - @class ConeBounds - - Bounds for a conical Surface, - the opening angle is stored in \f$ \tan(\alpha) \f$ and always positively defined. - The cone can open to both sides, steered by \f$ z_min \f$ and \f$ z_max \f$. - - @image html ConeBounds.gif - - @author Ian.Watson@cern.ch, Andreas.Salzburger@cern.ch, Robert.Langenberg@cern.ch - */ - - class ConeBounds : public SurfaceBounds { - public: - /** BoundValues for readablility */ - enum BoundValues { - bv_alpha = 0, - bv_minZ = 1, - bv_maxZ = 2, - bv_averagePhi = 3, - bv_halfPhiSector = 4, - bv_length = 5 - }; - - /**Default Constructor*/ - ConeBounds(); - - /**Constructor - open cone with alpha, by default a full cone - but optionally can make a conical section */ - ConeBounds(double alpha, bool symm, double halfphi=M_PI, double avphi=0.); - - /**Constructor - open cone with alpha, minz and maxz, by - default a full cone but can optionally make it a conical section */ - ConeBounds(double alpha, double zmin, double zmax, double halfphi=M_PI, double avphi=0.); - - /**Copy Constructor */ - ConeBounds(const ConeBounds& cylbo); - - /**Destructor */ - virtual ~ConeBounds(); - - /**Assignment operator*/ - ConeBounds& operator=(const ConeBounds& cylbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor */ - virtual ConeBounds* clone() const override; - - /** Return the bounds type */ - virtual BoundsType type() const override { return SurfaceBounds::Cone; } - - /**This method checks if a LocalPosition is inside z bounds and rphi value- interface method */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1, double tol2) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk=true) const override; - - /**This method checks if a GlobalPosition is inside the Cylinder - not an interface method, - assumes that GlobalPosition is in the right frame*/ - virtual bool inside(const Amg::Vector3D& gp, double tol1=0., double tol2=0.) const; - virtual bool inside(const Amg::Vector3D& locpo, const BoundaryCheck& bchk) const; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns the maximal radius - for an unbound cone it returns MAXBOUNDVALUE*/ - virtual double r() const override; - - /** Return the radius at a specific z values */ - double r(double z) const; - - /**This method returns the average phi*/ - double tanAlpha() const; - double sinAlpha() const; - double cosAlpha() const; - double alpha() const; - - /**This method returns the minimum z value in the local framee - - for an unbound symmetric cone, it returns -MAXBOUNDVALUE*/ - double minZ() const; - - /**This method returns the maximum z value in the local framee - - for an unbound cone, it returns MAXBOUNDVALUE*/ - double maxZ() const; - - /**This method returns the average phi value (i.e. the "middle" - phi value for the conical sector we are describing) */ - - double averagePhi() const; - /**This method returns the half-phi width of the sector (so that - averagePhi +/- halfPhiSector gives the phi bounds of the - cone) */ - double halfPhiSector() const; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** internal storage of the geometry parameters */ - std::vector<TDD_real_t> m_boundValues; - TDD_real_t m_tanAlpha; - TDD_real_t m_sinAlpha; - TDD_real_t m_cosAlpha; - - /** Helper function for angle parameter initialization */ - virtual void initCache() override; - - /** Helpers for inside() functions */ - inline double minPhi() const {return m_boundValues[ConeBounds::bv_averagePhi]-m_boundValues[ConeBounds::bv_halfPhiSector];} - inline double maxPhi() const {return m_boundValues[ConeBounds::bv_averagePhi]+m_boundValues[ConeBounds::bv_halfPhiSector];} - }; - - inline ConeBounds* ConeBounds::clone() const - { return new ConeBounds(*this); } - - inline bool ConeBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const - { - double z = locpo[locZ]; - bool insideZ = z > (m_boundValues[ConeBounds::bv_minZ]-tol2) && z < (m_boundValues[ConeBounds::bv_maxZ]+tol2); - if (!insideZ) return false; - // TODO: Do we need some sort of "R" tolerance also here (take - // it off the z tol2 in that case?) or does the rphi tol1 cover - // this? (Could argue either way) - double coneR = z*m_tanAlpha; - double minRPhi = coneR*minPhi() - tol1, maxRPhi = coneR*maxPhi() + tol1; - return minRPhi < locpo[locRPhi] && locpo[locRPhi] < maxRPhi; - } - - inline bool ConeBounds::inside(const Amg::Vector3D &glopo, double tol1, double tol2) const - { - // coords are (rphi,z) - return inside(Amg::Vector2D(glopo.perp()*glopo.phi(),glopo.z()) ,tol1,tol2); - } - - inline bool ConeBounds::inside(const Amg::Vector3D &glopo, const BoundaryCheck& bchk) const - { - // coords are (rphi,z) - return inside(Amg::Vector2D(glopo.perp()*glopo.phi(),glopo.z()) ,bchk.toleranceLoc1,bchk.toleranceLoc2); - } - - inline bool ConeBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +/** + @class ConeBounds + + Bounds for a conical Surface, + the opening angle is stored in \f$ \tan(\alpha) \f$ and always positively defined. + The cone can open to both sides, steered by \f$ z_min \f$ and \f$ z_max \f$. + + @image html ConeBounds.gif + + @author Ian.Watson@cern.ch, Andreas.Salzburger@cern.ch, Robert.Langenberg@cern.ch +*/ + +class ConeBounds : public SurfaceBounds +{ +public: + /** BoundValues for readablility */ + enum BoundValues + { + bv_alpha = 0, + bv_minZ = 1, + bv_maxZ = 2, + bv_averagePhi = 3, + bv_halfPhiSector = 4, + bv_length = 5 + }; + + /**Default Constructor*/ + ConeBounds(); + + /**Constructor - open cone with alpha, by default a full cone + but optionally can make a conical section */ + ConeBounds(double alpha, bool symm, double halfphi = M_PI, double avphi = 0.); + + /**Constructor - open cone with alpha, minz and maxz, by + default a full cone but can optionally make it a conical section */ + ConeBounds(double alpha, double zmin, double zmax, double halfphi = M_PI, double avphi = 0.); + + /**Copy Constructor */ + ConeBounds(const ConeBounds& cylbo); + + /**Destructor */ + virtual ~ConeBounds(); + + /**Assignment operator*/ + ConeBounds& operator=(const ConeBounds& cylbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor */ + virtual ConeBounds* clone() const override; + + /** Return the bounds type */ + virtual BoundsType type() const override { return SurfaceBounds::Cone; } + + /**This method checks if a LocalPosition is inside z bounds and rphi value- interface method */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1, double tol2) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk = true) const override; + + /**This method checks if a GlobalPosition is inside the Cylinder - not an interface method, + assumes that GlobalPosition is in the right frame*/ + virtual bool inside(const Amg::Vector3D& gp, double tol1 = 0., double tol2 = 0.) const; + virtual bool inside(const Amg::Vector3D& locpo, const BoundaryCheck& bchk) const; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns the maximal radius - for an unbound cone it returns MAXBOUNDVALUE*/ + virtual double r() const override; + + /** Return the radius at a specific z values */ + double r(double z) const; + + /**This method returns the average phi*/ + double tanAlpha() const; + double sinAlpha() const; + double cosAlpha() const; + double alpha() const; + + /**This method returns the minimum z value in the local framee + - for an unbound symmetric cone, it returns -MAXBOUNDVALUE*/ + double minZ() const; + + /**This method returns the maximum z value in the local framee + - for an unbound cone, it returns MAXBOUNDVALUE*/ + double maxZ() const; + + /**This method returns the average phi value (i.e. the "middle" + phi value for the conical sector we are describing) */ + + double averagePhi() const; + /**This method returns the half-phi width of the sector (so that + averagePhi +/- halfPhiSector gives the phi bounds of the + cone) */ + double halfPhiSector() const; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** internal storage of the geometry parameters */ + std::vector<TDD_real_t> m_boundValues; + TDD_real_t m_tanAlpha; + TDD_real_t m_sinAlpha; + TDD_real_t m_cosAlpha; + + /** Helper function for angle parameter initialization */ + virtual void initCache() override; + + /** Helpers for inside() functions */ + inline double minPhi() const + { + return m_boundValues[ConeBounds::bv_averagePhi] - m_boundValues[ConeBounds::bv_halfPhiSector]; + } + inline double maxPhi() const { - return ConeBounds::inside(locpo,bchk.toleranceLoc1,bchk.toleranceLoc2); + return m_boundValues[ConeBounds::bv_averagePhi] + m_boundValues[ConeBounds::bv_halfPhiSector]; } +}; - inline bool ConeBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { - double z = locpo[locZ]; - double coneR = z*m_tanAlpha; - double minRPhi = coneR*minPhi() - tol1, maxRPhi = coneR*maxPhi() + tol1; - return minRPhi < locpo[locRPhi] && locpo[locRPhi] < maxRPhi; - } - - inline bool ConeBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { - double z = locpo[locZ]; - return (z > (m_boundValues[ConeBounds::bv_minZ] - tol2) && z < (m_boundValues[ConeBounds::bv_maxZ] + tol2)); - } - - inline double ConeBounds::r() const - { - double z = fabs(m_boundValues[ConeBounds::bv_maxZ]), mz = fabs(m_boundValues[ConeBounds::bv_minZ]); - if(mz > z) - z = mz; - return fabs(z*m_tanAlpha); - } - - inline double ConeBounds::r(double z) const - { - return fabs(z*m_tanAlpha); - } - - - inline double ConeBounds::tanAlpha() const { return m_tanAlpha; } - - inline double ConeBounds::sinAlpha() const { return m_sinAlpha; } - - inline double ConeBounds::cosAlpha() const { return m_cosAlpha; } - - inline double ConeBounds::alpha() const { return m_boundValues[ConeBounds::bv_alpha]; } - - inline double ConeBounds::minZ() const { return m_boundValues[ConeBounds::bv_minZ]; } - - inline double ConeBounds::maxZ() const { return m_boundValues[ConeBounds::bv_maxZ]; } - - inline double ConeBounds::averagePhi() const { return m_boundValues[ConeBounds::bv_averagePhi]; } - - inline double ConeBounds::halfPhiSector() const { return m_boundValues[ConeBounds::bv_halfPhiSector]; } - - inline void ConeBounds::initCache() - { - m_tanAlpha = tan(m_boundValues[ConeBounds::bv_alpha]); - m_sinAlpha = sin(m_boundValues[ConeBounds::bv_alpha]); - m_cosAlpha = cos(m_boundValues[ConeBounds::bv_alpha]); - // validate the halfphi - if(m_boundValues[ConeBounds::bv_halfPhiSector] < 0.) - m_boundValues[ConeBounds::bv_halfPhiSector] = -m_boundValues[ConeBounds::bv_halfPhiSector]; - if(m_boundValues[ConeBounds::bv_halfPhiSector] > M_PI) - m_boundValues[ConeBounds::bv_halfPhiSector] = M_PI; - } +inline ConeBounds* +ConeBounds::clone() const +{ + return new ConeBounds(*this); } -#endif // TRKSURFACES_CONEBOUNDS_H +inline bool +ConeBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + double z = locpo[locZ]; + bool insideZ = z > (m_boundValues[ConeBounds::bv_minZ] - tol2) && z < (m_boundValues[ConeBounds::bv_maxZ] + tol2); + if (!insideZ) + return false; + // TODO: Do we need some sort of "R" tolerance also here (take + // it off the z tol2 in that case?) or does the rphi tol1 cover + // this? (Could argue either way) + double coneR = z * m_tanAlpha; + double minRPhi = coneR * minPhi() - tol1, maxRPhi = coneR * maxPhi() + tol1; + return minRPhi < locpo[locRPhi] && locpo[locRPhi] < maxRPhi; +} + +inline bool +ConeBounds::inside(const Amg::Vector3D& glopo, double tol1, double tol2) const +{ + // coords are (rphi,z) + return inside(Amg::Vector2D(glopo.perp() * glopo.phi(), glopo.z()), tol1, tol2); +} + +inline bool +ConeBounds::inside(const Amg::Vector3D& glopo, const BoundaryCheck& bchk) const +{ + // coords are (rphi,z) + return inside(Amg::Vector2D(glopo.perp() * glopo.phi(), glopo.z()), bchk.toleranceLoc1, bchk.toleranceLoc2); +} + +inline bool +ConeBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + return ConeBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); +} + +inline bool +ConeBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + double z = locpo[locZ]; + double coneR = z * m_tanAlpha; + double minRPhi = coneR * minPhi() - tol1, maxRPhi = coneR * maxPhi() + tol1; + return minRPhi < locpo[locRPhi] && locpo[locRPhi] < maxRPhi; +} +inline bool +ConeBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + double z = locpo[locZ]; + return (z > (m_boundValues[ConeBounds::bv_minZ] - tol2) && z < (m_boundValues[ConeBounds::bv_maxZ] + tol2)); +} +inline double +ConeBounds::r() const +{ + double z = fabs(m_boundValues[ConeBounds::bv_maxZ]), mz = fabs(m_boundValues[ConeBounds::bv_minZ]); + if (mz > z) + z = mz; + return fabs(z * m_tanAlpha); +} + +inline double +ConeBounds::r(double z) const +{ + return fabs(z * m_tanAlpha); +} + +inline double +ConeBounds::tanAlpha() const +{ + return m_tanAlpha; +} + +inline double +ConeBounds::sinAlpha() const +{ + return m_sinAlpha; +} + +inline double +ConeBounds::cosAlpha() const +{ + return m_cosAlpha; +} + +inline double +ConeBounds::alpha() const +{ + return m_boundValues[ConeBounds::bv_alpha]; +} + +inline double +ConeBounds::minZ() const +{ + return m_boundValues[ConeBounds::bv_minZ]; +} + +inline double +ConeBounds::maxZ() const +{ + return m_boundValues[ConeBounds::bv_maxZ]; +} + +inline double +ConeBounds::averagePhi() const +{ + return m_boundValues[ConeBounds::bv_averagePhi]; +} + +inline double +ConeBounds::halfPhiSector() const +{ + return m_boundValues[ConeBounds::bv_halfPhiSector]; +} + +inline void +ConeBounds::initCache() +{ + m_tanAlpha = tan(m_boundValues[ConeBounds::bv_alpha]); + m_sinAlpha = sin(m_boundValues[ConeBounds::bv_alpha]); + m_cosAlpha = cos(m_boundValues[ConeBounds::bv_alpha]); + // validate the halfphi + if (m_boundValues[ConeBounds::bv_halfPhiSector] < 0.) + m_boundValues[ConeBounds::bv_halfPhiSector] = -m_boundValues[ConeBounds::bv_halfPhiSector]; + if (m_boundValues[ConeBounds::bv_halfPhiSector] > M_PI) + m_boundValues[ConeBounds::bv_halfPhiSector] = M_PI; +} +} + +#endif // TRKSURFACES_CONEBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeSurface.h index f3b366a35b43cb702f2c3936efea3bc7791c8c0b..dad35522b3008a53957c635a4f0ccc6d585d6f92 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/ConeSurface.h @@ -9,268 +9,299 @@ #ifndef TRKSURFACES_CONESURFACE_H #define TRKSURFACES_CONESURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/ConeBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" +// Trk #include "TrkDetDescrUtils/SharedObject.h" +#include "TrkEventPrimitives/ParamDefs.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/ConeBounds.h" +#include "TrkSurfaces/Surface.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; namespace Trk { - class LocalParameters; - template<int DIM, class T, class S> class ParametersT; - - /** - @class ConeSurface - - Class for a conical surface in the ATLAS detector. - It inherits from Surface. - - The ConeSurface is special since no corresponding - TrackParameters exist since they're numerical instable - at the tip of the cone. - Propagations to a cone surface will be returned in - curvilinear coordinates. - - @author Ian.Watson@cern.ch, Andreas.Salzburger@cern.ch - */ - - class ConeSurface : public Surface { - - public: - /**Default Constructor*/ - ConeSurface(); - - /**Constructor form HepTransform and an opening angle */ - ConeSurface(Amg::Transform3D* htrans, double alpha, bool symmetric=false); - - /**Constructor form HepTransform, radius halfphi, and halflenght*/ - ConeSurface(Amg::Transform3D* htrans, double alpha, double locZmin, double locZmax, double halfPhi=M_PI); - - /**Constructor from HepTransform and CylinderBounds - - ownership of the bounds is passed - */ - ConeSurface(Amg::Transform3D* htrans, ConeBounds* cbounds); - - /**Constructor from HepTransform by unique_ptr. - - bounds is not set. */ - ConeSurface(std::unique_ptr<Amg::Transform3D> htrans); - - /**Copy constructor */ - ConeSurface(const ConeSurface& csf); - - /**Copy constructor with shift */ - ConeSurface(const ConeSurface& csf, const Amg::Transform3D& transf); - - /**Destructor*/ - virtual ~ConeSurface(); - - /**Assignment operator*/ - ConeSurface& operator=(const ConeSurface& csf); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /**Implicit Constructor*/ - virtual ConeSurface* clone() const override; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, ConeSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, ConeSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, ConeSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, ConeSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, ConeSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, ConeSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, ConeSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, ConeSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, ConeSurface>(position, momentum, charge, *this, cov); } - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Cone; } - - - /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface - - the default implementation is the the RotationMatrix3D of the transform */ - virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const override; - - /** Returns a global reference point: - For the Cylinder this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ - Where @f$ \phi @f$ denotes the averagePhi() of the cylinderBounds. - */ - virtual const Amg::Vector3D& globalReferencePoint() const override; - - /**Return method for surface normal information - at a given local point, overwrites the normal() from base class.*/ - virtual const Amg::Vector3D& normal() const override; - - /**Return method for surface normal information - at a given local point, overwrites the normal() from base class.*/ - virtual const Amg::Vector3D* normal(const Amg::Vector2D& locpo) const override; - - /**Return method for the rotational symmetry axis - the z-Axis of the HepTransform */ - virtual const Amg::Vector3D& rotSymmetryAxis() const; - - /**This method returns the ConeBounds by reference - (NoBounds is not possible for cone)*/ - virtual const ConeBounds& bounds() const override; - - /**This method calls the inside method of ConeBounds*/ - virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const override; - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** Specialized for ConeSurface : LocalParameters to Vector2D */ - virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; - - /** Specialized for ConeSurface : LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** Specialized for ConeSurface : GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** fast straight line intersection schema - provides closest intersection and (signed) path length - - <b>mathematical motivation:</b> - - The calculation will be done in the 3-dim frame of the cone, - i.e. the symmetry axis of the cone is the z-axis, x- and y-axis are perpenticular - to the the z-axis. In this frame the cone is centered around the origin. - Therefore the two points describing the line have to be first recalculated into the new frame. - Suppose, this is done, the points of intersection can be - obtained as follows:<br> - - The cone is described by the implicit equation - @f$x^2 + y^2 = z^2 \tan \alpha@f$ - where @f$\alpha@f$ is opening half-angle of the cone the and - the line by the parameter equation (with @f$t@f$ the - parameter and @f$x_1@f$ and @f$x_2@f$ are points on the line) - @f$(x,y,z) = \vec x_1 + (\vec x_2 - \vec x_2) t @f$. - The intersection is the given to the value of @f$t@f$ where - the @f$(x,y,z)@f$ coordinates of the line satisfy the implicit - equation of the cone. Inserting the expression for the points - on the line into the equation of the cone and rearranging to - the form of a gives (letting @f$ \vec x_d = \frac{\vec x_2 - \vec - x_1}{\abs{\vec x_2 - \vec x_1}} @f$): - @f$t^2 (x_d^2 + y_d^2 - z_d^2 \tan^2 \alpha) + 2 t (x_1 x_d + - y_1 y_d - z_1 z_d \tan^2 \alpha) + (x_1^2 + y_1^2 - z_1^2 - \tan^2 \alpha) = 0 @f$ - Solving the above for @f$t@f$ and putting the values into the - equation of the line gives the points of intersection. @f$t@f$ - is also the length of the path, since we normalized @f$x_d@f$ - to be unit length. - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool forceDir=false, BoundaryCheck bchk=false) const override; - - /** fast straight line distance to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const override; - - /** fast straight line distance to Surface - with bounds options */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool bound) const override; - - /** the pathCorrection for derived classes with thickness */ - virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::ConeSurface"; } - - protected: //!< data members - SharedObject<const ConeBounds> m_bounds; //!< bounds (shared) - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_referencePoint; //!< The global reference point (== a point on the surface) - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_rotSymmetryAxis; //!< The rotational symmetry axis - }; - - inline ConeSurface* ConeSurface::clone() const - { return new ConeSurface(*this); } - - inline const Amg::Vector3D& ConeSurface::normal() const - { return Surface::normal(); } - - inline const Amg::Vector3D* ConeSurface::normal(const Amg::Vector2D& lp) const +class LocalParameters; +template<int DIM, class T, class S> +class ParametersT; + +/** + @class ConeSurface + + Class for a conical surface in the ATLAS detector. + It inherits from Surface. + + The ConeSurface is special since no corresponding + TrackParameters exist since they're numerical instable + at the tip of the cone. + Propagations to a cone surface will be returned in + curvilinear coordinates. + + @author Ian.Watson@cern.ch, Andreas.Salzburger@cern.ch + */ + +class ConeSurface : public Surface +{ + +public: + /**Default Constructor*/ + ConeSurface(); + + /**Constructor form HepTransform and an opening angle */ + ConeSurface(Amg::Transform3D* htrans, double alpha, bool symmetric = false); + + /**Constructor form HepTransform, radius halfphi, and halflenght*/ + ConeSurface(Amg::Transform3D* htrans, double alpha, double locZmin, double locZmax, double halfPhi = M_PI); + + /**Constructor from HepTransform and CylinderBounds + - ownership of the bounds is passed + */ + ConeSurface(Amg::Transform3D* htrans, ConeBounds* cbounds); + + /**Constructor from HepTransform by unique_ptr. + - bounds is not set. */ + ConeSurface(std::unique_ptr<Amg::Transform3D> htrans); + + /**Copy constructor */ + ConeSurface(const ConeSurface& csf); + + /**Copy constructor with shift */ + ConeSurface(const ConeSurface& csf, const Amg::Transform3D& transf); + + /**Destructor*/ + virtual ~ConeSurface(); + + /**Assignment operator*/ + ConeSurface& operator=(const ConeSurface& csf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /**Implicit Constructor*/ + virtual ConeSurface* clone() const override; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, ConeSurface>* createTrackParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - // (cos phi cos alpha, sin phi cos alpha, sgn z sin alpha) - double phi = lp[Trk::locRPhi]/(bounds().r(lp[Trk::locZ])), - sgn = lp[Trk::locZ] > 0 ? -1. : +1.; - Amg::Vector3D localNormal(cos(phi) * bounds().cosAlpha(), - sin(phi) * bounds().cosAlpha(), - sgn*bounds().sinAlpha()); - return new Amg::Vector3D(transform().rotation()*localNormal); - } - - inline const ConeBounds& ConeSurface::bounds() const - { return *(m_bounds.get()); } - - inline bool ConeSurface::insideBounds(const Amg::Vector2D& locpos, - double tol1, - double tol2) const - { return bounds().inside(locpos,tol1,tol2); } - - inline bool ConeSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const - { return bounds().inside(locpos,bchk.toleranceLoc1,bchk.toleranceLoc2); } - - inline const Amg::Vector2D ConeSurface::localParametersToPosition(const LocalParameters& locpars) const + return new ParametersT<5, Charged, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, ConeSurface>* createTrackParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override { - if (locpars.contains(Trk::locRPhi) && locpars.contains(Trk::locZ)) - return Amg::Vector2D(locpars[Trk::locRPhi],locpars[Trk::locZ]); - if (locpars.contains(Trk::locRPhi)) { - // not obvious what one should do here with the "r" bit, so by definintion - // take that r=1 if no z is given to fix down the r component - double phi = locpars[Trk::locRPhi]; - return Amg::Vector2D(phi, locpars[Trk::locZ]); - } else if (locpars.contains(Trk::locZ)){ - double r = locpars[Trk::locZ]*bounds().tanAlpha(); - // by definition set it to M_PI/2 - return Amg::Vector2D(r*M_PI*0.5, locpars[Trk::locZ]); - } - return Amg::Vector2D(0.,0.); + return new ParametersT<5, Charged, ConeSurface>(position, momentum, charge, *this, cov); } - -} // end of namespace -#endif // TRKSURFACES_CONESURFACE_H + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, ConeSurface>* createNeutralParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, ConeSurface>* createNeutralParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, ConeSurface>(position, momentum, charge, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, ConeSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, ConeSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, ConeSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, ConeSurface>(position, momentum, charge, *this, cov); + } + + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Cone; } + + /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface + - the default implementation is the the RotationMatrix3D of the transform */ + virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom) const override; + + /** Returns a global reference point: + For the Cylinder this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ + Where @f$ \phi @f$ denotes the averagePhi() of the cylinderBounds. + */ + virtual const Amg::Vector3D& globalReferencePoint() const override; + + /**Return method for surface normal information + at a given local point, overwrites the normal() from base class.*/ + virtual const Amg::Vector3D& normal() const override; + + /**Return method for surface normal information + at a given local point, overwrites the normal() from base class.*/ + virtual const Amg::Vector3D* normal(const Amg::Vector2D& locpo) const override; + + /**Return method for the rotational symmetry axis - the z-Axis of the HepTransform */ + virtual const Amg::Vector3D& rotSymmetryAxis() const; + + /**This method returns the ConeBounds by reference + (NoBounds is not possible for cone)*/ + virtual const ConeBounds& bounds() const override; + + /**This method calls the inside method of ConeBounds*/ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + + /** Specialized for ConeSurface : LocalParameters to Vector2D */ + virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; + + /** Specialized for ConeSurface : LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** Specialized for ConeSurface : GlobalToLocal method without dynamic memory allocation - boolean checks if on + * surface */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** fast straight line intersection schema - provides closest intersection and (signed) path length + + <b>mathematical motivation:</b> + The calculation will be done in the 3-dim frame of the cone, + i.e. the symmetry axis of the cone is the z-axis, x- and y-axis are perpenticular + to the the z-axis. In this frame the cone is centered around the origin. + Therefore the two points describing the line have to be first recalculated into the new frame. + Suppose, this is done, the points of intersection can be + obtained as follows:<br> + The cone is described by the implicit equation + @f$x^2 + y^2 = z^2 \tan \alpha@f$ + where @f$\alpha@f$ is opening half-angle of the cone the and + the line by the parameter equation (with @f$t@f$ the + parameter and @f$x_1@f$ and @f$x_2@f$ are points on the line) + @f$(x,y,z) = \vec x_1 + (\vec x_2 - \vec x_2) t @f$. + The intersection is the given to the value of @f$t@f$ where + the @f$(x,y,z)@f$ coordinates of the line satisfy the implicit + equation of the cone. Inserting the expression for the points + on the line into the equation of the cone and rearranging to + the form of a gives (letting @f$ \vec x_d = \frac{\vec x_2 - \vec + x_1}{\abs{\vec x_2 - \vec x_1}} @f$): + @f$t^2 (x_d^2 + y_d^2 - z_d^2 \tan^2 \alpha) + 2 t (x_1 x_d + + y_1 y_d - z_1 z_d \tan^2 \alpha) + (x_1^2 + y_1^2 - z_1^2 + \tan^2 \alpha) = 0 @f$ + Solving the above for @f$t@f$ and putting the values into the + equation of the line gives the points of intersection. @f$t@f$ + is also the length of the path, since we normalized @f$x_d@f$ + to be unit length. + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir = false, + BoundaryCheck bchk = false) const override; + + /** fast straight line distance to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + + /** fast straight line distance to Surface - with bounds options */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool bound) const override; + + /** the pathCorrection for derived classes with thickness */ + virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::ConeSurface"; } + +protected: //!< data members + SharedObject<const ConeBounds> m_bounds; //!< bounds (shared) + CxxUtils::CachedUniquePtrT<Amg::Vector3D> + m_referencePoint; //!< The global reference point (== a point on the surface) + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_rotSymmetryAxis; //!< The rotational symmetry axis +}; + +inline ConeSurface* +ConeSurface::clone() const +{ + return new ConeSurface(*this); +} + +inline const Amg::Vector3D& +ConeSurface::normal() const +{ + return Surface::normal(); +} + +inline const Amg::Vector3D* +ConeSurface::normal(const Amg::Vector2D& lp) const +{ + // (cos phi cos alpha, sin phi cos alpha, sgn z sin alpha) + double phi = lp[Trk::locRPhi] / (bounds().r(lp[Trk::locZ])), sgn = lp[Trk::locZ] > 0 ? -1. : +1.; + Amg::Vector3D localNormal(cos(phi) * bounds().cosAlpha(), sin(phi) * bounds().cosAlpha(), sgn * bounds().sinAlpha()); + return new Amg::Vector3D(transform().rotation() * localNormal); +} + +inline const ConeBounds& +ConeSurface::bounds() const +{ + return *(m_bounds.get()); +} + +inline bool +ConeSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + return bounds().inside(locpos, tol1, tol2); +} + +inline bool +ConeSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const +{ + return bounds().inside(locpos, bchk.toleranceLoc1, bchk.toleranceLoc2); +} + +inline const Amg::Vector2D +ConeSurface::localParametersToPosition(const LocalParameters& locpars) const +{ + if (locpars.contains(Trk::locRPhi) && locpars.contains(Trk::locZ)) + return Amg::Vector2D(locpars[Trk::locRPhi], locpars[Trk::locZ]); + if (locpars.contains(Trk::locRPhi)) { + // not obvious what one should do here with the "r" bit, so by definintion + // take that r=1 if no z is given to fix down the r component + double phi = locpars[Trk::locRPhi]; + return Amg::Vector2D(phi, locpars[Trk::locZ]); + } else if (locpars.contains(Trk::locZ)) { + double r = locpars[Trk::locZ] * bounds().tanAlpha(); + // by definition set it to M_PI/2 + return Amg::Vector2D(r * M_PI * 0.5, locpars[Trk::locZ]); + } + return Amg::Vector2D(0., 0.); +} + +} // end of namespace + +#endif // TRKSURFACES_CONESURFACE_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderBounds.h index 8b50dbe2087e142e279dab6db2c9456fe10e2110..3e3089acf9241cf54ca1599cc1d727bf0197f650 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderBounds.h @@ -8,221 +8,262 @@ #ifndef TRKSURFACES_CYLINDERBOUNDS_H #define TRKSURFACES_CYLINDERBOUNDS_H - -#include "TrkSurfaces/SurfaceBounds.h" + #include "TrkEventPrimitives/ParamDefs.h" -//Eigen Primitives +#include "TrkSurfaces/SurfaceBounds.h" +// Eigen Primitives #include "GeoPrimitives/GeoPrimitives.h" -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif class MsgStream; namespace Trk { - /** - @class CylinderBounds - - Bounds for a cylindrical Surface. - These bounds may be used for both, CylinderSurface and StraightLineSurface. - In case of bounds for a StraightLineSurface the radius determines the radius within a localPosition - is regarded as inside bounds. - - Trk::CylinderBounds also enhance the possibility of a cylinder segment with an opening angle @f$ 2\cdot\phi_{half}@f$ - around an average @f$ \phi @f$ angle @f$ \phi_{ave} @f$. - - @todo update the documentation picture for cylinder segments - - @image html CylinderBounds.gif - - @author Andreas.Salzburger@cern.ch - */ - - class CylinderBounds : public SurfaceBounds { - public: - /** BoundValues for readablility */ - enum BoundValues { - bv_radius = 0, - bv_averagePhi = 1, - bv_halfPhiSector = 2, - bv_halfZ = 3, - bv_length = 4 - }; - - /**Default Constructor*/ - CylinderBounds(); - - /**Constructor - full cylinder */ - CylinderBounds(double radius, double halez); - - /**Constructor - cylinder segment */ - CylinderBounds(double radius, double halfphi, double halez); - - /**Constructor - cylinder segment with given averagePhi, not supposed for CylinderSurfaces*/ - CylinderBounds(double radius, double halfphi, double avphi, double halez); - - /**Copy Constructor */ - CylinderBounds(const CylinderBounds& cylbo); - - /**Destructor */ - virtual ~CylinderBounds(); - - /**Assignment operator*/ - CylinderBounds& operator=(const CylinderBounds& cylbo); - - /**Move assignment operator*/ - CylinderBounds& operator=(CylinderBounds&& cylbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor */ - virtual CylinderBounds* clone() const override; - - /** Return the bounds type */ - virtual BoundsType type() const override { return SurfaceBounds::Cylinder; } - - /**This method checks if a LocalPosition is inside z bounds and rphi value- interface method */ - virtual bool inside(const Amg::Vector2D &locpo, double tol1, double tol2) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /**This method checks if a GlobalPosition is inside the Cylinder - not an interface method, - assumes that GlobalPosition is in the right frame*/ - bool inside3D(const Amg::Vector3D& gp, double tol1=0., double tol2=0.) const; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method checks if a LocalPosition is inside z bounds and inside the radius (for straws) */ - bool insideRadius(const Amg::Vector2D &locpo, double tol) const; - - /**This method returns the radius*/ - virtual double r() const override; - - /**This method returns the average phi*/ - double averagePhi() const; - - /**This method returns the halfPhiSector angle*/ - double halfPhiSector() const; - - /**This method returns the halflengthZ*/ - double halflengthZ() const; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** helper methods for the inside check */ - bool inside(double r, double phi, double z, double tol1, double tol2) const; - bool insideLocZ(double z, double tol2) const; - - /** internal storage of the geometry parameters */ - std::vector<TDD_real_t> m_boundValues; - bool m_checkPhi; - - }; +/** + @class CylinderBounds - inline CylinderBounds* CylinderBounds::clone() const - { return new CylinderBounds(*this); } - - inline bool CylinderBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const - { - double z = locpo[locZ]; - bool insideZ = insideLocZ(z,tol2); - if (!insideZ) return false; - // no check on Phi neccesary - if (!m_checkPhi) return true; - // now check insidePhi - double localPhi = (locpo[locRPhi]/m_boundValues[CylinderBounds::bv_radius])-m_boundValues[CylinderBounds::bv_averagePhi]; - localPhi -= (localPhi > M_PI) ? 2.*M_PI : 0.; - return ( localPhi*localPhi < (m_boundValues[CylinderBounds::bv_halfPhiSector]+tol1)*(m_boundValues[CylinderBounds::bv_halfPhiSector]+tol1) ); - } - - inline bool CylinderBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const - { - if(bchk.bcType==0 || bchk.nSigmas==0 || m_boundValues[CylinderBounds::bv_halfPhiSector]!=M_PI) return CylinderBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - double dphi = scResult.sinC*scResult.sinC*bchk.lCovariance(0,0); - double dz = scResult.cosC*scResult.cosC*bchk.lCovariance(0,1); - double max_ell = dphi > dz ? dphi : dz; - double limit = bchk.nSigmas*sqrt(max_ell); - return insideLocZ(locpo[locZ],limit); - } + Bounds for a cylindrical Surface. + These bounds may be used for both, CylinderSurface and StraightLineSurface. + In case of bounds for a StraightLineSurface the radius determines the radius within a localPosition + is regarded as inside bounds. - inline bool CylinderBounds::inside3D(const Amg::Vector3D& glopo, double tol1, double tol2) const - { - return inside(glopo.perp(),glopo.phi(),glopo.z(),tol1,tol2); - } - - inline bool CylinderBounds::inside(double r, double phi, double z, double tol1, double tol2) const - { + Trk::CylinderBounds also enhance the possibility of a cylinder segment with an opening angle @f$ 2\cdot\phi_{half}@f$ + around an average @f$ \phi @f$ angle @f$ \phi_{ave} @f$. - bool insideZ = insideLocZ(z,tol2); - if (!insideZ) return false; - double diffR = (m_boundValues[CylinderBounds::bv_radius] - r ); - bool insideR = diffR*diffR < tol1*tol1; - if (!insideR) return false; - // now check insidePhi if needed - if (!m_checkPhi) return true; - // phi needs to be checked - double localPhi = phi-m_boundValues[CylinderBounds::bv_averagePhi]; - localPhi -= (localPhi > M_PI) ? 2.*M_PI : 0.; - return (localPhi*localPhi < m_boundValues[CylinderBounds::bv_halfPhiSector]*m_boundValues[CylinderBounds::bv_halfPhiSector]); - } - - inline bool CylinderBounds::insideLocZ(double z, double tol2) const - { - return (m_boundValues[CylinderBounds::bv_halfZ]+tol2)-fabs(z) > 0.; - } - - inline bool CylinderBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { - bool insideRphi = false; - if (fabs(m_boundValues[CylinderBounds::bv_averagePhi])<10e-7) - insideRphi = ( fabs(locpo[locRPhi]/m_boundValues[CylinderBounds::bv_radius]) < (m_boundValues[CylinderBounds::bv_halfPhiSector]+tol1) ) ; - else { - double localPhi = (locpo[locRPhi]/m_boundValues[CylinderBounds::bv_radius])-m_boundValues[CylinderBounds::bv_averagePhi]; - localPhi -= (localPhi > M_PI) ? 2.*M_PI : 0.; - insideRphi = ( localPhi < (m_boundValues[CylinderBounds::bv_halfPhiSector]+tol1) ) ; - } - return (insideRphi); - } - - inline bool CylinderBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return insideLocZ(locpo[locZ],tol2); } - - inline bool CylinderBounds::insideRadius(const Amg::Vector2D& locpo, double tol) const + @todo update the documentation picture for cylinder segments + + @image html CylinderBounds.gif + + @author Andreas.Salzburger@cern.ch + */ + +class CylinderBounds : public SurfaceBounds +{ +public: + /** BoundValues for readablility */ + enum BoundValues { - return ( this->inside(locpo,tol,0) && fabs(locpo[locR])< m_boundValues[CylinderBounds::bv_radius] + tol); + bv_radius = 0, + bv_averagePhi = 1, + bv_halfPhiSector = 2, + bv_halfZ = 3, + bv_length = 4 + }; + + /**Default Constructor*/ + CylinderBounds(); + + /**Constructor - full cylinder */ + CylinderBounds(double radius, double halez); + + /**Constructor - cylinder segment */ + CylinderBounds(double radius, double halfphi, double halez); + + /**Constructor - cylinder segment with given averagePhi, not supposed for CylinderSurfaces*/ + CylinderBounds(double radius, double halfphi, double avphi, double halez); + + /**Copy Constructor */ + CylinderBounds(const CylinderBounds& cylbo); + + /**Destructor */ + virtual ~CylinderBounds(); + + /**Assignment operator*/ + CylinderBounds& operator=(const CylinderBounds& cylbo); + + /**Move assignment operator*/ + CylinderBounds& operator=(CylinderBounds&& cylbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor */ + virtual CylinderBounds* clone() const override; + + /** Return the bounds type */ + virtual BoundsType type() const override { return SurfaceBounds::Cylinder; } + + /**This method checks if a LocalPosition is inside z bounds and rphi value- interface method */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1, double tol2) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /**This method checks if a GlobalPosition is inside the Cylinder - not an interface method, + assumes that GlobalPosition is in the right frame*/ + bool inside3D(const Amg::Vector3D& gp, double tol1 = 0., double tol2 = 0.) const; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method checks if a LocalPosition is inside z bounds and inside the radius (for straws) */ + bool insideRadius(const Amg::Vector2D& locpo, double tol) const; + + /**This method returns the radius*/ + virtual double r() const override; + + /**This method returns the average phi*/ + double averagePhi() const; + + /**This method returns the halfPhiSector angle*/ + double halfPhiSector() const; + + /**This method returns the halflengthZ*/ + double halflengthZ() const; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** helper methods for the inside check */ + bool inside(double r, double phi, double z, double tol1, double tol2) const; + bool insideLocZ(double z, double tol2) const; + + /** internal storage of the geometry parameters */ + std::vector<TDD_real_t> m_boundValues; + bool m_checkPhi; +}; + +inline CylinderBounds* +CylinderBounds::clone() const +{ + return new CylinderBounds(*this); +} + +inline bool +CylinderBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + double z = locpo[locZ]; + bool insideZ = insideLocZ(z, tol2); + if (!insideZ) + return false; + // no check on Phi neccesary + if (!m_checkPhi) + return true; + // now check insidePhi + double localPhi = + (locpo[locRPhi] / m_boundValues[CylinderBounds::bv_radius]) - m_boundValues[CylinderBounds::bv_averagePhi]; + localPhi -= (localPhi > M_PI) ? 2. * M_PI : 0.; + return (localPhi * localPhi < (m_boundValues[CylinderBounds::bv_halfPhiSector] + tol1) * + (m_boundValues[CylinderBounds::bv_halfPhiSector] + tol1)); +} + +inline bool +CylinderBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0 || bchk.nSigmas == 0 || m_boundValues[CylinderBounds::bv_halfPhiSector] != M_PI) + return CylinderBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + double dphi = scResult.sinC * scResult.sinC * bchk.lCovariance(0, 0); + double dz = scResult.cosC * scResult.cosC * bchk.lCovariance(0, 1); + double max_ell = dphi > dz ? dphi : dz; + double limit = bchk.nSigmas * sqrt(max_ell); + return insideLocZ(locpo[locZ], limit); +} + +inline bool +CylinderBounds::inside3D(const Amg::Vector3D& glopo, double tol1, double tol2) const +{ + return inside(glopo.perp(), glopo.phi(), glopo.z(), tol1, tol2); +} + +inline bool +CylinderBounds::inside(double r, double phi, double z, double tol1, double tol2) const +{ + + bool insideZ = insideLocZ(z, tol2); + if (!insideZ) + return false; + double diffR = (m_boundValues[CylinderBounds::bv_radius] - r); + bool insideR = diffR * diffR < tol1 * tol1; + if (!insideR) + return false; + // now check insidePhi if needed + if (!m_checkPhi) + return true; + // phi needs to be checked + double localPhi = phi - m_boundValues[CylinderBounds::bv_averagePhi]; + localPhi -= (localPhi > M_PI) ? 2. * M_PI : 0.; + return (localPhi * localPhi < + m_boundValues[CylinderBounds::bv_halfPhiSector] * m_boundValues[CylinderBounds::bv_halfPhiSector]); +} + +inline bool +CylinderBounds::insideLocZ(double z, double tol2) const +{ + return (m_boundValues[CylinderBounds::bv_halfZ] + tol2) - fabs(z) > 0.; +} + +inline bool +CylinderBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + bool insideRphi = false; + if (fabs(m_boundValues[CylinderBounds::bv_averagePhi]) < 10e-7) + insideRphi = (fabs(locpo[locRPhi] / m_boundValues[CylinderBounds::bv_radius]) < + (m_boundValues[CylinderBounds::bv_halfPhiSector] + tol1)); + else { + double localPhi = + (locpo[locRPhi] / m_boundValues[CylinderBounds::bv_radius]) - m_boundValues[CylinderBounds::bv_averagePhi]; + localPhi -= (localPhi > M_PI) ? 2. * M_PI : 0.; + insideRphi = (localPhi < (m_boundValues[CylinderBounds::bv_halfPhiSector] + tol1)); } - - inline double CylinderBounds::r() const { return m_boundValues[CylinderBounds::bv_radius]; } - - inline double CylinderBounds::averagePhi() const { return m_boundValues[CylinderBounds::bv_averagePhi]; } - - inline double CylinderBounds::halfPhiSector() const { return m_boundValues[CylinderBounds::bv_halfPhiSector]; } - - inline double CylinderBounds::halflengthZ() const { return m_boundValues[CylinderBounds::bv_halfZ]; } - + return (insideRphi); } -#endif // TRKSURFACES_CYLINDERBOUNDS_H +inline bool +CylinderBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return insideLocZ(locpo[locZ], tol2); +} +inline bool +CylinderBounds::insideRadius(const Amg::Vector2D& locpo, double tol) const +{ + return (this->inside(locpo, tol, 0) && fabs(locpo[locR]) < m_boundValues[CylinderBounds::bv_radius] + tol); +} + +inline double +CylinderBounds::r() const +{ + return m_boundValues[CylinderBounds::bv_radius]; +} +inline double +CylinderBounds::averagePhi() const +{ + return m_boundValues[CylinderBounds::bv_averagePhi]; +} + +inline double +CylinderBounds::halfPhiSector() const +{ + return m_boundValues[CylinderBounds::bv_halfPhiSector]; +} + +inline double +CylinderBounds::halflengthZ() const +{ + return m_boundValues[CylinderBounds::bv_halfZ]; +} + +} + +#endif // TRKSURFACES_CYLINDERBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderSurface.h index 3337d47e2ef8808d72fee8055a9776d48be714e3..8c95bfe9f4949b47688fbe494100b93d3697c194 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/CylinderSurface.h @@ -9,285 +9,324 @@ #ifndef TRKSURFACES_CYLINDERSURFACE_H #define TRKSURFACES_CYLINDERSURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/CylinderBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" -#include "TrkEventPrimitives/LocalParameters.h" +// Trk #include "TrkDetDescrUtils/SharedObject.h" +#include "TrkEventPrimitives/LocalParameters.h" +#include "TrkEventPrimitives/ParamDefs.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/CylinderBounds.h" +#include "TrkSurfaces/Surface.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; -template< class SURFACE, class BOUNDS_CNV > class BoundSurfaceCnv_p1; +template<class SURFACE, class BOUNDS_CNV> +class BoundSurfaceCnv_p1; namespace Trk { - - template<int DIM, class T, class S> class ParametersT; - - /** - @class CylinderSurface - Class for a CylinderSurface in the ATLAS detector. - It inherits from Surface. - - The cylinder surface has a special role in the TrackingGeometry, - since it builds the surfaces of all TrackingVolumes at container level, - hence, to optimize speed in global to local transformations, - constructors w/o transform is possible, - assumint the identity transform to. - - @todo update for new Possibility of CylinderBounds - - @image html CylinderSurface.gif - - @author Andreas.Salzburger@cern.ch - */ - - class CylinderSurface : public Surface { - - public: - /**Default Constructor*/ - CylinderSurface(); - - /**Constructor from EigenTransform, radius and halflenght*/ - CylinderSurface(Amg::Transform3D* htrans, double radius, double hlength); - - /**Constructor from EigenTransform, radius halfphi, and halflenght*/ - CylinderSurface(Amg::Transform3D* htrans, double radius, double hphi, double hlength); - - /**Constructor from EigenTransform and CylinderBounds - - ownership of the bounds is passed */ - CylinderSurface(Amg::Transform3D* htrans, CylinderBounds* cbounds); - - /**Constructor from EigenTransform from unique_ptr. - - bounds is not set */ - CylinderSurface(std::unique_ptr<Amg::Transform3D> htrans); - - /** Constructor from radius and halflenght - speed optimized for concentric volumes */ - CylinderSurface(double radius, double hlength); - - /**Constructor from radius halfphi, and halflenght - speed optimized fron concentric volumes */ - CylinderSurface(double radius, double hphi, double hlength); - - /**Constructor from EigenTransform and CylinderBounds - - ownership of the bounds is passed - - speed optimized fron concentric volumes */ - CylinderSurface(CylinderBounds* cbounds); - - /**Copy constructor */ - CylinderSurface(const CylinderSurface& csf); - - /**Copy constructor with shift */ - CylinderSurface(const CylinderSurface& csf, const Amg::Transform3D& transf); - - /**Destructor*/ - virtual ~CylinderSurface(); - - /**Assignment operator*/ - CylinderSurface& operator=(const CylinderSurface& csf); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /**Implicit Constructor*/ - virtual CylinderSurface* clone() const override; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, CylinderSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, CylinderSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, CylinderSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, CylinderSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, CylinderSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, CylinderSurface>(position, momentum, charge, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, CylinderSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, CylinderSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, CylinderSurface>(position, momentum, charge, *this, cov); } - - /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface - - the default implementation is the the RotationMatrix3D of the transform */ - virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const override; - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Cylinder; } - - /** Returns a global reference point: - For the Cylinder this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ - Where @f$ \phi @f$ denotes the averagePhi() of the cylinderBounds. - */ - virtual const Amg::Vector3D& globalReferencePoint() const override; - - /**Return method for surface normal information - at a given local point, overwrites the normal() from base class.*/ - virtual const Amg::Vector3D& normal() const override; - - /**Return method for surface normal information - at a given local point, overwrites the normal() from base class.*/ - virtual const Amg::Vector3D* normal(const Amg::Vector2D& locpo) const override; - - /**Return method for the rotational symmetry axis - the z-Axis of the HepTransform */ - virtual const Amg::Vector3D& rotSymmetryAxis() const; - - /**This method returns the CylinderBounds by reference - (NoBounds is not possible for cylinder)*/ - virtual const CylinderBounds& bounds() const override; - - bool hasBounds() const; - - /**This method calls the inside method of CylinderBounds*/ - virtual bool insideBounds(const Amg::Vector2D& locpos, - double tol1=0., - double tol2=0.) const override; - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** Specialized for CylinderSurface : LocalParameters to Vector2D */ - virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; - - /** Specialized for CylinderSurface : LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** Specialized for CylinderSurface : GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - virtual bool isOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk=true, - double tol1=0., - double tol2=0.) const override; - - /** fast straight line intersection schema - provides closest intersection and (signed) path length - - <b>mathematical motivation:</b> - - The calculation will be done in the 3-dim frame of the cylinder, - i.e. the symmetry axis of the cylinder is the z-axis, x- and y-axis are perpenticular - to the the z-axis. In this frame the cylinder is centered around the origin. - Therefore the two points describing the line have to be first recalculated into the new frame. - Suppose, this is done, the intersection is straight forward:<br> - may @f$p_{1}=(p_{1x}, p_{1y}, p_{1z}), p_{2}=(p_{2x}, p_{2y}, p_{2z}) @f$the two points describing the 3D-line, - then the line in the \f$x-y@f$plane can be written as - @f$y=kx+d\f$, where @f$k =\frac{p_{2y}-p_{1y}}{p_{2x}-p_{1x}}@f$such as @f$d=\frac{p_{2x}p_{1y}-p_{1x}p_{2y}}{p_{2x}-p_{1x}},\f$<br> - and intersects with the corresponding circle @f$x^{2}+y^{2} = R^{2}. @f$<br> - The solutions can then be found by a simple quadratic equation and reinsertion into the line equation. - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir = false, - Trk::BoundaryCheck bchk = false) const override; - - /** fast distance to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const override; - - /** fast distance to Surface - with bounds directive*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool bound) const override; - - /** the pathCorrection for derived classes with thickness */ - virtual double pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::CylinderSurface"; } - - - protected: //!< data members - template< class SURFACE, class BOUNDS_CNV > friend class ::BoundSurfaceCnv_p1; - - SharedObject<const CylinderBounds> m_bounds; //!< bounds (shared) - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_referencePoint; //!< The global reference point (== a point on the surface) - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_rotSymmetryAxis; //!< The rotational symmetry axis - }; - - inline CylinderSurface* CylinderSurface::clone() const - { return new CylinderSurface(*this); } - - inline const Amg::Vector3D& CylinderSurface::normal() const - { return Surface::normal(); } - - inline const Amg::Vector3D* CylinderSurface::normal(const Amg::Vector2D& lp) const + +template<int DIM, class T, class S> +class ParametersT; + +/** + @class CylinderSurface + Class for a CylinderSurface in the ATLAS detector. + It inherits from Surface. + + The cylinder surface has a special role in the TrackingGeometry, + since it builds the surfaces of all TrackingVolumes at container level, + hence, to optimize speed in global to local transformations, + constructors w/o transform is possible, + assumint the identity transform to. + + @todo update for new Possibility of CylinderBounds + + @image html CylinderSurface.gif + + @author Andreas.Salzburger@cern.ch + */ + +class CylinderSurface : public Surface +{ + +public: + /**Default Constructor*/ + CylinderSurface(); + + /**Constructor from EigenTransform, radius and halflenght*/ + CylinderSurface(Amg::Transform3D* htrans, double radius, double hlength); + + /**Constructor from EigenTransform, radius halfphi, and halflenght*/ + CylinderSurface(Amg::Transform3D* htrans, double radius, double hphi, double hlength); + + /**Constructor from EigenTransform and CylinderBounds + - ownership of the bounds is passed */ + CylinderSurface(Amg::Transform3D* htrans, CylinderBounds* cbounds); + + /**Constructor from EigenTransform from unique_ptr. + - bounds is not set */ + CylinderSurface(std::unique_ptr<Amg::Transform3D> htrans); + + /** Constructor from radius and halflenght - speed optimized for concentric volumes */ + CylinderSurface(double radius, double hlength); + + /**Constructor from radius halfphi, and halflenght - speed optimized fron concentric volumes */ + CylinderSurface(double radius, double hphi, double hlength); + + /**Constructor from EigenTransform and CylinderBounds + - ownership of the bounds is passed + - speed optimized fron concentric volumes */ + CylinderSurface(CylinderBounds* cbounds); + + /**Copy constructor */ + CylinderSurface(const CylinderSurface& csf); + + /**Copy constructor with shift */ + CylinderSurface(const CylinderSurface& csf, const Amg::Transform3D& transf); + + /**Destructor*/ + virtual ~CylinderSurface(); + + /**Assignment operator*/ + CylinderSurface& operator=(const CylinderSurface& csf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /**Implicit Constructor*/ + virtual CylinderSurface* clone() const override; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, CylinderSurface>* createTrackParameters( + double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - double phi = lp[Trk::locRPhi]/(bounds().r()); - Amg::Vector3D localNormal(cos(phi), sin(phi), 0.); - return new Amg::Vector3D(transform().rotation()*localNormal); - } + return new ParametersT<5, Charged, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); + } - inline double CylinderSurface::pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, CylinderSurface>* createTrackParameters( + const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override { - // the global normal vector is pos-center.unit() - at the z of the position @TODO make safe for tilt - Amg::Vector3D pcT(pos.x()-center().x(),pos.y()-center().y(),0.) ; - Amg::Vector3D normalT(pcT.unit()); // transverse normal - double cosAlpha = normalT.dot(mom.unit()); - return ( cosAlpha!=0 ? fabs(1./cosAlpha) : 1. ); //ST undefined for cosAlpha=0 + return new ParametersT<5, Charged, CylinderSurface>(position, momentum, charge, *this, cov); } - inline const CylinderBounds& CylinderSurface::bounds() const - { return *(m_bounds.get()); } + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, CylinderSurface>* createNeutralParameters( + double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); + } - inline bool CylinderSurface::hasBounds() const - { return m_bounds.get() != nullptr; } + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, CylinderSurface>* createNeutralParameters( + const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, CylinderSurface>(position, momentum, charge, *this, cov); + } - inline bool CylinderSurface::insideBounds(const Amg::Vector2D& locpos, - double tol1, - double tol2) const - { return bounds().inside(locpos,tol1,tol2); } - - inline bool CylinderSurface::insideBoundsCheck(const Amg::Vector2D& locpos, - const BoundaryCheck& bchk) const - {return bounds().inside(locpos,bchk);} - + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, CylinderSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, CylinderSurface>(l1, l2, phi, theta, qop, *this, cov); + } - inline const Amg::Vector2D CylinderSurface::localParametersToPosition(const LocalParameters& locpars) const + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, CylinderSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const { - if (locpars.contains(Trk::locRPhi) && locpars.contains(Trk::locZ)) - return Amg::Vector2D(locpars[Trk::locRPhi], locpars[Trk::locZ]); - if (locpars.contains(Trk::locRPhi)) - return Amg::Vector2D(locpars[Trk::locRPhi], 0.); - if (locpars.contains(Trk::locZ)) - return Amg::Vector2D(bounds().r(), locpars[Trk::locZ]); - return Amg::Vector2D(bounds().r(), 0.); + return new ParametersT<DIM, T, CylinderSurface>(position, momentum, charge, *this, cov); } - -} // end of namespace -#endif // TRKSURFACES_CYLINDERSURFACE_H + /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface + - the default implementation is the the RotationMatrix3D of the transform */ + virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom) const override; + + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Cylinder; } + + /** Returns a global reference point: + For the Cylinder this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ + Where @f$ \phi @f$ denotes the averagePhi() of the cylinderBounds. + */ + virtual const Amg::Vector3D& globalReferencePoint() const override; + + /**Return method for surface normal information + at a given local point, overwrites the normal() from base class.*/ + virtual const Amg::Vector3D& normal() const override; + + /**Return method for surface normal information + at a given local point, overwrites the normal() from base class.*/ + virtual const Amg::Vector3D* normal(const Amg::Vector2D& locpo) const override; + + /**Return method for the rotational symmetry axis - the z-Axis of the HepTransform */ + virtual const Amg::Vector3D& rotSymmetryAxis() const; + + /**This method returns the CylinderBounds by reference + (NoBounds is not possible for cylinder)*/ + virtual const CylinderBounds& bounds() const override; + + bool hasBounds() const; + + /**This method calls the inside method of CylinderBounds*/ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + + /** Specialized for CylinderSurface : LocalParameters to Vector2D */ + virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; + + /** Specialized for CylinderSurface : LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** Specialized for CylinderSurface : GlobalToLocal method without dynamic memory allocation - boolean checks if on + * surface */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const override; + + /** fast straight line intersection schema - provides closest intersection and (signed) path length + + <b>mathematical motivation:</b> + + The calculation will be done in the 3-dim frame of the cylinder, + i.e. the symmetry axis of the cylinder is the z-axis, x- and y-axis are perpenticular + to the the z-axis. In this frame the cylinder is centered around the origin. + Therefore the two points describing the line have to be first recalculated into the new frame. + Suppose, this is done, the intersection is straight forward:<br> + may @f$p_{1}=(p_{1x}, p_{1y}, p_{1z}), p_{2}=(p_{2x}, p_{2y}, p_{2z}) @f$the two points describing the 3D-line, + then the line in the \f$x-y@f$plane can be written as + @f$y=kx+d\f$, where @f$k =\frac{p_{2y}-p_{1y}}{p_{2x}-p_{1x}}@f$such as + @f$d=\frac{p_{2x}p_{1y}-p_{1x}p_{2y}}{p_{2x}-p_{1x}},\f$<br> and intersects with the corresponding circle + @f$x^{2}+y^{2} = R^{2}. @f$<br> The solutions can then be found by a simple quadratic equation and reinsertion into + the line equation. + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir = false, + Trk::BoundaryCheck bchk = false) const override; + /** fast distance to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + /** fast distance to Surface - with bounds directive*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool bound) const override; + + /** the pathCorrection for derived classes with thickness */ + virtual double pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::CylinderSurface"; } + +protected: //!< data members + template<class SURFACE, class BOUNDS_CNV> + friend class ::BoundSurfaceCnv_p1; + + SharedObject<const CylinderBounds> m_bounds; //!< bounds (shared) + CxxUtils::CachedUniquePtrT<Amg::Vector3D> + m_referencePoint; //!< The global reference point (== a point on the surface) + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_rotSymmetryAxis; //!< The rotational symmetry axis +}; + +inline CylinderSurface* +CylinderSurface::clone() const +{ + return new CylinderSurface(*this); +} + +inline const Amg::Vector3D& +CylinderSurface::normal() const +{ + return Surface::normal(); +} + +inline const Amg::Vector3D* +CylinderSurface::normal(const Amg::Vector2D& lp) const +{ + double phi = lp[Trk::locRPhi] / (bounds().r()); + Amg::Vector3D localNormal(cos(phi), sin(phi), 0.); + return new Amg::Vector3D(transform().rotation() * localNormal); +} + +inline double +CylinderSurface::pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const +{ + // the global normal vector is pos-center.unit() - at the z of the position @TODO make safe for tilt + Amg::Vector3D pcT(pos.x() - center().x(), pos.y() - center().y(), 0.); + Amg::Vector3D normalT(pcT.unit()); // transverse normal + double cosAlpha = normalT.dot(mom.unit()); + return (cosAlpha != 0 ? fabs(1. / cosAlpha) : 1.); // ST undefined for cosAlpha=0 +} + +inline const CylinderBounds& +CylinderSurface::bounds() const +{ + return *(m_bounds.get()); +} + +inline bool +CylinderSurface::hasBounds() const +{ + return m_bounds.get() != nullptr; +} + +inline bool +CylinderSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + return bounds().inside(locpos, tol1, tol2); +} + +inline bool +CylinderSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const +{ + return bounds().inside(locpos, bchk); +} + +inline const Amg::Vector2D +CylinderSurface::localParametersToPosition(const LocalParameters& locpars) const +{ + if (locpars.contains(Trk::locRPhi) && locpars.contains(Trk::locZ)) + return Amg::Vector2D(locpars[Trk::locRPhi], locpars[Trk::locZ]); + if (locpars.contains(Trk::locRPhi)) + return Amg::Vector2D(locpars[Trk::locRPhi], 0.); + if (locpars.contains(Trk::locZ)) + return Amg::Vector2D(bounds().r(), locpars[Trk::locZ]); + return Amg::Vector2D(bounds().r(), 0.); +} + +} // end of namespace + +#endif // TRKSURFACES_CYLINDERSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiamondBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiamondBounds.h index 7ccec47e54da44e311c19d597d2f0f74245b61c6..212401fd19cef6533ae7a69dfa4fa2859160dc15 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiamondBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiamondBounds.h @@ -9,213 +9,263 @@ #ifndef TRKSURFACES_DIAMONDDBOUNDS_H #define TRKSURFACES_DIAMONDDBOUNDS_H -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" #include <math.h> class MsgStream; class DiamondBoundsCnv_p1; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class DiamondBounds - Bounds for a double trapezoidal ("diamond"), planar Surface. - - @author Andreas.Salzburger@cern.ch, Sarka.Todorova@cern.ch - */ - - class DiamondBounds : public SurfaceBounds { - - public: - /** BoundValues for better readability */ - enum BoundValues { - bv_minHalfX = 0, - bv_medHalfX = 1, - bv_maxHalfX = 2, - bv_halfY1 = 3, - bv_halfY2 = 4, - bv_length = 5 - }; - - /**Default Constructor, needed for persistency*/ - DiamondBounds(); - - /**Constructor for symmetric Diamond*/ - DiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2); - - /**Copy constructor*/ - DiamondBounds(const DiamondBounds& diabo); - - /**Destructor*/ - virtual ~DiamondBounds(); - - /**Virtual constructor*/ - DiamondBounds* clone() const override; - - /**Assignment operator*/ - DiamondBounds& operator=(const DiamondBounds& sbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& diabo) const override; - - /** Return the bounds type */ - virtual BoundsType type() const override { return SurfaceBounds::Diamond; } - - /**This method returns the halflength in X at minimal Y (first coordinate of local surface frame)*/ - double minHalflengthX() const; - - /**This method returns the (maximal) halflength in X (first coordinate of local surface frame)*/ - double medHalflengthX() const; - - /**This method returns the halflength in X at maximal Y (first coordinate of local surface frame)*/ - double maxHalflengthX() const; - - /**This method returns the halflength in Y of trapezoid at negative/positive Y (second coordinate)*/ - double halflengthY1() const; - double halflengthY2() const; - - /**This method returns the maximal extension on the local plane*/ - virtual double r() const override; - - /**This method returns the opening angle alpha in point A */ - double alpha1() const; - - /**This method returns the opening angle alpha in point A' */ - double alpha2() const; - - /** The orientation of the Diamond is according to the figure */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! - */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! - */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - friend class ::DiamondBoundsCnv_p1; - - /** inside() method for a full symmetric diamond */ - bool insideFull(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const; - - /** initialize the alpha1/2 cache - needed also for object persistency */ - virtual void initCache() override; - - /** Internal parameters stored in the geometry */ - std::vector<TDD_real_t> m_boundValues; - TDD_real_t m_alpha1; - TDD_real_t m_alpha2; - - }; +/** + @class DiamondBounds + Bounds for a double trapezoidal ("diamond"), planar Surface. + + @author Andreas.Salzburger@cern.ch, Sarka.Todorova@cern.ch + */ - inline DiamondBounds* DiamondBounds::clone() const { return new DiamondBounds(*this); } - - inline double DiamondBounds::minHalflengthX() const { return m_boundValues[DiamondBounds::bv_minHalfX]; } - - inline double DiamondBounds::medHalflengthX() const { return m_boundValues[DiamondBounds::bv_medHalfX]; } - - inline double DiamondBounds::maxHalflengthX() const { return m_boundValues[DiamondBounds::bv_maxHalfX]; } - - inline double DiamondBounds::halflengthY1() const { return m_boundValues[DiamondBounds::bv_halfY1]; } - - inline double DiamondBounds::halflengthY2() const { return m_boundValues[DiamondBounds::bv_halfY2]; } - - inline double DiamondBounds::r() const - { return sqrt(m_boundValues[DiamondBounds::bv_medHalfX]*m_boundValues[DiamondBounds::bv_medHalfX] - + m_boundValues[DiamondBounds::bv_halfY1]*m_boundValues[DiamondBounds::bv_halfY1]); } - - inline bool DiamondBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +class DiamondBounds : public SurfaceBounds +{ + +public: + /** BoundValues for better readability */ + enum BoundValues { - if(bchk.bcType==0) return DiamondBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) :bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - if ( locpo[Trk::locY] < -2*m_boundValues[DiamondBounds::bv_halfY1] - limit) return false; - if ( locpo[Trk::locY] > 2*m_boundValues[DiamondBounds::bv_halfY2] + limit) return false; - // a fast FALSE - double fabsX = fabs(locpo[Trk::locX]); - if (fabsX > (m_boundValues[DiamondBounds::bv_medHalfX] + limit)) return false; - // a fast TRUE - double min_ell = bchk.lCovariance(0,0) < bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - limit = bchk.nSigmas*sqrt(min_ell); - if (fabsX < (fmin(m_boundValues[DiamondBounds::bv_minHalfX],m_boundValues[DiamondBounds::bv_maxHalfX]) - limit)) return true; - // a fast TRUE - if (fabs(locpo[Trk::locY]) < (fmin(m_boundValues[DiamondBounds::bv_halfY1],m_boundValues[DiamondBounds::bv_halfY2]) - limit)) return true; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(5); - std::vector<Amg::Vector2D> elementP(6); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p << -m_boundValues[DiamondBounds::bv_minHalfX],-2.*m_boundValues[DiamondBounds::bv_halfY1]; - elementP[0] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[DiamondBounds::bv_medHalfX],0.; - elementP[1] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[DiamondBounds::bv_maxHalfX], 2.*m_boundValues[DiamondBounds::bv_halfY2]; - elementP[2] =( rotMatrix * (p - locpo) ); - p << m_boundValues[DiamondBounds::bv_maxHalfX], 2.*m_boundValues[DiamondBounds::bv_halfY2]; - elementP[3] =( rotMatrix * (p - locpo) ); - p << m_boundValues[DiamondBounds::bv_medHalfX], 0.; - elementP[4] =( rotMatrix * (p - locpo) ); - p << m_boundValues[DiamondBounds::bv_minHalfX], -2.*m_boundValues[DiamondBounds::bv_halfY1]; - elementP[5] =( rotMatrix * (p - locpo) ); - std::vector<Amg::Vector2D> axis = {normal*(elementP[1]-elementP[0]), normal*(elementP[2]-elementP[1]), normal*(elementP[3]-elementP[2]), normal*(elementP[4]-elementP[3]), normal*(elementP[5]-elementP[4])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(5); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - - inline bool DiamondBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (fabs(locpo[locX]) < m_boundValues[DiamondBounds::bv_medHalfX] + tol1); } - - inline bool DiamondBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return ((locpo[locY] > -2.*m_boundValues[DiamondBounds::bv_halfY1] - tol2) && (locpo[locY] < 2.*m_boundValues[DiamondBounds::bv_halfY2] + tol2) ); } - - inline void DiamondBounds::initCache() { - m_alpha1 = atan2(m_boundValues[DiamondBounds::bv_medHalfX]-m_boundValues[DiamondBounds::bv_minHalfX], 2.*m_boundValues[DiamondBounds::bv_halfY1]); - m_alpha2 = atan2(m_boundValues[DiamondBounds::bv_medHalfX]-m_boundValues[DiamondBounds::bv_maxHalfX], 2.*m_boundValues[DiamondBounds::bv_halfY2]); - } - + bv_minHalfX = 0, + bv_medHalfX = 1, + bv_maxHalfX = 2, + bv_halfY1 = 3, + bv_halfY2 = 4, + bv_length = 5 + }; + + /**Default Constructor, needed for persistency*/ + DiamondBounds(); + + /**Constructor for symmetric Diamond*/ + DiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2); + + /**Copy constructor*/ + DiamondBounds(const DiamondBounds& diabo); + + /**Destructor*/ + virtual ~DiamondBounds(); + + /**Virtual constructor*/ + DiamondBounds* clone() const override; + + /**Assignment operator*/ + DiamondBounds& operator=(const DiamondBounds& sbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& diabo) const override; + + /** Return the bounds type */ + virtual BoundsType type() const override { return SurfaceBounds::Diamond; } + + /**This method returns the halflength in X at minimal Y (first coordinate of local surface frame)*/ + double minHalflengthX() const; + + /**This method returns the (maximal) halflength in X (first coordinate of local surface frame)*/ + double medHalflengthX() const; + + /**This method returns the halflength in X at maximal Y (first coordinate of local surface frame)*/ + double maxHalflengthX() const; + + /**This method returns the halflength in Y of trapezoid at negative/positive Y (second coordinate)*/ + double halflengthY1() const; + double halflengthY2() const; + + /**This method returns the maximal extension on the local plane*/ + virtual double r() const override; + + /**This method returns the opening angle alpha in point A */ + double alpha1() const; + + /**This method returns the opening angle alpha in point A' */ + double alpha2() const; + + /** The orientation of the Diamond is according to the figure */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! + */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! + */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + friend class ::DiamondBoundsCnv_p1; + + /** inside() method for a full symmetric diamond */ + bool insideFull(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const; + + /** initialize the alpha1/2 cache - needed also for object persistency */ + virtual void initCache() override; + + /** Internal parameters stored in the geometry */ + std::vector<TDD_real_t> m_boundValues; + TDD_real_t m_alpha1; + TDD_real_t m_alpha2; +}; + +inline DiamondBounds* +DiamondBounds::clone() const +{ + return new DiamondBounds(*this); +} + +inline double +DiamondBounds::minHalflengthX() const +{ + return m_boundValues[DiamondBounds::bv_minHalfX]; +} + +inline double +DiamondBounds::medHalflengthX() const +{ + return m_boundValues[DiamondBounds::bv_medHalfX]; +} + +inline double +DiamondBounds::maxHalflengthX() const +{ + return m_boundValues[DiamondBounds::bv_maxHalfX]; +} + +inline double +DiamondBounds::halflengthY1() const +{ + return m_boundValues[DiamondBounds::bv_halfY1]; +} + +inline double +DiamondBounds::halflengthY2() const +{ + return m_boundValues[DiamondBounds::bv_halfY2]; +} + +inline double +DiamondBounds::r() const +{ + return sqrt(m_boundValues[DiamondBounds::bv_medHalfX] * m_boundValues[DiamondBounds::bv_medHalfX] + + m_boundValues[DiamondBounds::bv_halfY1] * m_boundValues[DiamondBounds::bv_halfY1]); +} + +inline bool +DiamondBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0) + return DiamondBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + if (locpo[Trk::locY] < -2 * m_boundValues[DiamondBounds::bv_halfY1] - limit) + return false; + if (locpo[Trk::locY] > 2 * m_boundValues[DiamondBounds::bv_halfY2] + limit) + return false; + // a fast FALSE + double fabsX = fabs(locpo[Trk::locX]); + if (fabsX > (m_boundValues[DiamondBounds::bv_medHalfX] + limit)) + return false; + // a fast TRUE + double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + limit = bchk.nSigmas * sqrt(min_ell); + if (fabsX < (fmin(m_boundValues[DiamondBounds::bv_minHalfX], m_boundValues[DiamondBounds::bv_maxHalfX]) - limit)) + return true; + // a fast TRUE + if (fabs(locpo[Trk::locY]) < + (fmin(m_boundValues[DiamondBounds::bv_halfY1], m_boundValues[DiamondBounds::bv_halfY2]) - limit)) + return true; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(5); + std::vector<Amg::Vector2D> elementP(6); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << -m_boundValues[DiamondBounds::bv_minHalfX], -2. * m_boundValues[DiamondBounds::bv_halfY1]; + elementP[0] = (rotMatrix * (p - locpo)); + p << -m_boundValues[DiamondBounds::bv_medHalfX], 0.; + elementP[1] = (rotMatrix * (p - locpo)); + p << -m_boundValues[DiamondBounds::bv_maxHalfX], 2. * m_boundValues[DiamondBounds::bv_halfY2]; + elementP[2] = (rotMatrix * (p - locpo)); + p << m_boundValues[DiamondBounds::bv_maxHalfX], 2. * m_boundValues[DiamondBounds::bv_halfY2]; + elementP[3] = (rotMatrix * (p - locpo)); + p << m_boundValues[DiamondBounds::bv_medHalfX], 0.; + elementP[4] = (rotMatrix * (p - locpo)); + p << m_boundValues[DiamondBounds::bv_minHalfX], -2. * m_boundValues[DiamondBounds::bv_halfY1]; + elementP[5] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]), + normal * (elementP[2] - elementP[1]), + normal * (elementP[3] - elementP[2]), + normal * (elementP[4] - elementP[3]), + normal * (elementP[5] - elementP[4]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(5); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +DiamondBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (fabs(locpo[locX]) < m_boundValues[DiamondBounds::bv_medHalfX] + tol1); +} + +inline bool +DiamondBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return ((locpo[locY] > -2. * m_boundValues[DiamondBounds::bv_halfY1] - tol2) && + (locpo[locY] < 2. * m_boundValues[DiamondBounds::bv_halfY2] + tol2)); +} + +inline void +DiamondBounds::initCache() +{ + m_alpha1 = atan2(m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_minHalfX], + 2. * m_boundValues[DiamondBounds::bv_halfY1]); + m_alpha2 = atan2(m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_maxHalfX], + 2. * m_boundValues[DiamondBounds::bv_halfY2]); +} + } // end of namespace #endif // TRKSURFACES_DIAMONDBOUNDS_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscBounds.h index d914e9186d27be3c6e961f1f00dae074c26d8802..a3ea6150c0b13ab5365ee63740dcfe193ae55f10 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscBounds.h @@ -10,292 +10,338 @@ #define TRKSURFACES_DISCBOUNDS_H // Trk -#include "TrkSurfaces/SurfaceBounds.h" #include "TrkEventPrimitives/ParamDefs.h" -// -#include <math.h> +#include "TrkSurfaces/SurfaceBounds.h" +// #include <cmath> -//Eigen +#include <math.h> +// Eigen #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class DiscBounds - - Class to describe the bounds for a planar DiscSurface. - By providing an argument for hphisec, the bounds can - be restricted to a phirange around the center position. - - @image html DiscBounds.gif - - @author Andreas.Salzburger@cern.ch - */ - - class DiscBounds : public SurfaceBounds { - - public: - /** enumeration for readability */ - enum BoundValues { - bv_rMin = 0, - bv_rMax = 1, - bv_averagePhi = 2, - bv_halfPhiSector = 3, - bv_length = 4 - }; - /**Default Constructor*/ - DiscBounds(); - - /**Constructor for full disc of symmetric disc around phi=0*/ - DiscBounds(double minrad, double maxrad, double hphisec=M_PI); - - /**Constructor for a symmetric disc around phi != 0*/ - DiscBounds(double minrad, double maxrad, double avephi, double hphisec); - - /**Default copy constructor*/ - DiscBounds(const DiscBounds&) = default; - - /**Destructor*/ - virtual ~DiscBounds(); - - /**Default move constructor*/ - DiscBounds(DiscBounds&& discbo) = default; - - /**Default move assignment operator*/ - DiscBounds& operator=(DiscBounds&& discbo) = default; - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor*/ - virtual DiscBounds* clone() const override; - - /** Return the type - mainly for persistency */ - virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Disc; } - - /**This method cheks if the radius given in the LocalPosition is inside [rMin,rMax] - if only tol1 is given and additional in the phi sector is tol2 is given */ - virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns inner radius*/ - double rMin() const; - - /**This method returns outer radius*/ - double rMax() const; - - /**This method returns the maximum expansion on the plane (=rMax)*/ - virtual double r() const override; - - /**This method returns the average phi*/ - double averagePhi() const; - - /**This method returns the halfPhiSector which is covered by the disc*/ - double halfPhiSector() const; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** Internal members of the bounds (float/double)*/ - std::vector<TDD_real_t> m_boundValues; - +/** + @class DiscBounds + + Class to describe the bounds for a planar DiscSurface. + By providing an argument for hphisec, the bounds can + be restricted to a phirange around the center position. + + @image html DiscBounds.gif + + @author Andreas.Salzburger@cern.ch + */ + +class DiscBounds : public SurfaceBounds +{ + +public: + /** enumeration for readability */ + enum BoundValues + { + bv_rMin = 0, + bv_rMax = 1, + bv_averagePhi = 2, + bv_halfPhiSector = 3, + bv_length = 4 }; - - inline DiscBounds* DiscBounds::clone() const - { return new DiscBounds(*this); } - - inline bool DiscBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const - { - double alpha = fabs(locpo[locPhi]-m_boundValues[DiscBounds::bv_averagePhi]); - if ( alpha>M_PI) alpha = 2*M_PI - alpha; - bool insidePhi = (alpha <= (m_boundValues[DiscBounds::bv_halfPhiSector]+tol2)); - return ( locpo[locR] > (m_boundValues[DiscBounds::bv_rMin] - tol1) && locpo[locR] < (m_boundValues[DiscBounds::bv_rMax] + tol1) && insidePhi ); - } - - inline bool DiscBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const + /**Default Constructor*/ + DiscBounds(); + + /**Constructor for full disc of symmetric disc around phi=0*/ + DiscBounds(double minrad, double maxrad, double hphisec = M_PI); + + /**Constructor for a symmetric disc around phi != 0*/ + DiscBounds(double minrad, double maxrad, double avephi, double hphisec); + + /**Default copy constructor*/ + DiscBounds(const DiscBounds&) = default; + + /**Destructor*/ + virtual ~DiscBounds(); + + /**Default move constructor*/ + DiscBounds(DiscBounds&& discbo) = default; + + /**Default move assignment operator*/ + DiscBounds& operator=(DiscBounds&& discbo) = default; + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor*/ + virtual DiscBounds* clone() const override; + + /** Return the type - mainly for persistency */ + virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Disc; } + + /**This method cheks if the radius given in the LocalPosition is inside [rMin,rMax] + if only tol1 is given and additional in the phi sector is tol2 is given */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns inner radius*/ + double rMin() const; + + /**This method returns outer radius*/ + double rMax() const; + + /**This method returns the maximum expansion on the plane (=rMax)*/ + virtual double r() const override; + + /**This method returns the average phi*/ + double averagePhi() const; + + /**This method returns the halfPhiSector which is covered by the disc*/ + double halfPhiSector() const; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** Internal members of the bounds (float/double)*/ + std::vector<TDD_real_t> m_boundValues; +}; + +inline DiscBounds* +DiscBounds::clone() const +{ + return new DiscBounds(*this); +} + +inline bool +DiscBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + double alpha = fabs(locpo[locPhi] - m_boundValues[DiscBounds::bv_averagePhi]); + if (alpha > M_PI) + alpha = 2 * M_PI - alpha; + bool insidePhi = (alpha <= (m_boundValues[DiscBounds::bv_halfPhiSector] + tol2)); + return (locpo[locR] > (m_boundValues[DiscBounds::bv_rMin] - tol1) && + locpo[locR] < (m_boundValues[DiscBounds::bv_rMax] + tol1) && insidePhi); +} + +inline bool +DiscBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0 || bchk.nSigmas == 0 || m_boundValues[DiscBounds::bv_rMin] != 0 || + m_boundValues[DiscBounds::bv_halfPhiSector] != M_PI) + return DiscBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + sincosCache scResult = bchk.FastSinCos(locpo(1, 0)); + double dx = bchk.nSigmas * sqrt(bchk.lCovariance(0, 0)); + double dy = bchk.nSigmas * sqrt(scResult.sinC * scResult.sinC * bchk.lCovariance(0, 0) + + locpo(0, 0) * locpo(0, 0) * scResult.cosC * scResult.cosC * bchk.lCovariance(1, 1) + + 2 * scResult.cosC * scResult.sinC * locpo(0, 0) * bchk.lCovariance(0, 1)); + double max_ell = dx > dy ? dx : dy; + if (locpo(0, 0) > (m_boundValues[DiscBounds::bv_rMax] + max_ell)) + return false; + // a fast TRUE + double min_ell = dx < dy ? dx : dy; + if (locpo(0, 0) < (m_boundValues[DiscBounds::bv_rMax] + min_ell)) + return true; + + // we are not using the KDOP approach here but rather a highly optimized one + class EllipseCollisionTest { - if(bchk.bcType==0 || bchk.nSigmas==0 || m_boundValues[DiscBounds::bv_rMin]!=0 || m_boundValues[DiscBounds::bv_halfPhiSector]!=M_PI) return DiscBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - sincosCache scResult = bchk.FastSinCos(locpo(1,0)); - double dx = bchk.nSigmas*sqrt(bchk.lCovariance(0,0)); - double dy = bchk.nSigmas*sqrt(scResult.sinC*scResult.sinC*bchk.lCovariance(0,0) + locpo(0,0)*locpo(0,0)*scResult.cosC*scResult.cosC*bchk.lCovariance(1,1)+2*scResult.cosC*scResult.sinC*locpo(0,0)*bchk.lCovariance(0,1)); - double max_ell = dx > dy ? dx : dy; - if (locpo(0,0) > ( m_boundValues[DiscBounds::bv_rMax] + max_ell)) return false; - // a fast TRUE - double min_ell = dx < dy ? dx : dy; - if (locpo(0,0) < ( m_boundValues[DiscBounds::bv_rMax] + min_ell)) return true; - - // we are not using the KDOP approach here but rather a highly optimized one - class EllipseCollisionTest { - private: - int m_maxIterations; - bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const { - std::vector<double> innerPolygonCoef(m_maxIterations+1); - std::vector<double> outerPolygonCoef(m_maxIterations+1); - /* - t2______t4 - --_ \ - --_ \ /¨¨¨ ¨¨\ - t1 = (0, 0) ( t ) - | \ \__ _ / - | \ - | t3 - | / - | / - t0 - */ - for (int t = 1; t <= m_maxIterations; t++) { - int numNodes = 4 << t; - innerPolygonCoef[t] = 0.5/cos(4*acos(0.0)/numNodes); - double c1x = (c0x + c2x)*innerPolygonCoef[t]; - double c1y = (c0y + c2y)*innerPolygonCoef[t]; - double tx = x - c1x; // t indicates a translated coordinate - double ty = y - c1y; - if (tx*tx + ty*ty <= rr) { - return true; // collision with t1 - } - double t2x = c2x - c1x; - double t2y = c2y - c1y; - if (tx*t2x + ty*t2y >= 0 && tx*t2x + ty*t2y <= t2x*t2x + t2y*t2y && - (ty*t2x - tx*t2y >= 0 || rr*(t2x*t2x + t2y*t2y) >= (ty*t2x - tx*t2y)*(ty*t2x - tx*t2y))) { - return true; // collision with t1---t2 - } - double t0x = c0x - c1x; - double t0y = c0y - c1y; - if (tx*t0x + ty*t0y >= 0 && tx*t0x + ty*t0y <= t0x*t0x + t0y*t0y && - (ty*t0x - tx*t0y <= 0 || rr*(t0x*t0x + t0y*t0y) >= (ty*t0x - tx*t0y)*(ty*t0x - tx*t0y))) { - return true; // collision with t1---t0 - } - outerPolygonCoef[t] = 0.5/(cos(2*acos(0.0)/numNodes)*cos(2*acos(0.0)/numNodes)); - double c3x = (c0x + c1x)*outerPolygonCoef[t]; - double c3y = (c0y + c1y)*outerPolygonCoef[t]; - if ((c3x-x)*(c3x-x) + (c3y-y)*(c3y-y) < rr) { - c2x = c1x; - c2y = c1y; - continue; // t3 is inside circle - } - double c4x = c1x - c3x + c1x; - double c4y = c1y - c3y + c1y; - if ((c4x-x)*(c4x-x) + (c4y-y)*(c4y-y) < rr) { - c0x = c1x; - c0y = c1y; - continue; // t4 is inside circle - } - double t3x = c3x - c1x; - double t3y = c3y - c1y; - if (ty*t3x - tx*t3y <= 0 || rr*(t3x*t3x + t3y*t3y) > (ty*t3x - tx*t3y)*(ty*t3x - tx*t3y)) { - if (tx*t3x + ty*t3y > 0) { - if (std::abs(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c3x)*(c0x-c3x) + (y-c3y)*(c0y-c3y) >= 0) { - c2x = c1x; - c2y = c1y; - continue; // circle center is inside t0---t1---t3 - } - } else if (-(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c4x)*(c2x-c4x) + (y-c4y)*(c2y-c4y) >= 0) { - c0x = c1x; - c0y = c1y; - continue; // circle center is inside t1---t2---t4 - } - } - return false; // no collision possible - } - return false; // out of iterations so it is unsure if there was a collision. But have to return something. - } - public: - // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of radius r at (x1, y1) - bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const { - double x = fabs(x1 - x0); - double y = fabs(y1 - y0); - if (x*x + (h - y)*(h - y) <= r*r || (w - x)*(w - x) + y*y <= r*r || x*h + y*w <= w*h // collision with (0, h) - || ((x*h + y*w - w*h)*(x*h + y*w - w*h) <= r*r*(w*w + h*h) && x*w - y*h >= -h*h && x*w - y*h <= w*w)) { // collision with (0, h)---(w, 0) - return true; - } else { - if ((x-w)*(x-w) + (y-h)*(y-h) <= r*r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { - return iterate(x, y, w, 0, 0, h, r*r); // collision within triangle (0, h) (w, h) (0, 0) is possible - } - return false; - } - } - EllipseCollisionTest(int maxIterations) { - this->m_maxIterations = maxIterations; - } - }; - - EllipseCollisionTest test(4); - // convert to cartesian coordinates - AmgMatrix(2,2) covRotMatrix ; - covRotMatrix << scResult.cosC, -locpo(0,0)*scResult.sinC, - scResult.sinC, locpo(0,0)*scResult.cosC; - AmgMatrix(2,2) lCovarianceCar = covRotMatrix*bchk.lCovariance*covRotMatrix.transpose(); - Amg::Vector2D locpoCar(covRotMatrix(1,1), -covRotMatrix(0,1)); - - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - double w = bchk.nSigmas*sqrt( lCovarianceCar(0,0)); - double h = bchk.nSigmas*sqrt( lCovarianceCar(1,1)); - double x0 = 0; - double y0 = 0; - float theta = (lCovarianceCar(1,0) != 0 && (lCovarianceCar(1,1)-lCovarianceCar(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*lCovarianceCar(1,0)/(lCovarianceCar(1,1)-lCovarianceCar(0,0)) ) : 0.; - scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - Amg::Vector2D tmp = rotMatrix * (- locpoCar) ; - double x1 = tmp(0,0); - double y1 = tmp(1,0); - double r = m_boundValues[DiscBounds::bv_rMax]; - // check if ellipse and circle overlap and return result - return test.collide(x0, y0, w, h, x1, y1, r); - } - - inline bool DiscBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (locpo[locR] > (m_boundValues[DiscBounds::bv_rMin] -tol1) && locpo[locR] < (m_boundValues[DiscBounds::bv_rMax] + tol1)); } - - inline bool DiscBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { - double alpha = fabs(locpo[locPhi]-m_boundValues[DiscBounds::bv_averagePhi]); - if ( alpha > M_PI ) alpha = 2.*M_PI-alpha; - //alpha -= alpha > M_PI ? 2.*M_PI : 0.; - //alpha += alpha < -M_PI ? 2.*M_PI : 0.; - bool insidePhi = (alpha <= (m_boundValues[DiscBounds::bv_halfPhiSector]+tol2)); - return insidePhi; - } - - inline double DiscBounds::rMin() const { return m_boundValues[DiscBounds::bv_rMin]; } - - inline double DiscBounds::rMax() const { return m_boundValues[DiscBounds::bv_rMax]; } - - inline double DiscBounds::r() const { return m_boundValues[DiscBounds::bv_rMax]; } - - inline double DiscBounds::averagePhi() const { return m_boundValues[DiscBounds::bv_averagePhi]; } - - inline double DiscBounds::halfPhiSector() const { return m_boundValues[DiscBounds::bv_halfPhiSector]; } + private: + int m_maxIterations; + bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const + { + std::vector<double> innerPolygonCoef(m_maxIterations + 1); + std::vector<double> outerPolygonCoef(m_maxIterations + 1); + /* + t2______t4 + --_ \ + --_ \ /¨¨¨ ¨¨\ + t1 = (0, 0) ( t ) + | \ \__ _ / + | \ + | t3 + | / + | / + t0 + */ + for (int t = 1; t <= m_maxIterations; t++) { + int numNodes = 4 << t; + innerPolygonCoef[t] = 0.5 / cos(4 * acos(0.0) / numNodes); + double c1x = (c0x + c2x) * innerPolygonCoef[t]; + double c1y = (c0y + c2y) * innerPolygonCoef[t]; + double tx = x - c1x; // t indicates a translated coordinate + double ty = y - c1y; + if (tx * tx + ty * ty <= rr) { + return true; // collision with t1 + } + double t2x = c2x - c1x; + double t2y = c2y - c1y; + if (tx * t2x + ty * t2y >= 0 && tx * t2x + ty * t2y <= t2x * t2x + t2y * t2y && + (ty * t2x - tx * t2y >= 0 || + rr * (t2x * t2x + t2y * t2y) >= (ty * t2x - tx * t2y) * (ty * t2x - tx * t2y))) { + return true; // collision with t1---t2 + } + double t0x = c0x - c1x; + double t0y = c0y - c1y; + if (tx * t0x + ty * t0y >= 0 && tx * t0x + ty * t0y <= t0x * t0x + t0y * t0y && + (ty * t0x - tx * t0y <= 0 || + rr * (t0x * t0x + t0y * t0y) >= (ty * t0x - tx * t0y) * (ty * t0x - tx * t0y))) { + return true; // collision with t1---t0 + } + outerPolygonCoef[t] = 0.5 / (cos(2 * acos(0.0) / numNodes) * cos(2 * acos(0.0) / numNodes)); + double c3x = (c0x + c1x) * outerPolygonCoef[t]; + double c3y = (c0y + c1y) * outerPolygonCoef[t]; + if ((c3x - x) * (c3x - x) + (c3y - y) * (c3y - y) < rr) { + c2x = c1x; + c2y = c1y; + continue; // t3 is inside circle + } + double c4x = c1x - c3x + c1x; + double c4y = c1y - c3y + c1y; + if ((c4x - x) * (c4x - x) + (c4y - y) * (c4y - y) < rr) { + c0x = c1x; + c0y = c1y; + continue; // t4 is inside circle + } + double t3x = c3x - c1x; + double t3y = c3y - c1y; + if (ty * t3x - tx * t3y <= 0 || rr * (t3x * t3x + t3y * t3y) > (ty * t3x - tx * t3y) * (ty * t3x - tx * t3y)) { + if (tx * t3x + ty * t3y > 0) { + if (std::abs(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c3x) * (c0x - c3x) + (y - c3y) * (c0y - c3y) >= 0) { + c2x = c1x; + c2y = c1y; + continue; // circle center is inside t0---t1---t3 + } + } else if (-(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c4x) * (c2x - c4x) + (y - c4y) * (c2y - c4y) >= 0) { + c0x = c1x; + c0y = c1y; + continue; // circle center is inside t1---t2---t4 + } + } + return false; // no collision possible + } + return false; // out of iterations so it is unsure if there was a collision. But have to return something. + } -} // end of namespace + public: + // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of + // radius r at (x1, y1) + bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const + { + double x = fabs(x1 - x0); + double y = fabs(y1 - y0); + if (x * x + (h - y) * (h - y) <= r * r || (w - x) * (w - x) + y * y <= r * r || + x * h + y * w <= w * h // collision with (0, h) + || ((x * h + y * w - w * h) * (x * h + y * w - w * h) <= r * r * (w * w + h * h) && x * w - y * h >= -h * h && + x * w - y * h <= w * w)) { // collision with (0, h)---(w, 0) + return true; + } else { + if ((x - w) * (x - w) + (y - h) * (y - h) <= r * r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { + return iterate(x, y, w, 0, 0, h, r * r); // collision within triangle (0, h) (w, h) (0, 0) is possible + } + return false; + } + } + EllipseCollisionTest(int maxIterations) { this->m_maxIterations = maxIterations; } + }; + EllipseCollisionTest test(4); + // convert to cartesian coordinates + AmgMatrix(2, 2) covRotMatrix; + covRotMatrix << scResult.cosC, -locpo(0, 0) * scResult.sinC, scResult.sinC, locpo(0, 0) * scResult.cosC; + AmgMatrix(2, 2) lCovarianceCar = covRotMatrix * bchk.lCovariance * covRotMatrix.transpose(); + Amg::Vector2D locpoCar(covRotMatrix(1, 1), -covRotMatrix(0, 1)); -#endif // TRKSURFACES_DISCBOUNDS_H + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + double w = bchk.nSigmas * sqrt(lCovarianceCar(0, 0)); + double h = bchk.nSigmas * sqrt(lCovarianceCar(1, 1)); + double x0 = 0; + double y0 = 0; + float theta = (lCovarianceCar(1, 0) != 0 && (lCovarianceCar(1, 1) - lCovarianceCar(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * lCovarianceCar(1, 0) / (lCovarianceCar(1, 1) - lCovarianceCar(0, 0))) + : 0.; + scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + Amg::Vector2D tmp = rotMatrix * (-locpoCar); + double x1 = tmp(0, 0); + double y1 = tmp(1, 0); + double r = m_boundValues[DiscBounds::bv_rMax]; + // check if ellipse and circle overlap and return result + return test.collide(x0, y0, w, h, x1, y1, r); +} + +inline bool +DiscBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (locpo[locR] > (m_boundValues[DiscBounds::bv_rMin] - tol1) && + locpo[locR] < (m_boundValues[DiscBounds::bv_rMax] + tol1)); +} + +inline bool +DiscBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + double alpha = fabs(locpo[locPhi] - m_boundValues[DiscBounds::bv_averagePhi]); + if (alpha > M_PI) + alpha = 2. * M_PI - alpha; + // alpha -= alpha > M_PI ? 2.*M_PI : 0.; + // alpha += alpha < -M_PI ? 2.*M_PI : 0.; + bool insidePhi = (alpha <= (m_boundValues[DiscBounds::bv_halfPhiSector] + tol2)); + return insidePhi; +} + +inline double +DiscBounds::rMin() const +{ + return m_boundValues[DiscBounds::bv_rMin]; +} +inline double +DiscBounds::rMax() const +{ + return m_boundValues[DiscBounds::bv_rMax]; +} +inline double +DiscBounds::r() const +{ + return m_boundValues[DiscBounds::bv_rMax]; +} + +inline double +DiscBounds::averagePhi() const +{ + return m_boundValues[DiscBounds::bv_averagePhi]; +} + +inline double +DiscBounds::halfPhiSector() const +{ + return m_boundValues[DiscBounds::bv_halfPhiSector]; +} + +} // end of namespace + +#endif // TRKSURFACES_DISCBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscSurface.h index e08fd02d1c691b84dffeb1882829f6b03362cbde..8911b41d8f5b799d41f0a1fbf2b011e5d459c608 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscSurface.h @@ -9,293 +9,335 @@ #ifndef TRKSURFACES_DISCSURFACE_H #define TRKSURFACES_DISCSURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkSurfaces/NoBounds.h" +// Trk #include "TrkDetDescrUtils/SharedObject.h" #include "TrkEventPrimitives/LocalParameters.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/Surface.h" +#include "TrkSurfaces/SurfaceBounds.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" -//std +// std #include <cmath> //for cos, sin etc class MsgStream; -template< class SURFACE, class BOUNDS_CNV > class BoundSurfaceCnv_p1; +template<class SURFACE, class BOUNDS_CNV> +class BoundSurfaceCnv_p1; namespace Trk { - class DiscBounds; - class DiscTrapezoidalBounds; - class TrkDetElementBase; - class LocalParameters; - - template<int DIM, class T, class S> class ParametersT; - - /** - @class DiscSurface - Class for a DiscSurface in the ATLAS detector. - It inherits from Surface. - - @author Andreas.Salzburger@cern.ch - */ +class DiscBounds; +class DiscTrapezoidalBounds; +class TrkDetElementBase; +class LocalParameters; + +template<int DIM, class T, class S> +class ParametersT; + +/** + @class DiscSurface + Class for a DiscSurface in the ATLAS detector. + It inherits from Surface. + + @author Andreas.Salzburger@cern.ch + */ + +class DiscSurface : public Surface +{ + +public: + /**Default Constructor*/ + DiscSurface(); + + /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max} \f$ */ + DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax); + + /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max}, \phi_{hsec} \f$ */ + DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax, double hphisec); + + /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max}, hx_{min}, hx_{max} \f$ + In this case you have DiscTrapezoidalBounds*/ + DiscSurface(Amg::Transform3D* htrans, + double minhalfx, + double maxhalfx, + double maxR, + double minR, + double avephi, + double stereo = 0.); + + /**Constructor for Discs from HepGeom::Transform3D and DiscBounds + - ownership of bounds is passed */ + DiscSurface(Amg::Transform3D* htrans, DiscBounds* dbounds); + + /**Constructor for Discs from HepGeom::Transform3D and DiscTrapezoidalBounds + - ownership of bounds is passed */ + DiscSurface(Amg::Transform3D* htrans, DiscTrapezoidalBounds* dtbounds); - class DiscSurface : public Surface { - - public: - /**Default Constructor*/ - DiscSurface(); - - /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max} \f$ */ - DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax); - - /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max}, \phi_{hsec} \f$ */ - DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax, double hphisec); - - /**Constructor for Discs from HepGeom::Transform3D, \f$ r_{min}, r_{max}, hx_{min}, hx_{max} \f$ - In this case you have DiscTrapezoidalBounds*/ - DiscSurface(Amg::Transform3D* htrans, double minhalfx, double maxhalfx, double maxR, double minR, double avephi, double stereo = 0.); - - /**Constructor for Discs from HepGeom::Transform3D and DiscBounds - - ownership of bounds is passed */ - DiscSurface(Amg::Transform3D* htrans, DiscBounds* dbounds); - - /**Constructor for Discs from HepGeom::Transform3D and DiscTrapezoidalBounds - - ownership of bounds is passed */ - DiscSurface(Amg::Transform3D* htrans, DiscTrapezoidalBounds* dtbounds); - - /**Constructor for Discs from HepGeom::Transform3D by unique_ptr - - bounds is not set */ - DiscSurface(std::unique_ptr<Amg::Transform3D> htrans); - - /**Constructor for DiscSegment from DetectorElement*/ - DiscSurface(const TrkDetElementBase& dmnt); - - /**Copy Constructor*/ - DiscSurface(const DiscSurface& psf); - - /**Copy Constructor with shift*/ - DiscSurface(const DiscSurface& psf, const Amg::Transform3D& transf); - - /**Destructor*/ - virtual ~DiscSurface(); - - /**Assignement operator*/ - DiscSurface& operator=(const DiscSurface&dsf); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /** Virtual constructor*/ - virtual DiscSurface* clone() const override; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, DiscSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, DiscSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, DiscSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, DiscSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, DiscSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, DiscSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, DiscSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, DiscSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, DiscSurface>(position, momentum, charge, *this, cov); } - - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Disc; } - - /** Returns a global reference point: - For the Disc this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ - Where @f$ r, \phi @f$ denote the r(), averagePhi() of the Bounds. - */ - virtual const Amg::Vector3D& globalReferencePoint() const override; - - /**This method returns the bounds by reference*/ - const SurfaceBounds& bounds() const override; - - /**This method calls the inside method of the bounds*/ - virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const override; - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - virtual bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk=true, double tol1=0., double tol2=0.) const override; - - /** Specialized for DiscSurface : LocalParameters to Vector2D */ - virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; - - /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** Special method for DiscSurface : local<->local transformations polar <-> cartesian */ - const Amg::Vector2D* localPolarToCartesian(const Amg::Vector2D& locpol) const; - - /** Special method for Disc surface : local<->local transformations polar <-> cartesian */ - const Amg::Vector2D* localCartesianToPolar(const Amg::Vector2D& loccart) const; - - /** Special method for Disc surface : local<->local transformations polar <-> cartesian by value*/ - Amg::Vector2D localCartesianToPolarValue(const Amg::Vector2D& loccart) const; - - /** Special method for DiscSurface : local<->local transformations polar <-> cartesian */ - const Amg::Vector2D* localPolarToLocalCartesian(const Amg::Vector2D& locpol) const; - - /** Special method for DiscSurface : local<->global transformation when provided cartesian coordinates */ - const Amg::Vector3D* localCartesianToGlobal(const Amg::Vector2D& locpos) const; - - /** Special method for DiscSurface : global<->local from cartesian coordinates */ - const Amg::Vector2D* globalToLocalCartesian(const Amg::Vector3D& glopos, double tol=0.) const; - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceDir is to provide the closest forward solution - - <b>mathematical motivation:</b> - - the equation of the plane is given by: <br> - @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> - where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, - @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible points - on the plane.<br> - Given a line with:<br> - @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> - the solution for @f$ u @f$ can be written: - @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> - If the denominator is 0 then the line lies: - - either in the plane - - perpenticular to the normal of the plane - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir = false, - Trk::BoundaryCheck bchk = false) const override; - - /** fast straight line distance evaluation to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const override; - - /** fast straight line distance evaluation to Surface - with bound option*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::DiscSurface"; } - - protected: //!< data members - template< class SURFACE, class BOUNDS_CNV > friend class ::BoundSurfaceCnv_p1; - - SharedObject<const SurfaceBounds> m_bounds; //!< bounds (shared) - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_referencePoint; //!< reference Point on the Surface - static const NoBounds s_boundless; //!< static member for boundless approach - }; - - inline DiscSurface* DiscSurface::clone() const - { return new DiscSurface(*this); } - - inline const SurfaceBounds& DiscSurface::bounds() const + /**Constructor for Discs from HepGeom::Transform3D by unique_ptr + - bounds is not set */ + DiscSurface(std::unique_ptr<Amg::Transform3D> htrans); + + /**Constructor for DiscSegment from DetectorElement*/ + DiscSurface(const TrkDetElementBase& dmnt); + + /**Copy Constructor*/ + DiscSurface(const DiscSurface& psf); + + /**Copy Constructor with shift*/ + DiscSurface(const DiscSurface& psf, const Amg::Transform3D& transf); + + /**Destructor*/ + virtual ~DiscSurface(); + + /**Assignement operator*/ + DiscSurface& operator=(const DiscSurface& dsf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /** Virtual constructor*/ + virtual DiscSurface* clone() const override; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, DiscSurface>* createTrackParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - if (m_bounds.get()) return (*(m_bounds.get())); - if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()){ - return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); - } - if (Surface::m_associatedDetElement) return m_associatedDetElement->bounds(); - return s_boundless; + return new ParametersT<5, Charged, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - inline bool DiscSurface::insideBounds(const Amg::Vector2D& locpos, - double tol1, - double tol2) const - { return bounds().inside(locpos,tol1,tol2); } - - inline bool DiscSurface::insideBoundsCheck(const Amg::Vector2D& locpos, - const BoundaryCheck& bchk) const - { return (bounds().inside(locpos,bchk));} + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, DiscSurface>* createTrackParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Charged, DiscSurface>(position, momentum, charge, *this, cov); + } - inline const Amg::Vector2D DiscSurface::localParametersToPosition(const LocalParameters& locpars) const + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, DiscSurface>* createNeutralParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - if (locpars.contains(Trk::locR) && locpars.contains(Trk::locPhi)) - return Amg::Vector2D(locpars[Trk::locR], locpars[Trk::locPhi]); - if (locpars.contains(Trk::locR)) - return Amg::Vector2D(locpars[Trk::locR], 0.); - if (locpars.contains(Trk::locPhi)) - return Amg::Vector2D(0.5*bounds().r(), locpars[Trk::locPhi]); - return Amg::Vector2D(0.5*bounds().r(), 0.); + return new ParametersT<5, Neutral, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - inline const Amg::Vector2D* DiscSurface::localPolarToCartesian(const Amg::Vector2D& locpol) const - { return(new Amg::Vector2D(locpol[locR]*std::cos(locpol[locPhi]),locpol[locR]*std::sin(locpol[locPhi]))); } - - inline const Amg::Vector2D* DiscSurface::localCartesianToPolar(const Amg::Vector2D& loccart) const + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, DiscSurface>* createNeutralParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override { - return(new Amg::Vector2D(std::sqrt(loccart[locX]*loccart[locX]+loccart[locY]*loccart[locY]), - std::atan2(loccart[locY], loccart[locX]))); + return new ParametersT<5, Neutral, DiscSurface>(position, momentum, charge, *this, cov); } - inline Amg::Vector2D DiscSurface::localCartesianToPolarValue(const Amg::Vector2D& loccart) const + + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, DiscSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const { - return(Amg::Vector2D(std::sqrt(loccart[locX]*loccart[locX]+loccart[locY]*loccart[locY]), - std::atan2(loccart[locY], loccart[locX]))); + return new ParametersT<DIM, T, DiscSurface>(l1, l2, phi, theta, qop, *this, cov); } - - inline Intersection DiscSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const + + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, DiscSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const { - double denom = dir.dot(normal()); - if (denom){ - double u = (normal().dot((center()-pos)))/(denom); - Amg::Vector3D intersectPoint(pos + u * dir); - // evaluate the intersection in terms of direction - bool isValid = forceDir ? ( u > 0.) : true; - // evaluate (if necessary in terms of boundaries) - isValid = bchk ? (isValid && isOnSurface(intersectPoint) ) : isValid; - // return the result - return Trk::Intersection(intersectPoint,u,isValid); - } - return Trk::Intersection(pos,0.,false); + return new ParametersT<DIM, T, DiscSurface>(position, momentum, charge, *this, cov); } - -} // end of namespace -#endif // TRKSURFACES_DISCSURFACE_H + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Disc; } + + /** Returns a global reference point: + For the Disc this is @f$ (R*cos(\phi), R*sin(\phi),0)*transform() @f$ + Where @f$ r, \phi @f$ denote the r(), averagePhi() of the Bounds. + */ + virtual const Amg::Vector3D& globalReferencePoint() const override; + + /**This method returns the bounds by reference*/ + const SurfaceBounds& bounds() const override; + /**This method calls the inside method of the bounds*/ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const override; + + /** Specialized for DiscSurface : LocalParameters to Vector2D */ + virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const override; + + /** Specialized for DiscSurface: LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** Specialized for DiscSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface + */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** Special method for DiscSurface : local<->local transformations polar <-> cartesian */ + const Amg::Vector2D* localPolarToCartesian(const Amg::Vector2D& locpol) const; + + /** Special method for Disc surface : local<->local transformations polar <-> cartesian */ + const Amg::Vector2D* localCartesianToPolar(const Amg::Vector2D& loccart) const; + + /** Special method for Disc surface : local<->local transformations polar <-> cartesian by value*/ + Amg::Vector2D localCartesianToPolarValue(const Amg::Vector2D& loccart) const; + + /** Special method for DiscSurface : local<->local transformations polar <-> cartesian */ + const Amg::Vector2D* localPolarToLocalCartesian(const Amg::Vector2D& locpol) const; + + /** Special method for DiscSurface : local<->global transformation when provided cartesian coordinates */ + const Amg::Vector3D* localCartesianToGlobal(const Amg::Vector2D& locpos) const; + + /** Special method for DiscSurface : global<->local from cartesian coordinates */ + const Amg::Vector2D* globalToLocalCartesian(const Amg::Vector3D& glopos, double tol = 0.) const; + + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceDir is to provide the closest forward solution + + <b>mathematical motivation:</b> + + the equation of the plane is given by: <br> + @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> + where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, + @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible + points on the plane.<br> Given a line with:<br> + @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> + the solution for @f$ u @f$ can be written: + @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> + If the denominator is 0 then the line lies: + - either in the plane + - perpenticular to the normal of the plane + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir = false, + Trk::BoundaryCheck bchk = false) const override; + + /** fast straight line distance evaluation to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + + /** fast straight line distance evaluation to Surface - with bound option*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool Bound) const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::DiscSurface"; } + +protected: //!< data members + template<class SURFACE, class BOUNDS_CNV> + friend class ::BoundSurfaceCnv_p1; + + SharedObject<const SurfaceBounds> m_bounds; //!< bounds (shared) + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_referencePoint; //!< reference Point on the Surface + static const NoBounds s_boundless; //!< static member for boundless approach +}; + +inline DiscSurface* +DiscSurface::clone() const +{ + return new DiscSurface(*this); +} + +inline const SurfaceBounds& +DiscSurface::bounds() const +{ + if (m_bounds.get()) + return (*(m_bounds.get())); + if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()) { + return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); + } + if (Surface::m_associatedDetElement) + return m_associatedDetElement->bounds(); + return s_boundless; +} + +inline bool +DiscSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + return bounds().inside(locpos, tol1, tol2); +} + +inline bool +DiscSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const +{ + return (bounds().inside(locpos, bchk)); +} + +inline const Amg::Vector2D +DiscSurface::localParametersToPosition(const LocalParameters& locpars) const +{ + if (locpars.contains(Trk::locR) && locpars.contains(Trk::locPhi)) + return Amg::Vector2D(locpars[Trk::locR], locpars[Trk::locPhi]); + if (locpars.contains(Trk::locR)) + return Amg::Vector2D(locpars[Trk::locR], 0.); + if (locpars.contains(Trk::locPhi)) + return Amg::Vector2D(0.5 * bounds().r(), locpars[Trk::locPhi]); + return Amg::Vector2D(0.5 * bounds().r(), 0.); +} + +inline const Amg::Vector2D* +DiscSurface::localPolarToCartesian(const Amg::Vector2D& locpol) const +{ + return (new Amg::Vector2D(locpol[locR] * std::cos(locpol[locPhi]), locpol[locR] * std::sin(locpol[locPhi]))); +} + +inline const Amg::Vector2D* +DiscSurface::localCartesianToPolar(const Amg::Vector2D& loccart) const +{ + return (new Amg::Vector2D(std::sqrt(loccart[locX] * loccart[locX] + loccart[locY] * loccart[locY]), + std::atan2(loccart[locY], loccart[locX]))); +} +inline Amg::Vector2D +DiscSurface::localCartesianToPolarValue(const Amg::Vector2D& loccart) const +{ + return (Amg::Vector2D(std::sqrt(loccart[locX] * loccart[locX] + loccart[locY] * loccart[locY]), + std::atan2(loccart[locY], loccart[locX]))); +} + +inline Intersection +DiscSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const +{ + double denom = dir.dot(normal()); + if (denom) { + double u = (normal().dot((center() - pos))) / (denom); + Amg::Vector3D intersectPoint(pos + u * dir); + // evaluate the intersection in terms of direction + bool isValid = forceDir ? (u > 0.) : true; + // evaluate (if necessary in terms of boundaries) + isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid; + // return the result + return Trk::Intersection(intersectPoint, u, isValid); + } + return Trk::Intersection(pos, 0., false); +} + +} // end of namespace + +#endif // TRKSURFACES_DISCSURFACE_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscTrapezoidalBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscTrapezoidalBounds.h index b3513c2382d966e4251109a9e320f61c422ccdbe..ae37fa2d07ff6104a3688e7d19bbfdd79a10bba2 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscTrapezoidalBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DiscTrapezoidalBounds.h @@ -10,341 +10,416 @@ #define TRKSURFACES_DISCTRAPEZOIDALBOUNDS_H // Trk -#include "TrkSurfaces/SurfaceBounds.h" #include "TrkEventPrimitives/ParamDefs.h" -// -#include <math.h> +#include "TrkSurfaces/SurfaceBounds.h" +// #include <cmath> -//Eigen +#include <math.h> +// Eigen #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - - /** - @class DiscTrapezoidalBounds - - Class to describe the bounds for a planar DiscSurface. - By providing an argument for hphisec, the bounds can - be restricted to a phirange around the center position. - - @author Noemi.Calace@cern.ch , Andreas.Salzburger@cern.ch - */ - - class DiscTrapezoidalBounds : public SurfaceBounds { - public: - /** enumeration for readability */ - enum BoundValues { - bv_rMin = 0, - bv_rMax = 1, - bv_minHalfX = 2, - bv_maxHalfX = 3, - bv_halfY = 4, - bv_halfPhiSector = 5, - bv_averagePhi = 6, - bv_rCenter = 7, - bv_stereo = 8, - bv_length = 9 - }; - - /**Default Constructor*/ - DiscTrapezoidalBounds(); - - /**Constructor for a symmetric Trapezoid giving min X lenght, max X lenght, Rmin and R max */ - DiscTrapezoidalBounds(double minhalfx, double maxhalfx, double rMin, double rMax, double avephi, double stereo = 0.); - - /**Copy constructor*/ - DiscTrapezoidalBounds(const DiscTrapezoidalBounds& disctrbo); - - /**Destructor*/ - virtual ~DiscTrapezoidalBounds(); - - /**Assignment operator*/ - DiscTrapezoidalBounds& operator=(const DiscTrapezoidalBounds& disctrbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor*/ - virtual DiscTrapezoidalBounds* clone() const override; - - /** Return the type - mainly for persistency */ - virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::DiscTrapezoidal; } - - /**This method cheks if the radius given in the LocalPosition is inside [rMin,rMax] - if only tol1 is given and additional in the phi sector is tol2 is given */ - virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns inner radius*/ - double rMin() const; - - /**This method returns outer radius*/ - double rMax() const; - - /**This method returns the maximum expansion on the plane (=rMax)*/ - virtual double r() const override; - - /**This method returns the average phi*/ - double averagePhi() const; - - /**This method returns the center radius*/ - double rCenter() const; - - /**This method returns the stereo angle*/ - double stereo() const; - - /**This method returns the halfPhiSector which is covered by the disc*/ - double halfPhiSector() const; - - /**This method returns the minimal halflength in X */ - double minHalflengthX() const; - - /**This method returns the maximal halflength in X */ - double maxHalflengthX() const; - - /**This method returns the halflength in Y (this is Rmax -Rmin)*/ - double halflengthY() const; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** Internal members of the bounds (float/double)*/ - std::vector<TDD_real_t> m_boundValues; - +/** + @class DiscTrapezoidalBounds + + Class to describe the bounds for a planar DiscSurface. + By providing an argument for hphisec, the bounds can + be restricted to a phirange around the center position. + + @author Noemi.Calace@cern.ch , Andreas.Salzburger@cern.ch +*/ + +class DiscTrapezoidalBounds : public SurfaceBounds +{ + +public: + /** enumeration for readability */ + enum BoundValues + { + bv_rMin = 0, + bv_rMax = 1, + bv_minHalfX = 2, + bv_maxHalfX = 3, + bv_halfY = 4, + bv_halfPhiSector = 5, + bv_averagePhi = 6, + bv_rCenter = 7, + bv_stereo = 8, + bv_length = 9 }; - inline DiscTrapezoidalBounds* DiscTrapezoidalBounds::clone() const - { return new DiscTrapezoidalBounds(*this); } - - inline bool DiscTrapezoidalBounds::inside(const Amg::Vector2D &locpo, double , double ) const - { - double rMedium = m_boundValues[DiscTrapezoidalBounds::bv_rCenter]; - double phi = m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]; - - Amg::Vector2D cartCenter(rMedium*cos(phi), - rMedium*sin(phi)); - - Amg::Vector2D cartPos(locpo[Trk::locR]*cos(locpo[Trk::locPhi]), - locpo[Trk::locR]*sin(locpo[Trk::locPhi])); - - Amg::Vector2D Pos = cartPos - cartCenter; - - Amg::Vector2D DeltaPos(Pos[Trk::locX]*sin(phi) - Pos[Trk::locY]*cos(phi), - Pos[Trk::locY]*sin(phi) + Pos[Trk::locX]*cos(phi)); - - bool insideX = (fabs(DeltaPos[Trk::locX])<m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); - bool insideY = (fabs(DeltaPos[Trk::locY])<m_boundValues[DiscTrapezoidalBounds::bv_halfY]); - - if (!insideX || !insideY) return false; - - if (fabs(DeltaPos[Trk::locX]) < m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]) return true; - - double m = 2.*m_boundValues[DiscTrapezoidalBounds::bv_halfY]/(m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] - m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]); - - double q = m_boundValues[DiscTrapezoidalBounds::bv_halfY]*(m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] + m_boundValues[DiscTrapezoidalBounds::bv_minHalfX])/(m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] - m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); - - bool inside = (DeltaPos[Trk::locY] > (m*fabs(DeltaPos[Trk::locX])+q)); - - return inside; - - } - - inline bool DiscTrapezoidalBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const + /**Default Constructor*/ + DiscTrapezoidalBounds(); + + /**Constructor for a symmetric Trapezoid giving min X lenght, max X lenght, Rmin and R max */ + DiscTrapezoidalBounds(double minhalfx, double maxhalfx, double rMin, double rMax, double avephi, double stereo = 0.); + + /**Copy constructor*/ + DiscTrapezoidalBounds(const DiscTrapezoidalBounds& disctrbo); + + /**Destructor*/ + virtual ~DiscTrapezoidalBounds(); + + /**Assignment operator*/ + DiscTrapezoidalBounds& operator=(const DiscTrapezoidalBounds& disctrbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor*/ + virtual DiscTrapezoidalBounds* clone() const override; + + /** Return the type - mainly for persistency */ + virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::DiscTrapezoidal; } + + /**This method cheks if the radius given in the LocalPosition is inside [rMin,rMax] + if only tol1 is given and additional in the phi sector is tol2 is given */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns inner radius*/ + double rMin() const; + + /**This method returns outer radius*/ + double rMax() const; + + /**This method returns the maximum expansion on the plane (=rMax)*/ + virtual double r() const override; + + /**This method returns the average phi*/ + double averagePhi() const; + + /**This method returns the center radius*/ + double rCenter() const; + + /**This method returns the stereo angle*/ + double stereo() const; + + /**This method returns the halfPhiSector which is covered by the disc*/ + double halfPhiSector() const; + + /**This method returns the minimal halflength in X */ + double minHalflengthX() const; + + /**This method returns the maximal halflength in X */ + double maxHalflengthX() const; + + /**This method returns the halflength in Y (this is Rmax -Rmin)*/ + double halflengthY() const; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** Internal members of the bounds (float/double)*/ + std::vector<TDD_real_t> m_boundValues; +}; + +inline DiscTrapezoidalBounds* +DiscTrapezoidalBounds::clone() const +{ + return new DiscTrapezoidalBounds(*this); +} + +inline bool +DiscTrapezoidalBounds::inside(const Amg::Vector2D& locpo, double, double) const +{ + double rMedium = m_boundValues[DiscTrapezoidalBounds::bv_rCenter]; + double phi = m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]; + + Amg::Vector2D cartCenter(rMedium * cos(phi), rMedium * sin(phi)); + + Amg::Vector2D cartPos(locpo[Trk::locR] * cos(locpo[Trk::locPhi]), locpo[Trk::locR] * sin(locpo[Trk::locPhi])); + + Amg::Vector2D Pos = cartPos - cartCenter; + + Amg::Vector2D DeltaPos(Pos[Trk::locX] * sin(phi) - Pos[Trk::locY] * cos(phi), + Pos[Trk::locY] * sin(phi) + Pos[Trk::locX] * cos(phi)); + + bool insideX = (fabs(DeltaPos[Trk::locX]) < m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); + bool insideY = (fabs(DeltaPos[Trk::locY]) < m_boundValues[DiscTrapezoidalBounds::bv_halfY]); + + if (!insideX || !insideY) + return false; + + if (fabs(DeltaPos[Trk::locX]) < m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]) + return true; + + double m = 2. * m_boundValues[DiscTrapezoidalBounds::bv_halfY] / + (m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] - m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]); + + double q = m_boundValues[DiscTrapezoidalBounds::bv_halfY] * + (m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] + m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]) / + (m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] - m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); + + bool inside = (DeltaPos[Trk::locY] > (m * fabs(DeltaPos[Trk::locX]) + q)); + + return inside; +} + +inline bool +DiscTrapezoidalBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0 || bchk.nSigmas == 0 || m_boundValues[DiscTrapezoidalBounds::bv_rMin] != 0) + return DiscTrapezoidalBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + double alpha = fabs(locpo[locPhi] - m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); + if (alpha > M_PI) + alpha = 2 * M_PI - alpha; + // a fast FALSE + sincosCache scResult = bchk.FastSinCos(locpo(1, 0)); + double dx = bchk.nSigmas * sqrt(bchk.lCovariance(0, 0)); + double dy = bchk.nSigmas * sqrt(scResult.sinC * scResult.sinC * bchk.lCovariance(0, 0) + + locpo(0, 0) * locpo(0, 0) * scResult.cosC * scResult.cosC * bchk.lCovariance(1, 1) + + 2 * scResult.cosC * scResult.sinC * locpo(0, 0) * bchk.lCovariance(0, 1)); + double max_ell = dx > dy ? dx : dy; + if (locpo(0, 0) > (m_boundValues[DiscTrapezoidalBounds::bv_rMax] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha) + + max_ell)) + return false; + // a fast TRUE + double min_ell = dx < dy ? dx : dy; + if (locpo(0, 0) < (m_boundValues[DiscTrapezoidalBounds::bv_rMax] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha) + + min_ell)) + return true; + + // we are not using the KDOP approach here but rather a highly optimized one + class EllipseCollisionTest + { + private: + int m_maxIterations; + bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const { - if(bchk.bcType==0 || bchk.nSigmas==0 || m_boundValues[DiscTrapezoidalBounds::bv_rMin]!=0) return DiscTrapezoidalBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - double alpha = fabs(locpo[locPhi]-m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); - if ( alpha>M_PI) alpha = 2*M_PI - alpha; - // a fast FALSE - sincosCache scResult = bchk.FastSinCos(locpo(1,0)); - double dx = bchk.nSigmas*sqrt(bchk.lCovariance(0,0)); - double dy = bchk.nSigmas*sqrt(scResult.sinC*scResult.sinC*bchk.lCovariance(0,0) + locpo(0,0)*locpo(0,0)*scResult.cosC*scResult.cosC*bchk.lCovariance(1,1)+2*scResult.cosC*scResult.sinC*locpo(0,0)*bchk.lCovariance(0,1)); - double max_ell = dx > dy ? dx : dy; - if (locpo(0,0) > ( m_boundValues[DiscTrapezoidalBounds::bv_rMax]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha) + max_ell)) - return false; - // a fast TRUE - double min_ell = dx < dy ? dx : dy; - if (locpo(0,0) < ( m_boundValues[DiscTrapezoidalBounds::bv_rMax]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha) + min_ell)) - return true; - - // we are not using the KDOP approach here but rather a highly optimized one - class EllipseCollisionTest { - private: - int m_maxIterations; - bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const { - std::vector<double> innerPolygonCoef(m_maxIterations+1); - std::vector<double> outerPolygonCoef(m_maxIterations+1); - /* - t2______t4 - --_ \ - --_ \ /¨¨¨ ¨¨\ - t1 = (0, 0) ( t ) - | \ \__ _ / - | \ - | t3 - | / - | / - t0 - */ - for (int t = 1; t <= m_maxIterations; t++) { - int numNodes = 4 << t; - innerPolygonCoef[t] = 0.5/cos(4*acos(0.0)/numNodes); - double c1x = (c0x + c2x)*innerPolygonCoef[t]; - double c1y = (c0y + c2y)*innerPolygonCoef[t]; - double tx = x - c1x; // t indicates a translated coordinate - double ty = y - c1y; - if (tx*tx + ty*ty <= rr) { - return true; // collision with t1 - } - double t2x = c2x - c1x; - double t2y = c2y - c1y; - if (tx*t2x + ty*t2y >= 0 && tx*t2x + ty*t2y <= t2x*t2x + t2y*t2y && - (ty*t2x - tx*t2y >= 0 || rr*(t2x*t2x + t2y*t2y) >= (ty*t2x - tx*t2y)*(ty*t2x - tx*t2y))) { - return true; // collision with t1---t2 - } - double t0x = c0x - c1x; - double t0y = c0y - c1y; - if (tx*t0x + ty*t0y >= 0 && tx*t0x + ty*t0y <= t0x*t0x + t0y*t0y && - (ty*t0x - tx*t0y <= 0 || rr*(t0x*t0x + t0y*t0y) >= (ty*t0x - tx*t0y)*(ty*t0x - tx*t0y))) { - return true; // collision with t1---t0 - } - outerPolygonCoef[t] = 0.5/(cos(2*acos(0.0)/numNodes)*cos(2*acos(0.0)/numNodes)); - double c3x = (c0x + c1x)*outerPolygonCoef[t]; - double c3y = (c0y + c1y)*outerPolygonCoef[t]; - if ((c3x-x)*(c3x-x) + (c3y-y)*(c3y-y) < rr) { - c2x = c1x; - c2y = c1y; - continue; // t3 is inside circle - } - double c4x = c1x - c3x + c1x; - double c4y = c1y - c3y + c1y; - if ((c4x-x)*(c4x-x) + (c4y-y)*(c4y-y) < rr) { - c0x = c1x; - c0y = c1y; - continue; // t4 is inside circle - } - double t3x = c3x - c1x; - double t3y = c3y - c1y; - if (ty*t3x - tx*t3y <= 0 || rr*(t3x*t3x + t3y*t3y) > (ty*t3x - tx*t3y)*(ty*t3x - tx*t3y)) { - if (tx*t3x + ty*t3y > 0) { - if (std::abs(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c3x)*(c0x-c3x) + (y-c3y)*(c0y-c3y) >= 0) { - c2x = c1x; - c2y = c1y; - continue; // circle center is inside t0---t1---t3 - } - } else if (-(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c4x)*(c2x-c4x) + (y-c4y)*(c2y-c4y) >= 0) { - c0x = c1x; - c0y = c1y; - continue; // circle center is inside t1---t2---t4 - } - } - return false; // no collision possible - } - return false; // out of iterations so it is unsure if there was a collision. But have to return something. - } - public: - // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of radius r at (x1, y1) - bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const { - double x = fabs(x1 - x0); - double y = fabs(y1 - y0); - if (x*x + (h - y)*(h - y) <= r*r || (w - x)*(w - x) + y*y <= r*r || x*h + y*w <= w*h // collision with (0, h) - || ((x*h + y*w - w*h)*(x*h + y*w - w*h) <= r*r*(w*w + h*h) && x*w - y*h >= -h*h && x*w - y*h <= w*w)) { // collision with (0, h)---(w, 0) - return true; - } else { - if ((x-w)*(x-w) + (y-h)*(y-h) <= r*r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { - return iterate(x, y, w, 0, 0, h, r*r); // collision within triangle (0, h) (w, h) (0, 0) is possible - } - return false; - } - } - EllipseCollisionTest(int maxIterations) { - this->m_maxIterations = maxIterations; - } - }; - - EllipseCollisionTest test(4); - // convert to cartesian coordinates - AmgMatrix(2,2) covRotMatrix ; - covRotMatrix << scResult.cosC, -locpo(0,0)*scResult.sinC, - scResult.sinC, locpo(0,0)*scResult.cosC; - AmgMatrix(2,2) lCovarianceCar = covRotMatrix*bchk.lCovariance*covRotMatrix.transpose(); - Amg::Vector2D locpoCar(covRotMatrix(1,1), -covRotMatrix(0,1)); - - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - double w = bchk.nSigmas*sqrt( lCovarianceCar(0,0)); - double h = bchk.nSigmas*sqrt( lCovarianceCar(1,1)); - double x0 = 0; - double y0 = 0; - float theta = (lCovarianceCar(1,0) != 0 && (lCovarianceCar(1,1)-lCovarianceCar(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*lCovarianceCar(1,0)/(lCovarianceCar(1,1)-lCovarianceCar(0,0)) ) : 0.; - scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - Amg::Vector2D tmp = rotMatrix * (- locpoCar) ; - double x1 = tmp(0,0); - double y1 = tmp(1,0); - double r = m_boundValues[DiscTrapezoidalBounds::bv_rMax]; - // check if ellipse and circle overlap and return result - return test.collide(x0, y0, w, h, x1, y1, r); + std::vector<double> innerPolygonCoef(m_maxIterations + 1); + std::vector<double> outerPolygonCoef(m_maxIterations + 1); + /* + t2______t4 + --_ \ + --_ \ /¨¨¨ ¨¨\ + t1 = (0, 0) ( t ) + | \ \__ _ / + | \ + | t3 + | / + | / + t0 + */ + for (int t = 1; t <= m_maxIterations; t++) { + int numNodes = 4 << t; + innerPolygonCoef[t] = 0.5 / cos(4 * acos(0.0) / numNodes); + double c1x = (c0x + c2x) * innerPolygonCoef[t]; + double c1y = (c0y + c2y) * innerPolygonCoef[t]; + double tx = x - c1x; // t indicates a translated coordinate + double ty = y - c1y; + if (tx * tx + ty * ty <= rr) { + return true; // collision with t1 + } + double t2x = c2x - c1x; + double t2y = c2y - c1y; + if (tx * t2x + ty * t2y >= 0 && tx * t2x + ty * t2y <= t2x * t2x + t2y * t2y && + (ty * t2x - tx * t2y >= 0 || + rr * (t2x * t2x + t2y * t2y) >= (ty * t2x - tx * t2y) * (ty * t2x - tx * t2y))) { + return true; // collision with t1---t2 + } + double t0x = c0x - c1x; + double t0y = c0y - c1y; + if (tx * t0x + ty * t0y >= 0 && tx * t0x + ty * t0y <= t0x * t0x + t0y * t0y && + (ty * t0x - tx * t0y <= 0 || + rr * (t0x * t0x + t0y * t0y) >= (ty * t0x - tx * t0y) * (ty * t0x - tx * t0y))) { + return true; // collision with t1---t0 + } + outerPolygonCoef[t] = 0.5 / (cos(2 * acos(0.0) / numNodes) * cos(2 * acos(0.0) / numNodes)); + double c3x = (c0x + c1x) * outerPolygonCoef[t]; + double c3y = (c0y + c1y) * outerPolygonCoef[t]; + if ((c3x - x) * (c3x - x) + (c3y - y) * (c3y - y) < rr) { + c2x = c1x; + c2y = c1y; + continue; // t3 is inside circle + } + double c4x = c1x - c3x + c1x; + double c4y = c1y - c3y + c1y; + if ((c4x - x) * (c4x - x) + (c4y - y) * (c4y - y) < rr) { + c0x = c1x; + c0y = c1y; + continue; // t4 is inside circle + } + double t3x = c3x - c1x; + double t3y = c3y - c1y; + if (ty * t3x - tx * t3y <= 0 || rr * (t3x * t3x + t3y * t3y) > (ty * t3x - tx * t3y) * (ty * t3x - tx * t3y)) { + if (tx * t3x + ty * t3y > 0) { + if (std::abs(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c3x) * (c0x - c3x) + (y - c3y) * (c0y - c3y) >= 0) { + c2x = c1x; + c2y = c1y; + continue; // circle center is inside t0---t1---t3 + } + } else if (-(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c4x) * (c2x - c4x) + (y - c4y) * (c2y - c4y) >= 0) { + c0x = c1x; + c0y = c1y; + continue; // circle center is inside t1---t2---t4 + } + } + return false; // no collision possible + } + return false; // out of iterations so it is unsure if there was a collision. But have to return something. } - - inline bool DiscTrapezoidalBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const { - double alpha = fabs(locpo[locPhi]-m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); - if ( alpha>M_PI) alpha = 2*M_PI - alpha; - - return ( locpo[locR] > (m_boundValues[DiscTrapezoidalBounds::bv_rMin]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha) - tol1) && - locpo[locR] < (m_boundValues[DiscTrapezoidalBounds::bv_rMax]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha) + tol1)); } - - inline bool DiscTrapezoidalBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const { - double alpha = fabs(locpo[locPhi]-m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); - if ( alpha > M_PI ) alpha = 2.*M_PI-alpha; - return (alpha <= (m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] + tol2)); - } - - inline double DiscTrapezoidalBounds::rMin() const { return m_boundValues[DiscTrapezoidalBounds::bv_rMin]; } - - inline double DiscTrapezoidalBounds::rMax() const { return m_boundValues[DiscTrapezoidalBounds::bv_rMax]; } - - inline double DiscTrapezoidalBounds::r() const { return m_boundValues[DiscTrapezoidalBounds::bv_rMax]; } - - inline double DiscTrapezoidalBounds::averagePhi() const { return m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]; } - - inline double DiscTrapezoidalBounds::rCenter() const { return m_boundValues[DiscTrapezoidalBounds::bv_rCenter]; } - - inline double DiscTrapezoidalBounds::stereo() const { return m_boundValues[DiscTrapezoidalBounds::bv_stereo]; } - - inline double DiscTrapezoidalBounds::halfPhiSector() const { return m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]; } - - inline double DiscTrapezoidalBounds::minHalflengthX() const { return m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]; } - - inline double DiscTrapezoidalBounds::maxHalflengthX() const { return m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]; } - - inline double DiscTrapezoidalBounds::halflengthY() const {return m_boundValues[DiscTrapezoidalBounds::bv_halfY]; } -} // end of namespace + public: + // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of + // radius r at (x1, y1) + bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const + { + double x = fabs(x1 - x0); + double y = fabs(y1 - y0); + if (x * x + (h - y) * (h - y) <= r * r || (w - x) * (w - x) + y * y <= r * r || + x * h + y * w <= w * h // collision with (0, h) + || ((x * h + y * w - w * h) * (x * h + y * w - w * h) <= r * r * (w * w + h * h) && x * w - y * h >= -h * h && + x * w - y * h <= w * w)) { // collision with (0, h)---(w, 0) + return true; + } else { + if ((x - w) * (x - w) + (y - h) * (y - h) <= r * r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { + return iterate(x, y, w, 0, 0, h, r * r); // collision within triangle (0, h) (w, h) (0, 0) is possible + } + return false; + } + } + EllipseCollisionTest(int maxIterations) { this->m_maxIterations = maxIterations; } + }; + + EllipseCollisionTest test(4); + // convert to cartesian coordinates + AmgMatrix(2, 2) covRotMatrix; + covRotMatrix << scResult.cosC, -locpo(0, 0) * scResult.sinC, scResult.sinC, locpo(0, 0) * scResult.cosC; + AmgMatrix(2, 2) lCovarianceCar = covRotMatrix * bchk.lCovariance * covRotMatrix.transpose(); + Amg::Vector2D locpoCar(covRotMatrix(1, 1), -covRotMatrix(0, 1)); + + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + double w = bchk.nSigmas * sqrt(lCovarianceCar(0, 0)); + double h = bchk.nSigmas * sqrt(lCovarianceCar(1, 1)); + double x0 = 0; + double y0 = 0; + float theta = (lCovarianceCar(1, 0) != 0 && (lCovarianceCar(1, 1) - lCovarianceCar(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * lCovarianceCar(1, 0) / (lCovarianceCar(1, 1) - lCovarianceCar(0, 0))) + : 0.; + scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + Amg::Vector2D tmp = rotMatrix * (-locpoCar); + double x1 = tmp(0, 0); + double y1 = tmp(1, 0); + double r = m_boundValues[DiscTrapezoidalBounds::bv_rMax]; + // check if ellipse and circle overlap and return result + return test.collide(x0, y0, w, h, x1, y1, r); +} + +inline bool +DiscTrapezoidalBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + double alpha = fabs(locpo[locPhi] - m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); + if (alpha > M_PI) + alpha = 2 * M_PI - alpha; + + return (locpo[locR] > (m_boundValues[DiscTrapezoidalBounds::bv_rMin] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha) - + tol1) && + locpo[locR] < (m_boundValues[DiscTrapezoidalBounds::bv_rMax] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha) + + tol1)); +} + +inline bool +DiscTrapezoidalBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + double alpha = fabs(locpo[locPhi] - m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]); + if (alpha > M_PI) + alpha = 2. * M_PI - alpha; + return (alpha <= (m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] + tol2)); +} + +inline double +DiscTrapezoidalBounds::rMin() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_rMin]; +} + +inline double +DiscTrapezoidalBounds::rMax() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_rMax]; +} + +inline double +DiscTrapezoidalBounds::r() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_rMax]; +} +inline double +DiscTrapezoidalBounds::averagePhi() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_averagePhi]; +} + +inline double +DiscTrapezoidalBounds::rCenter() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_rCenter]; +} + +inline double +DiscTrapezoidalBounds::stereo() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_stereo]; +} + +inline double +DiscTrapezoidalBounds::halfPhiSector() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]; +} + +inline double +DiscTrapezoidalBounds::minHalflengthX() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]; +} + +inline double +DiscTrapezoidalBounds::maxHalflengthX() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]; +} + +inline double +DiscTrapezoidalBounds::halflengthY() const +{ + return m_boundValues[DiscTrapezoidalBounds::bv_halfY]; +} + +} // end of namespace #endif // TRKSURFACES_DISCTRAPEZOIDALBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DistanceSolution.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DistanceSolution.h index 15a625c242dd5d052aef015fef2a127393991921..60ee6ea87fed1f56e8807a616da6585214a3295f 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DistanceSolution.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/DistanceSolution.h @@ -9,99 +9,111 @@ #ifndef TRKSURFACES_DISTANCESOLUTION_H #define TRKSURFACES_DISTANCESOLUTION_H -//STD -#include <math.h> +// STD #include <iostream> +#include <math.h> namespace Trk { - - /** - @class DistanceSolution - Access to distance solutions. Driven by need to accomodate - intersections with a cylinder into common interface. - - @author Sarka.Todorova@cern.ch - */ - - class DistanceSolution { - public: - /**Default Constructor*/ - DistanceSolution(); - - /**Constructor*/ - DistanceSolution(int num, double current=0., bool signedDist=false, double first=0., double second=0.); - - /**Destructor*/ - virtual ~DistanceSolution() = default; - - // methods to access solutions - /** Number of intersection solutions*/ - int numberOfSolutions() const; - - /** Distance to first intersection solution along direction*/ - double first() const; - - /** Distance to second intersection solution along direction (for a cylinder surface)*/ - double second() const; - - /** Absolute Distance to closest solution */ - double absClosest() const; - - /** Distance to point of closest approach along direction*/ - double toPointOfClosestApproach() const; - - /** Current distance to surface (spatial), signed (along/opposite to surface normal) if input argument true (absolute value by default)*/ - double currentDistance(bool signedDist=false) const; - - /** This method indicates availability of signed current distance (false for Perigee and StraighLineSurface) */ - bool signedDistance() const; - - protected: - int m_num; - double m_first; - double m_second; - double m_current; - bool m_signedDist; - }; - - inline int DistanceSolution::numberOfSolutions() const - { - return m_num; - } - - inline double DistanceSolution::first() const - { - return m_first; - } - - inline double DistanceSolution::second() const - { - return m_second; - } - - inline double DistanceSolution::absClosest() const - { - if (m_num > 1) - return ( m_first*m_first < m_second*m_second ) ? fabs(m_first) : fabs(m_second); - else return fabs(m_first); - } - - inline double DistanceSolution::toPointOfClosestApproach() const - { - return m_first; - } - - inline double DistanceSolution::currentDistance(bool signedDist) const - { - if (signedDist) return m_current; - else return fabs(m_current); - } - - inline bool DistanceSolution::signedDistance() const - { - return m_signedDist; - } - + +/** + @class DistanceSolution + Access to distance solutions. Driven by need to accomodate + intersections with a cylinder into common interface. + + @author Sarka.Todorova@cern.ch + */ + +class DistanceSolution +{ +public: + /**Default Constructor*/ + DistanceSolution(); + + /**Constructor*/ + DistanceSolution(int num, double current = 0., bool signedDist = false, double first = 0., double second = 0.); + + /**Destructor*/ + virtual ~DistanceSolution() = default; + + // methods to access solutions + /** Number of intersection solutions*/ + int numberOfSolutions() const; + + /** Distance to first intersection solution along direction*/ + double first() const; + + /** Distance to second intersection solution along direction (for a cylinder surface)*/ + double second() const; + + /** Absolute Distance to closest solution */ + double absClosest() const; + + /** Distance to point of closest approach along direction*/ + double toPointOfClosestApproach() const; + + /** Current distance to surface (spatial), signed (along/opposite to surface normal) if input argument true (absolute + * value by default)*/ + double currentDistance(bool signedDist = false) const; + + /** This method indicates availability of signed current distance (false for Perigee and StraighLineSurface) */ + bool signedDistance() const; + +protected: + int m_num; + double m_first; + double m_second; + double m_current; + bool m_signedDist; +}; + +inline int +DistanceSolution::numberOfSolutions() const +{ + return m_num; +} + +inline double +DistanceSolution::first() const +{ + return m_first; +} + +inline double +DistanceSolution::second() const +{ + return m_second; +} + +inline double +DistanceSolution::absClosest() const +{ + if (m_num > 1) + return (m_first * m_first < m_second * m_second) ? fabs(m_first) : fabs(m_second); + else + return fabs(m_first); +} + +inline double +DistanceSolution::toPointOfClosestApproach() const +{ + return m_first; +} + +inline double +DistanceSolution::currentDistance(bool signedDist) const +{ + if (signedDist) + return m_current; + else + return fabs(m_current); +} + +inline bool +DistanceSolution::signedDistance() const +{ + return m_signedDist; +} + } // end of namespace #endif // TRKSURFACES_DISTANCESOLUTION_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/EllipseBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/EllipseBounds.h index 91adb0914c25b9e91f907abe6613de57fa86b3bd..d64675cab2359cee34cba0ddb822f2277bafdb26 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/EllipseBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/EllipseBounds.h @@ -11,169 +11,216 @@ #define TRKSURFACES_ELLIPSEBOUNDS_H // Trk -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" -// +#include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" +// #include <math.h> #include <stdlib.h> class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif - namespace Trk { - /** - @class EllipseBounds - - Class to describe the bounds for a planar EllipseSurface, - i.e. the surface between two ellipses. - By providing an argument for hphisec, the bounds can - be restricted to a phirange around the center position. - - @author Marcin.Wolter@cern.ch - */ - - class EllipseBounds : public SurfaceBounds { - public: - /** @enum for readibility */ - enum BoundValues { - bv_rMinX = 0, - bv_rMinY = 1, - bv_rMaxX = 2, - bv_rMaxY = 3, - bv_averagePhi = 4, - bv_halfPhiSector = 5, - bv_length = 6 - }; - /**Default Constructor*/ - EllipseBounds(); - - /**Constructor for full of an ellipsoid disc around phi=0*/ - EllipseBounds(double minrad1, double minrad2, double maxrad1, double maxrad2, double hphisec=M_PI); - - /**Constructor for an ellipsoid disc around phi != 0*/ - EllipseBounds(double minrad1, double minrad2, double maxrad1, double maxrad2, double avephi, double hphisec); - - /**Copy constructor*/ - EllipseBounds(const EllipseBounds& discbo); - - /**Destructor*/ - virtual ~EllipseBounds(); - - /**Assignment operator*/ - EllipseBounds& operator=(const EllipseBounds& discbo); - - /**Move assignment operator*/ - EllipseBounds& operator=(EllipseBounds&& discbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor*/ - virtual EllipseBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::Ellipse; } - - /**This method checks if the point given in the local coordinates is between two ellipsoids - if only tol1 is given and additional in the phi sector is tol2 is given */ - virtual bool inside(const Amg::Vector2D &locpo, double tol1 = 0., double tol2 = 0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /**Check for inside first local coordinate */ - virtual bool insideLoc1(const Amg::Vector2D &locpo, double tol1 = 0.) const override; - - /**Check for inside second local coordinate */ - virtual bool insideLoc2(const Amg::Vector2D &locpo, double tol2 = 0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns first inner radius*/ - double rMinX() const; - - /**This method returns second inner radius*/ - double rMinY() const; - - /**This method returns first outer radius*/ - double rMaxX() const; - - /**This method returns second outer radius*/ - double rMaxY() const; - - /**This method returns the maximum expansion on the plane (=max(rMaxX,rMaxY))*/ - virtual double r() const override; - - /**This method returns the average phi*/ - double averagePhi() const; - - /**This method returns the halfPhiSector which is covered by the disc*/ - double halfPhiSector() const; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** The internal storage of the bounds can be float/double*/ - std::vector<TDD_real_t> m_boundValues; - - /** helper function for squaring */ - inline double square(double x) const {return x*x;}; - }; - - inline EllipseBounds* EllipseBounds::clone() const - { return new EllipseBounds(*this); } - - inline bool EllipseBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const - { double alpha = acos(cos(locpo[locPhi]-m_boundValues[EllipseBounds::bv_averagePhi])); - bool insidePhi = ( m_boundValues[EllipseBounds::bv_halfPhiSector]+tol2 < M_PI ) ? (alpha <= (m_boundValues[EllipseBounds::bv_halfPhiSector]+tol2)) : 1; - bool insideInner =( m_boundValues[EllipseBounds::bv_rMinX]<=tol1 ) || ( m_boundValues[EllipseBounds::bv_rMinY] <= tol1 ) - || ( square(locpo[locX]/(m_boundValues[EllipseBounds::bv_rMinX]-tol1)) + square(locpo[locY]/(m_boundValues[EllipseBounds::bv_rMinY]-tol1)) >1); - bool insideOuter = ( square(locpo[locX]/(m_boundValues[EllipseBounds::bv_rMaxX]+tol1)) + square(locpo[locY]/(m_boundValues[EllipseBounds::bv_rMaxY]+tol1)) <1); - return ( insideInner && insideOuter && insidePhi ); - - } - - inline bool EllipseBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +/** + @class EllipseBounds + + Class to describe the bounds for a planar EllipseSurface, + i.e. the surface between two ellipses. + By providing an argument for hphisec, the bounds can + be restricted to a phirange around the center position. + + @author Marcin.Wolter@cern.ch + */ + +class EllipseBounds : public SurfaceBounds +{ +public: + /** @enum for readibility */ + enum BoundValues { - return EllipseBounds::inside(locpo,bchk.toleranceLoc1,bchk.toleranceLoc2); - } - - inline bool EllipseBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { - bool insideInner =( m_boundValues[EllipseBounds::bv_rMinX]<=tol1 ) || ( m_boundValues[EllipseBounds::bv_rMinY] <= tol1 ) - || ( square(locpo[locX]/(m_boundValues[EllipseBounds::bv_rMinX]-tol1)) + square(locpo[locY]/(m_boundValues[EllipseBounds::bv_rMinY]-tol1)) >1); - bool insideOuter = ( square(locpo[locX]/(m_boundValues[EllipseBounds::bv_rMaxX]+tol1)) + square(locpo[locY]/(m_boundValues[EllipseBounds::bv_rMaxY]+tol1)) <1); - return ( insideInner && insideOuter ); + bv_rMinX = 0, + bv_rMinY = 1, + bv_rMaxX = 2, + bv_rMaxY = 3, + bv_averagePhi = 4, + bv_halfPhiSector = 5, + bv_length = 6 + }; + /**Default Constructor*/ + EllipseBounds(); + + /**Constructor for full of an ellipsoid disc around phi=0*/ + EllipseBounds(double minrad1, double minrad2, double maxrad1, double maxrad2, double hphisec = M_PI); + + /**Constructor for an ellipsoid disc around phi != 0*/ + EllipseBounds(double minrad1, double minrad2, double maxrad1, double maxrad2, double avephi, double hphisec); + + /**Copy constructor*/ + EllipseBounds(const EllipseBounds& discbo); + + /**Destructor*/ + virtual ~EllipseBounds(); + + /**Assignment operator*/ + EllipseBounds& operator=(const EllipseBounds& discbo); + + /**Move assignment operator*/ + EllipseBounds& operator=(EllipseBounds&& discbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor*/ + virtual EllipseBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::Ellipse; } + + /**This method checks if the point given in the local coordinates is between two ellipsoids + if only tol1 is given and additional in the phi sector is tol2 is given */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /**Check for inside first local coordinate */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /**Check for inside second local coordinate */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns first inner radius*/ + double rMinX() const; + + /**This method returns second inner radius*/ + double rMinY() const; + + /**This method returns first outer radius*/ + double rMaxX() const; + + /**This method returns second outer radius*/ + double rMaxY() const; + + /**This method returns the maximum expansion on the plane (=max(rMaxX,rMaxY))*/ + virtual double r() const override; + + /**This method returns the average phi*/ + double averagePhi() const; + + /**This method returns the halfPhiSector which is covered by the disc*/ + double halfPhiSector() const; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** The internal storage of the bounds can be float/double*/ + std::vector<TDD_real_t> m_boundValues; + + /** helper function for squaring */ + inline double square(double x) const { return x * x; }; +}; + +inline EllipseBounds* +EllipseBounds::clone() const +{ + return new EllipseBounds(*this); +} + +inline bool +EllipseBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + double alpha = acos(cos(locpo[locPhi] - m_boundValues[EllipseBounds::bv_averagePhi])); + bool insidePhi = (m_boundValues[EllipseBounds::bv_halfPhiSector] + tol2 < M_PI) + ? (alpha <= (m_boundValues[EllipseBounds::bv_halfPhiSector] + tol2)) + : 1; + bool insideInner = (m_boundValues[EllipseBounds::bv_rMinX] <= tol1) || + (m_boundValues[EllipseBounds::bv_rMinY] <= tol1) || + (square(locpo[locX] / (m_boundValues[EllipseBounds::bv_rMinX] - tol1)) + + square(locpo[locY] / (m_boundValues[EllipseBounds::bv_rMinY] - tol1)) > + 1); + bool insideOuter = (square(locpo[locX] / (m_boundValues[EllipseBounds::bv_rMaxX] + tol1)) + + square(locpo[locY] / (m_boundValues[EllipseBounds::bv_rMaxY] + tol1)) < + 1); + return (insideInner && insideOuter && insidePhi); } - inline bool EllipseBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { - double alpha = acos(cos(locpo[locPhi]-m_boundValues[EllipseBounds::bv_averagePhi])); - bool insidePhi = ( m_boundValues[EllipseBounds::bv_halfPhiSector]+tol2 < M_PI ) ? (alpha <= (m_boundValues[EllipseBounds::bv_halfPhiSector]+tol2)) : 1; - return insidePhi; - } - - inline double EllipseBounds::rMinX() const { return m_boundValues[EllipseBounds::bv_rMinX]; } - inline double EllipseBounds::rMinY() const { return m_boundValues[EllipseBounds::bv_rMinY]; } - inline double EllipseBounds::rMaxX() const { return m_boundValues[EllipseBounds::bv_rMaxX]; } - inline double EllipseBounds::rMaxY() const { return m_boundValues[EllipseBounds::bv_rMaxY]; } - inline double EllipseBounds::r() const { return std::max(m_boundValues[EllipseBounds::bv_rMaxX],m_boundValues[EllipseBounds::bv_rMaxY]); } - inline double EllipseBounds::averagePhi() const { return m_boundValues[EllipseBounds::bv_averagePhi]; } - inline double EllipseBounds::halfPhiSector() const { return m_boundValues[EllipseBounds::bv_halfPhiSector]; } +inline bool +EllipseBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + return EllipseBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); +} -} // end of namespace +inline bool +EllipseBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + bool insideInner = (m_boundValues[EllipseBounds::bv_rMinX] <= tol1) || + (m_boundValues[EllipseBounds::bv_rMinY] <= tol1) || + (square(locpo[locX] / (m_boundValues[EllipseBounds::bv_rMinX] - tol1)) + + square(locpo[locY] / (m_boundValues[EllipseBounds::bv_rMinY] - tol1)) > + 1); + bool insideOuter = (square(locpo[locX] / (m_boundValues[EllipseBounds::bv_rMaxX] + tol1)) + + square(locpo[locY] / (m_boundValues[EllipseBounds::bv_rMaxY] + tol1)) < + 1); + return (insideInner && insideOuter); +} +inline bool +EllipseBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + double alpha = acos(cos(locpo[locPhi] - m_boundValues[EllipseBounds::bv_averagePhi])); + bool insidePhi = (m_boundValues[EllipseBounds::bv_halfPhiSector] + tol2 < M_PI) + ? (alpha <= (m_boundValues[EllipseBounds::bv_halfPhiSector] + tol2)) + : 1; + return insidePhi; +} -#endif // TRKSURFACES_ELLIPSEBOUNDS_H +inline double +EllipseBounds::rMinX() const +{ + return m_boundValues[EllipseBounds::bv_rMinX]; +} +inline double +EllipseBounds::rMinY() const +{ + return m_boundValues[EllipseBounds::bv_rMinY]; +} +inline double +EllipseBounds::rMaxX() const +{ + return m_boundValues[EllipseBounds::bv_rMaxX]; +} +inline double +EllipseBounds::rMaxY() const +{ + return m_boundValues[EllipseBounds::bv_rMaxY]; +} +inline double +EllipseBounds::r() const +{ + return std::max(m_boundValues[EllipseBounds::bv_rMaxX], m_boundValues[EllipseBounds::bv_rMaxY]); +} +inline double +EllipseBounds::averagePhi() const +{ + return m_boundValues[EllipseBounds::bv_averagePhi]; +} +inline double +EllipseBounds::halfPhiSector() const +{ + return m_boundValues[EllipseBounds::bv_halfPhiSector]; +} +} // end of namespace +#endif // TRKSURFACES_ELLIPSEBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/InvalidBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/InvalidBounds.h index c8aacee902d1341ea7bf9d9838bae24093292ef3..d13bf173b22053807357a3e728b985a2ad3b967a 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/InvalidBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/InvalidBounds.h @@ -8,88 +8,88 @@ #ifndef TRKSURFACES_INVALIDBOUNDS_H #define TRKSURFACES_INVALIDBOUNDS_H - -#include "TrkSurfaces/SurfaceBounds.h" + #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" -//Eigen +// Eigen #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; namespace Trk { - - /** - @class InvalidBounds - Invalid Bounds object - - @author Shaun Roe - */ - - class InvalidBounds : public SurfaceBounds { - public: - /**Default Constructor*/ - InvalidBounds(){} - - /** Destructor */ - ~InvalidBounds(){} - - /**Equality operator */ - virtual bool operator==(const SurfaceBounds& ) const override {return false;} - - /**Non-Equality operator*/ - virtual bool operator!=(const SurfaceBounds& ) const override {return true;} - - /**'address of' will return nullptr **/ - InvalidBounds * operator &() {return nullptr;} - - - /** Return SurfaceBounds for persistency */ - virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Other; } - - /** Method inside() returns false for any case */ - virtual bool inside(const Amg::Vector2D& , double =0., double =0.) const override {return false; } - virtual bool inside(const Amg::Vector2D& , const BoundaryCheck& ) const override {return false; } - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& , double =0.) const override {return false; } - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& , double =0.) const override {return false; } - - /** Minimal distance to boundary (=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& ) const override {return std::nan("");} - - /** Invalidate cloning of an invalid object */ - virtual InvalidBounds* clone() const override {return nullptr;} - - /** r() method to complete inherited interface */ - virtual double r() const override {return std::nan(""); } - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - - }; - - - inline MsgStream& InvalidBounds::dump(MsgStream& sl) const - { - sl << "Trk::InvalidBounds ... invalid surface" << endmsg; - return sl; - } - - inline std::ostream& InvalidBounds::dump(std::ostream& sl) const - { - sl << "Trk::InvalidBounds ... invalid surface" << std::endl; - return sl; - } - + +/** + @class InvalidBounds + Invalid Bounds object + + @author Shaun Roe + */ + +class InvalidBounds : public SurfaceBounds +{ +public: + /**Default Constructor*/ + InvalidBounds() {} + + /** Destructor */ + ~InvalidBounds() {} + + /**Equality operator */ + virtual bool operator==(const SurfaceBounds&) const override { return false; } + + /**Non-Equality operator*/ + virtual bool operator!=(const SurfaceBounds&) const override { return true; } + + /**'address of' will return nullptr **/ + InvalidBounds* operator&() { return nullptr; } + + /** Return SurfaceBounds for persistency */ + virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Other; } + + /** Method inside() returns false for any case */ + virtual bool inside(const Amg::Vector2D&, double = 0., double = 0.) const override { return false; } + virtual bool inside(const Amg::Vector2D&, const BoundaryCheck&) const override { return false; } + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D&, double = 0.) const override { return false; } + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D&, double = 0.) const override { return false; } + + /** Minimal distance to boundary (=0 if inside) */ + virtual double minDistance(const Amg::Vector2D&) const override { return std::nan(""); } + + /** Invalidate cloning of an invalid object */ + virtual InvalidBounds* clone() const override { return nullptr; } + + /** r() method to complete inherited interface */ + virtual double r() const override { return std::nan(""); } + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: +}; + +inline MsgStream& +InvalidBounds::dump(MsgStream& sl) const +{ + sl << "Trk::InvalidBounds ... invalid surface" << endmsg; + return sl; +} + +inline std::ostream& +InvalidBounds::dump(std::ostream& sl) const +{ + sl << "Trk::InvalidBounds ... invalid surface" << std::endl; + return sl; +} + } // end of namespace #endif // TRKSURFACES_INVALIDBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/NoBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/NoBounds.h index dd03295165502b4ec3551afb48fb7017ac8e34a9..968d95dc2bcc4425e64b038a30913d9f83877f16 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/NoBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/NoBounds.h @@ -8,104 +8,130 @@ #ifndef TRKSURFACES_NOBOUNDS_H #define TRKSURFACES_NOBOUNDS_H - -#include "TrkSurfaces/SurfaceBounds.h" + #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" -//Eigen +// Eigen #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; namespace Trk { - - /** - @class NoBounds - Bounds object for a boundless surface (...) - - @author Andreas.Salzburger@cern.ch - */ - - class NoBounds : public SurfaceBounds { - public: - /**Default Constructor*/ - NoBounds(){} - - /** Destructor */ - ~NoBounds(){} - - /**Equality operator */ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /** Return SurfaceBounds for persistency */ - virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Other; } - - /** Method inside() returns true for any case */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary (=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Clone method to complete inherited interface */ - virtual NoBounds* clone() const override; - - /** r() method to complete inherited interface */ - virtual double r() const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - - }; - - inline bool NoBounds::operator==(const SurfaceBounds&) const - { return true; } - - inline bool NoBounds::inside(const Amg::Vector2D&, double, double) const - { return true; } - - inline bool NoBounds::inside(const Amg::Vector2D&, const BoundaryCheck&) const - { return true; } - - inline bool NoBounds::insideLoc1(const Amg::Vector2D&, double) const - { return true; } - - inline bool NoBounds::insideLoc2(const Amg::Vector2D&, double) const - { return true; } - - inline double NoBounds::minDistance(const Amg::Vector2D&) const - { return 0.; } - - inline NoBounds* NoBounds::clone() const - { return new NoBounds(); } - - inline double NoBounds::r() const - { return 0.; } - - inline MsgStream& NoBounds::dump(MsgStream& sl) const - { - sl << "Trk::NoBounds ... boundless surface" << endmsg; - return sl; - } - - inline std::ostream& NoBounds::dump(std::ostream& sl) const - { - sl << "Trk::NoBounds ... boundless surface" << std::endl; - return sl; - } - + +/** + @class NoBounds + Bounds object for a boundless surface (...) + + @author Andreas.Salzburger@cern.ch + */ + +class NoBounds : public SurfaceBounds +{ +public: + /**Default Constructor*/ + NoBounds() {} + + /** Destructor */ + ~NoBounds() {} + + /**Equality operator */ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /** Return SurfaceBounds for persistency */ + virtual SurfaceBounds::BoundsType type() const override { return SurfaceBounds::Other; } + + /** Method inside() returns true for any case */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary (=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /** Clone method to complete inherited interface */ + virtual NoBounds* clone() const override; + + /** r() method to complete inherited interface */ + virtual double r() const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: +}; + +inline bool +NoBounds::operator==(const SurfaceBounds&) const +{ + return true; +} + +inline bool +NoBounds::inside(const Amg::Vector2D&, double, double) const +{ + return true; +} + +inline bool +NoBounds::inside(const Amg::Vector2D&, const BoundaryCheck&) const +{ + return true; +} + +inline bool +NoBounds::insideLoc1(const Amg::Vector2D&, double) const +{ + return true; +} + +inline bool +NoBounds::insideLoc2(const Amg::Vector2D&, double) const +{ + return true; +} + +inline double +NoBounds::minDistance(const Amg::Vector2D&) const +{ + return 0.; +} + +inline NoBounds* +NoBounds::clone() const +{ + return new NoBounds(); +} + +inline double +NoBounds::r() const +{ + return 0.; +} + +inline MsgStream& +NoBounds::dump(MsgStream& sl) const +{ + sl << "Trk::NoBounds ... boundless surface" << endmsg; + return sl; +} + +inline std::ostream& +NoBounds::dump(std::ostream& sl) const +{ + sl << "Trk::NoBounds ... boundless surface" << std::endl; + return sl; +} + } // end of namespace #endif // TRKSURFACES_NOBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.h index cd06e940dad71ee7d89ebacc81f11b42f10537ea..48c50ee77a0afeeb11015030e79306f49df4b94b 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PerigeeSurface.h @@ -9,288 +9,344 @@ #ifndef TRKSURFACES_PERIGEESURFACE_H #define TRKSURFACES_PERIGEESURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/NoBounds.h" -#include "TrkParametersBase/ParametersT.h" +// Trk #include "TrkDetDescrUtils/GeometryStatics.h" +#include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/Surface.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; namespace Trk { - class LocalParameters; - template<int DIM, class T, class S> class ParametersT; - - /** - @class PerigeeSurface - - Class describing the Line to which the Perigee refers to. - The Surface axis is fixed to be the z-axis of the Tracking frame. - It inherits from Surface. - - @author Andreas.Salzburger@cern.ch - */ +class LocalParameters; +template<int DIM, class T, class S> +class ParametersT; - class PerigeeSurface : public Surface { - - public: - /**Default Constructor - needed for persistency*/ - PerigeeSurface(); - - /**Constructor from GlobalPosition*/ - PerigeeSurface(const Amg::Vector3D& gp); - - /**Constructor with a Transform - needed for tilt */ - PerigeeSurface(Amg::Transform3D* tTransform); - - /**Constructor with a Transform by unique_ptr - needed for tilt */ - PerigeeSurface(std::unique_ptr<Amg::Transform3D> tTransform); - - /**Copy constructor*/ - PerigeeSurface(const PerigeeSurface& pesf); - - /**Copy constructor with shift*/ - PerigeeSurface(const PerigeeSurface& pesf, const Amg::Transform3D& transf); - - /**Destructor*/ - virtual ~PerigeeSurface(); - - /**Virtual constructor*/ - virtual PerigeeSurface* clone() const override; - - /**Assignment operator*/ - PerigeeSurface& operator=(const PerigeeSurface& slsf ); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, PerigeeSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, PerigeeSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, PerigeeSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, PerigeeSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, PerigeeSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, PerigeeSurface>(position, momentum, charge, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, PerigeeSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, PerigeeSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, PerigeeSurface>(position, momentum, charge, *this, cov); } - - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Perigee; } - - /**Return method for transfromation, overwrites the transform() form base class*/ - virtual const Amg::Transform3D& transform() const override; - - /**Return method for surface center infromation, overwrites the center() form base class*/ - virtual const Amg::Vector3D& center() const override; - - /**Return method for surface center infromation, overwrites the center() form base class*/ - virtual const Amg::Vector3D& normal() const override; - - /**Returns a normal vector at a specific localPosition*/ - virtual const Amg::Vector3D* normal(const Amg::Vector2D& lp) const override; - - /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface - - the default implementation is the the RotationMatrix3D of the transform */ - virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const override; - - /** Local to global method: - Take care that by just providing locR and locZ the global position cannot be calculated. - Therefor only the locZ-coordinate is taken and transformed into the global frame. - for calculating the global position, a momentum direction has to be provided as well, use the - appropriate function! - */ - virtual const Amg::Vector3D* localToGlobal(const LocalParameters& locpos) const; - - /** This method is the true local->global transformation.<br> - by providing a locR and locZ coordinate such as a GlobalMomentum - the global position can be calculated. - The choice between the two possible canditates is done by the sign of the radius - */ - virtual const Amg::Vector3D* localToGlobal(const LocalParameters& locpos, const Amg::Vector3D& glomom) const; - - /** LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** GlobalToLocal method without dynamic memory allocation - boolean checks if on surface - \image html SignOfDriftCircleD0.gif - */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceDir is to provide the closest forward solution - - b>mathematical motivation:</b> - Given two lines in parameteric form:<br> - - @f$ \vec l_{a}(\lambda) = \vec m_a + \lambda \cdot \vec e_{a} @f$ <br> - - @f$ \vec l_{b}(\mu) = \vec m_b + \mu \cdot \vec e_{b} @f$ <br> - the vector between any two points on the two lines is given by: - - @f$ \vec s(\lambda, \mu) = \vec l_{b} - l_{a} = \vec m_{ab} + \mu \cdot \vec e_{b} - \lambda \cdot \vec e_{a} @f$, <br> - when @f$ \vec m_{ab} = \vec m_{b} - \vec m_{a} @f$.<br> - @f$ \vec s(\lambda_0, \mu_0) @f$ denotes the vector between the two closest points <br> - @f$ \vec l_{a,0} = l_{a}(\lambda_0) @f$ and @f$ \vec l_{b,0} = l_{b}(\mu_0) @f$ <br> - and is perpenticular to both, @f$ \vec e_{a} @f$ and @f$ \vec e_{b} @f$. - - This results in a system of two linear equations:<br> - - (i) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_a = \vec m_ab \cdot \vec e_a + \mu_0 \vec e_a \cdot \vec e_b - \lambda_0 @f$ <br> - - (ii) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_b = \vec m_ab \cdot \vec e_b + \mu_0 - \lambda_0 \vec e_b \cdot \vec e_a @f$ <br> - - Solving (i), (ii) for @f$ \lambda_0 @f$ and @f$ \mu_0 @f$ yields: - - @f$ \lambda_0 = \frac{(\vec m_ab \cdot \vec e_a)-(\vec m_ab \cdot \vec e_b)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br> - - @f$ \mu_0 = - \frac{(\vec m_ab \cdot \vec e_b)-(\vec m_ab \cdot \vec e_a)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br> - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir = false, - Trk::BoundaryCheck bchk = false) const override; - - /** fast straight line distance evaluation to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const override; - - /** fast straight line distance evaluation to Surface - with bound option*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const override; - - - /** the pathCorrection for derived classes with thickness */ - virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override { return 1.; } - - /**This method checks if a globalPosition in on the Surface or not*/ - virtual bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk=true, double tol1=0., double tol2=0.) const override; - - /**This surface calls the iside method of the bounds*/ - virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const override; - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** Special method for StraightLineSurface - provides the Line direction from cache: speedup */ - const Amg::Vector3D& lineDirection() const; - - /** Return bounds() method */ - virtual const NoBounds& bounds() const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::PerigeeSurface"; } - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - /** Output Method for std::ostream*/ - virtual std::ostream& dump(std::ostream& sl) const override; - - protected: //!< data members - - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_lineDirection; //!< cache of the line direction (speeds up) - static const NoBounds s_perigeeBounds; - - }; - - - inline PerigeeSurface* PerigeeSurface::clone() const {return new PerigeeSurface(*this);} - - inline const Amg::Transform3D& PerigeeSurface::transform() const +/** + @class PerigeeSurface + + Class describing the Line to which the Perigee refers to. + The Surface axis is fixed to be the z-axis of the Tracking frame. + It inherits from Surface. + + @author Andreas.Salzburger@cern.ch + */ + +class PerigeeSurface : public Surface +{ + +public: + /**Default Constructor - needed for persistency*/ + PerigeeSurface(); + + /**Constructor from GlobalPosition*/ + PerigeeSurface(const Amg::Vector3D& gp); + + /**Constructor with a Transform - needed for tilt */ + PerigeeSurface(Amg::Transform3D* tTransform); + + /**Constructor with a Transform by unique_ptr - needed for tilt */ + PerigeeSurface(std::unique_ptr<Amg::Transform3D> tTransform); + + /**Copy constructor*/ + PerigeeSurface(const PerigeeSurface& pesf); + + /**Copy constructor with shift*/ + PerigeeSurface(const PerigeeSurface& pesf, const Amg::Transform3D& transf); + + /**Destructor*/ + virtual ~PerigeeSurface(); + + /**Virtual constructor*/ + virtual PerigeeSurface* clone() const override; + + /**Assignment operator*/ + PerigeeSurface& operator=(const PerigeeSurface& slsf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, PerigeeSurface>* createTrackParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Charged, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, PerigeeSurface>* createTrackParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override { - if (!Surface::m_transform) return(s_idTransform); - return(*Trk::Surface::m_transform); + return new ParametersT<5, Charged, PerigeeSurface>(position, momentum, charge, *this, cov); } - inline const Amg::Vector3D& PerigeeSurface::center() const + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, PerigeeSurface>* createNeutralParameters( + double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - if (!Surface::m_center && !Surface::m_transform) return(s_origin); - else if (!Surface::m_center) m_center.set(std::make_unique<Amg::Vector3D>(m_transform->translation())); - return(*Surface::m_center); + return new ParametersT<5, Neutral, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); } - - inline const Amg::Vector3D& PerigeeSurface::normal() const { return(s_xAxis); } - - inline const Amg::Vector3D* PerigeeSurface::normal(const Amg::Vector2D&) const { return new Amg::Vector3D(this->normal()); } - - inline bool PerigeeSurface::insideBounds(const Amg::Vector2D&, double, double) const { return true;} - - inline bool PerigeeSurface::insideBoundsCheck(const Amg::Vector2D&, const BoundaryCheck& ) const { return true;} - - inline bool PerigeeSurface::isOnSurface(const Amg::Vector3D&, BoundaryCheck, double, double) const {return true;} - - inline const NoBounds& PerigeeSurface::bounds() const { return s_perigeeBounds; } - - inline Intersection PerigeeSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck) const + + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, PerigeeSurface>* createNeutralParameters( + const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override { - // following nominclature found in header file and doxygen documentation - // line one is the straight track - const Amg::Vector3D ma = pos; - const Amg::Vector3D& ea = dir; - // line two is the line surface - const Amg::Vector3D& mb = center(); - const Amg::Vector3D& eb = lineDirection(); - // now go ahead - Amg::Vector3D mab(mb - ma); - double eaTeb = ea.dot(eb); - double denom = 1 - eaTeb*eaTeb; - if (fabs(denom)>10e-7){ - double lambda0 = (mab.dot(ea) - mab.dot(eb)*eaTeb)/denom; - // evaluate the direction, bounds are always true for Perigee - bool isValid = forceDir ? (lambda0 > 0.) : true; - return Trk::Intersection( (ma+lambda0*ea),lambda0, isValid ); - } - return Trk::Intersection(pos,0.,false); + return new ParametersT<5, Neutral, PerigeeSurface>(position, momentum, charge, *this, cov); } - - inline const Amg::Vector3D& PerigeeSurface::lineDirection() const { - if (m_lineDirection) - return (*m_lineDirection); - if (!m_lineDirection && Surface::m_transform) { - m_lineDirection.set(std::make_unique<Amg::Vector3D>(transform().rotation().col(2))); - return (*m_lineDirection); - } - return Trk::s_zAxis; - - } - + + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, PerigeeSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, PerigeeSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, PerigeeSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, PerigeeSurface>(position, momentum, charge, *this, cov); + } + + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Perigee; } + + /**Return method for transfromation, overwrites the transform() form base class*/ + virtual const Amg::Transform3D& transform() const override; + + /**Return method for surface center infromation, overwrites the center() form base class*/ + virtual const Amg::Vector3D& center() const override; + + /**Return method for surface center infromation, overwrites the center() form base class*/ + virtual const Amg::Vector3D& normal() const override; + + /**Returns a normal vector at a specific localPosition*/ + virtual const Amg::Vector3D* normal(const Amg::Vector2D& lp) const override; + + /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface + - the default implementation is the the RotationMatrix3D of the transform */ + virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom) const override; + + /** Local to global method: + Take care that by just providing locR and locZ the global position cannot be calculated. + Therefor only the locZ-coordinate is taken and transformed into the global frame. + for calculating the global position, a momentum direction has to be provided as well, use the + appropriate function! + */ + virtual const Amg::Vector3D* localToGlobal(const LocalParameters& locpos) const; + + /** This method is the true local->global transformation.<br> + by providing a locR and locZ coordinate such as a GlobalMomentum + the global position can be calculated. + The choice between the two possible canditates is done by the sign of the radius + */ + virtual const Amg::Vector3D* localToGlobal(const LocalParameters& locpos, const Amg::Vector3D& glomom) const; + + /** LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** GlobalToLocal method without dynamic memory allocation - boolean checks if on surface + \image html SignOfDriftCircleD0.gif + */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceDir is to provide the closest forward solution + + b>mathematical motivation:</b> + Given two lines in parameteric form:<br> + - @f$ \vec l_{a}(\lambda) = \vec m_a + \lambda \cdot \vec e_{a} @f$ <br> + - @f$ \vec l_{b}(\mu) = \vec m_b + \mu \cdot \vec e_{b} @f$ <br> + the vector between any two points on the two lines is given by: + - @f$ \vec s(\lambda, \mu) = \vec l_{b} - l_{a} = \vec m_{ab} + \mu \cdot \vec e_{b} - \lambda \cdot \vec e_{a} + @f$, <br> when @f$ \vec m_{ab} = \vec m_{b} - \vec m_{a} @f$.<br> + @f$ \vec s(\lambda_0, \mu_0) @f$ denotes the vector between the two closest points <br> + @f$ \vec l_{a,0} = l_{a}(\lambda_0) @f$ and @f$ \vec l_{b,0} = l_{b}(\mu_0) @f$ <br> + and is perpenticular to both, @f$ \vec e_{a} @f$ and @f$ \vec e_{b} @f$. + + This results in a system of two linear equations:<br> + - (i) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_a = \vec m_ab \cdot \vec e_a + \mu_0 \vec e_a \cdot \vec e_b - + \lambda_0 @f$ <br> + - (ii) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_b = \vec m_ab \cdot \vec e_b + \mu_0 - \lambda_0 \vec e_b + \cdot \vec e_a @f$ <br> + + Solving (i), (ii) for @f$ \lambda_0 @f$ and @f$ \mu_0 @f$ yields: + - @f$ \lambda_0 = \frac{(\vec m_ab \cdot \vec e_a)-(\vec m_ab \cdot \vec e_b)(\vec e_a \cdot \vec e_b)}{1-(\vec + e_a \cdot \vec e_b)^2} @f$ <br> + - @f$ \mu_0 = - \frac{(\vec m_ab \cdot \vec e_b)-(\vec m_ab \cdot \vec e_a)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a + \cdot \vec e_b)^2} @f$ <br> + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir = false, + Trk::BoundaryCheck bchk = false) const override; + + /** fast straight line distance evaluation to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + + /** fast straight line distance evaluation to Surface - with bound option*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool Bound) const override; + + /** the pathCorrection for derived classes with thickness */ + virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override { return 1.; } + + /**This method checks if a globalPosition in on the Surface or not*/ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const override; + + /**This surface calls the iside method of the bounds*/ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + + /** Special method for StraightLineSurface - provides the Line direction from cache: speedup */ + const Amg::Vector3D& lineDirection() const; + + /** Return bounds() method */ + virtual const NoBounds& bounds() const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::PerigeeSurface"; } + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + /** Output Method for std::ostream*/ + virtual std::ostream& dump(std::ostream& sl) const override; + +protected: //!< data members + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_lineDirection; //!< cache of the line direction (speeds up) + static const NoBounds s_perigeeBounds; +}; + +inline PerigeeSurface* +PerigeeSurface::clone() const +{ + return new PerigeeSurface(*this); +} + +inline const Amg::Transform3D& +PerigeeSurface::transform() const +{ + if (!Surface::m_transform) + return (s_idTransform); + return (*Trk::Surface::m_transform); +} + +inline const Amg::Vector3D& +PerigeeSurface::center() const +{ + if (!Surface::m_center && !Surface::m_transform) + return (s_origin); + else if (!Surface::m_center) + m_center.set(std::make_unique<Amg::Vector3D>(m_transform->translation())); + return (*Surface::m_center); +} + +inline const Amg::Vector3D& +PerigeeSurface::normal() const +{ + return (s_xAxis); +} + +inline const Amg::Vector3D* +PerigeeSurface::normal(const Amg::Vector2D&) const +{ + return new Amg::Vector3D(this->normal()); +} + +inline bool +PerigeeSurface::insideBounds(const Amg::Vector2D&, double, double) const +{ + return true; +} + +inline bool +PerigeeSurface::insideBoundsCheck(const Amg::Vector2D&, const BoundaryCheck&) const +{ + return true; +} + +inline bool +PerigeeSurface::isOnSurface(const Amg::Vector3D&, BoundaryCheck, double, double) const +{ + return true; +} + +inline const NoBounds& +PerigeeSurface::bounds() const +{ + return s_perigeeBounds; +} + +inline Intersection +PerigeeSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck) const +{ + // following nominclature found in header file and doxygen documentation + // line one is the straight track + const Amg::Vector3D ma = pos; + const Amg::Vector3D& ea = dir; + // line two is the line surface + const Amg::Vector3D& mb = center(); + const Amg::Vector3D& eb = lineDirection(); + // now go ahead + Amg::Vector3D mab(mb - ma); + double eaTeb = ea.dot(eb); + double denom = 1 - eaTeb * eaTeb; + if (fabs(denom) > 10e-7) { + double lambda0 = (mab.dot(ea) - mab.dot(eb) * eaTeb) / denom; + // evaluate the direction, bounds are always true for Perigee + bool isValid = forceDir ? (lambda0 > 0.) : true; + return Trk::Intersection((ma + lambda0 * ea), lambda0, isValid); + } + return Trk::Intersection(pos, 0., false); +} + +inline const Amg::Vector3D& +PerigeeSurface::lineDirection() const +{ + if (m_lineDirection) + return (*m_lineDirection); + if (!m_lineDirection && Surface::m_transform) { + m_lineDirection.set(std::make_unique<Amg::Vector3D>(transform().rotation().col(2))); + return (*m_lineDirection); + } + return Trk::s_zAxis; +} + } // end of namespace #endif // TRKSURFACES_PERIGEESURFACE_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PlaneSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PlaneSurface.h index aa85a3e6d6f51fa409893456143924654388c80e..e2906e3c77f1477b81781a87ba3dd8ce17990c49 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PlaneSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/PlaneSurface.h @@ -9,279 +9,308 @@ #ifndef TRKSURFACES_PLANESURFACE_H #define TRKSURFACES_PLANESURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkSurfaces/NoBounds.h" +// Trk #include "TrkDetDescrUtils/SharedObject.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/Surface.h" +#include "TrkSurfaces/SurfaceBounds.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class MsgStream; class Identifier; -template< class SURFACE, class BOUNDS_CNV > class BoundSurfaceCnv_p1; +template<class SURFACE, class BOUNDS_CNV> +class BoundSurfaceCnv_p1; namespace Trk { - class LocalDirection; - class LocalParameters; - class TrkDetElementBase; - class RectangleBounds; - class TriangleBounds; - class AnnulusBounds; - class TrapezoidBounds; - class RotatedTrapezoidBounds; - class DiamondBounds; - class EllipseBounds; - class CurvilinearUVT; - template<int DIM, class T, class S> class ParametersT; - - /** - @class PlaneSurface - Class for a planaer rectangular or trapezoidal surface in the ATLAS detector. - It inherits from Surface. - - The Trk::PlaneSurface extends the Surface class with the possibility to convert - in addition to local to global positions, also local to global direction (vice versa). - The definition with of a local direciton with respect to a plane can be found in - the dedicated Trk::LocalDirection class of the TrkEventPrimitives package. - - @image html PlaneSurface.gif - - @author Andreas.Salzburger@cern.ch - */ +class LocalDirection; +class LocalParameters; +class TrkDetElementBase; +class RectangleBounds; +class TriangleBounds; +class AnnulusBounds; +class TrapezoidBounds; +class RotatedTrapezoidBounds; +class DiamondBounds; +class EllipseBounds; +class CurvilinearUVT; +template<int DIM, class T, class S> +class ParametersT; + +/** + @class PlaneSurface + Class for a planaer rectangular or trapezoidal surface in the ATLAS detector. + It inherits from Surface. + + The Trk::PlaneSurface extends the Surface class with the possibility to convert + in addition to local to global positions, also local to global direction (vice versa). + The definition with of a local direciton with respect to a plane can be found in + the dedicated Trk::LocalDirection class of the TrkEventPrimitives package. + + @image html PlaneSurface.gif + + @author Andreas.Salzburger@cern.ch + */ + +class PlaneSurface : public Surface +{ +public: + /** Default Constructor - needed for persistency*/ + PlaneSurface(); + + /** Copy Constructor*/ + PlaneSurface(const PlaneSurface& psf); + + /** Copy Constructor with shift*/ + PlaneSurface(const PlaneSurface& psf, const Amg::Transform3D& transf); + + /** Dedicated Constructor with CurvilinearUVT class */ + PlaneSurface(const Amg::Vector3D& position, const CurvilinearUVT& curvUVT); + + /** Constructor from TrkDetElementBase*/ + PlaneSurface(const TrkDetElementBase& detelement, Amg::Transform3D* transf = nullptr); + + /** Constructor from TrkDetElementBase and Identifier in case one element holds more surfaces*/ + PlaneSurface(const TrkDetElementBase& detelement, const Identifier& id, Amg::Transform3D* transf = nullptr); + + /** Constructor for planar Surface without Bounds */ + PlaneSurface(Amg::Transform3D* htrans); + + /** Constructor for planar Surface from unique_ptr without Bounds */ + PlaneSurface(std::unique_ptr<Amg::Transform3D> htrans); - class PlaneSurface : public Surface { - public: - - /** Default Constructor - needed for persistency*/ - PlaneSurface(); - - /** Copy Constructor*/ - PlaneSurface(const PlaneSurface& psf); - - /** Copy Constructor with shift*/ - PlaneSurface(const PlaneSurface& psf, const Amg::Transform3D& transf); - - /** Dedicated Constructor with CurvilinearUVT class */ - PlaneSurface(const Amg::Vector3D& position, const CurvilinearUVT& curvUVT); - - /** Constructor from TrkDetElementBase*/ - PlaneSurface(const TrkDetElementBase& detelement,Amg::Transform3D* transf=nullptr); - - /** Constructor from TrkDetElementBase and Identifier in case one element holds more surfaces*/ - PlaneSurface(const TrkDetElementBase& detelement, const Identifier& id,Amg::Transform3D* transf=nullptr); - - /** Constructor for planar Surface without Bounds */ - PlaneSurface(Amg::Transform3D* htrans); - - /** Constructor for planar Surface from unique_ptr without Bounds */ - PlaneSurface(std::unique_ptr<Amg::Transform3D> htrans); - - /** Constructor for Rectangular Planes*/ - PlaneSurface(Amg::Transform3D* htrans, double halephi, double haleta); - - /** Constructor for Trapezoidal Planes*/ - PlaneSurface(Amg::Transform3D* htrans, double minhalephi, double maxhalephi, double haleta); - - /** Constructor for Planes with provided RectangleBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, RectangleBounds* rbounds); - - /** Constructor for Planes with provided TriangleBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, TriangleBounds* rbounds); - - /** Constructor for Planes with provided AnnulusBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, AnnulusBounds* rbounds); - - /** Constructor for Planes with provided TrapezoidBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, TrapezoidBounds* rbounds); - - /** Constructor for Planes with provided RotatedTrapezoidBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, RotatedTrapezoidBounds* rbounds); - - /** Constructor for Planes with provided DiamondBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, DiamondBounds* rbounds); - - /** Constructor for Planes with provided EllipseBounds - ownership of bounds is passed*/ - PlaneSurface(Amg::Transform3D* htrans, EllipseBounds* rbounds); - - /** Constructor for Planes with shared object*/ - PlaneSurface(Amg::Transform3D* htrans, Trk::SharedObject<const Trk::SurfaceBounds>& sbounds); - - /**Destructor*/ - virtual ~PlaneSurface(); - - /**Assignment operator*/ - PlaneSurface& operator=(const PlaneSurface& psf); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /**Virtual constructor*/ - virtual PlaneSurface* clone() const override; - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Plane; } - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, PlaneSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, PlaneSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, PlaneSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, PlaneSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, PlaneSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double oop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, PlaneSurface>(l1, l2, phi, theta, oop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, PlaneSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge = 0., - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, PlaneSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, PlaneSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, PlaneSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, PlaneSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, PlaneSurface>(position, momentum, charge, *this, cov); } - - /**This method returns the bounds by reference, static NoBounds in case of no boundaries*/ - virtual const SurfaceBounds& bounds() const override; - - /**This method calls the inside() method of the Bounds*/ - virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const override; - - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - virtual bool isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk=true, double tol1=0., double tol2=0.) const override; - - /** Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** This method transforms a local direction wrt the plane to a global direction */ - void localToGlobalDirection(const Trk::LocalDirection& locdir, Amg::Vector3D& globdir) const; - - /**This method transforms the global direction to a local direction wrt the plane */ - void globalToLocalDirection(const Amg::Vector3D& glodir, Trk::LocalDirection& locdir ) const; - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceDir is to provide the closest forward solution - - <b>mathematical motivation:</b> - - the equation of the plane is given by: <br> - @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> - where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, - @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible points - on the plane.<br> - Given a line with:<br> - @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> - the solution for @f$ u @f$ can be written: - @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> - If the denominator is 0 then the line lies: - - either in the plane - - perpenticular to the normal of the plane - - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const override; - - /** fast straight line distance evaluation to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const override; - - /** fast straight line distance evaluation to Surface - with bound option*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::PlaneSurface"; } - - protected: //!< data members - template< class SURFACE, class BOUNDS_CNV > friend class ::BoundSurfaceCnv_p1; - - SharedObject<const SurfaceBounds> m_bounds; //!< bounds (shared) - static const NoBounds s_boundless; //!< NoBounds as return object when no bounds are declared - - }; - - - inline PlaneSurface* PlaneSurface::clone() const { return new PlaneSurface(*this);} - - inline bool PlaneSurface::insideBounds(const Amg::Vector2D& locpos, - double tol1, - double tol2) const - { return (bounds().inside(locpos,tol1,tol2));} - - inline bool PlaneSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const - { return (bounds().inside(locpos,bchk));} - - inline const SurfaceBounds& PlaneSurface::bounds() const + /** Constructor for Rectangular Planes*/ + PlaneSurface(Amg::Transform3D* htrans, double halephi, double haleta); + + /** Constructor for Trapezoidal Planes*/ + PlaneSurface(Amg::Transform3D* htrans, double minhalephi, double maxhalephi, double haleta); + + /** Constructor for Planes with provided RectangleBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, RectangleBounds* rbounds); + + /** Constructor for Planes with provided TriangleBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, TriangleBounds* rbounds); + + /** Constructor for Planes with provided AnnulusBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, AnnulusBounds* rbounds); + + /** Constructor for Planes with provided TrapezoidBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, TrapezoidBounds* rbounds); + + /** Constructor for Planes with provided RotatedTrapezoidBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, RotatedTrapezoidBounds* rbounds); + + /** Constructor for Planes with provided DiamondBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, DiamondBounds* rbounds); + + /** Constructor for Planes with provided EllipseBounds - ownership of bounds is passed*/ + PlaneSurface(Amg::Transform3D* htrans, EllipseBounds* rbounds); + + /** Constructor for Planes with shared object*/ + PlaneSurface(Amg::Transform3D* htrans, Trk::SharedObject<const Trk::SurfaceBounds>& sbounds); + + /**Destructor*/ + virtual ~PlaneSurface(); + + /**Assignment operator*/ + PlaneSurface& operator=(const PlaneSurface& psf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /**Virtual constructor*/ + virtual PlaneSurface* clone() const override; + + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Plane; } + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, PlaneSurface>* createTrackParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override { - if (m_bounds.get()) return *(m_bounds.get()); - if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()){ - return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); - } - if (Surface::m_associatedDetElement) return m_associatedDetElement->bounds(); - return s_boundless; + return new ParametersT<5, Charged, PlaneSurface>(l1, l2, phi, theta, qop, *this, cov); } + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, PlaneSurface>* createTrackParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Charged, PlaneSurface>(position, momentum, charge, *this, cov); + } - inline Intersection PlaneSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, PlaneSurface>* createNeutralParameters(double l1, + double l2, + double phi, + double theta, + double oop, + AmgSymMatrix(5) * cov = 0) const override { - double denom = dir.dot(normal()); - if (denom){ - double u = (normal().dot((center()-pos)))/(denom); - Amg::Vector3D intersectPoint(pos + u * dir); - // evaluate the intersection in terms of direction - bool isValid = forceDir ? ( u > 0.) : true; - // evaluate (if necessary in terms of boundaries) - isValid = bchk ? (isValid && isOnSurface(intersectPoint) ) : isValid; - // return the result - return Trk::Intersection(intersectPoint,u,isValid); - } - return Trk::Intersection(pos,0.,false); + return new ParametersT<5, Neutral, PlaneSurface>(l1, l2, phi, theta, oop, *this, cov); } - -} // end of namespace -#endif // TRKSURFACES_PLANESURFACE_H + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, PlaneSurface>* createNeutralParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge = 0., + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, PlaneSurface>(position, momentum, charge, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, PlaneSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, PlaneSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, PlaneSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, PlaneSurface>(position, momentum, charge, *this, cov); + } + + /**This method returns the bounds by reference, static NoBounds in case of no boundaries*/ + virtual const SurfaceBounds& bounds() const override; + + /**This method calls the inside() method of the Bounds*/ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const override; + + /** Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface + */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** This method transforms a local direction wrt the plane to a global direction */ + void localToGlobalDirection(const Trk::LocalDirection& locdir, Amg::Vector3D& globdir) const; + + /**This method transforms the global direction to a local direction wrt the plane */ + void globalToLocalDirection(const Amg::Vector3D& glodir, Trk::LocalDirection& locdir) const; + + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceDir is to provide the closest forward solution + <b>mathematical motivation:</b> + the equation of the plane is given by: <br> + @f$ \vec n \cdot \vec x = \vec n \cdot \vec p,@f$ <br> + where @f$ \vec n = (n_{x}, n_{y}, n_{z})@f$ denotes the normal vector of the plane, + @f$ \vec p = (p_{x}, p_{y}, p_{z})@f$ one specific point on the plane and @f$ \vec x = (x,y,z) @f$ all possible + points on the plane.<br> Given a line with:<br> + @f$ \vec l(u) = \vec l_{1} + u \cdot \vec v @f$, <br> + the solution for @f$ u @f$ can be written: + @f$ u = \frac{\vec n (\vec p - \vec l_{1})}{\vec n \vec v}@f$ <br> + If the denominator is 0 then the line lies: + - either in the plane + - perpenticular to the normal of the plane + + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const override; + + /** fast straight line distance evaluation to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + + /** fast straight line distance evaluation to Surface - with bound option*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool Bound) const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::PlaneSurface"; } + +protected: //!< data members + template<class SURFACE, class BOUNDS_CNV> + friend class ::BoundSurfaceCnv_p1; + + SharedObject<const SurfaceBounds> m_bounds; //!< bounds (shared) + static const NoBounds s_boundless; //!< NoBounds as return object when no bounds are declared +}; + +inline PlaneSurface* +PlaneSurface::clone() const +{ + return new PlaneSurface(*this); +} + +inline bool +PlaneSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + return (bounds().inside(locpos, tol1, tol2)); +} + +inline bool +PlaneSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const +{ + return (bounds().inside(locpos, bchk)); +} + +inline const SurfaceBounds& +PlaneSurface::bounds() const +{ + if (m_bounds.get()) + return *(m_bounds.get()); + if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()) { + return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); + } + if (Surface::m_associatedDetElement) + return m_associatedDetElement->bounds(); + return s_boundless; +} + +inline Intersection +PlaneSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const +{ + double denom = dir.dot(normal()); + if (denom) { + double u = (normal().dot((center() - pos))) / (denom); + Amg::Vector3D intersectPoint(pos + u * dir); + // evaluate the intersection in terms of direction + bool isValid = forceDir ? (u > 0.) : true; + // evaluate (if necessary in terms of boundaries) + isValid = bchk ? (isValid && isOnSurface(intersectPoint)) : isValid; + // return the result + return Trk::Intersection(intersectPoint, u, isValid); + } + return Trk::Intersection(pos, 0., false); +} + +} // end of namespace + +#endif // TRKSURFACES_PLANESURFACE_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h index 5a95bd723eae68bb5d78b05b714d7e6363ab64ca..e0723a56d6ce4b79e584f06467d776f0e442a57a 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RealQuadraticEquation.h @@ -9,56 +9,68 @@ #ifndef TRKEXUTILS_REALQUADRATICEQUATION_H #define TRKEXUTILS_REALQUADRATICEQUATION_H -#include <utility> #include <cmath> +#include <utility> namespace Trk { - /** @enum RQESolutionType - */ - - enum RQESolutionType { none=0, one=1, two=2 }; - - /** @struct RealQuadradicEquation - Mathematic struct for solving real quadratic equations - - <b>Mathematical motivation</b>:<br> - The equation is given by:<br> - @f$ \alpha x^{2} + \beta x + \gamma = 0 @f$ - and has therefore the analytical solution:<br> - @f$ x_{1, 2} = - \frac{\beta \pm \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha}@f$ <br> - <br> - - case @f$ \beta > 0 @f$:<br> - @f$ x_{1} = - \frac{\beta + \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha} := \frac{q}{\alpha}@f$, <br> - so that @f$ q= -\frac{1}{2}(\beta+sqrt{\beta^{2}-4\alpha\gamma})@f$. - @f$ x_{2} @f$ can now be written as: @f$ x_{2} = \frac{\gamma}{q} = -\frac{2\gamma}{\beta+sqrt{\beta^{2}-4\alpha\gamma}}@f$, since: <br> - @f$ -\frac{2\gamma}{\beta+sqrt{\beta^{2}-4\alpha\gamma}} = -\frac{2\gamma}{\beta}\frac{1}{1+\sqrt{1-4\alpha\gamma/\beta^{2}}}@f$, and <br> - @f$ x_{2}\frac{1}{1-\sqrt{1-4\alpha\gamma/\beta^{2}}} = -\frac{2\gamma}{\beta}\frac{1}{1-1+4\alpha\gamma/\beta^{2}}=-\frac{\beta}{2\alpha}.@f$<br> - Hence,@f$ -\frac{\beta(1-\sqrt{1-4\alpha\gamma/\beta^{2}}}{2\alpha} = - \frac{\beta - \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha} @f$.<br> - - case @f$ \beta > 0 @f$ is similar. - - @author Andreas.Salzburger@cern.ch - */ - - struct RealQuadraticEquation { +/** @enum RQESolutionType + */ - double first; - double second; - RQESolutionType solutions; +enum RQESolutionType +{ + none = 0, + one = 1, + two = 2 +}; - RealQuadraticEquation(double alpha, double beta, double gamma) : first(0.), second(0.) { - double discriminant = beta*beta - 4*alpha*gamma; - if (discriminant<0) solutions = none; - else { - solutions = (discriminant==0) ? one : two; - double q = -0.5*(beta + (beta>0 ? sqrt(discriminant) : -sqrt(discriminant))); - first = q/alpha; - second = gamma/q; - } - } +/** @struct RealQuadradicEquation + Mathematic struct for solving real quadratic equations - }; + <b>Mathematical motivation</b>:<br> + The equation is given by:<br> + @f$ \alpha x^{2} + \beta x + \gamma = 0 @f$ + and has therefore the analytical solution:<br> + @f$ x_{1, 2} = - \frac{\beta \pm \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha}@f$ <br> + <br> + - case @f$ \beta > 0 @f$:<br> + @f$ x_{1} = - \frac{\beta + \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha} := \frac{q}{\alpha}@f$, <br> + so that @f$ q= -\frac{1}{2}(\beta+sqrt{\beta^{2}-4\alpha\gamma})@f$. + @f$ x_{2} @f$ can now be written as: @f$ x_{2} = \frac{\gamma}{q} = + -\frac{2\gamma}{\beta+sqrt{\beta^{2}-4\alpha\gamma}}@f$, since: <br> + @f$ -\frac{2\gamma}{\beta+sqrt{\beta^{2}-4\alpha\gamma}} = + -\frac{2\gamma}{\beta}\frac{1}{1+\sqrt{1-4\alpha\gamma/\beta^{2}}}@f$, and <br> + @f$ x_{2}\frac{1}{1-\sqrt{1-4\alpha\gamma/\beta^{2}}} = + -\frac{2\gamma}{\beta}\frac{1}{1-1+4\alpha\gamma/\beta^{2}}=-\frac{\beta}{2\alpha}.@f$<br> Hence,@f$ + -\frac{\beta(1-\sqrt{1-4\alpha\gamma/\beta^{2}}}{2\alpha} = - \frac{\beta - \sqrt{\beta^{2}-4\alpha\gamma}}{2\alpha} + @f$.<br> + - case @f$ \beta > 0 @f$ is similar. -} // end of namespace + @author Andreas.Salzburger@cern.ch + */ + +struct RealQuadraticEquation +{ -#endif // TRKEXUTILS_REALQUADRATICEQUATION_H + double first; + double second; + RQESolutionType solutions; + + RealQuadraticEquation(double alpha, double beta, double gamma) + : first(0.) + , second(0.) + { + double discriminant = beta * beta - 4 * alpha * gamma; + if (discriminant < 0) + solutions = none; + else { + solutions = (discriminant == 0) ? one : two; + double q = -0.5 * (beta + (beta > 0 ? sqrt(discriminant) : -sqrt(discriminant))); + first = q / alpha; + second = gamma / q; + } + } +}; + +} // end of namespace +#endif // TRKEXUTILS_REALQUADRATICEQUATION_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RectangleBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RectangleBounds.h index a81e46c7e49a6509e6495c63d872d2f1a4e2fe67..063ac1d4047d4615b7e82942a1f28f411071b55c 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RectangleBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RectangleBounds.h @@ -11,177 +11,211 @@ #include "TrkSurfaces/SurfaceBounds.h" - class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class RectangleBounds - - Bounds for a rectangular, planar surface. - The two local coordinates locX, locY are for legacy reasons - also called @f$ phi @f$ respectively @f$ eta @f$. The orientation - with respect to the local surface framce can be seen in the attached - illustration. - - @image html RectangularBounds.gif - - @author Andreas.Salzburger@cern.ch */ - - class RectangleBounds : public SurfaceBounds { - - public: - - /** @enum BoundValues for readability */ - enum BoundValues { - bv_halfX = 0, - bv_halfY = 1, - bv_length = 2 - }; - - /**Default Constructor - needed for persistency*/ - RectangleBounds(); - - /**Constructor with halflength in x (phi) and halflength in y (eta)*/ - RectangleBounds(double halex, double haley); - - /**Copy constructor*/ - RectangleBounds(const RectangleBounds& recbo); - - /**Destructor*/ - virtual ~RectangleBounds(); - - /**Assignment Operator*/ - RectangleBounds& operator=(const RectangleBounds& recbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor*/ - virtual RectangleBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::Rectangle; } - - /**This method checks if the provided local coordinates are inside the surface bounds*/ - virtual bool inside(const Amg::Vector2D &locpo, double tol1=0., double tol2=0.) const override; - - /**This method checks if the provided local coordinates are inside the surface bounds*/ - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns the halflength in phi (first coordinate of local surface frame)*/ - double halflengthPhi() const; - - /**This method returns the halflength in Eta (second coordinate of local surface frame)*/ - double halflengthEta() const; - - /**for consistant naming*/ - double halflengthX() const; - - /**for consitant naming*/ - double halflengthY() const; - - /**This method returns the maximal extension on the local plane, i.e. @f$s\sqrt{h_{\phi}^2 + h_{\eta}^2}\f$*/ - virtual double r() const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - /** The internal version of the bounds can be float/double*/ - std::vector<TDD_real_t> m_boundValues; +/** + @class RectangleBounds - }; + Bounds for a rectangular, planar surface. + The two local coordinates locX, locY are for legacy reasons + also called @f$ phi @f$ respectively @f$ eta @f$. The orientation + with respect to the local surface framce can be seen in the attached + illustration. - inline RectangleBounds* RectangleBounds::clone() const - { return new RectangleBounds(*this); } - - inline bool RectangleBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const - { return ((fabs(locpo[locX]) < m_boundValues[RectangleBounds::bv_halfX] + tol1) && (fabs(locpo[locY]) < m_boundValues[RectangleBounds::bv_halfY] + tol2) ); } - - inline bool RectangleBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const - { - if(bchk.bcType==0) return RectangleBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - if (!RectangleBounds::inside(locpo, limit, limit)) return false; - // a fast TRUE - double min_ell = bchk.lCovariance(0,0) < bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - limit = bchk.nSigmas*sqrt(min_ell); - if (RectangleBounds::inside(locpo, limit, limit)) return true; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(4); - std::vector<Amg::Vector2D> elementP(4); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p << m_boundValues[RectangleBounds::bv_halfX],m_boundValues[RectangleBounds::bv_halfY]; - elementP[0] = ( rotMatrix * (p - locpo) ); - p << m_boundValues[RectangleBounds::bv_halfX],-m_boundValues[RectangleBounds::bv_halfY]; - elementP[1] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[RectangleBounds::bv_halfX],m_boundValues[RectangleBounds::bv_halfY]; - elementP[2] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[RectangleBounds::bv_halfX],-m_boundValues[RectangleBounds::bv_halfY]; - elementP[3] =( rotMatrix * (p - locpo) ); - std::vector<Amg::Vector2D> axis = {elementP[0]-elementP[1], elementP[0]-elementP[2], elementP[0]-elementP[3], elementP[1]-elementP[2]}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(4); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - - inline bool RectangleBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (fabs(locpo[locX]) < m_boundValues[RectangleBounds::bv_halfX] + tol1); } - - inline bool RectangleBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return (fabs(locpo[locY]) < m_boundValues[RectangleBounds::bv_halfY] + tol2); } - - inline double RectangleBounds::halflengthPhi() const { return this->halflengthX(); } - - inline double RectangleBounds::halflengthEta() const { return this->halflengthY(); } - - inline double RectangleBounds::halflengthX() const { return m_boundValues[RectangleBounds::bv_halfX]; } - - inline double RectangleBounds::halflengthY() const { return m_boundValues[RectangleBounds::bv_halfY]; } - - inline double RectangleBounds::r() const { - return sqrt(m_boundValues[RectangleBounds::bv_halfX]*m_boundValues[RectangleBounds::bv_halfX] - + m_boundValues[RectangleBounds::bv_halfY]*m_boundValues[RectangleBounds::bv_halfY]); - } + @image html RectangularBounds.gif -} // end of namespace + @author Andreas.Salzburger@cern.ch */ +class RectangleBounds : public SurfaceBounds +{ -#endif // TRKSURFACES_RECTANGLEBOUNDS_H +public: + /** @enum BoundValues for readability */ + enum BoundValues + { + bv_halfX = 0, + bv_halfY = 1, + bv_length = 2 + }; + + /**Default Constructor - needed for persistency*/ + RectangleBounds(); + /**Constructor with halflength in x (phi) and halflength in y (eta)*/ + RectangleBounds(double halex, double haley); + /**Copy constructor*/ + RectangleBounds(const RectangleBounds& recbo); + + /**Destructor*/ + virtual ~RectangleBounds(); + + /**Assignment Operator*/ + RectangleBounds& operator=(const RectangleBounds& recbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor*/ + virtual RectangleBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::Rectangle; } + + /**This method checks if the provided local coordinates are inside the surface bounds*/ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + + /**This method checks if the provided local coordinates are inside the surface bounds*/ + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns the halflength in phi (first coordinate of local surface frame)*/ + double halflengthPhi() const; + + /**This method returns the halflength in Eta (second coordinate of local surface frame)*/ + double halflengthEta() const; + + /**for consistant naming*/ + double halflengthX() const; + + /**for consitant naming*/ + double halflengthY() const; + + /**This method returns the maximal extension on the local plane, i.e. @f$s\sqrt{h_{\phi}^2 + h_{\eta}^2}\f$*/ + virtual double r() const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + /** The internal version of the bounds can be float/double*/ + std::vector<TDD_real_t> m_boundValues; +}; + +inline RectangleBounds* +RectangleBounds::clone() const +{ + return new RectangleBounds(*this); +} + +inline bool +RectangleBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + return ((fabs(locpo[locX]) < m_boundValues[RectangleBounds::bv_halfX] + tol1) && + (fabs(locpo[locY]) < m_boundValues[RectangleBounds::bv_halfY] + tol2)); +} + +inline bool +RectangleBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0) + return RectangleBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + if (!RectangleBounds::inside(locpo, limit, limit)) + return false; + // a fast TRUE + double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + limit = bchk.nSigmas * sqrt(min_ell); + if (RectangleBounds::inside(locpo, limit, limit)) + return true; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(4); + std::vector<Amg::Vector2D> elementP(4); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << m_boundValues[RectangleBounds::bv_halfX], m_boundValues[RectangleBounds::bv_halfY]; + elementP[0] = (rotMatrix * (p - locpo)); + p << m_boundValues[RectangleBounds::bv_halfX], -m_boundValues[RectangleBounds::bv_halfY]; + elementP[1] = (rotMatrix * (p - locpo)); + p << -m_boundValues[RectangleBounds::bv_halfX], m_boundValues[RectangleBounds::bv_halfY]; + elementP[2] = (rotMatrix * (p - locpo)); + p << -m_boundValues[RectangleBounds::bv_halfX], -m_boundValues[RectangleBounds::bv_halfY]; + elementP[3] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { + elementP[0] - elementP[1], elementP[0] - elementP[2], elementP[0] - elementP[3], elementP[1] - elementP[2] + }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(4); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +RectangleBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (fabs(locpo[locX]) < m_boundValues[RectangleBounds::bv_halfX] + tol1); +} + +inline bool +RectangleBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return (fabs(locpo[locY]) < m_boundValues[RectangleBounds::bv_halfY] + tol2); +} + +inline double +RectangleBounds::halflengthPhi() const +{ + return this->halflengthX(); +} + +inline double +RectangleBounds::halflengthEta() const +{ + return this->halflengthY(); +} + +inline double +RectangleBounds::halflengthX() const +{ + return m_boundValues[RectangleBounds::bv_halfX]; +} + +inline double +RectangleBounds::halflengthY() const +{ + return m_boundValues[RectangleBounds::bv_halfY]; +} + +inline double +RectangleBounds::r() const +{ + return sqrt(m_boundValues[RectangleBounds::bv_halfX] * m_boundValues[RectangleBounds::bv_halfX] + + m_boundValues[RectangleBounds::bv_halfY] * m_boundValues[RectangleBounds::bv_halfY]); +} + +} // end of namespace + +#endif // TRKSURFACES_RECTANGLEBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedDiamondBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedDiamondBounds.h index 4f90766bff11ab57d15291465f951f438f398625..99f163c3fa8785b66d5deb15c40d99b0a5e9b04b 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedDiamondBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedDiamondBounds.h @@ -9,220 +9,274 @@ #ifndef TRKSURFACES_ROTATEDDIAMONDDBOUNDS_H #define TRKSURFACES_ROTATEDDIAMONDDBOUNDS_H -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" #include <math.h> class MsgStream; class RotatedDiamondBoundsCnv_p1; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class RotatedDiamondBounds - Bounds for a double trapezoidal ("diamond"), planar Surface. - - The RotatedDiamondBounds Class specifies the same diamond as the DiamondBounds Class. The local X and Y coordinates will be interchanged internally for boundary checks. - (This is opposed to the TrapezoidBounds, where X and Y are interchanged in the constructor.) - - @author Andreas.Salzburger@cern.ch, Sarka.Todorova@cern.ch, Peter.Kluit@cern.ch, Alice.Alfonsi@cern.ch, Michiel.Jan.Veen@cern.ch - */ - - class RotatedDiamondBounds : public SurfaceBounds { - - public: - /** BoundValues for better readability */ - enum BoundValues { - bv_minHalfX = 0, - bv_medHalfX = 1, - bv_maxHalfX = 2, - bv_halfY1 = 3, - bv_halfY2 = 4, - bv_length = 5 - }; - - /**Default Constructor, needed for persistency*/ - RotatedDiamondBounds(); - - /**Constructor for symmetric Diamond*/ - RotatedDiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2); - - /**Copy constructor*/ - RotatedDiamondBounds(const RotatedDiamondBounds& diabo); - - /**Destructor*/ - virtual ~RotatedDiamondBounds(); - - /**Virtual constructor*/ - RotatedDiamondBounds* clone() const override; - - /**Assignment operator*/ - RotatedDiamondBounds& operator=(const RotatedDiamondBounds& sbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& diabo) const override; - - /** Return the bounds type */ - virtual BoundsType type() const override { return SurfaceBounds::Diamond; } - - /**This method returns the halflength in X at minimal Y (first coordinate of local surface frame)*/ - double minHalflengthX() const; - - /**This method returns the (maximal) halflength in X (first coordinate of local surface frame)*/ - double medHalflengthX() const; - - /**This method returns the halflength in X at maximal Y (first coordinate of local surface frame)*/ - double maxHalflengthX() const; - - /**This method returns the halflength in Y of trapezoid at negative/positive Y (second coordinate)*/ - double halflengthY1() const; - double halflengthY2() const; - - /**This method returns the maximal extension on the local plane*/ - virtual double r() const override; - - /**This method returns the opening angle alpha in point A */ - double alpha1() const; - - /**This method returns the opening angle alpha in point A' */ - double alpha2() const; - - /** The orientation of the Diamond is according to the figure */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! - */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! - */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - friend class ::RotatedDiamondBoundsCnv_p1; - - /** inside() method for a full symmetric diamond */ - bool insideFull(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const; - - /** initialize the alpha1/2 cache - needed also for object persistency */ - virtual void initCache() override; - - /** Internal parameters stored in the geometry */ - std::vector<TDD_real_t> m_boundValues; - TDD_real_t m_alpha1; - TDD_real_t m_alpha2; - - }; +/** +@class RotatedDiamondBounds +Bounds for a double trapezoidal ("diamond"), planar Surface. + +The RotatedDiamondBounds Class specifies the same diamond as the DiamondBounds Class. The local X and Y coordinates will +be interchanged internally for boundary checks. (This is opposed to the TrapezoidBounds, where X and Y are interchanged +in the constructor.) - inline RotatedDiamondBounds* RotatedDiamondBounds::clone() const { return new RotatedDiamondBounds(*this); } - - inline double RotatedDiamondBounds::minHalflengthX() const { return m_boundValues[RotatedDiamondBounds::bv_minHalfX]; } - - inline double RotatedDiamondBounds::medHalflengthX() const { return m_boundValues[RotatedDiamondBounds::bv_medHalfX]; } - - inline double RotatedDiamondBounds::maxHalflengthX() const { return m_boundValues[RotatedDiamondBounds::bv_maxHalfX]; } - - inline double RotatedDiamondBounds::halflengthY1() const { return m_boundValues[RotatedDiamondBounds::bv_halfY1]; } - - inline double RotatedDiamondBounds::halflengthY2() const { return m_boundValues[RotatedDiamondBounds::bv_halfY2]; } - - inline double RotatedDiamondBounds::r() const - { return sqrt(m_boundValues[RotatedDiamondBounds::bv_medHalfX]*m_boundValues[RotatedDiamondBounds::bv_medHalfX] - + m_boundValues[RotatedDiamondBounds::bv_halfY1]*m_boundValues[RotatedDiamondBounds::bv_halfY1]); } - - inline bool RotatedDiamondBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +@author Andreas.Salzburger@cern.ch, Sarka.Todorova@cern.ch, Peter.Kluit@cern.ch, Alice.Alfonsi@cern.ch, +Michiel.Jan.Veen@cern.ch +*/ + +class RotatedDiamondBounds : public SurfaceBounds +{ + +public: + /** BoundValues for better readability */ + enum BoundValues { - // locX and locY are interchanged wrt DiamondBounds - if(bchk.bcType==0) return RotatedDiamondBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - // a fast FALSE - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) :bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - if ( locpo[Trk::locX] < -2*m_boundValues[RotatedDiamondBounds::bv_halfY1] - limit) return false; - if ( locpo[Trk::locX] > 2*m_boundValues[RotatedDiamondBounds::bv_halfY2] + limit) return false; - // a fast FALSE - double fabsX = fabs(locpo[Trk::locY]); - if (fabsX > (m_boundValues[RotatedDiamondBounds::bv_medHalfX] + limit)) return false; - // a fast TRUE - double min_ell = bchk.lCovariance(0,0) < bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - limit = bchk.nSigmas*sqrt(min_ell); - if (fabsX < (fmin(m_boundValues[RotatedDiamondBounds::bv_minHalfX],m_boundValues[RotatedDiamondBounds::bv_maxHalfX]) - limit)) return true; - // a fast TRUE - if (fabs(locpo[Trk::locX]) < (fmin(m_boundValues[RotatedDiamondBounds::bv_halfY1],m_boundValues[RotatedDiamondBounds::bv_halfY2]) - limit)) return true; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(5); - std::vector<Amg::Vector2D> elementP(6); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - // exchange locX and locY - Amg::Vector2D locpoF; - locpoF[0] = locpo[Trk::locY]; - locpoF[1] = locpo[Trk::locX]; - Amg::Vector2D p; - p << -m_boundValues[RotatedDiamondBounds::bv_minHalfX],-2.*m_boundValues[RotatedDiamondBounds::bv_halfY1]; - elementP[0] =( rotMatrix * (p - locpoF) ); - p << -m_boundValues[RotatedDiamondBounds::bv_medHalfX],0.; - elementP[1] =( rotMatrix * (p - locpoF) ); - p << -m_boundValues[RotatedDiamondBounds::bv_maxHalfX], 2.*m_boundValues[RotatedDiamondBounds::bv_halfY2]; - elementP[2] =( rotMatrix * (p - locpoF) ); - p << m_boundValues[RotatedDiamondBounds::bv_maxHalfX], 2.*m_boundValues[RotatedDiamondBounds::bv_halfY2]; - elementP[3] =( rotMatrix * (p - locpoF) ); - p << m_boundValues[RotatedDiamondBounds::bv_medHalfX], 0.; - elementP[4] =( rotMatrix * (p - locpoF) ); - p << m_boundValues[RotatedDiamondBounds::bv_minHalfX], -2.*m_boundValues[RotatedDiamondBounds::bv_halfY1]; - elementP[5] =( rotMatrix * (p - locpoF) ); - std::vector<Amg::Vector2D> axis = {normal*(elementP[1]-elementP[0]), normal*(elementP[2]-elementP[1]), normal*(elementP[3]-elementP[2]), normal*(elementP[4]-elementP[3]), normal*(elementP[5]-elementP[4])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(5); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - - inline bool RotatedDiamondBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (fabs(locpo[locY]) < m_boundValues[RotatedDiamondBounds::bv_medHalfX] + tol1); } - - inline bool RotatedDiamondBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return ((locpo[locX] > -2.*m_boundValues[RotatedDiamondBounds::bv_halfY1] - tol2) && (locpo[locY] < 2.*m_boundValues[RotatedDiamondBounds::bv_halfY2] + tol2) ); } - - inline void RotatedDiamondBounds::initCache() { - m_alpha1 = atan2(m_boundValues[RotatedDiamondBounds::bv_medHalfX]-m_boundValues[RotatedDiamondBounds::bv_minHalfX], 2.*m_boundValues[RotatedDiamondBounds::bv_halfY1]); - m_alpha2 = atan2(m_boundValues[RotatedDiamondBounds::bv_medHalfX]-m_boundValues[RotatedDiamondBounds::bv_maxHalfX], 2.*m_boundValues[RotatedDiamondBounds::bv_halfY2]); - } - + bv_minHalfX = 0, + bv_medHalfX = 1, + bv_maxHalfX = 2, + bv_halfY1 = 3, + bv_halfY2 = 4, + bv_length = 5 + }; + + /**Default Constructor, needed for persistency*/ + RotatedDiamondBounds(); + + /**Constructor for symmetric Diamond*/ + RotatedDiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2); + + /**Copy constructor*/ + RotatedDiamondBounds(const RotatedDiamondBounds& diabo); + + /**Destructor*/ + virtual ~RotatedDiamondBounds(); + + /**Virtual constructor*/ + RotatedDiamondBounds* clone() const override; + + /**Assignment operator*/ + RotatedDiamondBounds& operator=(const RotatedDiamondBounds& sbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& diabo) const override; + + /** Return the bounds type */ + virtual BoundsType type() const override { return SurfaceBounds::Diamond; } + + /**This method returns the halflength in X at minimal Y (first coordinate of local surface frame)*/ + double minHalflengthX() const; + + /**This method returns the (maximal) halflength in X (first coordinate of local surface frame)*/ + double medHalflengthX() const; + + /**This method returns the halflength in X at maximal Y (first coordinate of local surface frame)*/ + double maxHalflengthX() const; + + /**This method returns the halflength in Y of trapezoid at negative/positive Y (second coordinate)*/ + double halflengthY1() const; + double halflengthY2() const; + + /**This method returns the maximal extension on the local plane*/ + virtual double r() const override; + + /**This method returns the opening angle alpha in point A */ + double alpha1() const; + + /**This method returns the opening angle alpha in point A' */ + double alpha2() const; + + /** The orientation of the Diamond is according to the figure */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! + */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! + */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + friend class ::RotatedDiamondBoundsCnv_p1; + + /** inside() method for a full symmetric diamond */ + bool insideFull(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const; + + /** initialize the alpha1/2 cache - needed also for object persistency */ + virtual void initCache() override; + + /** Internal parameters stored in the geometry */ + std::vector<TDD_real_t> m_boundValues; + TDD_real_t m_alpha1; + TDD_real_t m_alpha2; +}; + +inline RotatedDiamondBounds* +RotatedDiamondBounds::clone() const +{ + return new RotatedDiamondBounds(*this); +} + +inline double +RotatedDiamondBounds::minHalflengthX() const +{ + return m_boundValues[RotatedDiamondBounds::bv_minHalfX]; +} + +inline double +RotatedDiamondBounds::medHalflengthX() const +{ + return m_boundValues[RotatedDiamondBounds::bv_medHalfX]; +} + +inline double +RotatedDiamondBounds::maxHalflengthX() const +{ + return m_boundValues[RotatedDiamondBounds::bv_maxHalfX]; +} + +inline double +RotatedDiamondBounds::halflengthY1() const +{ + return m_boundValues[RotatedDiamondBounds::bv_halfY1]; +} + +inline double +RotatedDiamondBounds::halflengthY2() const +{ + return m_boundValues[RotatedDiamondBounds::bv_halfY2]; +} + +inline double +RotatedDiamondBounds::r() const +{ + return sqrt(m_boundValues[RotatedDiamondBounds::bv_medHalfX] * m_boundValues[RotatedDiamondBounds::bv_medHalfX] + + m_boundValues[RotatedDiamondBounds::bv_halfY1] * m_boundValues[RotatedDiamondBounds::bv_halfY1]); +} + +inline bool +RotatedDiamondBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + // locX and locY are interchanged wrt DiamondBounds + if (bchk.bcType == 0) + return RotatedDiamondBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + // a fast FALSE + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + if (locpo[Trk::locX] < -2 * m_boundValues[RotatedDiamondBounds::bv_halfY1] - limit) + return false; + if (locpo[Trk::locX] > 2 * m_boundValues[RotatedDiamondBounds::bv_halfY2] + limit) + return false; + // a fast FALSE + double fabsX = fabs(locpo[Trk::locY]); + if (fabsX > (m_boundValues[RotatedDiamondBounds::bv_medHalfX] + limit)) + return false; + // a fast TRUE + double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + limit = bchk.nSigmas * sqrt(min_ell); + if (fabsX < + (fmin(m_boundValues[RotatedDiamondBounds::bv_minHalfX], m_boundValues[RotatedDiamondBounds::bv_maxHalfX]) - + limit)) + return true; + // a fast TRUE + if (fabs(locpo[Trk::locX]) < + (fmin(m_boundValues[RotatedDiamondBounds::bv_halfY1], m_boundValues[RotatedDiamondBounds::bv_halfY2]) - limit)) + return true; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(5); + std::vector<Amg::Vector2D> elementP(6); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + // exchange locX and locY + Amg::Vector2D locpoF; + locpoF[0] = locpo[Trk::locY]; + locpoF[1] = locpo[Trk::locX]; + Amg::Vector2D p; + p << -m_boundValues[RotatedDiamondBounds::bv_minHalfX], -2. * m_boundValues[RotatedDiamondBounds::bv_halfY1]; + elementP[0] = (rotMatrix * (p - locpoF)); + p << -m_boundValues[RotatedDiamondBounds::bv_medHalfX], 0.; + elementP[1] = (rotMatrix * (p - locpoF)); + p << -m_boundValues[RotatedDiamondBounds::bv_maxHalfX], 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2]; + elementP[2] = (rotMatrix * (p - locpoF)); + p << m_boundValues[RotatedDiamondBounds::bv_maxHalfX], 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2]; + elementP[3] = (rotMatrix * (p - locpoF)); + p << m_boundValues[RotatedDiamondBounds::bv_medHalfX], 0.; + elementP[4] = (rotMatrix * (p - locpoF)); + p << m_boundValues[RotatedDiamondBounds::bv_minHalfX], -2. * m_boundValues[RotatedDiamondBounds::bv_halfY1]; + elementP[5] = (rotMatrix * (p - locpoF)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]), + normal * (elementP[2] - elementP[1]), + normal * (elementP[3] - elementP[2]), + normal * (elementP[4] - elementP[3]), + normal * (elementP[5] - elementP[4]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(5); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +RotatedDiamondBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (fabs(locpo[locY]) < m_boundValues[RotatedDiamondBounds::bv_medHalfX] + tol1); +} + +inline bool +RotatedDiamondBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return ((locpo[locX] > -2. * m_boundValues[RotatedDiamondBounds::bv_halfY1] - tol2) && + (locpo[locY] < 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2] + tol2)); +} + +inline void +RotatedDiamondBounds::initCache() +{ + m_alpha1 = atan2(m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_minHalfX], + 2. * m_boundValues[RotatedDiamondBounds::bv_halfY1]); + m_alpha2 = atan2(m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_maxHalfX], + 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2]); +} + } // end of namespace #endif // TRKSURFACES_DIAMONDBOUNDS_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedTrapezoidBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedTrapezoidBounds.h index 1d63fa0bc7c21d7957cf2314012a57ef05284628..c6f9986ca7ff7bd8ebfaca23a13c2ac19568a216 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedTrapezoidBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/RotatedTrapezoidBounds.h @@ -9,219 +9,258 @@ #ifndef TRKSURFACES_ROTATEDTRAPEZOIDBOUNDS_H #define TRKSURFACES_ROTATEDTRAPEZOIDBOUNDS_H -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" #include <math.h> -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif - class MsgStream; class RotatedTrapezoidBoundsCnv_p1; namespace Trk { - /** - @class RotatedTrapezoidBounds - - Bounds for a rotated trapezoidal, planar Surface. - Contrary to the TrapezoidBounds the local x axis builds the - symmetry axis for a symmetric Trapezoid. - - An arbitrary rotated trapezoidal shape has not been implemented yet, - the TrapezoidBounds may be taken instead. - - @image html RotatedTrapezoidBounds.gif - - @author Andreas.Salzburger@cern.ch - */ - - class RotatedTrapezoidBounds : public SurfaceBounds { - - public: - /** @enum BoundValues for readibility */ - enum BoundValues { - bv_halfX = 0, - bv_minHalfY = 1, - bv_maxHalfY = 2, - bv_length = 3 - }; - - /**Default Constructor, needed for persistency*/ - RotatedTrapezoidBounds(); - - /**Constructor for symmetric Trapezoid*/ - RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex); - - /**Copy constructor*/ - RotatedTrapezoidBounds(const RotatedTrapezoidBounds& trabo); - - /**Destructor*/ - virtual ~RotatedTrapezoidBounds(); - - /**Virtual constructor*/ - virtual RotatedTrapezoidBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::RotatedTrapezoid; } - - /**Assignment operator*/ - RotatedTrapezoidBounds& operator=(const RotatedTrapezoidBounds& sbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& trabo) const override; - - /**This method returns the minimal halflength in X (first coordinate of local surface frame)*/ - double halflengthX() const; - - /**This method returns the maximal halflength in X (first coordinate of local surface frame)*/ - double minHalflengthY() const; - - /**This method returns the halflength in Y (second coordinate of local surface frame)*/ - double maxHalflengthY() const; - - /**This method returns the maximal extension on the local plane*/ - virtual double r() const override; - - /** The orientation of the Trapezoid is according to the figure above, - in words: the shorter of the two parallel sides of the trapezoid intersects - with the negative @f$ y @f$ - axis of the local frame. - - <br> - The cases are:<br> - (0) @f$ \eta @f$ or @f$ \phi @f$ bounds are 0 || 0<br> - (1) LocalPosition is outside @f$ x @f$ bounds <br> - (2) LocalPosition is inside @f$ x @f$ bounds, but outside maximum @f$ y @f$ bounds <br> - (3) LocalPosition is inside @f$ x @f$ bounds AND inside minimum @f$ y @f$ bounds <br> - (4) LocalPosition is inside @f$ x @f$ bounds AND inside maximum @f$ y @f$ bounds, so that - it depends on the @f$ x @f$ coordinate - (5) LocalPosition fails test of (4) <br> - - The inside check is done using single equations of straight lines and one has to take care if a point - lies on the positive @f$ \phi @f$ half area(I) or the negative one(II). Denoting @f$ | y_{min}| @f$ and - @f$ | y_{max} | @f$ as \c minHalfY respectively \c maxHalfX, such as @f$ | x_{H} | @f$ as \c halfX, - the equations for the straing lines in (I) and (II) can be written as:<br> - <br> - - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> - - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> - <br> - where <br> - @f$ \kappa_{I} = - \kappa_{II} = \frac{y_{max}-y_{min}}{x_{H}} @f$ <br> - @f$ \delta_{I} = \frac{1}{2}\cdot (y_{max} + y_{min} ) @f$ <br>*/ - virtual bool inside(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle !*/ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle !*/ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - friend class ::RotatedTrapezoidBoundsCnv_p1; - - /** isBelow() method for checking whether a point lies above or under a straight line */ - bool isBelow(double locX, double fabsLocY, double tol1, double tol2) const; - - /** Helper function for angle parameter initialization */ - virtual void initCache() override; - - /** The internal storage of the bounds can be float/double*/ - std::vector<TDD_real_t> m_boundValues; - TDD_real_t m_kappa; - TDD_real_t m_delta; - - }; +/** + @class RotatedTrapezoidBounds - inline RotatedTrapezoidBounds* RotatedTrapezoidBounds::clone() const { return new RotatedTrapezoidBounds(*this); } - - inline void RotatedTrapezoidBounds::initCache(){ - m_kappa = 0.5*(m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]-m_boundValues[RotatedTrapezoidBounds::bv_minHalfY])/m_boundValues[RotatedTrapezoidBounds::bv_halfX]; - m_delta = 0.5*(m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]+m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); - } - - inline double RotatedTrapezoidBounds::halflengthX() const { return m_boundValues[RotatedTrapezoidBounds::bv_halfX]; } - - inline double RotatedTrapezoidBounds::minHalflengthY() const { return m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; } - - inline double RotatedTrapezoidBounds::maxHalflengthY() const { return m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; } - - inline double RotatedTrapezoidBounds::r() const { return sqrt(m_boundValues[RotatedTrapezoidBounds::bv_halfX]*m_boundValues[RotatedTrapezoidBounds::bv_halfX] + m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]*m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); } - - inline bool RotatedTrapezoidBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const + Bounds for a rotated trapezoidal, planar Surface. + Contrary to the TrapezoidBounds the local x axis builds the + symmetry axis for a symmetric Trapezoid. + + An arbitrary rotated trapezoidal shape has not been implemented yet, + the TrapezoidBounds may be taken instead. + + @image html RotatedTrapezoidBounds.gif + + @author Andreas.Salzburger@cern.ch + */ + +class RotatedTrapezoidBounds : public SurfaceBounds +{ + +public: + /** @enum BoundValues for readibility */ + enum BoundValues { - if(bchk.bcType==0) return RotatedTrapezoidBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - double fabsX = fabs(locpo[Trk::locX]); - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) :bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - if (fabsX > ( m_boundValues[RotatedTrapezoidBounds::bv_halfX] + limit)) return false; - // a fast FALSE - double fabsY = fabs(locpo[Trk::locY]); - if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + limit)) return false; - // a fast TRUE - double min_ell = bchk.lCovariance(0,0) < bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - limit = bchk.nSigmas*sqrt(min_ell); - if (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] + limit) && fabsX < (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + limit)) return true; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(3); - std::vector<Amg::Vector2D> elementP(4); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p << -m_boundValues[RotatedTrapezoidBounds::bv_halfX], m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; - elementP[0] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[RotatedTrapezoidBounds::bv_halfX], -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; - elementP[1] =( rotMatrix * (p - locpo) ); - p << m_boundValues[RotatedTrapezoidBounds::bv_halfX], m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; - elementP[2] =( rotMatrix * (p - locpo) ); - p << m_boundValues[RotatedTrapezoidBounds::bv_halfX], -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; - elementP[3] =( rotMatrix * (p - locpo) ); - std::vector<Amg::Vector2D> axis = {normal*(elementP[1]-elementP[0]), normal*(elementP[3]-elementP[1]), normal*(elementP[2]-elementP[0])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(3); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - - inline bool RotatedTrapezoidBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (fabs(locpo[locX]) < m_boundValues[RotatedTrapezoidBounds::bv_halfX] + tol1); } - - inline bool RotatedTrapezoidBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return (fabs(locpo[locY]) < m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + tol2); } + bv_halfX = 0, + bv_minHalfY = 1, + bv_maxHalfY = 2, + bv_length = 3 + }; + + /**Default Constructor, needed for persistency*/ + RotatedTrapezoidBounds(); + + /**Constructor for symmetric Trapezoid*/ + RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex); + + /**Copy constructor*/ + RotatedTrapezoidBounds(const RotatedTrapezoidBounds& trabo); + + /**Destructor*/ + virtual ~RotatedTrapezoidBounds(); + + /**Virtual constructor*/ + virtual RotatedTrapezoidBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::RotatedTrapezoid; } + + /**Assignment operator*/ + RotatedTrapezoidBounds& operator=(const RotatedTrapezoidBounds& sbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& trabo) const override; + + /**This method returns the minimal halflength in X (first coordinate of local surface frame)*/ + double halflengthX() const; + + /**This method returns the maximal halflength in X (first coordinate of local surface frame)*/ + double minHalflengthY() const; + + /**This method returns the halflength in Y (second coordinate of local surface frame)*/ + double maxHalflengthY() const; + + /**This method returns the maximal extension on the local plane*/ + virtual double r() const override; + + /** The orientation of the Trapezoid is according to the figure above, + in words: the shorter of the two parallel sides of the trapezoid intersects + with the negative @f$ y @f$ - axis of the local frame. + + <br> + The cases are:<br> + (0) @f$ \eta @f$ or @f$ \phi @f$ bounds are 0 || 0<br> + (1) LocalPosition is outside @f$ x @f$ bounds <br> + (2) LocalPosition is inside @f$ x @f$ bounds, but outside maximum @f$ y @f$ bounds <br> + (3) LocalPosition is inside @f$ x @f$ bounds AND inside minimum @f$ y @f$ bounds <br> + (4) LocalPosition is inside @f$ x @f$ bounds AND inside maximum @f$ y @f$ bounds, so that + it depends on the @f$ x @f$ coordinate + (5) LocalPosition fails test of (4) <br> + + The inside check is done using single equations of straight lines and one has to take care if a point + lies on the positive @f$ \phi @f$ half area(I) or the negative one(II). Denoting @f$ | y_{min}| @f$ and + @f$ | y_{max} | @f$ as \c minHalfY respectively \c maxHalfX, such as @f$ | x_{H} | @f$ as \c halfX, + the equations for the straing lines in (I) and (II) can be written as:<br> + <br> + - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> + - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> + <br> + where <br> + @f$ \kappa_{I} = - \kappa_{II} = \frac{y_{max}-y_{min}}{x_{H}} @f$ <br> + @f$ \delta_{I} = \frac{1}{2}\cdot (y_{max} + y_{min} ) @f$ <br>*/ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle !*/ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle !*/ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + friend class ::RotatedTrapezoidBoundsCnv_p1; + + /** isBelow() method for checking whether a point lies above or under a straight line */ + bool isBelow(double locX, double fabsLocY, double tol1, double tol2) const; + + /** Helper function for angle parameter initialization */ + virtual void initCache() override; + + /** The internal storage of the bounds can be float/double*/ + std::vector<TDD_real_t> m_boundValues; + TDD_real_t m_kappa; + TDD_real_t m_delta; +}; + +inline RotatedTrapezoidBounds* +RotatedTrapezoidBounds::clone() const +{ + return new RotatedTrapezoidBounds(*this); +} + +inline void +RotatedTrapezoidBounds::initCache() +{ + m_kappa = 0.5 * + (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] - m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]) / + m_boundValues[RotatedTrapezoidBounds::bv_halfX]; + m_delta = + 0.5 * (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] + m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); +} + +inline double +RotatedTrapezoidBounds::halflengthX() const +{ + return m_boundValues[RotatedTrapezoidBounds::bv_halfX]; +} + +inline double +RotatedTrapezoidBounds::minHalflengthY() const +{ + return m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; +} + +inline double +RotatedTrapezoidBounds::maxHalflengthY() const +{ + return m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; +} + +inline double +RotatedTrapezoidBounds::r() const +{ + return sqrt(m_boundValues[RotatedTrapezoidBounds::bv_halfX] * m_boundValues[RotatedTrapezoidBounds::bv_halfX] + + m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] * m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); +} + +inline bool +RotatedTrapezoidBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0) + return RotatedTrapezoidBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + double fabsX = fabs(locpo[Trk::locX]); + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + if (fabsX > (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + limit)) + return false; + // a fast FALSE + double fabsY = fabs(locpo[Trk::locY]); + if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + limit)) + return false; + // a fast TRUE + double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + limit = bchk.nSigmas * sqrt(min_ell); + if (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] + limit) && + fabsX < (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + limit)) + return true; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(3); + std::vector<Amg::Vector2D> elementP(4); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << -m_boundValues[RotatedTrapezoidBounds::bv_halfX], m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; + elementP[0] = (rotMatrix * (p - locpo)); + p << -m_boundValues[RotatedTrapezoidBounds::bv_halfX], -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY]; + elementP[1] = (rotMatrix * (p - locpo)); + p << m_boundValues[RotatedTrapezoidBounds::bv_halfX], m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; + elementP[2] = (rotMatrix * (p - locpo)); + p << m_boundValues[RotatedTrapezoidBounds::bv_halfX], -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]; + elementP[3] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]), + normal * (elementP[3] - elementP[1]), + normal * (elementP[2] - elementP[0]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(3); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +RotatedTrapezoidBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (fabs(locpo[locX]) < m_boundValues[RotatedTrapezoidBounds::bv_halfX] + tol1); +} + +inline bool +RotatedTrapezoidBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return (fabs(locpo[locY]) < m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + tol2); +} } // end of namespace #endif // TRKSURFACES_TRAPEZOIDBOUNDS_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/StraightLineSurface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/StraightLineSurface.h index b9b1547397de24f88b1303fef06bb70d93213741..8e7f67123c36ac014f3a93388d11478554356e23 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/StraightLineSurface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/StraightLineSurface.h @@ -9,256 +9,291 @@ #ifndef TRKSURFACES_STRAIGHTLINESURFACE_H #define TRKSURFACES_STRAIGHTLINESURFACE_H -//Trk -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/CylinderBounds.h" -#include "TrkSurfaces/NoBounds.h" +// Trk #include "TrkDetDescrUtils/SharedObject.h" #include "TrkParametersBase/ParametersT.h" +#include "TrkSurfaces/CylinderBounds.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/Surface.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" class Identifier; class MsgStream; -template< class SURFACE, class BOUNDS_CNV > class BoundSurfaceCnv_p1; +template<class SURFACE, class BOUNDS_CNV> +class BoundSurfaceCnv_p1; namespace Trk { - class TrkDetElementBase; - class LocalParameters; - template<int DIM, class T, class S> class ParametersT; - - /** - @class StraightLineSurface - - Class for a StraightLineSurface in the ATLAS detector - to describe dirft tube and straw like detectors. - It inherits from Surface. - - @author Andreas.Salzburger@cern.ch - */ +class TrkDetElementBase; +class LocalParameters; +template<int DIM, class T, class S> +class ParametersT; + +/** + @class StraightLineSurface + + Class for a StraightLineSurface in the ATLAS detector + to describe dirft tube and straw like detectors. + It inherits from Surface. + + @author Andreas.Salzburger@cern.ch + */ + +class StraightLineSurface : public Surface +{ + +public: + /**Default Constructor - needed for persistency*/ + StraightLineSurface(); + + /**Constructor from HepTransform (boundless surface)*/ + StraightLineSurface(Amg::Transform3D* htrans); + + /**Constructor from HepTransform by unique_ptr (boundless surface)*/ + StraightLineSurface(std::unique_ptr<Amg::Transform3D> htrans); + + /**Constructor from HepTransform and bounds*/ + StraightLineSurface(Amg::Transform3D* htrans, double radius, double halez); + + /**Constructor from TrkDetElementBase and Element identifier*/ + StraightLineSurface(const TrkDetElementBase& detelement, const Identifier& id); + + /**Copy constructor*/ + StraightLineSurface(const StraightLineSurface& slsf); + + /**Copy constructor with shift*/ + StraightLineSurface(const StraightLineSurface& slsf, const Amg::Transform3D& transf); + + /**Destructor*/ + virtual ~StraightLineSurface(); + + /**Assignment operator*/ + StraightLineSurface& operator=(const StraightLineSurface& slsf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const override; + + /**Implicit constructor*/ + virtual StraightLineSurface* clone() const override; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersT<5, Charged, StraightLineSurface>* createTrackParameters( + double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Charged, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersT<5, Charged, StraightLineSurface>* createTrackParameters( + const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Charged, StraightLineSurface>(position, momentum, charge, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersT<5, Neutral, StraightLineSurface>* createNeutralParameters( + double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); + } + + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersT<5, Neutral, StraightLineSurface>* createNeutralParameters( + const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(5) * cov = 0) const override + { + return new ParametersT<5, Neutral, StraightLineSurface>(position, momentum, charge, *this, cov); + } - class StraightLineSurface : public Surface { - - public: - /**Default Constructor - needed for persistency*/ - StraightLineSurface(); - - /**Constructor from HepTransform (boundless surface)*/ - StraightLineSurface(Amg::Transform3D* htrans); - - /**Constructor from HepTransform by unique_ptr (boundless surface)*/ - StraightLineSurface(std::unique_ptr<Amg::Transform3D> htrans); - - /**Constructor from HepTransform and bounds*/ - StraightLineSurface(Amg::Transform3D* htrans, double radius, double halez); - - /**Constructor from TrkDetElementBase and Element identifier*/ - StraightLineSurface(const TrkDetElementBase& detelement, const Identifier& id); - - /**Copy constructor*/ - StraightLineSurface(const StraightLineSurface& slsf); - - /**Copy constructor with shift*/ - StraightLineSurface(const StraightLineSurface& slsf, const Amg::Transform3D& transf); - - /**Destructor*/ - virtual ~StraightLineSurface(); - - /**Assignment operator*/ - StraightLineSurface& operator=(const StraightLineSurface& slsf ); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const override; - - /**Implicit constructor*/ - virtual StraightLineSurface* clone() const override; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersT<5, Charged, StraightLineSurface>* createTrackParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); } - - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersT<5, Charged, StraightLineSurface>* createTrackParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Charged, StraightLineSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersT<5, Neutral, StraightLineSurface>* createNeutralParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersT<5, Neutral, StraightLineSurface>* createNeutralParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(5)* cov = 0) const override - { return new ParametersT<5, Neutral, StraightLineSurface>(position, momentum, charge, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from local parameters */ - template <int DIM, class T> const ParametersT<DIM, T, StraightLineSurface>* createParameters(double l1, - double l2, - double phi, - double theta, - double qop, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); } - - /** Use the Surface as a ParametersBase constructor, from global parameters */ - template <int DIM, class T> const ParametersT<DIM, T, StraightLineSurface>* createParameters(const Amg::Vector3D& position, - const Amg::Vector3D& momentum, - double charge, - AmgSymMatrix(DIM)* cov = 0) const - { return new ParametersT<DIM, T, StraightLineSurface>(position, momentum, charge, *this, cov); } - - /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface - - the default implementation is the the RotationMatrix3D of the transform */ - virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const override; - - /** Return the surface type */ - virtual SurfaceType type() const override { return Surface::Line; } - - /** Specified for StraightLineSurface: LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; - - /** Specified for StraightLineSurface: GlobalToLocal method without dynamic memory allocation - This method is the true global->local transformation.<br> - makes use of globalToLocal and indicates the sign of the locR by the given momentum - - The calculation of the sign of the radius (or \f$ d_0 \f$) can be done as follows:<br> - May \f$ \vec d = \vec m - \vec c \f$ denote the difference between the center of the line and - the global position of the measurement/predicted state, then \f$ \vec d \f$ lies within the so - called measurement plane. - The measurement plane is determined by the two orthogonal vectors \f$ \vec{measY}= \vec{locZ} \f$ - and \f$ \vec{measX} = \vec{measY} \times \frac{\vec{p}}{|\vec{p}|} \f$.<br> - - The sign of the radius (\f$ d_{0} \f$ ) is then defined by the projection of \f$ \vec{d} \f$ - onto \f$ \vec{measX} \f$:<br> - \f$ sign = -sign(\vec{d} \cdot \vec{measX}) \f$ - - \image html SignOfDriftCircleD0.gif - */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; - - /** Special method for StraightLineSurface - providing a different z estimate */ - virtual const Amg::Vector3D* localToGlobal(const Trk::LocalParameters& locpars, - const Amg::Vector3D& glomom, - double locZ) const; - - - /** Special method for StraightLineSurface - provides the Line direction from cache: speedup */ - const Amg::Vector3D& lineDirection() const; - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceDir is to provide the closest forward solution - - b>mathematical motivation:</b> - Given two lines in parameteric form:<br> - - @f$ \vec l_{a}(\lambda) = \vec m_a + \lambda \cdot \vec e_{a} @f$ <br> - - @f$ \vec l_{b}(\mu) = \vec m_b + \mu \cdot \vec e_{b} @f$ <br> - the vector between any two points on the two lines is given by: - - @f$ \vec s(\lambda, \mu) = \vec l_{b} - l_{a} = \vec m_{ab} + \mu \cdot \vec e_{b} - \lambda \cdot \vec e_{a} @f$, <br> - when @f$ \vec m_{ab} = \vec m_{b} - \vec m_{a} @f$.<br> - @f$ \vec s(\lambda_0, \mu_0) @f$ denotes the vector between the two closest points <br> - @f$ \vec l_{a,0} = l_{a}(\lambda_0) @f$ and @f$ \vec l_{b,0} = l_{b}(\mu_0) @f$ <br> - and is perpenticular to both, @f$ \vec e_{a} @f$ and @f$ \vec e_{b} @f$. - - This results in a system of two linear equations:<br> - - (i) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_a = \vec m_ab \cdot \vec e_a + \mu_0 \vec e_a \cdot \vec e_b - \lambda_0 @f$ <br> - - (ii) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_b = \vec m_ab \cdot \vec e_b + \mu_0 - \lambda_0 \vec e_b \cdot \vec e_a @f$ <br> - - Solving (i), (ii) for @f$ \lambda_0 @f$ and @f$ \mu_0 @f$ yields: - - @f$ \lambda_0 = \frac{(\vec m_ab \cdot \vec e_a)-(\vec m_ab \cdot \vec e_b)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br> - - @f$ \mu_0 = - \frac{(\vec m_ab \cdot \vec e_b)-(\vec m_ab \cdot \vec e_a)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a \cdot \vec e_b)^2} @f$ <br> - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const override; - - /** fast straight line distance evaluation to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const override; - - /** fast straight line distance evaluation to Surface - with bound option*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const override; - - - /** the pathCorrection for derived classes with thickness */ - virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override { return 1.; } - - /** This method checks if the provided GlobalPosition is inside the assigned straw radius, but - no check is done whether the GlobalPosition is inside bounds or not. - It overwrites isOnSurface from Base Class as it saves the time of sign determination. */ - virtual bool isOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk=true, - double tol1=0., - double tol2=0.) const override; - - /**This method returns the bounds of the Surface by reference */ - virtual const SurfaceBounds& bounds() const override; - - /**This surface calls the iside method of the bouns */ - virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1=0., double tol2=0.) const override; - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; - - /** Return properly formatted class name for screen output */ - virtual std::string name() const override { return "Trk::StraightLineSurface"; }; - - protected: //!< data members - template< class SURFACE, class BOUNDS_CNV > friend class ::BoundSurfaceCnv_p1; - - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_lineDirection; //!< cache of the line direction (speeds up) - SharedObject<const CylinderBounds> m_bounds; //!< bounds (shared) - static const NoBounds s_boundless; //!< NoBounds as return object when no bounds are declared - - }; - - inline StraightLineSurface* StraightLineSurface::clone() const - { return new StraightLineSurface(*this); } - - inline const SurfaceBounds& StraightLineSurface::bounds() const + /** Use the Surface as a ParametersBase constructor, from local parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, StraightLineSurface>* createParameters(double l1, + double l2, + double phi, + double theta, + double qop, + AmgSymMatrix(DIM) * cov = 0) const { - if (m_bounds.get()) return *(m_bounds.get()); - if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()){ - return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); - } - if (Surface::m_associatedDetElement) return m_associatedDetElement->bounds(); - return s_boundless; + return new ParametersT<DIM, T, StraightLineSurface>(l1, l2, phi, theta, qop, *this, cov); } - inline bool StraightLineSurface::insideBounds(const Amg::Vector2D& locpos, - double tol1, - double tol2) const - { - if (!(m_bounds.get()) && !Surface::m_associatedDetElement) return true; - return (fabs(locpos[locR]) < bounds().r() + tol1 - && bounds().insideLoc2(locpos, tol2)); + /** Use the Surface as a ParametersBase constructor, from global parameters */ + template<int DIM, class T> + const ParametersT<DIM, T, StraightLineSurface>* createParameters(const Amg::Vector3D& position, + const Amg::Vector3D& momentum, + double charge, + AmgSymMatrix(DIM) * cov = 0) const + { + return new ParametersT<DIM, T, StraightLineSurface>(position, momentum, charge, *this, cov); } - - inline bool StraightLineSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const - { return StraightLineSurface::insideBounds(locpos,bchk.toleranceLoc1,bchk.toleranceLoc2); } - - inline const Amg::Vector3D& StraightLineSurface::lineDirection() const { - if (!m_lineDirection) { - m_lineDirection.set(std::make_unique<Amg::Vector3D>(transform().rotation().col(2))); - } - return (*m_lineDirection); + + /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface + - the default implementation is the the RotationMatrix3D of the transform */ + virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom) const override; + + /** Return the surface type */ + virtual SurfaceType type() const override { return Surface::Line; } + + /** Specified for StraightLineSurface: LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const override; + + /** Specified for StraightLineSurface: GlobalToLocal method without dynamic memory allocation + This method is the true global->local transformation.<br> + makes use of globalToLocal and indicates the sign of the locR by the given momentum + + The calculation of the sign of the radius (or \f$ d_0 \f$) can be done as follows:<br> + May \f$ \vec d = \vec m - \vec c \f$ denote the difference between the center of the line and + the global position of the measurement/predicted state, then \f$ \vec d \f$ lies within the so + called measurement plane. + The measurement plane is determined by the two orthogonal vectors \f$ \vec{measY}= \vec{locZ} \f$ + and \f$ \vec{measX} = \vec{measY} \times \frac{\vec{p}}{|\vec{p}|} \f$.<br> + + The sign of the radius (\f$ d_{0} \f$ ) is then defined by the projection of \f$ \vec{d} \f$ + onto \f$ \vec{measX} \f$:<br> + \f$ sign = -sign(\vec{d} \cdot \vec{measX}) \f$ + + \image html SignOfDriftCircleD0.gif + */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const override; + + /** Special method for StraightLineSurface - providing a different z estimate */ + virtual const Amg::Vector3D* localToGlobal(const Trk::LocalParameters& locpars, + const Amg::Vector3D& glomom, + double locZ) const; + + /** Special method for StraightLineSurface - provides the Line direction from cache: speedup */ + const Amg::Vector3D& lineDirection() const; + + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceDir is to provide the closest forward solution + + b>mathematical motivation:</b> + Given two lines in parameteric form:<br> + - @f$ \vec l_{a}(\lambda) = \vec m_a + \lambda \cdot \vec e_{a} @f$ <br> + - @f$ \vec l_{b}(\mu) = \vec m_b + \mu \cdot \vec e_{b} @f$ <br> + the vector between any two points on the two lines is given by: + - @f$ \vec s(\lambda, \mu) = \vec l_{b} - l_{a} = \vec m_{ab} + \mu \cdot \vec e_{b} - \lambda \cdot \vec e_{a} + @f$, <br> when @f$ \vec m_{ab} = \vec m_{b} - \vec m_{a} @f$.<br> + @f$ \vec s(\lambda_0, \mu_0) @f$ denotes the vector between the two closest points <br> + @f$ \vec l_{a,0} = l_{a}(\lambda_0) @f$ and @f$ \vec l_{b,0} = l_{b}(\mu_0) @f$ <br> + and is perpenticular to both, @f$ \vec e_{a} @f$ and @f$ \vec e_{b} @f$. + + This results in a system of two linear equations:<br> + - (i) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_a = \vec m_ab \cdot \vec e_a + \mu_0 \vec e_a \cdot \vec e_b - + \lambda_0 @f$ <br> + - (ii) @f$ 0 = \vec s(\lambda_0, \mu_0) \cdot \vec e_b = \vec m_ab \cdot \vec e_b + \mu_0 - \lambda_0 \vec e_b + \cdot \vec e_a @f$ <br> + + Solving (i), (ii) for @f$ \lambda_0 @f$ and @f$ \mu_0 @f$ yields: + - @f$ \lambda_0 = \frac{(\vec m_ab \cdot \vec e_a)-(\vec m_ab \cdot \vec e_b)(\vec e_a \cdot \vec e_b)}{1-(\vec + e_a \cdot \vec e_b)^2} @f$ <br> + - @f$ \mu_0 = - \frac{(\vec m_ab \cdot \vec e_b)-(\vec m_ab \cdot \vec e_a)(\vec e_a \cdot \vec e_b)}{1-(\vec e_a + \cdot \vec e_b)^2} @f$ <br> + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const override; + + /** fast straight line distance evaluation to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir) const override; + + /** fast straight line distance evaluation to Surface - with bound option*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool Bound) const override; + + /** the pathCorrection for derived classes with thickness */ + virtual double pathCorrection(const Amg::Vector3D&, const Amg::Vector3D&) const override { return 1.; } + + /** This method checks if the provided GlobalPosition is inside the assigned straw radius, but + no check is done whether the GlobalPosition is inside bounds or not. + It overwrites isOnSurface from Base Class as it saves the time of sign determination. */ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const override; + + /**This method returns the bounds of the Surface by reference */ + virtual const SurfaceBounds& bounds() const override; + + /**This surface calls the iside method of the bouns */ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const override; + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const override; + + /** Return properly formatted class name for screen output */ + virtual std::string name() const override { return "Trk::StraightLineSurface"; }; + +protected: //!< data members + template<class SURFACE, class BOUNDS_CNV> + friend class ::BoundSurfaceCnv_p1; + + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_lineDirection; //!< cache of the line direction (speeds up) + SharedObject<const CylinderBounds> m_bounds; //!< bounds (shared) + static const NoBounds s_boundless; //!< NoBounds as return object when no bounds are declared +}; + +inline StraightLineSurface* +StraightLineSurface::clone() const +{ + return new StraightLineSurface(*this); +} + +inline const SurfaceBounds& +StraightLineSurface::bounds() const +{ + if (m_bounds.get()) + return *(m_bounds.get()); + if (Surface::m_associatedDetElement && Surface::m_associatedDetElementId.is_valid()) { + return m_associatedDetElement->bounds(Surface::m_associatedDetElementId); + } + if (Surface::m_associatedDetElement) + return m_associatedDetElement->bounds(); + return s_boundless; +} + +inline bool +StraightLineSurface::insideBounds(const Amg::Vector2D& locpos, double tol1, double tol2) const +{ + if (!(m_bounds.get()) && !Surface::m_associatedDetElement) + return true; + return (fabs(locpos[locR]) < bounds().r() + tol1 && bounds().insideLoc2(locpos, tol2)); +} + +inline bool +StraightLineSurface::insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const +{ + return StraightLineSurface::insideBounds(locpos, bchk.toleranceLoc1, bchk.toleranceLoc2); +} + +inline const Amg::Vector3D& +StraightLineSurface::lineDirection() const +{ + if (!m_lineDirection) { + m_lineDirection.set(std::make_unique<Amg::Vector3D>(transform().rotation().col(2))); } - + return (*m_lineDirection); +} + } // end of namespace #endif // TRKSURFACES_STRAIGHTLINESURFACE_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h index ff4d952aac9b685db4e39de4abfdf8496332d3a9..42f76b5a5f130b3e77dd7518fc92bf7ab101a2d7 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h @@ -9,530 +9,603 @@ #ifndef TRKSURFACES_SURFACE_H #define TRKSURFACES_SURFACE_H -//Trk -#include "TrkEventPrimitives/ParamDefs.h" -#include "TrkEventPrimitives/LocalParameters.h" -#include "TrkSurfaces/BoundaryCheck.h" -#include "TrkSurfaces/DistanceSolution.h" -#include "TrkDetElementBase/TrkDetElementBase.h" +// Trk #include "TrkDetDescrUtils/GeometryStatics.h" #include "TrkDetDescrUtils/Intersection.h" +#include "TrkDetElementBase/TrkDetElementBase.h" +#include "TrkEventPrimitives/LocalParameters.h" +#include "TrkEventPrimitives/ParamDefs.h" #include "TrkEventPrimitives/PropDirection.h" -#include "TrkParametersBase/ParametersBase.h" #include "TrkParametersBase/Charged.h" #include "TrkParametersBase/Neutral.h" +#include "TrkParametersBase/ParametersBase.h" #include "TrkParametersBase/SurfaceUniquePtrT.h" +#include "TrkSurfaces/BoundaryCheck.h" +#include "TrkSurfaces/DistanceSolution.h" // Amg -#include "EventPrimitives/EventPrimitives.h" +#include "EventPrimitives/EventPrimitives.h" #include "GeoPrimitives/GeoPrimitives.h" // Identifier #include "Identifier/Identifier.h" -#include <atomic> #include "CxxUtils/CachedUniquePtr.h" #include "CxxUtils/checker_macros.h" +#include <atomic> class MsgStream; class SurfaceCnv_p1; namespace Trk { - class TrkDetElementBase; - class SurfaceBounds; - class Layer; +class TrkDetElementBase; +class SurfaceBounds; +class Layer; - enum SurfaceOwner{ - noOwn = 0, - TGOwn = 1, - DetElOwn = 2 - }; +enum SurfaceOwner +{ + noOwn = 0, + TGOwn = 1, + DetElOwn = 2 +}; +/** + @class Surface - /** - @class Surface - - Abstract Base Class for tracking surfaces - - The creation of a Surface by passing a HepGeom::Transform3D* through the constructor - implies that the ownership of the HepGeom::Transform3D object is also passed to the Surface, - therfor the memory is freed in the Surface destructor. - - For all isOnSurface, or positionOnSurface and insideBounds methods two tolerance parameters - can be given which correspond to the two local natural coordinates of the surface loc1, loc2. + Abstract Base Class for tracking surfaces - @author Andreas.Salzburger@cern.ch - */ - - class Surface { - - /** Declare the ILayerBuilder / ITrackingVolumeHelper to be a friend class such it is able to set the layer */ - friend class ILayerBuilder; - friend class ITrackingVolumeHelper; - - public: - - /** @enum SurfaceType - - This enumerator simplifies the persistency & calculations, - by saving a dynamic_cast to happen. - - Other is reserved for the GeometrySurfaces implementation. - - */ - enum SurfaceType { - Cone = 0, - Cylinder = 1, - Disc = 2, - Perigee = 3, - Plane = 4, - Line = 5, - Curvilinear = 6, - Other = 7 - }; - - /**Default Constructor - - needed for inherited classes */ - Surface(); - - /**Copy constructor - it resets the associated - detector element to 0 and the identifier to invalid, - as the copy cannot be owned by the same detector element as the original */ - Surface(const Surface& sf); - - /**Copy constructor with shift */ - Surface(const Surface& sf, const Amg::Transform3D& transf); - - /**Constructor with HepGeom::Transform3D, passing ownership */ - Surface(Amg::Transform3D* htrans); - - /**Constructor with HepGeom::Transform3D, by unique_ptr */ - Surface(std::unique_ptr<Amg::Transform3D> htrans); - - /**Constructor from TrkDetElement*/ - Surface(const TrkDetElementBase& detelement); - - /**Constructor form TrkDetElement and Identifier*/ - Surface(const TrkDetElementBase& detelement, const Identifier& id); - - /**Virtual Destructor*/ - virtual ~Surface(); - - /**Assignment operator- it sets the associated - detector element to 0 and the associated identifier to invalid, - as the copy cannot be owned by the same detector element as the original */ - Surface& operator=(const Surface& sf); - - /**Equality operator*/ - virtual bool operator==(const Surface& sf) const = 0; - - /**Non-equality operator*/ - virtual bool operator!=(const Surface& sf) const; - - /**Implicit constructor - uses the copy constructor */ - virtual Surface* clone() const = 0; - - /** Returns the Surface type to avoid dynamic casts */ - virtual SurfaceType type() const = 0; - - /** Return the cached transformation directly. Don't try to make - a new transform if it's not here. */ - const Amg::Transform3D* cachedTransform() const; - - /** Returns HepGeom::Transform3D by reference */ - virtual const Amg::Transform3D& transform() const; - - /** Returns the center position of the Surface */ - virtual const Amg::Vector3D& center() const; - - /** Returns the normal vector of the Surface (i.e. in generall z-axis of rotation) */ - virtual const Amg::Vector3D& normal() const; - - /** Returns a normal vector at a specific local position */ - virtual const Amg::Vector3D* normal(const Amg::Vector2D& lp) const; - - /** Returns a global reference point on the surface, - for PlaneSurface, StraightLineSurface, PerigeeSurface this is equal to center(), - for CylinderSurface and DiscSurface this is a new member - */ - virtual const Amg::Vector3D& globalReferencePoint() const; - - /** return associated Detector Element */ - const TrkDetElementBase* associatedDetectorElement() const; - - /** return Identifier of the associated Detector Element */ - const Identifier associatedDetectorElementIdentifier() const; - - /** return the associated Layer */ - const Trk::Layer* associatedLayer() const; - - /** return the material Layer */ - const Trk::Layer* materialLayer() const; - - /** return the base surface (simplified for persistification) */ - virtual const Trk::Surface* baseSurface() const; - - /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ - virtual const ParametersBase<5, Trk::Charged>* createTrackParameters(double, double, double, double, double, AmgSymMatrix(5)* cov = 0) const = 0; - - /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ - virtual const ParametersBase<5, Trk::Charged>* createTrackParameters(const Amg::Vector3D&, const Amg::Vector3D&, double, AmgSymMatrix(5)* cov = 0) const = 0; - - /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ - virtual const ParametersBase<5, Trk::Neutral>* createNeutralParameters(double, double, double, double, double, AmgSymMatrix(5)* cov = 0) const = 0; - - /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ - virtual const ParametersBase<5, Trk::Neutral>* createNeutralParameters(const Amg::Vector3D&, const Amg::Vector3D&, double charge=0., AmgSymMatrix(5)* cov = 0) const = 0; - - /** positionOnSurface() returns a pointer to a LocalPosition on the Surface,<br> - If BoundaryCheck==false it just returns the value of globalToLocal (including NULL pointer possibility), - if BoundaryCheck==true it checks whether the point is inside bounds or not (returns NULL pointer in this case). */ - const Amg::Vector2D* positionOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk=true, - double tol1=0., - double tol2=0.) const; - - /** The templated Parameters OnSurface method - checks on surface pointer first */ - template <class T> bool onSurface(const T& parameters, const BoundaryCheck& bchk = BoundaryCheck(true)) const; - - /** This method returns true if the GlobalPosition is on the Surface for both, within - or without check of whether the local position is inside boundaries or not */ - virtual bool isOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk=true, - double tol1=0., - double tol2=0.) const; - - /** virtual methods to be overwritten by the inherited surfaces */ - virtual bool insideBounds(const Amg::Vector2D& locpos, - double tol1=0., - double tol2=0.) const = 0; - - virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, - const BoundaryCheck& bchk) const = 0; - - /** This method returns the GlobalPosition from a LocalPosition - The LocalPosition can be outside Surface bounds - only for planar, cylinder surfaces fully defined */ - const Amg::Vector3D* localToGlobal(const Amg::Vector2D& locpos) const; - - /** This method returns the GlobalPosition from a LocalPosition - The LocalPosition can be outside Surface bounds - for generality with momentum*/ - const Amg::Vector3D* localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D& glomom) const; - - /** This method returns the GlobalPosition from LocalParameters - The LocalParameters can be outside Surface bounds - only for planar, cylinder surfaces fully defined */ - const Amg::Vector3D* localToGlobal(const LocalParameters& locpars) const; - - /** This method returns the GlobalPosition from LocalParameters - The LocalParameters can be outside Surface bounds - for generality with momentum */ - const Amg::Vector3D* localToGlobal(const LocalParameters& locpars, const Amg::Vector3D& glomom) const; - - /** Specified by each surface type: LocalToGlobal method without dynamic memory allocation */ - virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const = 0; - - /** Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean checks if on surface */ - virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const = 0; - - /** This method returns the LocalPosition from a provided GlobalPosition. - If the GlobalPosition is not on the Surface, it returns a NULL pointer. - This method does not check if the calculated LocalPosition is inside surface bounds. - If this check is needed, use positionOnSurface - only for planar, cylinder surface fully defined*/ - const Amg::Vector2D* globalToLocal(const Amg::Vector3D& glopos, double tol=0.) const; - - /** This method returns the LocalPosition from a provided GlobalPosition. - If the GlobalPosition is not on the Surface, it returns a NULL pointer. - This method does not check if the calculated LocalPosition is inside surface bounds. - If this check is needed, use positionOnSurface - for generality with momentum */ - const Amg::Vector2D* globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const; - - /** Optionally specified by each surface type : LocalParameters to Vector2D */ - virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const; - - /** the pathCorrection for derived classes with thickness - it reflects if the direction projection is positive or negative */ - virtual double pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const; - - /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface - - the default implementation is the the RotationMatrix3D of the transform */ - virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const; - - /** fst straight line intersection schema - templated for cvharged and neutral parameters */ - template <class T> Intersection straightLineIntersection(const T& pars, bool forceDir = false, Trk::BoundaryCheck bchk = false) const - { return straightLineIntersection(pars.position(),pars.momentum().unit(),forceDir,bchk); } - - /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length - forceFwd is to provide the closest forward solution - */ - virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir = false, - Trk::BoundaryCheck bchk = false) const = 0; - - /** fast straight line distance evaluation to Surface */ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const = 0; - - /** fast straight line distance evaluation to Surface - with bound option*/ - virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir, bool Bound) const = 0; - - /** Surface Bounds method */ - virtual const SurfaceBounds& bounds() const = 0; - - /** Returns 'true' if this surface is 'free', i.e. it does not belong to a detector element (and returns false otherwise*/ - bool isFree() const; - - /** Return 'true' if this surface is own by the detector element */ - bool isActive() const; - - /** Set ownership - * Athena MT note : This should not be really used - * as it modifies a const object. - * The non-const overload below is fine. - */ - void setOwner ATLAS_NOT_THREAD_SAFE (SurfaceOwner x) const - { const_cast<SurfaceOwner&> (m_owner) = x; } - - /* set Ownership */ - void setOwner(SurfaceOwner x) - { m_owner = x; } - - /** return ownership */ - SurfaceOwner owner() const - { return m_owner; } - - /** set material layer */ - void setMaterialLayer(const Layer& mlay) - { m_materialLayer = (&mlay); } - - void setMaterialLayer(const Layer* mlay) - { m_materialLayer = mlay; } - - /** set material layer - * Athena MT note : This should not be really used - * as it modifies a const object. - * The non-const overload above is fine. - */ - void setMaterialLayer ATLAS_NOT_THREAD_SAFE (const Layer& mlay) const - { const_cast<Surface*> (this)->m_materialLayer = (&mlay); } - void setMaterialLayer ATLAS_NOT_THREAD_SAFE (const Layer* mlay) const - { const_cast<Surface*> (this)->m_materialLayer = mlay; } - - /** Output Method for MsgStream, to be overloaded by child classes */ - virtual MsgStream& dump(MsgStream& sl) const; - - /** Output Method for std::ostream, to be overloaded by child classes */ - virtual std::ostream& dump(std::ostream& sl) const; - - /** Return properly formatted class name */ - virtual std::string name() const = 0; - - /**return number of surfaces currently created - needed for EDM monitor */ - static unsigned int numberOfInstantiations(); - /**return number of free surfaces currently created (i.e. those not belonging to a DE) - needed for EDM monitor */ - static unsigned int numberOfFreeInstantiations(); - - /** method to associate the associated Trk::Layer which is alreay owned - - only allowed by LayerBuilder - - only done if no Layer is set already */ - void associateLayer(const Layer& lay) - { m_associatedLayer = (&lay); } - - /* Athena MT note : This should not be really used - * as it modifies a const object. - * The non-const overload above is fine - */ - void associateLayer ATLAS_NOT_THREAD_SAFE (const Layer& lay) const - { const_cast<Surface*> (this)->m_associatedLayer = (&lay); } - - protected: - friend class ::SurfaceCnv_p1; - - /** Private members are in principle implemented as mutable pointers to objects for easy checks - if they are already declared or not */ - CxxUtils::CachedUniquePtrT<Amg::Transform3D> m_transform; //!< Transform3D to orient surface w.r.t to global frame - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_center; //!< center position of the surface - CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_normal; //!< normal vector of the surface - - /** Pointers to the a TrkDetElementBase */ - const TrkDetElementBase* m_associatedDetElement; - Identifier m_associatedDetElementId; - - /**The associated layer Trk::Layer - - layer in which the Surface is be embedded - */ - const Layer* m_associatedLayer; - - /** Possibility to attach a material descrption - - potentially given as the associated material layer - don't delete, it's the TrackingGeometry's job to do so - */ - const Layer* m_materialLayer; - - /** pointer to surface owner : 0 free surface */ - SurfaceOwner m_owner; - - /**Tolerance for being on Surface */ - const static double s_onSurfaceTolerance; -#ifndef NDEBUG - /** number of objects of this type in memory - needed for EDM monitor*/ - static std::atomic<unsigned int> s_numberOfInstantiations; - - /** number of objects of this type in memory which do not belong to a detector element - needed for EDM monitor*/ - static std::atomic<unsigned int> s_numberOfFreeInstantiations; -#endif - }; + The creation of a Surface by passing a HepGeom::Transform3D* through the constructor + implies that the ownership of the HepGeom::Transform3D object is also passed to the Surface, + therfor the memory is freed in the Surface destructor. + For all isOnSurface, or positionOnSurface and insideBounds methods two tolerance parameters + can be given which correspond to the two local natural coordinates of the surface loc1, loc2. - inline bool Surface::operator!=(const Surface& sf) const { return !((*this)==sf); } - - inline const Amg::Transform3D* Surface::cachedTransform() const - { - return m_transform.get(); - } + @author Andreas.Salzburger@cern.ch + */ - inline const Amg::Transform3D& Surface::transform() const - { - if (m_transform) return (*m_transform); - if (m_associatedDetElement && m_associatedDetElementId.is_valid()) return m_associatedDetElement->transform(m_associatedDetElementId); - if (m_associatedDetElement) return m_associatedDetElement->transform(); - return s_idTransform; - } +class Surface +{ + /** Declare the ILayerBuilder / ITrackingVolumeHelper to be a friend class such it is able to set the layer */ + friend class ILayerBuilder; + friend class ITrackingVolumeHelper; - inline const Amg::Vector3D& Surface::center() const - { - if(m_transform && !m_center){ - return *(m_center.set( - std::make_unique<Amg::Vector3D>(m_transform->translation()) - )); - - } - if(m_center) return (*m_center); - if(m_associatedDetElement && m_associatedDetElementId.is_valid()) return m_associatedDetElement->center(m_associatedDetElementId); - if (m_associatedDetElement) return m_associatedDetElement->center(); - return s_origin; - } +public: + /** @enum SurfaceType - inline const Amg::Vector3D& Surface::normal() const - { - if (m_transform && !m_normal) { - return *(m_normal.set( - std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2)) - )); - } - if (m_normal) return (*m_normal); - if (m_associatedDetElement && m_associatedDetElementId.is_valid()) return m_associatedDetElement->normal(m_associatedDetElementId); - if (m_associatedDetElement) return m_associatedDetElement->normal(); - return s_zAxis; - } + This enumerator simplifies the persistency & calculations, + by saving a dynamic_cast to happen. - // standard is to set non-defined parameters to 0, but can be changed for surface type - inline const Amg::Vector2D Surface::localParametersToPosition(const LocalParameters& locpars) const - { - if ( locpars.contains(Trk::loc1) && locpars.contains(Trk::loc2) ) - return Amg::Vector2D(locpars[Trk::loc1],locpars[loc2]); - if ( locpars.contains(Trk::loc1) ) - return Amg::Vector2D(locpars[Trk::loc1], 0.); - if ( locpars.contains(Trk::loc2) ) - return Amg::Vector2D(0.,locpars[loc2]); - return Amg::Vector2D(0.,0.); - } + Other is reserved for the GeometrySurfaces implementation. - // common to planar surfaces - inline double Surface::pathCorrection(const Amg::Vector3D&, const Amg::Vector3D& mom) const + */ + enum SurfaceType { - Amg::Vector3D dir(mom.unit()); - double cosAlpha = dir.dot(normal()); - return ( cosAlpha!=0 ? fabs(1./cosAlpha) : 1. ); //ST undefined for cosAlpha=0 - } + Cone = 0, + Cylinder = 1, + Disc = 2, + Perigee = 3, + Plane = 4, + Line = 5, + Curvilinear = 6, + Other = 7 + }; - //* the templated parameters on Surface method */ - template <class T> bool Surface::onSurface(const T& pars, const Trk::BoundaryCheck& bcheck ) const - { - // surface pointer comparison as a first fast check (w/o transform) - if ( (&pars.associatedSurface() == this ) ){ - return (bcheck ? insideBoundsCheck(pars.localPosition(),bcheck) : true); - } - return isOnSurface(pars.position(),bcheck); - } + /**Default Constructor + - needed for inherited classes */ + Surface(); - // common to all surface, uses memory optized method - inline const Amg::Vector3D* Surface::localToGlobal(const Amg::Vector2D& locpos) const - { - Amg::Vector3D* gPosition = new Amg::Vector3D; - localToGlobal(locpos, Amg::Vector3D(1.,1.,1.), *gPosition); - return gPosition; - } - // common to all surfaces uses memory optimized method - inline const Amg::Vector3D* Surface::localToGlobal(const Amg::Vector2D& locpos, - const Amg::Vector3D& glomom) const - { - Amg::Vector3D* gPosition = new Amg::Vector3D; - localToGlobal(locpos, glomom, *gPosition); - return gPosition; - } - // common to all surface, uses memory optized method - inline const Amg::Vector3D* Surface::localToGlobal(const LocalParameters& locpars) const + /**Copy constructor - it resets the associated + detector element to 0 and the identifier to invalid, + as the copy cannot be owned by the same detector element as the original */ + Surface(const Surface& sf); + + /**Copy constructor with shift */ + Surface(const Surface& sf, const Amg::Transform3D& transf); + + /**Constructor with HepGeom::Transform3D, passing ownership */ + Surface(Amg::Transform3D* htrans); + + /**Constructor with HepGeom::Transform3D, by unique_ptr */ + Surface(std::unique_ptr<Amg::Transform3D> htrans); + + /**Constructor from TrkDetElement*/ + Surface(const TrkDetElementBase& detelement); + + /**Constructor form TrkDetElement and Identifier*/ + Surface(const TrkDetElementBase& detelement, const Identifier& id); + + /**Virtual Destructor*/ + virtual ~Surface(); + + /**Assignment operator- it sets the associated + detector element to 0 and the associated identifier to invalid, + as the copy cannot be owned by the same detector element as the original */ + Surface& operator=(const Surface& sf); + + /**Equality operator*/ + virtual bool operator==(const Surface& sf) const = 0; + + /**Non-equality operator*/ + virtual bool operator!=(const Surface& sf) const; + + /**Implicit constructor - uses the copy constructor */ + virtual Surface* clone() const = 0; + + /** Returns the Surface type to avoid dynamic casts */ + virtual SurfaceType type() const = 0; + + /** Return the cached transformation directly. Don't try to make + a new transform if it's not here. */ + const Amg::Transform3D* cachedTransform() const; + + /** Returns HepGeom::Transform3D by reference */ + virtual const Amg::Transform3D& transform() const; + + /** Returns the center position of the Surface */ + virtual const Amg::Vector3D& center() const; + + /** Returns the normal vector of the Surface (i.e. in generall z-axis of rotation) */ + virtual const Amg::Vector3D& normal() const; + + /** Returns a normal vector at a specific local position */ + virtual const Amg::Vector3D* normal(const Amg::Vector2D& lp) const; + + /** Returns a global reference point on the surface, + for PlaneSurface, StraightLineSurface, PerigeeSurface this is equal to center(), + for CylinderSurface and DiscSurface this is a new member + */ + virtual const Amg::Vector3D& globalReferencePoint() const; + + /** return associated Detector Element */ + const TrkDetElementBase* associatedDetectorElement() const; + + /** return Identifier of the associated Detector Element */ + const Identifier associatedDetectorElementIdentifier() const; + + /** return the associated Layer */ + const Trk::Layer* associatedLayer() const; + + /** return the material Layer */ + const Trk::Layer* materialLayer() const; + + /** return the base surface (simplified for persistification) */ + virtual const Trk::Surface* baseSurface() const; + + /** Use the Surface as a ParametersBase constructor, from local parameters - charged */ + virtual const ParametersBase<5, Trk::Charged>* createTrackParameters(double, + double, + double, + double, + double, + AmgSymMatrix(5) * cov = 0) const = 0; + + /** Use the Surface as a ParametersBase constructor, from global parameters - charged*/ + virtual const ParametersBase<5, Trk::Charged>* createTrackParameters(const Amg::Vector3D&, + const Amg::Vector3D&, + double, + AmgSymMatrix(5) * cov = 0) const = 0; + + /** Use the Surface as a ParametersBase constructor, from local parameters - neutral */ + virtual const ParametersBase<5, Trk::Neutral>* createNeutralParameters(double, + double, + double, + double, + double, + AmgSymMatrix(5) * cov = 0) const = 0; + + /** Use the Surface as a ParametersBase constructor, from global parameters - neutral */ + virtual const ParametersBase<5, Trk::Neutral>* createNeutralParameters(const Amg::Vector3D&, + const Amg::Vector3D&, + double charge = 0., + AmgSymMatrix(5) * cov = 0) const = 0; + + /** positionOnSurface() returns a pointer to a LocalPosition on the Surface,<br> + If BoundaryCheck==false it just returns the value of globalToLocal (including NULL pointer possibility), + if BoundaryCheck==true it checks whether the point is inside bounds or not (returns NULL pointer in this case). */ + const Amg::Vector2D* positionOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const; + + /** The templated Parameters OnSurface method - checks on surface pointer first */ + template<class T> + bool onSurface(const T& parameters, const BoundaryCheck& bchk = BoundaryCheck(true)) const; + + /** This method returns true if the GlobalPosition is on the Surface for both, within + or without check of whether the local position is inside boundaries or not */ + virtual bool isOnSurface(const Amg::Vector3D& glopo, + BoundaryCheck bchk = true, + double tol1 = 0., + double tol2 = 0.) const; + + /** virtual methods to be overwritten by the inherited surfaces */ + virtual bool insideBounds(const Amg::Vector2D& locpos, double tol1 = 0., double tol2 = 0.) const = 0; + + virtual bool insideBoundsCheck(const Amg::Vector2D& locpos, const BoundaryCheck& bchk) const = 0; + + /** This method returns the GlobalPosition from a LocalPosition + The LocalPosition can be outside Surface bounds - only for planar, cylinder surfaces fully defined */ + const Amg::Vector3D* localToGlobal(const Amg::Vector2D& locpos) const; + + /** This method returns the GlobalPosition from a LocalPosition + The LocalPosition can be outside Surface bounds - for generality with momentum*/ + const Amg::Vector3D* localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D& glomom) const; + + /** This method returns the GlobalPosition from LocalParameters + The LocalParameters can be outside Surface bounds - only for planar, cylinder surfaces fully defined */ + const Amg::Vector3D* localToGlobal(const LocalParameters& locpars) const; + + /** This method returns the GlobalPosition from LocalParameters + The LocalParameters can be outside Surface bounds - for generality with momentum */ + const Amg::Vector3D* localToGlobal(const LocalParameters& locpars, const Amg::Vector3D& glomom) const; + + /** Specified by each surface type: LocalToGlobal method without dynamic memory allocation */ + virtual void localToGlobal(const Amg::Vector2D& locp, const Amg::Vector3D& mom, Amg::Vector3D& glob) const = 0; + + /** Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean checks if on + * surface */ + virtual bool globalToLocal(const Amg::Vector3D& glob, const Amg::Vector3D& mom, Amg::Vector2D& loc) const = 0; + + /** This method returns the LocalPosition from a provided GlobalPosition. + If the GlobalPosition is not on the Surface, it returns a NULL pointer. + This method does not check if the calculated LocalPosition is inside surface bounds. + If this check is needed, use positionOnSurface - only for planar, cylinder surface fully defined*/ + const Amg::Vector2D* globalToLocal(const Amg::Vector3D& glopos, double tol = 0.) const; + + /** This method returns the LocalPosition from a provided GlobalPosition. + If the GlobalPosition is not on the Surface, it returns a NULL pointer. + This method does not check if the calculated LocalPosition is inside surface bounds. + If this check is needed, use positionOnSurface - for generality with momentum */ + const Amg::Vector2D* globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const; + + /** Optionally specified by each surface type : LocalParameters to Vector2D */ + virtual const Amg::Vector2D localParametersToPosition(const LocalParameters& locpars) const; + + /** the pathCorrection for derived classes with thickness - it reflects if the direction projection is positive or + * negative */ + virtual double pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const; + + /** Return the measurement frame - this is needed for alignment, in particular for StraightLine and Perigee Surface + - the default implementation is the the RotationMatrix3D of the transform */ + virtual const Amg::RotationMatrix3D measurementFrame(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const; + + /** fst straight line intersection schema - templated for cvharged and neutral parameters */ + template<class T> + Intersection straightLineIntersection(const T& pars, bool forceDir = false, Trk::BoundaryCheck bchk = false) const { - Amg::Vector3D* gPosition = new Amg::Vector3D; - localToGlobal(localParametersToPosition(locpars), Amg::Vector3D(1.,1.,1.), *gPosition); - return gPosition; + return straightLineIntersection(pars.position(), pars.momentum().unit(), forceDir, bchk); } - // common to all surfaces uses memory optimized method - inline const Amg::Vector3D* Surface::localToGlobal(const LocalParameters& locpars, - const Amg::Vector3D& glomom) const + + /** fast straight line intersection schema - standard: provides closest intersection and (signed) path length + forceFwd is to provide the closest forward solution + */ + virtual Intersection straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir = false, + Trk::BoundaryCheck bchk = false) const = 0; + + /** fast straight line distance evaluation to Surface */ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const = 0; + + /** fast straight line distance evaluation to Surface - with bound option*/ + virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool Bound) const = 0; + + /** Surface Bounds method */ + virtual const SurfaceBounds& bounds() const = 0; + + /** Returns 'true' if this surface is 'free', i.e. it does not belong to a detector element (and returns false + * otherwise*/ + bool isFree() const; + + /** Return 'true' if this surface is own by the detector element */ + bool isActive() const; + + /** Set ownership + * Athena MT note : This should not be really used + * as it modifies a const object. + * The non-const overload below is fine. + */ + void setOwner ATLAS_NOT_THREAD_SAFE(SurfaceOwner x) const { const_cast<SurfaceOwner&>(m_owner) = x; } + + /* set Ownership */ + void setOwner(SurfaceOwner x) { m_owner = x; } + + /** return ownership */ + SurfaceOwner owner() const { return m_owner; } + + /** set material layer */ + void setMaterialLayer(const Layer& mlay) { m_materialLayer = (&mlay); } + + void setMaterialLayer(const Layer* mlay) { m_materialLayer = mlay; } + + /** set material layer + * Athena MT note : This should not be really used + * as it modifies a const object. + * The non-const overload above is fine. + */ + void setMaterialLayer ATLAS_NOT_THREAD_SAFE(const Layer& mlay) const { - Amg::Vector3D* gPosition = new Amg::Vector3D(0.,0.,0.); - localToGlobal(localParametersToPosition(locpars), glomom, *gPosition); - return gPosition; + const_cast<Surface*>(this)->m_materialLayer = (&mlay); } - // common to all surfaces, uses memory optized method - inline const Amg::Vector2D* Surface::globalToLocal(const Amg::Vector3D& glopos, double) const + void setMaterialLayer ATLAS_NOT_THREAD_SAFE(const Layer* mlay) const { - Amg::Vector2D* lPosition = new Amg::Vector2D(0.,0.); - if (globalToLocal(glopos, Amg::Vector3D(1.,1.,1.),*lPosition)) return lPosition; - delete lPosition; return 0; + const_cast<Surface*>(this)->m_materialLayer = mlay; } - // common to all surfaces, uses memory optized method - inline const Amg::Vector2D* Surface::globalToLocal(const Amg::Vector3D& glopos, - const Amg::Vector3D& glomom) const + + /** Output Method for MsgStream, to be overloaded by child classes */ + virtual MsgStream& dump(MsgStream& sl) const; + + /** Output Method for std::ostream, to be overloaded by child classes */ + virtual std::ostream& dump(std::ostream& sl) const; + + /** Return properly formatted class name */ + virtual std::string name() const = 0; + + /**return number of surfaces currently created - needed for EDM monitor */ + static unsigned int numberOfInstantiations(); + /**return number of free surfaces currently created (i.e. those not belonging to a DE) - needed for EDM monitor */ + static unsigned int numberOfFreeInstantiations(); + + /** method to associate the associated Trk::Layer which is alreay owned + - only allowed by LayerBuilder + - only done if no Layer is set already */ + void associateLayer(const Layer& lay) { m_associatedLayer = (&lay); } + + /* Athena MT note : This should not be really used + * as it modifies a const object. + * The non-const overload above is fine + */ + void associateLayer ATLAS_NOT_THREAD_SAFE(const Layer& lay) const { - Amg::Vector2D* lPosition = new Amg::Vector2D(0.,0.); - if (globalToLocal(glopos, glomom, *lPosition)) return lPosition; - delete lPosition; return nullptr; + const_cast<Surface*>(this)->m_associatedLayer = (&lay); } - // take local position and return global direction - inline const Amg::Vector3D* Surface::normal(const Amg::Vector2D &) const - { return new Amg::Vector3D(normal()); } +protected: + friend class ::SurfaceCnv_p1; - inline const Amg::Vector3D& Surface::globalReferencePoint() const - { return center(); } + /** Private members are in principle implemented as mutable pointers to objects for easy checks + if they are already declared or not */ + CxxUtils::CachedUniquePtrT<Amg::Transform3D> m_transform; //!< Transform3D to orient surface w.r.t to global frame + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_center; //!< center position of the surface + CxxUtils::CachedUniquePtrT<Amg::Vector3D> m_normal; //!< normal vector of the surface - inline const TrkDetElementBase* Surface::associatedDetectorElement() const - { return m_associatedDetElement; } + /** Pointers to the a TrkDetElementBase */ + const TrkDetElementBase* m_associatedDetElement; + Identifier m_associatedDetElementId; - inline const Identifier Surface::associatedDetectorElementIdentifier() const - { - if (!m_associatedDetElement) return Identifier(); // in invalid state - if (m_associatedDetElementId.is_valid()) return m_associatedDetElementId; - return m_associatedDetElement->identify(); + /**The associated layer Trk::Layer + - layer in which the Surface is be embedded + */ + const Layer* m_associatedLayer; + + /** Possibility to attach a material descrption + - potentially given as the associated material layer + don't delete, it's the TrackingGeometry's job to do so + */ + const Layer* m_materialLayer; + + /** pointer to surface owner : 0 free surface */ + SurfaceOwner m_owner; + + /**Tolerance for being on Surface */ + const static double s_onSurfaceTolerance; +#ifndef NDEBUG + /** number of objects of this type in memory - needed for EDM monitor*/ + static std::atomic<unsigned int> s_numberOfInstantiations; + + /** number of objects of this type in memory which do not belong to a detector element - needed for EDM monitor*/ + static std::atomic<unsigned int> s_numberOfFreeInstantiations; +#endif +}; + +inline bool +Surface::operator!=(const Surface& sf) const +{ + return !((*this) == sf); +} + +inline const Amg::Transform3D* +Surface::cachedTransform() const +{ + return m_transform.get(); +} + +inline const Amg::Transform3D& +Surface::transform() const +{ + if (m_transform) + return (*m_transform); + if (m_associatedDetElement && m_associatedDetElementId.is_valid()) + return m_associatedDetElement->transform(m_associatedDetElementId); + if (m_associatedDetElement) + return m_associatedDetElement->transform(); + return s_idTransform; +} + +inline const Amg::Vector3D& +Surface::center() const +{ + if (m_transform && !m_center) { + return *(m_center.set(std::make_unique<Amg::Vector3D>(m_transform->translation()))); } - - inline const Layer* Surface::associatedLayer() const - { return (m_associatedLayer); } - - inline const Layer* Surface::materialLayer() const - { return m_materialLayer; } - - inline const Surface* Surface::baseSurface() const - { return (this); } - - inline bool Surface::isActive() const - { return (m_associatedDetElement!=0); } - - inline bool Surface::isFree() const - { return (m_owner==Trk::noOwn); } - -/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ -MsgStream& operator << ( MsgStream& sl, const Surface& sf); -std::ostream& operator << ( std::ostream& sl, const Surface& sf); + if (m_center) + return (*m_center); + if (m_associatedDetElement && m_associatedDetElementId.is_valid()) + return m_associatedDetElement->center(m_associatedDetElementId); + if (m_associatedDetElement) + return m_associatedDetElement->center(); + return s_origin; +} + +inline const Amg::Vector3D& +Surface::normal() const +{ + if (m_transform && !m_normal) { + return *(m_normal.set(std::make_unique<Amg::Vector3D>(m_transform->rotation().col(2)))); + } + if (m_normal) + return (*m_normal); + if (m_associatedDetElement && m_associatedDetElementId.is_valid()) + return m_associatedDetElement->normal(m_associatedDetElementId); + if (m_associatedDetElement) + return m_associatedDetElement->normal(); + return s_zAxis; +} + +// standard is to set non-defined parameters to 0, but can be changed for surface type +inline const Amg::Vector2D +Surface::localParametersToPosition(const LocalParameters& locpars) const +{ + if (locpars.contains(Trk::loc1) && locpars.contains(Trk::loc2)) + return Amg::Vector2D(locpars[Trk::loc1], locpars[loc2]); + if (locpars.contains(Trk::loc1)) + return Amg::Vector2D(locpars[Trk::loc1], 0.); + if (locpars.contains(Trk::loc2)) + return Amg::Vector2D(0., locpars[loc2]); + return Amg::Vector2D(0., 0.); +} + +// common to planar surfaces +inline double +Surface::pathCorrection(const Amg::Vector3D&, const Amg::Vector3D& mom) const +{ + Amg::Vector3D dir(mom.unit()); + double cosAlpha = dir.dot(normal()); + return (cosAlpha != 0 ? fabs(1. / cosAlpha) : 1.); // ST undefined for cosAlpha=0 +} + +//* the templated parameters on Surface method */ +template<class T> +bool +Surface::onSurface(const T& pars, const Trk::BoundaryCheck& bcheck) const +{ + // surface pointer comparison as a first fast check (w/o transform) + if ((&pars.associatedSurface() == this)) { + return (bcheck ? insideBoundsCheck(pars.localPosition(), bcheck) : true); + } + return isOnSurface(pars.position(), bcheck); +} + +// common to all surface, uses memory optized method +inline const Amg::Vector3D* +Surface::localToGlobal(const Amg::Vector2D& locpos) const +{ + Amg::Vector3D* gPosition = new Amg::Vector3D; + localToGlobal(locpos, Amg::Vector3D(1., 1., 1.), *gPosition); + return gPosition; +} +// common to all surfaces uses memory optimized method +inline const Amg::Vector3D* +Surface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D& glomom) const +{ + Amg::Vector3D* gPosition = new Amg::Vector3D; + localToGlobal(locpos, glomom, *gPosition); + return gPosition; +} +// common to all surface, uses memory optized method +inline const Amg::Vector3D* +Surface::localToGlobal(const LocalParameters& locpars) const +{ + Amg::Vector3D* gPosition = new Amg::Vector3D; + localToGlobal(localParametersToPosition(locpars), Amg::Vector3D(1., 1., 1.), *gPosition); + return gPosition; +} +// common to all surfaces uses memory optimized method +inline const Amg::Vector3D* +Surface::localToGlobal(const LocalParameters& locpars, const Amg::Vector3D& glomom) const +{ + Amg::Vector3D* gPosition = new Amg::Vector3D(0., 0., 0.); + localToGlobal(localParametersToPosition(locpars), glomom, *gPosition); + return gPosition; +} +// common to all surfaces, uses memory optized method +inline const Amg::Vector2D* +Surface::globalToLocal(const Amg::Vector3D& glopos, double) const +{ + Amg::Vector2D* lPosition = new Amg::Vector2D(0., 0.); + if (globalToLocal(glopos, Amg::Vector3D(1., 1., 1.), *lPosition)) + return lPosition; + delete lPosition; + return 0; +} +// common to all surfaces, uses memory optized method +inline const Amg::Vector2D* +Surface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom) const +{ + Amg::Vector2D* lPosition = new Amg::Vector2D(0., 0.); + if (globalToLocal(glopos, glomom, *lPosition)) + return lPosition; + delete lPosition; + return nullptr; +} + +// take local position and return global direction +inline const Amg::Vector3D* +Surface::normal(const Amg::Vector2D&) const +{ + return new Amg::Vector3D(normal()); +} + +inline const Amg::Vector3D& +Surface::globalReferencePoint() const +{ + return center(); +} + +inline const TrkDetElementBase* +Surface::associatedDetectorElement() const +{ + return m_associatedDetElement; +} + +inline const Identifier +Surface::associatedDetectorElementIdentifier() const +{ + if (!m_associatedDetElement) + return Identifier(); // in invalid state + if (m_associatedDetElementId.is_valid()) + return m_associatedDetElementId; + return m_associatedDetElement->identify(); +} + +inline const Layer* +Surface::associatedLayer() const +{ + return (m_associatedLayer); +} + +inline const Layer* +Surface::materialLayer() const +{ + return m_materialLayer; +} + +inline const Surface* +Surface::baseSurface() const +{ + return (this); +} + +inline bool +Surface::isActive() const +{ + return (m_associatedDetElement != 0); +} + +inline bool +Surface::isFree() const +{ + return (m_owner == Trk::noOwn); +} + +/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ +MsgStream& +operator<<(MsgStream& sl, const Surface& sf); +std::ostream& +operator<<(std::ostream& sl, const Surface& sf); typedef SurfaceUniquePtrT<Trk::Surface> SurfaceUniquePtr; typedef SurfaceUniquePtrT<const Trk::Surface> ConstSurfaceUniquePtr; @@ -540,4 +613,3 @@ typedef SurfaceUniquePtrT<const Trk::Surface> ConstSurfaceUniquePtr; } // end of namespace Trk #endif // TRKSURFACES_SURFACE_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceBounds.h index 8b26ad5d10e09e946235a0efd81ada37fa1aff94..5533088f51f54c3376b0a419afb4c03c57bd6dbc 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceBounds.h @@ -9,11 +9,11 @@ #ifndef TRKSURFACES_SURFACEBOUNDS_H #define TRKSURFACES_SURFACEBOUNDS_H -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -//GaudiKernel +// GaudiKernel #include "GaudiKernel/MsgStream.h" // Geo & Math library @@ -22,123 +22,129 @@ // Trk included #include "TrkSurfaces/BoundaryCheck.h" -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else typedef double TDD_real_t; #endif - namespace Trk { - /** - @class SurfaceBounds - - Abstract base class for surface bounds to be specified. - - Surface bounds provide: - - inside() checks - - the BoundsType return type - - an initCache() method - - @author Andreas.Salzburger@cern.ch - */ - - - class SurfaceBounds { - - public: - - /** @enum BoundsType - - This enumerator simplifies the persistency, - by saving a dynamic_cast to happen. - - Other is reserved for the GeometrySurfaces implementation. - - */ - enum BoundsType { - Cone = 0, - Cylinder = 1, - Diamond = 2, - Disc = 3, - Ellipse = 5, - Rectangle = 6, - RotatedTrapezoid = 7, - Trapezoid = 8, - Triangle = 9, - DiscTrapezoidal = 10, - Annulus = 11, - Other = 12 - - }; - - /**Default Constructor*/ - SurfaceBounds() = default; - - /**Destructor*/ - virtual ~SurfaceBounds() = default; - - /** clone() method to make deep copy in Surface copy constructor and for assigment operator - of the Surface class.*/ - virtual SurfaceBounds* clone() const = 0; - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sb) const = 0; - - /**Non-Equality operator*/ - virtual bool operator!=(const SurfaceBounds& sb) const; - - /** Return the bounds type - for persistency optimization */ - virtual BoundsType type() const = 0; - - /** Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds. - Inside can be called without/with tolerances. */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const = 0; - virtual bool inside(const Amg::Vector2D& locpo, - const BoundaryCheck& bchk) const = 0; - /** Extend the interface to for single inside Loc 1 / Loc2 tests - - loc1/loc2 correspond to the natural coordinates of the surface - */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const = 0; - - /** Extend the interface to for single inside Loc 1 / Loc2 tests - - loc1/loc2 correspond to the natural coordinates of the surface - */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const = 0; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const = 0; - - /** Interface method for the maximal extension or the radius*/ - virtual double r() const = 0; - - /** Output Method for MsgStream, to be overloaded by child classes */ - virtual MsgStream& dump(MsgStream& sl) const = 0; - - /** Output Method for std::ostream, to be overloaded by child classes */ - virtual std::ostream& dump(std::ostream& sl) const = 0; - - protected: - /** Swap method to be called from DiscBounds or TrapezoidalBounds */ - void swap(double& b1, double& b2); - - /** virtual initCache method for object persistency */ - virtual void initCache() {} +/** + @class SurfaceBounds + + Abstract base class for surface bounds to be specified. + + Surface bounds provide: + - inside() checks + - the BoundsType return type + - an initCache() method + + @author Andreas.Salzburger@cern.ch + */ + +class SurfaceBounds +{ + +public: + /** @enum BoundsType + + This enumerator simplifies the persistency, + by saving a dynamic_cast to happen. + + Other is reserved for the GeometrySurfaces implementation. + + */ + enum BoundsType + { + Cone = 0, + Cylinder = 1, + Diamond = 2, + Disc = 3, + Ellipse = 5, + Rectangle = 6, + RotatedTrapezoid = 7, + Trapezoid = 8, + Triangle = 9, + DiscTrapezoidal = 10, + Annulus = 11, + Other = 12 + }; - inline void SurfaceBounds::swap(double& b1, double& b2) { - double tmp=b1; - b1 = b2; - b2 = tmp; - } - - inline bool SurfaceBounds::operator!=(const SurfaceBounds& sb) const { return !((*this)==sb);} - -/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ -MsgStream& operator << ( MsgStream& sl, const SurfaceBounds& sb); -std::ostream& operator << ( std::ostream& sl, const SurfaceBounds& sb); - + /**Default Constructor*/ + SurfaceBounds() = default; + + /**Destructor*/ + virtual ~SurfaceBounds() = default; + + /** clone() method to make deep copy in Surface copy constructor and for assigment operator + of the Surface class.*/ + virtual SurfaceBounds* clone() const = 0; + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sb) const = 0; + + /**Non-Equality operator*/ + virtual bool operator!=(const SurfaceBounds& sb) const; + + /** Return the bounds type - for persistency optimization */ + virtual BoundsType type() const = 0; + + /** Each Bounds has a method inside, which checks if a LocalPosition is inside the bounds. + Inside can be called without/with tolerances. */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const = 0; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const = 0; + /** Extend the interface to for single inside Loc 1 / Loc2 tests + - loc1/loc2 correspond to the natural coordinates of the surface + */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const = 0; + + /** Extend the interface to for single inside Loc 1 / Loc2 tests + - loc1/loc2 correspond to the natural coordinates of the surface + */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const = 0; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const = 0; + + /** Interface method for the maximal extension or the radius*/ + virtual double r() const = 0; + + /** Output Method for MsgStream, to be overloaded by child classes */ + virtual MsgStream& dump(MsgStream& sl) const = 0; + + /** Output Method for std::ostream, to be overloaded by child classes */ + virtual std::ostream& dump(std::ostream& sl) const = 0; + +protected: + /** Swap method to be called from DiscBounds or TrapezoidalBounds */ + void swap(double& b1, double& b2); + + /** virtual initCache method for object persistency */ + virtual void initCache() {} +}; + +inline void +SurfaceBounds::swap(double& b1, double& b2) +{ + double tmp = b1; + b1 = b2; + b2 = tmp; +} + +inline bool +SurfaceBounds::operator!=(const SurfaceBounds& sb) const +{ + return !((*this) == sb); +} + +/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ +MsgStream& +operator<<(MsgStream& sl, const SurfaceBounds& sb); +std::ostream& +operator<<(std::ostream& sl, const SurfaceBounds& sb); + } // end of namespace #endif // TRKSURFACES_SURFACEBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceCollection.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceCollection.h index c7f396c0402b9fc7e08f764a94b0262379e9b2a2..ec209c7d5473eeb2b1906c071ddcbd90c485cbc6 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceCollection.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/SurfaceCollection.h @@ -9,9 +9,8 @@ #ifndef TRKSURFACES_SURFACECOLLECTION_H #define TRKSURFACES_SURFACECOLLECTION_H - -#include "Identifier/Identifier.h" #include "AthContainers/DataVector.h" +#include "Identifier/Identifier.h" #include "SGTools/CLASS_DEF.h" // Trk #include "TrkSurfaces/Surface.h" @@ -19,38 +18,36 @@ #include <map> #include <utility> - /** - <b>SurfaceCollection</b> - - DataVector filled with pointers to Surfaces and an iterator - as well as a const iterator typedef. - - - <b>SurfaceMap</b> - - Standard STL map using the Identifier as map key for surfaces created directly form GeoModel - - - - <b>TrachingSurfaceMap</b> - - Standard STL multimap using const double as map key for surfaces created through TrkGeometryBuilder - - @author Andreas.Salzburger@cern.ch */ - - /** DataVector of const Surface / 24.08.2004 - % clid.py SurfaceCollection - 1185938832 SurfaceCollection */ - - typedef DataVector<const Trk::Surface> SurfaceCollection; - typedef DataVector<const Trk::Surface>::const_iterator SurfaceCollectionIterator; - - // map of const Surface* - typedef std::map<const Identifier, const Trk::Surface*> SurfaceMap; - typedef std::map<const Identifier, const Trk::Surface*>::const_iterator SurfaceMapIterator; - // map of const Surface* type2 - typedef std::multimap<double, const Trk::Surface*> TrackingSurfaceMap; - typedef std::multimap<double, const Trk::Surface*>::const_iterator TrackingSurfaceMapIterator; - -CLASS_DEF(SurfaceCollection , 1185938832 , 1 ) +/** - <b>SurfaceCollection</b> + + DataVector filled with pointers to Surfaces and an iterator + as well as a const iterator typedef. + + - <b>SurfaceMap</b> + + Standard STL map using the Identifier as map key for surfaces created directly form GeoModel -#endif // TRKSURFACES_SURFACECOLLECTION_H + - <b>TrachingSurfaceMap</b> + Standard STL multimap using const double as map key for surfaces created through TrkGeometryBuilder + + @author Andreas.Salzburger@cern.ch */ + +/** DataVector of const Surface / 24.08.2004 + % clid.py SurfaceCollection + 1185938832 SurfaceCollection */ + +typedef DataVector<const Trk::Surface> SurfaceCollection; +typedef DataVector<const Trk::Surface>::const_iterator SurfaceCollectionIterator; + +// map of const Surface* +typedef std::map<const Identifier, const Trk::Surface*> SurfaceMap; +typedef std::map<const Identifier, const Trk::Surface*>::const_iterator SurfaceMapIterator; +// map of const Surface* type2 +typedef std::multimap<double, const Trk::Surface*> TrackingSurfaceMap; +typedef std::multimap<double, const Trk::Surface*>::const_iterator TrackingSurfaceMapIterator; + +CLASS_DEF(SurfaceCollection, 1185938832, 1) + +#endif // TRKSURFACES_SURFACECOLLECTION_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrapezoidBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrapezoidBounds.h index c7fc7e8c903cc4e2dd889eacd27a61b0fb2f0d61..08c4038c0e7fa9f8f5239c70385f647a3441cc67 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrapezoidBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrapezoidBounds.h @@ -9,8 +9,8 @@ #ifndef TRKSURFACES_TRAPEZOIDBOUNDS_H #define TRKSURFACES_TRAPEZOIDBOUNDS_H -#include "TrkSurfaces/SurfaceBounds.h" #include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" #include <math.h> #include "GeoPrimitives/GeoPrimitives.h" @@ -18,242 +18,294 @@ class MsgStream; class TrapezoidBoundsCnv_p1; -#ifdef TRKDETDESCR_USEFLOATPRECISON +#ifdef TRKDETDESCR_USEFLOATPRECISON typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class TrapezoidBounds - Bounds for a trapezoidal, planar Surface. - - @image html TrapezoidalBounds.gif - <br> - @image html SCT_Trapezoid.gif - - @todo can be speed optimized by calculating kappa/delta and caching it - - @author Andreas.Salzburger@cern.ch - */ - - class TrapezoidBounds : public SurfaceBounds { - - public: - /** @enum BoundValues - for readability */ - enum BoundValues { - bv_minHalfX = 0, - bv_maxHalfX = 1, - bv_halfY = 2, - bv_length = 3 - }; - - /**Default Constructor, needed for persistency*/ - TrapezoidBounds(); - - /**Constructor for symmetric Trapezoid*/ - TrapezoidBounds(double minhalex, double maxhalex, double haley); - - /**Constructor for arbitrary Trapezoid*/ - TrapezoidBounds(double minhalex, double haley, double alpha, double beta); - - /**Copy constructor*/ - TrapezoidBounds(const TrapezoidBounds& trabo); - - /**Destructor*/ - virtual ~TrapezoidBounds(); - - /**Virtual constructor*/ - virtual TrapezoidBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::Trapezoid; } - - /**Assignment operator*/ - TrapezoidBounds& operator=(const TrapezoidBounds& sbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& trabo) const override; - - /**This method returns the minimal halflength in phi (first coordinate of local surface frame)*/ - double minHalflengthPhi() const; - - /**This method returns the maximal halflength in phi (first coordinate of local surface frame)*/ - double maxHalflengthPhi() const; - - /**This method returns the halflength in eta (second coordinate of local surface frame)*/ - double halflengthEta() const; - - /**This method returns the minimal halflength in X (first coordinate of local surface frame)*/ - double minHalflengthX() const; - - /**This method returns the maximal halflength in X (first coordinate of local surface frame)*/ - double maxHalflengthX() const; - - /**This method returns the halflength in Y (second coordinate of local surface frame)*/ - double halflengthY() const; - - /**This method returns the maximal extension on the local plane*/ - virtual double r() const override; - - /**This method returns the opening angle alpha in point A (negative local phi) */ - double alpha() const; - - /**This method returns the opening angle beta in point B (positive local phi) */ - double beta() const; - - /** The orientation of the Trapezoid is according to the figure above, - in words: the shorter of the two parallel sides of the trapezoid intersects - with the negative @f$ y @f$ - axis of the local frame. - - <br> - The cases are:<br> - (0) @f$ y @f$ or @f$ x @f$ bounds are 0 || 0<br> - (1) LocalPosition is outside @f$ y @f$ bounds <br> - (2) LocalPosition is inside @f$ y @f$ bounds, but outside maximum @f$ x @f$ bounds <br> - (3) LocalPosition is inside @f$ y @f$ bounds AND inside minimum @f$ x @f$ bounds <br> - (4) LocalPosition is inside @f$ y @f$ bounds AND inside maximum @f$ x @f$ bounds, so that - it depends on the @f$ eta @f$ coordinate - (5) LocalPosition fails test of (4) <br> - - The inside check is done using single equations of straight lines and one has to take care if a point - lies on the positive @f$ x @f$ half area(I) or the negative one(II). Denoting @f$ |x_{min}| @f$ and - @f$ | x_{max} | @f$ as \c minHalfX respectively \c maxHalfX, such as @f$ | y_{H} | @f$ as \c halfY, - the equations for the straing lines in (I) and (II) can be written as:<br> - <br> - - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> - - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> - <br> - where @f$ \kappa_{I} = - \kappa_{II} = 2 \frac{y_{H}}{x_{max} - x_{min}} @f$ <br> - and @f$ \delta_{I} = \delta_{II} = - \frac{1}{2}\kappa_{I}(x_{max} + x_{min}) @f$ */ - virtual bool inside(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! */ - - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface - - As loc1/loc2 are correlated the single check doesn't make sense : - -> check is done on enclosing Rectangle ! */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - friend class ::TrapezoidBoundsCnv_p1; - - /** inside() method for a full symmetric trapezoid */ - bool insideFull(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const; - - /** inside() method for the triangular exclude area for an arbitrary trapezoid */ - bool insideExclude(const Amg::Vector2D& locpo, double tol1=0., double tol2=0.) const; - - /** isAbove() method for checking whether a point lies above or under a straight line */ - bool isAbove(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double k, - double d) const; - - std::vector<TDD_real_t> m_boundValues; - TDD_real_t m_alpha; - TDD_real_t m_beta; +/** + @class TrapezoidBounds + Bounds for a trapezoidal, planar Surface. - }; + @image html TrapezoidalBounds.gif + <br> + @image html SCT_Trapezoid.gif + + @todo can be speed optimized by calculating kappa/delta and caching it - inline TrapezoidBounds* TrapezoidBounds::clone() const { return new TrapezoidBounds(*this); } - - inline double TrapezoidBounds::minHalflengthX() const { return m_boundValues[TrapezoidBounds::bv_minHalfX]; } - - inline double TrapezoidBounds::maxHalflengthX() const { return m_boundValues[TrapezoidBounds::bv_maxHalfX]; } - - inline double TrapezoidBounds::halflengthY() const { return m_boundValues[TrapezoidBounds::bv_halfY]; } - - inline double TrapezoidBounds::minHalflengthPhi() const { return minHalflengthX(); } - - inline double TrapezoidBounds::maxHalflengthPhi() const { return maxHalflengthX(); } - - inline double TrapezoidBounds::halflengthEta() const { return halflengthY(); } - - inline double TrapezoidBounds::alpha() const { return m_alpha; } - - inline double TrapezoidBounds::beta() const { return m_beta; } - - inline double TrapezoidBounds::r() const - { return sqrt(m_boundValues[TrapezoidBounds::bv_maxHalfX]*m_boundValues[TrapezoidBounds::bv_maxHalfX] - + m_boundValues[TrapezoidBounds::bv_halfY]*m_boundValues[TrapezoidBounds::bv_halfY]); } - - inline bool TrapezoidBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const + @author Andreas.Salzburger@cern.ch + */ + +class TrapezoidBounds : public SurfaceBounds +{ + +public: + /** @enum BoundValues - for readability */ + enum BoundValues { - if(bchk.bcType==0) return TrapezoidBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - double fabsY = fabs(locpo[Trk::locY]); - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) :bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - if (fabsY > ( m_boundValues[TrapezoidBounds::bv_halfY] + limit)) return false; - // a fast FALSE - double fabsX = fabs(locpo[Trk::locX]); - if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + limit)) return false; - // a fast TRUE - double min_ell = bchk.lCovariance(0,0) < bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) : bchk.lCovariance(1,1); - limit = bchk.nSigmas*sqrt(min_ell); - if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] + limit) && fabsY < (m_boundValues[TrapezoidBounds::bv_halfY] + limit)) return true; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(3); - std::vector<Amg::Vector2D> elementP(4); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p << m_boundValues[TrapezoidBounds::bv_minHalfX],-m_boundValues[TrapezoidBounds::bv_halfY]; - elementP[0] =( rotMatrix * (p - locpo) ); - p << -m_boundValues[TrapezoidBounds::bv_minHalfX],-m_boundValues[TrapezoidBounds::bv_halfY]; - elementP[1] =( rotMatrix * (p - locpo) ); - scResult = bchk.FastSinCos(m_beta); - p << m_boundValues[TrapezoidBounds::bv_minHalfX] + (2.*m_boundValues[TrapezoidBounds::bv_halfY])*(scResult.sinC/scResult.cosC),m_boundValues[TrapezoidBounds::bv_halfY]; - elementP[2] =( rotMatrix * (p - locpo) ); - scResult = bchk.FastSinCos(m_alpha); - p << -(m_boundValues[TrapezoidBounds::bv_minHalfX] + (2.*m_boundValues[TrapezoidBounds::bv_halfY])*(scResult.sinC/scResult.cosC)),m_boundValues[TrapezoidBounds::bv_halfY]; - elementP[3] =( rotMatrix * (p - locpo) ); - std::vector<Amg::Vector2D> axis = {normal*(elementP[1]-elementP[0]), normal*(elementP[3]-elementP[1]), normal*(elementP[2]-elementP[0])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(3); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - - inline bool TrapezoidBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return (fabs(locpo[locX]) < m_boundValues[TrapezoidBounds::bv_maxHalfX] + tol1); } - - inline bool TrapezoidBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return (fabs(locpo[locY]) < m_boundValues[TrapezoidBounds::bv_halfY] + tol2); } - + bv_minHalfX = 0, + bv_maxHalfX = 1, + bv_halfY = 2, + bv_length = 3 + }; + + /**Default Constructor, needed for persistency*/ + TrapezoidBounds(); + + /**Constructor for symmetric Trapezoid*/ + TrapezoidBounds(double minhalex, double maxhalex, double haley); + + /**Constructor for arbitrary Trapezoid*/ + TrapezoidBounds(double minhalex, double haley, double alpha, double beta); + + /**Copy constructor*/ + TrapezoidBounds(const TrapezoidBounds& trabo); + + /**Destructor*/ + virtual ~TrapezoidBounds(); + + /**Virtual constructor*/ + virtual TrapezoidBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::Trapezoid; } + + /**Assignment operator*/ + TrapezoidBounds& operator=(const TrapezoidBounds& sbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& trabo) const override; + + /**This method returns the minimal halflength in phi (first coordinate of local surface frame)*/ + double minHalflengthPhi() const; + + /**This method returns the maximal halflength in phi (first coordinate of local surface frame)*/ + double maxHalflengthPhi() const; + + /**This method returns the halflength in eta (second coordinate of local surface frame)*/ + double halflengthEta() const; + + /**This method returns the minimal halflength in X (first coordinate of local surface frame)*/ + double minHalflengthX() const; + + /**This method returns the maximal halflength in X (first coordinate of local surface frame)*/ + double maxHalflengthX() const; + + /**This method returns the halflength in Y (second coordinate of local surface frame)*/ + double halflengthY() const; + + /**This method returns the maximal extension on the local plane*/ + virtual double r() const override; + + /**This method returns the opening angle alpha in point A (negative local phi) */ + double alpha() const; + + /**This method returns the opening angle beta in point B (positive local phi) */ + double beta() const; + + /** The orientation of the Trapezoid is according to the figure above, + in words: the shorter of the two parallel sides of the trapezoid intersects + with the negative @f$ y @f$ - axis of the local frame. + + <br> + The cases are:<br> + (0) @f$ y @f$ or @f$ x @f$ bounds are 0 || 0<br> + (1) LocalPosition is outside @f$ y @f$ bounds <br> + (2) LocalPosition is inside @f$ y @f$ bounds, but outside maximum @f$ x @f$ bounds <br> + (3) LocalPosition is inside @f$ y @f$ bounds AND inside minimum @f$ x @f$ bounds <br> + (4) LocalPosition is inside @f$ y @f$ bounds AND inside maximum @f$ x @f$ bounds, so that + it depends on the @f$ eta @f$ coordinate + (5) LocalPosition fails test of (4) <br> + + The inside check is done using single equations of straight lines and one has to take care if a point + lies on the positive @f$ x @f$ half area(I) or the negative one(II). Denoting @f$ |x_{min}| @f$ and + @f$ | x_{max} | @f$ as \c minHalfX respectively \c maxHalfX, such as @f$ | y_{H} | @f$ as \c halfY, + the equations for the straing lines in (I) and (II) can be written as:<br> + <br> + - (I): @f$ y = \kappa_{I} x + \delta_{I} @f$ <br> + - (II): @f$ y = \kappa_{II} x + \delta_{II} @f$ ,<br> + <br> + where @f$ \kappa_{I} = - \kappa_{II} = 2 \frac{y_{H}}{x_{max} - x_{min}} @f$ <br> + and @f$ \delta_{I} = \delta_{II} = - \frac{1}{2}\kappa_{I}(x_{max} + x_{min}) @f$ */ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! */ + + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface + - As loc1/loc2 are correlated the single check doesn't make sense : + -> check is done on enclosing Rectangle ! */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + friend class ::TrapezoidBoundsCnv_p1; + + /** inside() method for a full symmetric trapezoid */ + bool insideFull(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const; + + /** inside() method for the triangular exclude area for an arbitrary trapezoid */ + bool insideExclude(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const; + + /** isAbove() method for checking whether a point lies above or under a straight line */ + bool isAbove(const Amg::Vector2D& locpo, double tol1, double tol2, double k, double d) const; + + std::vector<TDD_real_t> m_boundValues; + TDD_real_t m_alpha; + TDD_real_t m_beta; +}; + +inline TrapezoidBounds* +TrapezoidBounds::clone() const +{ + return new TrapezoidBounds(*this); +} + +inline double +TrapezoidBounds::minHalflengthX() const +{ + return m_boundValues[TrapezoidBounds::bv_minHalfX]; +} + +inline double +TrapezoidBounds::maxHalflengthX() const +{ + return m_boundValues[TrapezoidBounds::bv_maxHalfX]; +} + +inline double +TrapezoidBounds::halflengthY() const +{ + return m_boundValues[TrapezoidBounds::bv_halfY]; +} + +inline double +TrapezoidBounds::minHalflengthPhi() const +{ + return minHalflengthX(); +} + +inline double +TrapezoidBounds::maxHalflengthPhi() const +{ + return maxHalflengthX(); +} + +inline double +TrapezoidBounds::halflengthEta() const +{ + return halflengthY(); +} + +inline double +TrapezoidBounds::alpha() const +{ + return m_alpha; +} + +inline double +TrapezoidBounds::beta() const +{ + return m_beta; +} + +inline double +TrapezoidBounds::r() const +{ + return sqrt(m_boundValues[TrapezoidBounds::bv_maxHalfX] * m_boundValues[TrapezoidBounds::bv_maxHalfX] + + m_boundValues[TrapezoidBounds::bv_halfY] * m_boundValues[TrapezoidBounds::bv_halfY]); +} + +inline bool +TrapezoidBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0) + return TrapezoidBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + double fabsY = fabs(locpo[Trk::locY]); + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + if (fabsY > (m_boundValues[TrapezoidBounds::bv_halfY] + limit)) + return false; + // a fast FALSE + double fabsX = fabs(locpo[Trk::locX]); + if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + limit)) + return false; + // a fast TRUE + double min_ell = bchk.lCovariance(0, 0) < bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + limit = bchk.nSigmas * sqrt(min_ell); + if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] + limit) && + fabsY < (m_boundValues[TrapezoidBounds::bv_halfY] + limit)) + return true; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(3); + std::vector<Amg::Vector2D> elementP(4); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << m_boundValues[TrapezoidBounds::bv_minHalfX], -m_boundValues[TrapezoidBounds::bv_halfY]; + elementP[0] = (rotMatrix * (p - locpo)); + p << -m_boundValues[TrapezoidBounds::bv_minHalfX], -m_boundValues[TrapezoidBounds::bv_halfY]; + elementP[1] = (rotMatrix * (p - locpo)); + scResult = bchk.FastSinCos(m_beta); + p << m_boundValues[TrapezoidBounds::bv_minHalfX] + + (2. * m_boundValues[TrapezoidBounds::bv_halfY]) * (scResult.sinC / scResult.cosC), + m_boundValues[TrapezoidBounds::bv_halfY]; + elementP[2] = (rotMatrix * (p - locpo)); + scResult = bchk.FastSinCos(m_alpha); + p << -(m_boundValues[TrapezoidBounds::bv_minHalfX] + + (2. * m_boundValues[TrapezoidBounds::bv_halfY]) * (scResult.sinC / scResult.cosC)), + m_boundValues[TrapezoidBounds::bv_halfY]; + elementP[3] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]), + normal * (elementP[3] - elementP[1]), + normal * (elementP[2] - elementP[0]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(3); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +TrapezoidBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return (fabs(locpo[locX]) < m_boundValues[TrapezoidBounds::bv_maxHalfX] + tol1); +} + +inline bool +TrapezoidBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return (fabs(locpo[locY]) < m_boundValues[TrapezoidBounds::bv_halfY] + tol2); +} + } // end of namespace #endif // TRKSURFACES_TRAPEZOIDBOUNDS_H - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TriangleBounds.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TriangleBounds.h index 4e79f218fcb220d66446517a1484ca716528a7d9..79069ca3d53c5cbc3525b0731a865a647389fb80 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TriangleBounds.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TriangleBounds.h @@ -9,209 +9,231 @@ #ifndef TRKSURFACES_TRIANGLEBOUNDS_H #define TRKSURFACES_TRIANGLEBOUNDS_H -#include "TrkSurfaces/SurfaceBounds.h" -#include "TrkEventPrimitives/ParamDefs.h" #include "GeoPrimitives/GeoPrimitives.h" +#include "TrkEventPrimitives/ParamDefs.h" +#include "TrkSurfaces/SurfaceBounds.h" #include <utility> class MsgStream; -#ifdef TRKDETDESCR_USEFLOATPRECISON -typedef float TDD_real_t; -#else -typedef double TDD_real_t; +#ifdef TRKDETDESCR_USEFLOATPRECISON +typedef float TDD_real_t; +#else +typedef double TDD_real_t; #endif namespace Trk { - /** - @class TriangleBounds - - Bounds for a triangular, planar surface. - - @internal - @image html TriangularBounds.gif - @endinternal - - @author sarka.todorova@cern.ch */ - - class TriangleBounds : public SurfaceBounds { - - - public: - /** @enum BoundValues for readability */ - enum BoundValues { - bv_x1 = 0, - bv_y1 = 1, - bv_x2 = 2, - bv_y2 = 3, - bv_x3 = 4, - bv_y3 = 5, - bv_length = 6 - }; - - /**Default Constructor - needed for persistency*/ - TriangleBounds(); - - /**Constructor with coordinates of vertices - floats*/ - TriangleBounds( const std::vector< std::pair<float,float> >& ); - - /**Constructor with coordinates of vertices - double*/ - TriangleBounds( const std::vector< std::pair<double,double> >& ); - - /**Constructor from three 2 Vectors */ - TriangleBounds( const Amg::Vector2D& p1, const Amg::Vector2D& p2, const Amg::Vector2D& p3); - - /**Copy constructor*/ - TriangleBounds(const TriangleBounds& tribo); - - /**Destructor*/ - virtual ~TriangleBounds(); - - /**Assignment Operator*/ - TriangleBounds& operator=(const TriangleBounds& recbo); - - /**Equality operator*/ - virtual bool operator==(const SurfaceBounds& sbo) const override; - - /**Virtual constructor*/ - virtual TriangleBounds* clone() const override; - - /** Return the type of the bounds for persistency */ - virtual BoundsType type() const override { return SurfaceBounds::Triangle; } - - /**This method checks if the provided local coordinates are inside the surface bounds*/ - virtual bool inside(const Amg::Vector2D &locpo, double tol1 = 0., double tol2 = 0.) const override; - virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; - - /** This method checks inside bounds in loc1 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1=0.) const override; - - /** This method checks inside bounds in loc2 - - loc1/loc2 correspond to the natural coordinates of the surface */ - virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2=0.) const override; - - /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ - virtual double minDistance(const Amg::Vector2D& pos) const override; - - /**This method returns the coordinates of vertices*/ - const std::vector< std::pair< TDD_real_t, TDD_real_t> > vertices() const; - - /**This method returns the maximal extension on the local plane, i.e. @f$s\sqrt{h_{\phi}^2 + h_{\eta}^2}\f$*/ - virtual double r() const override; - - /** Output Method for MsgStream*/ - virtual MsgStream& dump(MsgStream& sl) const override; - - /** Output Method for std::ostream */ - virtual std::ostream& dump(std::ostream& sl) const override; - - private: - std::vector<TDD_real_t> m_boundValues; - +/** + @class TriangleBounds + + Bounds for a triangular, planar surface. + + @internal + @image html TriangularBounds.gif + @endinternal + + @author sarka.todorova@cern.ch */ + +class TriangleBounds : public SurfaceBounds +{ + +public: + /** @enum BoundValues for readability */ + enum BoundValues + { + bv_x1 = 0, + bv_y1 = 1, + bv_x2 = 2, + bv_y2 = 3, + bv_x3 = 4, + bv_y3 = 5, + bv_length = 6 }; - inline TriangleBounds* TriangleBounds::clone() const - { return new TriangleBounds(*this); } - - inline bool TriangleBounds::inside(const Amg::Vector2D &locpo, double tol1, double tol2) const { - std::pair<double,double> locB(m_boundValues[TriangleBounds::bv_x2]-m_boundValues[TriangleBounds::bv_x1], - m_boundValues[TriangleBounds::bv_y2]-m_boundValues[TriangleBounds::bv_y1]); - std::pair<double,double> locT(m_boundValues[TriangleBounds::bv_x3] -locpo[0], - m_boundValues[TriangleBounds::bv_y3]-locpo[1]); - std::pair<double,double> locV(m_boundValues[TriangleBounds::bv_x1] -locpo[0], - m_boundValues[TriangleBounds::bv_y1]-locpo[1]); - - // special case :: third vertex ? - if (locT.first*locT.first+locT.second*locT.second<tol1*tol1) return true; - - // special case : lies on base ? - double db = locB.first*locV.second-locB.second*locV.first; - if ( fabs(db)<tol1 ) { - double a = (locB.first!=0) ? -locV.first/locB.first : -locV.second/locB.second; - if ( a>-tol2 && a-1.<tol2 ) return true; - return false; - } - - double dn = locB.first*locT.second-locB.second*locT.first; - - if ( fabs(dn) > fabs(tol1) ) { - double t = (locB.first*locV.second-locB.second*locV.first)/dn; - if ( t > 0.) return false; - - double a = (locB.first!=0.) ? (t*locT.first - locV.first)/locB.first : - (t*locT.second - locV.second)/locB.second ; - if ( a < -tol2 || a-1.>tol2 ) return false; - } else { - return false; - } + /**Default Constructor - needed for persistency*/ + TriangleBounds(); + + /**Constructor with coordinates of vertices - floats*/ + TriangleBounds(const std::vector<std::pair<float, float>>&); + + /**Constructor with coordinates of vertices - double*/ + TriangleBounds(const std::vector<std::pair<double, double>>&); + + /**Constructor from three 2 Vectors */ + TriangleBounds(const Amg::Vector2D& p1, const Amg::Vector2D& p2, const Amg::Vector2D& p3); + + /**Copy constructor*/ + TriangleBounds(const TriangleBounds& tribo); + + /**Destructor*/ + virtual ~TriangleBounds(); + + /**Assignment Operator*/ + TriangleBounds& operator=(const TriangleBounds& recbo); + + /**Equality operator*/ + virtual bool operator==(const SurfaceBounds& sbo) const override; + + /**Virtual constructor*/ + virtual TriangleBounds* clone() const override; + + /** Return the type of the bounds for persistency */ + virtual BoundsType type() const override { return SurfaceBounds::Triangle; } + + /**This method checks if the provided local coordinates are inside the surface bounds*/ + virtual bool inside(const Amg::Vector2D& locpo, double tol1 = 0., double tol2 = 0.) const override; + virtual bool inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const override; + + /** This method checks inside bounds in loc1 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc1(const Amg::Vector2D& locpo, double tol1 = 0.) const override; + + /** This method checks inside bounds in loc2 + - loc1/loc2 correspond to the natural coordinates of the surface */ + virtual bool insideLoc2(const Amg::Vector2D& locpo, double tol2 = 0.) const override; + + /** Minimal distance to boundary ( > 0 if outside and <=0 if inside) */ + virtual double minDistance(const Amg::Vector2D& pos) const override; + + /**This method returns the coordinates of vertices*/ + const std::vector<std::pair<TDD_real_t, TDD_real_t>> vertices() const; + + /**This method returns the maximal extension on the local plane, i.e. @f$s\sqrt{h_{\phi}^2 + h_{\eta}^2}\f$*/ + virtual double r() const override; + + /** Output Method for MsgStream*/ + virtual MsgStream& dump(MsgStream& sl) const override; + + /** Output Method for std::ostream */ + virtual std::ostream& dump(std::ostream& sl) const override; + +private: + std::vector<TDD_real_t> m_boundValues; +}; + +inline TriangleBounds* +TriangleBounds::clone() const +{ + return new TriangleBounds(*this); +} + +inline bool +TriangleBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + std::pair<double, double> locB(m_boundValues[TriangleBounds::bv_x2] - m_boundValues[TriangleBounds::bv_x1], + m_boundValues[TriangleBounds::bv_y2] - m_boundValues[TriangleBounds::bv_y1]); + std::pair<double, double> locT(m_boundValues[TriangleBounds::bv_x3] - locpo[0], + m_boundValues[TriangleBounds::bv_y3] - locpo[1]); + std::pair<double, double> locV(m_boundValues[TriangleBounds::bv_x1] - locpo[0], + m_boundValues[TriangleBounds::bv_y1] - locpo[1]); + + // special case :: third vertex ? + if (locT.first * locT.first + locT.second * locT.second < tol1 * tol1) return true; - } - - inline bool TriangleBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const - { - if (bchk.bcType==0) return TriangleBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - // a fast FALSE - double fabsR = sqrt(locpo[Trk::locX]*locpo[Trk::locX]+locpo[Trk::locY]*locpo[Trk::locY]); - double max_ell = bchk.lCovariance(0,0) > bchk.lCovariance(1,1) ? bchk.lCovariance(0,0) :bchk.lCovariance(1,1); - double limit = bchk.nSigmas*sqrt(max_ell); - double r_max = TriangleBounds::r(); - if (fabsR > ( r_max + limit)) return false; - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(3); - std::vector<Amg::Vector2D> elementP(3); - float theta = (bchk.lCovariance(1,0) != 0 && (bchk.lCovariance(1,1)-bchk.lCovariance(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*bchk.lCovariance(1,0)/(bchk.lCovariance(1,1)-bchk.lCovariance(0,0)) ) : 0.; - sincosCache scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p << m_boundValues[TriangleBounds::bv_x1],m_boundValues[TriangleBounds::bv_y1]; - elementP[0] =( rotMatrix * (p - locpo) ); - p << m_boundValues[TriangleBounds::bv_x2],m_boundValues[TriangleBounds::bv_y2]; - elementP[1] =( rotMatrix * (p - locpo) ); - p << m_boundValues[TriangleBounds::bv_x3],m_boundValues[TriangleBounds::bv_y3]; - elementP[2] =( rotMatrix * (p - locpo) ); - std::vector<Amg::Vector2D> axis = {normal*(elementP[1]-elementP[0]), normal*(elementP[2]-elementP[1]), normal*(elementP[2]-elementP[0])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(3); - bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); - // check if KDOPs overlap and return result - return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - } - inline bool TriangleBounds::insideLoc1(const Amg::Vector2D &locpo, double tol1) const - { return inside(locpo,tol1,tol1); } - - inline bool TriangleBounds::insideLoc2(const Amg::Vector2D &locpo, double tol2) const - { return inside(locpo,tol2,tol2); } - - inline const std::vector<std::pair<TDD_real_t,TDD_real_t> > TriangleBounds::vertices() const - { std::vector< std::pair<TDD_real_t,TDD_real_t> > vertices; - vertices.resize(3); - for (size_t iv = 0; iv < 3 ; iv++) - vertices.push_back(std::pair<TDD_real_t,TDD_real_t>(m_boundValues[2*iv],m_boundValues[2*iv+1])); - return vertices; - } - - inline double TriangleBounds::r() const { - double rmax = 0.; - for (size_t iv = 0; iv < 3 ; iv++) - rmax = fmax(rmax, m_boundValues[2*iv]*m_boundValues[2*iv] + m_boundValues[2*iv+1]*m_boundValues[2*iv+1]); - return sqrt(rmax); + // special case : lies on base ? + double db = locB.first * locV.second - locB.second * locV.first; + if (fabs(db) < tol1) { + double a = (locB.first != 0) ? -locV.first / locB.first : -locV.second / locB.second; + if (a > -tol2 && a - 1. < tol2) + return true; + return false; } -} // end of namespace + double dn = locB.first * locT.second - locB.second * locT.first; + if (fabs(dn) > fabs(tol1)) { + double t = (locB.first * locV.second - locB.second * locV.first) / dn; + if (t > 0.) + return false; -#endif // TRKSURFACES_RECTANGLEBOUNDS_H + double a = + (locB.first != 0.) ? (t * locT.first - locV.first) / locB.first : (t * locT.second - locV.second) / locB.second; + if (a < -tol2 || a - 1. > tol2) + return false; + } else { + return false; + } + return true; +} + +inline bool +TriangleBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ + if (bchk.bcType == 0) + return TriangleBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + // a fast FALSE + double fabsR = sqrt(locpo[Trk::locX] * locpo[Trk::locX] + locpo[Trk::locY] * locpo[Trk::locY]); + double max_ell = bchk.lCovariance(0, 0) > bchk.lCovariance(1, 1) ? bchk.lCovariance(0, 0) : bchk.lCovariance(1, 1); + double limit = bchk.nSigmas * sqrt(max_ell); + double r_max = TriangleBounds::r(); + if (fabsR > (r_max + limit)) + return false; + + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(3); + std::vector<Amg::Vector2D> elementP(3); + float theta = (bchk.lCovariance(1, 0) != 0 && (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * bchk.lCovariance(1, 0) / (bchk.lCovariance(1, 1) - bchk.lCovariance(0, 0))) + : 0.; + sincosCache scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << m_boundValues[TriangleBounds::bv_x1], m_boundValues[TriangleBounds::bv_y1]; + elementP[0] = (rotMatrix * (p - locpo)); + p << m_boundValues[TriangleBounds::bv_x2], m_boundValues[TriangleBounds::bv_y2]; + elementP[1] = (rotMatrix * (p - locpo)); + p << m_boundValues[TriangleBounds::bv_x3], m_boundValues[TriangleBounds::bv_y3]; + elementP[2] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[1] - elementP[0]), + normal * (elementP[2] - elementP[1]), + normal * (elementP[2] - elementP[0]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(3); + bchk.ComputeKDOP(bchk.EllipseToPoly(3), axis, errelipseKDOP); + // check if KDOPs overlap and return result + return bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); +} + +inline bool +TriangleBounds::insideLoc1(const Amg::Vector2D& locpo, double tol1) const +{ + return inside(locpo, tol1, tol1); +} + +inline bool +TriangleBounds::insideLoc2(const Amg::Vector2D& locpo, double tol2) const +{ + return inside(locpo, tol2, tol2); +} + +inline const std::vector<std::pair<TDD_real_t, TDD_real_t>> +TriangleBounds::vertices() const +{ + std::vector<std::pair<TDD_real_t, TDD_real_t>> vertices; + vertices.resize(3); + for (size_t iv = 0; iv < 3; iv++) + vertices.push_back(std::pair<TDD_real_t, TDD_real_t>(m_boundValues[2 * iv], m_boundValues[2 * iv + 1])); + return vertices; +} + +inline double +TriangleBounds::r() const +{ + double rmax = 0.; + for (size_t iv = 0; iv < 3; iv++) + rmax = + fmax(rmax, m_boundValues[2 * iv] * m_boundValues[2 * iv] + m_boundValues[2 * iv + 1] * m_boundValues[2 * iv + 1]); + return sqrt(rmax); +} +} // end of namespace +#endif // TRKSURFACES_RECTANGLEBOUNDS_H diff --git a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrkSurfacesDict.h b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrkSurfacesDict.h index 907c2b2a1e4b10b7c4688d5b97d49337bfdbab8c..d93936c797ba164151edba8cd0231b0b2dd60f2e 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrkSurfacesDict.h +++ b/Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/TrkSurfacesDict.h @@ -5,26 +5,25 @@ #ifndef TRKSURFACES_TRKSURFACESDICT_H #define TRKSURFACES_TRKSURFACESDICT_H -#include "TrkSurfaces/Surface.h" -#include "TrkSurfaces/CylinderSurface.h" +#include "TrkSurfaces/AnnulusBounds.h" +#include "TrkSurfaces/ConeBounds.h" #include "TrkSurfaces/ConeSurface.h" -#include "TrkSurfaces/DiscSurface.h" -#include "TrkSurfaces/PlaneSurface.h" -#include "TrkSurfaces/PerigeeSurface.h" -#include "TrkSurfaces/StraightLineSurface.h" -#include "TrkSurfaces/SurfaceBounds.h" #include "TrkSurfaces/CylinderBounds.h" -#include "TrkSurfaces/ConeBounds.h" +#include "TrkSurfaces/CylinderSurface.h" #include "TrkSurfaces/DiamondBounds.h" #include "TrkSurfaces/DiscBounds.h" +#include "TrkSurfaces/DiscSurface.h" +#include "TrkSurfaces/DiscTrapezoidalBounds.h" #include "TrkSurfaces/EllipseBounds.h" +#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/PerigeeSurface.h" +#include "TrkSurfaces/PlaneSurface.h" #include "TrkSurfaces/RectangleBounds.h" -#include "TrkSurfaces/TriangleBounds.h" #include "TrkSurfaces/RotatedTrapezoidBounds.h" +#include "TrkSurfaces/StraightLineSurface.h" +#include "TrkSurfaces/Surface.h" +#include "TrkSurfaces/SurfaceBounds.h" #include "TrkSurfaces/TrapezoidBounds.h" -#include "TrkSurfaces/AnnulusBounds.h" -#include "TrkSurfaces/DiscTrapezoidalBounds.h" -#include "TrkSurfaces/NoBounds.h" +#include "TrkSurfaces/TriangleBounds.h" #endif - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/AnnulusBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/AnnulusBounds.cxx index e67083f2579098e31eb1a273f87e432719b1e315..85e145f43f2d4cefde5c94ba7c1181845a878994 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/AnnulusBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/AnnulusBounds.cxx @@ -6,624 +6,604 @@ // AnnulusBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/AnnulusBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <ostream> -#include <iomanip> -#include <cmath> //sin, cos etc +// STD #include <algorithm> //std::max_element +#include <cmath> //sin, cos etc +#include <iomanip> +#include <ostream> namespace { - constexpr double twoPi=2.0*M_PI; +constexpr double twoPi = 2.0 * M_PI; } // Class checking the interface of an ellipse with a circle - class EllipseCollisionTest { - private: - int m_maxIterations; - bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const { - std::vector<double> innerPolygonCoef(m_maxIterations+1); - std::vector<double> outerPolygonCoef(m_maxIterations+1); - - - for (int t = 1; t <= m_maxIterations; t++) { - int numNodes = 4 << t; - //innerPolygonCoef[t] = 0.5/std::cos(4*std::acos(0.0)/numNodes); - innerPolygonCoef[t] = 0.5/std::cos(twoPi/numNodes); - double c1x = (c0x + c2x)*innerPolygonCoef[t]; - double c1y = (c0y + c2y)*innerPolygonCoef[t]; - double tx = x - c1x; // t indicates a translated coordinate - double ty = y - c1y; - if (tx*tx + ty*ty <= rr) { - return true; // collision with t1 - } - double t2x = c2x - c1x; - double t2y = c2y - c1y; - if (tx*t2x + ty*t2y >= 0 && tx*t2x + ty*t2y <= t2x*t2x + t2y*t2y && - (ty*t2x - tx*t2y >= 0 || rr*(t2x*t2x + t2y*t2y) >= (ty*t2x - tx*t2y)*(ty*t2x - tx*t2y))) { - return true; // collision with t1---t2 - } - double t0x = c0x - c1x; - double t0y = c0y - c1y; - if (tx*t0x + ty*t0y >= 0 && tx*t0x + ty*t0y <= t0x*t0x + t0y*t0y && - (ty*t0x - tx*t0y <= 0 || rr*(t0x*t0x + t0y*t0y) >= (ty*t0x - tx*t0y)*(ty*t0x - tx*t0y))) { - return true; // collision with t1---t0 - } - outerPolygonCoef[t] = 0.5/(std::cos(M_PI/numNodes)*std::cos(M_PI/numNodes)); - double c3x = (c0x + c1x)*outerPolygonCoef[t]; - double c3y = (c0y + c1y)*outerPolygonCoef[t]; - if ((c3x-x)*(c3x-x) + (c3y-y)*(c3y-y) < rr) { - c2x = c1x; - c2y = c1y; - continue; // t3 is inside circle - } - double c4x = c1x - c3x + c1x; - double c4y = c1y - c3y + c1y; - if ((c4x-x)*(c4x-x) + (c4y-y)*(c4y-y) < rr) { - c0x = c1x; - c0y = c1y; - continue; // t4 is inside circle - } - double t3x = c3x - c1x; - double t3y = c3y - c1y; - if (ty*t3x - tx*t3y <= 0 || rr*(t3x*t3x + t3y*t3y) > (ty*t3x - tx*t3y)*(ty*t3x - tx*t3y)) { - if (tx*t3x + ty*t3y > 0) { - if (std::abs(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c3x)*(c0x-c3x) + (y-c3y)*(c0y-c3y) >= 0) { - c2x = c1x; - c2y = c1y; - continue; // circle center is inside t0---t1---t3 - } - } else if (-(tx*t3x + ty*t3y) <= t3x*t3x + t3y*t3y || (x-c4x)*(c2x-c4x) + (y-c4y)*(c2y-c4y) >= 0) { - c0x = c1x; - c0y = c1y; - continue; // circle center is inside t1---t2---t4 - } - } - return false; // no collision possible - } - return false; // out of iterations so it is unsure if there was a collision. But have to return something. - } - public: - // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of radius r at (x1, y1) - bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const { - double x = std::fabs(x1 - x0); - double y = std::fabs(y1 - y0); - -// return iterate(x, y, w, 0, 0, h, r*r); - - if (r>0) { - if (x*x + (h - y)*(h - y) <= r*r || (w - x)*(w - x) + y*y <= r*r || x*h + y*w <= w*h // collision with (0, h) - || ((x*h + y*w - w*h)*(x*h + y*w - w*h) <= r*r*(w*w + h*h) && x*w - y*h >= -h*h && x*w - y*h <= w*w)) { // collision with (0, h)---(w, 0) - return true; - } else { - if ((x-w)*(x-w) + (y-h)*(y-h) <= r*r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { - return iterate(x, y, w, 0, 0, h, r*r); // collision within triangle (0, h) (w, h) (0, 0) is possible - } - return false; - } - } - else { - double R=-r; - double localCos = x/R; - double deltaR = std::sqrt( h*h+(w*w-h*h)*localCos*localCos ); - if (deltaR<R-std::sqrt(x*x+y*y)) return false; - else return true; - } - } - EllipseCollisionTest(int maxIterations) { - this->m_maxIterations = maxIterations; - } - }; +class EllipseCollisionTest +{ +private: + int m_maxIterations; + bool iterate(double x, double y, double c0x, double c0y, double c2x, double c2y, double rr) const + { + std::vector<double> innerPolygonCoef(m_maxIterations + 1); + std::vector<double> outerPolygonCoef(m_maxIterations + 1); + + for (int t = 1; t <= m_maxIterations; t++) { + int numNodes = 4 << t; + // innerPolygonCoef[t] = 0.5/std::cos(4*std::acos(0.0)/numNodes); + innerPolygonCoef[t] = 0.5 / std::cos(twoPi / numNodes); + double c1x = (c0x + c2x) * innerPolygonCoef[t]; + double c1y = (c0y + c2y) * innerPolygonCoef[t]; + double tx = x - c1x; // t indicates a translated coordinate + double ty = y - c1y; + if (tx * tx + ty * ty <= rr) { + return true; // collision with t1 + } + double t2x = c2x - c1x; + double t2y = c2y - c1y; + if (tx * t2x + ty * t2y >= 0 && tx * t2x + ty * t2y <= t2x * t2x + t2y * t2y && + (ty * t2x - tx * t2y >= 0 || rr * (t2x * t2x + t2y * t2y) >= (ty * t2x - tx * t2y) * (ty * t2x - tx * t2y))) { + return true; // collision with t1---t2 + } + double t0x = c0x - c1x; + double t0y = c0y - c1y; + if (tx * t0x + ty * t0y >= 0 && tx * t0x + ty * t0y <= t0x * t0x + t0y * t0y && + (ty * t0x - tx * t0y <= 0 || rr * (t0x * t0x + t0y * t0y) >= (ty * t0x - tx * t0y) * (ty * t0x - tx * t0y))) { + return true; // collision with t1---t0 + } + outerPolygonCoef[t] = 0.5 / (std::cos(M_PI / numNodes) * std::cos(M_PI / numNodes)); + double c3x = (c0x + c1x) * outerPolygonCoef[t]; + double c3y = (c0y + c1y) * outerPolygonCoef[t]; + if ((c3x - x) * (c3x - x) + (c3y - y) * (c3y - y) < rr) { + c2x = c1x; + c2y = c1y; + continue; // t3 is inside circle + } + double c4x = c1x - c3x + c1x; + double c4y = c1y - c3y + c1y; + if ((c4x - x) * (c4x - x) + (c4y - y) * (c4y - y) < rr) { + c0x = c1x; + c0y = c1y; + continue; // t4 is inside circle + } + double t3x = c3x - c1x; + double t3y = c3y - c1y; + if (ty * t3x - tx * t3y <= 0 || rr * (t3x * t3x + t3y * t3y) > (ty * t3x - tx * t3y) * (ty * t3x - tx * t3y)) { + if (tx * t3x + ty * t3y > 0) { + if (std::abs(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c3x) * (c0x - c3x) + (y - c3y) * (c0y - c3y) >= 0) { + c2x = c1x; + c2y = c1y; + continue; // circle center is inside t0---t1---t3 + } + } else if (-(tx * t3x + ty * t3y) <= t3x * t3x + t3y * t3y || + (x - c4x) * (c2x - c4x) + (y - c4y) * (c2y - c4y) >= 0) { + c0x = c1x; + c0y = c1y; + continue; // circle center is inside t1---t2---t4 + } + } + return false; // no collision possible + } + return false; // out of iterations so it is unsure if there was a collision. But have to return something. + } -////////////////////////////////////////////////////////////////////////////////////////////////////////// +public: + // test for collision between an ellipse of horizontal radius w and vertical radius h at (x0, y0) and a circle of + // radius r at (x1, y1) + bool collide(double x0, double y0, double w, double h, double x1, double y1, double r) const + { + double x = std::fabs(x1 - x0); + double y = std::fabs(y1 - y0); + + // return iterate(x, y, w, 0, 0, h, r*r); + + if (r > 0) { + if (x * x + (h - y) * (h - y) <= r * r || (w - x) * (w - x) + y * y <= r * r || + x * h + y * w <= w * h // collision with (0, h) + || ((x * h + y * w - w * h) * (x * h + y * w - w * h) <= r * r * (w * w + h * h) && x * w - y * h >= -h * h && + x * w - y * h <= w * w)) { // collision with (0, h)---(w, 0) + return true; + } else { + if ((x - w) * (x - w) + (y - h) * (y - h) <= r * r || (x <= w && y - r <= h) || (y <= h && x - r <= w)) { + return iterate(x, y, w, 0, 0, h, r * r); // collision within triangle (0, h) (w, h) (0, 0) is possible + } + return false; + } + } else { + double R = -r; + double localCos = x / R; + double deltaR = std::sqrt(h * h + (w * w - h * h) * localCos * localCos); + if (deltaR < R - std::sqrt(x * x + y * y)) + return false; + else + return true; + } + } + EllipseCollisionTest(int maxIterations) { this->m_maxIterations = maxIterations; } +}; +////////////////////////////////////////////////////////////////////////////////////////////////////////// // default constructor -Trk::AnnulusBounds::AnnulusBounds() : -// Trk::SurfaceBounds() - m_boundValues(AnnulusBounds::bv_length, 0.), - m_maxYout{}, m_minYout{}, m_maxXout{}, m_minXout{}, - m_maxYin{}, m_minYin{}, m_maxXin{}, m_minXin{}, - m_k_L{}, m_k_R{}, - m_d_L{}, m_d_R{}, - m_solution_L_min{}, m_solution_L_max{}, - m_solution_R_min{}, m_solution_R_max{} { -// nop +Trk::AnnulusBounds::AnnulusBounds() + : // Trk::SurfaceBounds() + m_boundValues(AnnulusBounds::bv_length, 0.) + , m_maxYout{} + , m_minYout{} + , m_maxXout{} + , m_minXout{} + , m_maxYin{} + , m_minYin{} + , m_maxXin{} + , m_minXin{} + , m_k_L{} + , m_k_R{} + , m_d_L{} + , m_d_R{} + , m_solution_L_min{} + , m_solution_L_max{} + , m_solution_R_min{} + , m_solution_R_max{} +{ + // nop } // constructor from arguments I -Trk::AnnulusBounds::AnnulusBounds(double minR, double maxR, double R, double phi, double phiS) : - m_boundValues(AnnulusBounds::bv_length, 0.) +Trk::AnnulusBounds::AnnulusBounds(double minR, double maxR, double R, double phi, double phiS) + : m_boundValues(AnnulusBounds::bv_length, 0.) { - m_boundValues[AnnulusBounds::bv_minR] = std::fabs(minR); - m_boundValues[AnnulusBounds::bv_maxR] = std::fabs(maxR); - m_boundValues[AnnulusBounds::bv_R] = std::fabs(R); - m_boundValues[AnnulusBounds::bv_phi] = std::fabs(phi); - m_boundValues[AnnulusBounds::bv_phiS] = std::fabs(phiS); - if (m_boundValues[AnnulusBounds::bv_minR] > m_boundValues[AnnulusBounds::bv_maxR]) swap(m_boundValues[AnnulusBounds::bv_minR], m_boundValues[AnnulusBounds::bv_maxR]); - - m_k_L = std::tan( (M_PI+phi)/2. + phiS); - m_k_R = std::tan( (M_PI-phi)/2. + phiS); - - m_d_L = R*std::sin(phiS)*std::tan( (M_PI-phi)/2. - phiS) + R*(1.-std::cos(phiS)); - m_d_R = R*std::sin(phiS)*std::tan( (M_PI+phi)/2. - phiS) + R*(1.-std::cos(phiS)); - - - - - // solving quadratic equation to find four corners of the AnnulusBounds - m_solution_L_min = circleLineIntersection(minR, m_k_L, m_d_L); - m_solution_L_max = circleLineIntersection(maxR, m_k_L, m_d_L); - m_solution_R_min = circleLineIntersection(minR, m_k_R, m_d_R); - m_solution_R_max = circleLineIntersection(maxR, m_k_R, m_d_R); - - std::vector<TDD_real_t> XX; - XX.push_back (m_solution_L_min[0]); - XX.push_back (m_solution_L_max[0]); - XX.push_back (m_solution_R_min[0]); - XX.push_back (m_solution_R_max[0]); - - std::vector<TDD_real_t> YY; - YY.push_back (m_solution_L_min[1]); - YY.push_back (m_solution_L_max[1]); - YY.push_back (m_solution_R_min[1]); - YY.push_back (m_solution_R_max[1]); - YY.push_back (maxR); - - m_maxXout = *std::max_element(XX.begin(), XX.end()); - m_minXout = *std::min_element(XX.begin(), XX.end()); - m_maxYout = *std::max_element(YY.begin(), YY.end()); - m_minYout = *std::min_element(YY.begin(), YY.end()); - - m_maxXin = std::min(m_solution_R_min[0],m_solution_R_max[0]); - m_minXin = std::max(m_solution_L_min[0],m_solution_L_max[0]); - m_maxYin = std::min(m_solution_R_max[1],m_solution_L_max[1]); - m_minYin = minR; - + m_boundValues[AnnulusBounds::bv_minR] = std::fabs(minR); + m_boundValues[AnnulusBounds::bv_maxR] = std::fabs(maxR); + m_boundValues[AnnulusBounds::bv_R] = std::fabs(R); + m_boundValues[AnnulusBounds::bv_phi] = std::fabs(phi); + m_boundValues[AnnulusBounds::bv_phiS] = std::fabs(phiS); + if (m_boundValues[AnnulusBounds::bv_minR] > m_boundValues[AnnulusBounds::bv_maxR]) + swap(m_boundValues[AnnulusBounds::bv_minR], m_boundValues[AnnulusBounds::bv_maxR]); + + m_k_L = std::tan((M_PI + phi) / 2. + phiS); + m_k_R = std::tan((M_PI - phi) / 2. + phiS); + + m_d_L = R * std::sin(phiS) * std::tan((M_PI - phi) / 2. - phiS) + R * (1. - std::cos(phiS)); + m_d_R = R * std::sin(phiS) * std::tan((M_PI + phi) / 2. - phiS) + R * (1. - std::cos(phiS)); + + // solving quadratic equation to find four corners of the AnnulusBounds + m_solution_L_min = circleLineIntersection(minR, m_k_L, m_d_L); + m_solution_L_max = circleLineIntersection(maxR, m_k_L, m_d_L); + m_solution_R_min = circleLineIntersection(minR, m_k_R, m_d_R); + m_solution_R_max = circleLineIntersection(maxR, m_k_R, m_d_R); + + std::vector<TDD_real_t> XX; + XX.push_back(m_solution_L_min[0]); + XX.push_back(m_solution_L_max[0]); + XX.push_back(m_solution_R_min[0]); + XX.push_back(m_solution_R_max[0]); + + std::vector<TDD_real_t> YY; + YY.push_back(m_solution_L_min[1]); + YY.push_back(m_solution_L_max[1]); + YY.push_back(m_solution_R_min[1]); + YY.push_back(m_solution_R_max[1]); + YY.push_back(maxR); + + m_maxXout = *std::max_element(XX.begin(), XX.end()); + m_minXout = *std::min_element(XX.begin(), XX.end()); + m_maxYout = *std::max_element(YY.begin(), YY.end()); + m_minYout = *std::min_element(YY.begin(), YY.end()); + + m_maxXin = std::min(m_solution_R_min[0], m_solution_R_max[0]); + m_minXin = std::max(m_solution_L_min[0], m_solution_L_max[0]); + m_maxYin = std::min(m_solution_R_max[1], m_solution_L_max[1]); + m_minYin = minR; } // destructor -Trk::AnnulusBounds::~AnnulusBounds() -{} +Trk::AnnulusBounds::~AnnulusBounds() {} -bool Trk::AnnulusBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::AnnulusBounds::operator==(const Trk::SurfaceBounds& sbo) const { - // check the type first not to compare apples with oranges + // check the type first not to compare apples with oranges const Trk::AnnulusBounds* annbo = dynamic_cast<const Trk::AnnulusBounds*>(&sbo); - if (!annbo) return false; + if (!annbo) + return false; return (m_boundValues == annbo->m_boundValues); } // checking if inside bounds -bool Trk::AnnulusBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::AnnulusBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +{ + // a fast FALSE + double localY = locpo[Trk::locY]; + if (localY > (m_maxYout + tol2) || localY < (m_minYout - tol2)) + return false; + // a fast FALSE + double localX = locpo[Trk::locX]; + if (localX > (m_maxXout + tol1) || localX < (m_minXout - tol1)) + return false; + // a fast TRUE + if (localX > (m_minXin - tol1) && localX < (m_maxXin + tol1) && localY > (m_minYin - tol2) && + localY < (m_maxYin + tol2)) + return true; + + /////// + // if (this->minDistance(locpo)>std::max(tol1,tol2)) return false; + + double localR2 = localX * localX + localY * localY; + double localR = std::sqrt(localR2); + double localCos = localX / localR; + double localSin = localY / localR; + double deltaR = std::sqrt(tol2 * tol2 * localSin * localSin + tol1 * tol1 * localCos * localCos); -{ - // a fast FALSE - double localY = locpo[Trk::locY]; - if (localY > ( m_maxYout + tol2) || localY < ( m_minYout - tol2) ) return false; - // a fast FALSE - double localX = locpo[Trk::locX]; - if (localX > ( m_maxXout + tol1) || localX < ( m_minXout - tol1) ) return false; - // a fast TRUE - if (localX > ( m_minXin - tol1) && localX < ( m_maxXin + tol1) - && localY > ( m_minYin - tol2) && localY < ( m_maxYin + tol2) ) return true; + double minR = m_boundValues[AnnulusBounds::bv_minR]; + double maxR = m_boundValues[AnnulusBounds::bv_maxR]; + bool condRad = (localR < maxR + deltaR && localR > minR - deltaR); + bool condL = + (isRight(locpo, tol1, tol2, m_solution_L_max[0], m_solution_L_max[1], m_solution_L_min[0], m_solution_L_min[1])); + bool condR = + (isLeft(locpo, tol1, tol2, m_solution_R_max[0], m_solution_R_max[1], m_solution_R_min[0], m_solution_R_min[1])); -/////// -// if (this->minDistance(locpo)>std::max(tol1,tol2)) return false; + return (condRad && condL && condR); +} - +bool +Trk::AnnulusBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const +{ - - double localR2 = localX*localX + localY*localY; - double localR = std::sqrt(localR2); - double localCos = localX/localR; - double localSin = localY/localR; - double deltaR = std::sqrt( tol2*tol2*localSin*localSin+tol1*tol1*localCos*localCos ); + if (bchk.bcType == 0 || bchk.nSigmas == 0) + return AnnulusBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); + + sincosCache scResult = bchk.FastSinCos(locpo(1, 0)); + + EllipseCollisionTest test(4); + + Amg::Vector2D locpoCar = locpo; + AmgMatrix(2, 2) lCovarianceCar = bchk.lCovariance; + + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + double w = bchk.nSigmas * std::sqrt(lCovarianceCar(0, 0)); + double h = bchk.nSigmas * std::sqrt(lCovarianceCar(1, 1)); + + // a fast FALSE + double maxTol = std::max(w, h); + double minTol = std::min(w, h); + double localY = locpo[Trk::locY]; + if (localY > (m_maxYout + maxTol) || localY < (m_minYout - maxTol)) + return false; + // a fast FALSE + double localX = locpo[Trk::locX]; + if (localX > (m_maxXout + maxTol) || localX < (m_minXout - maxTol)) + return false; + // a fast TRUE + if (localX > (m_minXin - minTol) && localX < (m_maxXin + minTol) && localY > (m_minYin - minTol) && + localY < (m_maxYin + minTol)) + return true; + + double x0 = 0; + double y0 = 0; + float theta = (lCovarianceCar(1, 0) != 0 && (lCovarianceCar(1, 1) - lCovarianceCar(0, 0)) != 0) + ? .5 * bchk.FastArcTan(2 * lCovarianceCar(1, 0) / (lCovarianceCar(1, 1) - lCovarianceCar(0, 0))) + : 0.; + scResult = bchk.FastSinCos(theta); + AmgMatrix(2, 2) rotMatrix; + rotMatrix << scResult.cosC, scResult.sinC, -scResult.sinC, scResult.cosC; + Amg::Vector2D tmp = rotMatrix * (-locpoCar); + double x1 = tmp(0, 0); + double y1 = tmp(1, 0); + double maxR = m_boundValues[AnnulusBounds::bv_maxR]; + double minR = m_boundValues[AnnulusBounds::bv_minR]; + bool condR = (test.collide(x0, y0, w, h, x1, y1, -minR) && test.collide(x0, y0, w, h, x1, y1, maxR)); - - double minR = m_boundValues[AnnulusBounds::bv_minR]; - double maxR = m_boundValues[AnnulusBounds::bv_maxR]; + // compute KDOP and axes for surface polygon + std::vector<KDOP> elementKDOP(4); + std::vector<Amg::Vector2D> elementP(4); + AmgMatrix(2, 2) normal; + normal << 0, -1, 1, 0; + // ellipse is always at (0,0), surface is moved to ellipse position and then rotated + Amg::Vector2D p; + p << m_solution_L_min[0], m_solution_L_min[1]; + elementP[0] = (rotMatrix * (p - locpo)); - bool condRad = (localR < maxR+deltaR && localR > minR-deltaR); - bool condL = ( isRight(locpo,tol1, tol2, m_solution_L_max[0], m_solution_L_max[1], m_solution_L_min[0], m_solution_L_min[1]) ) ; - bool condR = ( isLeft(locpo,tol1, tol2, m_solution_R_max[0], m_solution_R_max[1], m_solution_R_min[0], m_solution_R_min[1]) ) ; + p << m_solution_L_max[0], m_solution_L_max[1]; + elementP[1] = (rotMatrix * (p - locpo)); - return (condRad && condL && condR); - - + p << m_solution_R_max[0], m_solution_R_max[1]; + elementP[2] = (rotMatrix * (p - locpo)); -} + p << m_solution_R_min[0], m_solution_R_min[1]; + elementP[3] = (rotMatrix * (p - locpo)); + std::vector<Amg::Vector2D> axis = { normal * (elementP[0] - elementP[1]), + normal * (elementP[1] - elementP[2]), + normal * (elementP[2] - elementP[3]), + normal * (elementP[3] - elementP[0]) }; + bchk.ComputeKDOP(elementP, axis, elementKDOP); + // compute KDOP for error ellipse + std::vector<KDOP> errelipseKDOP(4); + bchk.ComputeKDOP(bchk.EllipseToPoly(4), axis, errelipseKDOP); - bool Trk::AnnulusBounds::inside(const Amg::Vector2D& locpo, const BoundaryCheck& bchk) const - { - - if(bchk.bcType==0 || bchk.nSigmas==0 ) return AnnulusBounds::inside(locpo, bchk.toleranceLoc1, bchk.toleranceLoc2); - - - sincosCache scResult = bchk.FastSinCos(locpo(1,0)); - - - - EllipseCollisionTest test(4); - - - Amg::Vector2D locpoCar = locpo; - AmgMatrix(2,2) lCovarianceCar = bchk.lCovariance; - - - - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - double w = bchk.nSigmas*std::sqrt( lCovarianceCar(0,0)); - double h = bchk.nSigmas*std::sqrt( lCovarianceCar(1,1)); - - // a fast FALSE - double maxTol = std::max(w,h); - double minTol = std::min(w,h); - double localY = locpo[Trk::locY]; - if (localY > ( m_maxYout + maxTol) || localY < ( m_minYout - maxTol) ) return false; - // a fast FALSE - double localX = locpo[Trk::locX]; - if (localX > ( m_maxXout + maxTol) || localX < ( m_minXout - maxTol) ) return false; - // a fast TRUE - if (localX > ( m_minXin - minTol) && localX < ( m_maxXin + minTol) - && localY > ( m_minYin - minTol) && localY < ( m_maxYin + minTol) ) return true; - - - double x0 = 0; - double y0 = 0; - float theta = (lCovarianceCar(1,0) != 0 && (lCovarianceCar(1,1)-lCovarianceCar(0,0))!=0 ) ? .5*bchk.FastArcTan( 2*lCovarianceCar(1,0)/(lCovarianceCar(1,1)-lCovarianceCar(0,0)) ) : 0.; - scResult = bchk.FastSinCos(theta); - AmgMatrix(2,2) rotMatrix ; - rotMatrix << scResult.cosC, scResult.sinC, - -scResult.sinC, scResult.cosC; - Amg::Vector2D tmp = rotMatrix * (- locpoCar) ; - double x1 = tmp(0,0); - double y1 = tmp(1,0); - double maxR = m_boundValues[AnnulusBounds::bv_maxR]; - double minR = m_boundValues[AnnulusBounds::bv_minR]; - - bool condR = (test.collide(x0, y0, w, h, x1, y1, -minR) && test.collide(x0, y0, w, h, x1, y1, maxR) ); - - - - - - // compute KDOP and axes for surface polygon - std::vector<KDOP> elementKDOP(4); - std::vector<Amg::Vector2D> elementP(4); - - AmgMatrix(2,2) normal ; - normal << 0, -1, - 1, 0; - - - // ellipse is always at (0,0), surface is moved to ellipse position and then rotated - Amg::Vector2D p; - p<<m_solution_L_min[0],m_solution_L_min[1]; - elementP[0] =( rotMatrix * (p - locpo) ); - - p<<m_solution_L_max[0],m_solution_L_max[1]; - elementP[1] =( rotMatrix * (p - locpo) ); - - p<<m_solution_R_max[0],m_solution_R_max[1]; - elementP[2] =( rotMatrix * (p - locpo) ); - - p<<m_solution_R_min[0],m_solution_R_min[1]; - elementP[3] =( rotMatrix * (p - locpo) ); - - - - std::vector<Amg::Vector2D> axis = {normal*(elementP[0]-elementP[1]), normal*(elementP[1]-elementP[2]), normal*(elementP[2]-elementP[3]), normal*(elementP[3]-elementP[0])}; - bchk.ComputeKDOP(elementP, axis, elementKDOP); - // compute KDOP for error ellipse - std::vector<KDOP> errelipseKDOP(4); - bchk.ComputeKDOP(bchk.EllipseToPoly(4), axis, errelipseKDOP); - - bool condSide = bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); - - bool condLine = ( isAbove(locpo, 0, 0, m_solution_L_max[0], m_solution_L_max[1], m_solution_R_max[0], m_solution_R_max[1]) && - isRight(locpo, 0, 0, m_solution_L_max[0], m_solution_L_max[1], m_solution_L_min[0], m_solution_L_min[1]) && - isLeft(locpo, 0, 0, m_solution_R_max[0], m_solution_R_max[1], m_solution_R_min[0], m_solution_R_min[1]) ); - - - - if (condLine) return condR; - else return (condR && condSide); - - - - } + bool condSide = bchk.TestKDOPKDOP(elementKDOP, errelipseKDOP); + bool condLine = + (isAbove(locpo, 0, 0, m_solution_L_max[0], m_solution_L_max[1], m_solution_R_max[0], m_solution_R_max[1]) && + isRight(locpo, 0, 0, m_solution_L_max[0], m_solution_L_max[1], m_solution_L_min[0], m_solution_L_min[1]) && + isLeft(locpo, 0, 0, m_solution_R_max[0], m_solution_R_max[1], m_solution_R_min[0], m_solution_R_min[1])); + if (condLine) + return condR; + else + return (condR && condSide); +} // checking if local point lies above a line -bool Trk::AnnulusBounds::isAbove(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const +bool +Trk::AnnulusBounds::isAbove(const Amg::Vector2D& locpo, + double tol1, + double tol2, + double x1, + double y1, + double x2, + double y2) const { if (x2 != x1) { - double k = (y2-y1)/(x2-x1); - double d = y1-k*x1; - // the most tolerant approach for tol1 and tol2 - double sign = k > 0. ? -1. : + 1.; - return ( locpo[Trk::locY] + tol2 > (k * ( locpo[Trk::locX] + sign*tol1)+ d) ); - } - else return false; - + double k = (y2 - y1) / (x2 - x1); + double d = y1 - k * x1; + // the most tolerant approach for tol1 and tol2 + double sign = k > 0. ? -1. : +1.; + return (locpo[Trk::locY] + tol2 > (k * (locpo[Trk::locX] + sign * tol1) + d)); + } else + return false; } - // checking if local point right from a line -bool Trk::AnnulusBounds::isRight(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const +bool +Trk::AnnulusBounds::isRight(const Amg::Vector2D& locpo, + double tol1, + double tol2, + double x1, + double y1, + double x2, + double y2) const { - - if ( x1 != x2) - { - double k = (y2-y1)/(x2-x1); - double d = y1-k*x1; - - - - - if (k>0) - return (locpo[Trk::locY]< (k * locpo[Trk::locX]+ d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - else if (k<0) - return (locpo[Trk::locY]> (k * locpo[Trk::locX]+ d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - else return false; - } + + if (x1 != x2) { + double k = (y2 - y1) / (x2 - x1); + double d = y1 - k * x1; + + if (k > 0) + return (locpo[Trk::locY] < (k * locpo[Trk::locX] + d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); + else if (k < 0) + return (locpo[Trk::locY] > (k * locpo[Trk::locX] + d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); else - { - return (locpo[Trk::locX] > x1 || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - } + return false; + } else { + return (locpo[Trk::locX] > x1 || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); + } } - // checking if local point left from a line -bool Trk::AnnulusBounds::isLeft(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double x1, double y1, - double x2, double y2) const +bool +Trk::AnnulusBounds::isLeft(const Amg::Vector2D& locpo, + double tol1, + double tol2, + double x1, + double y1, + double x2, + double y2) const { - - if ( x1 != x2) - { - double k = (y2-y1)/(x2-x1); - double d = y1-k*x1; - - if (k<0) - return (locpo[Trk::locY]< (k * locpo[Trk::locX]+ d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - else if (k>0) - return (locpo[Trk::locY]> (k * locpo[Trk::locX]+ d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - else return false; - } + + if (x1 != x2) { + double k = (y2 - y1) / (x2 - x1); + double d = y1 - k * x1; + + if (k < 0) + return (locpo[Trk::locY] < (k * locpo[Trk::locX] + d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); + else if (k > 0) + return (locpo[Trk::locY] > (k * locpo[Trk::locX] + d) || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); else - { - return (locpo[Trk::locX] < x1 || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); - } + return false; + } else { + return (locpo[Trk::locX] < x1 || EllipseIntersectLine(locpo, tol1, tol2, x1, y1, x2, y2)); + } } - -double Trk::AnnulusBounds::minDistance(const Amg::Vector2D& locpo ) const +double +Trk::AnnulusBounds::minDistance(const Amg::Vector2D& locpo) const { - - // Calculate four corner points - crossings of an arc with a line + + // Calculate four corner points - crossings of an arc with a line double minR = m_boundValues[AnnulusBounds::bv_minR]; double maxR = m_boundValues[AnnulusBounds::bv_maxR]; - // distance to left and right line double distLine_L = distanceToLine(locpo, m_solution_L_min, m_solution_L_max); double distLine_R = distanceToLine(locpo, m_solution_R_min, m_solution_R_max); - + double dist = std::min(distLine_L, distLine_R); - + // calculate distance to both arcs - double distMin = distanceToArc( locpo, minR, m_solution_L_min, m_solution_R_min ); - double distMax = distanceToArc( locpo, maxR, m_solution_L_max, m_solution_R_max ); + double distMin = distanceToArc(locpo, minR, m_solution_L_min, m_solution_R_min); + double distMax = distanceToArc(locpo, maxR, m_solution_L_max, m_solution_R_max); double distArc = std::min(distMin, distMax); - - dist = std::min(dist, distArc); - - if (inside(locpo, 0., 0.)) dist = -dist; - - return dist; - -} - + dist = std::min(dist, distArc); + if (inside(locpo, 0., 0.)) + dist = -dist; + return dist; +} /** Circle and line intersection **/ -std::vector<double> Trk::AnnulusBounds::circleLineIntersection(double R, double k, double d) const +std::vector<double> +Trk::AnnulusBounds::circleLineIntersection(double R, double k, double d) const { // change k, d -> phi, d // think: which of two intersection points to chose - std::vector<double> solution; - double x1, y1, x2, y2; - - // Intersection of a line with an arc - // equation: (1+k^2)*x^2 + 2kdx +d^2 - R^2 = 0 - double delta = 4.*k*d*k*d - 4.*(1+k*k)*(d*d - R*R); - - if (delta < 0) - return solution; - else { - x1 = (-2.*k*d - std::sqrt(delta))/(2.*(1+k*k)); - x2 = (-2.*k*d + std::sqrt(delta))/(2.*(1+k*k)); - y1 = k*x1 + d; - y2 = k*x2 + d; - } - if (y1>y2) { - solution.push_back(x1); - solution.push_back(y1); - } - else { - solution.push_back(x2); - solution.push_back(y2); - } - return solution; - -} - + std::vector<double> solution; + double x1, y1, x2, y2; + + // Intersection of a line with an arc + // equation: (1+k^2)*x^2 + 2kdx +d^2 - R^2 = 0 + double delta = 4. * k * d * k * d - 4. * (1 + k * k) * (d * d - R * R); + + if (delta < 0) + return solution; + else { + x1 = (-2. * k * d - std::sqrt(delta)) / (2. * (1 + k * k)); + x2 = (-2. * k * d + std::sqrt(delta)) / (2. * (1 + k * k)); + y1 = k * x1 + d; + y2 = k * x2 + d; + } + if (y1 > y2) { + solution.push_back(x1); + solution.push_back(y1); + } else { + solution.push_back(x2); + solution.push_back(y2); + } + return solution; +} /** Distance to line */ -double Trk::AnnulusBounds::distanceToLine(const Amg::Vector2D& locpo, - std::vector<TDD_real_t> P1, - std::vector<TDD_real_t> P2) const +double +Trk::AnnulusBounds::distanceToLine(const Amg::Vector2D& locpo, + std::vector<TDD_real_t> P1, + std::vector<TDD_real_t> P2) const { - double P1x=P1[0]; - double P1y=P1[1]; - double P2x=P2[0]; - double P2y=P2[1]; - - double A = P2x-P1x; - double B = P2y-P1y; - double P3x, P3y; - - double X = locpo[Trk::locX]; - double Y = locpo[Trk::locY]; - - double u = (A*(X-P1x)+B*(Y-P1y))/(A*A+B*B); - if (u<=0) { - P3x = P1x; - P3y = P1y; - } - else if (u>=1) { - P3x = P2x; - P3y = P2y; - } - else { - P3x = P1x + u * A; - P3y = P1y + u * B; - - } - return std::sqrt( (X-P3x)*(X-P3x) + (Y-P3y)*(Y-P3y) ); - -} - - + double P1x = P1[0]; + double P1y = P1[1]; + double P2x = P2[0]; + double P2y = P2[1]; + + double A = P2x - P1x; + double B = P2y - P1y; + double P3x, P3y; + + double X = locpo[Trk::locX]; + double Y = locpo[Trk::locY]; + + double u = (A * (X - P1x) + B * (Y - P1y)) / (A * A + B * B); + if (u <= 0) { + P3x = P1x; + P3y = P1y; + } else if (u >= 1) { + P3x = P2x; + P3y = P2y; + } else { + P3x = P1x + u * A; + P3y = P1y + u * B; + } + return std::sqrt((X - P3x) * (X - P3x) + (Y - P3y) * (Y - P3y)); +} /** Distance to arc */ -double Trk::AnnulusBounds::distanceToArc(const Amg::Vector2D& locpo, - double R, std::vector<TDD_real_t> sL, std::vector<TDD_real_t> sR) const +double +Trk::AnnulusBounds::distanceToArc(const Amg::Vector2D& locpo, + double R, + std::vector<TDD_real_t> sL, + std::vector<TDD_real_t> sR) const { - - double X = locpo[Trk::locX]; - double Y = locpo[Trk::locY]; - - double tanlocPhi = X/Y; - double tanPhi_L = sL[0]/sL[1]; - double tanPhi_R = sR[0]/sR[1]; - - - if (tanlocPhi > tanPhi_L && tanlocPhi < tanPhi_R) - return std::fabs(std::sqrt(X*X+Y*Y) - R); - else - return 9999999999.; - - -} - + + double X = locpo[Trk::locX]; + double Y = locpo[Trk::locY]; + + double tanlocPhi = X / Y; + double tanPhi_L = sL[0] / sL[1]; + double tanPhi_R = sR[0] / sR[1]; + + if (tanlocPhi > tanPhi_L && tanlocPhi < tanPhi_R) + return std::fabs(std::sqrt(X * X + Y * Y) - R); + else + return 9999999999.; +} // ellipse and line intersection -bool Trk::AnnulusBounds::EllipseIntersectLine(const Amg::Vector2D& locpo, double h, double k, - double x1 , double y1 , double x2 , double y2) const +bool +Trk::AnnulusBounds::EllipseIntersectLine(const Amg::Vector2D& locpo, + double h, + double k, + double x1, + double y1, + double x2, + double y2) const { -// h, k - ellipse axis (h - horizontal, k - vertical) -// x1, y1, x2, y2 - define a line - -// Solving two equations -// x*x/(h*h) + y*y/(k*k) = 1 -// -// y = y1 + (y2-y1) * (x-x1) / (x2-x1) -// - - // fast false - if the tolerance is zero - if (h == 0 && k == 0) return false; - - - - double r, s, t, m, c, d; - - x1 = x1 - locpo[Trk::locX]; - y1 = y1 - locpo[Trk::locY]; - x2 = x2 - locpo[Trk::locX]; - y2 = y2 - locpo[Trk::locY]; + // h, k - ellipse axis (h - horizontal, k - vertical) + // x1, y1, x2, y2 - define a line - // - if ( x1 != x2) - { - m = (y2-y1)/(x2-x1); - c = y1 - m*x1; - - if (h == 0) return ( std::fabs(c) < k ); - if (k == 0) return ( std::fabs(c/m) < h ); - - r = m*m*h*h + k*k; - s = 2*m*c*h*h; - t = h*h*c*c - h*h*k*k; - - d = s*s - 4*r*t; - - } - else - { - // - // vertical line case - // - - d = std::fabs(x1) - h; - - } - - - return (d >= 0.0); //intersection if d>=0 + // Solving two equations + // x*x/(h*h) + y*y/(k*k) = 1 + // + // y = y1 + (y2-y1) * (x-x1) / (x2-x1) + // -} + // fast false - if the tolerance is zero + if (h == 0 && k == 0) + return false; + double r, s, t, m, c, d; + x1 = x1 - locpo[Trk::locX]; + y1 = y1 - locpo[Trk::locY]; + x2 = x2 - locpo[Trk::locX]; + y2 = y2 - locpo[Trk::locY]; + // + if (x1 != x2) { + m = (y2 - y1) / (x2 - x1); + c = y1 - m * x1; + if (h == 0) + return (std::fabs(c) < k); + if (k == 0) + return (std::fabs(c / m) < h); -MsgStream& Trk::AnnulusBounds::dump( MsgStream& sl ) const -{ - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::AnnulusBounds: (minR, maxR, phi) = " << "(" - << m_boundValues[AnnulusBounds::bv_minR] << ", " - << m_boundValues[AnnulusBounds::bv_maxR] << ", " - << m_boundValues[AnnulusBounds::bv_phi] << ")"; - sl << std::setprecision(-1); - return sl; + r = m * m * h * h + k * k; + s = 2 * m * c * h * h; + t = h * h * c * c - h * h * k * k; + + d = s * s - 4 * r * t; + + } else { + // + // vertical line case + // + + d = std::fabs(x1) - h; + } + + return (d >= 0.0); // intersection if d>=0 } -std::ostream& Trk::AnnulusBounds::dump( std::ostream& sl ) const +MsgStream& +Trk::AnnulusBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::AnnulusBounds: (minR, maxR, phi) = " << "(" - << m_boundValues[AnnulusBounds::bv_minR] << ", " - << m_boundValues[AnnulusBounds::bv_maxR] << ", " - << m_boundValues[AnnulusBounds::bv_phi] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::AnnulusBounds: (minR, maxR, phi) = " + << "(" << m_boundValues[AnnulusBounds::bv_minR] << ", " << m_boundValues[AnnulusBounds::bv_maxR] << ", " + << m_boundValues[AnnulusBounds::bv_phi] << ")"; + sl << std::setprecision(-1); + return sl; } +std::ostream& +Trk::AnnulusBounds::dump(std::ostream& sl) const +{ + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::AnnulusBounds: (minR, maxR, phi) = " + << "(" << m_boundValues[AnnulusBounds::bv_minR] << ", " << m_boundValues[AnnulusBounds::bv_maxR] << ", " + << m_boundValues[AnnulusBounds::bv_phi] << ")"; + sl << std::setprecision(-1); + return sl; +} diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/ConeBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/ConeBounds.cxx index 9a21ae455f657953c63d81e79da852d13013569b..fdc999c997ea131f9dd8d58a77d5b5ebb42a34d8 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/ConeBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/ConeBounds.cxx @@ -6,84 +6,83 @@ // ConeBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/ConeBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> -Trk::ConeBounds::ConeBounds() : - m_boundValues(ConeBounds::bv_length, 0.), - m_tanAlpha(0.), - m_sinAlpha(0.), - m_cosAlpha(0.) -{ -} - +Trk::ConeBounds::ConeBounds() + : m_boundValues(ConeBounds::bv_length, 0.) + , m_tanAlpha(0.) + , m_sinAlpha(0.) + , m_cosAlpha(0.) +{} -Trk::ConeBounds::ConeBounds(double alpha, bool symm, double halfphi, double avphi) : - m_boundValues(ConeBounds::bv_length, 0.), - m_tanAlpha(0.), - m_sinAlpha(0.), - m_cosAlpha(0.) +Trk::ConeBounds::ConeBounds(double alpha, bool symm, double halfphi, double avphi) + : m_boundValues(ConeBounds::bv_length, 0.) + , m_tanAlpha(0.) + , m_sinAlpha(0.) + , m_cosAlpha(0.) { - m_boundValues[ConeBounds::bv_alpha] = alpha; - m_boundValues[ConeBounds::bv_minZ] = symm ? -MAXBOUNDVALUE : 0.; - m_boundValues[ConeBounds::bv_maxZ] = MAXBOUNDVALUE; - m_boundValues[ConeBounds::bv_averagePhi] = avphi; + m_boundValues[ConeBounds::bv_alpha] = alpha; + m_boundValues[ConeBounds::bv_minZ] = symm ? -MAXBOUNDVALUE : 0.; + m_boundValues[ConeBounds::bv_maxZ] = MAXBOUNDVALUE; + m_boundValues[ConeBounds::bv_averagePhi] = avphi; m_boundValues[ConeBounds::bv_halfPhiSector] = halfphi; initCache(); } - -Trk::ConeBounds::ConeBounds(double alpha, double zmin, double zmax, double halfphi, double avphi) : - m_boundValues(ConeBounds::bv_length, 0.), - m_tanAlpha(0.), - m_sinAlpha(0.), - m_cosAlpha(0.) +Trk::ConeBounds::ConeBounds(double alpha, double zmin, double zmax, double halfphi, double avphi) + : m_boundValues(ConeBounds::bv_length, 0.) + , m_tanAlpha(0.) + , m_sinAlpha(0.) + , m_cosAlpha(0.) { - m_boundValues[ConeBounds::bv_alpha] = alpha; - m_boundValues[ConeBounds::bv_minZ] = zmin; - m_boundValues[ConeBounds::bv_maxZ] = zmax; - m_boundValues[ConeBounds::bv_averagePhi] = avphi; + m_boundValues[ConeBounds::bv_alpha] = alpha; + m_boundValues[ConeBounds::bv_minZ] = zmin; + m_boundValues[ConeBounds::bv_maxZ] = zmax; + m_boundValues[ConeBounds::bv_averagePhi] = avphi; m_boundValues[ConeBounds::bv_halfPhiSector] = halfphi; initCache(); - } -Trk::ConeBounds::ConeBounds(const Trk::ConeBounds& conebo) : - m_boundValues(conebo.m_boundValues), - m_tanAlpha(conebo.m_tanAlpha), - m_sinAlpha(conebo.m_sinAlpha), - m_cosAlpha(conebo.m_cosAlpha) +Trk::ConeBounds::ConeBounds(const Trk::ConeBounds& conebo) + : m_boundValues(conebo.m_boundValues) + , m_tanAlpha(conebo.m_tanAlpha) + , m_sinAlpha(conebo.m_sinAlpha) + , m_cosAlpha(conebo.m_cosAlpha) {} -Trk::ConeBounds::~ConeBounds() -{} +Trk::ConeBounds::~ConeBounds() {} -Trk::ConeBounds& Trk::ConeBounds::operator=(const Trk::ConeBounds& conebo) +Trk::ConeBounds& +Trk::ConeBounds::operator=(const Trk::ConeBounds& conebo) { - if(this != &conebo) { - m_tanAlpha = conebo.m_tanAlpha; - m_sinAlpha = conebo.m_sinAlpha; - m_cosAlpha = conebo.m_cosAlpha; - m_boundValues = conebo.m_boundValues; + if (this != &conebo) { + m_tanAlpha = conebo.m_tanAlpha; + m_sinAlpha = conebo.m_sinAlpha; + m_cosAlpha = conebo.m_cosAlpha; + m_boundValues = conebo.m_boundValues; } return *this; } -bool Trk::ConeBounds::operator==(const SurfaceBounds& sbo) const +bool +Trk::ConeBounds::operator==(const SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::ConeBounds* conebo = dynamic_cast<const Trk::ConeBounds*>(&sbo); - if (!conebo) return false; + if (!conebo) + return false; return (m_boundValues == conebo->m_boundValues); } -double Trk::ConeBounds::minDistance(const Amg::Vector2D& pos) const +double +Trk::ConeBounds::minDistance(const Amg::Vector2D& pos) const { // This needs to be split based on where pos is with respect to the // cone. Inside, its easy, inside the z-region or inside the phi @@ -105,7 +104,7 @@ double Trk::ConeBounds::minDistance(const Amg::Vector2D& pos) const // NB this works only if the localPos is in the same hemisphere as // the cone (i.e. if the localPos has z < 0 and the cone only // defined for z > z_min where z_min > 0, this is wrong) - double zDist = sqrt(toZ*toZ*(1.+m_tanAlpha*m_tanAlpha)); + double zDist = sqrt(toZ * toZ * (1. + m_tanAlpha * m_tanAlpha)); if (toZ < 0.) // positive if outside the cone only zDist = -zDist; @@ -119,13 +118,15 @@ double Trk::ConeBounds::minDistance(const Amg::Vector2D& pos) const // going to the correct phi by a straight line at the point that was // input by the user (not at the point of closest approach to the // cone) - double posR = pos[locZ]*m_tanAlpha; + double posR = pos[locZ] * m_tanAlpha; double deltaPhi = pos[locRPhi] / posR - m_boundValues[ConeBounds::bv_averagePhi]; // from center - if (deltaPhi > M_PI) deltaPhi = 2*M_PI - deltaPhi; - if (deltaPhi < -M_PI) deltaPhi = 2*M_PI + deltaPhi; + if (deltaPhi > M_PI) + deltaPhi = 2 * M_PI - deltaPhi; + if (deltaPhi < -M_PI) + deltaPhi = 2 * M_PI + deltaPhi; // straight line distance (goes off cone) - double phiDist = 2*posR*sin(.5*(deltaPhi-m_boundValues[ConeBounds::bv_halfPhiSector])); + double phiDist = 2 * posR * sin(.5 * (deltaPhi - m_boundValues[ConeBounds::bv_halfPhiSector])); // if inside the cone, return the smaller length (since both are // negative, the *larger* of the 2 is the *smaller* distance) @@ -137,42 +138,38 @@ double Trk::ConeBounds::minDistance(const Amg::Vector2D& pos) const } // if inside the phi or z boundary, return the other - if (phiDist <= 0.) return zDist; - if (zDist <= 0.) return phiDist; + if (phiDist <= 0.) + return zDist; + if (zDist <= 0.) + return phiDist; // otherwise, return both (this should be the distance to the corner // closest to the cone - return sqrt(zDist*zDist + phiDist*phiDist); + return sqrt(zDist * zDist + phiDist * phiDist); } // ostream operator overload -MsgStream& Trk::ConeBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::ConeBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, halfPhiSector) = "; - sl << "(" << - this->tanAlpha() << ", " << - this->minZ() << ", " << - this->maxZ() << ", " << - this->averagePhi() << ", " << - this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, halfPhiSector) = "; + sl << "(" << this->tanAlpha() << ", " << this->minZ() << ", " << this->maxZ() << ", " << this->averagePhi() << ", " + << this->halfPhiSector() << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::ConeBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::ConeBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, halfPhiSector) = "; - sl << "(" << - this->tanAlpha() << ", " << - this->minZ() << ", " << - this->maxZ() << ", " << - this->averagePhi() << ", " << - this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, halfPhiSector) = "; + sl << "(" << this->tanAlpha() << ", " << this->minZ() << ", " << this->maxZ() << ", " << this->averagePhi() << ", " + << this->halfPhiSector() << ")"; + sl << std::setprecision(-1); + return sl; } diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/ConeSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/ConeSurface.cxx index ab92f7c51f09b20c8eaa0cbbcb08f2d578c962a9..a69e601a09d89b4c9ad0e88291ed7442fe08a84b 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/ConeSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/ConeSurface.cxx @@ -9,237 +9,231 @@ // Trk #include "TrkSurfaces/ConeSurface.h" #include "TrkSurfaces/RealQuadraticEquation.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD +// STD //#include <iostream> //#include <iomanip> #include <assert.h> - // default constructor -Trk::ConeSurface::ConeSurface() : - Trk::Surface(), - m_bounds(), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface() + : Trk::Surface() + , m_bounds() + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // copy constructor -Trk::ConeSurface::ConeSurface(const ConeSurface& csf) : - Trk::Surface(csf), - m_bounds(csf.m_bounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface(const ConeSurface& csf) + : Trk::Surface(csf) + , m_bounds(csf.m_bounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // copy constructor with shift -Trk::ConeSurface::ConeSurface(const ConeSurface& csf, const Amg::Transform3D& transf) : - Trk::Surface(csf,transf), - m_bounds(csf.m_bounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface(const ConeSurface& csf, const Amg::Transform3D& transf) + : Trk::Surface(csf, transf) + , m_bounds(csf.m_bounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by opening angle and whether its symmetric or a single cone -Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, double alpha, bool symmetric) : - Trk::Surface(htrans), - m_bounds(new Trk::ConeBounds(alpha, symmetric)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, double alpha, bool symmetric) + : Trk::Surface(htrans) + , m_bounds(new Trk::ConeBounds(alpha, symmetric)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by opening angle and its z values -Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, double alpha, double zmin, double zmax, double halfPhi) : - Trk::Surface(htrans), - m_bounds(new Trk::ConeBounds(alpha, zmin, zmax, halfPhi)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, double alpha, double zmin, double zmax, double halfPhi) + : Trk::Surface(htrans) + , m_bounds(new Trk::ConeBounds(alpha, zmin, zmax, halfPhi)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} - // constructor by ConeBounds -Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, Trk::ConeBounds* cbounds): - Trk::Surface(htrans), - m_bounds(cbounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::ConeSurface::ConeSurface(Amg::Transform3D* htrans, Trk::ConeBounds* cbounds) + : Trk::Surface(htrans) + , m_bounds(cbounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) { assert(cbounds); } // constructor from transform, bounds not set. -Trk::ConeSurface::ConeSurface(std::unique_ptr<Amg::Transform3D> htrans): - Trk::Surface(std::move(htrans)), - m_bounds(nullptr), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) -{ -} +Trk::ConeSurface::ConeSurface(std::unique_ptr<Amg::Transform3D> htrans) + : Trk::Surface(std::move(htrans)) + , m_bounds(nullptr) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) +{} // destructor (will call destructor from base class which deletes objects) -Trk::ConeSurface::~ConeSurface() -{ -} +Trk::ConeSurface::~ConeSurface() {} - -Trk::ConeSurface& Trk::ConeSurface::operator=(const ConeSurface& csf) +Trk::ConeSurface& +Trk::ConeSurface::operator=(const ConeSurface& csf) { - if (this!=&csf){ - Trk::Surface::operator=(csf); - m_bounds = csf.m_bounds; - m_referencePoint.store(nullptr); - m_rotSymmetryAxis.store(nullptr); + if (this != &csf) { + Trk::Surface::operator=(csf); + m_bounds = csf.m_bounds; + m_referencePoint.store(nullptr); + m_rotSymmetryAxis.store(nullptr); } return *this; } // TODO: is the 0 always the cone center? -const Amg::Vector3D& Trk::ConeSurface::globalReferencePoint() const +const Amg::Vector3D& +Trk::ConeSurface::globalReferencePoint() const { - if (!m_referencePoint){ + if (!m_referencePoint) { // this is what was in cylinder - //double rMedium = bounds().r(); - //double phi = bounds().averagePhi(); - //Trk::GlobalPosition gp(rMedium*cos(phi), rMedium*sin(phi), 0.); - Amg::Vector3D gp(0.,0.,0.); - m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform()*gp)); - } + // double rMedium = bounds().r(); + // double phi = bounds().averagePhi(); + // Trk::GlobalPosition gp(rMedium*cos(phi), rMedium*sin(phi), 0.); + Amg::Vector3D gp(0., 0., 0.); + m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp)); + } return (*m_referencePoint); } -bool Trk::ConeSurface::operator==(const Trk::Surface& sf) const +bool +Trk::ConeSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::ConeSurface* csf = dynamic_cast<const Trk::ConeSurface*>(&sf); - if (!csf) return false; - if (this==csf) return true; - bool transfEqual(transform().isApprox(csf->transform(),10e-8)); + if (!csf) + return false; + if (this == csf) + return true; + bool transfEqual(transform().isApprox(csf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == csf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == csf->bounds()) : false; return boundsEqual; } -const Amg::Vector3D& Trk::ConeSurface::rotSymmetryAxis() const +const Amg::Vector3D& +Trk::ConeSurface::rotSymmetryAxis() const { - if (!m_rotSymmetryAxis){ - Amg::Vector3D zAxis(transform().rotation().col(2)); + if (!m_rotSymmetryAxis) { + Amg::Vector3D zAxis(transform().rotation().col(2)); m_rotSymmetryAxis.set(std::make_unique<Amg::Vector3D>(zAxis)); } - return(*m_rotSymmetryAxis); + return (*m_rotSymmetryAxis); } // return the measurement frame: it's the tangential plane -const Amg::RotationMatrix3D Trk::ConeSurface::measurementFrame(const Amg::Vector3D& pos, const Amg::Vector3D&) const +const Amg::RotationMatrix3D +Trk::ConeSurface::measurementFrame(const Amg::Vector3D& pos, const Amg::Vector3D&) const { - Amg::RotationMatrix3D mFrame; - // construct the measurement frame - Amg::Vector3D measY(transform().rotation().col(2)); // measured Y is the z axis - Amg::Vector3D measDepth = Amg::Vector3D(pos.x(), pos.y(), 0.).unit(); // measured z is the position transverse normalized - Amg::Vector3D measX(measY.cross(measDepth).unit()); // measured X is what comoes out of it - // the columnes - mFrame.col(0) = measX; - mFrame.col(1) = measY; - mFrame.col(2) = measDepth; - // return the rotation matrix - //!< @todo fold in alpha - // return it - return mFrame; + Amg::RotationMatrix3D mFrame; + // construct the measurement frame + Amg::Vector3D measY(transform().rotation().col(2)); // measured Y is the z axis + Amg::Vector3D measDepth = + Amg::Vector3D(pos.x(), pos.y(), 0.).unit(); // measured z is the position transverse normalized + Amg::Vector3D measX(measY.cross(measDepth).unit()); // measured X is what comoes out of it + // the columnes + mFrame.col(0) = measX; + mFrame.col(1) = measY; + mFrame.col(2) = measDepth; + // return the rotation matrix + //!< @todo fold in alpha + // return it + return mFrame; } - -void Trk::ConeSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +void +Trk::ConeSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const { // create the position in the local 3d frame - double r = locpos[Trk::locZ]*bounds().tanAlpha(); - double phi = locpos[Trk::locRPhi]/r; - Amg::Vector3D loc3Dframe(r*cos(phi), r*sin(phi), locpos[Trk::locZ]); + double r = locpos[Trk::locZ] * bounds().tanAlpha(); + double phi = locpos[Trk::locRPhi] / r; + Amg::Vector3D loc3Dframe(r * cos(phi), r * sin(phi), locpos[Trk::locZ]); // transport it to the globalframe - glopos = transform()*loc3Dframe; + glopos = transform() * loc3Dframe; } -bool Trk::ConeSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +bool +Trk::ConeSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const { - const Amg::Transform3D& surfaceTrans = transform(); - Amg::Transform3D inverseTrans(surfaceTrans.inverse()); - Amg::Vector3D loc3Dframe(inverseTrans*glopos); - double r = loc3Dframe.z()*bounds().tanAlpha(); - locpos = Amg::Vector2D(r*atan2(loc3Dframe.y(), loc3Dframe.x()), loc3Dframe.z()); - // now decide on the quility of the transformation - //double inttol = r*0.0001; - //inttol = (inttol<0.01) ? 0.01 : 0.01; // ? - double inttol = 0.01; - return ( ( (loc3Dframe.perp() - r) > inttol ) ? false : true ); + const Amg::Transform3D& surfaceTrans = transform(); + Amg::Transform3D inverseTrans(surfaceTrans.inverse()); + Amg::Vector3D loc3Dframe(inverseTrans * glopos); + double r = loc3Dframe.z() * bounds().tanAlpha(); + locpos = Amg::Vector2D(r * atan2(loc3Dframe.y(), loc3Dframe.x()), loc3Dframe.z()); + // now decide on the quility of the transformation + // double inttol = r*0.0001; + // inttol = (inttol<0.01) ? 0.01 : 0.01; // ? + double inttol = 0.01; + return (((loc3Dframe.perp() - r) > inttol) ? false : true); } - -Trk::Intersection Trk::ConeSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const +Trk::Intersection +Trk::ConeSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const { - // transform to a frame with the cone along z, with the tip at 0 - Amg::Vector3D tpos1 = transform().inverse()*pos; - Amg::Vector3D tdir = transform().inverse().linear()*dir; - // see the header for the formula derivation - double - tan2Alpha = bounds().tanAlpha() * - bounds().tanAlpha(), - A = tdir.x()*tdir.x() + - tdir.y()*tdir.y() - - tan2Alpha*tdir.z()*tdir.z(), - B = 2*(tdir.x()*tpos1.x() + - tdir.y()*tpos1.y() - - tan2Alpha*dir.z()*tpos1.z()), - C = tpos1.x()*tpos1.x() + - tpos1.y()*tpos1.y() - - tan2Alpha*tpos1.z()*tpos1.z(); - if (A == 0.) A += 1e-16; // avoid div by zero - - // use Andreas' quad solver, much more stable than what I wrote - Trk::RealQuadraticEquation solns(A,B,C); - - Amg::Vector3D solution (0.,0.,0.); - double path = 0.; - bool isValid = false; - if (solns.solutions != Trk::none) { - double t1 = solns.first; - Amg::Vector3D soln1Loc(tpos1 + t1 * dir); - isValid = forceDir ? ( t1 > 0. ) : true; - // there's only one solution - if (solns.solutions == Trk::one){ - solution = soln1Loc; - path = t1; - } else { - double t2 = solns.second; - Amg::Vector3D soln2Loc(tpos1 + t2 * dir); - // both solutions have the same sign - if (t1*t2 > 0. || !forceDir) { - if (t1*t1 < t2*t2) { - solution = soln1Loc; - path = t1; - } else { - solution = soln2Loc; - path = t2; - } - } else { - if (t1 > 0.) { - solution = soln1Loc; - path = t1; - } else { - solution = soln2Loc; - path = t2; - } - } - } - } - solution = transform()*solution; - - isValid = bchk ? (isValid && isOnSurface(solution)) : isValid; - return Trk::Intersection(solution,path,isValid); -} + // transform to a frame with the cone along z, with the tip at 0 + Amg::Vector3D tpos1 = transform().inverse() * pos; + Amg::Vector3D tdir = transform().inverse().linear() * dir; + // see the header for the formula derivation + double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha(), + A = tdir.x() * tdir.x() + tdir.y() * tdir.y() - tan2Alpha * tdir.z() * tdir.z(), + B = 2 * (tdir.x() * tpos1.x() + tdir.y() * tpos1.y() - tan2Alpha * dir.z() * tpos1.z()), + C = tpos1.x() * tpos1.x() + tpos1.y() * tpos1.y() - tan2Alpha * tpos1.z() * tpos1.z(); + if (A == 0.) + A += 1e-16; // avoid div by zero + // use Andreas' quad solver, much more stable than what I wrote + Trk::RealQuadraticEquation solns(A, B, C); + + Amg::Vector3D solution(0., 0., 0.); + double path = 0.; + bool isValid = false; + if (solns.solutions != Trk::none) { + double t1 = solns.first; + Amg::Vector3D soln1Loc(tpos1 + t1 * dir); + isValid = forceDir ? (t1 > 0.) : true; + // there's only one solution + if (solns.solutions == Trk::one) { + solution = soln1Loc; + path = t1; + } else { + double t2 = solns.second; + Amg::Vector3D soln2Loc(tpos1 + t2 * dir); + // both solutions have the same sign + if (t1 * t2 > 0. || !forceDir) { + if (t1 * t1 < t2 * t2) { + solution = soln1Loc; + path = t1; + } else { + solution = soln2Loc; + path = t2; + } + } else { + if (t1 > 0.) { + solution = soln1Loc; + path = t1; + } else { + solution = soln2Loc; + path = t2; + } + } + } + } + solution = transform() * solution; + isValid = bchk ? (isValid && isOnSurface(solution)) : isValid; + return Trk::Intersection(solution, path, isValid); +} /** distance to surface */ @@ -247,94 +241,90 @@ Trk::Intersection Trk::ConeSurface::straightLineIntersection(const Amg::Vector3D // because i really don't see what the idea is here vs. the other // straightLineDistanceEstimate, and this is harder to see whats // happening. -Trk::DistanceSolution Trk::ConeSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::ConeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { - return straightLineDistanceEstimate(pos,dir,false); + return straightLineDistanceEstimate(pos, dir, false); } - -Trk::DistanceSolution Trk::ConeSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos, const Amg::Vector3D& dir,bool bound) const +Trk::DistanceSolution +Trk::ConeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool bound) const { double tol = 0.001; - Amg::Vector3D Cntr = center(); // tip of the cone (i.e. join between halves) - Amg::Vector3D N = normal(); // this is the z-direction of the cone in - // global coordiantes i believe + Amg::Vector3D Cntr = center(); // tip of the cone (i.e. join between halves) + Amg::Vector3D N = normal(); // this is the z-direction of the cone in + // global coordiantes i believe Amg::Vector3D dPos = pos - Cntr; // pos w.r.t. cone tip - double - posLength = sqrt(dPos.dot(dPos)); + double posLength = sqrt(dPos.dot(dPos)); if (posLength < tol) // at origin of cone => on cone (avoid div by zero) - return Trk::DistanceSolution(1,0.,true,0.); - double - posProj = dPos.dot(N), - posProjAngle = acos(posProj/posLength); - double currDist = posLength*sin(posProjAngle-atan(bounds().tanAlpha())); + return Trk::DistanceSolution(1, 0., true, 0.); + double posProj = dPos.dot(N), posProjAngle = acos(posProj / posLength); + double currDist = posLength * sin(posProjAngle - atan(bounds().tanAlpha())); // solution on the surface - if (fabs(currDist) < tol) return Trk::DistanceSolution(1,currDist,true,0.); + if (fabs(currDist) < tol) + return Trk::DistanceSolution(1, currDist, true, 0.); // transform to a frame with the cone along z, with the tip a 0 Amg::Vector3D locFramePos = transform().inverse() * pos; Amg::Vector3D locFrameDir = transform().rotation().inverse() * dir.normalized(); // solutions are in the form of a solution to a quadratic eqn. - double - tan2Alpha = bounds().tanAlpha()*bounds().tanAlpha(), - A = locFrameDir.x()*locFrameDir.x() + - locFrameDir.y()*locFrameDir.y() - - tan2Alpha*locFrameDir.z()*locFrameDir.z(), - B = 2*(locFrameDir.x()*locFramePos.x() + - locFrameDir.y()*locFramePos.y() - - tan2Alpha*locFrameDir.z()*locFramePos.z()), - C = locFramePos.x()*locFramePos.x() + - locFramePos.y()*locFramePos.y() - - tan2Alpha*locFramePos.z()*locFramePos.z(); - if (A == 0.) A += 1e-16; // avoid div by zero + double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha(), + A = locFrameDir.x() * locFrameDir.x() + locFrameDir.y() * locFrameDir.y() - + tan2Alpha * locFrameDir.z() * locFrameDir.z(), + B = 2 * (locFrameDir.x() * locFramePos.x() + locFrameDir.y() * locFramePos.y() - + tan2Alpha * locFrameDir.z() * locFramePos.z()), + C = locFramePos.x() * locFramePos.x() + locFramePos.y() * locFramePos.y() - + tan2Alpha * locFramePos.z() * locFramePos.z(); + if (A == 0.) + A += 1e-16; // avoid div by zero // use Andreas' quad solver, much more stable than what I wrote - Trk::RealQuadraticEquation solns(A,B,C); + Trk::RealQuadraticEquation solns(A, B, C); double d2bound = 0.; if (bound && solns.solutions != Trk::none) { - const Amg::Vector2D *p = 0; + const Amg::Vector2D* p = 0; if (fabs(solns.first) < fabs(solns.second)) - p = Surface::globalToLocal(locFramePos + solns.first*locFrameDir); + p = Surface::globalToLocal(locFramePos + solns.first * locFrameDir); else - p = Surface::globalToLocal(locFramePos + solns.second*locFrameDir); + p = Surface::globalToLocal(locFramePos + solns.second * locFrameDir); if (p) { - d2bound= bounds().minDistance(*p); + d2bound = bounds().minDistance(*p); delete p; } - if (d2bound < 0) d2bound = 0; + if (d2bound < 0) + d2bound = 0; } - double totDist = d2bound > 0. ? sqrt(d2bound*d2bound + currDist*currDist) : currDist; + double totDist = d2bound > 0. ? sqrt(d2bound * d2bound + currDist * currDist) : currDist; - switch(solns.solutions) { + switch (solns.solutions) { case Trk::none: - return Trk::DistanceSolution(0,totDist,true,0.,0.); + return Trk::DistanceSolution(0, totDist, true, 0., 0.); case Trk::one: - return Trk::DistanceSolution(1,totDist,true,solns.first); + return Trk::DistanceSolution(1, totDist, true, solns.first); case Trk::two: if (fabs(solns.first) < fabs(solns.second)) - return Trk::DistanceSolution(2,totDist,true,solns.first,solns.second); - return Trk::DistanceSolution(2,totDist,true,solns.second,solns.first); + return Trk::DistanceSolution(2, totDist, true, solns.first, solns.second); + return Trk::DistanceSolution(2, totDist, true, solns.second, solns.first); default: - return Trk::DistanceSolution(0,totDist,true,0.,0.); + return Trk::DistanceSolution(0, totDist, true, 0., 0.); }; } -double Trk::ConeSurface::pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const { - // (cos phi cos alpha, sin phi cos alpha, sgn z sin alpha) - bool applyTransform = !(transform().isApprox(Amg::Transform3D::Identity())); - Amg::Vector3D posLocal = applyTransform ? transform().inverse()*pos : pos; - double phi = posLocal.phi(); - double sgn = posLocal.z() > 0. ? -1. : +1.; - Amg::Vector3D normalC(cos(phi) * bounds().cosAlpha(), - sin(phi) * bounds().cosAlpha(), - sgn*bounds().sinAlpha()); - if (applyTransform) normalC = transform()*normalC; - // back in global frame - double cAlpha = normalC.dot(mom.unit()); - return ( cAlpha!=0.) ? fabs(1./cAlpha) : 1.; //ST undefined for cAlpha=0 +double +Trk::ConeSurface::pathCorrection(const Amg::Vector3D& pos, const Amg::Vector3D& mom) const +{ + // (cos phi cos alpha, sin phi cos alpha, sgn z sin alpha) + bool applyTransform = !(transform().isApprox(Amg::Transform3D::Identity())); + Amg::Vector3D posLocal = applyTransform ? transform().inverse() * pos : pos; + double phi = posLocal.phi(); + double sgn = posLocal.z() > 0. ? -1. : +1.; + Amg::Vector3D normalC(cos(phi) * bounds().cosAlpha(), sin(phi) * bounds().cosAlpha(), sgn * bounds().sinAlpha()); + if (applyTransform) + normalC = transform() * normalC; + // back in global frame + double cAlpha = normalC.dot(mom.unit()); + return (cAlpha != 0.) ? fabs(1. / cAlpha) : 1.; // ST undefined for cAlpha=0 } diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderBounds.cxx index 1f7e116f0bdc6da7338e005f25a3c353111c1bf0..99be4eab04dcff9a73b68865a892c05aa129f80d 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderBounds.cxx @@ -6,125 +6,131 @@ // CylinderBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/CylinderBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> -Trk::CylinderBounds::CylinderBounds() : - m_boundValues(CylinderBounds::bv_length, 0.), - m_checkPhi(false) +Trk::CylinderBounds::CylinderBounds() + : m_boundValues(CylinderBounds::bv_length, 0.) + , m_checkPhi(false) {} -Trk::CylinderBounds::CylinderBounds(double radius, double halez) : - m_boundValues(CylinderBounds::bv_length, 0.), - m_checkPhi(false) +Trk::CylinderBounds::CylinderBounds(double radius, double halez) + : m_boundValues(CylinderBounds::bv_length, 0.) + , m_checkPhi(false) { - m_boundValues[CylinderBounds::bv_radius] = fabs(radius); - m_boundValues[CylinderBounds::bv_halfPhiSector] = M_PI; - m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); + m_boundValues[CylinderBounds::bv_radius] = fabs(radius); + m_boundValues[CylinderBounds::bv_halfPhiSector] = M_PI; + m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); } -Trk::CylinderBounds::CylinderBounds(double radius, double haphi, double halez) : - m_boundValues(CylinderBounds::bv_length, 0.), - m_checkPhi(true) +Trk::CylinderBounds::CylinderBounds(double radius, double haphi, double halez) + : m_boundValues(CylinderBounds::bv_length, 0.) + , m_checkPhi(true) { - m_boundValues[CylinderBounds::bv_radius] = fabs(radius); - m_boundValues[CylinderBounds::bv_halfPhiSector] = haphi; - m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); + m_boundValues[CylinderBounds::bv_radius] = fabs(radius); + m_boundValues[CylinderBounds::bv_halfPhiSector] = haphi; + m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); } -Trk::CylinderBounds::CylinderBounds(double radius, double haphi, double averagephi, double halez) : - m_boundValues(CylinderBounds::bv_length, 0.), - m_checkPhi(true) +Trk::CylinderBounds::CylinderBounds(double radius, double haphi, double averagephi, double halez) + : m_boundValues(CylinderBounds::bv_length, 0.) + , m_checkPhi(true) { - m_boundValues[CylinderBounds::bv_radius] = fabs(radius); - m_boundValues[CylinderBounds::bv_averagePhi] = averagephi; - m_boundValues[CylinderBounds::bv_halfPhiSector] = haphi; - m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); + m_boundValues[CylinderBounds::bv_radius] = fabs(radius); + m_boundValues[CylinderBounds::bv_averagePhi] = averagephi; + m_boundValues[CylinderBounds::bv_halfPhiSector] = haphi; + m_boundValues[CylinderBounds::bv_halfZ] = fabs(halez); } -Trk::CylinderBounds::CylinderBounds(const Trk::CylinderBounds& cylbo) : - Trk::SurfaceBounds(), - m_boundValues(cylbo.m_boundValues), - m_checkPhi(cylbo.m_checkPhi) +Trk::CylinderBounds::CylinderBounds(const Trk::CylinderBounds& cylbo) + : Trk::SurfaceBounds() + , m_boundValues(cylbo.m_boundValues) + , m_checkPhi(cylbo.m_checkPhi) {} -Trk::CylinderBounds::~CylinderBounds() -{} +Trk::CylinderBounds::~CylinderBounds() {} -Trk::CylinderBounds& Trk::CylinderBounds::operator=(const Trk::CylinderBounds& cylbo) +Trk::CylinderBounds& +Trk::CylinderBounds::operator=(const Trk::CylinderBounds& cylbo) { - if (this!=&cylbo) { + if (this != &cylbo) { m_boundValues = cylbo.m_boundValues; m_checkPhi = cylbo.m_checkPhi; } return *this; } -Trk::CylinderBounds& Trk::CylinderBounds::operator=(Trk::CylinderBounds&& cylbo) +Trk::CylinderBounds& +Trk::CylinderBounds::operator=(Trk::CylinderBounds&& cylbo) { - if (this!=&cylbo) { + if (this != &cylbo) { m_boundValues = std::move(cylbo.m_boundValues); m_checkPhi = cylbo.m_checkPhi; } return *this; } -bool Trk::CylinderBounds::operator==(const SurfaceBounds& sbo) const +bool +Trk::CylinderBounds::operator==(const SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::CylinderBounds* cylbo = dynamic_cast<const Trk::CylinderBounds*>(&sbo); - if (!cylbo) return false; + if (!cylbo) + return false; return (m_boundValues == cylbo->m_boundValues); } -double Trk::CylinderBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::CylinderBounds::minDistance(const Amg::Vector2D& pos) const { - const double pi2 = 2.*M_PI; - - double sZ = fabs(pos[locZ])-m_boundValues[CylinderBounds::bv_halfZ]; - double wF = m_boundValues[CylinderBounds::bv_halfPhiSector]; if(wF >= M_PI) return sZ; - double dF = fabs(pos[locRPhi]/m_boundValues[CylinderBounds::bv_radius]-m_boundValues[CylinderBounds::bv_averagePhi]); if(dF>M_PI) dF=pi2-dF; - double sF = 2.*m_boundValues[CylinderBounds::bv_radius]*sin(.5* (dF-wF)); - - if(sF <= 0. || sZ <= 0.) { - if (sF > sZ) return sF; - else return sZ; + const double pi2 = 2. * M_PI; + + double sZ = fabs(pos[locZ]) - m_boundValues[CylinderBounds::bv_halfZ]; + double wF = m_boundValues[CylinderBounds::bv_halfPhiSector]; + if (wF >= M_PI) + return sZ; + double dF = + fabs(pos[locRPhi] / m_boundValues[CylinderBounds::bv_radius] - m_boundValues[CylinderBounds::bv_averagePhi]); + if (dF > M_PI) + dF = pi2 - dF; + double sF = 2. * m_boundValues[CylinderBounds::bv_radius] * sin(.5 * (dF - wF)); + + if (sF <= 0. || sZ <= 0.) { + if (sF > sZ) + return sF; + else + return sZ; } - return sqrt(sF*sF+sZ*sZ); + return sqrt(sF * sF + sZ * sZ); } - // ostream operator overload -MsgStream& Trk::CylinderBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::CylinderBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::CylinderBounds: (radius, averagePhi, halfPhiSector, halflengthInZ) = "; - sl << "(" << this->r() << ", " << this->averagePhi() << ", "; - sl << this->halfPhiSector() << ", " << this->halflengthZ() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::CylinderBounds: (radius, averagePhi, halfPhiSector, halflengthInZ) = "; + sl << "(" << this->r() << ", " << this->averagePhi() << ", "; + sl << this->halfPhiSector() << ", " << this->halflengthZ() << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::CylinderBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::CylinderBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::CylinderBounds: (radius, averagePhi, halfPhiSector, halflengthInZ) = "; - sl << "(" << this->r() << ", " << this->averagePhi() << ", "; - sl << this->halfPhiSector() << ", " << this->halflengthZ() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::CylinderBounds: (radius, averagePhi, halfPhiSector, halflengthInZ) = "; + sl << "(" << this->r() << ", " << this->averagePhi() << ", "; + sl << this->halfPhiSector() << ", " << this->halflengthZ() << ")"; + sl << std::setprecision(-1); + return sl; } - - - - - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx index 82f78f2b21483fb21211c4930edada10f4048290..6c5f575dcf834564a3fbd7009e7f36e87983786f 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/CylinderSurface.cxx @@ -8,132 +8,135 @@ // Trk #include "TrkSurfaces/CylinderSurface.h" -#include "TrkSurfaces/RealQuadraticEquation.h" #include "CxxUtils/unused.h" -//Gaudi +#include "TrkSurfaces/RealQuadraticEquation.h" +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> -#include <iomanip> +// STD #include <assert.h> +#include <iomanip> +#include <iostream> // default constructor -Trk::CylinderSurface::CylinderSurface() : - Trk::Surface(), - m_bounds(), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface() + : Trk::Surface() + , m_bounds() + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // copy constructor -Trk::CylinderSurface::CylinderSurface(const CylinderSurface& csf) : - Trk::Surface(csf), - m_bounds(csf.m_bounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(const CylinderSurface& csf) + : Trk::Surface(csf) + , m_bounds(csf.m_bounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // copy constructor with shift -Trk::CylinderSurface::CylinderSurface(const CylinderSurface& csf, const Amg::Transform3D& transf) : - Trk::Surface(csf, transf), - m_bounds(csf.m_bounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(const CylinderSurface& csf, const Amg::Transform3D& transf) + : Trk::Surface(csf, transf) + , m_bounds(csf.m_bounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by radius and halflength -Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, double radius, double hlength) : - Trk::Surface(htrans), - m_bounds(new Trk::CylinderBounds(radius, hlength)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, double radius, double hlength) + : Trk::Surface(htrans) + , m_bounds(new Trk::CylinderBounds(radius, hlength)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by radius, halflenght and phisector -Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, double radius, double hphi, double hlength) : - Trk::Surface(htrans), - m_bounds(new Trk::CylinderBounds(radius, hphi, hlength)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, double radius, double hphi, double hlength) + : Trk::Surface(htrans) + , m_bounds(new Trk::CylinderBounds(radius, hphi, hlength)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by CylinderBounds -Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, Trk::CylinderBounds* cbounds): - Trk::Surface(htrans), - m_bounds(cbounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(Amg::Transform3D* htrans, Trk::CylinderBounds* cbounds) + : Trk::Surface(htrans) + , m_bounds(cbounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) { assert(cbounds); } // constructor from transform by unique_ptr -Trk::CylinderSurface::CylinderSurface(std::unique_ptr<Amg::Transform3D> htrans): - Trk::Surface(std::move(htrans)), - m_bounds(nullptr), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) -{ -} +Trk::CylinderSurface::CylinderSurface(std::unique_ptr<Amg::Transform3D> htrans) + : Trk::Surface(std::move(htrans)) + , m_bounds(nullptr) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) +{} // constructor by radius and halflength -Trk::CylinderSurface::CylinderSurface(double radius, double hlength) : - Trk::Surface(0), - m_bounds(new Trk::CylinderBounds(radius, hlength)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(double radius, double hlength) + : Trk::Surface(0) + , m_bounds(new Trk::CylinderBounds(radius, hlength)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by radius, halflenght and phisector -Trk::CylinderSurface::CylinderSurface(double radius, double hphi, double hlength) : - Trk::Surface(0), - m_bounds(new Trk::CylinderBounds(radius, hphi, hlength)), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(double radius, double hphi, double hlength) + : Trk::Surface(0) + , m_bounds(new Trk::CylinderBounds(radius, hphi, hlength)) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) {} // constructor by CylinderBounds -Trk::CylinderSurface::CylinderSurface(Trk::CylinderBounds* cbounds): - Trk::Surface(), - m_bounds(cbounds), - m_referencePoint(nullptr), - m_rotSymmetryAxis(nullptr) +Trk::CylinderSurface::CylinderSurface(Trk::CylinderBounds* cbounds) + : Trk::Surface() + , m_bounds(cbounds) + , m_referencePoint(nullptr) + , m_rotSymmetryAxis(nullptr) { assert(cbounds); } // destructor (will call destructor from base class which deletes objects) -Trk::CylinderSurface::~CylinderSurface() -{ -} +Trk::CylinderSurface::~CylinderSurface() {} -Trk::CylinderSurface& Trk::CylinderSurface::operator=(const CylinderSurface& csf) +Trk::CylinderSurface& +Trk::CylinderSurface::operator=(const CylinderSurface& csf) { - if (this!=&csf){ - Trk::Surface::operator=(csf); - m_bounds = csf.m_bounds; - m_referencePoint.store(nullptr); - m_rotSymmetryAxis.store(nullptr); + if (this != &csf) { + Trk::Surface::operator=(csf); + m_bounds = csf.m_bounds; + m_referencePoint.store(nullptr); + m_rotSymmetryAxis.store(nullptr); } return *this; } -const Amg::Vector3D& Trk::CylinderSurface::globalReferencePoint() const -{ if (!m_referencePoint){ - double rMedium = bounds().r(); - double phi = bounds().averagePhi(); - Amg::Vector3D gp(rMedium*cos(phi), rMedium*sin(phi), 0.); - m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform()*gp)); - } +const Amg::Vector3D& +Trk::CylinderSurface::globalReferencePoint() const +{ + if (!m_referencePoint) { + double rMedium = bounds().r(); + double phi = bounds().averagePhi(); + Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.); + m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp)); + } return (*m_referencePoint); } -bool Trk::CylinderSurface::operator==(const Trk::Surface& sf) const +bool +Trk::CylinderSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::CylinderSurface* csf = dynamic_cast<const Trk::CylinderSurface*>(&sf); - if (!csf) return false; - if (this==csf) return true; + if (!csf) + return false; + if (this == csf) + return true; bool transfEqual(transform().isApprox(csf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == csf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == csf->bounds()) : false; @@ -141,187 +144,192 @@ bool Trk::CylinderSurface::operator==(const Trk::Surface& sf) const } // return the measurement frame: it's the tangential plane -const Amg::RotationMatrix3D Trk::CylinderSurface::measurementFrame(const Amg::Vector3D& pos, const Amg::Vector3D&) const +const Amg::RotationMatrix3D +Trk::CylinderSurface::measurementFrame(const Amg::Vector3D& pos, const Amg::Vector3D&) const { - Amg::RotationMatrix3D mFrame; - // construct the measurement frame - Amg::Vector3D measY(transform().rotation().col(2)); // measured Y is the z axis - Amg::Vector3D measDepth = Amg::Vector3D(pos.x(), pos.y(), 0.).unit(); // measured z is the position transverse normalized - Amg::Vector3D measX(measY.cross(measDepth).unit()); // measured X is what comoes out of it - // the columnes - mFrame.col(0) = measX; - mFrame.col(1) = measY; - mFrame.col(2) = measDepth; - // return the rotation matrix - return mFrame; + Amg::RotationMatrix3D mFrame; + // construct the measurement frame + Amg::Vector3D measY(transform().rotation().col(2)); // measured Y is the z axis + Amg::Vector3D measDepth = + Amg::Vector3D(pos.x(), pos.y(), 0.).unit(); // measured z is the position transverse normalized + Amg::Vector3D measX(measY.cross(measDepth).unit()); // measured X is what comoes out of it + // the columnes + mFrame.col(0) = measX; + mFrame.col(1) = measY; + mFrame.col(2) = measDepth; + // return the rotation matrix + return mFrame; } - -const Amg::Vector3D& Trk::CylinderSurface::rotSymmetryAxis() const +const Amg::Vector3D& +Trk::CylinderSurface::rotSymmetryAxis() const { - if (!m_rotSymmetryAxis){ - Amg::Vector3D zAxis(transform().rotation().col(2)); - m_rotSymmetryAxis.set(std::make_unique<Amg::Vector3D>(zAxis)); + if (!m_rotSymmetryAxis) { + Amg::Vector3D zAxis(transform().rotation().col(2)); + m_rotSymmetryAxis.set(std::make_unique<Amg::Vector3D>(zAxis)); } - return(*m_rotSymmetryAxis); + return (*m_rotSymmetryAxis); } -void Trk::CylinderSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +void +Trk::CylinderSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const { - // create the position in the local 3d frame - double r = bounds().r(); - double phi = locpos[Trk::locRPhi]/r; - glopos = Amg::Vector3D(r*cos(phi), r*sin(phi), locpos[Trk::locZ]); - // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform - if (Trk::Surface::m_transform) glopos = transform()*glopos; + // create the position in the local 3d frame + double r = bounds().r(); + double phi = locpos[Trk::locRPhi] / r; + glopos = Amg::Vector3D(r * cos(phi), r * sin(phi), locpos[Trk::locZ]); + // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform + if (Trk::Surface::m_transform) + glopos = transform() * glopos; } -bool Trk::CylinderSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const { - // get the transform & transform global position into cylinder frame - // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform - double radius = 0.; - double inttol = bounds().r()*0.0001; - if ( inttol < 0.01) inttol = 0.01; - // do the transformation or not - if (Trk::Surface::m_transform) { - const Amg::Transform3D& surfaceTrans = transform(); - Amg::Transform3D inverseTrans(surfaceTrans.inverse()); - Amg::Vector3D loc3Dframe(inverseTrans*glopos); - locpos = Amg::Vector2D(bounds().r()*loc3Dframe.phi(), loc3Dframe.z()); - radius = loc3Dframe.perp(); - } else { - locpos = Amg::Vector2D(bounds().r()*glopos.phi(), glopos.z()); - radius = glopos.perp(); - } - // return true or false - return (( fabs(radius - bounds().r()) > inttol) ? false : true ); +bool +Trk::CylinderSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +{ + // get the transform & transform global position into cylinder frame + // transform it to the globalframe: CylinderSurfaces are allowed to have 0 pointer transform + double radius = 0.; + double inttol = bounds().r() * 0.0001; + if (inttol < 0.01) + inttol = 0.01; + // do the transformation or not + if (Trk::Surface::m_transform) { + const Amg::Transform3D& surfaceTrans = transform(); + Amg::Transform3D inverseTrans(surfaceTrans.inverse()); + Amg::Vector3D loc3Dframe(inverseTrans * glopos); + locpos = Amg::Vector2D(bounds().r() * loc3Dframe.phi(), loc3Dframe.z()); + radius = loc3Dframe.perp(); + } else { + locpos = Amg::Vector2D(bounds().r() * glopos.phi(), glopos.z()); + radius = glopos.perp(); + } + // return true or false + return ((fabs(radius - bounds().r()) > inttol) ? false : true); } - -bool Trk::CylinderSurface::isOnSurface(const Amg::Vector3D& glopo, - Trk::BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::CylinderSurface::isOnSurface(const Amg::Vector3D& glopo, Trk::BoundaryCheck bchk, double tol1, double tol2) const { - Amg::Vector3D loc3Dframe = Trk::Surface::m_transform ? (transform().inverse())*glopo : glopo; - return ( bchk ? bounds().inside3D(loc3Dframe,tol1+s_onSurfaceTolerance,tol2+s_onSurfaceTolerance) : true ); + Amg::Vector3D loc3Dframe = Trk::Surface::m_transform ? (transform().inverse()) * glopo : glopo; + return (bchk ? bounds().inside3D(loc3Dframe, tol1 + s_onSurfaceTolerance, tol2 + s_onSurfaceTolerance) : true); } - -Trk::Intersection Trk::CylinderSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const +Trk::Intersection +Trk::CylinderSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const { - bool needsTransform = (m_transform || m_associatedDetElement) ? true : false; - // create the hep points - Amg::Vector3D point1 = pos; - Amg::Vector3D direction = dir; - if (needsTransform){ - Amg::Transform3D invTrans = transform().inverse(); - point1 = invTrans*pos; - direction = invTrans.linear()*dir; - } - // the bounds radius - double R = bounds().r(); - double t1 = 0.; - double t2 = 0.; - if (direction.x()){ - // get line and circle constants - double idirx = 1. / direction.x(); - double k = direction.y() * idirx; - double d = point1.y() - point1.x()*k; - // and solve the qaudratic equation - Trk::RealQuadraticEquation pquad(1 + k*k, 2*k*d, d*d - R*R); - if (pquad.solutions != Trk::none){ - // the solutions in the 3D frame of the cylinder - t1 = (pquad.first - point1.x()) * idirx; - t2 = (pquad.second - point1.x()) * idirx; - } else // bail out if no solution exists - return Trk::Intersection(pos, 0., false); - } else if (direction.y()) { - // x value is the one of point1 - // x^2 + y^2 = R^2 - // y = sqrt(R^2-x^2) - double x = point1.x(); - double r2mx2 = R*R-x*x; - // bail out if no solution - if (r2mx2 < 0. ) return Trk::Intersection(pos, 0., false); - double y = sqrt(r2mx2); - // assign parameters and solutions - double idiry = 1. / direction.y(); - t1 = (y-point1.y()) * idiry; - t2 = (-y-point1.y()) * idiry; - } - else { - return Trk::Intersection(pos, 0., false); + bool needsTransform = (m_transform || m_associatedDetElement) ? true : false; + // create the hep points + Amg::Vector3D point1 = pos; + Amg::Vector3D direction = dir; + if (needsTransform) { + Amg::Transform3D invTrans = transform().inverse(); + point1 = invTrans * pos; + direction = invTrans.linear() * dir; + } + // the bounds radius + double R = bounds().r(); + double t1 = 0.; + double t2 = 0.; + if (direction.x()) { + // get line and circle constants + double idirx = 1. / direction.x(); + double k = direction.y() * idirx; + double d = point1.y() - point1.x() * k; + // and solve the qaudratic equation + Trk::RealQuadraticEquation pquad(1 + k * k, 2 * k * d, d * d - R * R); + if (pquad.solutions != Trk::none) { + // the solutions in the 3D frame of the cylinder + t1 = (pquad.first - point1.x()) * idirx; + t2 = (pquad.second - point1.x()) * idirx; + } else // bail out if no solution exists + return Trk::Intersection(pos, 0., false); + } else if (direction.y()) { + // x value is the one of point1 + // x^2 + y^2 = R^2 + // y = sqrt(R^2-x^2) + double x = point1.x(); + double r2mx2 = R * R - x * x; + // bail out if no solution + if (r2mx2 < 0.) + return Trk::Intersection(pos, 0., false); + double y = sqrt(r2mx2); + // assign parameters and solutions + double idiry = 1. / direction.y(); + t1 = (y - point1.y()) * idiry; + t2 = (-y - point1.y()) * idiry; + } else { + return Trk::Intersection(pos, 0., false); + } + Amg::Vector3D sol1raw(point1 + t1 * direction); + Amg::Vector3D sol2raw(point1 + t2 * direction); + // now reorder and return + Amg::Vector3D solution(0, 0, 0); + double path = 0.; + + // first check the validity of the direction + bool isValid = true; + + // both solutions are of same sign, take the smaller, but flag as false if not forward + if (t1 * t2 > 0 || !forceDir) { + // asign validity + isValid = forceDir ? (t1 > 0.) : true; + // assign the right solution + if (t1 * t1 < t2 * t2) { + solution = sol1raw; + path = t1; + } else { + solution = sol2raw; + path = t2; } - Amg::Vector3D sol1raw(point1 + t1 * direction); - Amg::Vector3D sol2raw(point1 + t2 * direction); - // now reorder and return - Amg::Vector3D solution(0,0,0); - double path = 0.; - - // first check the validity of the direction - bool isValid = true; - - // both solutions are of same sign, take the smaller, but flag as false if not forward - if (t1*t2 > 0 || !forceDir){ - // asign validity - isValid = forceDir ? ( t1 > 0. ) : true ; - // assign the right solution - if (t1*t1 < t2*t2){ - solution = sol1raw; - path = t1; - } else { - solution = sol2raw; - path = t2; - } + } else { + if (t1 > 0.) { + solution = sol1raw; + path = t1; } else { - if (t1 > 0.) { - solution = sol1raw; - path = t1; - } else { - solution = sol2raw; - path = t2; - } + solution = sol2raw; + path = t2; } - // the solution is still in the local 3D frame, direct check - isValid = bchk ? (isValid && m_bounds->inside3D(solution, Trk::Surface::s_onSurfaceTolerance, Trk::Surface::s_onSurfaceTolerance) ) : isValid; - - // now return - return needsTransform ? Intersection( transform()*solution, path, isValid ) - : Intersection( solution, path, isValid ); + } + // the solution is still in the local 3D frame, direct check + isValid = bchk + ? (isValid && + m_bounds->inside3D(solution, Trk::Surface::s_onSurfaceTolerance, Trk::Surface::s_onSurfaceTolerance)) + : isValid; + + // now return + return needsTransform ? Intersection(transform() * solution, path, isValid) : Intersection(solution, path, isValid); } - - /** distance to surface */ -Trk::DistanceSolution Trk::CylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::CylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { double tol = 0.001; - const Amg::Vector3D& X = center(); //point - const Amg::Vector3D& S = normal(); //vector + const Amg::Vector3D& X = center(); // point + const Amg::Vector3D& S = normal(); // vector double radius = bounds().r(); - double sp = pos.dot(S); - double sc = X.dot(S); - double dp = dir.dot(S); - Amg::Vector3D dx = X-pos-(sc-sp)*S ; //vector - Amg::Vector3D ax = dir-dp*S; //vector - - double A = ax.dot(ax); // size of projected direction (squared) - double B = ax.dot(dx); // dot product (->cos angle) - double C = dx.dot(dx); // distance to axis (squared) - double currDist = radius-sqrt(C); - - if (A==0.) { // direction parallel to cylinder axis - if ( fabs(currDist) < tol ) { - return Trk::DistanceSolution(1,0.,true,0.); // solution at surface + double sp = pos.dot(S); + double sc = X.dot(S); + double dp = dir.dot(S); + Amg::Vector3D dx = X - pos - (sc - sp) * S; // vector + Amg::Vector3D ax = dir - dp * S; // vector + + double A = ax.dot(ax); // size of projected direction (squared) + double B = ax.dot(dx); // dot product (->cos angle) + double C = dx.dot(dx); // distance to axis (squared) + double currDist = radius - sqrt(C); + + if (A == 0.) { // direction parallel to cylinder axis + if (fabs(currDist) < tol) { + return Trk::DistanceSolution(1, 0., true, 0.); // solution at surface } else { - return Trk::DistanceSolution(0,currDist,true,0.); // point of closest approach without intersection + return Trk::DistanceSolution(0, currDist, true, 0.); // point of closest approach without intersection } } @@ -329,45 +337,44 @@ Trk::DistanceSolution Trk::CylinderSurface::straightLineDistanceEstimate(const A // The UNUSED declaration is to suppress redundant division checking here. // Even a tiny change in rmin (~1e-13) can cause huge changes in the // reconstructed output, so don't change how it's evaluated. - const double UNUSED(rmin_tmp) = B*B/A; + const double UNUSED(rmin_tmp) = B * B / A; const double rmin2 = C - rmin_tmp; const double rmin = rmin2 < 0 ? 0 : sqrt(rmin2); - if ( rmin > radius ) { // no intersection - double first = B/A; - return Trk::DistanceSolution(0,currDist,true,first); // point of closest approach without intersection + if (rmin > radius) { // no intersection + double first = B / A; + return Trk::DistanceSolution(0, currDist, true, first); // point of closest approach without intersection } else { - if ( fabs(rmin - radius) < tol ) { // tangential 'intersection' - return double solution - double first = B/A; - return Trk::DistanceSolution(2, currDist,true,first,first); + if (fabs(rmin - radius) < tol) { // tangential 'intersection' - return double solution + double first = B / A; + return Trk::DistanceSolution(2, currDist, true, first, first); } else { // The UNUSED declaration here suppresses redundant division checking. // We don't want to rewrite how this is evaluated due to instabilities. - const double UNUSED(b_a) = B/A; - const double x = sqrt((radius-rmin)*(radius+rmin)/A); - double first = b_a - x; + const double UNUSED(b_a) = B / A; + const double x = sqrt((radius - rmin) * (radius + rmin) / A); + double first = b_a - x; double second = b_a + x; - if ( first >= 0. ) { - return Trk::DistanceSolution(2,currDist,true,first,second); - } else if ( second <= 0. ) { - return Trk::DistanceSolution(2,currDist,true,second,first); - } else { // inside cylinder - return Trk::DistanceSolution(2,currDist,true,second,first); + if (first >= 0.) { + return Trk::DistanceSolution(2, currDist, true, first, second); + } else if (second <= 0.) { + return Trk::DistanceSolution(2, currDist, true, second, first); + } else { // inside cylinder + return Trk::DistanceSolution(2, currDist, true, second, first); } } } } - -Trk::DistanceSolution Trk::CylinderSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos, const Amg::Vector3D& dir,bool bound) const +Trk::DistanceSolution +Trk::CylinderSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool bound) const { - const double tolb = .01; + const double tolb = .01; - const Amg::Transform3D& T = transform() ; -// double Ax[3] = {T.xx(),T.yx(),T.zx()}; -// double Ay[3] = {T.xy(),T.yy(),T.zy()}; -// double Az[3] = {T.xz(),T.yz(),T.zz()}; + const Amg::Transform3D& T = transform(); + // double Ax[3] = {T.xx(),T.yx(),T.zx()}; + // double Ay[3] = {T.xy(),T.yy(),T.zy()}; + // double Az[3] = {T.xz(),T.yz(),T.zz()}; // Transformation to cylinder system coordinates // @@ -383,69 +390,69 @@ Trk::DistanceSolution Trk::CylinderSurface::straightLineDistanceEstimate double z = dxyz.dot(Az); double ax = dir.dot(Ax); double ay = dir.dot(Ay); - double at = ax*ax+ay*ay; - double r = sqrt(x*x+y*y) ; - double R = bounds().r() ; + double at = ax * ax + ay * ay; + double r = sqrt(x * x + y * y); + double R = bounds().r(); // END here is what i guessed this means END -// double dx = pos[0]-T.dx() ; -// double dy = pos[1]-T.dy() ; -// double dz = pos[2]-T.dz() ; -// double x = dx*Ax[0]+dy*Ax[1]+dz*Ax[2] ; -// double y = dx*Ay[0]+dy*Ay[1]+dz*Ay[2] ; -// double z = dx*Az[0]+dy*Az[1]+dz*Az[2] ; -// double ax = dir[0]*Ax[0]+dir[1]*Ax[1]+dir[2]*Ax[2]; -// double ay = dir[0]*Ay[0]+dir[1]*Ay[1]+dir[2]*Ay[2]; -// double at = ax*ax+ay*ay ; -// double r = sqrt(x*x+y*y) ; -// double R = bounds().r() ; + // double dx = pos[0]-T.dx() ; + // double dy = pos[1]-T.dy() ; + // double dz = pos[2]-T.dz() ; + // double x = dx*Ax[0]+dy*Ax[1]+dz*Ax[2] ; + // double y = dx*Ay[0]+dy*Ay[1]+dz*Ay[2] ; + // double z = dx*Az[0]+dy*Az[1]+dz*Az[2] ; + // double ax = dir[0]*Ax[0]+dir[1]*Ax[1]+dir[2]*Ax[2]; + // double ay = dir[0]*Ay[0]+dir[1]*Ay[1]+dir[2]*Ay[2]; + // double at = ax*ax+ay*ay ; + // double r = sqrt(x*x+y*y) ; + // double R = bounds().r() ; // Step to surface // - int ns = 0 ; - double s1 = 0.; - double s2 = 0.; + int ns = 0; + double s1 = 0.; + double s2 = 0.; - if (at!=0.) { + if (at != 0.) { const double inv_at = 1. / at; - double A = -(ax*x+ay*y) *inv_at; - double B = A*A+(R-r)*(R-r)*inv_at; + double A = -(ax * x + ay * y) * inv_at; + double B = A * A + (R - r) * (R - r) * inv_at; - if (B>=0.) { + if (B >= 0.) { B = sqrt(B); if (B > tolb) { - if (A > 0.) { - s1 = A-B; - s2 = A+B; - } - else { - s1 = A+B; - s2 = A-B; - } - ns = 2; - } - else { - s1 = A; - ns = 1; + if (A > 0.) { + s1 = A - B; + s2 = A + B; + } else { + s1 = A + B; + s2 = A - B; + } + ns = 2; + } else { + s1 = A; + ns = 1; } } } - double sr = r-R; - if(!bound) return Trk::DistanceSolution(ns,fabs(sr),true,s1,s2); + double sr = r - R; + if (!bound) + return Trk::DistanceSolution(ns, fabs(sr), true, s1, s2); // Min distance to surface // - Amg::Vector2D lp(atan2(y,x)*R,0.); + Amg::Vector2D lp(atan2(y, x) * R, 0.); - double d = bounds().minDistance(lp); - double sz = fabs(z)-bounds().halflengthZ(); - if (sz <= 0.) sz = 0.; - double dist = sr*sr+sz*sz; - if(d>0.) dist+=((d*d)*(sr/R+1.)); + double d = bounds().minDistance(lp); + double sz = fabs(z) - bounds().halflengthZ(); + if (sz <= 0.) + sz = 0.; + double dist = sr * sr + sz * sz; + if (d > 0.) + dist += ((d * d) * (sr / R + 1.)); - return Trk::DistanceSolution(ns,sqrt(dist),true,s1,s2); + return Trk::DistanceSolution(ns, sqrt(dist), true, s1, s2); } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/DiamondBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/DiamondBounds.cxx index 1fb21bb5c8eaf7af12765949eee0e84bec347651..62d60247dd10acfa0798580ae72993178189d4e5 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/DiamondBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/DiamondBounds.cxx @@ -6,186 +6,203 @@ // DiamondBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/DiamondBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> // default constructor -Trk::DiamondBounds::DiamondBounds() : - m_boundValues(DiamondBounds::bv_length, 0.), - m_alpha1(0.), - m_alpha2(0.) +Trk::DiamondBounds::DiamondBounds() + : m_boundValues(DiamondBounds::bv_length, 0.) + , m_alpha1(0.) + , m_alpha2(0.) {} // constructor from arguments I -Trk::DiamondBounds::DiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2) : - m_boundValues(DiamondBounds::bv_length, 0.), - m_alpha1(0.), - m_alpha2(0.) +Trk::DiamondBounds::DiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2) + : m_boundValues(DiamondBounds::bv_length, 0.) + , m_alpha1(0.) + , m_alpha2(0.) { m_boundValues[DiamondBounds::bv_minHalfX] = minhalex; - m_boundValues[DiamondBounds::bv_medHalfX] = medhalex; - m_boundValues[DiamondBounds::bv_maxHalfX] = maxhalex; - m_boundValues[DiamondBounds::bv_halfY1] = haley1; - m_boundValues[DiamondBounds::bv_halfY2] = haley2; - if (minhalex > maxhalex) - swap(m_boundValues[DiamondBounds::bv_minHalfX], m_boundValues[DiamondBounds::bv_maxHalfX]); + m_boundValues[DiamondBounds::bv_medHalfX] = medhalex; + m_boundValues[DiamondBounds::bv_maxHalfX] = maxhalex; + m_boundValues[DiamondBounds::bv_halfY1] = haley1; + m_boundValues[DiamondBounds::bv_halfY2] = haley2; + if (minhalex > maxhalex) + swap(m_boundValues[DiamondBounds::bv_minHalfX], m_boundValues[DiamondBounds::bv_maxHalfX]); initCache(); - } // copy constructor -Trk::DiamondBounds::DiamondBounds(const DiamondBounds& diabo) : - Trk::SurfaceBounds(), - m_boundValues(diabo.m_boundValues), - m_alpha1(diabo.m_alpha1), - m_alpha2(diabo.m_alpha2) +Trk::DiamondBounds::DiamondBounds(const DiamondBounds& diabo) + : Trk::SurfaceBounds() + , m_boundValues(diabo.m_boundValues) + , m_alpha1(diabo.m_alpha1) + , m_alpha2(diabo.m_alpha2) {} // destructor -Trk::DiamondBounds::~DiamondBounds() -{} +Trk::DiamondBounds::~DiamondBounds() {} -Trk::DiamondBounds& Trk::DiamondBounds::operator=(const DiamondBounds& diabo) +Trk::DiamondBounds& +Trk::DiamondBounds::operator=(const DiamondBounds& diabo) { - if (this!=&diabo){ - m_boundValues = diabo.m_boundValues; - m_alpha1 = diabo.m_alpha1; - m_alpha2 = diabo.m_alpha2; + if (this != &diabo) { + m_boundValues = diabo.m_boundValues; + m_alpha1 = diabo.m_alpha1; + m_alpha2 = diabo.m_alpha2; } return *this; } -bool Trk::DiamondBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::DiamondBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::DiamondBounds* diabo = dynamic_cast<const Trk::DiamondBounds*>(&sbo); - if (!diabo) return false; + if (!diabo) + return false; return (m_boundValues == diabo->m_boundValues); - } +} // checking if inside bounds (Full symmetrical Diamond) -bool Trk::DiamondBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::DiamondBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const { - return this->insideFull(locpo, tol1, tol2); + return this->insideFull(locpo, tol1, tol2); } // checking if inside bounds (Full symmetrical Diamond) -bool Trk::DiamondBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::DiamondBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const { // the cases: // (0) - if (!m_boundValues[DiamondBounds::bv_halfY1] && !m_boundValues[DiamondBounds::bv_minHalfX]) return false; + if (!m_boundValues[DiamondBounds::bv_halfY1] && !m_boundValues[DiamondBounds::bv_minHalfX]) + return false; // (1) - if (locpo[Trk::locY] < -2. * m_boundValues[DiamondBounds::bv_halfY1] - tol2) return false; - if (locpo[Trk::locY] > 2. * m_boundValues[DiamondBounds::bv_halfY2] + tol2) return false; + if (locpo[Trk::locY] < -2. * m_boundValues[DiamondBounds::bv_halfY1] - tol2) + return false; + if (locpo[Trk::locY] > 2. * m_boundValues[DiamondBounds::bv_halfY2] + tol2) + return false; // (2) - if (fabs(locpo[Trk::locX]) > (m_boundValues[DiamondBounds::bv_medHalfX] + tol1)) return false; + if (fabs(locpo[Trk::locX]) > (m_boundValues[DiamondBounds::bv_medHalfX] + tol1)) + return false; // (3) - if (fabs(locpo[Trk::locX]) < (fmin(m_boundValues[DiamondBounds::bv_minHalfX],m_boundValues[DiamondBounds::bv_maxHalfX]) - tol1)) return true; + if (fabs(locpo[Trk::locX]) < + (fmin(m_boundValues[DiamondBounds::bv_minHalfX], m_boundValues[DiamondBounds::bv_maxHalfX]) - tol1)) + return true; // (4) /** use basic calculation of a straight line */ - if (locpo[Trk::locY]<0) { - double k = m_boundValues[DiamondBounds::bv_halfY1]>0. ? (m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_minHalfX])/2/m_boundValues[DiamondBounds::bv_halfY1] : 0.; - return ( fabs(locpo[Trk::locX]) <= m_boundValues[DiamondBounds::bv_medHalfX]-k*fabs(locpo[Trk::locY]) ); + if (locpo[Trk::locY] < 0) { + double k = m_boundValues[DiamondBounds::bv_halfY1] > 0. + ? (m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_minHalfX]) / 2 / + m_boundValues[DiamondBounds::bv_halfY1] + : 0.; + return (fabs(locpo[Trk::locX]) <= m_boundValues[DiamondBounds::bv_medHalfX] - k * fabs(locpo[Trk::locY])); } else { - double k = m_boundValues[DiamondBounds::bv_halfY2]>0. ? (m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_maxHalfX])/2/m_boundValues[DiamondBounds::bv_halfY2] : 0.; - return ( fabs(locpo[Trk::locX]) <= m_boundValues[DiamondBounds::bv_medHalfX]-k*fabs(locpo[Trk::locY]) ); + double k = m_boundValues[DiamondBounds::bv_halfY2] > 0. + ? (m_boundValues[DiamondBounds::bv_medHalfX] - m_boundValues[DiamondBounds::bv_maxHalfX]) / 2 / + m_boundValues[DiamondBounds::bv_halfY2] + : 0.; + return (fabs(locpo[Trk::locX]) <= m_boundValues[DiamondBounds::bv_medHalfX] - k * fabs(locpo[Trk::locY])); } } // opening angle in point A -double Trk::DiamondBounds::alpha1() const +double +Trk::DiamondBounds::alpha1() const { - return m_alpha1; + return m_alpha1; } // opening angle in point A' -double Trk::DiamondBounds::alpha2() const +double +Trk::DiamondBounds::alpha2() const { - return m_alpha2; + return m_alpha2; } -double Trk::DiamondBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::DiamondBounds::minDistance(const Amg::Vector2D& pos) const { const int Np = 6; - double y1 = 2.*m_boundValues[DiamondBounds::bv_halfY1]; - double y2 = 2.*m_boundValues[DiamondBounds::bv_halfY2]; + double y1 = 2. * m_boundValues[DiamondBounds::bv_halfY1]; + double y2 = 2. * m_boundValues[DiamondBounds::bv_halfY2]; - double X [6] = {-m_boundValues[DiamondBounds::bv_minHalfX], - -m_boundValues[DiamondBounds::bv_medHalfX], - -m_boundValues[DiamondBounds::bv_maxHalfX], - m_boundValues[DiamondBounds::bv_maxHalfX], - m_boundValues[DiamondBounds::bv_medHalfX], - m_boundValues[DiamondBounds::bv_minHalfX]}; - double Y [6] = { -y1, 0., y2, y2, 0., -y1}; + double X[6] = { -m_boundValues[DiamondBounds::bv_minHalfX], -m_boundValues[DiamondBounds::bv_medHalfX], + -m_boundValues[DiamondBounds::bv_maxHalfX], m_boundValues[DiamondBounds::bv_maxHalfX], + m_boundValues[DiamondBounds::bv_medHalfX], m_boundValues[DiamondBounds::bv_minHalfX] }; + double Y[6] = { -y1, 0., y2, y2, 0., -y1 }; double dm = 1.e+20; - double Ao = 0.; - bool in = true; + double Ao = 0.; + bool in = true; - for (int i=0; i!=Np; ++i) { + for (int i = 0; i != Np; ++i) { - int j = i+1; if (j==Np) j=0; + int j = i + 1; + if (j == Np) + j = 0; - double x = X[i]-pos[0]; - double y = Y[i]-pos[1]; - double dx = X[j]-X[i] ; - double dy = Y[j]-Y[i] ; - double A = x*dy-y*dx ; - double S =-(x*dx+y*dy); + double x = X[i] - pos[0]; + double y = Y[i] - pos[1]; + double dx = X[j] - X[i]; + double dy = Y[j] - Y[i]; + double A = x * dy - y * dx; + double S = -(x * dx + y * dy); if (S <= 0.) { - double d = x*x+y*y; - if (d<dm) dm=d; - } - else { - double a = dx*dx+dy*dy; + double d = x * x + y * y; + if (d < dm) + dm = d; + } else { + double a = dx * dx + dy * dy; if (S <= a) { - double d = (A*A)/a; - if (d<dm) dm=d; + double d = (A * A) / a; + if (d < dm) + dm = d; } } - if (i && in && Ao*A < 0.) in = false; + if (i && in && Ao * A < 0.) + in = false; Ao = A; } - if (in) return -sqrt(dm); + if (in) + return -sqrt(dm); return sqrt(dm); } // ostream operator overload -MsgStream& Trk::DiamondBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::DiamondBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; - sl << "(" << m_boundValues[DiamondBounds::bv_minHalfX] << ", " - << m_boundValues[DiamondBounds::bv_medHalfX] <<", " - << m_boundValues[DiamondBounds::bv_maxHalfX] << ", " - << m_boundValues[DiamondBounds::bv_halfY1] << ", " - << m_boundValues[DiamondBounds::bv_halfY2] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; + sl << "(" << m_boundValues[DiamondBounds::bv_minHalfX] << ", " << m_boundValues[DiamondBounds::bv_medHalfX] << ", " + << m_boundValues[DiamondBounds::bv_maxHalfX] << ", " << m_boundValues[DiamondBounds::bv_halfY1] << ", " + << m_boundValues[DiamondBounds::bv_halfY2] << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::DiamondBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::DiamondBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; - sl << "(" << m_boundValues[DiamondBounds::bv_minHalfX] << ", " - << m_boundValues[DiamondBounds::bv_medHalfX] <<", " - << m_boundValues[DiamondBounds::bv_maxHalfX] << ", " - << m_boundValues[DiamondBounds::bv_halfY1] << ", " - << m_boundValues[DiamondBounds::bv_halfY2] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; + sl << "(" << m_boundValues[DiamondBounds::bv_minHalfX] << ", " << m_boundValues[DiamondBounds::bv_medHalfX] << ", " + << m_boundValues[DiamondBounds::bv_maxHalfX] << ", " << m_boundValues[DiamondBounds::bv_halfY1] << ", " + << m_boundValues[DiamondBounds::bv_halfY2] << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscBounds.cxx index 38c88c13b6ebb373b5cc0b3f9dba7903885a655a..07b1695ab47060623e9f527376036a9ea64e8b69 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscBounds.cxx @@ -6,106 +6,123 @@ // DiscBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/DiscBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -Trk::DiscBounds::DiscBounds() : - m_boundValues(DiscBounds::bv_length, 0.) +Trk::DiscBounds::DiscBounds() + : m_boundValues(DiscBounds::bv_length, 0.) {} -Trk::DiscBounds::DiscBounds(double minrad, double maxrad, double hphisec) : - m_boundValues(DiscBounds::bv_length, 0.) +Trk::DiscBounds::DiscBounds(double minrad, double maxrad, double hphisec) + : m_boundValues(DiscBounds::bv_length, 0.) { - m_boundValues[DiscBounds::bv_rMin] = minrad; - m_boundValues[DiscBounds::bv_rMax] = maxrad; - m_boundValues[DiscBounds::bv_averagePhi] = 0.; - m_boundValues[DiscBounds::bv_halfPhiSector] = hphisec; - if (m_boundValues[DiscBounds::bv_rMin] > m_boundValues[DiscBounds::bv_rMax]) - swap(m_boundValues[DiscBounds::bv_rMin], m_boundValues[DiscBounds::bv_rMax]); + m_boundValues[DiscBounds::bv_rMin] = minrad; + m_boundValues[DiscBounds::bv_rMax] = maxrad; + m_boundValues[DiscBounds::bv_averagePhi] = 0.; + m_boundValues[DiscBounds::bv_halfPhiSector] = hphisec; + if (m_boundValues[DiscBounds::bv_rMin] > m_boundValues[DiscBounds::bv_rMax]) + swap(m_boundValues[DiscBounds::bv_rMin], m_boundValues[DiscBounds::bv_rMax]); } -Trk::DiscBounds::DiscBounds(double minrad, double maxrad, double avephi, double hphisec) : - m_boundValues(DiscBounds::bv_length, 0.) +Trk::DiscBounds::DiscBounds(double minrad, double maxrad, double avephi, double hphisec) + : m_boundValues(DiscBounds::bv_length, 0.) { - m_boundValues[DiscBounds::bv_rMin] = minrad; - m_boundValues[DiscBounds::bv_rMax] = maxrad; - m_boundValues[DiscBounds::bv_averagePhi] = avephi; - m_boundValues[DiscBounds::bv_halfPhiSector] = hphisec; - if (m_boundValues[DiscBounds::bv_rMin] > m_boundValues[DiscBounds::bv_rMax]) - swap(m_boundValues[DiscBounds::bv_rMin], m_boundValues[DiscBounds::bv_rMax]); + m_boundValues[DiscBounds::bv_rMin] = minrad; + m_boundValues[DiscBounds::bv_rMax] = maxrad; + m_boundValues[DiscBounds::bv_averagePhi] = avephi; + m_boundValues[DiscBounds::bv_halfPhiSector] = hphisec; + if (m_boundValues[DiscBounds::bv_rMin] > m_boundValues[DiscBounds::bv_rMax]) + swap(m_boundValues[DiscBounds::bv_rMin], m_boundValues[DiscBounds::bv_rMax]); } +Trk::DiscBounds::~DiscBounds() {} -Trk::DiscBounds::~DiscBounds() -{} - -bool Trk::DiscBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::DiscBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::DiscBounds* discbo = dynamic_cast<const Trk::DiscBounds*>(&sbo); - if (!discbo) return false; - return ( m_boundValues == discbo->m_boundValues); + if (!discbo) + return false; + return (m_boundValues == discbo->m_boundValues); } -double Trk::DiscBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::DiscBounds::minDistance(const Amg::Vector2D& pos) const { - const double pi2 = 2.*M_PI; - - double r = pos[locR]; if(r==0.) return m_boundValues[DiscBounds::bv_rMin]; - double sf = 0. ; - double dF = 0. ; - - if(m_boundValues[DiscBounds::bv_halfPhiSector] < M_PI) { - - dF = fabs(pos[locPhi]-m_boundValues[DiscBounds::bv_averagePhi]); - if (dF>M_PI) dF=pi2-dF; - dF-=m_boundValues[DiscBounds::bv_halfPhiSector]; - sf=r*sin(dF); - if (dF > 0.) r*=cos(dF); - - } - else { - sf =-1.e+10; + const double pi2 = 2. * M_PI; + + double r = pos[locR]; + if (r == 0.) + return m_boundValues[DiscBounds::bv_rMin]; + double sf = 0.; + double dF = 0.; + + if (m_boundValues[DiscBounds::bv_halfPhiSector] < M_PI) { + + dF = fabs(pos[locPhi] - m_boundValues[DiscBounds::bv_averagePhi]); + if (dF > M_PI) + dF = pi2 - dF; + dF -= m_boundValues[DiscBounds::bv_halfPhiSector]; + sf = r * sin(dF); + if (dF > 0.) + r *= cos(dF); + + } else { + sf = -1.e+10; } - if(sf <=0.) { - - double sr0 = m_boundValues[DiscBounds::bv_rMin]-r; if(sr0 > 0.) return sr0; - double sr1 = r-m_boundValues[DiscBounds::bv_rMax]; if(sr1 > 0.) return sr1; - if(sf < sr0) sf = sr0; - if(sf < sr1) sf = sr1; + if (sf <= 0.) { + + double sr0 = m_boundValues[DiscBounds::bv_rMin] - r; + if (sr0 > 0.) + return sr0; + double sr1 = r - m_boundValues[DiscBounds::bv_rMax]; + if (sr1 > 0.) + return sr1; + if (sf < sr0) + sf = sr0; + if (sf < sr1) + sf = sr1; return sf; } - double sr0 = m_boundValues[DiscBounds::bv_rMin]-r; if(sr0 > 0.) return sqrt(sr0*sr0+sf*sf); - double sr1 = r-m_boundValues[DiscBounds::bv_rMax]; if(sr1 > 0.) return sqrt(sr1*sr1+sf*sf); + double sr0 = m_boundValues[DiscBounds::bv_rMin] - r; + if (sr0 > 0.) + return sqrt(sr0 * sr0 + sf * sf); + double sr1 = r - m_boundValues[DiscBounds::bv_rMax]; + if (sr1 > 0.) + return sqrt(sr1 * sr1 + sf * sf); return sf; } // ostream operator overload -MsgStream& Trk::DiscBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::DiscBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiscBounds: (innerRadius, outerRadius, averagePhi, hPhiSector) = "; - sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->averagePhi() << ", "<< this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiscBounds: (innerRadius, outerRadius, averagePhi, hPhiSector) = "; + sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->averagePhi() << ", " << this->halfPhiSector() + << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::DiscBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::DiscBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiscBounds: (innerRadius, outerRadius, hPhiSector) = "; - sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->averagePhi() << ", "<< this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiscBounds: (innerRadius, outerRadius, hPhiSector) = "; + sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->averagePhi() << ", " << this->halfPhiSector() + << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscSurface.cxx index fad63d8ddfced1885ddd77605eeb536b042745a2..6733a1a113a5ed55ee2685b4a3ec5360304de602 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscSurface.cxx @@ -8,262 +8,280 @@ // Trk #include "TrkSurfaces/DiscSurface.h" +#include "TrkEventPrimitives/LocalParameters.h" #include "TrkSurfaces/DiscBounds.h" #include "TrkSurfaces/DiscTrapezoidalBounds.h" -#include "TrkEventPrimitives/LocalParameters.h" - -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD +// STD //#include <iostream> //#include <iomanip> -//Eigen +// Eigen #include "GeoPrimitives/GeoPrimitives.h" const Trk::NoBounds Trk::DiscSurface::s_boundless; // default constructor -Trk::DiscSurface::DiscSurface() : - Trk::Surface(), - m_bounds(), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface() + : Trk::Surface() + , m_bounds() + , m_referencePoint(nullptr) {} // copy constructor -Trk::DiscSurface::DiscSurface(const DiscSurface& dsf) : - Trk::Surface(dsf), - m_bounds(dsf.m_bounds), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(const DiscSurface& dsf) + : Trk::Surface(dsf) + , m_bounds(dsf.m_bounds) + , m_referencePoint(nullptr) {} // copy constructor with shift -Trk::DiscSurface::DiscSurface(const DiscSurface& dsf, const Amg::Transform3D& transf ) : - Trk::Surface(dsf, transf), - m_bounds(dsf.m_bounds), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(const DiscSurface& dsf, const Amg::Transform3D& transf) + : Trk::Surface(dsf, transf) + , m_bounds(dsf.m_bounds) + , m_referencePoint(nullptr) {} // construct a disc with full phi coverage -Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax) : - Trk::Surface(htrans), - m_bounds(new Trk::DiscBounds(rmin, rmax)), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax) + : Trk::Surface(htrans) + , m_bounds(new Trk::DiscBounds(rmin, rmax)) + , m_referencePoint(nullptr) {} // construct a disc with given phi coverage -Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax, double hphisec) : - Trk::Surface(htrans), - m_bounds(new Trk::DiscBounds(rmin, rmax, hphisec)), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, double rmin, double rmax, double hphisec) + : Trk::Surface(htrans) + , m_bounds(new Trk::DiscBounds(rmin, rmax, hphisec)) + , m_referencePoint(nullptr) {} -Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, double minhalfx, double maxhalfx, double maxR, double minR, double avephi, double stereo): - Trk::Surface(htrans), - m_bounds(new Trk::DiscTrapezoidalBounds(minhalfx, maxhalfx, maxR, minR, avephi, stereo)), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, + double minhalfx, + double maxhalfx, + double maxR, + double minR, + double avephi, + double stereo) + : Trk::Surface(htrans) + , m_bounds(new Trk::DiscTrapezoidalBounds(minhalfx, maxhalfx, maxR, minR, avephi, stereo)) + , m_referencePoint(nullptr) {} // construct a disc with given bounds -Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, Trk::DiscBounds* dbounds) : - Trk::Surface(htrans), - m_bounds(dbounds), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, Trk::DiscBounds* dbounds) + : Trk::Surface(htrans) + , m_bounds(dbounds) + , m_referencePoint(nullptr) {} // construct a disc with given bounds -Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, Trk::DiscTrapezoidalBounds* dbounds) : - Trk::Surface(htrans), - m_bounds(dbounds), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(Amg::Transform3D* htrans, Trk::DiscTrapezoidalBounds* dbounds) + : Trk::Surface(htrans) + , m_bounds(dbounds) + , m_referencePoint(nullptr) {} // construct a disc from a transform, bounds is not set. -Trk::DiscSurface::DiscSurface(std::unique_ptr<Amg::Transform3D> htrans) : - Trk::Surface(std::move(htrans)), - m_bounds(nullptr), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(std::unique_ptr<Amg::Transform3D> htrans) + : Trk::Surface(std::move(htrans)) + , m_bounds(nullptr) + , m_referencePoint(nullptr) {} // construct form TrkDetElementBase -Trk::DiscSurface::DiscSurface(const Trk::TrkDetElementBase& detelement) : - Trk::Surface(detelement), - m_bounds(), - m_referencePoint(nullptr) +Trk::DiscSurface::DiscSurface(const Trk::TrkDetElementBase& detelement) + : Trk::Surface(detelement) + , m_bounds() + , m_referencePoint(nullptr) {} // destructor (will call destructor from base class which deletes objects) -Trk::DiscSurface::~DiscSurface() -{ -} +Trk::DiscSurface::~DiscSurface() {} -Trk::DiscSurface& Trk::DiscSurface::operator=(const DiscSurface& dsf) +Trk::DiscSurface& +Trk::DiscSurface::operator=(const DiscSurface& dsf) { - if (this!=&dsf){ + if (this != &dsf) { Trk::Surface::operator=(dsf); - m_bounds = dsf.m_bounds; + m_bounds = dsf.m_bounds; m_referencePoint.store(nullptr); } return *this; } -bool Trk::DiscSurface::operator==(const Trk::Surface& sf) const +bool +Trk::DiscSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::DiscSurface* dsf = dynamic_cast<const Trk::DiscSurface*>(&sf); - if (!dsf) return false; - if (this==dsf) return true; - bool transfEqual(transform().isApprox(dsf->transform(),10e-8)); + if (!dsf) + return false; + if (this == dsf) + return true; + bool transfEqual(transform().isApprox(dsf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == dsf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == dsf->bounds()) : false; return boundsEqual; } -const Amg::Vector3D& Trk::DiscSurface::globalReferencePoint() const -{ - if (!m_referencePoint){ +const Amg::Vector3D& +Trk::DiscSurface::globalReferencePoint() const +{ + if (!m_referencePoint) { const Trk::DiscBounds* dbo = dynamic_cast<const Trk::DiscBounds*>(&(bounds())); if (dbo) { double rMedium = bounds().r(); - double phi = dbo->averagePhi() ; - Amg::Vector3D gp(rMedium*cos(phi), rMedium*sin(phi), 0.); - m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform()*gp)); + double phi = dbo->averagePhi(); + Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.); + m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp)); } else { const Trk::DiscTrapezoidalBounds* dtbo = dynamic_cast<const Trk::DiscTrapezoidalBounds*>(&(bounds())); - //double rMedium = dtbo ? bounds().r() : dtbo->rCenter() ; //nonsense, or logic inverted? - double rMedium = bounds().r(); - double phi = dtbo ? dtbo->averagePhi() : 0.; - Amg::Vector3D gp(rMedium*cos(phi), rMedium*sin(phi), 0.); - m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform()*gp)); + // double rMedium = dtbo ? bounds().r() : dtbo->rCenter() ; //nonsense, or logic inverted? + double rMedium = bounds().r(); + double phi = dtbo ? dtbo->averagePhi() : 0.; + Amg::Vector3D gp(rMedium * cos(phi), rMedium * sin(phi), 0.); + m_referencePoint.set(std::make_unique<Amg::Vector3D>(transform() * gp)); } } return (*m_referencePoint); } - -void Trk::DiscSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const -{ +void +Trk::DiscSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +{ // create the position in the local 3d frame - Amg::Vector3D loc3Dframe(locpos[Trk::locR]*cos(locpos[Trk::locPhi]), - locpos[Trk::locR]*sin(locpos[Trk::locPhi]), - 0.); + Amg::Vector3D loc3Dframe( + locpos[Trk::locR] * cos(locpos[Trk::locPhi]), locpos[Trk::locR] * sin(locpos[Trk::locPhi]), 0.); // transport it to the globalframe - glopos = transform()*loc3Dframe; + glopos = transform() * loc3Dframe; } /** local<->global transformation in case of polar local coordinates */ -bool Trk::DiscSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +bool +Trk::DiscSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopos; - locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi() ); - return ( ( fabs(loc3Dframe.z()) > s_onSurfaceTolerance ) ? false : true ); + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopos; + locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()); + return ((fabs(loc3Dframe.z()) > s_onSurfaceTolerance) ? false : true); } -const Amg::Vector2D* Trk::DiscSurface::localPolarToLocalCartesian(const Amg::Vector2D& locpol) const +const Amg::Vector2D* +Trk::DiscSurface::localPolarToLocalCartesian(const Amg::Vector2D& locpol) const { const Trk::DiscTrapezoidalBounds* dtbo = dynamic_cast<const Trk::DiscTrapezoidalBounds*>(&(bounds())); if (dtbo) { double rMedium = dtbo->rCenter(); - double phi = dtbo->averagePhi(); + double phi = dtbo->averagePhi(); Amg::Vector2D polarCenter(rMedium, phi); const Amg::Vector2D* cartCenter = localPolarToCartesian(polarCenter); const Amg::Vector2D* cartPos = localPolarToCartesian(locpol); Amg::Vector2D Pos = *cartPos - *cartCenter; - delete cartCenter; delete cartPos; - - Amg::Vector2D locPos(Pos[Trk::locX]*sin(phi) - Pos[Trk::locY]*cos(phi), - Pos[Trk::locY]*sin(phi) + Pos[Trk::locX]*cos(phi)); - - return (new Amg::Vector2D(locPos[Trk::locX], locPos[Trk::locY])); + delete cartCenter; + delete cartPos; + + Amg::Vector2D locPos(Pos[Trk::locX] * sin(phi) - Pos[Trk::locY] * cos(phi), + Pos[Trk::locY] * sin(phi) + Pos[Trk::locX] * cos(phi)); + + return (new Amg::Vector2D(locPos[Trk::locX], locPos[Trk::locY])); } - - return(new Amg::Vector2D(locpol[Trk::locR]*cos(locpol[Trk::locPhi]),locpol[Trk::locR]*sin(locpol[Trk::locPhi]))); -} + return ( + new Amg::Vector2D(locpol[Trk::locR] * cos(locpol[Trk::locPhi]), locpol[Trk::locR] * sin(locpol[Trk::locPhi]))); +} /** local<->global transformation in case of polar local coordinates */ -const Amg::Vector3D* Trk::DiscSurface::localCartesianToGlobal(const Amg::Vector2D& locpos) const +const Amg::Vector3D* +Trk::DiscSurface::localCartesianToGlobal(const Amg::Vector2D& locpos) const { Amg::Vector3D loc3Dframe(locpos[Trk::locX], locpos[Trk::locY], 0.); - return new Amg::Vector3D(transform()*loc3Dframe); + return new Amg::Vector3D(transform() * loc3Dframe); } /** local<->global transformation in case of polar local coordinates */ -const Amg::Vector2D* Trk::DiscSurface::globalToLocalCartesian(const Amg::Vector3D& glopos, double tol) const +const Amg::Vector2D* +Trk::DiscSurface::globalToLocalCartesian(const Amg::Vector3D& glopos, double tol) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopos; - if ( fabs(loc3Dframe.z()) > s_onSurfaceTolerance+tol ) return 0; + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopos; + if (fabs(loc3Dframe.z()) > s_onSurfaceTolerance + tol) + return 0; return new Amg::Vector2D(loc3Dframe.x(), loc3Dframe.y()); } -bool Trk::DiscSurface::isOnSurface(const Amg::Vector3D& glopo, - Trk::BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::DiscSurface::isOnSurface(const Amg::Vector3D& glopo, Trk::BoundaryCheck bchk, double tol1, double tol2) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopo; - if ( fabs(loc3Dframe.z()) > (s_onSurfaceTolerance+tol1) ) return false; - return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe.perp(),loc3Dframe.phi()),tol1,tol2) : true); + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopo; + if (fabs(loc3Dframe.z()) > (s_onSurfaceTolerance + tol1)) + return false; + return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.phi()), tol1, tol2) : true); } /** distance to surface */ -Trk::DistanceSolution Trk::DiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::DiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { double tol = 0.001; - - const Amg::Vector3D& C = center(); + + const Amg::Vector3D& C = center(); const Amg::Vector3D& N = normal(); - + double S = C.dot(N); - double b = S < 0. ? -1 : 1 ; - double d = (pos-C).dot(N); // distance to surface - - double A = b* dir.dot(N); - if(A==0.) { // direction parallel to surface - if ( fabs(d)<tol ) { - return Trk::DistanceSolution(1,0.,true,0.); + double b = S < 0. ? -1 : 1; + double d = (pos - C).dot(N); // distance to surface + + double A = b * dir.dot(N); + if (A == 0.) { // direction parallel to surface + if (fabs(d) < tol) { + return Trk::DistanceSolution(1, 0., true, 0.); } else { - return Trk::DistanceSolution(0,d,true,0.); + return Trk::DistanceSolution(0, d, true, 0.); } } - - double D = b*(S-(pos.dot(N)))/A; - return Trk::DistanceSolution(1,d,true,D); -} + double D = b * (S - (pos.dot(N))) / A; + return Trk::DistanceSolution(1, d, true, D); +} -Trk::DistanceSolution Trk::DiscSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool bound) const +Trk::DistanceSolution +Trk::DiscSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool bound) const { - const Amg::Transform3D& T = transform() ; - double Az[3] = {T(0,2),T(1,2),T(2,2)}; + const Amg::Transform3D& T = transform(); + double Az[3] = { T(0, 2), T(1, 2), T(2, 2) }; // Transformation to cylinder system coordinates // - double dx = pos[0]-T(0,3) ; - double dy = pos[1]-T(1,3) ; - double dz = pos[2]-T(2,3) ; - double z = dx*Az[0]+dy*Az[1]+dz*Az[2] ; - double az = dir[0]*Az[0]+dir[1]*Az[1]+dir[2]*Az[2]; + double dx = pos[0] - T(0, 3); + double dy = pos[1] - T(1, 3); + double dz = pos[2] - T(2, 3); + double z = dx * Az[0] + dy * Az[1] + dz * Az[2]; + double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2]; // Step to surface // - int ns = 0; - double s = 0.; if(az!=0.) {s =-z/az; ns = 1;} + int ns = 0; + double s = 0.; + if (az != 0.) { + s = -z / az; + ns = 1; + } double dist = fabs(z); - if (!bound) return Trk::DistanceSolution(ns,dist,true,s); + if (!bound) + return Trk::DistanceSolution(ns, dist, true, s); // Min distance to surface // - double x = dx*T(0,0)+dy*T(1,0)+dz*T(2,0); - double y = dx*T(0,1)+dy*T(1,1)+dz*T(2,1); + double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0); + double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1); - Amg::Vector2D lp(sqrt(x*x+y*y),atan2(y,x)); + Amg::Vector2D lp(sqrt(x * x + y * y), atan2(y, x)); - double d = bounds().minDistance(lp); - if (d>0.) dist = sqrt(dist*dist+d*d); + double d = bounds().minDistance(lp); + if (d > 0.) + dist = sqrt(dist * dist + d * d); - return Trk::DistanceSolution(ns,dist,true,s); + return Trk::DistanceSolution(ns, dist, true, s); } diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscTrapezoidalBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscTrapezoidalBounds.cxx index a5ba1df553c40b6221d6e126f3d5a17a5a6b4683..775c0e53985e927ceb970ef9d460e2ec7ab561e7 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/DiscTrapezoidalBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/DiscTrapezoidalBounds.cxx @@ -6,118 +6,143 @@ // DiscTrapezoidalBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/DiscTrapezoidalBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds() : - m_boundValues(DiscTrapezoidalBounds::bv_length, 0.) +Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds() + : m_boundValues(DiscTrapezoidalBounds::bv_length, 0.) {} -Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds(double minhalfx, double maxhalfx, double maxR, double minR, double avephi, double stereo) : - m_boundValues(DiscTrapezoidalBounds::bv_length, 0.) -{ - m_boundValues[DiscTrapezoidalBounds::bv_averagePhi] = avephi; - m_boundValues[DiscTrapezoidalBounds::bv_stereo] = stereo; - - m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] = minhalfx; - m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] = maxhalfx; - if (m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] > m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]) - swap(m_boundValues[DiscTrapezoidalBounds::bv_minHalfX], m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); +Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds(double minhalfx, + double maxhalfx, + double maxR, + double minR, + double avephi, + double stereo) + : m_boundValues(DiscTrapezoidalBounds::bv_length, 0.) +{ + m_boundValues[DiscTrapezoidalBounds::bv_averagePhi] = avephi; + m_boundValues[DiscTrapezoidalBounds::bv_stereo] = stereo; + + m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] = minhalfx; + m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] = maxhalfx; + if (m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] > m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]) + swap(m_boundValues[DiscTrapezoidalBounds::bv_minHalfX], m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); m_boundValues[DiscTrapezoidalBounds::bv_rMax] = minR; m_boundValues[DiscTrapezoidalBounds::bv_rMin] = maxR; - if (m_boundValues[DiscTrapezoidalBounds::bv_rMin] > m_boundValues[DiscTrapezoidalBounds::bv_rMax]) - swap(m_boundValues[DiscTrapezoidalBounds::bv_rMin], m_boundValues[DiscTrapezoidalBounds::bv_rMax]); + if (m_boundValues[DiscTrapezoidalBounds::bv_rMin] > m_boundValues[DiscTrapezoidalBounds::bv_rMax]) + swap(m_boundValues[DiscTrapezoidalBounds::bv_rMin], m_boundValues[DiscTrapezoidalBounds::bv_rMax]); - m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] = asin(m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]/m_boundValues[DiscTrapezoidalBounds::bv_rMax]); + m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] = + asin(m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] / m_boundValues[DiscTrapezoidalBounds::bv_rMax]); - double hmax = sqrt(m_boundValues[DiscTrapezoidalBounds::bv_rMax]*m_boundValues[DiscTrapezoidalBounds::bv_rMax]- - m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]*m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); + double hmax = + sqrt(m_boundValues[DiscTrapezoidalBounds::bv_rMax] * m_boundValues[DiscTrapezoidalBounds::bv_rMax] - + m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX] * m_boundValues[DiscTrapezoidalBounds::bv_maxHalfX]); - double hmin = sqrt(m_boundValues[DiscTrapezoidalBounds::bv_rMin]*m_boundValues[DiscTrapezoidalBounds::bv_rMin]- - m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]*m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]); + double hmin = + sqrt(m_boundValues[DiscTrapezoidalBounds::bv_rMin] * m_boundValues[DiscTrapezoidalBounds::bv_rMin] - + m_boundValues[DiscTrapezoidalBounds::bv_minHalfX] * m_boundValues[DiscTrapezoidalBounds::bv_minHalfX]); - m_boundValues[DiscTrapezoidalBounds::bv_rCenter] = (hmax+hmin)/2.; - m_boundValues[DiscTrapezoidalBounds::bv_halfY] = (hmax-hmin)/2.; - - + m_boundValues[DiscTrapezoidalBounds::bv_rCenter] = (hmax + hmin) / 2.; + m_boundValues[DiscTrapezoidalBounds::bv_halfY] = (hmax - hmin) / 2.; } -Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds(const DiscTrapezoidalBounds& disctrbo) : - Trk::SurfaceBounds(), - m_boundValues(disctrbo.m_boundValues) +Trk::DiscTrapezoidalBounds::DiscTrapezoidalBounds(const DiscTrapezoidalBounds& disctrbo) + : Trk::SurfaceBounds() + , m_boundValues(disctrbo.m_boundValues) {} -Trk::DiscTrapezoidalBounds::~DiscTrapezoidalBounds() -{} +Trk::DiscTrapezoidalBounds::~DiscTrapezoidalBounds() {} -Trk::DiscTrapezoidalBounds& Trk::DiscTrapezoidalBounds::operator=(const DiscTrapezoidalBounds& disctrbo) +Trk::DiscTrapezoidalBounds& +Trk::DiscTrapezoidalBounds::operator=(const DiscTrapezoidalBounds& disctrbo) { - if (this!=&disctrbo) - m_boundValues = disctrbo.m_boundValues; + if (this != &disctrbo) + m_boundValues = disctrbo.m_boundValues; return *this; } -bool Trk::DiscTrapezoidalBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::DiscTrapezoidalBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::DiscTrapezoidalBounds* disctrbo = dynamic_cast<const Trk::DiscTrapezoidalBounds*>(&sbo); - if (!disctrbo) return false; - return ( m_boundValues == disctrbo->m_boundValues); + if (!disctrbo) + return false; + return (m_boundValues == disctrbo->m_boundValues); } -double Trk::DiscTrapezoidalBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::DiscTrapezoidalBounds::minDistance(const Amg::Vector2D& pos) const { - const double pi2 = 2.*M_PI; - double alpha = fabs(pos[locPhi]); - if ( alpha>M_PI) alpha = pi2 - alpha; - - double r = pos[locR]; if(r==0.) return m_boundValues[DiscTrapezoidalBounds::bv_rMin]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha); - - // check if it is external in R - double sr0 = m_boundValues[DiscTrapezoidalBounds::bv_rMin]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha)-r; - if(sr0 > 0.) return sr0; - double sr1 = r-m_boundValues[DiscTrapezoidalBounds::bv_rMax]*cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])/cos(alpha); - if(sr1 > 0.) return sr1; - - // check if it is external in phi - if((alpha-m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])>0.) return r*fabs(sin(alpha-m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])); - - // if here it is inside: - // Evaluate the distance from the 4 segments - double dist [4] = { sr0, - sr1, - -r*sin(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]-alpha), - -r*sin(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]+alpha)}; - - return *std::max_element(dist,dist+4); + const double pi2 = 2. * M_PI; + double alpha = fabs(pos[locPhi]); + if (alpha > M_PI) + alpha = pi2 - alpha; + + double r = pos[locR]; + if (r == 0.) + return m_boundValues[DiscTrapezoidalBounds::bv_rMin] * cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / + cos(alpha); + + // check if it is external in R + double sr0 = m_boundValues[DiscTrapezoidalBounds::bv_rMin] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha) - + r; + if (sr0 > 0.) + return sr0; + double sr1 = r - m_boundValues[DiscTrapezoidalBounds::bv_rMax] * + cos(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) / cos(alpha); + if (sr1 > 0.) + return sr1; + + // check if it is external in phi + if ((alpha - m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector]) > 0.) + return r * fabs(sin(alpha - m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector])); + + // if here it is inside: + // Evaluate the distance from the 4 segments + double dist[4] = { sr0, + sr1, + -r * sin(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] - alpha), + -r * sin(m_boundValues[DiscTrapezoidalBounds::bv_halfPhiSector] + alpha) }; + + return *std::max_element(dist, dist + 4); } // ostream operator overload -MsgStream& Trk::DiscTrapezoidalBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::DiscTrapezoidalBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiscTrapezoidalBounds: (innerRadius, outerRadius, hMinX, hMaxX, hlengthY, hPhiSector, averagePhi, rCenter, stereo) = "; - sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->minHalflengthX() << ", " << this->maxHalflengthX() << ", " << this->halflengthY() << ", " << this->halfPhiSector() << ", " << this->averagePhi() << ", " << this->rCenter() << ", " << this->stereo() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiscTrapezoidalBounds: (innerRadius, outerRadius, hMinX, hMaxX, hlengthY, hPhiSector, averagePhi, " + "rCenter, stereo) = "; + sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->minHalflengthX() << ", " << this->maxHalflengthX() + << ", " << this->halflengthY() << ", " << this->halfPhiSector() << ", " << this->averagePhi() << ", " + << this->rCenter() << ", " << this->stereo() << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::DiscTrapezoidalBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::DiscTrapezoidalBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::DiscTrapezoidalBounds: (innerRadius, outerRadius, hMinX, hMaxX, hlengthY, hPhiSector, averagePhi, rCenter, stereo) = "; - sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->minHalflengthX() << ", " << this->maxHalflengthX() << ", " << this->halflengthY() << ", " << this->halfPhiSector() << ", " << this->averagePhi() << ", " << this->rCenter() << ", " << this->stereo() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::DiscTrapezoidalBounds: (innerRadius, outerRadius, hMinX, hMaxX, hlengthY, hPhiSector, averagePhi, " + "rCenter, stereo) = "; + sl << "(" << this->rMin() << ", " << this->rMax() << ", " << this->minHalflengthX() << ", " << this->maxHalflengthX() + << ", " << this->halflengthY() << ", " << this->halfPhiSector() << ", " << this->averagePhi() << ", " + << this->rCenter() << ", " << this->stereo() << ")"; + sl << std::setprecision(-1); + return sl; } - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/DistanceSolution.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/DistanceSolution.cxx index faa7157544afff582259fdecd36c5a4ef4681892..a7d7a4cdf54896944a2b300672f0aa0f5635abf6 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/DistanceSolution.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/DistanceSolution.cxx @@ -6,25 +6,23 @@ // DistanceSolution.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/DistanceSolution.h" // default constructor -Trk::DistanceSolution::DistanceSolution() : - m_num(), - m_first(), - m_second(), - m_current(), - m_signedDist() +Trk::DistanceSolution::DistanceSolution() + : m_num() + , m_first() + , m_second() + , m_current() + , m_signedDist() {} -// constructor -Trk::DistanceSolution::DistanceSolution(int num, double current, bool signedDist, double first, double second) : - m_num(num), - m_first(first), - m_second(second), - m_current(current), - m_signedDist(signedDist) +// constructor +Trk::DistanceSolution::DistanceSolution(int num, double current, bool signedDist, double first, double second) + : m_num(num) + , m_first(first) + , m_second(second) + , m_current(current) + , m_signedDist(signedDist) {} - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/EllipseBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/EllipseBounds.cxx index d04db86e3a46154a067b93948144358356c97c93..32d1536a8fd7ba92d8180cfe5b6b181be0552568 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/EllipseBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/EllipseBounds.cxx @@ -6,157 +6,180 @@ // EllipseBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/EllipseBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> -Trk::EllipseBounds::EllipseBounds() : - m_boundValues(EllipseBounds::bv_length,0.) +Trk::EllipseBounds::EllipseBounds() + : m_boundValues(EllipseBounds::bv_length, 0.) {} - -Trk::EllipseBounds::EllipseBounds(double minradX, double minradY, double maxradX, double maxradY, double hphisec) : - m_boundValues(EllipseBounds::bv_length,0.) +Trk::EllipseBounds::EllipseBounds(double minradX, double minradY, double maxradX, double maxradY, double hphisec) + : m_boundValues(EllipseBounds::bv_length, 0.) { - m_boundValues[EllipseBounds::bv_rMinX] = minradX; - m_boundValues[EllipseBounds::bv_rMinY] = minradY; - m_boundValues[EllipseBounds::bv_rMaxX] = maxradX; - m_boundValues[EllipseBounds::bv_rMaxY] = maxradY; - m_boundValues[EllipseBounds::bv_averagePhi] = 0.; - m_boundValues[EllipseBounds::bv_halfPhiSector] = hphisec; - if (m_boundValues[EllipseBounds::bv_rMinX] > m_boundValues[EllipseBounds::bv_rMaxX]) - swap(m_boundValues[EllipseBounds::bv_rMinX], m_boundValues[EllipseBounds::bv_rMaxX]); - if (m_boundValues[EllipseBounds::bv_rMinY] > m_boundValues[EllipseBounds::bv_rMaxY]) - swap(m_boundValues[EllipseBounds::bv_rMinY], m_boundValues[EllipseBounds::bv_rMaxY]); + m_boundValues[EllipseBounds::bv_rMinX] = minradX; + m_boundValues[EllipseBounds::bv_rMinY] = minradY; + m_boundValues[EllipseBounds::bv_rMaxX] = maxradX; + m_boundValues[EllipseBounds::bv_rMaxY] = maxradY; + m_boundValues[EllipseBounds::bv_averagePhi] = 0.; + m_boundValues[EllipseBounds::bv_halfPhiSector] = hphisec; + if (m_boundValues[EllipseBounds::bv_rMinX] > m_boundValues[EllipseBounds::bv_rMaxX]) + swap(m_boundValues[EllipseBounds::bv_rMinX], m_boundValues[EllipseBounds::bv_rMaxX]); + if (m_boundValues[EllipseBounds::bv_rMinY] > m_boundValues[EllipseBounds::bv_rMaxY]) + swap(m_boundValues[EllipseBounds::bv_rMinY], m_boundValues[EllipseBounds::bv_rMaxY]); } -Trk::EllipseBounds::EllipseBounds(double minradX, double minradY, double maxradX, double maxradY, double avephi, double hphisec) : - m_boundValues(EllipseBounds::bv_length,0.) +Trk::EllipseBounds::EllipseBounds(double minradX, + double minradY, + double maxradX, + double maxradY, + double avephi, + double hphisec) + : m_boundValues(EllipseBounds::bv_length, 0.) { - m_boundValues[EllipseBounds::bv_rMinX] = minradX; - m_boundValues[EllipseBounds::bv_rMinY] = minradY; - m_boundValues[EllipseBounds::bv_rMaxX] = maxradX; - m_boundValues[EllipseBounds::bv_rMaxY] = maxradY; - m_boundValues[EllipseBounds::bv_averagePhi] = avephi; - m_boundValues[EllipseBounds::bv_halfPhiSector] = hphisec; - if (m_boundValues[EllipseBounds::bv_rMinX] > m_boundValues[EllipseBounds::bv_rMaxX]) - swap(m_boundValues[EllipseBounds::bv_rMinX], m_boundValues[EllipseBounds::bv_rMaxX]); - if (m_boundValues[EllipseBounds::bv_rMinY] > m_boundValues[EllipseBounds::bv_rMaxY]) - swap(m_boundValues[EllipseBounds::bv_rMinY], m_boundValues[EllipseBounds::bv_rMaxY]); + m_boundValues[EllipseBounds::bv_rMinX] = minradX; + m_boundValues[EllipseBounds::bv_rMinY] = minradY; + m_boundValues[EllipseBounds::bv_rMaxX] = maxradX; + m_boundValues[EllipseBounds::bv_rMaxY] = maxradY; + m_boundValues[EllipseBounds::bv_averagePhi] = avephi; + m_boundValues[EllipseBounds::bv_halfPhiSector] = hphisec; + if (m_boundValues[EllipseBounds::bv_rMinX] > m_boundValues[EllipseBounds::bv_rMaxX]) + swap(m_boundValues[EllipseBounds::bv_rMinX], m_boundValues[EllipseBounds::bv_rMaxX]); + if (m_boundValues[EllipseBounds::bv_rMinY] > m_boundValues[EllipseBounds::bv_rMaxY]) + swap(m_boundValues[EllipseBounds::bv_rMinY], m_boundValues[EllipseBounds::bv_rMaxY]); } -Trk::EllipseBounds::EllipseBounds(const EllipseBounds& discbo) : - Trk::SurfaceBounds(), - m_boundValues(discbo.m_boundValues) +Trk::EllipseBounds::EllipseBounds(const EllipseBounds& discbo) + : Trk::SurfaceBounds() + , m_boundValues(discbo.m_boundValues) {} -Trk::EllipseBounds::~EllipseBounds() -{} +Trk::EllipseBounds::~EllipseBounds() {} -Trk::EllipseBounds& Trk::EllipseBounds::operator=(const EllipseBounds& discbo) +Trk::EllipseBounds& +Trk::EllipseBounds::operator=(const EllipseBounds& discbo) { - if (this!=&discbo) - m_boundValues = discbo.m_boundValues; + if (this != &discbo) + m_boundValues = discbo.m_boundValues; return *this; } -Trk::EllipseBounds& Trk::EllipseBounds::operator=(EllipseBounds&& discbo) +Trk::EllipseBounds& +Trk::EllipseBounds::operator=(EllipseBounds&& discbo) { - if (this!=&discbo) + if (this != &discbo) m_boundValues = std::move(discbo.m_boundValues); return *this; } -bool Trk::EllipseBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::EllipseBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::EllipseBounds* discbo = dynamic_cast<const Trk::EllipseBounds*>(&sbo); - if (!discbo) return false; + if (!discbo) + return false; return (m_boundValues == discbo->m_boundValues); } // For ellipse bound this is only approximation which is valid -// only if m_boundValues[EllipseBounds::bv_rMinX] ~= m_boundValues[EllipseBounds::bv_rMinY] +// only if m_boundValues[EllipseBounds::bv_rMinX] ~= m_boundValues[EllipseBounds::bv_rMinY] // and m_boundValues[EllipseBounds::bv_rMaxX] ~= m_boundValues[EllipseBounds::bv_rMaxY] // -double Trk::EllipseBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::EllipseBounds::minDistance(const Amg::Vector2D& pos) const { - const double pi2 = 2.*M_PI; + const double pi2 = 2. * M_PI; - double r = sqrt(pos[0]*pos[0]+pos[1]*pos[1]); - if(r==0.) { - if (m_boundValues[EllipseBounds::bv_rMinX] <= m_boundValues[EllipseBounds::bv_rMinY]) return m_boundValues[EllipseBounds::bv_rMinX]; - return m_boundValues[EllipseBounds::bv_rMinY]; + double r = sqrt(pos[0] * pos[0] + pos[1] * pos[1]); + if (r == 0.) { + if (m_boundValues[EllipseBounds::bv_rMinX] <= m_boundValues[EllipseBounds::bv_rMinY]) + return m_boundValues[EllipseBounds::bv_rMinX]; + return m_boundValues[EllipseBounds::bv_rMinY]; } const double inv_r = 1. / r; - double sn = pos[1]*inv_r ; - double cs = pos[0]*inv_r ; - double sf = 0. ; - double dF = 0. ; + double sn = pos[1] * inv_r; + double cs = pos[0] * inv_r; + double sf = 0.; + double dF = 0.; - if(m_boundValues[EllipseBounds::bv_halfPhiSector] < M_PI) { + if (m_boundValues[EllipseBounds::bv_halfPhiSector] < M_PI) { - dF = atan2(cs,sn)-m_boundValues[EllipseBounds::bv_averagePhi]; + dF = atan2(cs, sn) - m_boundValues[EllipseBounds::bv_averagePhi]; dF += (dF > M_PI) ? -pi2 : (dF < -M_PI) ? pi2 : 0; - double df = fabs(dF)-m_boundValues[EllipseBounds::bv_halfPhiSector]; - sf = r*sin(df); - if (df > 0.) r*=cos(df); - } - else { + double df = fabs(dF) - m_boundValues[EllipseBounds::bv_halfPhiSector]; + sf = r * sin(df); + if (df > 0.) + r *= cos(df); + } else { sf = -1.e+10; } - if(sf <= 0. ) { - - double a = cs/m_boundValues[EllipseBounds::bv_rMaxX] ; - double b = sn/m_boundValues[EllipseBounds::bv_rMaxY] ; - double sr0 = r-1./sqrt(a*a+b*b); if(sr0 >=0.) return sr0; - a = cs/m_boundValues[EllipseBounds::bv_rMinX] ; - b = sn/m_boundValues[EllipseBounds::bv_rMinY] ; - double sr1 = 1./sqrt(a*a+b*b)-r; if(sr1 >=0.) return sr1; - if(sf < sr0) sf = sr0 ; - if(sf < sr1) sf = sr1 ; + if (sf <= 0.) { + + double a = cs / m_boundValues[EllipseBounds::bv_rMaxX]; + double b = sn / m_boundValues[EllipseBounds::bv_rMaxY]; + double sr0 = r - 1. / sqrt(a * a + b * b); + if (sr0 >= 0.) + return sr0; + a = cs / m_boundValues[EllipseBounds::bv_rMinX]; + b = sn / m_boundValues[EllipseBounds::bv_rMinY]; + double sr1 = 1. / sqrt(a * a + b * b) - r; + if (sr1 >= 0.) + return sr1; + if (sf < sr0) + sf = sr0; + if (sf < sr1) + sf = sr1; return sf; } double fb; - fb = (dF > 0.) ? m_boundValues[EllipseBounds::bv_averagePhi]+m_boundValues[EllipseBounds::bv_halfPhiSector] : m_boundValues[EllipseBounds::bv_averagePhi]-m_boundValues[EllipseBounds::bv_halfPhiSector]; - sn = sin(fb) ; - cs = cos(fb) ; - double a = cs/m_boundValues[EllipseBounds::bv_rMaxX] ; - double b = sn/m_boundValues[EllipseBounds::bv_rMaxY] ; - double sr0 = r-1./sqrt(a*a+b*b); if(sr0 >=0.) return sqrt(sr0*sr0+sf*sf); - a = cs/m_boundValues[EllipseBounds::bv_rMinX] ; - b = sn/m_boundValues[EllipseBounds::bv_rMinY] ; - double sr1 = 1./sqrt(a*a+b*b)-r; if(sr1 >=0.) return sqrt(sr1*sr1+sf*sf); + fb = (dF > 0.) ? m_boundValues[EllipseBounds::bv_averagePhi] + m_boundValues[EllipseBounds::bv_halfPhiSector] + : m_boundValues[EllipseBounds::bv_averagePhi] - m_boundValues[EllipseBounds::bv_halfPhiSector]; + sn = sin(fb); + cs = cos(fb); + double a = cs / m_boundValues[EllipseBounds::bv_rMaxX]; + double b = sn / m_boundValues[EllipseBounds::bv_rMaxY]; + double sr0 = r - 1. / sqrt(a * a + b * b); + if (sr0 >= 0.) + return sqrt(sr0 * sr0 + sf * sf); + a = cs / m_boundValues[EllipseBounds::bv_rMinX]; + b = sn / m_boundValues[EllipseBounds::bv_rMinY]; + double sr1 = 1. / sqrt(a * a + b * b) - r; + if (sr1 >= 0.) + return sqrt(sr1 * sr1 + sf * sf); return sf; } // ostream operator overload -MsgStream& Trk::EllipseBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::EllipseBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::EllipseBounds: (innerRadiusX, innerRadiusY, outerRadiusX, outerRadiusY, averagePhi, hPhiSector) = " ; - sl << "(" << this->rMinX() << ", " << this->rMinY() << ", " << this->rMaxX() << ", " << this->rMaxY() << ", " << this->averagePhi() << ", "<< this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::EllipseBounds: (innerRadiusX, innerRadiusY, outerRadiusX, outerRadiusY, averagePhi, hPhiSector) = "; + sl << "(" << this->rMinX() << ", " << this->rMinY() << ", " << this->rMaxX() << ", " << this->rMaxY() << ", " + << this->averagePhi() << ", " << this->halfPhiSector() << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::EllipseBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::EllipseBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::EllipseBounds: (innerRadiusX, innerRadiusY, outerRadiusX, outerRadiusY, hPhiSector) = "; - sl << "(" << this->rMinX() << ", " << this->rMinY() << ", " << this->rMaxX() << ", " << this->rMaxY() << ", " << this->averagePhi() << ", "<< this->halfPhiSector() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::EllipseBounds: (innerRadiusX, innerRadiusY, outerRadiusX, outerRadiusY, hPhiSector) = "; + sl << "(" << this->rMinX() << ", " << this->rMinY() << ", " << this->rMaxX() << ", " << this->rMaxY() << ", " + << this->averagePhi() << ", " << this->halfPhiSector() << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx index 2420a7a7e9a655c8607c4407e670aab04a8b3a4f..7eaee5a44097cf14c5ed380ecc8f1657b0f54ba6 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/PerigeeSurface.cxx @@ -8,216 +8,223 @@ // Trk #include "TrkSurfaces/PerigeeSurface.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> -//Eigen +#include <iostream> +// Eigen #include "GeoPrimitives/GeoPrimitives.h" const Trk::NoBounds Trk::PerigeeSurface::s_perigeeBounds; -Trk::PerigeeSurface::PerigeeSurface() : - Surface(), - m_lineDirection(nullptr) +Trk::PerigeeSurface::PerigeeSurface() + : Surface() + , m_lineDirection(nullptr) {} -Trk::PerigeeSurface::PerigeeSurface(const Amg::Vector3D& gp): - Surface(), - m_lineDirection(nullptr) -{ - Surface::m_center = std::make_unique<Amg::Vector3D>(gp); - Surface::m_transform =std::make_unique<Amg::Transform3D>(); - (*Surface::m_transform) = Amg::Translation3D(gp.x(),gp.y(),gp.z()); -} - -Trk::PerigeeSurface::PerigeeSurface(Amg::Transform3D* tTransform): - Surface(), - m_lineDirection(nullptr) +Trk::PerigeeSurface::PerigeeSurface(const Amg::Vector3D& gp) + : Surface() + , m_lineDirection(nullptr) { - Surface::m_transform.store(std::unique_ptr<Amg::Transform3D> (tTransform)); + Surface::m_center = std::make_unique<Amg::Vector3D>(gp); + Surface::m_transform = std::make_unique<Amg::Transform3D>(); + (*Surface::m_transform) = Amg::Translation3D(gp.x(), gp.y(), gp.z()); } - -Trk::PerigeeSurface::PerigeeSurface(std::unique_ptr<Amg::Transform3D> tTransform): - Surface(std::move(tTransform)), - m_lineDirection(0) +Trk::PerigeeSurface::PerigeeSurface(Amg::Transform3D* tTransform) + : Surface() + , m_lineDirection(nullptr) { + Surface::m_transform.store(std::unique_ptr<Amg::Transform3D>(tTransform)); } +Trk::PerigeeSurface::PerigeeSurface(std::unique_ptr<Amg::Transform3D> tTransform) + : Surface(std::move(tTransform)) + , m_lineDirection(0) +{} -Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf): - Surface(), - m_lineDirection(nullptr) +Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf) + : Surface() + , m_lineDirection(nullptr) { - if (pesf.m_center) Surface::m_center =std::make_unique<Amg::Vector3D>(*pesf.m_center); - if (pesf.m_transform) Surface::m_transform = std::make_unique<Amg::Transform3D>(*pesf.m_transform); - + if (pesf.m_center) + Surface::m_center = std::make_unique<Amg::Vector3D>(*pesf.m_center); + if (pesf.m_transform) + Surface::m_transform = std::make_unique<Amg::Transform3D>(*pesf.m_transform); } -Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf, const Amg::Transform3D& shift): - Surface(), - m_lineDirection(nullptr) +Trk::PerigeeSurface::PerigeeSurface(const PerigeeSurface& pesf, const Amg::Transform3D& shift) + : Surface() + , m_lineDirection(nullptr) { - if (pesf.m_center) Surface::m_center = std::make_unique<Amg::Vector3D>(shift*(*pesf.m_center)); - if (pesf.m_transform) Surface::m_transform = std::make_unique<Amg::Transform3D>(shift*(*pesf.m_transform)); - + if (pesf.m_center) + Surface::m_center = std::make_unique<Amg::Vector3D>(shift * (*pesf.m_center)); + if (pesf.m_transform) + Surface::m_transform = std::make_unique<Amg::Transform3D>(shift * (*pesf.m_transform)); } -Trk::PerigeeSurface::~PerigeeSurface() -{ -} +Trk::PerigeeSurface::~PerigeeSurface() {} // assignment operator -Trk::PerigeeSurface& Trk::PerigeeSurface::operator=(const Trk::PerigeeSurface& pesf) +Trk::PerigeeSurface& +Trk::PerigeeSurface::operator=(const Trk::PerigeeSurface& pesf) { - if (this!=&pesf){ - Trk::Surface::operator=(pesf); - m_lineDirection.store(std::make_unique<Amg::Vector3D>(lineDirection())); - + if (this != &pesf) { + Trk::Surface::operator=(pesf); + m_lineDirection.store(std::make_unique<Amg::Vector3D>(lineDirection())); } return *this; } -bool Trk::PerigeeSurface::operator==(const Trk::Surface& sf) const +bool +Trk::PerigeeSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::PerigeeSurface* persf = dynamic_cast<const Trk::PerigeeSurface*>(&sf); - if (!persf) return false; - if (this==persf) return true; + if (!persf) + return false; + if (this == persf) + return true; return (center() == persf->center()); } // simple local to global - from LocalParameters / -const Amg::Vector3D* Trk::PerigeeSurface::localToGlobal(const Trk::LocalParameters& locpars) const +const Amg::Vector3D* +Trk::PerigeeSurface::localToGlobal(const Trk::LocalParameters& locpars) const { - if (locpars.contains(Trk::phi0)){ - Amg::Vector3D loc3Dframe(-locpars[Trk::d0]*sin(locpars[Trk::phi0]), locpars[Trk::d0]*cos(locpars[Trk::phi0]), locpars[Trk::z0]); - return new Amg::Vector3D(transform()*loc3Dframe); - } - else return new Amg::Vector3D(0., 0., locpars[Trk::z0] + (center().z()) ); + if (locpars.contains(Trk::phi0)) { + Amg::Vector3D loc3Dframe( + -locpars[Trk::d0] * sin(locpars[Trk::phi0]), locpars[Trk::d0] * cos(locpars[Trk::phi0]), locpars[Trk::z0]); + return new Amg::Vector3D(transform() * loc3Dframe); + } else + return new Amg::Vector3D(0., 0., locpars[Trk::z0] + (center().z())); } - // true local to global method/ -void Trk::PerigeeSurface::localToGlobal(const Amg::Vector2D& locpos, - const Amg::Vector3D& glomom, - Amg::Vector3D& glopos) const -{ - // this is for a tilted perigee surface - if (Surface::m_transform){ - // get the vector perpenticular to the momentum and the straw axis - Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom)); - Amg::Vector3D locZinGlobal = transform()*Amg::Vector3D(0.,0.,locpos[Trk::locZ]); - // transform zPosition into global coordinates and add locR * radiusAxis - glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR]*radiusAxisGlobal.normalized()); - } else { - double phi = glomom.phi(); - glopos[Amg::x] = - locpos[Trk::d0]*sin(phi); - glopos[Amg::y] = locpos[Trk::d0]*cos(phi); - glopos[Amg::z] = locpos[Trk::z0]; - glopos += center(); - } +void +Trk::PerigeeSurface::localToGlobal(const Amg::Vector2D& locpos, + const Amg::Vector3D& glomom, + Amg::Vector3D& glopos) const +{ + // this is for a tilted perigee surface + if (Surface::m_transform) { + // get the vector perpenticular to the momentum and the straw axis + Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom)); + Amg::Vector3D locZinGlobal = transform() * Amg::Vector3D(0., 0., locpos[Trk::locZ]); + // transform zPosition into global coordinates and add locR * radiusAxis + glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR] * radiusAxisGlobal.normalized()); + } else { + double phi = glomom.phi(); + glopos[Amg::x] = -locpos[Trk::d0] * sin(phi); + glopos[Amg::y] = locpos[Trk::d0] * cos(phi); + glopos[Amg::z] = locpos[Trk::z0]; + glopos += center(); + } } // true local to global method - from LocalParameters / -const Amg::Vector3D* Trk::PerigeeSurface::localToGlobal(const Trk::LocalParameters& locpars, - const Amg::Vector3D& glomom) const +const Amg::Vector3D* +Trk::PerigeeSurface::localToGlobal(const Trk::LocalParameters& locpars, const Amg::Vector3D& glomom) const { - if (Surface::m_transform){ - Amg::Vector3D* glopos = new Amg::Vector3D(0.,0.,0.); - localToGlobal(Amg::Vector2D(locpars[Trk::d0],locpars[Trk::z0]),glomom,*glopos); - return glopos; - } - double phi = glomom.phi(); - double x = - locpars[Trk::d0]*sin(phi) + center().x(); - double y = locpars[Trk::d0]*cos(phi) + center().y(); - double z = locpars[Trk::z0] + center().z(); - return new Amg::Vector3D(x,y,z); + if (Surface::m_transform) { + Amg::Vector3D* glopos = new Amg::Vector3D(0., 0., 0.); + localToGlobal(Amg::Vector2D(locpars[Trk::d0], locpars[Trk::z0]), glomom, *glopos); + return glopos; + } + double phi = glomom.phi(); + double x = -locpars[Trk::d0] * sin(phi) + center().x(); + double y = locpars[Trk::d0] * cos(phi) + center().y(); + double z = locpars[Trk::z0] + center().z(); + return new Amg::Vector3D(x, y, z); } // true global to local method -bool Trk::PerigeeSurface::globalToLocal(const Amg::Vector3D& glopos, - const Amg::Vector3D& glomom, - Amg::Vector2D& locpos) const +bool +Trk::PerigeeSurface::globalToLocal(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom, + Amg::Vector2D& locpos) const { - Amg::Vector3D perPos = (transform().inverse())*glopos; - double d0 = perPos.perp(); - double z0 = perPos.z(); - // decide the sign of d0 - d0 *= ((lineDirection().cross(glomom)).dot(perPos)<0.0) ? -1.0 : 1.0; - locpos[Trk::d0] = d0; - locpos[Trk::z0] = z0; - return true; + Amg::Vector3D perPos = (transform().inverse()) * glopos; + double d0 = perPos.perp(); + double z0 = perPos.z(); + // decide the sign of d0 + d0 *= ((lineDirection().cross(glomom)).dot(perPos) < 0.0) ? -1.0 : 1.0; + locpos[Trk::d0] = d0; + locpos[Trk::z0] = z0; + return true; } // return the measurement frame - this is the frame where the covariance is defined -const Amg::RotationMatrix3D Trk::PerigeeSurface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D& glomom) const -{ - Amg::RotationMatrix3D mFrame; - // construct the measurement frame - const Amg::Vector3D& measY = lineDirection(); - Amg::Vector3D measX(measY.cross(glomom).unit()); - Amg::Vector3D measDepth(measX.cross(measY)); - // assign the columnes - mFrame.col(0) = measX; - mFrame.col(1) = measY; - mFrame.col(2) = measDepth; - // return the rotation matrix - return mFrame; +const Amg::RotationMatrix3D +Trk::PerigeeSurface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D& glomom) const +{ + Amg::RotationMatrix3D mFrame; + // construct the measurement frame + const Amg::Vector3D& measY = lineDirection(); + Amg::Vector3D measX(measY.cross(glomom).unit()); + Amg::Vector3D measDepth(measX.cross(measY)); + // assign the columnes + mFrame.col(0) = measX; + mFrame.col(1) = measY; + mFrame.col(2) = measDepth; + // return the rotation matrix + return mFrame; } /** distance to surface */ -Trk::DistanceSolution Trk::PerigeeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::PerigeeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { const Amg::Vector3D& C = center(); - Amg::Vector3D S(0.,0.,1.); + Amg::Vector3D S(0., 0., 1.); double D = dir.dot(S); - double A = (1.-D)*(1.+D); - if(A==0.) { - return Trk::DistanceSolution(1,pos.perp(),false,0.); + double A = (1. - D) * (1. + D); + if (A == 0.) { + return Trk::DistanceSolution(1, pos.perp(), false, 0.); } - double sol = (pos-C).dot(D*S-dir)/A; - return Trk::DistanceSolution(1,pos.perp(),false,sol); + double sol = (pos - C).dot(D * S - dir) / A; + return Trk::DistanceSolution(1, pos.perp(), false, sol); } -Trk::DistanceSolution Trk::PerigeeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool) const +Trk::DistanceSolution +Trk::PerigeeSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool) const { - const Amg::Transform3D& T = transform(); + const Amg::Transform3D& T = transform(); - double dx = pos[0]-T(3,0) ; - double dy = pos[1]-T(3,1) ; - double A = dir[0]*dir[0]+dir[1]*dir[1]; + double dx = pos[0] - T(3, 0); + double dy = pos[1] - T(3, 1); + double A = dir[0] * dir[0] + dir[1] * dir[1]; // Step to surface // - if(A > 0.) { - return Trk::DistanceSolution(1,0.,false,-(dir[0]*dx+dir[1]*dy)/A); + if (A > 0.) { + return Trk::DistanceSolution(1, 0., false, -(dir[0] * dx + dir[1] * dy) / A); } - return Trk::DistanceSolution(1,0.,false,0.); + return Trk::DistanceSolution(1, 0., false, 0.); } // overload of ostream operator -MsgStream& Trk::PerigeeSurface::dump( MsgStream& sl ) const +MsgStream& +Trk::PerigeeSurface::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::PerigeeSurface:" << std::endl; - sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::PerigeeSurface:" << std::endl; + sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")"; + sl << std::setprecision(-1); + return sl; } // overload of ostream operator -std::ostream& Trk::PerigeeSurface::dump( std::ostream& sl ) const +std::ostream& +Trk::PerigeeSurface::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::PerigeeSurface:" << std::endl; - sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::PerigeeSurface:" << std::endl; + sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx index abbe27fb930c3f665a72f06a08b3c6174c02d4a2..9bc287bb0f56c9f68ead85af0ae34082d3b502d7 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/PlaneSurface.cxx @@ -8,226 +8,234 @@ // Trk #include "TrkSurfaces/PlaneSurface.h" -#include "TrkSurfaces/RectangleBounds.h" -#include "TrkSurfaces/TriangleBounds.h" +#include "TrkEventPrimitives/CurvilinearUVT.h" +#include "TrkEventPrimitives/LocalDirection.h" #include "TrkSurfaces/AnnulusBounds.h" -#include "TrkSurfaces/TrapezoidBounds.h" -#include "TrkSurfaces/RotatedTrapezoidBounds.h" #include "TrkSurfaces/DiamondBounds.h" #include "TrkSurfaces/EllipseBounds.h" #include "TrkSurfaces/NoBounds.h" -#include "TrkEventPrimitives/CurvilinearUVT.h" -#include "TrkEventPrimitives/LocalDirection.h" +#include "TrkSurfaces/RectangleBounds.h" +#include "TrkSurfaces/RotatedTrapezoidBounds.h" +#include "TrkSurfaces/TrapezoidBounds.h" +#include "TrkSurfaces/TriangleBounds.h" // Identifier #include "Identifier/Identifier.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> -#include <iomanip> +// STD #include "CxxUtils/sincos.h" +#include <iomanip> +#include <iostream> const Trk::NoBounds Trk::PlaneSurface::s_boundless; // default constructor -Trk::PlaneSurface::PlaneSurface() : - Trk::Surface(), - m_bounds() +Trk::PlaneSurface::PlaneSurface() + : Trk::Surface() + , m_bounds() {} // copy constructor -Trk::PlaneSurface::PlaneSurface(const PlaneSurface& psf) : - Trk::Surface(psf), - m_bounds(psf.m_bounds) +Trk::PlaneSurface::PlaneSurface(const PlaneSurface& psf) + : Trk::Surface(psf) + , m_bounds(psf.m_bounds) {} // copy constructor with shift -Trk::PlaneSurface::PlaneSurface(const PlaneSurface& psf, const Amg::Transform3D& transf) : - Trk::Surface(psf, transf), - m_bounds(psf.m_bounds) +Trk::PlaneSurface::PlaneSurface(const PlaneSurface& psf, const Amg::Transform3D& transf) + : Trk::Surface(psf, transf) + , m_bounds(psf.m_bounds) {} // constructor from CurvilinearUVT -Trk::PlaneSurface::PlaneSurface(const Amg::Vector3D& position, const CurvilinearUVT& curvUVT) : - Trk::Surface(), - m_bounds(new Trk::NoBounds()) +Trk::PlaneSurface::PlaneSurface(const Amg::Vector3D& position, const CurvilinearUVT& curvUVT) + : Trk::Surface() + , m_bounds(new Trk::NoBounds()) { - Amg::Translation3D curvilinearTranslation(position.x(), position.y(),position.z()); - // create the rotation - Amg::RotationMatrix3D curvilinearRotation; - curvilinearRotation.col(0) = curvUVT.curvU(); - curvilinearRotation.col(1) = curvUVT.curvV(); - curvilinearRotation.col(2) = curvUVT.curvT(); - // curvilinear surfaces are boundless - Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>(); - (*Trk::Surface::m_transform) = curvilinearRotation; - Trk::Surface::m_transform->pretranslate(position); + Amg::Translation3D curvilinearTranslation(position.x(), position.y(), position.z()); + // create the rotation + Amg::RotationMatrix3D curvilinearRotation; + curvilinearRotation.col(0) = curvUVT.curvU(); + curvilinearRotation.col(1) = curvUVT.curvV(); + curvilinearRotation.col(2) = curvUVT.curvT(); + // curvilinear surfaces are boundless + Trk::Surface::m_transform = std::make_unique<Amg::Transform3D>(); + (*Trk::Surface::m_transform) = curvilinearRotation; + Trk::Surface::m_transform->pretranslate(position); } // construct form TrkDetElementBase -Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement,Amg::Transform3D* transf) : - Trk::Surface(detelement), - m_bounds() +Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement, Amg::Transform3D* transf) + : Trk::Surface(detelement) + , m_bounds() { - m_transform.store(std::unique_ptr<Amg::Transform3D> (transf)); + m_transform.store(std::unique_ptr<Amg::Transform3D>(transf)); } // construct form SiDetectorElement -Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement, const Identifier& id,Amg::Transform3D* transf) : - Trk::Surface(detelement, id), - m_bounds() +Trk::PlaneSurface::PlaneSurface(const Trk::TrkDetElementBase& detelement, + const Identifier& id, + Amg::Transform3D* transf) + : Trk::Surface(detelement, id) + , m_bounds() { - m_transform.store(std::unique_ptr<Amg::Transform3D> (transf)); + m_transform.store(std::unique_ptr<Amg::Transform3D>(transf)); } // construct planar surface without bounds -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans) : - Trk::Surface(htrans), - m_bounds() +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans) + : Trk::Surface(htrans) + , m_bounds() {} // construct planar surface without bounds -Trk::PlaneSurface::PlaneSurface(std::unique_ptr<Amg::Transform3D> htrans) : - Trk::Surface(std::move(htrans)), - m_bounds() +Trk::PlaneSurface::PlaneSurface(std::unique_ptr<Amg::Transform3D> htrans) + : Trk::Surface(std::move(htrans)) + , m_bounds() {} // construct rectangle module -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, double halephi, double haleta) : - Trk::Surface(htrans), - m_bounds(new Trk::RectangleBounds(halephi, haleta)) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, double halephi, double haleta) + : Trk::Surface(htrans) + , m_bounds(new Trk::RectangleBounds(halephi, haleta)) {} // construct trapezoidal module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, double minhalephi, double maxhalephi, double haleta) : - Trk::Surface(htrans), - m_bounds(new Trk::TrapezoidBounds(minhalephi, maxhalephi, haleta)) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, double minhalephi, double maxhalephi, double haleta) + : Trk::Surface(htrans) + , m_bounds(new Trk::TrapezoidBounds(minhalephi, maxhalephi, haleta)) {} // construct annulus module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::AnnulusBounds* tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::AnnulusBounds* tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // construct rectangle surface by giving RectangleBounds -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::RectangleBounds* rbounds) : - Trk::Surface(htrans), - m_bounds(rbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::RectangleBounds* rbounds) + : Trk::Surface(htrans) + , m_bounds(rbounds) {} // construct triangle surface by giving TriangleBounds -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::TriangleBounds* rbounds) : - Trk::Surface(htrans), - m_bounds(rbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::TriangleBounds* rbounds) + : Trk::Surface(htrans) + , m_bounds(rbounds) {} // construct trapezoidal module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::TrapezoidBounds* tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::TrapezoidBounds* tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // construct rotated trapezoidal module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::RotatedTrapezoidBounds* tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::RotatedTrapezoidBounds* tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // construct diamond module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::DiamondBounds* tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::DiamondBounds* tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // construct elliptic module with parameters -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::EllipseBounds* tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::EllipseBounds* tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // construct module with shared boundaries - change to reference -Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::SharedObject<const Trk::SurfaceBounds>& tbounds) : - Trk::Surface(htrans), - m_bounds(tbounds) +Trk::PlaneSurface::PlaneSurface(Amg::Transform3D* htrans, Trk::SharedObject<const Trk::SurfaceBounds>& tbounds) + : Trk::Surface(htrans) + , m_bounds(tbounds) {} // destructor (will call destructor from base class which deletes objects) -Trk::PlaneSurface::~PlaneSurface() -{} +Trk::PlaneSurface::~PlaneSurface() {} -Trk::PlaneSurface& Trk::PlaneSurface::operator=(const Trk::PlaneSurface& psf){ +Trk::PlaneSurface& +Trk::PlaneSurface::operator=(const Trk::PlaneSurface& psf) +{ - if (this!=&psf){ + if (this != &psf) { Trk::Surface::operator=(psf); - m_bounds = psf.m_bounds; + m_bounds = psf.m_bounds; } return *this; - } -bool Trk::PlaneSurface::operator==(const Trk::Surface& sf) const +bool +Trk::PlaneSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::PlaneSurface* psf = dynamic_cast<const Trk::PlaneSurface*>(&sf); - if (!psf) return false; - if (psf==this) return true; + if (!psf) + return false; + if (psf == this) + return true; bool transfEqual(transform().isApprox(psf->transform(), 10e-8)); bool centerEqual = center() == psf->center(); bool boundsEqual = bounds() == psf->bounds(); - return transfEqual&¢erEqual&&boundsEqual; + return transfEqual && centerEqual && boundsEqual; } -void Trk::PlaneSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const +void +Trk::PlaneSurface::localToGlobal(const Amg::Vector2D& locpos, const Amg::Vector3D&, Amg::Vector3D& glopos) const { - Amg::Vector3D loc3Dframe(locpos[Trk::locX], locpos[Trk::locY], 0.); - glopos = transform()*loc3Dframe; + Amg::Vector3D loc3Dframe(locpos[Trk::locX], locpos[Trk::locY], 0.); + glopos = transform() * loc3Dframe; } -bool Trk::PlaneSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const +bool +Trk::PlaneSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D&, Amg::Vector2D& locpos) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopos; - locpos = Amg::Vector2D(loc3Dframe.x(), loc3Dframe.y()); - return (( loc3Dframe.z()*loc3Dframe.z() > s_onSurfaceTolerance*s_onSurfaceTolerance ) ? false : true ); + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopos; + locpos = Amg::Vector2D(loc3Dframe.x(), loc3Dframe.y()); + return ((loc3Dframe.z() * loc3Dframe.z() > s_onSurfaceTolerance * s_onSurfaceTolerance) ? false : true); } - -void Trk::PlaneSurface::localToGlobalDirection(const Trk::LocalDirection& locdir, Amg::Vector3D& globdir ) const +void +Trk::PlaneSurface::localToGlobalDirection(const Trk::LocalDirection& locdir, Amg::Vector3D& globdir) const { CxxUtils::sincos scXZ(locdir.angleXZ()); CxxUtils::sincos scYZ(locdir.angleYZ()); - double norm = 1./sqrt( scYZ.cs*scYZ.cs*scXZ.sn*scXZ.sn + scYZ.sn*scYZ.sn ); + double norm = 1. / sqrt(scYZ.cs * scYZ.cs * scXZ.sn * scXZ.sn + scYZ.sn * scYZ.sn); // decide on the sign - double sign = (scXZ.sn < 0.) ? -1. : 1. ; + double sign = (scXZ.sn < 0.) ? -1. : 1.; // now calculate the GlobalDirection in the global frame - globdir = transform().linear()*Amg::Vector3D(sign * scXZ.cs*scYZ.sn*norm,sign * scXZ.sn*scYZ.cs*norm,sign * scXZ.sn*scYZ.sn*norm); + globdir = + transform().linear() * + Amg::Vector3D(sign * scXZ.cs * scYZ.sn * norm, sign * scXZ.sn * scYZ.cs * norm, sign * scXZ.sn * scYZ.sn * norm); } -void Trk::PlaneSurface::globalToLocalDirection(const Amg::Vector3D& glodir, Trk::LocalDirection& ldir ) const +void +Trk::PlaneSurface::globalToLocalDirection(const Amg::Vector3D& glodir, Trk::LocalDirection& ldir) const { // bring the global direction into the surface frame - Amg::Vector3D d(transform().inverse().linear()*glodir); - ldir = Trk::LocalDirection(atan2(d.z(),d.x()), atan2(d.z(),d.y())); + Amg::Vector3D d(transform().inverse().linear() * glodir); + ldir = Trk::LocalDirection(atan2(d.z(), d.x()), atan2(d.z(), d.y())); } -bool Trk::PlaneSurface::isOnSurface(const Amg::Vector3D& glopo, - Trk::BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::PlaneSurface::isOnSurface(const Amg::Vector3D& glopo, Trk::BoundaryCheck bchk, double tol1, double tol2) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopo; - if ( fabs(loc3Dframe(2)) > (s_onSurfaceTolerance + tol1) ) return false; - return ( bchk ? bounds().inside(Amg::Vector2D(loc3Dframe(0),loc3Dframe(1)),tol1,tol2) : true); - + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopo; + if (fabs(loc3Dframe(2)) > (s_onSurfaceTolerance + tol1)) + return false; + return (bchk ? bounds().inside(Amg::Vector2D(loc3Dframe(0), loc3Dframe(1)), tol1, tol2) : true); } - /** distance to surface */ -Trk::DistanceSolution Trk::PlaneSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::PlaneSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { static const double tol = 0.001; @@ -235,50 +243,54 @@ Trk::DistanceSolution Trk::PlaneSurface::straightLineDistanceEstimate(const Amg: const double d = (pos - center()).dot(N); - const double A = dir.dot(N);//ignore sign - if(A==0.) { // direction parallel to surface - if ( fabs(d)<tol ) { - return Trk::DistanceSolution(1,0.,true,0.); + const double A = dir.dot(N); // ignore sign + if (A == 0.) { // direction parallel to surface + if (fabs(d) < tol) { + return Trk::DistanceSolution(1, 0., true, 0.); } else { - return Trk::DistanceSolution(0,d,true,0.); + return Trk::DistanceSolution(0, d, true, 0.); } } - return Trk::DistanceSolution(1,d,true,-d/A); + return Trk::DistanceSolution(1, d, true, -d / A); } -Trk::DistanceSolution Trk::PlaneSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool bound) const +Trk::DistanceSolution +Trk::PlaneSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir, bool bound) const { - const Amg::Transform3D& T = transform() ; - double Az[3] = {T(0,2),T(1,2),T(2,2)}; + const Amg::Transform3D& T = transform(); + double Az[3] = { T(0, 2), T(1, 2), T(2, 2) }; // Transformation to plane system coordinates // - double dx = pos[0]-T(0,3) ; - double dy = pos[1]-T(1,3) ; - double dz = pos[2]-T(2,3) ; - double z = dx*Az[0]+dy*Az[1]+dz*Az[2] ; - double az = dir[0]*Az[0]+dir[1]*Az[1]+dir[2]*Az[2]; + double dx = pos[0] - T(0, 3); + double dy = pos[1] - T(1, 3); + double dz = pos[2] - T(2, 3); + double z = dx * Az[0] + dy * Az[1] + dz * Az[2]; + double az = dir[0] * Az[0] + dir[1] * Az[1] + dir[2] * Az[2]; // Step to surface // - int ns = 0; - double s = 0.; if(az!=0.) {s =-z/az; ns = 1;} + int ns = 0; + double s = 0.; + if (az != 0.) { + s = -z / az; + ns = 1; + } double dist = fabs(z); - if (!bound) return Trk::DistanceSolution(ns,fabs(z),true,s); + if (!bound) + return Trk::DistanceSolution(ns, fabs(z), true, s); // Min distance to surface // - double x = dx*T(0,0)+dy*T(1,0)+dz*T(2,0); - double y = dx*T(0,1)+dy*T(1,1)+dz*T(2,1); + double x = dx * T(0, 0) + dy * T(1, 0) + dz * T(2, 0); + double y = dx * T(0, 1) + dy * T(1, 1) + dz * T(2, 1); - Amg::Vector2D lp(x,y); + Amg::Vector2D lp(x, y); - double d = bounds().minDistance(lp); - if (d>0.) dist = sqrt(dist*dist+d*d); + double d = bounds().minDistance(lp); + if (d > 0.) + dist = sqrt(dist * dist + d * d); - return Trk::DistanceSolution(ns,dist,true,s); + return Trk::DistanceSolution(ns, dist, true, s); } - - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/RectangleBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/RectangleBounds.cxx index 27a51d934051b9128b55e89789a80f001fe7cacf..f6a5cce5a5b79d90799a8a29629c41c2c55c4c8a 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/RectangleBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/RectangleBounds.cxx @@ -8,80 +8,86 @@ // Trk #include "TrkSurfaces/RectangleBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> // default constructor -Trk::RectangleBounds::RectangleBounds() : - m_boundValues(RectangleBounds::bv_length,0.) +Trk::RectangleBounds::RectangleBounds() + : m_boundValues(RectangleBounds::bv_length, 0.) {} // rectangle constructor -Trk::RectangleBounds::RectangleBounds(double halex, double haley) : - m_boundValues(RectangleBounds::bv_length,0.) +Trk::RectangleBounds::RectangleBounds(double halex, double haley) + : m_boundValues(RectangleBounds::bv_length, 0.) { - m_boundValues[RectangleBounds::bv_halfX] = halex; - m_boundValues[RectangleBounds::bv_halfY] = haley; + m_boundValues[RectangleBounds::bv_halfX] = halex; + m_boundValues[RectangleBounds::bv_halfY] = haley; } // copy constructor -Trk::RectangleBounds::RectangleBounds(const RectangleBounds& recbo) : - Trk::SurfaceBounds(), - m_boundValues(recbo.m_boundValues) +Trk::RectangleBounds::RectangleBounds(const RectangleBounds& recbo) + : Trk::SurfaceBounds() + , m_boundValues(recbo.m_boundValues) {} // destructor -Trk::RectangleBounds::~RectangleBounds() -{} +Trk::RectangleBounds::~RectangleBounds() {} -Trk::RectangleBounds& Trk::RectangleBounds::operator=(const RectangleBounds& recbo) +Trk::RectangleBounds& +Trk::RectangleBounds::operator=(const RectangleBounds& recbo) { - if (this!=&recbo) + if (this != &recbo) m_boundValues = recbo.m_boundValues; return *this; } -bool Trk::RectangleBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::RectangleBounds::operator==(const Trk::SurfaceBounds& sbo) const { - // check the type first not to compare apples with oranges + // check the type first not to compare apples with oranges const Trk::RectangleBounds* recbo = dynamic_cast<const Trk::RectangleBounds*>(&sbo); - if (!recbo) return false; - return ( m_boundValues == recbo->m_boundValues ); + if (!recbo) + return false; + return (m_boundValues == recbo->m_boundValues); } -double Trk::RectangleBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::RectangleBounds::minDistance(const Amg::Vector2D& pos) const { - double dx = fabs(pos[0])-m_boundValues[RectangleBounds::bv_halfX]; - double dy = fabs(pos[1])-m_boundValues[RectangleBounds::bv_halfY]; + double dx = fabs(pos[0]) - m_boundValues[RectangleBounds::bv_halfX]; + double dy = fabs(pos[1]) - m_boundValues[RectangleBounds::bv_halfY]; - if (dx <= 0. || dy <=0.) { - if (dx > dy) return dx; - else return dy; + if (dx <= 0. || dy <= 0.) { + if (dx > dy) + return dx; + else + return dy; } - return sqrt(dx*dx+dy*dy); + return sqrt(dx * dx + dy * dy); } // ostream operator overload -MsgStream& Trk::RectangleBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::RectangleBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RectangleBounds: (halflenghtX, halflengthY) = " << "(" << m_boundValues[RectangleBounds::bv_halfX] << ", " << m_boundValues[RectangleBounds::bv_halfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RectangleBounds: (halflenghtX, halflengthY) = " + << "(" << m_boundValues[RectangleBounds::bv_halfX] << ", " << m_boundValues[RectangleBounds::bv_halfY] << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::RectangleBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::RectangleBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RectangleBounds: (halflenghtX, halflengthY) = " << "(" << m_boundValues[RectangleBounds::bv_halfX] << ", " << m_boundValues[RectangleBounds::bv_halfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RectangleBounds: (halflenghtX, halflengthY) = " + << "(" << m_boundValues[RectangleBounds::bv_halfX] << ", " << m_boundValues[RectangleBounds::bv_halfY] << ")"; + sl << std::setprecision(-1); + return sl; } - - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedDiamondBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedDiamondBounds.cxx index 918511941718eecb04af75366fdf6cc08a742e3c..676062fbfc6e04f2a0d191a39f2092049d4d172b 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedDiamondBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedDiamondBounds.cxx @@ -6,186 +6,211 @@ // RotatedDiamondBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/RotatedDiamondBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> // default constructor -Trk::RotatedDiamondBounds::RotatedDiamondBounds() : - m_boundValues(RotatedDiamondBounds::bv_length, 0.), - m_alpha1(0.), - m_alpha2(0.) +Trk::RotatedDiamondBounds::RotatedDiamondBounds() + : m_boundValues(RotatedDiamondBounds::bv_length, 0.) + , m_alpha1(0.) + , m_alpha2(0.) {} // constructor from arguments I -Trk::RotatedDiamondBounds::RotatedDiamondBounds(double minhalex, double medhalex, double maxhalex, double haley1, double haley2) : - m_boundValues(RotatedDiamondBounds::bv_length, 0.), - m_alpha1(0.), - m_alpha2(0.) +Trk::RotatedDiamondBounds::RotatedDiamondBounds(double minhalex, + double medhalex, + double maxhalex, + double haley1, + double haley2) + : m_boundValues(RotatedDiamondBounds::bv_length, 0.) + , m_alpha1(0.) + , m_alpha2(0.) { m_boundValues[RotatedDiamondBounds::bv_minHalfX] = minhalex; - m_boundValues[RotatedDiamondBounds::bv_medHalfX] = medhalex; - m_boundValues[RotatedDiamondBounds::bv_maxHalfX] = maxhalex; - m_boundValues[RotatedDiamondBounds::bv_halfY1] = haley1; - m_boundValues[RotatedDiamondBounds::bv_halfY2] = haley2; - if (minhalex > maxhalex) - swap(m_boundValues[RotatedDiamondBounds::bv_minHalfX], m_boundValues[RotatedDiamondBounds::bv_maxHalfX]); + m_boundValues[RotatedDiamondBounds::bv_medHalfX] = medhalex; + m_boundValues[RotatedDiamondBounds::bv_maxHalfX] = maxhalex; + m_boundValues[RotatedDiamondBounds::bv_halfY1] = haley1; + m_boundValues[RotatedDiamondBounds::bv_halfY2] = haley2; + if (minhalex > maxhalex) + swap(m_boundValues[RotatedDiamondBounds::bv_minHalfX], m_boundValues[RotatedDiamondBounds::bv_maxHalfX]); initCache(); - } // copy constructor -Trk::RotatedDiamondBounds::RotatedDiamondBounds(const RotatedDiamondBounds& diabo) : - Trk::SurfaceBounds(), - m_boundValues(diabo.m_boundValues), - m_alpha1(diabo.m_alpha1), - m_alpha2(diabo.m_alpha2) +Trk::RotatedDiamondBounds::RotatedDiamondBounds(const RotatedDiamondBounds& diabo) + : Trk::SurfaceBounds() + , m_boundValues(diabo.m_boundValues) + , m_alpha1(diabo.m_alpha1) + , m_alpha2(diabo.m_alpha2) {} // destructor -Trk::RotatedDiamondBounds::~RotatedDiamondBounds() -{} +Trk::RotatedDiamondBounds::~RotatedDiamondBounds() {} -Trk::RotatedDiamondBounds& Trk::RotatedDiamondBounds::operator=(const RotatedDiamondBounds& diabo) +Trk::RotatedDiamondBounds& +Trk::RotatedDiamondBounds::operator=(const RotatedDiamondBounds& diabo) { - if (this!=&diabo){ - m_boundValues = diabo.m_boundValues; - m_alpha1 = diabo.m_alpha1; - m_alpha2 = diabo.m_alpha2; + if (this != &diabo) { + m_boundValues = diabo.m_boundValues; + m_alpha1 = diabo.m_alpha1; + m_alpha2 = diabo.m_alpha2; } return *this; } -bool Trk::RotatedDiamondBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::RotatedDiamondBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::RotatedDiamondBounds* diabo = dynamic_cast<const Trk::RotatedDiamondBounds*>(&sbo); - if (!diabo) return false; + if (!diabo) + return false; return (m_boundValues == diabo->m_boundValues); - } +} // checking if inside bounds (Full symmetrical Diamond) -bool Trk::RotatedDiamondBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::RotatedDiamondBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const { - return this->insideFull(locpo, tol1, tol2); + return this->insideFull(locpo, tol1, tol2); } // checking if inside bounds (Full symmetrical Diamond) -bool Trk::RotatedDiamondBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::RotatedDiamondBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const { // the cases: // (0) - if (!m_boundValues[RotatedDiamondBounds::bv_halfY1] && !m_boundValues[RotatedDiamondBounds::bv_minHalfX]) return false; + if (!m_boundValues[RotatedDiamondBounds::bv_halfY1] && !m_boundValues[RotatedDiamondBounds::bv_minHalfX]) + return false; // (1) - if (locpo[Trk::locX] < -2. * m_boundValues[RotatedDiamondBounds::bv_halfY1] - tol2) return false; - if (locpo[Trk::locX] > 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2] + tol2) return false; + if (locpo[Trk::locX] < -2. * m_boundValues[RotatedDiamondBounds::bv_halfY1] - tol2) + return false; + if (locpo[Trk::locX] > 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2] + tol2) + return false; // (2) - if (fabs(locpo[Trk::locY]) > (m_boundValues[RotatedDiamondBounds::bv_medHalfX] + tol1)) return false; + if (fabs(locpo[Trk::locY]) > (m_boundValues[RotatedDiamondBounds::bv_medHalfX] + tol1)) + return false; // (3) - if (fabs(locpo[Trk::locY]) < (fmin(m_boundValues[RotatedDiamondBounds::bv_minHalfX],m_boundValues[RotatedDiamondBounds::bv_maxHalfX]) - tol1)) return true; + if (fabs(locpo[Trk::locY]) < + (fmin(m_boundValues[RotatedDiamondBounds::bv_minHalfX], m_boundValues[RotatedDiamondBounds::bv_maxHalfX]) - tol1)) + return true; // (4) /** use basic calculation of a straight line */ - if (locpo[Trk::locX]<0) { - double k = m_boundValues[RotatedDiamondBounds::bv_halfY1]>0. ? (m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_minHalfX])/2/m_boundValues[RotatedDiamondBounds::bv_halfY1] : 0.; - return ( fabs(locpo[Trk::locY]) <= m_boundValues[RotatedDiamondBounds::bv_medHalfX]-k*fabs(locpo[Trk::locX]) ); + if (locpo[Trk::locX] < 0) { + double k = + m_boundValues[RotatedDiamondBounds::bv_halfY1] > 0. + ? (m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_minHalfX]) / 2 / + m_boundValues[RotatedDiamondBounds::bv_halfY1] + : 0.; + return (fabs(locpo[Trk::locY]) <= m_boundValues[RotatedDiamondBounds::bv_medHalfX] - k * fabs(locpo[Trk::locX])); } else { - double k = m_boundValues[RotatedDiamondBounds::bv_halfY2]>0. ? (m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_maxHalfX])/2/m_boundValues[RotatedDiamondBounds::bv_halfY2] : 0.; - return ( fabs(locpo[Trk::locY]) <= m_boundValues[RotatedDiamondBounds::bv_medHalfX]-k*fabs(locpo[Trk::locX]) ); + double k = + m_boundValues[RotatedDiamondBounds::bv_halfY2] > 0. + ? (m_boundValues[RotatedDiamondBounds::bv_medHalfX] - m_boundValues[RotatedDiamondBounds::bv_maxHalfX]) / 2 / + m_boundValues[RotatedDiamondBounds::bv_halfY2] + : 0.; + return (fabs(locpo[Trk::locY]) <= m_boundValues[RotatedDiamondBounds::bv_medHalfX] - k * fabs(locpo[Trk::locX])); } } // opening angle in point A -double Trk::RotatedDiamondBounds::alpha1() const +double +Trk::RotatedDiamondBounds::alpha1() const { - return m_alpha1; + return m_alpha1; } // opening angle in point A' -double Trk::RotatedDiamondBounds::alpha2() const +double +Trk::RotatedDiamondBounds::alpha2() const { - return m_alpha2; + return m_alpha2; } -double Trk::RotatedDiamondBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::RotatedDiamondBounds::minDistance(const Amg::Vector2D& pos) const { const int Np = 6; - double y1 = 2.*m_boundValues[RotatedDiamondBounds::bv_halfY1]; - double y2 = 2.*m_boundValues[RotatedDiamondBounds::bv_halfY2]; + double y1 = 2. * m_boundValues[RotatedDiamondBounds::bv_halfY1]; + double y2 = 2. * m_boundValues[RotatedDiamondBounds::bv_halfY2]; - double X [6] = {-m_boundValues[RotatedDiamondBounds::bv_minHalfX], - -m_boundValues[RotatedDiamondBounds::bv_medHalfX], - -m_boundValues[RotatedDiamondBounds::bv_maxHalfX], - m_boundValues[RotatedDiamondBounds::bv_maxHalfX], - m_boundValues[RotatedDiamondBounds::bv_medHalfX], - m_boundValues[RotatedDiamondBounds::bv_minHalfX]}; - double Y [6] = { -y1, 0., y2, y2, 0., -y1}; + double X[6] = { -m_boundValues[RotatedDiamondBounds::bv_minHalfX], -m_boundValues[RotatedDiamondBounds::bv_medHalfX], + -m_boundValues[RotatedDiamondBounds::bv_maxHalfX], m_boundValues[RotatedDiamondBounds::bv_maxHalfX], + m_boundValues[RotatedDiamondBounds::bv_medHalfX], m_boundValues[RotatedDiamondBounds::bv_minHalfX] }; + double Y[6] = { -y1, 0., y2, y2, 0., -y1 }; double dm = 1.e+20; - double Ao = 0.; - bool in = true; - - for (int i=0; i!=Np; ++i) { - - int j = i+1; if (j==Np) j=0; -// interchange locx and locy - double x = X[i]-pos[1]; - double y = Y[i]-pos[0]; - double dx = X[j]-X[i] ; - double dy = Y[j]-Y[i] ; - double A = x*dy-y*dx ; - double S =-(x*dx+y*dy); + double Ao = 0.; + bool in = true; + + for (int i = 0; i != Np; ++i) { + + int j = i + 1; + if (j == Np) + j = 0; + // interchange locx and locy + double x = X[i] - pos[1]; + double y = Y[i] - pos[0]; + double dx = X[j] - X[i]; + double dy = Y[j] - Y[i]; + double A = x * dy - y * dx; + double S = -(x * dx + y * dy); if (S <= 0.) { - double d = x*x+y*y; - if (d<dm) dm=d; - } - else { - double a = dx*dx+dy*dy; + double d = x * x + y * y; + if (d < dm) + dm = d; + } else { + double a = dx * dx + dy * dy; if (S <= a) { - double d = (A*A)/a; - if (d<dm) dm=d; + double d = (A * A) / a; + if (d < dm) + dm = d; } } - if (i && in && Ao*A < 0.) in = false; + if (i && in && Ao * A < 0.) + in = false; Ao = A; } - if (in) return -sqrt(dm); + if (in) + return -sqrt(dm); return sqrt(dm); } // ostream operator overload -MsgStream& Trk::RotatedDiamondBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::RotatedDiamondBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RotatedDiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; - sl << "(" << m_boundValues[RotatedDiamondBounds::bv_minHalfX] << ", " - << m_boundValues[RotatedDiamondBounds::bv_medHalfX] <<", " - << m_boundValues[RotatedDiamondBounds::bv_maxHalfX] << ", " - << m_boundValues[RotatedDiamondBounds::bv_halfY1] << ", " - << m_boundValues[RotatedDiamondBounds::bv_halfY2] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RotatedDiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; + sl << "(" << m_boundValues[RotatedDiamondBounds::bv_minHalfX] << ", " + << m_boundValues[RotatedDiamondBounds::bv_medHalfX] << ", " << m_boundValues[RotatedDiamondBounds::bv_maxHalfX] + << ", " << m_boundValues[RotatedDiamondBounds::bv_halfY1] << ", " << m_boundValues[RotatedDiamondBounds::bv_halfY2] + << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::RotatedDiamondBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::RotatedDiamondBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RotatedDiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; - sl << "(" << m_boundValues[RotatedDiamondBounds::bv_minHalfX] << ", " - << m_boundValues[RotatedDiamondBounds::bv_medHalfX] <<", " - << m_boundValues[RotatedDiamondBounds::bv_maxHalfX] << ", " - << m_boundValues[RotatedDiamondBounds::bv_halfY1] << ", " - << m_boundValues[RotatedDiamondBounds::bv_halfY2] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RotatedDiamondBounds: (minHlenghtX, medHlengthX, maxHlengthX, hlengthY1, hlengthY2 ) = "; + sl << "(" << m_boundValues[RotatedDiamondBounds::bv_minHalfX] << ", " + << m_boundValues[RotatedDiamondBounds::bv_medHalfX] << ", " << m_boundValues[RotatedDiamondBounds::bv_maxHalfX] + << ", " << m_boundValues[RotatedDiamondBounds::bv_halfY1] << ", " << m_boundValues[RotatedDiamondBounds::bv_halfY2] + << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedTrapezoidBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedTrapezoidBounds.cxx index 255f652463863dc3f8e634c3cd0941ae42076e93..ca6753afbfa19f3e59d810a17f07a91cabdc6d9a 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedTrapezoidBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/RotatedTrapezoidBounds.cxx @@ -6,171 +6,176 @@ // RotatedTrapezoidBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/RotatedTrapezoidBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> // default constructor -Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds() : - m_boundValues(RotatedTrapezoidBounds::bv_length, 0.), - m_kappa(0.), - m_delta(0.) +Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds() + : m_boundValues(RotatedTrapezoidBounds::bv_length, 0.) + , m_kappa(0.) + , m_delta(0.) {} // constructor from arguments I -Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex) : - m_boundValues(RotatedTrapezoidBounds::bv_length, 0.), - m_kappa(0.), - m_delta(0.) +Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(double halex, double minhalex, double maxhalex) + : m_boundValues(RotatedTrapezoidBounds::bv_length, 0.) + , m_kappa(0.) + , m_delta(0.) { - m_boundValues[RotatedTrapezoidBounds::bv_halfX] = fabs(halex); - m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] = fabs(minhalex); - m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] = fabs(maxhalex); - // swap if needed - if (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] > m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]) - swap(m_boundValues[RotatedTrapezoidBounds::bv_minHalfY], m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); - // assign kappa and delta - initCache(); + m_boundValues[RotatedTrapezoidBounds::bv_halfX] = fabs(halex); + m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] = fabs(minhalex); + m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] = fabs(maxhalex); + // swap if needed + if (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] > m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]) + swap(m_boundValues[RotatedTrapezoidBounds::bv_minHalfY], m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]); + // assign kappa and delta + initCache(); } - // copy constructor -Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(const RotatedTrapezoidBounds& trabo) : - Trk::SurfaceBounds(), - m_boundValues(trabo.m_boundValues), - m_kappa(trabo.m_kappa), - m_delta(trabo.m_delta) +Trk::RotatedTrapezoidBounds::RotatedTrapezoidBounds(const RotatedTrapezoidBounds& trabo) + : Trk::SurfaceBounds() + , m_boundValues(trabo.m_boundValues) + , m_kappa(trabo.m_kappa) + , m_delta(trabo.m_delta) {} // destructor -Trk::RotatedTrapezoidBounds::~RotatedTrapezoidBounds() -{} +Trk::RotatedTrapezoidBounds::~RotatedTrapezoidBounds() {} -Trk::RotatedTrapezoidBounds& Trk::RotatedTrapezoidBounds::operator=(const RotatedTrapezoidBounds& trabo) +Trk::RotatedTrapezoidBounds& +Trk::RotatedTrapezoidBounds::operator=(const RotatedTrapezoidBounds& trabo) { - if (this!=&trabo) { - m_boundValues = trabo.m_boundValues; - m_kappa = trabo.m_kappa; - m_delta = trabo.m_delta; + if (this != &trabo) { + m_boundValues = trabo.m_boundValues; + m_kappa = trabo.m_kappa; + m_delta = trabo.m_delta; } return *this; } -bool Trk::RotatedTrapezoidBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::RotatedTrapezoidBounds::operator==(const Trk::SurfaceBounds& sbo) const { - // check the type first not to compare apples with oranges - const Trk::RotatedTrapezoidBounds* trabo = dynamic_cast<const Trk::RotatedTrapezoidBounds*>(&sbo); - if (!trabo) return false; - return (m_boundValues == trabo->m_boundValues); + // check the type first not to compare apples with oranges + const Trk::RotatedTrapezoidBounds* trabo = dynamic_cast<const Trk::RotatedTrapezoidBounds*>(&sbo); + if (!trabo) + return false; + return (m_boundValues == trabo->m_boundValues); } // checking if inside bounds -bool Trk::RotatedTrapezoidBounds::inside(const Amg::Vector2D& locpo, - double tol1, - double tol2) const +bool +Trk::RotatedTrapezoidBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const { // the cases: double fabsX = fabs(locpo[Trk::locX]); double fabsY = fabs(locpo[Trk::locY]); // (1) a fast FALSE - if (fabsX > (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + tol1)) return false; + if (fabsX > (m_boundValues[RotatedTrapezoidBounds::bv_halfX] + tol1)) + return false; // (2) a fast FALSE - if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + tol2)) return false; + if (fabsY > (m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + tol2)) + return false; // (3) a fast TRUE - if (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] - tol2)) return true; + if (fabsY < (m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] - tol2)) + return true; // (4) it is inside the rectangular shape solve the isBelow return (isBelow(locpo[Trk::locX], fabsY, tol1, tol2)); - } - - // checking if local point lies above a line -bool Trk::RotatedTrapezoidBounds::isBelow(double locX, - double fabsLocY, - double tol1, - double tol2) const +bool +Trk::RotatedTrapezoidBounds::isBelow(double locX, double fabsLocY, double tol1, double tol2) const { - // the most tolerant approach for tol1 and tol2 - return ((m_kappa * (locX + tol1) + m_delta) > fabsLocY-tol2); + // the most tolerant approach for tol1 and tol2 + return ((m_kappa * (locX + tol1) + m_delta) > fabsLocY - tol2); } -double Trk::RotatedTrapezoidBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::RotatedTrapezoidBounds::minDistance(const Amg::Vector2D& pos) const { const int Np = 4; - double X[4] = {-m_boundValues[RotatedTrapezoidBounds::bv_halfX], - -m_boundValues[RotatedTrapezoidBounds::bv_halfX], - m_boundValues[RotatedTrapezoidBounds::bv_halfX], - m_boundValues[RotatedTrapezoidBounds::bv_halfX]}; - double Y[4] = {-m_boundValues[RotatedTrapezoidBounds::bv_minHalfY], + double X[4] = { -m_boundValues[RotatedTrapezoidBounds::bv_halfX], + -m_boundValues[RotatedTrapezoidBounds::bv_halfX], + m_boundValues[RotatedTrapezoidBounds::bv_halfX], + m_boundValues[RotatedTrapezoidBounds::bv_halfX] }; + double Y[4] = { -m_boundValues[RotatedTrapezoidBounds::bv_minHalfY], m_boundValues[RotatedTrapezoidBounds::bv_minHalfY], - m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY], - -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY]}; + m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY], + -m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] }; double dm = 1.e+20; - double Ao = 0.; - bool in = true; + double Ao = 0.; + bool in = true; - for (int i=0; i!=Np; ++i) { + for (int i = 0; i != Np; ++i) { - int j = i+1; if (j==Np) j=0; + int j = i + 1; + if (j == Np) + j = 0; - double x = X[i]-pos[0]; - double y = Y[i]-pos[1]; - double dx = X[j]-X[i] ; - double dy = Y[j]-Y[i] ; - double A = x*dy-y*dx ; - double S =-(x*dx+y*dy); + double x = X[i] - pos[0]; + double y = Y[i] - pos[1]; + double dx = X[j] - X[i]; + double dy = Y[j] - Y[i]; + double A = x * dy - y * dx; + double S = -(x * dx + y * dy); if (S <= 0.) { - double d = x*x+y*y; - if (d<dm) dm=d; - } - else { - double a = dx*dx+dy*dy; + double d = x * x + y * y; + if (d < dm) + dm = d; + } else { + double a = dx * dx + dy * dy; if (S <= a) { - double d = (A*A)/a; - if (d<dm) dm=d; + double d = (A * A) / a; + if (d < dm) + dm = d; } } - if (i && in && Ao*A < 0.) in = false; + if (i && in && Ao * A < 0.) + in = false; Ao = A; } - if (in) return -sqrt (dm); - else return sqrt(dm); + if (in) + return -sqrt(dm); + else + return sqrt(dm); } // ostream operator overload -MsgStream& Trk::RotatedTrapezoidBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::RotatedTrapezoidBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = " << "(" - << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", " - << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " - << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = " + << "(" << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", " + << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::RotatedTrapezoidBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::RotatedTrapezoidBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = " << "(" - << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", " - << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " - << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::RotatedTrapezoidBounds: (halfX, minHalfX, maxHalfY) = " + << "(" << m_boundValues[RotatedTrapezoidBounds::bv_halfX] << ", " + << m_boundValues[RotatedTrapezoidBounds::bv_minHalfY] << ", " << m_boundValues[RotatedTrapezoidBounds::bv_maxHalfY] + << ")"; + sl << std::setprecision(-1); + return sl; } - - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/StraightLineSurface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/StraightLineSurface.cxx index 9bdc98f26d2707e90dc4f02acacbcb72873e0618..29853d4475c5440baac7274f07326601219c58ed 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/StraightLineSurface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/StraightLineSurface.cxx @@ -11,84 +11,85 @@ #include "TrkSurfaces/CylinderBounds.h" // Identifier #include "Identifier/Identifier.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> const Trk::NoBounds Trk::StraightLineSurface::s_boundless; // default constructor -Trk::StraightLineSurface::StraightLineSurface() : - Surface(), - m_lineDirection(nullptr), - m_bounds() +Trk::StraightLineSurface::StraightLineSurface() + : Surface() + , m_lineDirection(nullptr) + , m_bounds() {} // constructors by arguments: boundless surface -Trk::StraightLineSurface::StraightLineSurface(Amg::Transform3D* htrans) : - Surface(htrans), - m_lineDirection(nullptr), - m_bounds() +Trk::StraightLineSurface::StraightLineSurface(Amg::Transform3D* htrans) + : Surface(htrans) + , m_lineDirection(nullptr) + , m_bounds() {} // constructors by arguments: boundless surface -Trk::StraightLineSurface::StraightLineSurface(std::unique_ptr<Amg::Transform3D> htrans) : - Surface(std::move(htrans)), - m_lineDirection(nullptr), - m_bounds() +Trk::StraightLineSurface::StraightLineSurface(std::unique_ptr<Amg::Transform3D> htrans) + : Surface(std::move(htrans)) + , m_lineDirection(nullptr) + , m_bounds() {} // constructors by arguments -Trk::StraightLineSurface::StraightLineSurface(Amg::Transform3D* htrans, double radius, double halez) : - Surface(htrans), - m_lineDirection(nullptr), - m_bounds(new Trk::CylinderBounds(radius, halez)) +Trk::StraightLineSurface::StraightLineSurface(Amg::Transform3D* htrans, double radius, double halez) + : Surface(htrans) + , m_lineDirection(nullptr) + , m_bounds(new Trk::CylinderBounds(radius, halez)) {} // dummy implementation -Trk::StraightLineSurface::StraightLineSurface(const Trk::TrkDetElementBase& detelement, const Identifier& id) : - Surface(detelement,id), - m_lineDirection(nullptr), - m_bounds() +Trk::StraightLineSurface::StraightLineSurface(const Trk::TrkDetElementBase& detelement, const Identifier& id) + : Surface(detelement, id) + , m_lineDirection(nullptr) + , m_bounds() {} -//copy constructor -Trk::StraightLineSurface::StraightLineSurface(const Trk::StraightLineSurface& slsf): - Surface(slsf), - m_lineDirection(nullptr), - m_bounds(slsf.m_bounds) +// copy constructor +Trk::StraightLineSurface::StraightLineSurface(const Trk::StraightLineSurface& slsf) + : Surface(slsf) + , m_lineDirection(nullptr) + , m_bounds(slsf.m_bounds) {} // copy constructor with shift -Trk::StraightLineSurface::StraightLineSurface(const StraightLineSurface& csf, const Amg::Transform3D& transf) : - Surface(csf, transf), - m_lineDirection(nullptr), - m_bounds(csf.m_bounds) +Trk::StraightLineSurface::StraightLineSurface(const StraightLineSurface& csf, const Amg::Transform3D& transf) + : Surface(csf, transf) + , m_lineDirection(nullptr) + , m_bounds(csf.m_bounds) {} // destructor (will call destructor from base class which deletes objects) -Trk::StraightLineSurface::~StraightLineSurface() -{ -} +Trk::StraightLineSurface::~StraightLineSurface() {} // assignment operator -Trk::StraightLineSurface& Trk::StraightLineSurface::operator=(const Trk::StraightLineSurface& slsf) +Trk::StraightLineSurface& +Trk::StraightLineSurface::operator=(const Trk::StraightLineSurface& slsf) { - if (this!=&slsf){ - m_lineDirection.store(nullptr); - Trk::Surface::operator=(slsf); - m_bounds = slsf.m_bounds; + if (this != &slsf) { + m_lineDirection.store(nullptr); + Trk::Surface::operator=(slsf); + m_bounds = slsf.m_bounds; } return *this; } -bool Trk::StraightLineSurface::operator==(const Trk::Surface& sf) const +bool +Trk::StraightLineSurface::operator==(const Trk::Surface& sf) const { // first check the type not to compare apples with oranges const Trk::StraightLineSurface* slsf = dynamic_cast<const Trk::StraightLineSurface*>(&sf); - if (!slsf) return false; + if (!slsf) + return false; bool transfEqual(transform().isApprox(slsf->transform(), 10e-8)); bool centerEqual = (transfEqual) ? (center() == slsf->center()) : false; bool boundsEqual = (centerEqual) ? (bounds() == slsf->bounds()) : false; @@ -96,169 +97,176 @@ bool Trk::StraightLineSurface::operator==(const Trk::Surface& sf) const } // true local to global method - fully defined -void Trk::StraightLineSurface::localToGlobal(const Amg::Vector2D& locpos, - const Amg::Vector3D& glomom, - Amg::Vector3D& glopos) const +void +Trk::StraightLineSurface::localToGlobal(const Amg::Vector2D& locpos, + const Amg::Vector3D& glomom, + Amg::Vector3D& glopos) const { // get the vector perpenticular to the momentum and the straw axis Amg::Vector3D radiusAxisGlobal(lineDirection().cross(glomom)); - Amg::Vector3D locZinGlobal = transform()*Amg::Vector3D(0.,0.,locpos[Trk::locZ]); + Amg::Vector3D locZinGlobal = transform() * Amg::Vector3D(0., 0., locpos[Trk::locZ]); // transform zPosition into global coordinates and add locR * radiusAxis - glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR]*radiusAxisGlobal.normalized()); + glopos = Amg::Vector3D(locZinGlobal + locpos[Trk::locR] * radiusAxisGlobal.normalized()); } - // specialized version for providing different Z - local to global method - from LocalParameters/ -const Amg::Vector3D* Trk::StraightLineSurface::localToGlobal(const Trk::LocalParameters& locpars, - const Amg::Vector3D& glomom, - double locZ) const +const Amg::Vector3D* +Trk::StraightLineSurface::localToGlobal(const Trk::LocalParameters& locpars, + const Amg::Vector3D& glomom, + double locZ) const { // create a local Position Amg::Vector2D locPos(locpars[Trk::driftRadius], locZ); return Surface::localToGlobal(locPos, glomom); } - // true global to local method - fully defined -bool Trk::StraightLineSurface::globalToLocal(const Amg::Vector3D& glopos, const Amg::Vector3D& glomom, Amg::Vector2D& locpos) const { - Amg::Vector3D loc3Dframe = (transform().inverse())*glopos; - // construct localPosition with sign*candidate.perp() and z.() - locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.z()); - Amg::Vector3D decVec(glopos - center()); - // assign the right sign - double sign = ((lineDirection().cross(glomom)).dot(decVec) < 0. ) ? -1. : 1.; - locpos[Trk::locR] *= sign; - return true; +bool +Trk::StraightLineSurface::globalToLocal(const Amg::Vector3D& glopos, + const Amg::Vector3D& glomom, + Amg::Vector2D& locpos) const +{ + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopos; + // construct localPosition with sign*candidate.perp() and z.() + locpos = Amg::Vector2D(loc3Dframe.perp(), loc3Dframe.z()); + Amg::Vector3D decVec(glopos - center()); + // assign the right sign + double sign = ((lineDirection().cross(glomom)).dot(decVec) < 0.) ? -1. : 1.; + locpos[Trk::locR] *= sign; + return true; } // isOnSurface check -bool Trk::StraightLineSurface::isOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk, - double tol1, - double tol2) const +bool +Trk::StraightLineSurface::isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk, double tol1, double tol2) const { - if (!bchk) return true; - // check whether this is a boundless surface - if (!(m_bounds.get()) && !Surface::m_associatedDetElement) return true; - // get the standard bounds - Amg::Vector3D loc3Dframe = (transform().inverse())*glopo; - Amg::Vector2D locCand(loc3Dframe.perp(), loc3Dframe.z()); - return ( locCand[Trk::locR] < bounds().r()+tol1 && bounds().insideLoc2(locCand,tol2) ); + if (!bchk) + return true; + // check whether this is a boundless surface + if (!(m_bounds.get()) && !Surface::m_associatedDetElement) + return true; + // get the standard bounds + Amg::Vector3D loc3Dframe = (transform().inverse()) * glopo; + Amg::Vector2D locCand(loc3Dframe.perp(), loc3Dframe.z()); + return (locCand[Trk::locR] < bounds().r() + tol1 && bounds().insideLoc2(locCand, tol2)); } /** distance to surface */ -Trk::DistanceSolution Trk::StraightLineSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos,const Amg::Vector3D& dir) const +Trk::DistanceSolution +Trk::StraightLineSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, const Amg::Vector3D& dir) const { const Amg::Vector3D& C = center(); const Amg::Vector3D& S = lineDirection(); double D = dir.dot(S); - double A = (1.-D)*(1.+D); + double A = (1. - D) * (1. + D); - Amg::Vector3D dx = C-pos-(C.dot(S)-pos.dot(S))*S ; + Amg::Vector3D dx = C - pos - (C.dot(S) - pos.dot(S)) * S; double currDist = sqrt(dx.dot(dx)); - if( A < 0.0001 ) { - return Trk::DistanceSolution(1,currDist,false,0.); + if (A < 0.0001) { + return Trk::DistanceSolution(1, currDist, false, 0.); } - double sol = (pos-C).dot(D*S-dir)/A; - return Trk::DistanceSolution(1,currDist,false,sol); + double sol = (pos - C).dot(D * S - dir) / A; + return Trk::DistanceSolution(1, currDist, false, sol); } // return the measurement frame -const Amg::RotationMatrix3D Trk::StraightLineSurface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D& glomom) const +const Amg::RotationMatrix3D +Trk::StraightLineSurface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D& glomom) const { - Amg::RotationMatrix3D mFrame; - // construct the measurement frame - const Amg::Vector3D& measY = lineDirection(); - Amg::Vector3D measX(measY.cross(glomom).unit()); - Amg::Vector3D measDepth(measX.cross(measY)); - // assign the columnes - mFrame.col(0) = measX; - mFrame.col(1) = measY; - mFrame.col(2) = measDepth; - // return the rotation matrix - return mFrame; + Amg::RotationMatrix3D mFrame; + // construct the measurement frame + const Amg::Vector3D& measY = lineDirection(); + Amg::Vector3D measX(measY.cross(glomom).unit()); + Amg::Vector3D measDepth(measX.cross(measY)); + // assign the columnes + mFrame.col(0) = measX; + mFrame.col(1) = measY; + mFrame.col(2) = measDepth; + // return the rotation matrix + return mFrame; } -Trk::DistanceSolution Trk::StraightLineSurface::straightLineDistanceEstimate -(const Amg::Vector3D& pos,const Amg::Vector3D& dir,bool bound) const +Trk::DistanceSolution +Trk::StraightLineSurface::straightLineDistanceEstimate(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool bound) const { - const Amg::Transform3D& T = transform() ; - Amg::Vector3D Az(T(0,2),T(1,2),T(2,2)); - - Amg::Vector3D dxyz = pos-T.translation(); + const Amg::Transform3D& T = transform(); + Amg::Vector3D Az(T(0, 2), T(1, 2), T(2, 2)); + Amg::Vector3D dxyz = pos - T.translation(); - double D = dir.dot(Az) ; - double Lz = dxyz.dot(Az) ; - double A = (1.-D)*(1.+D) ; + double D = dir.dot(Az); + double Lz = dxyz.dot(Az); + double A = (1. - D) * (1. + D); // Step to surface // - double s = 0.; - if (A > 0.) s = (D*Lz-(dir.dot(dxyz)))/A; - if (!bound) return Trk::DistanceSolution(1,0.,false,s); + double s = 0.; + if (A > 0.) + s = (D * Lz - (dir.dot(dxyz))) / A; + if (!bound) + return Trk::DistanceSolution(1, 0., false, s); // Min distance to surface // double Rm = 20., Lzm = 1.e+10; if (m_bounds.get()) { - Rm = m_bounds.get()->r(); + Rm = m_bounds.get()->r(); Lzm = m_bounds.get()->halflengthZ(); - } - else if (Surface::m_associatedDetElement) { + } else if (Surface::m_associatedDetElement) { const Trk::CylinderBounds* cb = 0; if (Surface::m_associatedDetElementId.is_valid()) { - cb = dynamic_cast<const Trk::CylinderBounds*> (&m_associatedDetElement->bounds(Surface::m_associatedDetElementId)); - } - else { - cb = dynamic_cast<const Trk::CylinderBounds*> (&m_associatedDetElement->bounds()); + cb = dynamic_cast<const Trk::CylinderBounds*>(&m_associatedDetElement->bounds(Surface::m_associatedDetElementId)); + } else { + cb = dynamic_cast<const Trk::CylinderBounds*>(&m_associatedDetElement->bounds()); } if (cb) { - Rm = cb->r(); - Lzm = cb->halflengthZ(); + Rm = cb->r(); + Lzm = cb->halflengthZ(); } } - double dist = dxyz.dot(dxyz)-Lz*Lz; - dist = (dist > Rm*Rm) ? sqrt(dist)-Rm : 0.; - double dL = fabs(Lz)-Lzm; - if (dL > 0.) dist = sqrt(dist*dist+dL*dL); + double dist = dxyz.dot(dxyz) - Lz * Lz; + dist = (dist > Rm * Rm) ? sqrt(dist) - Rm : 0.; + double dL = fabs(Lz) - Lzm; + if (dL > 0.) + dist = sqrt(dist * dist + dL * dL); - return Trk::DistanceSolution(1,dist,false,s); + return Trk::DistanceSolution(1, dist, false, s); } -Trk::Intersection Trk::StraightLineSurface::straightLineIntersection(const Amg::Vector3D& pos, - const Amg::Vector3D& dir, - bool forceDir, - Trk::BoundaryCheck bchk) const +Trk::Intersection +Trk::StraightLineSurface::straightLineIntersection(const Amg::Vector3D& pos, + const Amg::Vector3D& dir, + bool forceDir, + Trk::BoundaryCheck bchk) const { - // following nominclature found in header file and doxygen documentation - // line one is the straight track - const Amg::Vector3D& ma = pos; - const Amg::Vector3D& ea = dir; - // line two is the line surface - const Amg::Vector3D& mb = center(); - const Amg::Vector3D& eb = lineDirection(); - // now go ahead and solve for the closest approach - Amg::Vector3D mab(mb - ma); - double eaTeb = ea.dot(eb); - double denom = 1 - eaTeb*eaTeb; - if (fabs(denom)>10e-7){ - double lambda0 = (mab.dot(ea) - mab.dot(eb)*eaTeb)/denom; - // evaluate in terms of direction - bool isValid = forceDir ? (lambda0 > 0.) : true; - // evaluate validaty in terms of bounds - Amg::Vector3D result = (ma+lambda0*ea); - isValid = bchk ? ( isValid && isOnSurface(result) ) : isValid; - // return the result - return Trk::Intersection(result,lambda0, isValid ); - } - return Trk::Intersection(pos,0.,false); -} - - + // following nominclature found in header file and doxygen documentation + // line one is the straight track + const Amg::Vector3D& ma = pos; + const Amg::Vector3D& ea = dir; + // line two is the line surface + const Amg::Vector3D& mb = center(); + const Amg::Vector3D& eb = lineDirection(); + // now go ahead and solve for the closest approach + Amg::Vector3D mab(mb - ma); + double eaTeb = ea.dot(eb); + double denom = 1 - eaTeb * eaTeb; + if (fabs(denom) > 10e-7) { + double lambda0 = (mab.dot(ea) - mab.dot(eb) * eaTeb) / denom; + // evaluate in terms of direction + bool isValid = forceDir ? (lambda0 > 0.) : true; + // evaluate validaty in terms of bounds + Amg::Vector3D result = (ma + lambda0 * ea); + isValid = bchk ? (isValid && isOnSurface(result)) : isValid; + // return the result + return Trk::Intersection(result, lambda0, isValid); + } + return Trk::Intersection(pos, 0., false); +} diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx index fa1aa8eb0c2c68f0ac5e50952c0eb81345767a16..4b59dab83470ce807f265dacb22ee8b5d2f9fa0d 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/Surface.cxx @@ -6,33 +6,32 @@ // Surface.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/Surface.h" #include "TrkSurfaces/SurfaceBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> - -const double Trk::Surface::s_onSurfaceTolerance = 10e-5; // 0.1 * micron +const double Trk::Surface::s_onSurfaceTolerance = 10e-5; // 0.1 * micron #ifndef NDEBUG -std::atomic<unsigned int> Trk::Surface::s_numberOfInstantiations{0}; -std::atomic<unsigned int> Trk::Surface::s_numberOfFreeInstantiations{0}; +std::atomic<unsigned int> Trk::Surface::s_numberOfInstantiations{ 0 }; +std::atomic<unsigned int> Trk::Surface::s_numberOfFreeInstantiations{ 0 }; #endif -Trk::Surface::Surface() : - m_transform(nullptr), - m_center(nullptr), - m_normal(nullptr), - m_associatedDetElement(0), - m_associatedDetElementId(), - m_associatedLayer(0), - m_materialLayer(0), - m_owner(Trk::SurfaceOwner(0)) +Trk::Surface::Surface() + : m_transform(nullptr) + , m_center(nullptr) + , m_normal(nullptr) + , m_associatedDetElement(0) + , m_associatedDetElementId() + , m_associatedLayer(0) + , m_materialLayer(0) + , m_owner(Trk::SurfaceOwner(0)) { #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor @@ -40,54 +39,53 @@ Trk::Surface::Surface() : #endif } -Trk::Surface::Surface(Amg::Transform3D* tform) : - m_transform (nullptr), - m_center (nullptr), - m_normal(nullptr), - m_associatedDetElement(0), - m_associatedDetElementId(), - m_associatedLayer(0), - m_materialLayer(0), - m_owner(Trk::SurfaceOwner(0)) +Trk::Surface::Surface(Amg::Transform3D* tform) + : m_transform(nullptr) + , m_center(nullptr) + , m_normal(nullptr) + , m_associatedDetElement(0) + , m_associatedDetElementId() + , m_associatedLayer(0) + , m_materialLayer(0) + , m_owner(Trk::SurfaceOwner(0)) { - m_transform.store(std::unique_ptr<Amg::Transform3D> (tform)); + m_transform.store(std::unique_ptr<Amg::Transform3D>(tform)); #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor - increment one instance s_numberOfFreeInstantiations++; #endif } -Trk::Surface::Surface(std::unique_ptr<Amg::Transform3D> tform) : - Surface (tform.release()) +Trk::Surface::Surface(std::unique_ptr<Amg::Transform3D> tform) + : Surface(tform.release()) { // No EDM monitor here since we delegate to the previous constructor. } - -Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement) : - m_transform(nullptr), - m_center(nullptr), - m_normal(nullptr), - m_associatedDetElement(&detelement), - m_associatedDetElementId(), - m_associatedLayer(0), - m_materialLayer(0), - m_owner(Trk::DetElOwn) +Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement) + : m_transform(nullptr) + , m_center(nullptr) + , m_normal(nullptr) + , m_associatedDetElement(&detelement) + , m_associatedDetElementId() + , m_associatedLayer(0) + , m_materialLayer(0) + , m_owner(Trk::DetElOwn) { #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor - increment one instance #endif } -Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement, const Identifier& id) : - m_transform(nullptr), - m_center(nullptr), - m_normal(nullptr), - m_associatedDetElement(&detelement), - m_associatedDetElementId(id), - m_associatedLayer(0), - m_materialLayer(0), - m_owner(Trk::DetElOwn) +Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement, const Identifier& id) + : m_transform(nullptr) + , m_center(nullptr) + , m_normal(nullptr) + , m_associatedDetElement(&detelement) + , m_associatedDetElementId(id) + , m_associatedLayer(0) + , m_materialLayer(0) + , m_owner(Trk::DetElOwn) { #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor - increment one instance @@ -95,18 +93,18 @@ Trk::Surface::Surface(const Trk::TrkDetElementBase& detelement, const Identifier } // copy constructor - Attention! sets the associatedDetElement to 0 and the identifier to invalid -Trk::Surface::Surface(const Surface& sf) : - m_transform(nullptr), - m_center(nullptr), - m_normal(nullptr), - m_associatedDetElement(0), - m_associatedDetElementId(), - m_associatedLayer(sf.m_associatedLayer), - m_materialLayer(sf.m_materialLayer), - m_owner(Trk::SurfaceOwner(0)) +Trk::Surface::Surface(const Surface& sf) + : m_transform(nullptr) + , m_center(nullptr) + , m_normal(nullptr) + , m_associatedDetElement(0) + , m_associatedDetElementId() + , m_associatedLayer(sf.m_associatedLayer) + , m_materialLayer(sf.m_materialLayer) + , m_owner(Trk::SurfaceOwner(0)) { - m_transform=std::make_unique<Amg::Transform3D>(sf.transform()); + m_transform = std::make_unique<Amg::Transform3D>(sf.transform()); #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor - increment one instance @@ -117,19 +115,16 @@ Trk::Surface::Surface(const Surface& sf) : // copy constructor with shift - Attention! sets the associatedDetElement to 0 and the identifieer to invalid // also invalidates the material layer -Trk::Surface::Surface(const Surface& sf, const Amg::Transform3D& shift) : - m_transform( sf.m_transform ? - std::make_unique<Amg::Transform3D>(shift* (*(sf.m_transform)) ) : - std::make_unique<Amg::Transform3D>(shift) ), - m_center( (sf.m_center) ? - std::make_unique<Amg::Vector3D>( shift*(*(sf.m_center)) ) : - nullptr), - m_normal(nullptr), - m_associatedDetElement(0), - m_associatedDetElementId(), - m_associatedLayer(0), - m_materialLayer(0), - m_owner(Trk::SurfaceOwner(0)) +Trk::Surface::Surface(const Surface& sf, const Amg::Transform3D& shift) + : m_transform(sf.m_transform ? std::make_unique<Amg::Transform3D>(shift * (*(sf.m_transform))) + : std::make_unique<Amg::Transform3D>(shift)) + , m_center((sf.m_center) ? std::make_unique<Amg::Vector3D>(shift * (*(sf.m_center))) : nullptr) + , m_normal(nullptr) + , m_associatedDetElement(0) + , m_associatedDetElementId() + , m_associatedLayer(0) + , m_materialLayer(0) + , m_owner(Trk::SurfaceOwner(0)) { #ifndef NDEBUG s_numberOfInstantiations++; // EDM Monitor - increment one instance @@ -143,62 +138,67 @@ Trk::Surface::~Surface() { #ifndef NDEBUG s_numberOfInstantiations--; // EDM Monitor - decrement one instance - if ( isFree() ) s_numberOfFreeInstantiations--; + if (isFree()) + s_numberOfFreeInstantiations--; #endif } // assignment operator // the assigned surfaces loses its link to the detector element -Trk::Surface& Trk::Surface::operator=(const Trk::Surface& sf) +Trk::Surface& +Trk::Surface::operator=(const Trk::Surface& sf) { - if (this!=&sf){ + if (this != &sf) { m_transform.release(); m_center.release(); m_normal.release(); m_transform = std::make_unique<Amg::Transform3D>(sf.transform()); - m_associatedDetElement = 0; + m_associatedDetElement = 0; m_associatedDetElementId = Identifier(); - m_associatedLayer = sf.m_associatedLayer; - m_materialLayer = sf.m_materialLayer; - m_owner = Trk::noOwn; + m_associatedLayer = sf.m_associatedLayer; + m_materialLayer = sf.m_materialLayer; + m_owner = Trk::noOwn; } return *this; } // returns the LocalPosition on a surface of a GlobalPosition -const Amg::Vector2D* Trk::Surface::positionOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk, - double tol1, - double tol2) const +const Amg::Vector2D* +Trk::Surface::positionOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk, double tol1, double tol2) const { - const Amg::Vector2D* posOnSurface = globalToLocal(glopo, tol1); - if (!bchk) return posOnSurface; - if (posOnSurface && insideBounds(*posOnSurface, tol1, tol2)) return posOnSurface; - delete posOnSurface; return 0; + const Amg::Vector2D* posOnSurface = globalToLocal(glopo, tol1); + if (!bchk) + return posOnSurface; + if (posOnSurface && insideBounds(*posOnSurface, tol1, tol2)) + return posOnSurface; + delete posOnSurface; + return 0; } // checks if GlobalPosition is on Surface and inside bounds -bool Trk::Surface::isOnSurface(const Amg::Vector3D& glopo, - BoundaryCheck bchk, - double tol1, - double tol2 ) const +bool +Trk::Surface::isOnSurface(const Amg::Vector3D& glopo, BoundaryCheck bchk, double tol1, double tol2) const { - const Amg::Vector2D *posOnSurface = positionOnSurface(glopo, bchk, tol1, tol2); - if (posOnSurface) { delete posOnSurface; return true; } - else return false; + const Amg::Vector2D* posOnSurface = positionOnSurface(glopo, bchk, tol1, tol2); + if (posOnSurface) { + delete posOnSurface; + return true; + } else + return false; } // return the measurement frame -const Amg::RotationMatrix3D Trk::Surface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D&) const +const Amg::RotationMatrix3D +Trk::Surface::measurementFrame(const Amg::Vector3D&, const Amg::Vector3D&) const { return transform().rotation(); } - // for the EDM monitor -unsigned int Trk::Surface::numberOfInstantiations() +unsigned int +Trk::Surface::numberOfInstantiations() { -#ifndef NDEBUG +#ifndef NDEBUG return s_numberOfInstantiations; #else return 0; @@ -206,59 +206,69 @@ unsigned int Trk::Surface::numberOfInstantiations() } // for the EDM monitor -unsigned int Trk::Surface::numberOfFreeInstantiations() +unsigned int +Trk::Surface::numberOfFreeInstantiations() { #ifndef NDEBUG - return s_numberOfFreeInstantiations; + return s_numberOfFreeInstantiations; #else - return 0; + return 0; #endif } // overload dump for MsgStream operator -MsgStream& Trk::Surface::dump( MsgStream& sl ) const +MsgStream& +Trk::Surface::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(4); - sl << name() << std::endl; - sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")" << std::endl; - Amg::RotationMatrix3D rot(transform().rotation()); - Amg::Vector3D rotX(rot.col(0)); - Amg::Vector3D rotY(rot.col(1)); - Amg::Vector3D rotZ(rot.col(2)); - sl << std::setprecision(6); - sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1) << ", " << rotX(2) << ")" << std::endl; - sl << " colY = (" << rotY(0) << ", " << rotY(1) << ", " << rotY(2) << ")" << std::endl; - sl << " colZ = (" << rotZ(0) << ", " << rotZ(1) << ", " << rotZ(2) << ")" << std::endl; - sl << " Bounds : " << bounds(); - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(4); + sl << name() << std::endl; + sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")" + << std::endl; + Amg::RotationMatrix3D rot(transform().rotation()); + Amg::Vector3D rotX(rot.col(0)); + Amg::Vector3D rotY(rot.col(1)); + Amg::Vector3D rotZ(rot.col(2)); + sl << std::setprecision(6); + sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1) << ", " << rotX(2) << ")" << std::endl; + sl << " colY = (" << rotY(0) << ", " << rotY(1) << ", " << rotY(2) << ")" << std::endl; + sl << " colZ = (" << rotZ(0) << ", " << rotZ(1) << ", " << rotZ(2) << ")" << std::endl; + sl << " Bounds : " << bounds(); + sl << std::setprecision(-1); + return sl; } // overload dump for MsgStream operator -std::ostream& Trk::Surface::dump( std::ostream& sl ) const +std::ostream& +Trk::Surface::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(4); - sl << name() << std::endl; - sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")" << std::endl; - Amg::RotationMatrix3D rot(transform().rotation()); - Amg::Vector3D rotX(rot.col(0)); - Amg::Vector3D rotY(rot.col(1)); - Amg::Vector3D rotZ(rot.col(2)); - sl << std::setprecision(6); - sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1) << ", " << rotX(2) << ")" << std::endl; - sl << " colY = (" << rotY(0) << ", " << rotY(1) << ", " << rotY(2) << ")" << std::endl; - sl << " colZ = (" << rotZ(0) << ", " << rotZ(1) << ", " << rotZ(2) << ")" << std::endl; - sl << " Bounds : " << bounds(); - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(4); + sl << name() << std::endl; + sl << " Center position (x, y, z) = (" << center().x() << ", " << center().y() << ", " << center().z() << ")" + << std::endl; + Amg::RotationMatrix3D rot(transform().rotation()); + Amg::Vector3D rotX(rot.col(0)); + Amg::Vector3D rotY(rot.col(1)); + Amg::Vector3D rotZ(rot.col(2)); + sl << std::setprecision(6); + sl << " Rotation: colX = (" << rotX(0) << ", " << rotX(1) << ", " << rotX(2) << ")" << std::endl; + sl << " colY = (" << rotY(0) << ", " << rotY(1) << ", " << rotY(2) << ")" << std::endl; + sl << " colZ = (" << rotZ(0) << ", " << rotZ(1) << ", " << rotZ(2) << ")" << std::endl; + sl << " Bounds : " << bounds(); + sl << std::setprecision(-1); + return sl; } /**Overload of << operator for both, MsgStream and std::ostream for debug output*/ -MsgStream& Trk::operator << ( MsgStream& sl, const Trk::Surface& sf) -{ return sf.dump(sl); } - -std::ostream& Trk::operator << ( std::ostream& sl, const Trk::Surface& sf) -{ return sf.dump(sl); } +MsgStream& +Trk::operator<<(MsgStream& sl, const Trk::Surface& sf) +{ + return sf.dump(sl); +} +std::ostream& +Trk::operator<<(std::ostream& sl, const Trk::Surface& sf) +{ + return sf.dump(sl); +} diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/SurfaceBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/SurfaceBounds.cxx index 08650ace241820faf8ec37bff09405f0dc81d6a8..1f58ef22643fd94d7f6abebeffe1a78a4d44dac9 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/SurfaceBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/SurfaceBounds.cxx @@ -6,13 +6,18 @@ // SurfaceBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// - -//Trk +// Trk #include "TrkSurfaces/SurfaceBounds.h" -/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ -MsgStream& Trk::operator << ( MsgStream& sl, const SurfaceBounds& sb) -{ return sb.dump(sl); } +/**Overload of << operator for both, MsgStream and std::ostream for debug output*/ +MsgStream& +Trk::operator<<(MsgStream& sl, const SurfaceBounds& sb) +{ + return sb.dump(sl); +} -std::ostream& Trk::operator << ( std::ostream& sl, const SurfaceBounds& sb) -{ return sb.dump(sl); } +std::ostream& +Trk::operator<<(std::ostream& sl, const SurfaceBounds& sb) +{ + return sb.dump(sl); +} diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/TrapezoidBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/TrapezoidBounds.cxx index ddb9730b56e5e0b64ac1f68c38a85a31c90dcf13..0a5d7e37b40376e423200e3e2a5e179b0b06a855 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/TrapezoidBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/TrapezoidBounds.cxx @@ -6,215 +6,222 @@ // TrapezoidBounds.cxx, (c) ATLAS Detector Software /////////////////////////////////////////////////////////////////// -//Trk +// Trk #include "TrkSurfaces/TrapezoidBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> #include <math.h> // default constructor -Trk::TrapezoidBounds::TrapezoidBounds() : - m_boundValues(TrapezoidBounds::bv_length, 0.), - m_alpha(0.), - m_beta(0.) +Trk::TrapezoidBounds::TrapezoidBounds() + : m_boundValues(TrapezoidBounds::bv_length, 0.) + , m_alpha(0.) + , m_beta(0.) {} // constructor from arguments I -Trk::TrapezoidBounds::TrapezoidBounds(double minhalex, double maxhalex, double haley) : - m_boundValues(TrapezoidBounds::bv_length, 0.), - m_alpha(0.), - m_beta(0.) +Trk::TrapezoidBounds::TrapezoidBounds(double minhalex, double maxhalex, double haley) + : m_boundValues(TrapezoidBounds::bv_length, 0.) + , m_alpha(0.) + , m_beta(0.) { - m_boundValues[TrapezoidBounds::bv_minHalfX] = fabs(minhalex); - m_boundValues[TrapezoidBounds::bv_maxHalfX] = fabs(maxhalex); - m_boundValues[TrapezoidBounds::bv_halfY] = fabs(haley); - if (m_boundValues[TrapezoidBounds::bv_minHalfX] > m_boundValues[TrapezoidBounds::bv_maxHalfX]) swap(m_boundValues[TrapezoidBounds::bv_minHalfX], m_boundValues[TrapezoidBounds::bv_maxHalfX]); - + m_boundValues[TrapezoidBounds::bv_minHalfX] = fabs(minhalex); + m_boundValues[TrapezoidBounds::bv_maxHalfX] = fabs(maxhalex); + m_boundValues[TrapezoidBounds::bv_halfY] = fabs(haley); + if (m_boundValues[TrapezoidBounds::bv_minHalfX] > m_boundValues[TrapezoidBounds::bv_maxHalfX]) + swap(m_boundValues[TrapezoidBounds::bv_minHalfX], m_boundValues[TrapezoidBounds::bv_maxHalfX]); } // constructor from arguments II -Trk::TrapezoidBounds::TrapezoidBounds(double minhalex, double haley, double alpha, double beta) : - m_boundValues(TrapezoidBounds::bv_length, 0.), - m_alpha(alpha), - m_beta(beta) +Trk::TrapezoidBounds::TrapezoidBounds(double minhalex, double haley, double alpha, double beta) + : m_boundValues(TrapezoidBounds::bv_length, 0.) + , m_alpha(alpha) + , m_beta(beta) { - double gamma = (alpha > beta) ? (alpha - 0.5*M_PI) : (beta - 0.5*M_PI); - // now fill them - m_boundValues[TrapezoidBounds::bv_minHalfX] = fabs(minhalex); - m_boundValues[TrapezoidBounds::bv_maxHalfX] = minhalex + (2.*m_boundValues[TrapezoidBounds::bv_halfY])*tan(gamma); - m_boundValues[TrapezoidBounds::bv_halfY] = fabs(haley); + double gamma = (alpha > beta) ? (alpha - 0.5 * M_PI) : (beta - 0.5 * M_PI); + // now fill them + m_boundValues[TrapezoidBounds::bv_minHalfX] = fabs(minhalex); + m_boundValues[TrapezoidBounds::bv_maxHalfX] = minhalex + (2. * m_boundValues[TrapezoidBounds::bv_halfY]) * tan(gamma); + m_boundValues[TrapezoidBounds::bv_halfY] = fabs(haley); } // copy constructor -Trk::TrapezoidBounds::TrapezoidBounds(const TrapezoidBounds& trabo) : - Trk::SurfaceBounds(), - m_boundValues(trabo.m_boundValues), - m_alpha(trabo.m_alpha), - m_beta(trabo.m_beta) +Trk::TrapezoidBounds::TrapezoidBounds(const TrapezoidBounds& trabo) + : Trk::SurfaceBounds() + , m_boundValues(trabo.m_boundValues) + , m_alpha(trabo.m_alpha) + , m_beta(trabo.m_beta) {} // destructor -Trk::TrapezoidBounds::~TrapezoidBounds() -{} +Trk::TrapezoidBounds::~TrapezoidBounds() {} -Trk::TrapezoidBounds& Trk::TrapezoidBounds::operator=(const TrapezoidBounds& trabo) +Trk::TrapezoidBounds& +Trk::TrapezoidBounds::operator=(const TrapezoidBounds& trabo) { - if (this!=&trabo){ - m_boundValues = trabo.m_boundValues; - m_alpha = trabo.m_alpha; - m_beta = trabo.m_beta; - } - return *this; + if (this != &trabo) { + m_boundValues = trabo.m_boundValues; + m_alpha = trabo.m_alpha; + m_beta = trabo.m_beta; + } + return *this; } -bool Trk::TrapezoidBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::TrapezoidBounds::operator==(const Trk::SurfaceBounds& sbo) const { - // check the type first not to compare apples with oranges + // check the type first not to compare apples with oranges const Trk::TrapezoidBounds* trabo = dynamic_cast<const Trk::TrapezoidBounds*>(&sbo); - if (!trabo) return false; + if (!trabo) + return false; return (m_boundValues == trabo->m_boundValues); } // checking if inside bounds -bool Trk::TrapezoidBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const +bool +Trk::TrapezoidBounds::inside(const Amg::Vector2D& locpo, double tol1, double tol2) const { - if (m_alpha==0.) return insideFull(locpo, tol1, tol2); - return (insideFull(locpo, tol1, tol2) && !insideExclude(locpo,tol1,tol2)); + if (m_alpha == 0.) + return insideFull(locpo, tol1, tol2); + return (insideFull(locpo, tol1, tol2) && !insideExclude(locpo, tol1, tol2)); } // checking if inside bounds (Full symmetrical Trapezoid) -bool Trk::TrapezoidBounds::insideFull(const Amg::Vector2D& locpo, - double tol1, - double tol2) const +bool +Trk::TrapezoidBounds::insideFull(const Amg::Vector2D& locpo, double tol1, double tol2) const { // the cases: // the cases: double fabsX = fabs(locpo[Trk::locX]); double fabsY = fabs(locpo[Trk::locY]); // (1) a fast FALSE - if (fabsY > ( m_boundValues[TrapezoidBounds::bv_halfY] + tol2)) return false; + if (fabsY > (m_boundValues[TrapezoidBounds::bv_halfY] + tol2)) + return false; // (2) a fast FALSE - if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + tol1)) return false; + if (fabsX > (m_boundValues[TrapezoidBounds::bv_maxHalfX] + tol1)) + return false; // (3) a fast TRUE - if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] - tol1)) return true; + if (fabsX < (m_boundValues[TrapezoidBounds::bv_minHalfX] - tol1)) + return true; // (4) particular case - a rectangle - if ( m_boundValues[TrapezoidBounds::bv_maxHalfX]==m_boundValues[TrapezoidBounds::bv_minHalfX] ) return true; + if (m_boundValues[TrapezoidBounds::bv_maxHalfX] == m_boundValues[TrapezoidBounds::bv_minHalfX]) + return true; // (5) /** use basic calculation of a straight line */ - double k = 2.0 * m_boundValues[TrapezoidBounds::bv_halfY]/(m_boundValues[TrapezoidBounds::bv_maxHalfX] - m_boundValues[TrapezoidBounds::bv_minHalfX]) * ( (locpo[Trk::locX] > 0.) ? 1.0 : -1.0 ); - double d = - fabs(k)*0.5*(m_boundValues[TrapezoidBounds::bv_maxHalfX] + m_boundValues[TrapezoidBounds::bv_minHalfX]); + double k = 2.0 * m_boundValues[TrapezoidBounds::bv_halfY] / + (m_boundValues[TrapezoidBounds::bv_maxHalfX] - m_boundValues[TrapezoidBounds::bv_minHalfX]) * + ((locpo[Trk::locX] > 0.) ? 1.0 : -1.0); + double d = + -fabs(k) * 0.5 * (m_boundValues[TrapezoidBounds::bv_maxHalfX] + m_boundValues[TrapezoidBounds::bv_minHalfX]); return (isAbove(locpo, tol1, tol2, k, d)); } // checking if local point is inside the exclude area -bool Trk::TrapezoidBounds::insideExclude(const Amg::Vector2D& locpo, - double tol1, - double tol2) const +bool +Trk::TrapezoidBounds::insideExclude(const Amg::Vector2D& locpo, double tol1, double tol2) const { - - //line a - bool alphaBiggerBeta(m_alpha > m_beta); - double ka = alphaBiggerBeta ? tan(M_PI - m_alpha) : tan(m_alpha); - double kb = alphaBiggerBeta ? tan(M_PI - m_beta) : tan(m_beta); - double sign = alphaBiggerBeta ? -1. : 1.; - double da = -m_boundValues[TrapezoidBounds::bv_halfY] + sign*ka*m_boundValues[TrapezoidBounds::bv_minHalfX]; - double db = -m_boundValues[TrapezoidBounds::bv_halfY] + sign*kb*m_boundValues[TrapezoidBounds::bv_minHalfX]; - - return (isAbove(locpo,tol1, tol2,ka,da) && isAbove(locpo,tol1, tol2,kb,db)); + + // line a + bool alphaBiggerBeta(m_alpha > m_beta); + double ka = alphaBiggerBeta ? tan(M_PI - m_alpha) : tan(m_alpha); + double kb = alphaBiggerBeta ? tan(M_PI - m_beta) : tan(m_beta); + double sign = alphaBiggerBeta ? -1. : 1.; + double da = -m_boundValues[TrapezoidBounds::bv_halfY] + sign * ka * m_boundValues[TrapezoidBounds::bv_minHalfX]; + double db = -m_boundValues[TrapezoidBounds::bv_halfY] + sign * kb * m_boundValues[TrapezoidBounds::bv_minHalfX]; + + return (isAbove(locpo, tol1, tol2, ka, da) && isAbove(locpo, tol1, tol2, kb, db)); } // checking if local point lies above a line -bool Trk::TrapezoidBounds::isAbove(const Amg::Vector2D& locpo, - double tol1, - double tol2, - double k, - double d) const +bool +Trk::TrapezoidBounds::isAbove(const Amg::Vector2D& locpo, double tol1, double tol2, double k, double d) const { - // the most tolerant approach for tol1 and tol2 - double sign = k > 0. ? -1. : + 1.; - return ( locpo[Trk::locY] + tol2 > (k * ( locpo[Trk::locX] + sign*tol1)+ d) ); + // the most tolerant approach for tol1 and tol2 + double sign = k > 0. ? -1. : +1.; + return (locpo[Trk::locY] + tol2 > (k * (locpo[Trk::locX] + sign * tol1) + d)); } - -double Trk::TrapezoidBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::TrapezoidBounds::minDistance(const Amg::Vector2D& pos) const { const int Np = 4; double xl = -m_boundValues[TrapezoidBounds::bv_maxHalfX]; - double xr = m_boundValues[TrapezoidBounds::bv_maxHalfX]; - if (m_alpha !=0.) { - xl = -m_boundValues[TrapezoidBounds::bv_minHalfX]-2.*tan(m_alpha)*m_boundValues[TrapezoidBounds::bv_halfY]; + double xr = m_boundValues[TrapezoidBounds::bv_maxHalfX]; + if (m_alpha != 0.) { + xl = -m_boundValues[TrapezoidBounds::bv_minHalfX] - 2. * tan(m_alpha) * m_boundValues[TrapezoidBounds::bv_halfY]; + } else if (m_beta != 0.) { + xr = m_boundValues[TrapezoidBounds::bv_minHalfX] + 2. * tan(m_beta) * m_boundValues[TrapezoidBounds::bv_halfY]; } - else if (m_beta !=0. ) { - xr = m_boundValues[TrapezoidBounds::bv_minHalfX]+2.*tan(m_beta )*m_boundValues[TrapezoidBounds::bv_halfY]; - } - double X [4] = { -m_boundValues[TrapezoidBounds::bv_minHalfX], - xl, - xr, - m_boundValues[TrapezoidBounds::bv_minHalfX]}; - double Y [4] = { -m_boundValues[TrapezoidBounds::bv_halfY], - m_boundValues[TrapezoidBounds::bv_halfY], - m_boundValues[TrapezoidBounds::bv_halfY], - -m_boundValues[TrapezoidBounds::bv_halfY]}; + double X[4] = { -m_boundValues[TrapezoidBounds::bv_minHalfX], xl, xr, m_boundValues[TrapezoidBounds::bv_minHalfX] }; + double Y[4] = { -m_boundValues[TrapezoidBounds::bv_halfY], + m_boundValues[TrapezoidBounds::bv_halfY], + m_boundValues[TrapezoidBounds::bv_halfY], + -m_boundValues[TrapezoidBounds::bv_halfY] }; double dm = 1.e+20; - double Ao = 0.; - bool in = true; + double Ao = 0.; + bool in = true; - for (int i=0; i!=Np; ++i) { + for (int i = 0; i != Np; ++i) { - int j = i+1; if(j==Np) j=0; + int j = i + 1; + if (j == Np) + j = 0; - double x = X[i]-pos[0]; - double y = Y[i]-pos[1]; - double dx = X[j]-X[i] ; - double dy = Y[j]-Y[i] ; - double A = x*dy-y*dx ; - double S =-(x*dx+y*dy); + double x = X[i] - pos[0]; + double y = Y[i] - pos[1]; + double dx = X[j] - X[i]; + double dy = Y[j] - Y[i]; + double A = x * dy - y * dx; + double S = -(x * dx + y * dy); if (S <= 0.) { - double d = x*x+y*y; - if (d<dm) dm=d; - } - else { - double a = dx*dx+dy*dy; - if (S <= a ) { - double d = (A*A)/a; - if (d<dm) dm=d; + double d = x * x + y * y; + if (d < dm) + dm = d; + } else { + double a = dx * dx + dy * dy; + if (S <= a) { + double d = (A * A) / a; + if (d < dm) + dm = d; } } - if (i && in && Ao*A < 0.) in = false; + if (i && in && Ao * A < 0.) + in = false; Ao = A; } - if (in) return -sqrt(dm); - else return sqrt(dm); + if (in) + return -sqrt(dm); + else + return sqrt(dm); } // ostream operator overload -MsgStream& Trk::TrapezoidBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::TrapezoidBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = " << "(" - << m_boundValues[TrapezoidBounds::bv_minHalfX] << ", " - << m_boundValues[TrapezoidBounds::bv_maxHalfX] << ", " - << m_boundValues[TrapezoidBounds::bv_halfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = " + << "(" << m_boundValues[TrapezoidBounds::bv_minHalfX] << ", " << m_boundValues[TrapezoidBounds::bv_maxHalfX] + << ", " << m_boundValues[TrapezoidBounds::bv_halfY] << ")"; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::TrapezoidBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::TrapezoidBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = " << "(" - << m_boundValues[TrapezoidBounds::bv_minHalfX] << ", " - << m_boundValues[TrapezoidBounds::bv_maxHalfX] << ", " - << m_boundValues[TrapezoidBounds::bv_halfY] << ")"; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::TrapezoidBounds: (minHlenghtX, maxHlengthX, hlengthY) = " + << "(" << m_boundValues[TrapezoidBounds::bv_minHalfX] << ", " << m_boundValues[TrapezoidBounds::bv_maxHalfX] + << ", " << m_boundValues[TrapezoidBounds::bv_halfY] << ")"; + sl << std::setprecision(-1); + return sl; } - diff --git a/Tracking/TrkDetDescr/TrkSurfaces/src/TriangleBounds.cxx b/Tracking/TrkDetDescr/TrkSurfaces/src/TriangleBounds.cxx index d8fb52c07564d4d04a62a24b59437cd634837ab6..d3057b65f43bad033a92aa3f9a7ac5c76e5b8400 100644 --- a/Tracking/TrkDetDescr/TrkSurfaces/src/TriangleBounds.cxx +++ b/Tracking/TrkDetDescr/TrkSurfaces/src/TriangleBounds.cxx @@ -8,149 +8,158 @@ // Trk #include "TrkSurfaces/TriangleBounds.h" -//Gaudi +// Gaudi #include "GaudiKernel/MsgStream.h" -//STD -#include <iostream> +// STD #include <iomanip> +#include <iostream> // default constructor -Trk::TriangleBounds::TriangleBounds() : - m_boundValues(TriangleBounds::bv_length,0.) +Trk::TriangleBounds::TriangleBounds() + : m_boundValues(TriangleBounds::bv_length, 0.) {} // rectangle constructor - float constructor -Trk::TriangleBounds::TriangleBounds(const std::vector<std::pair<float,float> >& vertices) : - m_boundValues(TriangleBounds::bv_length,0.) +Trk::TriangleBounds::TriangleBounds(const std::vector<std::pair<float, float>>& vertices) + : m_boundValues(TriangleBounds::bv_length, 0.) { - size_t ib = 0; - for (const std::pair<float, float>& p : vertices) { - m_boundValues[2*ib] = p.first; - m_boundValues[2*ib+1] = p.second; - if (ib==2) break; - ++ib; - } + size_t ib = 0; + for (const std::pair<float, float>& p : vertices) { + m_boundValues[2 * ib] = p.first; + m_boundValues[2 * ib + 1] = p.second; + if (ib == 2) + break; + ++ib; + } } // rectangle constructor - double constructor -Trk::TriangleBounds::TriangleBounds(const std::vector<std::pair<double,double> >& vertices) : - m_boundValues(TriangleBounds::bv_length,0.) +Trk::TriangleBounds::TriangleBounds(const std::vector<std::pair<double, double>>& vertices) + : m_boundValues(TriangleBounds::bv_length, 0.) { - size_t ib = 0; - for (const std::pair<double, double>& p : vertices) { - m_boundValues[2*ib] = p.first; - m_boundValues[2*ib+1] = p.second; - if (ib==2) break; - ++ib; - } + size_t ib = 0; + for (const std::pair<double, double>& p : vertices) { + m_boundValues[2 * ib] = p.first; + m_boundValues[2 * ib + 1] = p.second; + if (ib == 2) + break; + ++ib; + } } // constructor from three points -Trk::TriangleBounds::TriangleBounds( const Amg::Vector2D& p1, const Amg::Vector2D& p2, const Amg::Vector2D& p3) : - m_boundValues(TriangleBounds::bv_length,0.) +Trk::TriangleBounds::TriangleBounds(const Amg::Vector2D& p1, const Amg::Vector2D& p2, const Amg::Vector2D& p3) + : m_boundValues(TriangleBounds::bv_length, 0.) { - m_boundValues[TriangleBounds::bv_x1] = p1.x(); - m_boundValues[TriangleBounds::bv_y1] = p1.y(); - m_boundValues[TriangleBounds::bv_x2] = p2.x(); - m_boundValues[TriangleBounds::bv_y2] = p2.y(); - m_boundValues[TriangleBounds::bv_x3] = p3.x(); - m_boundValues[TriangleBounds::bv_y3] = p3.y(); + m_boundValues[TriangleBounds::bv_x1] = p1.x(); + m_boundValues[TriangleBounds::bv_y1] = p1.y(); + m_boundValues[TriangleBounds::bv_x2] = p2.x(); + m_boundValues[TriangleBounds::bv_y2] = p2.y(); + m_boundValues[TriangleBounds::bv_x3] = p3.x(); + m_boundValues[TriangleBounds::bv_y3] = p3.y(); } - // copy constructor -Trk::TriangleBounds::TriangleBounds(const TriangleBounds& tribo) : - Trk::SurfaceBounds(), - m_boundValues(tribo.m_boundValues) +Trk::TriangleBounds::TriangleBounds(const TriangleBounds& tribo) + : Trk::SurfaceBounds() + , m_boundValues(tribo.m_boundValues) {} // destructor -Trk::TriangleBounds::~TriangleBounds() -{} +Trk::TriangleBounds::~TriangleBounds() {} -Trk::TriangleBounds& Trk::TriangleBounds::operator=(const TriangleBounds& tribo) +Trk::TriangleBounds& +Trk::TriangleBounds::operator=(const TriangleBounds& tribo) { - if (this!=&tribo) - m_boundValues = tribo.m_boundValues; + if (this != &tribo) + m_boundValues = tribo.m_boundValues; return *this; } -bool Trk::TriangleBounds::operator==(const Trk::SurfaceBounds& sbo) const +bool +Trk::TriangleBounds::operator==(const Trk::SurfaceBounds& sbo) const { // check the type first not to compare apples with oranges const Trk::TriangleBounds* tribo = dynamic_cast<const Trk::TriangleBounds*>(&sbo); - if (!tribo) return false; + if (!tribo) + return false; return (m_boundValues == tribo->m_boundValues); } -double Trk::TriangleBounds::minDistance(const Amg::Vector2D& pos ) const +double +Trk::TriangleBounds::minDistance(const Amg::Vector2D& pos) const { const int Np = 3; - double X [3] = { m_boundValues[TriangleBounds::bv_x1] , - m_boundValues[TriangleBounds::bv_x2] , - m_boundValues[TriangleBounds::bv_x3] }; - double Y [3] = { m_boundValues[TriangleBounds::bv_y1] , - m_boundValues[TriangleBounds::bv_y2] , - m_boundValues[TriangleBounds::bv_y3] }; + double X[3] = { m_boundValues[TriangleBounds::bv_x1], + m_boundValues[TriangleBounds::bv_x2], + m_boundValues[TriangleBounds::bv_x3] }; + double Y[3] = { m_boundValues[TriangleBounds::bv_y1], + m_boundValues[TriangleBounds::bv_y2], + m_boundValues[TriangleBounds::bv_y3] }; double dm = 1.e+20; - double Ao = 0.; - bool in = true; + double Ao = 0.; + bool in = true; - for (int i=0; i!=Np; ++i) { + for (int i = 0; i != Np; ++i) { - int j = i+1; if(j==Np) j=0; + int j = i + 1; + if (j == Np) + j = 0; - double x = X[i]-pos[0]; - double y = Y[i]-pos[1]; - double dx = X[j]-X[i] ; - double dy = Y[j]-Y[i] ; - double A = x*dy-y*dx ; - double S =-(x*dx+y*dy); + double x = X[i] - pos[0]; + double y = Y[i] - pos[1]; + double dx = X[j] - X[i]; + double dy = Y[j] - Y[i]; + double A = x * dy - y * dx; + double S = -(x * dx + y * dy); if (S <= 0.) { - double d = x*x+y*y; - if (d<dm) dm=d; - } - else { - double a = dx*dx+dy*dy; - if (S <= a ) { - double d = (A*A)/a; - if (d<dm) dm=d; + double d = x * x + y * y; + if (d < dm) + dm = d; + } else { + double a = dx * dx + dy * dy; + if (S <= a) { + double d = (A * A) / a; + if (d < dm) + dm = d; } } - if (i && in && Ao*A < 0.) in = false; + if (i && in && Ao * A < 0.) + in = false; Ao = A; } - if (in) return -sqrt(dm); - else return sqrt(dm); + if (in) + return -sqrt(dm); + else + return sqrt(dm); } // ostream operator overload -MsgStream& Trk::TriangleBounds::dump( MsgStream& sl ) const +MsgStream& +Trk::TriangleBounds::dump(MsgStream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::TriangleBounds: generating vertices (X, Y) " << '\n'; - sl << "(" << m_boundValues[TriangleBounds::bv_x1] << " , " << m_boundValues[TriangleBounds::bv_y1] << ") " << '\n'; - sl << "(" << m_boundValues[TriangleBounds::bv_x2] << " , " << m_boundValues[TriangleBounds::bv_y2] << ") " << '\n'; - sl << "(" << m_boundValues[TriangleBounds::bv_x3] << " , " << m_boundValues[TriangleBounds::bv_y3] << ") "; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::TriangleBounds: generating vertices (X, Y) " << '\n'; + sl << "(" << m_boundValues[TriangleBounds::bv_x1] << " , " << m_boundValues[TriangleBounds::bv_y1] << ") " << '\n'; + sl << "(" << m_boundValues[TriangleBounds::bv_x2] << " , " << m_boundValues[TriangleBounds::bv_y2] << ") " << '\n'; + sl << "(" << m_boundValues[TriangleBounds::bv_x3] << " , " << m_boundValues[TriangleBounds::bv_y3] << ") "; + sl << std::setprecision(-1); + return sl; } -std::ostream& Trk::TriangleBounds::dump( std::ostream& sl ) const +std::ostream& +Trk::TriangleBounds::dump(std::ostream& sl) const { - sl << std::setiosflags(std::ios::fixed); - sl << std::setprecision(7); - sl << "Trk::TriangleBounds: generating vertices (X, Y)"; - sl << "(" << m_boundValues[TriangleBounds::bv_x1] << " , " << m_boundValues[TriangleBounds::bv_y1] << ") " << '\n'; - sl << "(" << m_boundValues[TriangleBounds::bv_x2] << " , " << m_boundValues[TriangleBounds::bv_y2] << ") " << '\n'; - sl << "(" << m_boundValues[TriangleBounds::bv_x3] << " , " << m_boundValues[TriangleBounds::bv_y3] << ") "; - sl << std::setprecision(-1); - return sl; + sl << std::setiosflags(std::ios::fixed); + sl << std::setprecision(7); + sl << "Trk::TriangleBounds: generating vertices (X, Y)"; + sl << "(" << m_boundValues[TriangleBounds::bv_x1] << " , " << m_boundValues[TriangleBounds::bv_y1] << ") " << '\n'; + sl << "(" << m_boundValues[TriangleBounds::bv_x2] << " , " << m_boundValues[TriangleBounds::bv_y2] << ") " << '\n'; + sl << "(" << m_boundValues[TriangleBounds::bv_x3] << " , " << m_boundValues[TriangleBounds::bv_y3] << ") "; + sl << std::setprecision(-1); + return sl; } - - -