Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:22

0001 #include <cmath>
0002 #include <climits>
0003 #include <algorithm>
0004 #include "JetMETCorrections/InterpolationTables/interface/NpstatException.h"
0005 
0006 #include "Alignment/Geners/interface/binaryIO.hh"
0007 #include "Alignment/Geners/interface/IOException.hh"
0008 
0009 #include "JetMETCorrections/InterpolationTables/interface/UniformAxis.h"
0010 #include "JetMETCorrections/InterpolationTables/interface/closeWithinTolerance.h"
0011 
0012 namespace npstat {
0013   UniformAxis::UniformAxis(const unsigned nCoords, const double min, const double max, const char* label)
0014       : min_(min), max_(max), label_(label ? label : ""), npt_(nCoords) {
0015     if (!(npt_ > 1U && npt_ < UINT_MAX / 2U - 1U))
0016       throw npstat::NpstatInvalidArgument(
0017           "In npstat::UniformAxis constructor: "
0018           "number of points is out of range");
0019     if (min_ > max_)
0020       std::swap(min_, max_);
0021     bw_ = (max_ - min_) / (npt_ - 1U);
0022     if (max_ == min_)
0023       throw npstat::NpstatInvalidArgument(
0024           "In npstat::UniformAxis constructor: "
0025           "minimum and maximum must be distinct");
0026   }
0027 
0028   std::pair<unsigned, double> UniformAxis::getInterval(const double x) const {
0029     if (x <= min_)
0030       return std::pair<unsigned, double>(0U, 1.0);
0031     else if (x >= max_)
0032       return std::pair<unsigned, double>(npt_ - 2U, 0.0);
0033     else {
0034       unsigned binnum = static_cast<unsigned>(floor((x - min_) / bw_));
0035       if (binnum > npt_ - 2U)
0036         binnum = npt_ - 2U;
0037       double w = binnum + 1.0 - (x - min_) / bw_;
0038       if (w < 0.0)
0039         w = 0.0;
0040       else if (w > 1.0)
0041         w = 1.0;
0042       return std::pair<unsigned, double>(binnum, w);
0043     }
0044   }
0045 
0046   std::pair<unsigned, double> UniformAxis::linearInterval(const double x) const {
0047     if (x <= min_)
0048       return std::pair<unsigned, double>(0U, 1.0 - (x - min_) / bw_);
0049     else if (x >= max_)
0050       return std::pair<unsigned, double>(npt_ - 2U, (max_ - x) / bw_);
0051     else {
0052       unsigned binnum = static_cast<unsigned>(floor((x - min_) / bw_));
0053       if (binnum > npt_ - 2U)
0054         binnum = npt_ - 2U;
0055       double w = binnum + 1.0 - (x - min_) / bw_;
0056       if (w < 0.0)
0057         w = 0.0;
0058       else if (w > 1.0)
0059         w = 1.0;
0060       return std::pair<unsigned, double>(binnum, w);
0061     }
0062   }
0063 
0064   std::vector<double> UniformAxis::coords() const {
0065     std::vector<double> vec;
0066     vec.reserve(npt_);
0067     const unsigned nptm1 = npt_ - 1U;
0068     for (unsigned i = 0; i < nptm1; ++i)
0069       vec.push_back(min_ + bw_ * i);
0070     vec.push_back(max_);
0071     return vec;
0072   }
0073 
0074   double UniformAxis::coordinate(const unsigned i) const {
0075     if (i >= npt_)
0076       throw npstat::NpstatOutOfRange("In npstat::UniformAxis::coordinate: index out of range");
0077     if (i == npt_ - 1U)
0078       return max_;
0079     else
0080       return min_ + bw_ * i;
0081   }
0082 
0083   bool UniformAxis::isClose(const UniformAxis& r, const double tol) const {
0084     return closeWithinTolerance(min_, r.min_, tol) && closeWithinTolerance(max_, r.max_, tol) && label_ == r.label_ &&
0085            npt_ == r.npt_;
0086   }
0087 
0088   bool UniformAxis::operator==(const UniformAxis& r) const {
0089     return min_ == r.min_ && max_ == r.max_ && label_ == r.label_ && npt_ == r.npt_;
0090   }
0091 
0092   bool UniformAxis::write(std::ostream& of) const {
0093     gs::write_pod(of, min_);
0094     gs::write_pod(of, max_);
0095     gs::write_pod(of, label_);
0096     gs::write_pod(of, npt_);
0097     return !of.fail();
0098   }
0099 
0100   UniformAxis* UniformAxis::read(const gs::ClassId& id, std::istream& in) {
0101     static const gs::ClassId current(gs::ClassId::makeId<UniformAxis>());
0102     current.ensureSameId(id);
0103 
0104     double min = 0.0, max = 0.0;
0105     std::string label;
0106     unsigned nBins = 0;
0107 
0108     gs::read_pod(in, &min);
0109     gs::read_pod(in, &max);
0110     gs::read_pod(in, &label);
0111     gs::read_pod(in, &nBins);
0112 
0113     if (!in.fail())
0114       return new UniformAxis(nBins, min, max, label.c_str());
0115     else
0116       throw gs::IOReadFailure(
0117           "In npstat::UniformAxis::read: "
0118           "input stream failure");
0119   }
0120 }  // namespace npstat