laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
Lau1DHistPdf.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2006 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 "Lau1DHistPdf.hh"
30 
31 #include "LauRandom.hh"
32 
33 #include "TAxis.h"
34 #include "TH1.h"
35 #include "TRandom.h"
36 #include "TSystem.h"
37 
38 #include <cstdlib>
39 #include <iostream>
40 #include <vector>
41 
42 class LauParameter;
43 
44 Lau1DHistPdf::Lau1DHistPdf( const TString& theVarName,
45  const TH1* hist,
46  Double_t minAbscissa,
47  Double_t maxAbscissa,
48  Bool_t useInterpolation,
49  Bool_t fluctuateBins ) :
50  LauAbsPdf( theVarName, std::vector<LauAbsRValue*>(), minAbscissa, maxAbscissa ),
51  hist_( hist ? dynamic_cast<TH1*>( hist->Clone() ) : 0 ),
52  useInterpolation_( useInterpolation ),
53  fluctuateBins_( fluctuateBins ),
54  nBins_( 0 ),
55  axisMin_( 0.0 ),
56  axisMax_( 0.0 ),
57  axisRange_( 0.0 )
58 {
59  // Constructor
60 
61  // Set the directory for the histogram
62  hist_->SetDirectory( 0 );
63 
64  // Save various attributes of the histogram
65  nBins_ = hist_->GetNbinsX();
66  TAxis* xAxis = hist_->GetXaxis();
67  axisMin_ = xAxis->GetXmin();
68  axisMax_ = xAxis->GetXmax();
70 
71  // Check that axis range corresponds to range of abscissa
72  if ( TMath::Abs( this->getMinAbscissa() - axisMin_ ) > 1e-6 ) {
73  std::cerr << "ERROR in Lau1DHistPdf::Lau1DHistPdf : Histogram axis minimum: " << axisMin_
74  << " does not correspond to abscissa minimum: " << this->getMinAbscissa() << "."
75  << std::endl;
76  gSystem->Exit( EXIT_FAILURE );
77  }
78  if ( TMath::Abs( this->getMaxAbscissa() - axisMax_ ) > 1e-6 ) {
79  std::cerr << "ERROR in Lau1DHistPdf::Lau1DHistPdf : Histogram axis maximum: " << axisMax_
80  << " does not correspond to abscissa maximum: " << this->getMaxAbscissa() << "."
81  << std::endl;
82  gSystem->Exit( EXIT_FAILURE );
83  }
84 
85  // If the bins are to be fluctuated then do so now before
86  // calculating anything that depends on the bin content.
87  if ( fluctuateBins ) {
88  this->doBinFluctuation();
89  }
90 
91  // Calculate the PDF normalisation.
92  this->calcNorm();
93 
94  // And check it is OK.
95  this->checkNormalisation();
96 }
97 
99 {
100  // Destructor
101  delete hist_;
102  hist_ = 0;
103 }
104 
105 void Lau1DHistPdf::calcPDFHeight( const LauKinematics* /*kinematics*/ )
106 {
107  if ( this->heightUpToDate() ) {
108  return;
109  }
110 
111  // Get the maximum height of the histogram
112  Int_t maxBin = hist_->GetMaximumBin();
113  Double_t height = hist_->GetBinContent( maxBin );
114  this->setMaxHeight( height );
115 }
116 
118 {
119  // Calculate the histogram normalisation.
120 
121  // Loop over the range to get the total area.
122  // Just sum the contributions up using 1e-3 increments of the range.
123  // Multiply the end result by dx.
124 
125  Double_t dx( 1e-3 * axisRange_ );
126  Double_t area( 0.0 );
127 
128  Double_t x( axisMin_ + dx / 2.0 );
129  while ( x > axisMin_ && x < axisMax_ ) {
130  area += this->interpolate( x );
131  x += dx;
132  }
133 
134  Double_t norm = area * dx;
135  this->setNorm( norm );
136 }
137 
139 {
140  Double_t dx( 1e-3 * axisRange_ );
141  Double_t area( 0.0 );
142  Double_t areaNoNorm( 0.0 );
143 
144  const Bool_t useInterpolationOrig { useInterpolation_ };
145 
146  Double_t x( axisMin_ + dx / 2.0 );
147  while ( x > axisMin_ && x < axisMax_ ) {
148  area += this->interpolateNorm( x );
149  useInterpolation_ = kFALSE;
150  areaNoNorm += this->interpolate( x );
151  useInterpolation_ = useInterpolationOrig;
152  x += dx;
153  }
154  Double_t norm = area * dx;
155 
156  std::cout << "INFO in Lau1DHistPdf::checkNormalisation : Area = " << area << ", dx = " << dx
157  << std::endl;
158  std::cout << " : Area with no norm = " << areaNoNorm
159  << "*dx = " << areaNoNorm * dx << std::endl;
160  std::cout << " : The total area of the normalised histogram PDF is "
161  << norm << std::endl;
162 }
163 
164 Double_t Lau1DHistPdf::getBinHistValue( Int_t bin ) const
165 {
166  // Check that bin is in range [1 , nBins_]
167  if ( ( bin < 1 ) || ( bin > nBins_ ) ) {
168  return 0.0;
169  }
170  Double_t value = static_cast<Double_t>( hist_->GetBinContent( bin ) );
171  // protect against negative values
172  if ( value < 0.0 ) {
173  std::cerr << "WARNING in Lau1DHistPdf::getBinHistValue : Negative bin content set to zero!"
174  << std::endl;
175  value = 0.0;
176  }
177  return value;
178 }
179 
180 Double_t Lau1DHistPdf::interpolateNorm( Double_t x ) const
181 {
182  // Get the normalised interpolated value.
183  Double_t value = this->interpolate( x );
184  Double_t norm = this->getNorm();
185  return value / norm;
186 }
187 
189 {
190  // Check that the given abscissa is within the allowed range
191  if ( ! this->checkRange( abscissas ) ) {
192  gSystem->Exit( EXIT_FAILURE );
193  }
194 
195  // Get our abscissa
196  Double_t abscissa = abscissas[0];
197 
198  // Calculate the interpolated value
199  Double_t value = this->interpolate( abscissa );
200  this->setUnNormPDFVal( value );
201 }
202 
203 Double_t Lau1DHistPdf::interpolate( Double_t x ) const
204 {
205  // This function returns the interpolated value of the histogram function
206  // for the given value of x by finding the adjacent bins and extrapolating
207  // using weights based on the inverse distance of the point from the adajcent
208  // bin centres.
209 
210  // Find the histogram bin
211  Int_t bin = hist_->FindFixBin( x );
212 
213  // Ask whether we want to do the interpolation, since this method is
214  // not reliable for low statistics histograms.
215  if ( useInterpolation_ == kFALSE ) {
216  return this->getBinHistValue( bin );
217  }
218 
219  // Find the bin centres (actual co-ordinate positions, not histogram indices)
220  Double_t cbinx = hist_->GetBinCenter( bin );
221 
222  // Find the adjacent bins
223  Double_t deltax = x - cbinx;
224 
225  Int_t bin_adj( 0 );
226  if ( deltax > 0.0 ) {
227  bin_adj = bin + 1;
228  } else {
229  bin_adj = bin - 1;
230  }
231 
232  Bool_t isBoundary( kFALSE );
233  if ( bin_adj > nBins_ || bin_adj < 1 ) {
234  isBoundary = kTRUE;
235  }
236 
237  // At the edges, do no interpolation, use entry in bin.
238  if ( isBoundary == kTRUE ) {
239  return this->getBinHistValue( bin );
240  }
241 
242  // Linear interpolation using inverse distance as weights.
243  // Find the adjacent bin centre
244  Double_t cbinx_adj = hist_->GetBinCenter( bin_adj );
245  Double_t deltax_adj = cbinx_adj - x;
246 
247  Double_t dx0 = TMath::Abs( deltax );
248  Double_t dx1 = TMath::Abs( deltax_adj );
249 
250  Double_t denom = dx0 + dx1;
251 
252  Double_t value0 = this->getBinHistValue( bin );
253  Double_t value1 = this->getBinHistValue( bin_adj );
254 
255  Double_t value = value0 * dx1 + value1 * dx0;
256  value /= denom;
257 
258  return value;
259 }
260 
262 {
263  TRandom* random = LauRandom::randomFun();
264  for ( Int_t bin( 0 ); bin < nBins_; bin++ ) {
265  Double_t currentContent = hist_->GetBinContent( bin + 1 );
266  Double_t currentError = hist_->GetBinError( bin + 1 );
267  Double_t newContent = random->Gaus( currentContent, currentError );
268  if ( newContent < 0.0 ) {
269  hist_->SetBinContent( bin + 1, 0.0 );
270  } else {
271  hist_->SetBinContent( bin + 1, newContent );
272  }
273  }
274 }
File containing LauRandom namespace.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:49
virtual Double_t getMaxAbscissa() const
Retrieve the maximum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:141
Double_t value() const
The value of the parameter.
virtual Double_t getMinAbscissa() const
Retrieve the minimum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:135
Double_t interpolateNorm(Double_t x) const
Perform the interpolation and divide by the normalisation.
Double_t interpolate(Double_t x) const
Perform the interpolation (unnormalised)
void doBinFluctuation()
Fluctuate the histogram bin contents in accorance with their errors.
std::vector< Double_t > LauAbscissas
The type used for containing multiple abscissa values.
Definition: LauAbsPdf.hh:58
virtual void calcPDFHeight(const LauKinematics *kinematics)
Calculate the PDF height.
Double_t axisRange_
The histogram axis range.
Bool_t useInterpolation_
Control boolean for using the linear interpolation.
Double_t axisMin_
The histogram axis minimum.
virtual void setNorm(Double_t norm)
Set the normalisation factor.
Definition: LauAbsPdf.hh:348
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
virtual ~Lau1DHistPdf()
Destructor.
Definition: Lau1DHistPdf.cc:98
virtual void setUnNormPDFVal(Double_t unNormPDFVal)
Set the unnormalised likelihood.
Definition: LauAbsPdf.hh:394
Int_t nBins_
The number of bins in the histogram.
virtual void calcNorm()
Calculate the normalisation.
TRandom * randomFun()
Access the singleton random number generator with a particular seed.
Definition: LauRandom.cc:33
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:54
TH1 * hist_
The underlying histogram.
void checkNormalisation()
Check the normalisation calculation.
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:45
File containing declaration of Lau1DHistPdf class.
Double_t axisMax_
The histogram axis maximum.
virtual void setMaxHeight(Double_t maxHeight)
Set the maximum height.
Definition: LauAbsPdf.hh:354
virtual Double_t getNorm() const
Retrieve the normalisation factor.
Definition: LauAbsPdf.hh:224
Double_t getBinHistValue(Int_t bin) const
Get the bin content from the histogram.
Class for calculating 3-body kinematic quantities.
virtual Bool_t heightUpToDate() const
Check if the maximum height of the PDF is up to date.
Definition: LauAbsPdf.hh:287
Lau1DHistPdf(const TString &theVarName, const TH1 *hist, Double_t minAbscissa, Double_t maxAbscissa, Bool_t useInterpolation=kTRUE, Bool_t fluctuateBins=kFALSE)
Constructor.
Definition: Lau1DHistPdf.cc:44
virtual Bool_t checkRange(const LauAbscissas &abscissas) const
Check that all abscissas are within their allowed ranges.
Definition: LauAbsPdf.cc:243