laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
Lau2DHistDP.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2004 University of Warwick
4 
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17 
18 /*
19 Laura++ package authors:
20 John Back
21 Paul Harrison
22 Thomas Latham
23 */
24 
29 #include <iostream>
30 
31 #include "TAxis.h"
32 #include "TH2.h"
33 #include "TRandom.h"
34 #include "TSystem.h"
35 
36 #include "Lau2DHistDP.hh"
37 #include "LauDaughters.hh"
38 #include "LauKinematics.hh"
39 #include "LauRandom.hh"
40 
42 
43 
44 Lau2DHistDP::Lau2DHistDP(const TH2* hist, const LauDaughters* daughters,
45  Bool_t useInterpolation, Bool_t fluctuateBins,
46  Double_t avEff, Double_t avEffError, Bool_t useUpperHalfOnly, Bool_t squareDP) :
47  Lau2DAbsHistDP(daughters,useUpperHalfOnly,squareDP),
48  hist_(hist ? dynamic_cast<TH2*>(hist->Clone()) : 0),
49  errorHi_(0), errorLo_(0),
50  minX_(0.0), maxX_(0.0),
51  minY_(0.0), maxY_(0.0),
52  rangeX_(0.0), rangeY_(0.0),
53  binXWidth_(0.0), binYWidth_(0.0),
54  nBinsX_(0), nBinsY_(0),
55  useInterpolation_(useInterpolation)
56 {
57  if ( ! hist_ ) {
58  std::cerr << "ERROR in Lau2DHistDP constructor : the histogram pointer is null." << std::endl;
59  gSystem->Exit(EXIT_FAILURE);
60  }
61 
62  // Save various attributes of the histogram
63  // (axis ranges, number of bins, areas)
64  TAxis* xAxis = hist_->GetXaxis();
65  minX_ = static_cast<Double_t>(xAxis->GetXmin());
66  maxX_ = static_cast<Double_t>(xAxis->GetXmax());
67  rangeX_ = maxX_ - minX_;
68 
69  TAxis* yAxis = hist_->GetYaxis();
70  minY_ = static_cast<Double_t>(yAxis->GetXmin());
71  maxY_ = static_cast<Double_t>(yAxis->GetXmax());
72  rangeY_ = maxY_ - minY_;
73 
74  nBinsX_ = static_cast<Int_t>(hist_->GetNbinsX());
75  nBinsY_ = static_cast<Int_t>(hist_->GetNbinsY());
76 
77  binXWidth_ = static_cast<Double_t>(TMath::Abs(rangeX_)/(nBinsX_*1.0));
78  binYWidth_ = static_cast<Double_t>(TMath::Abs(rangeY_)/(nBinsY_*1.0));
79 
80  if (fluctuateBins) {
81  this->doBinFluctuation(hist_);
82  }
83  if (avEff > 0.0 && avEffError > 0.0) {
84  this->raiseOrLowerBins(hist_,avEff,avEffError);
85  }
86 }
87 
88 Lau2DHistDP::Lau2DHistDP(const TH2* hist, const TH2* errorHi, const TH2* errorLo, const LauDaughters* daughters,
89  Bool_t useInterpolation, Bool_t fluctuateBins,
90  Double_t avEff, Double_t avEffError, Bool_t useUpperHalfOnly, Bool_t squareDP) :
91  Lau2DAbsHistDP(daughters,useUpperHalfOnly,squareDP),
92  hist_(hist ? dynamic_cast<TH2*>(hist->Clone()) : 0),
93  errorHi_(errorHi ? dynamic_cast<TH2*>(errorHi->Clone()) : 0),
94  errorLo_(errorLo ? dynamic_cast<TH2*>(errorLo->Clone()) : 0),
95  minX_(0.0), maxX_(0.0),
96  minY_(0.0), maxY_(0.0),
97  rangeX_(0.0), rangeY_(0.0),
98  binXWidth_(0.0), binYWidth_(0.0),
99  nBinsX_(0), nBinsY_(0),
100  useInterpolation_(useInterpolation)
101 {
102  if ( ! hist_ ) {
103  std::cerr << "ERROR in Lau2DHistDP constructor : the histogram pointer is null." << std::endl;
104  gSystem->Exit(EXIT_FAILURE);
105  }
106  if ( ! errorHi_ ) {
107  std::cerr << "ERROR in Lau2DHistDP constructor : the upper error histogram pointer is null." << std::endl;
108  gSystem->Exit(EXIT_FAILURE);
109  }
110  if ( ! errorLo_ ) {
111  std::cerr << "ERROR in Lau2DHistDP constructor : the lower error histogram pointer is null." << std::endl;
112  gSystem->Exit(EXIT_FAILURE);
113  }
114 
115  // Save various attributes of the histogram
116  // (axis ranges, number of bins, areas)
117  TAxis* xAxis = hist_->GetXaxis();
118  minX_ = static_cast<Double_t>(xAxis->GetXmin());
119  maxX_ = static_cast<Double_t>(xAxis->GetXmax());
120  rangeX_ = maxX_ - minX_;
121 
122  TAxis* yAxis = hist_->GetYaxis();
123  minY_ = static_cast<Double_t>(yAxis->GetXmin());
124  maxY_ = static_cast<Double_t>(yAxis->GetXmax());
125  rangeY_ = maxY_ - minY_;
126 
127  nBinsX_ = static_cast<Int_t>(hist_->GetNbinsX());
128  nBinsY_ = static_cast<Int_t>(hist_->GetNbinsY());
129 
130  binXWidth_ = static_cast<Double_t>(TMath::Abs(rangeX_)/(nBinsX_*1.0));
131  binYWidth_ = static_cast<Double_t>(TMath::Abs(rangeY_)/(nBinsY_*1.0));
132 
133  if(static_cast<Int_t>(errorLo_->GetNbinsX()) != nBinsX_ ||
134  static_cast<Int_t>(errorLo_->GetNbinsY()) != nBinsY_) {
135  std::cerr << "ERROR in Lau2DHistDP constructor : the lower error histogram has a different number of bins to the main histogram." << std::endl;
136  gSystem->Exit(EXIT_FAILURE);
137  }
138 
139  if(static_cast<Int_t>(errorHi_->GetNbinsX()) != nBinsX_ ||
140  static_cast<Int_t>(errorHi_->GetNbinsY()) != nBinsY_) {
141  std::cerr << "ERROR in Lau2DHistDP constructor : the upper error histogram has a different number of bins to the main histogram." << std::endl;
142  gSystem->Exit(EXIT_FAILURE);
143  }
144 
145  xAxis = errorLo_->GetXaxis();
146  yAxis = errorLo_->GetYaxis();
147 
148  if(static_cast<Double_t>(xAxis->GetXmin()) != minX_ ||
149  static_cast<Double_t>(xAxis->GetXmax()) != maxX_) {
150  std::cerr << "ERROR in Lau2DHistDP constructor : the lower error histogram has a different x range to the main histogram." << std::endl;
151  gSystem->Exit(EXIT_FAILURE);
152  }
153 
154  if(static_cast<Double_t>(yAxis->GetXmin()) != minY_ ||
155  static_cast<Double_t>(yAxis->GetXmax()) != maxY_) {
156  std::cerr << "ERROR in Lau2DHistDP constructor : the lower error histogram has a different y range to the main histogram." << std::endl;
157  gSystem->Exit(EXIT_FAILURE);
158  }
159 
160  xAxis = errorHi_->GetXaxis();
161  yAxis = errorHi_->GetYaxis();
162 
163  if(static_cast<Double_t>(xAxis->GetXmin()) != minX_ ||
164  static_cast<Double_t>(xAxis->GetXmax()) != maxX_) {
165  std::cerr << "ERROR in Lau2DHistDP constructor : the upper error histogram has a different x range to the main histogram." << std::endl;
166  gSystem->Exit(EXIT_FAILURE);
167  }
168 
169  if(static_cast<Double_t>(yAxis->GetXmin()) != minY_ ||
170  static_cast<Double_t>(yAxis->GetXmax()) != maxY_) {
171  std::cerr << "ERROR in Lau2DHistDP constructor : the upper error histogram has a different y range to the main histogram." << std::endl;
172  gSystem->Exit(EXIT_FAILURE);
173  }
174 
175  if (fluctuateBins) {
177  }
178  if (avEff > 0.0 && avEffError > 0.0) {
179  this->raiseOrLowerBins(hist_,avEff,avEffError);
180  }
181 }
182 
184 {
185  delete hist_;
186  hist_ = 0;
187  if(errorHi_) {
188  delete errorHi_;
189  errorHi_=0;
190  }
191  if(errorLo_) {
192  delete errorLo_;
193  errorLo_=0;
194  }
195 }
196 
197 Double_t Lau2DHistDP::getBinHistValue(Int_t xBinNo, Int_t yBinNo) const
198 {
199  if (xBinNo < 0) {
200  xBinNo = 0;
201  } else if (xBinNo >= nBinsX_) {
202  return 0.0;
203  }
204 
205  if (yBinNo < 0) {
206  yBinNo = 0;
207  } else if (yBinNo >= nBinsY_) {
208  return 0.0;
209  }
210 
211  Double_t value = hist_->GetBinContent(xBinNo+1, yBinNo+1);
212  return value;
213 }
214 
215 Double_t Lau2DHistDP::interpolateXY(Double_t x, Double_t y) const
216 {
217  // This function returns the interpolated value of the histogram function
218  // for the given values of x and y by finding the adjacent bins and extrapolating
219  // using weights based on the inverse distance of the point from the adajcent
220  // bin centres.
221  // Here, x = m13^2, y = m23^2, or m', theta' for square DP co-ordinates
222 
223  // If we're only using one half then flip co-ordinates
224  // appropriately for conventional or square DP
225  this->getUpperHalf(x,y);
226 
227  // First ask whether the point is inside the kinematic region.
228  if (this->withinDPBoundaries(x,y) == kFALSE) {
229  std::cerr << "WARNING in Lau2DHistDP::interpolateXY : Given position is outside the DP boundary, returning 0.0." << std::endl;
230  return 0.0;
231  }
232 
233  // Find the 2D histogram bin for x and y
234  Int_t i = Int_t((x - minX_)*nBinsX_/rangeX_);
235  Int_t j = Int_t((y - minY_)*nBinsY_/rangeY_);
236 
237  if (i >= nBinsX_) {i = nBinsX_ - 1;}
238  if (j >= nBinsY_) {j = nBinsY_ - 1;}
239 
240  // Ask whether we want to do the interpolation, since this method is
241  // not reliable for low statistics histograms.
242  if (useInterpolation_ == kFALSE) {return this->getBinHistValue(i,j);}
243 
244  // Find the bin centres (actual co-ordinate positions, not histogram indices)
245  Double_t cbinx = Double_t(i+0.5)*rangeX_/nBinsX_ + minX_;
246  Double_t cbiny = Double_t(j+0.5)*rangeY_/nBinsY_ + minY_;
247 
248  // If bin centres are outside kinematic region, do not extrapolate
249  if (this->withinDPBoundaries(cbinx,cbiny) == kFALSE) {return this->getBinHistValue(i,j);}
250 
251  // Find the adjacent bins
252  Double_t deltax = x - cbinx;
253  Double_t deltay = y - cbiny;
254 
255  Int_t i_adj(0), j_adj(0);
256  if (deltax > 0.0) {
257  i_adj = i + 1;
258  } else {
259  i_adj = i - 1;
260  }
261  if (deltay > 0.0) {
262  j_adj = j + 1;
263  } else {
264  j_adj = j - 1;
265  }
266 
267  Bool_t isXBoundary(kFALSE), isYBoundary(kFALSE);
268 
269  Double_t value(0.0);
270 
271  if (i_adj >= nBinsX_ || i_adj < 0) {isYBoundary = kTRUE;}
272  if (j_adj >= nBinsY_ || j_adj < 0) {isXBoundary = kTRUE;}
273 
274  // In the corners, do no interpolation. Use entry in bin (i,j)
275  if (isXBoundary == kTRUE && isYBoundary == kTRUE) {
276 
277  value = this->getBinHistValue(i,j);
278 
279  } else if (isXBoundary == kTRUE && isYBoundary == kFALSE) {
280 
281  // Find the adjacent x bin centre
282  Double_t cbinx_adj = Double_t(i_adj+0.5)*rangeX_/nBinsX_ + minX_;
283 
284  if (this->withinDPBoundaries(cbinx_adj, y) == kFALSE) {
285 
286  // The adjacent bin is outside the DP range. Don't extrapolate.
287  value = this->getBinHistValue(i,j);
288 
289  } else {
290 
291  Double_t dx0 = TMath::Abs(x - cbinx);
292  Double_t dx1 = TMath::Abs(cbinx_adj - x);
293  Double_t inter_denom = dx0 + dx1;
294 
295  Double_t value1 = this->getBinHistValue(i,j);
296  Double_t value2 = this->getBinHistValue(i_adj,j);
297 
298  value = (value1*dx1 + value2*dx0)/inter_denom;
299 
300  }
301 
302  } else if (isYBoundary == kTRUE && isXBoundary == kFALSE) {
303 
304  // Find the adjacent y bin centre
305  Double_t cbiny_adj = Double_t(j_adj+0.5)*rangeY_/nBinsY_ + minY_;
306 
307  if (this->withinDPBoundaries(x, cbiny_adj) == kFALSE) {
308 
309  // The adjacent bin is outside the DP range. Don't extrapolate.
310  value = this->getBinHistValue(i,j);
311 
312  } else {
313 
314  Double_t dy0 = TMath::Abs(y - cbiny);
315  Double_t dy1 = TMath::Abs(cbiny_adj - y);
316  Double_t inter_denom = dy0 + dy1;
317 
318  Double_t value1 = this->getBinHistValue(i,j);
319  Double_t value2 = this->getBinHistValue(i,j_adj);
320 
321  value = (value1*dy1 + value2*dy0)/inter_denom;
322 
323  }
324 
325  } else {
326 
327  // 2D linear interpolation using inverse distance as weights.
328  // Find the adjacent x and y bin centres
329  Double_t cbinx_adj = Double_t(i_adj+0.5)*rangeX_/nBinsX_ + minX_;
330  Double_t cbiny_adj = Double_t(j_adj+0.5)*rangeY_/nBinsY_ + minY_;
331 
332  if (this->withinDPBoundaries(cbinx_adj, cbiny_adj) == kFALSE) {
333 
334  // The adjacent bin is outside the DP range. Don't extrapolate.
335  value = this->getBinHistValue(i,j);
336 
337  } else {
338 
339  Double_t dx0 = TMath::Abs(x - cbinx);
340  Double_t dx1 = TMath::Abs(cbinx_adj - x);
341  Double_t dy0 = TMath::Abs(y - cbiny);
342  Double_t dy1 = TMath::Abs(cbiny_adj - y);
343 
344  Double_t inter_denom = (dx0 + dx1)*(dy0 + dy1);
345 
346  Double_t value1 = this->getBinHistValue(i,j);
347  Double_t value2 = this->getBinHistValue(i_adj,j);
348  Double_t value3 = this->getBinHistValue(i,j_adj);
349  Double_t value4 = this->getBinHistValue(i_adj,j_adj);
350 
351  value = value1*dx1*dy1 + value2*dx0*dy1 + value3*dx1*dy0 + value4*dx0*dy0;
352  value /= inter_denom;
353  }
354 
355  }
356 
357  return value;
358 
359 }
360 
Double_t minY_
The histogram y-axis minimum.
Definition: Lau2DHistDP.hh:126
ClassImp(LauAbsCoeffSet)
void raiseOrLowerBins(TH2 *hist, const Double_t avEff, const Double_t avEffError)
Rescale the histogram bin contents based on the desired average efficiency and its uncertainty...
void doBinFluctuation(TH2 *hist)
Fluctuate the contents of each histogram bin independently, in accordance with their errors...
Class that defines the particular 3-body decay under study.
Definition: LauDaughters.hh:47
Int_t nBinsY_
The number of bins on the y-axis of the histogram.
Definition: Lau2DHistDP.hh:142
Double_t binYWidth_
The histogram y-axis bin width.
Definition: Lau2DHistDP.hh:137
File containing declaration of LauDaughters class.
Double_t getBinHistValue(Int_t xBinNo, Int_t yBinNo) const
Get the raw bin content from the histogram.
Definition: Lau2DHistDP.cc:197
File containing declaration of LauKinematics class.
Double_t minX_
The histogram x-axis minimum.
Definition: Lau2DHistDP.hh:122
Double_t binXWidth_
The histogram x-axis bin width.
Definition: Lau2DHistDP.hh:135
Abstract base class for defining a variation across a 2D DP based on a histogram. ...
Lau2DHistDP(const TH2 *hist, const LauDaughters *daughters, Bool_t useInterpolation=kTRUE, Bool_t fluctuateBins=kFALSE, Double_t avEff=-1.0, Double_t avEffError=-1.0, Bool_t useUpperHalfOnly=kFALSE, Bool_t squareDP=kFALSE)
Constructor.
Definition: Lau2DHistDP.cc:44
Bool_t withinDPBoundaries(Double_t x, Double_t y) const
Check whether the given co-ordinates are within the kinematic boundary.
File containing declaration of Lau2DHistDP class.
Double_t interpolateXY(Double_t x, Double_t y) const
Perform the interpolation.
Definition: Lau2DHistDP.cc:215
File containing LauRandom namespace.
Bool_t useInterpolation_
Control boolean for using the linear interpolation.
Definition: Lau2DHistDP.hh:145
Double_t maxX_
The histogram x-axis maximum.
Definition: Lau2DHistDP.hh:124
Double_t maxY_
The histogram y-axis maximum.
Definition: Lau2DHistDP.hh:128
Class for defining a 2D DP histogram.
Definition: Lau2DHistDP.hh:48
virtual ~Lau2DHistDP()
Destructor.
Definition: Lau2DHistDP.cc:183
TH2 * errorLo_
The histogram containing the lower errors.
Definition: Lau2DHistDP.hh:119
void getUpperHalf(Double_t &x, Double_t &y) const
If only using the upper half of the (symmetric) DP then transform into the correct half...
Double_t value() const
The value of the parameter.
Int_t nBinsX_
The number of bins on the x-axis of the histogram.
Definition: Lau2DHistDP.hh:140
TH2 * errorHi_
The histogram containing the upper errors.
Definition: Lau2DHistDP.hh:117
TH2 * hist_
The underlying histogram.
Definition: Lau2DHistDP.hh:115
Double_t rangeX_
The histogram x-axis range.
Definition: Lau2DHistDP.hh:130
Double_t rangeY_
The histogram y-axis range.
Definition: Lau2DHistDP.hh:132