Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-10 09:26:58

0001 // @(#)root/hist:$Id$
0002 // Author: Axel Naumann, Nov 2011
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_THN
0013 #define ROOT_THN
0014 
0015 #include "THnBase.h"
0016 
0017 #include "TNDArray.h"
0018 
0019 #include "TArrayD.h"
0020 
0021 #include "TAxis.h"
0022 
0023 class TH1;
0024 class TH1D;
0025 class TH2D;
0026 class TH3D;
0027 class THnSparse;
0028 class TF1;
0029 
0030 class THn: public THnBase {
0031 
0032 protected:
0033    void AllocCoordBuf() const;
0034    void InitStorage(Int_t* nbins, Int_t chunkSize) override;
0035 
0036    THn() = default;
0037    THn(const char* name, const char* title, Int_t dim, const Int_t* nbins,
0038        const Double_t* xmin, const Double_t* xmax);
0039    THn(const char *name, const char *title, const std::vector<TAxis> &axes);
0040    THn(const char *name, const char *title, Int_t dim, const Int_t *nbins,
0041        const std::vector<std::vector<double>> &xbins);
0042 
0043 public:
0044    ~THn() override;
0045 
0046    static THn* CreateHn(const char* name, const char* title, const TH1* h1) {
0047       return (THn*) CreateHnAny(name, title, h1, kFALSE /*THn*/, -1);
0048    }
0049    static THn* CreateHn(const char* name, const char* title, const THnBase* hn) {
0050       return (THn*) CreateHnAny(name, title, hn, kFALSE /*THn*/, -1);
0051    }
0052 
0053    ROOT::Internal::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const override;
0054    Long64_t GetNbins() const override { return GetArray().GetNbins(); }
0055 
0056    Long64_t GetBin(const Int_t* idx) const override {
0057       return GetArray().GetBin(idx);
0058    }
0059    Long64_t GetBin(const Double_t* x) const override {
0060       if (fCoordBuf.empty())
0061          AllocCoordBuf();
0062       for (Int_t d = 0; d < fNdimensions; ++d) {
0063          fCoordBuf[d] = GetAxis(d)->FindFixBin(x[d]);
0064       }
0065       return GetArray().GetBin(fCoordBuf.data());
0066    }
0067    Long64_t GetBin(const char* name[]) const override {
0068       if (fCoordBuf.empty())
0069          AllocCoordBuf();
0070       for (Int_t d = 0; d < fNdimensions; ++d) {
0071          fCoordBuf[d] = GetAxis(d)->FindBin(name[d]);
0072       }
0073       return GetArray().GetBin(fCoordBuf.data());
0074    }
0075 
0076    Long64_t GetBin(const Int_t* idx, Bool_t /*allocate*/ = kTRUE) override {
0077       return const_cast<const THn*>(this)->GetBin(idx);
0078    }
0079    Long64_t GetBin(const Double_t* x, Bool_t /*allocate*/ = kTRUE) override {
0080       return const_cast<const THn*>(this)->GetBin(x);
0081    }
0082    Long64_t GetBin(const char* name[], Bool_t /*allocate*/ = kTRUE) override {
0083       return const_cast<const THn*>(this)->GetBin(name);
0084    }
0085 
0086    /// Increment the bin content of "bin" by "w", return the bin index.
0087    void FillBin(Long64_t bin, Double_t w) override {
0088       GetArray().AddAt(bin, w);
0089       if (GetCalculateErrors()) {
0090          fSumw2.AddAt(bin, w * w);
0091       }
0092       FillBinBase(w);
0093    }
0094 
0095    using THnBase::SetBinContent; // non-virtual void SetBinContent(const Int_t* idx, Double_t v)
0096    void SetBinContent(Long64_t bin, Double_t v) override {
0097       GetArray().SetAsDouble(bin, v);
0098    }
0099    void SetBinError2(Long64_t bin, Double_t e2) override {
0100       if (!GetCalculateErrors()) Sumw2();
0101       fSumw2.At(bin) = e2;
0102    }
0103    using THnBase::AddBinContent; // non-virtual void AddBinContent(const Int_t* idx, Double_t v = 1.)
0104    void AddBinContent(Long64_t bin, Double_t v = 1.) override {
0105       GetArray().AddAt(bin, v);
0106    }
0107    void AddBinError2(Long64_t bin, Double_t e2) override {
0108       fSumw2.At(bin) += e2;
0109    }
0110    using THnBase::GetBinContent; // non-virtual Double_t GetBinContent(const Int_t *idx) const
0111    /// Get the content of bin, and set its index if idx is != 0.
0112    Double_t GetBinContent(Long64_t bin, Int_t* idx = nullptr) const override {
0113       if (idx) {
0114          const TNDArray& arr = GetArray();
0115          Long64_t prevCellSize = arr.GetNbins();
0116          for (Int_t i = 0; i < GetNdimensions(); ++i) {
0117             Long64_t cellSize = arr.GetCellSize(i);
0118             idx[i] = (bin % prevCellSize) / cellSize;
0119             prevCellSize = cellSize;
0120          }
0121       }
0122       return GetArray().AtAsDouble(bin);
0123    }
0124    Double_t GetBinError2(Long64_t linidx) const override {
0125       return GetCalculateErrors() ? fSumw2.At(linidx) : GetBinContent(linidx);
0126    }
0127 
0128    virtual const TNDArray& GetArray() const = 0;
0129    virtual TNDArray& GetArray() = 0;
0130 
0131    void Sumw2() override;
0132 
0133    using THnBase::Projection; // non-virtual TH1D* Projection(Int_t xDim, Option_t* option = "") const
0134                               //             TH2D* Projection(Int_t yDim, Int_t xDim, Option_t* option = "") const
0135                               //             TH3D* Projection(Int_t xDim, Int_t yDim, Int_t zDim, Option_t* option = "") const
0136 
0137    THn*       Projection(Int_t ndim, const Int_t* dim,
0138                          Option_t* option = "") const {
0139       return (THn*) ProjectionND(ndim, dim, option);
0140    }
0141 
0142    THn*       Rebin(Int_t group) const {
0143       return (THn*) RebinBase(group);
0144    }
0145    THn*       Rebin(const Int_t* group) const {
0146       return (THn*) RebinBase(group);
0147    }
0148 
0149    void Reset(Option_t* option = "") override;
0150 
0151 protected:
0152    TNDArrayT<Double_t> fSumw2; // bin error, lazy allocation happens in TNDArrayT
0153    mutable std::vector<Int_t> fCoordBuf; ///<! Temporary buffer
0154 
0155    ClassDefOverride(THn, 1); //Base class for multi-dimensional histogram
0156 };
0157 
0158 
0159 //______________________________________________________________________________
0160 /** \class THnT
0161  Templated implementation of the abstract base THn.
0162  All functionality and the interfaces to be used are in THn!
0163 
0164  THn does not know how to store any bin content itself. Instead, this
0165  is delegated to the derived, templated class: the template parameter decides
0166  what the format for the bin content is. The actual storage is delegated to
0167  TNDArrayT<T>.
0168 
0169  Typedefs exist for template parameters with ROOT's generic types:
0170 
0171  Templated name   |     Typedef   |    Bin content type
0172  -----------------|---------------|--------------------
0173    THnT<Char_t>   |       THnC    |     Char_t
0174    THnT<Short_t>  |       THnS    |     Short_t
0175    THnT<Int_t>    |       THnI    |     Int_t
0176    THnT<Long64_t> |       THnL    |     Long64_t
0177    THnT<Float_t>  |       THnF    |     Float_t
0178    THnT<Double_t> |       THnD    |     Double_t
0179 
0180  We recommend to use THnC wherever possible, and to map its value space
0181  of 256 possible values to e.g. float values outside the class. This saves an
0182  enormous amount of memory. Only if more than 256 values need to be
0183  distinguished should e.g. THnS or even THnF be chosen.
0184 
0185  Implementation detail: the derived, templated class is kept extremely small
0186  on purpose. That way the (templated thus inlined) uses of this class will
0187  only create a small amount of machine code, in contrast to e.g. STL.
0188 */
0189 
0190 template <typename T>
0191 class THnT: public THn {
0192 public:
0193    THnT() {}
0194 
0195    THnT(const char* name, const char* title,
0196        Int_t dim, const Int_t* nbins,
0197        const Double_t* xmin, const Double_t* xmax):
0198    THn(name, title, dim, nbins, xmin, xmax),
0199    fArray(dim, nbins, true)  {}
0200 
0201    THnT(const char *name, const char *title, const std::vector<TAxis> &axes) : THn(name, title, axes)
0202    {
0203       const Int_t dim = axes.size();
0204       std::vector<Int_t> nbins(dim);
0205       for (Int_t i = 0; i < dim; i++)
0206          nbins[i] = axes.at(i).GetNbins();
0207       fArray = TNDArrayT<T>(dim, nbins.data(), true);
0208    }
0209 
0210    THnT(const char *name, const char *title, Int_t dim, const Int_t *nbins,
0211         const std::vector<std::vector<double>> &xbins)
0212       : THn(name, title, dim, nbins, xbins), fArray(dim, nbins, true)
0213    {
0214    }
0215 
0216    const TNDArray& GetArray() const override { return fArray; }
0217    TNDArray& GetArray() override { return fArray; }
0218 
0219 protected:
0220    TNDArrayT<T> fArray; ///< Bin content
0221    ClassDefOverride(THnT, 1);   ///< Multi-dimensional histogram with templated storage
0222 };
0223 
0224 typedef THnT<Float_t>  THnF;
0225 typedef THnT<Double_t> THnD;
0226 typedef THnT<Char_t>   THnC;
0227 typedef THnT<Short_t>  THnS;
0228 typedef THnT<Int_t>    THnI;
0229 typedef THnT<Long64_t> THnL;
0230 typedef THnT<Long64_t> THnL64;
0231 
0232 #endif // ROOT_THN