Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-04 09:28:30

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& operator=(const THnSparse&) = delete;
0047 
0048  protected:
0049 
0050    THnSparseCompactBinCoord* GetCompactCoord() const;
0051    THnSparseArrayChunk* GetChunk(Int_t idx) const {
0052       return (THnSparseArrayChunk*) fBinContent[idx]; }
0053 
0054    THnSparseArrayChunk* AddChunk();
0055    void Reserve(Long64_t nbins) override;
0056    void FillExMap();
0057    virtual TArray* GenerateArray() const = 0;
0058    Long64_t GetBinIndexForCurrentBin(Bool_t allocate);
0059 
0060    /// Increment the bin content of "bin" by "w",
0061    /// return the bin index.
0062    void FillBin(Long64_t bin, Double_t w) override {
0063       THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
0064       chunk->AddBinContent(bin % fChunkSize, w);
0065       FillBinBase(w);
0066    }
0067    void InitStorage(Int_t* nbins, Int_t chunkSize) override;
0068 
0069  public:
0070 
0071    THnSparse();
0072    THnSparse(const char* name, const char* title, Int_t dim,
0073              const Int_t* nbins, const Double_t* xmin = nullptr, const Double_t* xmax = nullptr,
0074              Int_t chunksize = 1024 * 16);
0075    THnSparse(const char* name, const char* title,
0076              const std::vector<TAxis>& axes,
0077              Int_t chunksize = 1024 * 16);
0078 
0079    THnSparse(const char *name, const char *title, Int_t dim, const Int_t *nbins,
0080              const std::vector<std::vector<double>> &xbins, Int_t chunksize = 1024 * 16);
0081 
0082    THnSparse(const THnSparse &other);
0083 
0084    ~THnSparse() override;
0085 
0086    static THnSparse* CreateSparse(const char* name, const char* title,
0087                                   const TH1* h1, Int_t chunkSize = 1024 * 16) {
0088       return (THnSparse*) CreateHnAny(name, title, h1, kTRUE /*sparse*/,
0089                                        chunkSize);
0090    }
0091    static THnSparse* CreateSparse(const char* name, const char* title,
0092                                   const THnBase* hn, Int_t chunkSize = 1024 * 16) {
0093       return (THnSparse*) CreateHnAny(name, title, hn, kTRUE /*sparse*/,
0094                                        chunkSize);
0095    }
0096 
0097    Int_t GetChunkSize() const { return fChunkSize; }
0098    Int_t GetNChunks() const { return fBinContent.GetEntriesFast(); }
0099 
0100    ROOT::Internal::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const override;
0101 
0102    Long64_t GetNbins() const override { return fFilledBins; }
0103    void SetFilledBins(Long64_t nbins) override { fFilledBins = nbins; }
0104 
0105    Long64_t GetBin(const Int_t* idx) const override { return const_cast<THnSparse*>(this)->GetBin(idx, kFALSE); }
0106    Long64_t GetBin(const Double_t* x) const override { return const_cast<THnSparse*>(this)->GetBin(x, kFALSE); }
0107    Long64_t GetBin(const char* name[]) const override { return const_cast<THnSparse*>(this)->GetBin(name, kFALSE); }
0108    Long64_t GetBin(const Int_t* idx, Bool_t allocate = kTRUE) override;
0109    Long64_t GetBin(const Double_t* x, Bool_t allocate = kTRUE) override;
0110    Long64_t GetBin(const char* name[], Bool_t allocate = kTRUE) override;
0111 
0112    using THnBase::SetBinContent; // non-virtual SetBinContent(const Int_t* idx, Double_t v)
0113    void SetBinContent(Long64_t bin, Double_t v) override;
0114    void SetBinError2(Long64_t bin, Double_t e2) override;
0115 
0116    using THnBase::AddBinContent; // non-virtual void AddBinContent(const Int_t* idx, Double_t v = 1.)
0117    void AddBinContent(Long64_t bin, Double_t v = 1.) override;
0118    void AddBinError2(Long64_t bin, Double_t e2) override;
0119 
0120    using THnBase::GetBinContent; // non-virtual Double_t GetBinContent(const Int_t *idx) const
0121    Double_t GetBinContent(Long64_t bin, Int_t* idx = nullptr) const override;
0122    Double_t GetBinError2(Long64_t linidx) const override;
0123 
0124    Double_t GetSparseFractionBins() const;
0125    Double_t GetSparseFractionMem() const;
0126 
0127    using THnBase::Projection; // non-virtual TH1D* Projection(Int_t xDim, Option_t* option = "") const
0128                               //             TH2D* Projection(Int_t yDim, Int_t xDim, Option_t* option = "") const
0129                               //             TH3D* Projection(Int_t xDim, Int_t yDim, Int_t zDim, Option_t* option = "") const
0130 
0131    THnSparse* Projection(Int_t ndim, const Int_t* dim,
0132                          Option_t* option = "") const {
0133       return (THnSparse*) ProjectionND(ndim, dim, option);
0134    }
0135 
0136    THnSparse* Rebin(Int_t group) const {
0137       return (THnSparse*) RebinBase(group);
0138    }
0139    THnSparse* Rebin(const Int_t* group) const {
0140       return (THnSparse*) RebinBase(group);
0141    }
0142 
0143    void Reset(Option_t* option = "") override;
0144    void Sumw2() override;
0145 
0146    ClassDefOverride(THnSparse, 3); // Interfaces of sparse n-dimensional histogram
0147 };
0148 
0149 
0150 
0151 //______________________________________________________________________________
0152 /** \class THnSparseT
0153  Templated implementation of the abstract base THnSparse.
0154  All functionality and the interfaces to be used are in THnSparse!
0155 
0156  THnSparse does not know how to store any bin content itself. Instead, this
0157  is delegated to the derived, templated class: the template parameter decides
0158  what the format for the bin content is. In fact it even defines the array
0159  itself; possible implementations probably derive from TArray.
0160 
0161  Typedefs exist for template parameters with ROOT's generic types:
0162 
0163  Templated name        |    Typedef    |    Bin content type
0164  ----------------------|---------------|--------------------
0165  THnSparseT<TArrayC>   |  THnSparseC   |  Char_t
0166  THnSparseT<TArrayS>   |  THnSparseS   |  Short_t
0167  THnSparseT<TArrayI>   |  THnSparseI   |  Int_t
0168  THnSparseT<TArrayL64> |  THnSparseL   |  Long64_t
0169  THnSparseT<TArrayF>   |  THnSparseF   |  Float_t
0170  THnSparseT<TArrayD>   |  THnSparseD   |  Double_t
0171 
0172  We recommend to use THnSparseC wherever possible, and to map its value space
0173  of 256 possible values to e.g. float values outside the class. This saves an
0174  enormous amount of memory. Only if more than 256 values need to be
0175  distinguished should e.g. THnSparseS or even THnSparseF be chosen.
0176 
0177  Implementation detail: the derived, templated class is kept extremely small
0178  on purpose. That way the (templated thus inlined) uses of this class will
0179  only create a small amount of machine code, in contrast to e.g. STL.
0180 */
0181 
0182 
0183 template <class CONT>
0184 class THnSparseT: public THnSparse {
0185  public:
0186    using THnSparse::THnSparse;
0187 
0188    TArray* GenerateArray() const override { return new CONT(GetChunkSize()); }
0189  private:
0190    ClassDefOverride(THnSparseT, 1); // Sparse n-dimensional histogram with templated content
0191 };
0192 
0193 typedef THnSparseT<TArrayD> THnSparseD;
0194 typedef THnSparseT<TArrayF> THnSparseF;
0195 typedef THnSparseT<TArrayL64> THnSparseL;
0196 typedef THnSparseT<TArrayI> THnSparseI;
0197 typedef THnSparseT<TArrayS> THnSparseS;
0198 typedef THnSparseT<TArrayC> THnSparseC;
0199 
0200 
0201 #endif //  ROOT_THnSparse