Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
THnSparse.h
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Axel Naumann (2007-09-11)
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2012, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_THnSparse
13 #define ROOT_THnSparse
14 
15 /*************************************************************************
16 
17  THnSparse: histogramming multi-dimensional, sparse distributions in
18  a memory-efficient way.
19 
20 *************************************************************************/
21 
22 
23 #include "THnBase.h"
24 #include "TExMap.h"
25 #include "THnSparse_Internal.h"
26 
27 // needed only for template instantiations of THnSparseT:
28 #include "TArrayF.h"
29 #include "TArrayL.h"
30 #include "TArrayI.h"
31 #include "TArrayS.h"
32 #include "TArrayC.h"
33 
34 class THnSparseCompactBinCoord;
35 
36 class THnSparse: public THnBase {
37  private:
38  Int_t fChunkSize; // number of entries for each chunk
39  Long64_t fFilledBins; // number of filled bins
40  TObjArray fBinContent; // array of THnSparseArrayChunk
41  TExMap fBins; //! filled bins
42  TExMap fBinsContinued;//! filled bins for non-unique hashes, containing pairs of (bin index 0, bin index 1)
43  THnSparseCompactBinCoord *fCompactCoord; //! compact coordinate
44 
45  THnSparse(const THnSparse&); // Not implemented
46  THnSparse& operator=(const THnSparse&); // Not implemented
47 
48  protected:
49 
50  THnSparse();
51  THnSparse(const char* name, const char* title, Int_t dim,
52  const Int_t* nbins, const Double_t* xmin, const Double_t* xmax,
53  Int_t chunksize);
54  THnSparseCompactBinCoord* GetCompactCoord() const;
55  THnSparseArrayChunk* GetChunk(Int_t idx) const {
56  return (THnSparseArrayChunk*) fBinContent[idx]; }
57 
58  THnSparseArrayChunk* AddChunk();
59  void Reserve(Long64_t nbins);
60  void FillExMap();
61  virtual TArray* GenerateArray() const = 0;
62  Long64_t GetBinIndexForCurrentBin(Bool_t allocate);
63 
64  /// Increment the bin content of "bin" by "w",
65  /// return the bin index.
66  void FillBin(Long64_t bin, Double_t w) {
67  THnSparseArrayChunk* chunk = GetChunk(bin / fChunkSize);
68  chunk->AddBinContent(bin % fChunkSize, w);
69  FillBinBase(w);
70  }
71  void InitStorage(Int_t* nbins, Int_t chunkSize);
72 
73  public:
74  virtual ~THnSparse();
75 
76  static THnSparse* CreateSparse(const char* name, const char* title,
77  const TH1* h1, Int_t chunkSize = 1024 * 16) {
78  return (THnSparse*) CreateHnAny(name, title, h1, kTRUE /*sparse*/,
79  chunkSize);
80  }
81  static THnSparse* CreateSparse(const char* name, const char* title,
82  const THnBase* hn, Int_t chunkSize = 1024 * 16) {
83  return (THnSparse*) CreateHnAny(name, title, hn, kTRUE /*sparse*/,
84  chunkSize);
85  }
86 
87  Int_t GetChunkSize() const { return fChunkSize; }
88  Int_t GetNChunks() const { return fBinContent.GetEntriesFast(); }
89 
90  ROOT::Internal::THnBaseBinIter* CreateIter(Bool_t respectAxisRange) const;
91 
92  Long64_t GetNbins() const { return fFilledBins; }
93  void SetFilledBins(Long64_t nbins) { fFilledBins = nbins; }
94 
95  Long64_t GetBin(const Int_t* idx) const { return const_cast<THnSparse*>(this)->GetBin(idx, kFALSE); }
96  Long64_t GetBin(const Double_t* x) const { return const_cast<THnSparse*>(this)->GetBin(x, kFALSE); }
97  Long64_t GetBin(const char* name[]) const { return const_cast<THnSparse*>(this)->GetBin(name, kFALSE); }
98  Long64_t GetBin(const Int_t* idx, Bool_t allocate = kTRUE);
99  Long64_t GetBin(const Double_t* x, Bool_t allocate = kTRUE);
100  Long64_t GetBin(const char* name[], Bool_t allocate = kTRUE);
101 
102  /// Forwards to THnBase::SetBinContent().
103  /// Non-virtual, CINT-compatible replacement of a using declaration.
104  void SetBinContent(const Int_t* idx, Double_t v) {
105  THnBase::SetBinContent(idx, v);
106  }
107  void SetBinContent(Long64_t bin, Double_t v);
108  void SetBinError2(Long64_t bin, Double_t e2);
109 
110  /// Forwards to THnBase::SetBinContent().
111  /// Non-virtual, CINT-compatible replacement of a using declaration.
112  void AddBinContent(const Int_t* idx, Double_t v = 1.) {
113  THnBase::AddBinContent(idx, v);
114  }
115  void AddBinContent(Long64_t bin, Double_t v = 1.);
116  void AddBinError2(Long64_t bin, Double_t e2);
117 
118  /// Forwards to THnBase::GetBinContent() overload.
119  /// Non-virtual, CINT-compatible replacement of a using declaration.
120  Double_t GetBinContent(const Int_t *idx) const {
121 
122  return THnBase::GetBinContent(idx);
123  }
124  Double_t GetBinContent(Long64_t bin, Int_t* idx = 0) const;
125  Double_t GetBinError2(Long64_t linidx) const;
126 
127  Double_t GetSparseFractionBins() const;
128  Double_t GetSparseFractionMem() const;
129 
130  /// Forwards to THnBase::Projection().
131  /// Non-virtual, as a CINT-compatible replacement of a using
132  /// declaration.
133  TH1D* Projection(Int_t xDim, Option_t* option = "") const{
134  return THnBase::Projection(xDim, option);
135  }
136 
137  /// Forwards to THnBase::Projection().
138  /// Non-virtual, as a CINT-compatible replacement of a using
139  /// declaration.
140  TH2D* Projection(Int_t yDim, Int_t xDim,
141  Option_t* option = "") const {
142  return THnBase::Projection(yDim, xDim, option);
143  }
144 
145  /// Forwards to THnBase::Projection().
146  /// Non-virtual, as a CINT-compatible replacement of a using
147  /// declaration.
148  TH3D* Projection(Int_t xDim, Int_t yDim, Int_t zDim,
149  Option_t* option = "") const {
150  return THnBase::Projection(xDim, yDim, zDim, option);
151  }
152 
153  THnSparse* Projection(Int_t ndim, const Int_t* dim,
154  Option_t* option = "") const {
155  return (THnSparse*) ProjectionND(ndim, dim, option);
156  }
157 
158  THnSparse* Rebin(Int_t group) const {
159  return (THnSparse*) RebinBase(group);
160  }
161  THnSparse* Rebin(const Int_t* group) const {
162  return (THnSparse*) RebinBase(group);
163  }
164 
165  void Reset(Option_t* option = "");
166  void Sumw2();
167 
168  ClassDef(THnSparse, 3); // Interfaces of sparse n-dimensional histogram
169 };
170 
171 
172 
173 //______________________________________________________________________________
174 /** \class THnSparseT
175  Templated implementation of the abstract base THnSparse.
176  All functionality and the interfaces to be used are in THnSparse!
177 
178  THnSparse does not know how to store any bin content itself. Instead, this
179  is delegated to the derived, templated class: the template parameter decides
180  what the format for the bin content is. In fact it even defines the array
181  itself; possible implementations probably derive from TArray.
182 
183  Typedefs exist for template parameters with ROOT's generic types:
184 
185  Templated name | Typedef | Bin content type
186  --------------------|--------------|--------------------
187  THnSparseT<TArrayC> | THnSparseC | Char_t
188  THnSparseT<TArrayS> | THnSparseS | Short_t
189  THnSparseT<TArrayI> | THnSparseI | Int_t
190  THnSparseT<TArrayL> | THnSparseL | Long_t
191  THnSparseT<TArrayF> | THnSparseF | Float_t
192  THnSparseT<TArrayD> | THnSparseD | Double_t
193 
194  We recommend to use THnSparseC wherever possible, and to map its value space
195  of 256 possible values to e.g. float values outside the class. This saves an
196  enormous amount of memory. Only if more than 256 values need to be
197  distinguished should e.g. THnSparseS or even THnSparseF be chosen.
198 
199  Implementation detail: the derived, templated class is kept extremely small
200  on purpose. That way the (templated thus inlined) uses of this class will
201  only create a small amount of machine code, in contrast to e.g. STL.
202 */
203 
204 
205 template <class CONT>
206 class THnSparseT: public THnSparse {
207  public:
208  THnSparseT() {}
209  THnSparseT(const char* name, const char* title, Int_t dim,
210  const Int_t* nbins, const Double_t* xmin = 0,
211  const Double_t* xmax = 0, Int_t chunksize = 1024 * 16):
212  THnSparse(name, title, dim, nbins, xmin, xmax, chunksize) {}
213 
214  TArray* GenerateArray() const { return new CONT(GetChunkSize()); }
215  private:
216  ClassDef(THnSparseT, 1); // Sparse n-dimensional histogram with templated content
217 };
218 
219 typedef THnSparseT<TArrayD> THnSparseD;
220 typedef THnSparseT<TArrayF> THnSparseF;
221 typedef THnSparseT<TArrayL> THnSparseL;
222 typedef THnSparseT<TArrayI> THnSparseI;
223 typedef THnSparseT<TArrayS> THnSparseS;
224 typedef THnSparseT<TArrayC> THnSparseC;
225 
226 
227 #endif // ROOT_THnSparse