00001 #ifndef CondFormats_PhysicsToolsObjects_Histogram3D_h
00002 #define CondFormats_PhysicsToolsObjects_Histogram3D_h
00003
00004 #include <utility>
00005 #include <vector>
00006 #include <cmath>
00007
00008 #include "CondFormats/PhysicsToolsObjects/interface/Histogram2D.h"
00009
00010 namespace PhysicsTools {
00011 namespace Calibration {
00012
00013
00014
00015
00016 template<typename Value_t, typename AxisX_t = Value_t,
00017 typename AxisY_t = AxisX_t, typename AxisZ_t = AxisX_t>
00018
00019
00020 class Histogram3D {
00021 public:
00022 typedef Range<AxisX_t> RangeX;
00023 typedef Range<AxisY_t> RangeY;
00024 typedef Range<AxisZ_t> RangeZ;
00025
00026 Histogram3D();
00027
00028 Histogram3D(const Histogram3D &orig);
00029
00030 template<typename OValue_t, typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
00031 Histogram3D(const Histogram3D<OValue_t, OAxisX_t, OAxisY_t, OAxisZ_t> &orig);
00032
00033 Histogram3D(const std::vector<AxisX_t> &binULimitsX,
00034 const std::vector<AxisY_t> &binULimitsY,
00035 const std::vector<AxisZ_t> &binULimitsZ);
00036
00037 template<typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
00038 Histogram3D(const std::vector<OAxisX_t> &binULimitsX,
00039 const std::vector<OAxisY_t> &binULimitsY,
00040 const std::vector<OAxisZ_t> &binULimitsZ);
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 Histogram3D(unsigned int nBinsX, AxisX_t minX, AxisX_t maxX,
00061 unsigned int nBinsY, AxisY_t minY, AxisY_t maxY,
00062 unsigned int nBinsZ, AxisZ_t minZ, AxisZ_t maxZ);
00063
00064 ~Histogram3D();
00065
00066 Histogram3D &operator = (const Histogram3D &orig);
00067
00068 template<typename OValue_t, typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
00069 Histogram3D &operator = (const Histogram3D<OValue_t,
00070 OAxisX_t, OAxisY_t, OAxisZ_t> &orig);
00071
00072 void reset();
00073
00074 const std::vector<AxisX_t> upperLimitsX() const { return binULimitsX; }
00075 const std::vector<AxisY_t> upperLimitsY() const { return binULimitsY; }
00076 const std::vector<AxisZ_t> upperLimitsZ() const { return binULimitsZ; }
00077
00078 inline int bin3D(int binX, int binY, int binZ) const
00079
00080 { return binZ*strideX*strideY + binY*strideX + binX; }
00081
00082
00083
00084 Value_t binContent(int bin) const { return binValues[bin]; }
00085 Value_t binContent(int binX, int binY, int binZ) const
00086 { return binValues[bin3D(binX, binY, binZ)]; }
00087 Value_t value(AxisX_t x, AxisY_t y, AxisY_t z) const
00088 { return binContent(findBin(x, y, z)); }
00089 Value_t normalizedValue(AxisX_t x, AxisY_t y, AxisZ_t z) const
00090 { return binContent(findBin(x, y, z)) / normalization(); }
00091
00092
00093
00094
00095
00096
00097 Value_t binError(int bin) const { return std::sqrt(binContent(bin)); }
00098 Value_t binError(int binX, int binY, int binZ) const
00099 { return binError(bin3D(binX, binY, binZ)); }
00100 Value_t error(AxisX_t x, AxisY_t y, AxisZ_t z) const
00101 { return binError(findBin(x, y, z)); }
00102 Value_t normalizedError(AxisX_t x, AxisY_t y, AxisY_t z) const
00103 { return std::sqrt(binContent(findBin(x, y, z))) / normalization(); }
00104
00105
00106
00107
00108
00109 void setBinContent(int bin, Value_t value);
00110 void setBinContent(int binX, int binY, int binZ, Value_t value)
00111 { setBinContent(bin3D(binX, binY, binZ), value); }
00112 void fill(AxisX_t x, AxisY_t y, AxisZ_t z, Value_t weight = 1.0);
00113
00114 bool empty() const { return binValues.empty(); }
00115 bool hasEquidistantBinsX() const { return binULimitsX.empty(); }
00116 bool hasEquidistantBinsY() const { return binULimitsY.empty(); }
00117 bool hasEquidistantBinsZ() const { return binULimitsZ.empty(); }
00118 int numberOfBinsX() const { return strideX - 2; }
00119 int numberOfBinsY() const { return strideY - 2; }
00120 int numberOfBinsZ() const { return binValues.size() / (strideX * strideY) - 2; }
00121 int numberOfBins() const
00122 { return numberOfBinsX() * numberOfBinsY() * numberOfBinsZ(); }
00123
00124 inline const std::vector<Value_t> &values() const
00125 { return binValues; }
00126
00127 void setValues(const std::vector<Value_t> &values);
00128
00129 template<typename OValue_t>
00130 void setValues(const std::vector<OValue_t> &values);
00131
00132 inline RangeX rangeX() const { return limitsX; }
00133 inline RangeY rangeY() const { return limitsY; }
00134 inline RangeZ rangeZ() const { return limitsZ; }
00135 RangeX binRangeX(int binX) const;
00136 RangeY binRangeY(int binY) const;
00137 RangeZ binRangeZ(int binZ) const;
00138
00139
00140
00141
00142
00143
00144 int findBinX(AxisX_t x) const;
00145 int findBinY(AxisY_t y) const;
00146 int findBinZ(AxisZ_t z) const;
00147 int findBin(AxisX_t x, AxisY_t y, AxisZ_t z) const
00148 { return bin3D(findBinX(x), findBinY(y), findBinZ(z)); }
00149 Value_t normalization() const;
00150
00151
00152
00153
00154
00155 protected:
00156 unsigned int strideX;
00157 unsigned int strideY;
00158 std::vector<AxisX_t> binULimitsX;
00159 std::vector<AxisY_t> binULimitsY;
00160 std::vector<AxisZ_t> binULimitsZ;
00161 std::vector<Value_t> binValues;
00162 RangeX limitsX;
00163 RangeY limitsY;
00164 RangeY limitsZ;
00165
00166
00167 mutable Value_t total;
00168 mutable bool totalValid;
00169 mutable std::vector<Value_t> sliceTotal;
00170 mutable std::vector<Value_t> rowTotal;
00171 mutable std::vector<Value_t> columnTotal;
00172 };
00173
00174 typedef Histogram3D<float> HistogramF3D;
00175 typedef Histogram3D<double> HistogramD3D;
00176
00177
00178 }
00179 }
00180
00181 #include "CondFormats/PhysicsToolsObjects/interface/Histogram3D.icc"
00182
00183 #endif // CondFormats_PhysicsToolsObjects_Histogram3D_h