File indexing completed on 2026-07-20 08:42:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_THnBase
0013 #define ROOT_THnBase
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 #include "TNamed.h"
0024 #include "TMath.h"
0025 #include "TFitResultPtr.h"
0026 #include "TObjArray.h"
0027 #include "TArrayD.h"
0028 #include <vector>
0029
0030
0031 class TAxis;
0032 class TH1;
0033 class TH1D;
0034 class TH2D;
0035 class TH3D;
0036 class TF1;
0037 class THnIter;
0038
0039 namespace ROOT {
0040 namespace Internal {
0041 class THnBaseBinIter;
0042 }
0043 }
0044
0045 class THnBase: public TNamed {
0046 protected:
0047 Int_t fNdimensions;
0048 TObjArray fAxes;
0049 TObjArray fBrowsables;
0050 Double_t fEntries;
0051 Double_t fTsumw;
0052 Double_t fTsumw2;
0053 TArrayD fTsumwx;
0054 TArrayD fTsumwx2;
0055 std::vector<Double_t> fIntegral;
0056 enum {
0057 kNoInt,
0058 kValidInt,
0059 kInvalidInt
0060 } fIntegralStatus;
0061
0062 protected:
0063 THnBase() : fNdimensions(0), fEntries(0), fTsumw(0), fTsumw2(-1.), fIntegral(), fIntegralStatus(kNoInt) {}
0064
0065 THnBase(const char *name, const char *title, Int_t dim, const Int_t *nbins, const Double_t *xmin,
0066 const Double_t *xmax);
0067
0068 THnBase(const char* name, const char* title, const std::vector<TAxis>& axes);
0069
0070 THnBase(const char *name, const char *title, Int_t dim, const Int_t *nbins,
0071 const std::vector<std::vector<double>> &xbins);
0072
0073 THnBase(const THnBase &other);
0074
0075 THnBase &operator=(const THnBase &other);
0076
0077 THnBase(THnBase &&other);
0078
0079 THnBase &operator=(THnBase &&other);
0080
0081 void UpdateXStat(const Double_t *x, Double_t w = 1.)
0082 {
0083 if (GetCalculateErrors()) {
0084 for (Int_t d = 0; d < fNdimensions; ++d) {
0085 const Double_t xd = x[d];
0086 fTsumwx[d] += w * xd;
0087 fTsumwx2[d] += w * xd * xd;
0088 }
0089 }
0090 }
0091
0092
0093 void FillBinBase(Double_t w) {
0094 fEntries += 1;
0095 if (GetCalculateErrors()) {
0096 fTsumw += w;
0097 fTsumw2 += w*w;
0098 }
0099 fIntegralStatus = kInvalidInt;
0100 }
0101
0102 virtual void InitStorage(Int_t* nbins, Int_t chunkSize) = 0;
0103 void Init(const char* name, const char* title,
0104 const TObjArray* axes, Bool_t keepTargetAxis,
0105 Int_t chunkSize = 1024 * 16);
0106 THnBase* CloneEmpty(const char* name, const char* title,
0107 const TObjArray* axes, Bool_t keepTargetAxis) const;
0108 virtual void Reserve(Long64_t ) {}
0109 virtual void SetFilledBins(Long64_t ) {};
0110
0111 Bool_t CheckConsistency(const THnBase *h, const char *tag) const;
0112 TH1* CreateHist(const char* name, const char* title,
0113 const TObjArray* axes, Bool_t keepTargetAxis) const;
0114 TObject* ProjectionAny(Int_t ndim, const Int_t* dim,
0115 Bool_t wantNDim, Option_t* option = "") const;
0116 Bool_t PrintBin(Long64_t idx, Int_t* coord, Option_t* options) const;
0117 void AddInternal(const THnBase* h, Double_t c, Bool_t rebinned);
0118 THnBase* RebinBase(Int_t group) const;
0119 THnBase* RebinBase(const Int_t* group) const;
0120 void ResetBase(Option_t *option= "");
0121 void SetTitleImpl(const char *title, bool overrideAxesTitle);
0122
0123 static THnBase* CreateHnAny(const char* name, const char* title,
0124 const TH1* h1, Bool_t sparse,
0125 Int_t chunkSize = 1024 * 16);
0126 static THnBase* CreateHnAny(const char* name, const char* title,
0127 const THnBase* hn, Bool_t sparse,
0128 Int_t chunkSize = 1024 * 16);
0129
0130 public:
0131 ~THnBase() override;
0132
0133 TObjArray* GetListOfAxes() { return &fAxes; }
0134 const TObjArray* GetListOfAxes() const { return &fAxes; }
0135 TAxis* GetAxis(Int_t dim) const { return (TAxis*)fAxes[dim]; }
0136
0137 TFitResultPtr Fit(TF1 *f1 ,Option_t *option = "", Option_t *goption = "");
0138 TList* GetListOfFunctions() { return nullptr; }
0139
0140 virtual ROOT::Internal::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const = 0;
0141
0142 virtual Long64_t GetNbins() const = 0;
0143 Double_t GetEntries() const { return fEntries; }
0144 Double_t GetWeightSum() const { return fTsumw; }
0145 Int_t GetNdimensions() const { return fNdimensions; }
0146 Bool_t GetCalculateErrors() const { return fTsumw2 >= 0.; }
0147
0148
0149 void CalculateErrors(Bool_t calc = kTRUE) {
0150 if (calc) Sumw2();
0151 else fTsumw2 = -1.;
0152 }
0153
0154 Long64_t Fill(const Double_t *x, Double_t w = 1.) {
0155 UpdateXStat(x, w);
0156 Long64_t bin = GetBin(x, kTRUE );
0157 FillBin(bin, w);
0158 return bin;
0159 }
0160 Long64_t Fill(const char* name[], Double_t w = 1.) {
0161 Long64_t bin = GetBin(name, kTRUE );
0162 FillBin(bin, w);
0163 return bin;
0164 }
0165
0166
0167
0168
0169
0170
0171 template <typename... MoreTypes>
0172 Long64_t Fill(Double_t firstval, MoreTypes... morevals)
0173 {
0174 const std::array<double, 1 + sizeof...(morevals)> x{firstval, static_cast<double>(morevals)...};
0175 if (Int_t(x.size()) == GetNdimensions()) {
0176
0177 return Fill(x.data());
0178 } else if (Int_t(x.size()) == (GetNdimensions() + 1)) {
0179
0180 return Fill(x.data(), x.back());
0181 } else {
0182 Error("Fill", "Wrong number of arguments for number of histogram axes.");
0183 }
0184
0185 return -1;
0186 }
0187
0188 virtual void FillBin(Long64_t bin, Double_t w) = 0;
0189
0190 void SetBinEdges(Int_t idim, const Double_t* bins);
0191 Bool_t IsInRange(Int_t *coord) const;
0192 Double_t GetBinError(const Int_t *idx) const { return GetBinError(GetBin(idx)); }
0193 Double_t GetBinError(Long64_t linidx) const { return TMath::Sqrt(GetBinError2(linidx)); }
0194 void SetBinError(const Int_t* idx, Double_t e) { SetBinError(GetBin(idx), e); }
0195 void SetBinError(Long64_t bin, Double_t e) { SetBinError2(bin, e*e); }
0196 void AddBinContent(const Int_t* x, Double_t v = 1.) { AddBinContent(GetBin(x), v); }
0197 void SetEntries(Double_t entries) { fEntries = entries; }
0198 void SetTitle(const char *title) override;
0199
0200 std::vector<Double_t> GetBinCenter(const std::vector<Int_t> &idx) const;
0201
0202 Double_t GetBinContent(const Int_t *idx) const { return GetBinContent(GetBin(idx)); }
0203 virtual Double_t GetBinContent(Long64_t bin, Int_t* idx = nullptr) const = 0;
0204 virtual Double_t GetBinError2(Long64_t linidx) const = 0;
0205 virtual Long64_t GetBin(const Int_t* idx) const = 0;
0206 virtual Long64_t GetBin(const Double_t* x) const = 0;
0207 virtual Long64_t GetBin(const char* name[]) const = 0;
0208 virtual Long64_t GetBin(const Int_t* idx, Bool_t = kTRUE) = 0;
0209 virtual Long64_t GetBin(const Double_t* x, Bool_t = kTRUE) = 0;
0210 virtual Long64_t GetBin(const char* name[], Bool_t = kTRUE) = 0;
0211
0212 void SetBinContent(const Int_t* idx, Double_t v) { SetBinContent(GetBin(idx), v); }
0213 virtual void SetBinContent(Long64_t bin, Double_t v) = 0;
0214 virtual void SetBinError2(Long64_t bin, Double_t e2) = 0;
0215 virtual void AddBinError2(Long64_t bin, Double_t e2) = 0;
0216 virtual void AddBinContent(Long64_t bin, Double_t v = 1.) = 0;
0217
0218 Double_t GetSumw() const { return fTsumw; }
0219 Double_t GetSumw2() const { return fTsumw2; }
0220 Double_t GetSumwx(Int_t dim) const { return fTsumwx[dim]; }
0221 Double_t GetSumwx2(Int_t dim) const { return fTsumwx2[dim]; }
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231 TH1D* Projection(Int_t xDim, Option_t* option = "") const {
0232 return (TH1D*) ProjectionAny(1, &xDim, false, option);
0233 }
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 TH2D* Projection(Int_t yDim, Int_t xDim, Option_t* option = "") const {
0245 const Int_t dim[2] = {xDim, yDim};
0246 return (TH2D*) ProjectionAny(2, dim, false, option);
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 TH3D* Projection(Int_t xDim, Int_t yDim, Int_t zDim, Option_t* option = "") const {
0258 const Int_t dim[3] = {xDim, yDim, zDim};
0259 return (TH3D*) ProjectionAny(3, dim, false, option);
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 THnBase* ProjectionND(Int_t ndim, const Int_t* dim,
0271 Option_t* option = "") const {
0272 return (THnBase*)ProjectionAny(ndim, dim, kTRUE , option);
0273 }
0274
0275 Long64_t Merge(TCollection* list);
0276
0277 void Scale(Double_t c);
0278 void Add(const THnBase* h, Double_t c=1.);
0279 void Add(const TH1* hist, Double_t c=1.);
0280 void Multiply(const THnBase* h);
0281 void Multiply(TF1* f, Double_t c = 1.);
0282 void Divide(const THnBase* h);
0283 void Divide(const THnBase* h1, const THnBase* h2, Double_t c1 = 1., Double_t c2 = 1., Option_t* option="");
0284 void RebinnedAdd(const THnBase* h, Double_t c=1.);
0285
0286 virtual void Reset(Option_t* option = "") = 0;
0287 virtual void Sumw2() = 0;
0288
0289 Double_t ComputeIntegral();
0290 void GetRandom(Double_t *rand, Bool_t subBinRandom = kTRUE);
0291 Double_t Integral(Bool_t respectAxisRange) const;
0292
0293 void Print(Option_t* option = "") const override;
0294 void PrintEntries(Long64_t from = 0, Long64_t howmany = -1, Option_t* options = nullptr) const;
0295 void PrintBin(Int_t* coord, Option_t* options) const {
0296 PrintBin(-1, coord, options);
0297 }
0298 void PrintBin(Long64_t idx, Option_t* options) const;
0299
0300 void Browse(TBrowser *b) override;
0301 Bool_t IsFolder() const override { return kTRUE; }
0302
0303
0304
0305 ClassDefOverride(THnBase, 1);
0306
0307 friend class THnIter;
0308 };
0309
0310 namespace ROOT {
0311 namespace Internal {
0312
0313 class THnBaseBrowsable: public TNamed {
0314 public:
0315 THnBaseBrowsable(THnBase* hist, Int_t axis);
0316 ~THnBaseBrowsable() override;
0317 void Browse(TBrowser *b) override;
0318 Bool_t IsFolder() const override { return kFALSE; }
0319
0320 private:
0321 THnBase* fHist;
0322 Int_t fAxis;
0323 TH1* fProj;
0324 ClassDefOverride(THnBaseBrowsable, 0);
0325 };
0326
0327
0328 class THnBaseBinIter {
0329 public:
0330 THnBaseBinIter(Bool_t respectAxisRange):
0331 fRespectAxisRange(respectAxisRange), fHaveSkippedBin(kFALSE) {}
0332 virtual ~THnBaseBinIter();
0333 Bool_t HaveSkippedBin() const { return fHaveSkippedBin; }
0334 Bool_t RespectsAxisRange() const { return fRespectAxisRange; }
0335
0336 virtual Int_t GetCoord(Int_t dim) const = 0;
0337 virtual Long64_t Next(Int_t* coord = nullptr) = 0;
0338
0339 protected:
0340 Bool_t fRespectAxisRange;
0341 Bool_t fHaveSkippedBin;
0342 };
0343 }
0344 }
0345
0346 class THnIter: public TObject {
0347 public:
0348 THnIter(const THnBase* hist, Bool_t respectAxisRange = kFALSE):
0349 fIter(hist->CreateIter(respectAxisRange)) {}
0350 ~THnIter() override;
0351
0352
0353
0354
0355
0356 Long64_t Next(Int_t* coord = nullptr) {
0357 return fIter->Next(coord);
0358 }
0359
0360 Int_t GetCoord(Int_t dim) const { return fIter->GetCoord(dim); }
0361 Bool_t HaveSkippedBin() const { return fIter->HaveSkippedBin(); }
0362 Bool_t RespectsAxisRange() const { return fIter->RespectsAxisRange(); }
0363
0364 private:
0365 ROOT::Internal::THnBaseBinIter* fIter;
0366 ClassDefOverride(THnIter, 0);
0367 };
0368
0369 #endif