File indexing completed on 2024-04-06 12:02:26
0001 #ifndef CondFormats_PhysicsToolsObjects_Histogram3D_h
0002 #define CondFormats_PhysicsToolsObjects_Histogram3D_h
0003
0004 #include "CondFormats/Serialization/interface/Serializable.h"
0005
0006 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0007 #include <atomic>
0008 #endif
0009
0010 #include <utility>
0011 #include <vector>
0012 #include <cmath>
0013
0014 #include "CondFormats/PhysicsToolsObjects/interface/Histogram2D.h"
0015
0016 namespace PhysicsTools {
0017 namespace Calibration {
0018
0019
0020
0021
0022 template <typename Value_t, typename AxisX_t = Value_t, typename AxisY_t = AxisX_t, typename AxisZ_t = AxisX_t>
0023
0024 class Histogram3D {
0025 public:
0026 typedef Range<AxisX_t> RangeX;
0027 typedef Range<AxisY_t> RangeY;
0028 typedef Range<AxisZ_t> RangeZ;
0029
0030 Histogram3D();
0031
0032 Histogram3D(const Histogram3D &orig);
0033
0034 template <typename OValue_t, typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
0035 Histogram3D(const Histogram3D<OValue_t, OAxisX_t, OAxisY_t, OAxisZ_t> &orig);
0036
0037 Histogram3D(const std::vector<AxisX_t> &binULimitsX,
0038 const std::vector<AxisY_t> &binULimitsY,
0039 const std::vector<AxisZ_t> &binULimitsZ);
0040
0041 template <typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
0042 Histogram3D(const std::vector<OAxisX_t> &binULimitsX,
0043 const std::vector<OAxisY_t> &binULimitsY,
0044 const std::vector<OAxisZ_t> &binULimitsZ);
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 Histogram3D(unsigned int nBinsX,
0065 AxisX_t minX,
0066 AxisX_t maxX,
0067 unsigned int nBinsY,
0068 AxisY_t minY,
0069 AxisY_t maxY,
0070 unsigned int nBinsZ,
0071 AxisZ_t minZ,
0072 AxisZ_t maxZ);
0073
0074 ~Histogram3D();
0075
0076 Histogram3D &operator=(const Histogram3D &orig);
0077
0078 template <typename OValue_t, typename OAxisX_t, typename OAxisY_t, typename OAxisZ_t>
0079 Histogram3D &operator=(const Histogram3D<OValue_t, OAxisX_t, OAxisY_t, OAxisZ_t> &orig);
0080
0081 void reset();
0082
0083 const std::vector<AxisX_t> upperLimitsX() const { return binULimitsX; }
0084 const std::vector<AxisY_t> upperLimitsY() const { return binULimitsY; }
0085 const std::vector<AxisZ_t> upperLimitsZ() const { return binULimitsZ; }
0086
0087 inline int bin3D(int binX, int binY, int binZ) const
0088
0089 {
0090 return binZ * strideX * strideY + binY * strideX + binX;
0091 }
0092
0093 Value_t binContent(int bin) const { return binValues[bin]; }
0094 Value_t binContent(int binX, int binY, int binZ) const { return binValues[bin3D(binX, binY, binZ)]; }
0095 Value_t value(AxisX_t x, AxisY_t y, AxisY_t z) const { return binContent(findBin(x, y, z)); }
0096 Value_t normalizedValue(AxisX_t x, AxisY_t y, AxisZ_t z) const {
0097 return binContent(findBin(x, y, z)) / normalization();
0098 }
0099
0100
0101
0102
0103
0104
0105 Value_t binError(int bin) const { return std::sqrt(binContent(bin)); }
0106 Value_t binError(int binX, int binY, int binZ) const { return binError(bin3D(binX, binY, binZ)); }
0107 Value_t error(AxisX_t x, AxisY_t y, AxisZ_t z) const { return binError(findBin(x, y, z)); }
0108 Value_t normalizedError(AxisX_t x, AxisY_t y, AxisY_t z) const {
0109 return std::sqrt(binContent(findBin(x, y, z))) / normalization();
0110 }
0111
0112
0113
0114
0115
0116 void setBinContent(int bin, Value_t value);
0117 void setBinContent(int binX, int binY, int binZ, Value_t value) { setBinContent(bin3D(binX, binY, binZ), value); }
0118 void fill(AxisX_t x, AxisY_t y, AxisZ_t z, Value_t weight = 1.0);
0119
0120 bool empty() const { return binValues.empty(); }
0121 bool hasEquidistantBinsX() const { return binULimitsX.empty(); }
0122 bool hasEquidistantBinsY() const { return binULimitsY.empty(); }
0123 bool hasEquidistantBinsZ() const { return binULimitsZ.empty(); }
0124 int numberOfBinsX() const { return strideX - 2; }
0125 int numberOfBinsY() const { return strideY - 2; }
0126 int numberOfBinsZ() const { return binValues.size() / (strideX * strideY) - 2; }
0127 int numberOfBins() const { return numberOfBinsX() * numberOfBinsY() * numberOfBinsZ(); }
0128
0129 inline const std::vector<Value_t> &values() const { return binValues; }
0130
0131 void setValues(const std::vector<Value_t> &values);
0132
0133 template <typename OValue_t>
0134 void setValues(const std::vector<OValue_t> &values);
0135
0136 inline RangeX rangeX() const { return limitsX; }
0137 inline RangeY rangeY() const { return limitsY; }
0138 inline RangeZ rangeZ() const { return limitsZ; }
0139 RangeX binRangeX(int binX) const;
0140 RangeY binRangeY(int binY) const;
0141 RangeZ binRangeZ(int binZ) const;
0142
0143
0144
0145
0146
0147
0148 int findBinX(AxisX_t x) const;
0149 int findBinY(AxisY_t y) const;
0150 int findBinZ(AxisZ_t z) const;
0151 int findBin(AxisX_t x, AxisY_t y, AxisZ_t z) const { return bin3D(findBinX(x), findBinY(y), findBinZ(z)); }
0152 Value_t normalization() const;
0153
0154
0155
0156
0157
0158 protected:
0159 unsigned int strideX;
0160 unsigned int strideY;
0161 std::vector<AxisX_t> binULimitsX;
0162 std::vector<AxisY_t> binULimitsY;
0163 std::vector<AxisZ_t> binULimitsZ;
0164 std::vector<Value_t> binValues;
0165 RangeX limitsX;
0166 RangeY limitsY;
0167 RangeY limitsZ;
0168
0169
0170 mutable Value_t total COND_TRANSIENT;
0171 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0172 mutable std::atomic<bool> totalValid COND_TRANSIENT;
0173 #else
0174 mutable bool totalValid COND_TRANSIENT;
0175 #endif
0176 mutable std::vector<Value_t> sliceTotal COND_TRANSIENT;
0177 mutable std::vector<Value_t> rowTotal COND_TRANSIENT;
0178 mutable std::vector<Value_t> columnTotal COND_TRANSIENT;
0179
0180 COND_SERIALIZABLE;
0181 };
0182
0183 typedef Histogram3D<float> HistogramF3D;
0184 typedef Histogram3D<double> HistogramD3D;
0185
0186 }
0187 }
0188
0189 #if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__REFLEX__)
0190 #include "CondFormats/PhysicsToolsObjects/interface/Histogram3D.icc"
0191 #endif
0192
0193 #endif