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