Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:09

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 
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    /// Forwards to THnBase::SetBinContent().
0096    /// Non-virtual, CINT-compatible replacement of a using declaration.
0097    void SetBinContent(const Int_t* idx, Double_t v) {
0098       THnBase::SetBinContent(idx, v);
0099    }
0100    void SetBinContent(Long64_t bin, Double_t v) override {
0101       GetArray().SetAsDouble(bin, v);
0102    }
0103    void SetBinError2(Long64_t bin, Double_t e2) override {
0104       if (!GetCalculateErrors()) Sumw2();
0105       fSumw2.At(bin) = e2;
0106    }
0107    /// Forwards to THnBase::SetBinContent().
0108    /// Non-virtual, CINT-compatible replacement of a using declaration.
0109    void AddBinContent(const Int_t* idx, Double_t v = 1.) {
0110       THnBase::AddBinContent(idx, v);
0111    }
0112    void AddBinContent(Long64_t bin, Double_t v = 1.) override {
0113       GetArray().AddAt(bin, v);
0114    }
0115    void AddBinError2(Long64_t bin, Double_t e2) override {
0116       fSumw2.At(bin) += e2;
0117    }
0118    /// Forwards to THnBase::GetBinContent() overload.
0119    /// Non-virtual, CINT-compatible replacement of a using declaration.
0120    Double_t GetBinContent(const Int_t *idx) const {
0121       return THnBase::GetBinContent(idx);
0122    }
0123    /// Get the content of bin, and set its index if idx is != 0.
0124    Double_t GetBinContent(Long64_t bin, Int_t* idx = nullptr) const override {
0125       if (idx) {
0126          const TNDArray& arr = GetArray();
0127          Long64_t prevCellSize = arr.GetNbins();
0128          for (Int_t i = 0; i < GetNdimensions(); ++i) {
0129             Long64_t cellSize = arr.GetCellSize(i);
0130             idx[i] = (bin % prevCellSize) / cellSize;
0131             prevCellSize = cellSize;
0132          }
0133       }
0134       return GetArray().AtAsDouble(bin);
0135    }
0136    Double_t GetBinError2(Long64_t linidx) const override {
0137       return GetCalculateErrors() ? fSumw2.At(linidx) : GetBinContent(linidx);
0138    }
0139 
0140    virtual const TNDArray& GetArray() const = 0;
0141    virtual TNDArray& GetArray() = 0;
0142 
0143    void Sumw2() override;
0144 
0145    /// Forwards to THnBase::Projection().
0146    /// Non-virtual, as a CINT-compatible replacement of a using declaration.
0147    TH1D*      Projection(Int_t xDim, Option_t* option = "") const {
0148       return THnBase::Projection(xDim, option);
0149    }
0150 
0151    /// Forwards to THnBase::Projection().
0152    /// Non-virtual, as a CINT-compatible replacement of a using declaration.
0153    TH2D*      Projection(Int_t yDim, Int_t xDim,
0154                          Option_t* option = "") const {
0155       return THnBase::Projection(yDim, xDim, option);
0156    }
0157 
0158    /// Forwards to THnBase::Projection().
0159    /// Non-virtual, as a CINT-compatible replacement of a using declaration.
0160    TH3D*      Projection(Int_t xDim, Int_t yDim, Int_t zDim,
0161                          Option_t* option = "") const {
0162       return THnBase::Projection(xDim, yDim, zDim, option);
0163    }
0164 
0165    THn*       Projection(Int_t ndim, const Int_t* dim,
0166                          Option_t* option = "") const {
0167       return (THn*) ProjectionND(ndim, dim, option);
0168    }
0169 
0170    THn*       Rebin(Int_t group) const {
0171       return (THn*) RebinBase(group);
0172    }
0173    THn*       Rebin(const Int_t* group) const {
0174       return (THn*) RebinBase(group);
0175    }
0176 
0177    void Reset(Option_t* option = "") override;
0178 
0179 protected:
0180    TNDArrayT<Double_t> fSumw2; // bin error, lazy allocation happens in TNDArrayT
0181    mutable std::vector<Int_t> fCoordBuf; //! Temporary buffer
0182 
0183    ClassDefOverride(THn, 1); //Base class for multi-dimensional histogram
0184 };
0185 
0186 
0187 //______________________________________________________________________________
0188 /** \class THnT
0189  Templated implementation of the abstract base THn.
0190  All functionality and the interfaces to be used are in THn!
0191 
0192  THn does not know how to store any bin content itself. Instead, this
0193  is delegated to the derived, templated class: the template parameter decides
0194  what the format for the bin content is. The actual storage is delegated to
0195  TNDArrayT<T>.
0196 
0197  Typedefs exist for template parameters with ROOT's generic types:
0198 
0199  Templated name   |     Typedef   |    Bin content type
0200  -----------------|---------------|--------------------
0201    THnT<Char_t>   |       THnC    |     Char_t
0202    THnT<Short_t>  |       THnS    |     Short_t
0203    THnT<Int_t>    |       THnI    |     Int_t
0204    THnT<Long64_t> |       THnL    |     Long64_t
0205    THnT<Float_t>  |       THnF    |     Float_t
0206    THnT<Double_t> |       THnD    |     Double_t
0207 
0208  We recommend to use THnC wherever possible, and to map its value space
0209  of 256 possible values to e.g. float values outside the class. This saves an
0210  enormous amount of memory. Only if more than 256 values need to be
0211  distinguished should e.g. THnS or even THnF be chosen.
0212 
0213  Implementation detail: the derived, templated class is kept extremely small
0214  on purpose. That way the (templated thus inlined) uses of this class will
0215  only create a small amount of machine code, in contrast to e.g. STL.
0216 */
0217 
0218 template <typename T>
0219 class THnT: public THn {
0220 public:
0221    THnT() {}
0222 
0223    THnT(const char* name, const char* title,
0224        Int_t dim, const Int_t* nbins,
0225        const Double_t* xmin, const Double_t* xmax):
0226    THn(name, title, dim, nbins, xmin, xmax),
0227    fArray(dim, nbins, true)  {}
0228 
0229    THnT(const char *name, const char *title, Int_t dim, const Int_t *nbins,
0230         const std::vector<std::vector<double>> &xbins)
0231       : THn(name, title, dim, nbins, xbins), fArray(dim, nbins, true)
0232    {
0233    }
0234 
0235    const TNDArray& GetArray() const override { return fArray; }
0236    TNDArray& GetArray() override { return fArray; }
0237 
0238 protected:
0239    TNDArrayT<T> fArray; ///< Bin content
0240    ClassDefOverride(THnT, 1);   ///< Multi-dimensional histogram with templated storage
0241 };
0242 
0243 typedef THnT<Float_t>  THnF;
0244 typedef THnT<Double_t> THnD;
0245 typedef THnT<Char_t>   THnC;
0246 typedef THnT<Short_t>  THnS;
0247 typedef THnT<Int_t>    THnI;
0248 typedef THnT<Long64_t> THnL;
0249 typedef THnT<Long64_t> THnL64;
0250 
0251 #endif // ROOT_THN