Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef Geom_SimpleConeBounds_H
0002 #define Geom_SimpleConeBounds_H
0003 
0004 /** \class SimpleConeBounds
0005  *  Cone bounds. The cone axis coincides with the Z axis.
0006  *  The bounds limit the length at constant Z, and allow finite thickness.
0007  *
0008  *  \warning: should be revised, probably works only when local and global
0009  *  Z axis coincide
0010  *
0011  */
0012 
0013 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0014 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0015 #include "DataFormats/GeometryVector/interface/Pi.h"
0016 #include "DataFormats/GeometrySurface/interface/LocalError.h"
0017 #include "DataFormats/GeometrySurface/interface/Bounds.h"
0018 
0019 #include <cmath>
0020 #include <limits>
0021 #include <algorithm>
0022 
0023 class SimpleConeBounds final : public Bounds {
0024 public:
0025   /// Construct from inner/outer radius on the two Z faces
0026   SimpleConeBounds(float zmin, float rmin_zmin, float rmax_zmin, float zmax, float rmin_zmax, float rmax_zmax)
0027       : theZmin(zmin),
0028         theRminZmin(rmin_zmin),
0029         theRmaxZmin(rmax_zmin),
0030         theZmax(zmax),
0031         theRminZmax(rmin_zmax),
0032         theRmaxZmax(rmax_zmax) {
0033     if (theZmin > theZmax) {
0034       std::swap(theRminZmin, theRminZmax);
0035       std::swap(theRmaxZmin, theRmaxZmax);
0036     }
0037     if (theRminZmin > theRmaxZmin)
0038       std::swap(theRminZmin, theRmaxZmin);
0039     if (theRminZmax > theRmaxZmax)
0040       std::swap(theRminZmax, theRmaxZmax);
0041   }
0042 
0043   /// Length along Z.
0044   float length() const override { return theZmax - theZmin; }
0045   /// Maximum diameter.
0046   float width() const override { return 2 * std::max(theRmaxZmin, theRmaxZmax); }
0047   /// Thickness in the middle (Z center).
0048   /// Maybe it's useless, but it is pure abstract in Bounds...
0049   float thickness() const override { return ((theRmaxZmin - theRminZmin) + (theRmaxZmax - theRminZmax)) / 2.; }
0050 
0051   using Bounds::inside;
0052 
0053   bool inside(const Local3DPoint& p) const override {
0054     float lrmin = (p.z() - theZmin) * (theRminZmax - theRminZmin) / (theZmax - theZmin);
0055     float lrmax = (p.z() - theZmin) * (theRmaxZmax - theRmaxZmin) / (theZmax - theZmin);
0056     return p.z() > theZmin && p.z() < theZmax && p.perp() > lrmin && p.perp() < lrmax;
0057   }
0058 
0059   bool inside(const Local3DPoint& p, const LocalError& err, float scale) const override {
0060     // std::cout << "WARNING: SimpleConeBounds::inside(const Local3DPoint&, const LocalError not fully implemented"
0061     //        << std::endl;     // FIXME! does not check R.
0062     SimpleConeBounds tmp(theZmin - sqrt(err.yy()) * scale,
0063                          theRminZmin,
0064                          theRmaxZmin,
0065                          theZmax + sqrt(err.yy()) * scale,
0066                          theRminZmax,
0067                          theRmaxZmax);
0068     return tmp.inside(p);
0069   }
0070 
0071   virtual bool inside(const Local2DPoint& p, const LocalError& err) const { return Bounds::inside(p, err); }
0072 
0073   Bounds* clone() const override { return new SimpleConeBounds(*this); }
0074 
0075   // Extension of the Bounds interface
0076   Geom::Theta<float> openingAngle() const {
0077     float theta = atan(((theRmaxZmax + theRminZmax) / 2. - (theRmaxZmin + theRminZmin) / 2.) / length());
0078     return Geom::Theta<float>(theta < 0 ? theta + Geom::pi() : theta);
0079   }
0080 
0081   GlobalPoint vertex() const {
0082     float rAtZmax = (theRmaxZmax + theRminZmax) / 2.;
0083     float rAtZmin = (theRmaxZmin + theRminZmin) / 2.;
0084     float dr = (rAtZmax - rAtZmin);
0085 
0086     if (std::abs(dr) < 0.0001) {  // handle degenerate case (cone->cylinder)
0087       return GlobalPoint(0, 0, std::numeric_limits<float>::max());
0088     } else {
0089       return GlobalPoint(0, 0, (theZmin * rAtZmax - theZmax * rAtZmin) / dr);
0090     }
0091   }
0092 
0093 private:
0094   float theZmin;
0095   float theRminZmin;
0096   float theRmaxZmin;
0097   float theZmax;
0098   float theRminZmax;
0099   float theRmaxZmax;
0100 };
0101 
0102 #endif  // Geom_SimpleConeBounds_H