Logo ROOT   6.16/01
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
16namespace {
17 //______________________________________________________________________________
18 //
19 // Helper struct to hold one dimension's bin range for THnBinIter.
20 /////////////////////////////////////////////////////////////////////////////
21
22 struct CounterRange_t {
23 Int_t i;
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
126Multidimensional histogram.
127
128Use a THn if you really, really have to store more than three dimensions,
129and if a large fraction of all bins are filled.
130Better alternatives are
131 - THnSparse if a fraction of all bins are filled
132 - TTree
133
134The major problem of THn is the memory use caused by n-dimensional
135histogramming: a THnD with 8 dimensions and 100 bins per dimension needs
136more than 2.5GB of RAM!
137
138To construct a THn object you must use one of its templated, derived
139classes:
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
148They take name and title, the number of dimensions, and for each dimension
149the number of bins, the minimal, and the maximal value on the dimension's
150axis. 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
158A THn is filled just like a regular histogram, using
159THn::Fill(x, weight), where x is a n-dimensional Double_t value.
160To take errors into account, Sumw2() must be called before filling the
161histogram.
162Storage is allocated when the first bin content is stored.
163
164## Projections
165The dimensionality of a THn can be reduced by projecting it to
1661, 2, 3, or n dimensions, which can be represented by a TH1, TH2, TH3, or
167a THn. See the Projection() members. To only project parts of the
168histogram, call
169
170 hn->GetAxis(12)->SetRange(from_bin, to_bin);
171
172## Conversion from other histogram classes
173The static factory function THn::CreateHn() can be used to create a THn
174from a TH1, TH2, TH3, THnSparse and (for copying) even from a THn. The
175created THn will have compatble storage type, i.e. calling CreateHn() on
176a TH2F will create a THnF.
177*/
178
180
181////////////////////////////////////////////////////////////////////////////////
182/// Construct a THn.
183
184THn::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
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
230{
232}
233
234////////////////////////////////////////////////////////////////////////////////
235/// Initialize the storage of a histogram created via Init()
236
237void THn::InitStorage(Int_t* nbins, Int_t /*chunkSize*/)
238{
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
247void THn::Reset(Option_t* option /*= ""*/)
248{
249 GetArray().Reset(option);
250 fSumw2.Reset(option);
251}
#define d(i)
Definition: RSha256.hxx:102
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
float xmin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
Binding & operator=(OUT(*fun)(void))
Iterator over THnBase bins (internal implementation).
Definition: THnBase.h:285
virtual Int_t GetCoord(Int_t dim) const =0
virtual Long64_t Next(Int_t *coord=0)=0
Class to manage histogram axis.
Definition: TAxis.h:30
@ kAxisRange
Definition: TAxis.h:61
Int_t GetLast() const
Return last bin on the axis i.e.
Definition: TAxis.cxx:455
Int_t GetNbins() const
Definition: TAxis.h:121
Int_t GetFirst() const
Return first bin on the axis i.e.
Definition: TAxis.cxx:444
Multidimensional histogram base.
Definition: THnBase.h:43
TObjArray * GetListOfAxes()
Definition: THnBase.h:123
Int_t GetNdimensions() const
Definition: THnBase.h:135
Bool_t GetCalculateErrors() const
Definition: THnBase.h:136
Double_t fTsumw2
Definition: THnBase.h:50
Int_t fNdimensions
Definition: THnBase.h:45
Multidimensional histogram.
Definition: THn.h:36
THn()
Definition: THn.h:45
void AllocCoordBuf() const
Create the coordinate buffer.
Definition: THn.cxx:229
void InitStorage(Int_t *nbins, Int_t chunkSize)
Initialize the storage of a histogram created via Init()
Definition: THn.cxx:237
Int_t * fCoordBuf
Definition: THn.h:189
virtual ~THn()
Destruct a THn.
Definition: THn.cxx:195
TNDArrayT< Double_t > fSumw2
Definition: THn.h:188
void Reset(Option_t *option="")
Reset the contents of a THn.
Definition: THn.cxx:247
Long64_t GetNbins() const
Definition: THn.h:60
void Sumw2()
Enable calculation of errors.
Definition: THn.cxx:213
virtual const TNDArray & GetArray() const =0
ROOT::Internal::THnBaseBinIter * CreateIter(Bool_t respectAxisRange) const
Create an iterator over all bins. Public interface is THnIter.
Definition: THn.cxx:204
virtual Double_t AtAsDouble(ULong64_t linidx) const =0
Long64_t GetCellSize(Int_t dim) const
Definition: TNDArray.h:73
virtual void Init(Int_t ndim, const Int_t *nbins, bool addOverflow=false)
Definition: TNDArray.h:56
virtual void Reset(Option_t *option="")=0
An array of TObjects.
Definition: TObjArray.h:37
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
Definition: first.py:1