Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TUnfoldBinning.h
Go to the documentation of this file.
1 // Author: Stefan Schmitt
2 // DESY, 10/08/11
3 
4 // Version 17.5, in parallel to changes in TUnfold
5 //
6 // History:
7 // Version 17.4, bug fix with error handling
8 // Version 17.3, bug fix with underflow/overflow bins
9 // Version 17.2, new option isPeriodic
10 // Version 17.1, in parallel to TUnfold
11 // Version 17.0, initial version, numbered in parallel to TUnfold
12 
13 #ifndef ROOT_TUnfoldBinning
14 #define ROOT_TUnfoldBinning
15 
16 
17 //////////////////////////////////////////////////////////////////////////
18 // //
19 // //
20 // TUnfoldBinning, an auxillary class to provide //
21 // complex binning schemes as input to TUnfoldDensity //
22 // //
23 // Citation: S.Schmitt, JINST 7 (2012) T10003 [arXiv:1205.6201] //
24 // //
25 //////////////////////////////////////////////////////////////////////////
26 
27 /*
28  This file is part of TUnfold.
29 
30  TUnfold is free software: you can redistribute it and/or modify
31  it under the terms of the GNU General Public License as published by
32  the Free Software Foundation, either version 3 of the License, or
33  (at your option) any later version.
34 
35  TUnfold is distributed in the hope that it will be useful,
36  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38  GNU General Public License for more details.
39 
40  You should have received a copy of the GNU General Public License
41  along with TUnfold. If not, see <http://www.gnu.org/licenses/>.
42 */
43 
44 #include "TUnfold.h"
45 #include <iostream>
46 #include <TNamed.h>
47 #include <TObjArray.h>
48 #include <TObjString.h>
49 #include <TAxis.h>
50 #include <TF1.h>
51 
52 
53 class TUnfoldBinning : public TNamed {
54  protected:
55  /// mother node
56  TUnfoldBinning *parentNode;
57  /// first daughter node
58  TUnfoldBinning *childNode;
59  /// next sister
60  TUnfoldBinning *nextNode;
61  /// previous sister
62  TUnfoldBinning *prevNode;
63  /// for each axis the bin borders (TVectorD)
64  TObjArray *fAxisList;
65  /// for each axis its name (TObjString), or names of unconnected bins
66  TObjArray *fAxisLabelList;
67  /// bit fields indicating whether there are underflow bins on the axes
68  Int_t fHasUnderflow;
69  /// bit fields indicating whether there are overflow bins on the axes
70  Int_t fHasOverflow;
71  /// number of bins in this node's distribution
72  Int_t fDistributionSize;
73  /// global bin number of the first bin
74  Int_t fFirstBin;
75  /// global bin number of the last(+1) bin, including daughters
76  Int_t fLastBin;
77  /// function to calculate a scale factor from bin centres (may be a TF1 or a TVectorD
78  TObject *fBinFactorFunction;
79  /// common scale factor for all bins of this node
80  Double_t fBinFactorConstant;
81  public:
82  /********************* setup **************************/
83  enum {
84  /// maximum numner of axes per distribution
85  MAXDIM=32
86  };
87  TUnfoldBinning(const char *name=0,Int_t nBins=0,const char *binNames=0); // create a new root node with a given number of unconnected bins
88  TUnfoldBinning(const TAxis &axis,Int_t includeUnderflow,Int_t includeOverflow); // create a binning scheme with one axis
89  TUnfoldBinning *AddBinning
90  (TUnfoldBinning *binning); // add a new node to the TUnfoldBinning tree
91  TUnfoldBinning *AddBinning(const char *name,Int_t nBins=0,const char *binNames=0); // add a new node to the TUnfoldBinning tree
92  Bool_t AddAxis(const char *name,Int_t nBins,const Double_t *binBorders,
93  Bool_t hasUnderflow,Bool_t hasOverflow); // add an axis (variable bins) to the distribution associated with this node
94  Bool_t AddAxis(const char *name,Int_t nBins,Double_t xMin,Double_t xMax,
95  Bool_t hasUnderflow,Bool_t hasOverflow); // add an axis (equidistant bins) to the distribution associated with this node
96  Bool_t AddAxis(const TAxis &axis,Bool_t includeUnderflow,Bool_t includeOverflow); // add an axis (from TAxis instance) to the distribution associated with this node
97  virtual ~TUnfoldBinning(void);
98  void PrintStream(std::ostream &out,Int_t indent=0,int debug=0) const;
99  void SetBinFactorFunction(Double_t normalisation,TF1 *userFunc=0); // define function to calculate bin factor. Note: the function is not owned by this class
100 
101  /********************* Navigation **********************/
102  /// first daughter node
103  inline TUnfoldBinning const *GetChildNode(void) const { return childNode; }
104  /// previous sister node
105  inline TUnfoldBinning const *GetPrevNode(void) const { return prevNode; }
106  /// next sister node
107  inline TUnfoldBinning const *GetNextNode(void) const { return nextNode; }
108  /// mother node
109  inline TUnfoldBinning const *GetParentNode(void) const { return parentNode; }
110  TUnfoldBinning const *FindNode(char const *name) const; // find node by name
111  /// return root node of the binnig scheme
112  TUnfoldBinning const *GetRootNode(void) const;
113 
114  /********************* Create THxx histograms **********/
115  Int_t GetTH1xNumberOfBins(Bool_t originalAxisBinning=kTRUE,const char *axisSteering=0) const; // get number of bins of a one-dimensional histogram TH1
116  TH1 *CreateHistogram(const char *histogramName,Bool_t originalAxisBinning=kFALSE,Int_t **binMap=0,const char *histogramTitle=0,const char *axisSteering=0) const; // create histogram and bin map for this node
117  TH2D *CreateErrorMatrixHistogram(const char *histogramName,Bool_t originalAxisBinning,Int_t **binMap=0,const char *histogramTitle=0,const char *axisSteering=0) const; // create histogram and bin map for this node
118  static TH2D *CreateHistogramOfMigrations(TUnfoldBinning const *xAxis,
119  TUnfoldBinning const *yAxis,
120  char const *histogramName,
121  Bool_t originalXAxisBinning=kFALSE,
122  Bool_t originalYAxisBinning=kFALSE,
123  char const *histogramTitle=0); // create 2D histogram with one binning on the x axis and the other binning on the y axis
124  TH1 *ExtractHistogram(const char *histogramName,const TH1 *globalBins,const TH2 *globalBinsEmatrix=0,Bool_t originalAxisBinning=kTRUE,const char *axisSteering=0) const; // extract a distribution from the given set of global bins
125  /********************* Create and manipulate bin map ****/
126  Int_t *CreateEmptyBinMap(void) const; // create empty bin map
127  void SetBinMapEntry(Int_t *binMap,Int_t globalBin,Int_t destBin) const; // change mapping for a given global bin
128  Int_t FillBinMap1D(Int_t *binMap,const char *axisSteering,
129  Int_t firstBinX) const; // map bins from this distribution to destHist
130  /********************* Calculate global bin number ******/
131  Int_t GetGlobalBinNumber(Double_t x) const; // get bin number 1-dim distribution
132  Int_t GetGlobalBinNumber(Double_t x,Double_t y) const; // get bin number 2-dim distribution
133  Int_t GetGlobalBinNumber(Double_t x,Double_t y,Double_t z) const; // get bin number 3-dim distribution
134  Int_t GetGlobalBinNumber(Double_t x0,Double_t x1,Double_t x2,Double_t x3) const; // get bin number four-dimensional binning
135  Int_t GetGlobalBinNumber(Double_t x0,Double_t x1,Double_t x2,Double_t x3,Double_t x4) const; // get bin number five-dimensional binning
136  Int_t GetGlobalBinNumber(Double_t x0,Double_t x1,Double_t x2,Double_t x3,Double_t x4,Double_t x5) const; // get bin number six-dimensional binning
137  Int_t GetGlobalBinNumber(const Double_t *x,Int_t *isBelow=0,Int_t *isAbove=0) const; // get bin number, up to 32 dimensional binning
138  /// first bin of this node
139  inline Int_t GetStartBin(void) const { return fFirstBin; }
140  /// last+1 bin of this node (includes children)
141  inline Int_t GetEndBin(void) const { return fLastBin; }
142  virtual Bool_t IsBinFactorGlobal(void) const; // check whether global or local bin factor must be used
143  Double_t GetGlobalFactor(void) const; // return global factor
144 
145  /********************* access by global bin number ******/
146  TString GetBinName(Int_t iBin) const; // return bin name
147  Double_t GetBinSize(Int_t iBin) const; // return bin size (in N dimensions)
148  virtual Double_t GetBinFactor(Int_t iBin) const; // return user factor
149  void GetBinUnderflowOverflowStatus(Int_t iBin,Int_t *uStatus,Int_t *oStatus) const; // return bit map indicating underflow and overflow status
150  Int_t GetBinNeighbours(Int_t globalBin,Int_t axis,
151  Int_t *prev,Double_t *distPrev,
152  Int_t *next,Double_t *distNext,
153  Bool_t isPeriodic=kFALSE) const; // get neighbour bins along an axis
154  /********************** access distribution properties *************/
155  /// number of bins in the distribution possibly including under/overflow
156  inline Int_t GetDistributionNumberOfBins(void) const { return fDistributionSize; }
157  /// query dimension of this node's distribution
158  inline Int_t GetDistributionDimension(void) const { return fAxisList->GetEntriesFast(); }
159  virtual Double_t GetDistributionAverageBinSize(Int_t axis,Bool_t includeUnderflow, Bool_t includeOverflow) const; // get average bin size
160  /// get vector of bin borders for one axis
161  inline TVectorD const *GetDistributionBinning(Int_t axis) const {
162  return (TVectorD const *)fAxisList->At(axis); }
163  /// get name of an axis
164  inline TString GetDistributionAxisLabel(Int_t axis) const {
165  return ((TObjString const *)fAxisLabelList->At(axis))->GetString(); }
166 
167  virtual Double_t GetDistributionUnderflowBinWidth(Int_t axis) const; // width of underflow bin on the given axis
168  virtual Double_t GetDistributionOverflowBinWidth(Int_t axis) const; // width of overflow bin on the given axis
169  virtual Double_t GetDistributionBinCenter(Int_t axis,Int_t bin) const; // position of bin center on the given axis
170  Bool_t HasUnconnectedBins(void) const; // check whether this node has bins without axis
171  const TObjString *GetUnconnectedBinName(Int_t bin) const; // return bin name (if any)
172  /// check whether an axis has an underflow bin
173  Bool_t HasUnderflow(int axis) const { return fHasUnderflow & (1<<axis); }
174  /// check whether the axis has an overflow bin
175  Bool_t HasOverflow(int axis) const { return fHasOverflow & (1<<axis); }
176  void DecodeAxisSteering(const char *axisSteering,const char *options,
177  Int_t *isOptionGiven) const; // decode axis steering options
178  protected:
179  /// return root node
180  TUnfoldBinning *GetRootNode(void);
181  void Initialize(Int_t nBins);
182  Int_t UpdateFirstLastBin(Bool_t startWithRootNode=kTRUE); // update fFirstBin and fLastBin
183  TUnfoldBinning const *ToAxisBins(Int_t globalBin,Int_t *axisBins) const; // return distribution in which the bin is located
184  Int_t ToGlobalBin(Int_t const *axisBins,Int_t *isBelow=0,Int_t *isAbove=0) const; // return -1 if not inside distribution
185  TString BuildHistogramTitle(const char *histogramName,const char *histogramTitle,
186  Int_t const *axisList) const; // construct histogram title
187  TString BuildHistogramTitle2D(const char *histogramName,const char *histogramTitle,
188  Int_t xAxis,const TUnfoldBinning *yAxisBinning,Int_t yAxis) const; // construct histogram title
189  Int_t GetTHxxBinning(Int_t maxDim,Int_t *axisBins,Int_t *axisList,const char *axisSteering) const; // get binning information for creating a THxx
190  Int_t GetTHxxBinningSingleNode(Int_t maxDim,Int_t *axisBins,Int_t *axisList,const char *axisSteering) const; // get binning information for creating a THxx
191  Int_t GetTHxxBinsRecursive(const char *axisSteering) const; // get binning information for creating a THxx
192  const TUnfoldBinning *GetNonemptyNode(void) const; // get the only nodes with non-empty distributions if there are multiple nodes, return 0
193  Int_t *CreateBinMap(const TH1 *hist,Int_t nDim,const Int_t *axisList,const char *axisSteering) const; // create mapping from global bins to a histogram
194  Int_t FillBinMapRecursive(Int_t startBin,const char *axisSteering,
195  Int_t *binMap) const; // fill bin map recursively
196  Int_t FillBinMapSingleNode(const TH1 *hist,Int_t startBin,Int_t nDim,const Int_t *axisList,const char *axisSteering,Int_t *binMap) const; // fill bin map for a single node
197  void SetBinFactor(Double_t normalisation,TObject *factors); // define function to calculate bin factor. Note: the object is owned by this class, unless it is a function
198 
199  ClassDef(TUnfoldBinning, TUnfold_CLASS_VERSION) //Complex binning schemes for TUnfoldDensity
200 };
201 
202 #endif