Logo ROOT   6.10/09
Reference Guide
THn.cxx
Go to the documentation of this file.
1 // @(#)root/hist:$Id$
2 // Author: Axel Naumann (2011-12-13)
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 #include "THn.h"
13 
14 #include "TClass.h"
15 
16 namespace {
17  //______________________________________________________________________________
18  //
19  // Helper struct to hold one dimension's bin range for THnBinIter.
20  /////////////////////////////////////////////////////////////////////////////
21 
22  struct CounterRange_t {
23  Int_t i;
24  Int_t first;
25  Int_t last;
26  Int_t len;
27  Long64_t cellSize;
28  };
29 
30  //______________________________________________________________________________
31  //
32  // THnBinIter iterates over all bins of a THn, recursing over all dimensions.
33  /////////////////////////////////////////////////////////////////////////////
34 
35  class THnBinIter: public ROOT::Internal::THnBaseBinIter {
36  public:
37  THnBinIter(Int_t dim, const TObjArray* axes, const TNDArray* arr,
38  Bool_t respectAxisRange);
39  ~THnBinIter() { delete [] fCounter; }
40 
41  Long64_t Next(Int_t* coord = 0);
42  Int_t GetCoord(Int_t dim) const { return fCounter[dim].i; }
43  private:
44  THnBinIter(const THnBinIter&); // intentionally unimplemented
45  THnBinIter& operator=(const THnBinIter&); // intentionally unimplemented
46 
47  public:
48  Int_t fNdimensions;
49  Long64_t fIndex;
50  const TNDArray* fArray;
51  CounterRange_t* fCounter;
52  };
53 
54 
55  /////////////////////////////////////////////////////////////////////////////
56  /// Construct a THnBinIter.
57 
58  THnBinIter::THnBinIter(Int_t dim, const TObjArray* axes,
59  const TNDArray* arr, Bool_t respectAxisRange):
60  ROOT::Internal::THnBaseBinIter(respectAxisRange),
61  fNdimensions(dim), fIndex(-1), fArray(arr) {
62  fCounter = new CounterRange_t[dim]();
63  for (Int_t i = 0; i < dim; ++i) {
64  TAxis *axis = (TAxis*) axes->At(i);
65  fCounter[i].len = axis->GetNbins() + 2;
66  fCounter[i].cellSize = arr->GetCellSize(i);
67  if (!respectAxisRange || !axis->TestBit(TAxis::kAxisRange)) {
68  fCounter[i].first = 0;
69  fCounter[i].last = fCounter[i].len - 1;
70  fCounter[i].i = 0;
71  continue;
72  }
73  fHaveSkippedBin = kTRUE;
74  Int_t min = axis->GetFirst();
75  Int_t max = axis->GetLast();
76  if (min == 0 && max == 0) {
77  // special case where TAxis::SetBit(kAxisRange) and
78  // over- and underflow bins are de-selected.
79  // first and last are == 0 due to axis12->SetRange(1, axis12->GetNbins());
80  min = 1;
81  max = axis->GetNbins();
82  }
83  fCounter[i].first = min;
84  fCounter[i].last = max;
85  fCounter[i].i = min;
86  fIndex += fCounter[i].first * fCounter[i].cellSize;
87  }
88  // First Next() will increment it:
89  --fCounter[dim - 1].i;
90  }
91 
92  /////////////////////////////////////////////////////////////////////////////
93  /// Return the current linear bin index (in range), then go to the next bin.
94  /// If all bins have been visited, return -1.
95 
96  Long64_t THnBinIter::Next(Int_t* coord /*= 0*/) {
97  if (fNdimensions < 0) return -1; // end
98  ++fCounter[fNdimensions - 1].i;
99  ++fIndex;
100  // Wrap around if needed
101  for (Int_t d = fNdimensions - 1; d > 0 && fCounter[d].i > fCounter[d].last; --d) {
102  // We skip last + 1..size and 0..first - 1, adjust fIndex
103  Int_t skippedCells = fCounter[d].len - (fCounter[d].last + 1);
104  skippedCells += fCounter[d].first;
105  fIndex += skippedCells * fCounter[d].cellSize;
106  fCounter[d].i = fCounter[d].first;
107  ++fCounter[d - 1].i;
108  }
109  if (fCounter[0].i > fCounter[0].last) {
110  fNdimensions = -1;
111  return -1;
112  }
113  if (coord) {
114  for (Int_t d = 0; d < fNdimensions; ++d) {
115  coord[d] = fCounter[d].i;
116  }
117  }
118  return fIndex;
119  }
120 } // unnamed namespce
121 
122 
123 
124 /** \class THn
125  \ingroup Hist
126 Multidimensional histogram.
127 
128 Use a THn if you really, really have to store more than three dimensions,
129 and if a large fraction of all bins are filled.
130 Better alternatives are
131  - THnSparse if a fraction of all bins are filled
132  - TTree
133 
134 The major problem of THn is the memory use caused by n-dimensional
135 histogramming: a THnD with 8 dimensions and 100 bins per dimension needs
136 more than 2.5GB of RAM!
137 
138 To construct a THn object you must use one of its templated, derived
139 classes:
140 
141  THnD (typedef for THnT<Double_t>): bin content held by a Double_t,
142  THnF (typedef for THnT<Float_t>): bin content held by a Float_t,
143  THnL (typedef for THnT<Long_t>): bin content held by a Long_t,
144  THnI (typedef for THnT<Int_t>): bin content held by an Int_t,
145  THnS (typedef for THnT<Short_t>): bin content held by a Short_t,
146  THnC (typedef for THnT<Char_t>): bin content held by a Char_t,
147 
148 They take name and title, the number of dimensions, and for each dimension
149 the number of bins, the minimal, and the maximal value on the dimension's
150 axis. A TH2F h("h","h",10, 0., 10., 20, -5., 5.) would correspond to
151 
152  Int_t bins[2] = {10, 20};
153  Double_t xmin[2] = {0., -5.};
154  Double_t xmax[2] = {10., 5.};
155  THnF hn("hn", "hn", 2, bins, xmin, xmax);
156 
157 ## Filling
158 A THn is filled just like a regular histogram, using
159 THn::Fill(x, weight), where x is a n-dimensional Double_t value.
160 To take errors into account, Sumw2() must be called before filling the
161 histogram.
162 Storage is allocated when the first bin content is stored.
163 
164 ## Projections
165 The dimensionality of a THn can be reduced by projecting it to
166 1, 2, 3, or n dimensions, which can be represented by a TH1, TH2, TH3, or
167 a THn. See the Projection() members. To only project parts of the
168 histogram, call
169 
170  hn->GetAxis(12)->SetRange(from_bin, to_bin);
171 
172 ## Conversion from other histogram classes
173 The static factory function THn::CreateHn() can be used to create a THn
174 from a TH1, TH2, TH3, THnSparse and (for copying) even from a THn. The
175 created THn will have compatble storage type, i.e. calling CreateHn() on
176 a TH2F will create a THnF.
177 */
178 
179 ClassImp(THn);
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 /// Construct a THn.
183 
184 THn::THn(const char* name, const char* title,
185  Int_t dim, const Int_t* nbins,
186  const Double_t* xmin, const Double_t* xmax):
187  THnBase(name, title, dim, nbins, xmin, xmax),
188  fSumw2(dim, nbins, kTRUE /*overflow*/),
189  fCoordBuf() {
190 }
191 
192 ////////////////////////////////////////////////////////////////////////////////
193 /// Destruct a THn
194 
196 {
197  delete [] fCoordBuf;
198 }
199 
200 
201 ////////////////////////////////////////////////////////////////////////////////
202 /// Create an iterator over all bins. Public interface is THnIter.
203 
205 {
206  return new THnBinIter(GetNdimensions(), GetListOfAxes(), &GetArray(),
207  respectAxisRange);
208 }
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// Enable calculation of errors
212 
213 void THn::Sumw2() {
214  if (!GetCalculateErrors()) {
215  fTsumw2 = 0.;
216  }
217  // fill sumw2 array with current content
218  TNDArray & content = GetArray();
219  Long64_t nbins = GetNbins();
220  for (Long64_t ibin = 0; ibin < nbins; ++ibin)
221  fSumw2.At(ibin) = content.AtAsDouble(ibin);
222 }
223 
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Create the coordinate buffer. Outlined to hide allocation
227 /// from inlined functions.
228 
229 void THn::AllocCoordBuf() const
230 {
231  fCoordBuf = new Int_t[fNdimensions]();
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Initialize the storage of a histogram created via Init()
236 
237 void THn::InitStorage(Int_t* nbins, Int_t /*chunkSize*/)
238 {
239  fCoordBuf = new Int_t[fNdimensions]();
240  GetArray().Init(fNdimensions, nbins, true /*addOverflow*/);
241  fSumw2.Init(fNdimensions, nbins, true /*addOverflow*/);
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Reset the contents of a THn.
246 
247 void THn::Reset(Option_t* option /*= ""*/)
248 {
249  GetArray().Reset(option);
250  fSumw2.Reset(option);
251 }
An array of TObjects.
Definition: TObjArray.h:37
ROOT::Internal::THnBaseBinIter * CreateIter(Bool_t respectAxisRange) const
Create an iterator over all bins. Public interface is THnIter.
Definition: THn.cxx:204
float xmin
Definition: THbookFile.cxx:93
Bool_t GetCalculateErrors() const
Definition: THnBase.h:136
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
long long Long64_t
Definition: RtypesCore.h:69
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
Double_t fTsumw2
Definition: THnBase.h:50
const char Option_t
Definition: RtypesCore.h:62
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:159
virtual Double_t AtAsDouble(ULong64_t linidx) const =0
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
int nbins[3]
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:135
virtual void Reset(Option_t *option="")=0
Long64_t GetNbins() const
Definition: THn.h:60
void Sumw2()
Enable calculation of errors.
Definition: THn.cxx:213
TNDArrayT< Double_t > fSumw2
Definition: THn.h:188
THn()
Definition: THn.h:45
void InitStorage(Int_t *nbins, Int_t chunkSize)
Initialize the storage of a histogram created via Init()
Definition: THn.cxx:237
void AllocCoordBuf() const
Create the coordinate buffer.
Definition: THn.cxx:229
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Class to manage histogram axis.
Definition: TAxis.h:30
T At(const Int_t *idx) const
Definition: TNDArray.h:159
void Reset(Option_t *="")
Definition: TNDArray.h:142
Iterator over THnBase bins (internal implementation).
Definition: THnBase.h:286
Multidimensional histogram.
Definition: THn.h:36
float xmax
Definition: THbookFile.cxx:93
Int_t * fCoordBuf
Definition: THn.h:189
#define ClassImp(name)
Definition: Rtypes.h:336
double Double_t
Definition: RtypesCore.h:55
virtual void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:56
Int_t GetNdimensions() const
Definition: THnBase.h:135
Binding & operator=(OUT(*fun)(void))
virtual ~THn()
Destruct a THn.
Definition: THn.cxx:195
Int_t fNdimensions
Definition: THnBase.h:45
TObjArray * GetListOfAxes()
Definition: THnBase.h:123
Long64_t GetCellSize(Int_t dim) const
Definition: TNDArray.h:73
Multidimensional histogram base.
Definition: THnBase.h:43
Definition: first.py:1
Int_t GetNbins() const
Definition: TAxis.h:121
const Bool_t kTRUE
Definition: RtypesCore.h:91
void Reset(Option_t *option="")
Reset the contents of a THn.
Definition: THn.cxx:247
virtual const TNDArray & GetArray() const =0