Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:21:30

0001 #ifndef NPSTAT_HISTOAXIS_HH_
0002 #define NPSTAT_HISTOAXIS_HH_
0003 
0004 /*!
0005 // \file HistoAxis.h
0006 //
0007 // \brief Histogram axis with equidistant bins
0008 //
0009 // Author: I. Volobouev
0010 //
0011 // July 2010
0012 */
0013 
0014 #include <utility>
0015 
0016 #include "Alignment/Geners/interface/ClassId.hh"
0017 
0018 #include "JetMETCorrections/InterpolationTables/interface/CircularMapper1d.h"
0019 #include "JetMETCorrections/InterpolationTables/interface/Interval.h"
0020 
0021 namespace npstat {
0022   template <typename Numeric, class Axis>
0023   class HistoND;
0024   class DualHistoAxis;
0025 
0026   /**
0027     // Class which contain the information needed to define a histogram axis.
0028     // All bins will have the same width. See NUHistoAxis and DualHistoAxis
0029     // classes for non-uniform binning.
0030     */
0031   class HistoAxis {
0032   public:
0033     /**
0034         // Minimum and maximum will be internally swapped
0035         // if the minimum parameter is larger than the maximum
0036         */
0037     HistoAxis(unsigned nBins, double min, double max, const char* label = nullptr);
0038 
0039     //@{
0040     /** Examine axis properties */
0041     inline double min() const { return min_; }
0042     inline double max() const { return max_; }
0043     inline Interval<double> interval() const { return Interval<double>(min_, max_); }
0044     inline double length() const { return max_ - min_; }
0045     inline unsigned nBins() const { return nBins_; }
0046     inline double binWidth(const int /*binNum*/ = 0) const { return bw_; }
0047     inline const std::string& label() const { return label_; }
0048     inline bool isUniform() const { return true; }
0049     //@}
0050 
0051     /** Return the coordinate of the given bin center */
0052     inline double binCenter(const int binNum) const { return min_ + (binNum + 0.5) * bw_; }
0053 
0054     /** Return the coordinate of the given bin left edge */
0055     inline double leftBinEdge(const int binNum) const { return min_ + binNum * bw_; }
0056 
0057     /** Return the coordinate of the given bin right edge */
0058     inline double rightBinEdge(const int binNum) const { return min_ + (binNum + 1) * bw_; }
0059 
0060     /** Return the coordinate interval occupied by the given bin */
0061     inline Interval<double> binInterval(const int binNum) const {
0062       return Interval<double>(min_ + binNum * bw_, min_ + (binNum + 1) * bw_);
0063     }
0064 
0065     /** Change the axis label */
0066     inline void setLabel(const char* newlabel) { label_ = newlabel ? newlabel : ""; }
0067 
0068     /**
0069         // This method returns arbitrary integer bin number, including
0070         // negative numbers and numbers which can exceed nBins()-1
0071         */
0072     int binNumber(double x) const;
0073 
0074     /**
0075         // This method returns the closest valid bin number
0076         // (above 0 and below nBins() )
0077         */
0078     unsigned closestValidBin(double x) const;
0079 
0080     /**
0081         // Return the mapper which calculates floating point bin number
0082         // given the coordinate. The resulting bin number can go above
0083         // and below the axis range. If "mapLeftEdgeTo0" is specified
0084         // as "false", it is the center of the first bin which gets
0085         // mapped to 0.
0086         */
0087     LinearMapper1d binNumberMapper(bool mapLeftEdgeTo0 = true) const;
0088 
0089     /**
0090         // Floating point bin number given the coordinate (no bin number
0091         // truncation of any kind is performed). Works in exactly the same
0092         // way as the mapper returned by the previous method.
0093         */
0094     inline double fltBinNumber(const double x, const bool mapLeftEdgeTo0 = true) const {
0095       return (x - min_) / bw_ - (mapLeftEdgeTo0 ? 0.0 : 0.5);
0096     }
0097 
0098     /**
0099         // The following function returns a mapper that can be
0100         // helpful in scanning a kernel (a density function) for
0101         // subsequent convolution with the histogram which contains
0102         // this axis.
0103         */
0104     CircularMapper1d kernelScanMapper(bool doubleRange) const;
0105 
0106     bool operator==(const HistoAxis&) const;
0107     bool operator!=(const HistoAxis&) const;
0108 
0109     /** Comparison of axis coordinates within given tolerance */
0110     bool isClose(const HistoAxis&, double tol) const;
0111 
0112     /** Return rebinned axis */
0113     HistoAxis rebin(unsigned newBins) const;
0114 
0115     //@{
0116     /** Method related to "geners" I/O */
0117     inline gs::ClassId classId() const { return gs::ClassId(*this); }
0118     bool write(std::ostream& of) const;
0119     //@}
0120 
0121     static inline const char* classname() { return "npstat::HistoAxis"; }
0122     static inline unsigned version() { return 1; }
0123     static HistoAxis* read(const gs::ClassId& id, std::istream& in);
0124 
0125   private:
0126     double min_;
0127     double max_;
0128     double bw_;
0129     std::string label_;
0130     unsigned nBins_;
0131 
0132     template <typename Numeric, class Axis>
0133     friend class HistoND;
0134     friend class DualHistoAxis;
0135 
0136     inline unsigned overflowIndex(const double x, unsigned* binNumber) const {
0137       if (x < min_)
0138         return 0U;
0139       else if (x >= max_)
0140         return 2U;
0141       else {
0142         const unsigned bin = static_cast<unsigned>((x - min_) / bw_);
0143         *binNumber = bin >= nBins_ ? nBins_ - 1U : bin;
0144         return 1U;
0145       }
0146     }
0147 
0148     unsigned overflowIndexWeighted(double x, unsigned* binNumber, double* weight) const;
0149     inline HistoAxis() : min_(0.0), max_(0.0), bw_(0.0), nBins_(0) {}
0150   };
0151 }  // namespace npstat
0152 
0153 #endif  // NPSTAT_HISTOAXIS_HH_