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 }