CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/JetMETCorrections/InterpolationTables/src/UniformAxis.cc

Go to the documentation of this file.
00001 #include <cmath>
00002 #include <climits>
00003 #include <algorithm>
00004 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
00005 
00006 #include "Alignment/Geners/interface/binaryIO.hh"
00007 #include "Alignment/Geners/interface/IOException.hh"
00008 
00009 #include "JetMETCorrections/InterpolationTables/interface/UniformAxis.h"
00010 #include "JetMETCorrections/InterpolationTables/interface/closeWithinTolerance.h"
00011 
00012 namespace npstat {
00013     UniformAxis::UniformAxis(const unsigned nCoords,
00014                              const double min, const double max,
00015                              const char* label)
00016         : min_(min), max_(max), label_(label ? label : ""), npt_(nCoords)
00017     {
00018         if (!(npt_ > 1U && npt_ < UINT_MAX/2U - 1U))
00019             throw npstat::NpstatInvalidArgument("In npstat::UniformAxis constructor: "
00020                                         "number of points is out of range");
00021         if (min_ > max_)
00022             std::swap(min_, max_);
00023         bw_ = (max_ - min_)/(npt_ - 1U);
00024         if (max_ == min_)
00025             throw npstat::NpstatInvalidArgument(
00026                 "In npstat::UniformAxis constructor: "
00027                 "minimum and maximum must be distinct");
00028     }
00029 
00030     std::pair<unsigned,double> UniformAxis::getInterval(const double x) const
00031     {
00032         if (x <= min_)
00033             return std::pair<unsigned,double>(0U, 1.0);
00034         else if (x >= max_)
00035             return std::pair<unsigned,double>(npt_ - 2U, 0.0);
00036         else
00037         {
00038             unsigned binnum = static_cast<unsigned>(floor((x - min_)/bw_));
00039             if (binnum > npt_ - 2U)
00040                 binnum = npt_ - 2U;
00041             double w = binnum + 1.0 - (x - min_)/bw_;
00042             if (w < 0.0)
00043                 w = 0.0;
00044             else if (w > 1.0)
00045                 w = 1.0;
00046             return std::pair<unsigned,double>(binnum, w);
00047         }
00048     }
00049 
00050     std::pair<unsigned,double> UniformAxis::linearInterval(const double x) const
00051     {
00052         if (x <= min_)
00053             return std::pair<unsigned,double>(0U, 1.0 - (x - min_)/bw_);
00054         else if (x >= max_)
00055             return std::pair<unsigned,double>(npt_ - 2U, (max_ - x)/bw_);
00056         else
00057         {
00058             unsigned binnum = static_cast<unsigned>(floor((x - min_)/bw_));
00059             if (binnum > npt_ - 2U)
00060                 binnum = npt_ - 2U;
00061             double w = binnum + 1.0 - (x - min_)/bw_;
00062             if (w < 0.0)
00063                 w = 0.0;
00064             else if (w > 1.0)
00065                 w = 1.0;
00066             return std::pair<unsigned,double>(binnum, w);
00067         }
00068     }
00069 
00070     std::vector<double> UniformAxis::coords() const
00071     {
00072         std::vector<double> vec;
00073         vec.reserve(npt_);
00074         const unsigned nptm1 = npt_ - 1U;
00075         for (unsigned i=0; i<nptm1; ++i)
00076             vec.push_back(min_ + bw_*i);
00077         vec.push_back(max_);
00078         return vec;
00079     }
00080 
00081     double UniformAxis::coordinate(const unsigned i) const
00082     {
00083         if (i >= npt_)
00084             throw npstat::NpstatOutOfRange(
00085                 "In npstat::UniformAxis::coordinate: index out of range");
00086         if (i == npt_ - 1U)
00087             return max_;
00088         else
00089             return min_ + bw_*i;
00090     }
00091 
00092     bool UniformAxis::isClose(const UniformAxis& r, const double tol) const
00093     {
00094         return closeWithinTolerance(min_, r.min_, tol) &&
00095                closeWithinTolerance(max_, r.max_, tol) &&
00096                label_ == r.label_ &&
00097                npt_ == r.npt_;
00098     }
00099 
00100     bool UniformAxis::operator==(const UniformAxis& r) const
00101     {
00102         return min_ == r.min_ &&
00103                max_ == r.max_ &&
00104                label_ == r.label_ &&
00105                npt_ == r.npt_;
00106     }
00107 
00108     bool UniformAxis::write(std::ostream& of) const
00109     {
00110         gs::write_pod(of, min_);
00111         gs::write_pod(of, max_);
00112         gs::write_pod(of, label_);
00113         gs::write_pod(of, npt_);
00114         return !of.fail();
00115     }
00116 
00117     UniformAxis* UniformAxis::read(const gs::ClassId& id, std::istream& in)
00118     {
00119         static const gs::ClassId current(gs::ClassId::makeId<UniformAxis>());
00120         current.ensureSameId(id);
00121 
00122         double min = 0.0, max = 0.0;
00123         std::string label;
00124         unsigned nBins = 0;
00125 
00126         gs::read_pod(in, &min);
00127         gs::read_pod(in, &max);
00128         gs::read_pod(in, &label);
00129         gs::read_pod(in, &nBins);
00130 
00131         if (!in.fail())
00132             return new UniformAxis(nBins, min, max, label.c_str());
00133         else
00134             throw gs::IOReadFailure("In npstat::UniformAxis::read: "
00135                                     "input stream failure");
00136     }
00137 }