Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:33:53

0001 // @(#)root/hist:$Id$
0002 // Author: Axel Naumann (2007-09-11)
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_THnSparse
0013 #define ROOT_THnSparse
0014 
0015 /*************************************************************************
0016 
0017  THnSparse: histogramming multi-dimensional, sparse distributions in
0018  a memory-efficient way.
0019 
0020 *************************************************************************/
0021 
0022 
0023 #include "THnBase.h"
0024 #include "TExMap.h"
0025 #include "THnSparse_Internal.h"
0026 
0027 // needed only for template instantiations of THnSparseT:
0028 #include "TArrayF.h"
0029 #include "TArrayL.h"
0030 #include "TArrayL64.h"
0031 #include "TArrayI.h"
0032 #include "TArrayS.h"
0033 #include "TArrayC.h"
0034 
0035 class THnSparseCompactBinCoord;
0036 
0037 class THnSparse: public THnBase {
0038  private:
0039    Int_t      fChunkSize;                   ///<  Number of entries for each chunk
0040    Long64_t   fFilledBins;                  ///<  Number of filled bins
0041    TObjArray  fBinContent;                  ///<  Array of THnSparseArrayChunk
0042    TExMap     fBins;                        ///<! Filled bins
0043    TExMap     fBinsContinued;               ///<! Filled bins for non-unique hashes, containing pairs of (bin index 0, bin index 1)
0044    THnSparseCompactBinCoord *fCompactCoord; ///<! Compact coordinate
0045 
0046    THnSparse(const THnSparse&) = delete;
0047    THnSparse& operator=(const THnSparse&) = delete;
0048 
0049  protected:
0050 
0051    THnSparseCompactBinCoord* GetCompactCoord() const;
0052    THnSparseArrayChunk* GetChunk(Int_t idx) const {
0053       return (THnSparseArrayChunk*) fBinContent[idx]; }
0054 
0055    THnSparseArrayChunk* AddChunk();
0056    void Reserve(Long64_t nbins) override;
0057    void FillExMap();
0058    virtual TArray* GenerateArray() const = 0;
0059    Long64_t GetBinIndexForCurrentBin(Bool_t allocate);
0060 
0061    /// Increment the bin content of "bin" by "w",
0062    /// return the bin index.
0063    void FillBin(Long64_t bin, Double_t w) override {
0064       THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
0065       chunk->AddBinContent(bin % fChunkSize, w);
0066       FillBinBase(w);
0067    }
0068    void InitStorage(Int_t* nbins, Int_t chunkSize) override;
0069 
0070  public:
0071 
0072    THnSparse();
0073    THnSparse(const char* name, const char* title, Int_t dim,
0074              const Int_t* nbins, const Double_t* xmin = nullptr, const Double_t* xmax = nullptr,
0075              Int_t chunksize = 1024 * 16);
0076    THnSparse(const char* name, const char* title,
0077              const std::vector<TAxis>& axes,
0078              Int_t chunksize = 1024 * 16);
0079 
0080    ~THnSparse() override;
0081 
0082    static THnSparse* CreateSparse(const char* name, const char* title,
0083                                   const TH1* h1, Int_t chunkSize = 1024 * 16) {
0084       return (THnSparse*) CreateHnAny(name, title, h1, kTRUE /*sparse*/,
0085                                        chunkSize);
0086    }
0087    static THnSparse* CreateSparse(const char* name, const char* title,
0088                                   const THnBase* hn, Int_t chunkSize = 1024 * 16) {
0089       return (THnSparse*) CreateHnAny(name, title, hn, kTRUE /*sparse*/,
0090                                        chunkSize);
0091    }
0092 
0093    Int_t GetChunkSize() const { return fChunkSize; }
0094    Int_t GetNChunks() const { return fBinContent.GetEntriesFast(); }
0095 
0096    ROOT::Internal::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const override;
0097 
0098    Long64_t GetNbins() const override { return fFilledBins; }
0099    void SetFilledBins(Long64_t nbins) override { fFilledBins = nbins; }
0100 
0101    Long64_t GetBin(const Int_t* idx) const override { return const_cast<THnSparse*>(this)->GetBin(idx, kFALSE); }
0102    Long64_t GetBin(const Double_t* x) const override { return const_cast<THnSparse*>(this)->GetBin(x, kFALSE); }
0103    Long64_t GetBin(const char* name[]) const override { return const_cast<THnSparse*>(this)->GetBin(name, kFALSE); }
0104    Long64_t GetBin(const Int_t* idx, Bool_t allocate = kTRUE) override;
0105    Long64_t GetBin(const Double_t* x, Bool_t allocate = kTRUE) override;
0106    Long64_t GetBin(const char* name[], Bool_t allocate = kTRUE) override;
0107 
0108    /// Forwards to THnBase::SetBinContent().
0109    /// Non-virtual, CINT-compatible replacement of a using declaration.
0110    void SetBinContent(const Int_t* idx, Double_t v) {
0111       THnBase::SetBinContent(idx, v);
0112    }
0113    void SetBinContent(Long64_t bin, Double_t v) override;
0114    void SetBinError2(Long64_t bin, Double_t e2) override;
0115 
0116    /// Forwards to THnBase::AddBinContent().
0117    /// Non-virtual, CINT-compatible replacement of a using declaration.
0118    void AddBinContent(const Int_t* idx, Double_t v = 1.) {
0119       THnBase::AddBinContent(idx, v);
0120    }
0121    void AddBinContent(Long64_t bin, Double_t v = 1.) override;
0122    void AddBinError2(Long64_t bin, Double_t e2) override;
0123 
0124    /// Forwards to THnBase::GetBinContent() overload.
0125    /// Non-virtual, CINT-compatible replacement of a using declaration.
0126    Double_t GetBinContent(const Int_t *idx) const {
0127 
0128       return THnBase::GetBinContent(idx);
0129    }
0130    Double_t GetBinContent(Long64_t bin, Int_t* idx = nullptr) const override;
0131    Double_t GetBinError2(Long64_t linidx) const override;
0132 
0133    Double_t GetSparseFractionBins() const;
0134    Double_t GetSparseFractionMem() const;
0135 
0136    /// Forwards to THnBase::Projection().
0137    /// Non-virtual, as a CINT-compatible replacement of a using
0138    /// declaration.
0139    TH1D*      Projection(Int_t xDim, Option_t* option = "") const{
0140       return THnBase::Projection(xDim, option);
0141    }
0142 
0143    /// Forwards to THnBase::Projection().
0144    /// Non-virtual, as a CINT-compatible replacement of a using
0145    /// declaration.
0146    TH2D*      Projection(Int_t yDim, Int_t xDim,
0147                          Option_t* option = "") const {
0148       return THnBase::Projection(yDim, xDim, option);
0149    }
0150 
0151    /// Forwards to THnBase::Projection().
0152    /// Non-virtual, as a CINT-compatible replacement of a using
0153    /// declaration.
0154    TH3D*      Projection(Int_t xDim, Int_t yDim, Int_t zDim,
0155                          Option_t* option = "") const {
0156       return THnBase::Projection(xDim, yDim, zDim, option);
0157    }
0158 
0159    THnSparse* Projection(Int_t ndim, const Int_t* dim,
0160                          Option_t* option = "") const {
0161       return (THnSparse*) ProjectionND(ndim, dim, option);
0162    }
0163 
0164    THnSparse* Rebin(Int_t group) const {
0165       return (THnSparse*) RebinBase(group);
0166    }
0167    THnSparse* Rebin(const Int_t* group) const {
0168       return (THnSparse*) RebinBase(group);
0169    }
0170 
0171    void Reset(Option_t* option = "") override;
0172    void Sumw2() override;
0173 
0174    ClassDefOverride(THnSparse, 3); // Interfaces of sparse n-dimensional histogram
0175 };
0176 
0177 
0178 
0179 //______________________________________________________________________________
0180 /** \class THnSparseT
0181  Templated implementation of the abstract base THnSparse.
0182  All functionality and the interfaces to be used are in THnSparse!
0183 
0184  THnSparse does not know how to store any bin content itself. Instead, this
0185  is delegated to the derived, templated class: the template parameter decides
0186  what the format for the bin content is. In fact it even defines the array
0187  itself; possible implementations probably derive from TArray.
0188 
0189  Typedefs exist for template parameters with ROOT's generic types:
0190 
0191  Templated name        |    Typedef    |    Bin content type
0192  ----------------------|---------------|--------------------
0193  THnSparseT<TArrayC>   |  THnSparseC   |  Char_t
0194  THnSparseT<TArrayS>   |  THnSparseS   |  Short_t
0195  THnSparseT<TArrayI>   |  THnSparseI   |  Int_t
0196  THnSparseT<TArrayL64> |  THnSparseL   |  Long64_t
0197  THnSparseT<TArrayF>   |  THnSparseF   |  Float_t
0198  THnSparseT<TArrayD>   |  THnSparseD   |  Double_t
0199 
0200  We recommend to use THnSparseC wherever possible, and to map its value space
0201  of 256 possible values to e.g. float values outside the class. This saves an
0202  enormous amount of memory. Only if more than 256 values need to be
0203  distinguished should e.g. THnSparseS or even THnSparseF be chosen.
0204 
0205  Implementation detail: the derived, templated class is kept extremely small
0206  on purpose. That way the (templated thus inlined) uses of this class will
0207  only create a small amount of machine code, in contrast to e.g. STL.
0208 */
0209 
0210 
0211 template <class CONT>
0212 class THnSparseT: public THnSparse {
0213  public:
0214    using THnSparse::THnSparse;
0215 
0216    TArray* GenerateArray() const override { return new CONT(GetChunkSize()); }
0217  private:
0218    ClassDefOverride(THnSparseT, 1); // Sparse n-dimensional histogram with templated content
0219 };
0220 
0221 typedef THnSparseT<TArrayD> THnSparseD;
0222 typedef THnSparseT<TArrayF> THnSparseF;
0223 typedef THnSparseT<TArrayL64> THnSparseL;
0224 typedef THnSparseT<TArrayI> THnSparseI;
0225 typedef THnSparseT<TArrayS> THnSparseS;
0226 typedef THnSparseT<TArrayC> THnSparseC;
0227 
0228 
0229 #endif //  ROOT_THnSparse