laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauBkgndDPModel.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 <cstdlib>
30 #include <iostream>
31 
32 #include "TRandom.h"
33 #include "TSystem.h"
34 
35 #include "Lau2DHistDPPdf.hh"
36 #include "Lau2DSplineDPPdf.hh"
37 #include "LauBkgndDPModel.hh"
38 #include "LauDaughters.hh"
39 #include "LauFitDataTree.hh"
40 #include "LauKinematics.hh"
41 #include "LauRandom.hh"
42 #include "LauVetoes.hh"
43 
45 
46 
48  LauAbsBkgndDPModel(daughters, vetoes),
49  symmetricalDP_(kFALSE),
50  squareDP_(kFALSE),
51  bgHistDPPdf_(0),
52  curEvtHistVal_(0.0),
53  maxPdfHeight_(1.0),
54  pdfNorm_(1.0),
55  doneGenWarning_(kFALSE),
56  lowBinWarningIssued_(kFALSE)
57 {
58  if (daughters != 0) {
59  symmetricalDP_ = daughters->gotSymmetricalDP();
60  }
61 }
62 
64 {
65  if (bgHistDPPdf_ != 0) {
66  delete bgHistDPPdf_; bgHistDPPdf_ = 0;
67  }
68 }
69 
70 void LauBkgndDPModel::setBkgndHisto(const TH2* histo, Bool_t useInterpolation, Bool_t fluctuateBins, Bool_t useUpperHalfOnly, Bool_t squareDP)
71 {
72  if ( ! histo ) {
73  std::cerr << "WARNING in LauBkgndDPModel::setBkgndHisto : Supplied background histogram pointer is null, likelihood for this component will be flat in the Dalitz plot" << std::endl;
74  }
75 
76  Bool_t upperHalf = kFALSE;
77  if (symmetricalDP_ == kTRUE && useUpperHalfOnly == kTRUE) {upperHalf = kTRUE;}
78  std::cout<<"INFO in LauBkgndDPModel::setBkgndHisto : Background histogram has upperHalf = "<<static_cast<Int_t>(upperHalf)<<std::endl;
79 
80  squareDP_ = squareDP;
81 
82  LauKinematics* kinematics = this->getKinematics();
83  const LauVetoes* vetoes = this->getVetoes();
84  bgHistDPPdf_ = new Lau2DHistDPPdf(histo, kinematics, vetoes, useInterpolation, fluctuateBins, upperHalf, squareDP);
85 
88 }
89 
90 void LauBkgndDPModel::setBkgndSpline(const TH2* histo, Bool_t fluctuateBins, Bool_t useUpperHalfOnly, Bool_t squareDP)
91 {
92  if ( ! histo ) {
93  std::cerr << "WARNING in LauBkgndDPModel::setBkgndSpline : Supplied background histogram pointer is null, construction of spline will fail" << std::endl;
94  }
95 
96  Bool_t upperHalf = kFALSE;
97  if (symmetricalDP_ == kTRUE && useUpperHalfOnly == kTRUE) {upperHalf = kTRUE;}
98  std::cout<<"INFO in LauBkgndDPModel::setBkgndSpline : Background histogram has upperHalf = "<<static_cast<Int_t>(upperHalf)<<std::endl;
99 
100  squareDP_ = squareDP;
101 
102  LauKinematics* kinematics = this->getKinematics();
103  const LauVetoes* vetoes = this->getVetoes();
104  bgHistDPPdf_ = new Lau2DSplineDPPdf(histo, kinematics, vetoes, fluctuateBins, upperHalf, squareDP);
105 
108 }
109 
110 Double_t LauBkgndDPModel::calcHistValue(Double_t xVal, Double_t yVal)
111 {
112  // Get the likelihood value of the background in the Dalitz plot.
113 
114  // Check that we have a valid histogram PDF
115  if (bgHistDPPdf_ == 0) {
116  std::cerr << "WARNING in LauBkgndDPModel::calcHistValue : We don't have a histogram so assuming the likelihood is flat in the Dalitz plot." << std::endl;
117  this->setBkgndHisto( 0, kFALSE, kFALSE, kFALSE, kFALSE );
118  }
119 
120  // Find out the un-normalised PDF value
121  Double_t value = bgHistDPPdf_->interpolateXY(xVal, yVal);
122 
123  // Check that the value is greater than zero
124  // If we're using a spline then negative values can be caused by adjacent bins that all contain a value of zero.
125  // The spline requires the value, its first derivatives and the mixed second derivative to be continuous and to match the input histogram
126  // at the bin centres. Derivatives are calculated using a finite difference approximation taking the difference between the neighbouring bins.
127  // If two bins are zero but the third is not then the second bin will have a positive first derivative causing the spline to dip below zero
128  // between the two zero bins to remain smooth. Such dips are unavoidable but are correctly removed here.
129  if ( value < 0.0 ) {
130  if(!lowBinWarningIssued_) {
131  std::cerr << "WARNING in LauBkgndDPModel::calcHistValue : Value " << value << " is less than 0 - setting to 0. You may want to check your histogram!" << std::endl
132  << " : If you are using a spline then this could be caused by adjacent empty bins. Further warnings will be suppressed." << std::endl;
133  lowBinWarningIssued_=kTRUE;
134  }
135  return 0.0;
136  }
137 
138  LauKinematics* kinematics = this->getKinematics();
139 
140  // For square DP co-ordinates, need to divide by Jacobian
141  if (squareDP_ == kTRUE) {
142  // Make sure that square DP kinematics are correct, then get Jacobian
143  kinematics->updateSqDPKinematics(xVal, yVal);
144  Double_t jacobian = kinematics->calcSqDPJacobian();
145  value /= jacobian;
146  }
147 
148  return value;
149 }
150 
152 {
153 }
154 
156 {
157  // Routine to generate the background, using data provided by an
158  // already defined histogram.
159 
160  LauKinematics* kinematics = this->getKinematics();
161 
162  Bool_t gotBG(kFALSE);
163 
164  while (gotBG == kFALSE) {
165 
166  if (squareDP_ == kTRUE) {
167  // Generate a point in m', theta' space. By construction, this point
168  // is already within the DP region.
169  Double_t mPrime(0.0), thetaPrime(0.0);
170  kinematics->genFlatSqDP(mPrime, thetaPrime);
171 
172  // If we're in a symmetrical DP then we should only generate events in one half
173  if ( symmetricalDP_ && thetaPrime > 0.5 ) {
174  thetaPrime = 1.0 - thetaPrime;
175  }
176 
177  // Calculate histogram height for DP point and
178  // compare with the maximum height
179  if ( bgHistDPPdf_ != 0 ) {
180  Double_t bgContDP = bgHistDPPdf_->interpolateXY(mPrime, thetaPrime)/maxPdfHeight_;
181  if (LauRandom::randomFun()->Rndm() < bgContDP) {
182  kinematics->updateSqDPKinematics(mPrime, thetaPrime);
183  gotBG = kTRUE;
184  }
185  } else {
186  if ( !doneGenWarning_ ) {
187  std::cerr << "WARNING in LauBkgndDPModel::generate : We don't have a histogram so generating flat in the square DP, which won't be flat in the conventional DP!" << std::endl;
188  std::cerr << "WARNING in LauBkgndDPModel::generate : This should never happen!! What have you done?!" << std::endl;
189  doneGenWarning_ = kTRUE;
190  }
191  kinematics->updateSqDPKinematics(mPrime, thetaPrime);
192  gotBG = kTRUE;
193  }
194  } else {
195  // Generate a point in the Dalitz plot (phase-space).
196  Double_t m13Sq(0.0), m23Sq(0.0);
197  kinematics->genFlatPhaseSpace(m13Sq, m23Sq);
198 
199  // If we're in a symmetrical DP then we should only generate events in one half
200  if ( symmetricalDP_ && m13Sq > m23Sq ) {
201  Double_t tmpSq = m13Sq;
202  m13Sq = m23Sq;
203  m23Sq = tmpSq;
204  }
205 
206  // Calculate histogram height for DP point and
207  // compare with the maximum height
208  if ( bgHistDPPdf_ != 0 ) {
209  Double_t bgContDP = bgHistDPPdf_->interpolateXY(m13Sq, m23Sq)/maxPdfHeight_;
210  if (LauRandom::randomFun()->Rndm() < bgContDP) {
211  kinematics->updateKinematics(m13Sq, m23Sq);
212  gotBG = kTRUE;
213  }
214  } else {
215  if ( !doneGenWarning_ ) {
216  std::cerr << "WARNING in LauBkgndDPModel::generate : We don't have a histogram so generating flat in the DP." << std::endl;
217  doneGenWarning_ = kTRUE;
218  }
219  kinematics->updateKinematics(m13Sq, m23Sq);
220  gotBG = kTRUE;
221  }
222  }
223  }
224 
225  // Implement veto
226  Bool_t vetoOK(kTRUE);
227  const LauVetoes* vetoes = this->getVetoes();
228  if (vetoes) {
229  vetoOK = vetoes->passVeto(kinematics);
230  }
231  // Call this function recusively until we pass the veto.
232  if (vetoOK == kFALSE) {
233  this->generate();
234  }
235  return kTRUE;
236 }
237 
239 {
240  // In LauFitDataTree, the first two variables should always be
241  // m13^2 and m23^2. Other variables follow thus: charge.
242 
243  Int_t nBranches = inputFitTree.nBranches();
244  if (nBranches < 2) {
245  std::cerr<<"ERROR in LauBkgndDPModel::fillDataTree : Expecting at least 2 variables "<<"in input data tree, but there are "<<nBranches<<"!\n";
246  std::cerr<<" : Make sure you have the right number of variables in your input data file!"<<std::endl;
247  return;
248  }
249 
250  Double_t m13Sq(0.0), m23Sq(0.0), mPrime(0.0), thetaPrime(0.0);
251 
252  UInt_t nEvents = inputFitTree.nEvents();
253  LauKinematics* kinematics = this->getKinematics();
254 
255  // clear and resize the data vector
256  bgData_.clear();
257  bgData_.resize(nEvents);
258 
259  for (UInt_t iEvt = 0; iEvt < nEvents; iEvt++) {
260 
261  const LauFitData& dataValues = inputFitTree.getData(iEvt);
262  LauFitData::const_iterator iter = dataValues.find("m13Sq");
263  m13Sq = iter->second;
264  iter = dataValues.find("m23Sq");
265  m23Sq = iter->second;
266 
267  // Update the kinematics. This will also update m' and theta' if squareDP = true
268  kinematics->updateKinematics(m13Sq, m23Sq);
269 
270  if (squareDP_ == kTRUE) {
271  mPrime = kinematics->getmPrime();
272  thetaPrime = kinematics->getThetaPrime();
273  curEvtHistVal_ = this->calcHistValue(mPrime, thetaPrime);
274  } else {
275  curEvtHistVal_ = this->calcHistValue(m13Sq, m23Sq);
276  }
277 
278  bgData_[iEvt] = curEvtHistVal_;
279  }
280 }
281 
282 Double_t LauBkgndDPModel::getUnNormValue(UInt_t iEvt)
283 {
284  // Retrieve the likelihood for the given event
285  this->setDataEventNo(iEvt);
286  return curEvtHistVal_;
287 }
288 
289 Double_t LauBkgndDPModel::getLikelihood(UInt_t iEvt)
290 {
291  // Retrieve the likelihood for the given event
292  this->setDataEventNo(iEvt);
293  Double_t llhd = curEvtHistVal_ / this->getPdfNorm();
294  return llhd;
295 }
296 
298 {
299  // Retrieve the data for event iEvt
300  if (bgData_.size() > iEvt) {
301  curEvtHistVal_ = bgData_[iEvt];
302  } else {
303  std::cerr<<"ERROR in LauBkgndDPModel::setDataEventNo : Event index too large: "<<iEvt<<" >= "<<bgData_.size()<<"."<<std::endl;
304  }
305 }
306 
The abstract interface for a background Dalitz plot model.
Bool_t passVeto(const LauKinematics *kinematics) const
Check whether the specified Dalitz plot point passes the vetoes.
Definition: LauVetoes.cc:118
TRandom * randomFun()
Access the singleton random number generator with a particular seed.
Definition: LauRandom.cc:34
File containing declaration of LauFitDataTree class.
virtual void initialise()
Initialise the model.
Bool_t lowBinWarningIssued_
Flag to track whether a warning has been issued for bin values less than zero.
Double_t maxPdfHeight_
Maximum height of PDF.
Lau2DAbsDPPdf * bgHistDPPdf_
PDF of Dalitz plot background, from a 2D histogram.
ClassImp(LauAbsCoeffSet)
File containing declaration of LauBkgndDPModel class.
void setBkgndSpline(const TH2 *histo, Bool_t fluctuateBins, Bool_t useUpperHalfOnly, Bool_t squareDP)
Set the background histogram and generate a spline.
std::vector< Double_t > bgData_
Cached histogram values for each event.
Double_t getmPrime() const
Get m&#39; value.
Class that defines the particular 3-body decay under study.
Definition: LauDaughters.hh:47
virtual Double_t getHistNorm() const =0
Retrieve PDF normalisation.
File containing declaration of LauDaughters class.
virtual Bool_t generate()
Generate a toy MC event from the model.
Class for defining a 2D DP histogram PDF.
void updateSqDPKinematics(const Double_t mPrime, const Double_t thetaPrime)
Update all kinematic quantities based on the square DP co-ordinates m&#39; and theta&#39;.
const LauKinematics * getKinematics() const
Get the Dalitz plot kinematics.
std::map< TString, Double_t > LauFitData
Type for holding event data.
UInt_t nBranches() const
Obtain the number of branches in the tree.
Bool_t symmetricalDP_
Flags whether the DP is symmetrical or not.
File containing declaration of Lau2DHistDPPdf class.
virtual Double_t getMaxHeight() const =0
Retrieve maximum height.
Class for defining a 2D DP spline PDF.
File containing declaration of LauKinematics class.
File containing declaration of Lau2DSplineDPPdf class.
virtual Double_t interpolateXY(Double_t x, Double_t y) const =0
Perform the interpolation (unnormalised)
Bool_t doneGenWarning_
Boolean to indicate if the warning that there is no histogram has already been issued.
Double_t calcSqDPJacobian(const Double_t mPrime, const Double_t thPrime) const
Calculate the Jacobian for the transformation m23^2, m13^2 -&gt; m&#39;, theta&#39; (square DP) at the given poin...
void setBkgndHisto(const TH2 *histo, Bool_t useInterpolation, Bool_t fluctuateBins, Bool_t useUpperHalfOnly, Bool_t squareDP=kFALSE)
Set background histogram.
virtual Double_t getLikelihood(UInt_t iEvt)
Get likelihood for a given event.
void genFlatSqDP(Double_t &mPrime, Double_t &thetaPrime) const
Routine to generate events flat in the square Dalitz plot.
const LauVetoes * getVetoes() const
Get vetoes in the Dalitz plot.
Double_t calcHistValue(Double_t xVal, Double_t yVal)
Calulate histogram value at a given point.
Double_t curEvtHistVal_
Histogram value for the current event.
Bool_t squareDP_
Flags whether or not to work in square DP coordinates.
Class for defining a histogram-based background Dalitz plot model.
void updateKinematics(const Double_t m13Sq, const Double_t m23Sq)
Update all kinematic quantities based on the DP co-ordinates m13Sq and m23Sq.
const LauFitData & getData(UInt_t iEvt) const
Retrieve the data for a given event.
File containing LauRandom namespace.
virtual Double_t getUnNormValue(UInt_t iEvt)
Get unnormalised likelihood for a given event.
virtual ~LauBkgndDPModel()
Destructor.
Double_t getThetaPrime() const
Get theta&#39; value.
virtual void fillDataTree(const LauFitDataTree &fitDataTree)
Cache the input data and (if appropriate) the per-event likelihood values.
virtual void setDataEventNo(UInt_t iEvt)
Set data event number.
void genFlatPhaseSpace(Double_t &m13Sq, Double_t &m23Sq) const
Routine to generate events flat in phase-space.
Class for calculating 3-body kinematic quantities.
Double_t value() const
The value of the parameter.
Double_t pdfNorm_
Normalisation of PDF.
UInt_t nEvents() const
Retrieve the number of events.
File containing declaration of LauVetoes class.
Class for defining vetoes within the Dalitz plot.
Definition: LauVetoes.hh:50
Class to store the input fit variables.
virtual Double_t getPdfNorm() const
Get PDF normalisation constant.