laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauDPDepMapPdf.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2013 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 #include <vector>
31 using std::cout;
32 using std::cerr;
33 using std::endl;
34 
35 #include "TH1.h"
36 #include "TMath.h"
37 #include "TSystem.h"
38 
39 #include "LauConstants.hh"
40 #include "LauDaughters.hh"
41 #include "Lau2DHistDP.hh"
42 #include "LauParameter.hh"
43 #include "LauDPDepMapPdf.hh"
44 
46 
47 
48 LauDPDepMapPdf::LauDPDepMapPdf(const std::vector<LauAbsPdf*>& pdfs,
49  const LauDaughters* daughters,
50  const TH2* dpHisto, Bool_t upperHalf) :
51  LauAbsPdf((!pdfs.empty() && pdfs[0]) ? pdfs[0]->varNames() : std::vector<TString>(), std::vector<LauAbsRValue*>(), (!pdfs.empty() && pdfs[0]) ? pdfs[0]->getMinAbscissas() : LauFitData(), (!pdfs.empty() && pdfs[0]) ? pdfs[0]->getMaxAbscissas() : LauFitData()),
52  daughters_( new LauDaughters(*daughters) ),
53  pdfs_(pdfs),
54  dpDependence_( new Lau2DHistDP(dpHisto, daughters, kFALSE, kFALSE, 0, 0, upperHalf, daughters->squareDP()) ),
55  dpAxisDependence_(0),
56  dpAxis_( CentreDist ),
57  indices_(0)
58 {
59  // Constructor for the PDF map.
60  // The index into the PDF collection is read from the DP histogram.
61 
62 
63  // So the first thing we have to do is check the pointers are all valid.
64  for ( std::vector<LauAbsPdf*>::const_iterator iter = pdfs_.begin(); iter != pdfs_.end(); ++iter){
65 
66  if (!(*iter)) {
67  cerr<<"ERROR in LauDPDepMapPdf constructor: one of the PDF pointers is null."<<endl;
68  gSystem->Exit(EXIT_FAILURE);
69  }
70 
71  // Next check that the abscissa ranges are the same for each PDF
72  if (pdfs_[0]->getMinAbscissa() != (*iter)->getMinAbscissa()) {
73  cerr<<"ERROR in LauDPDepMapPdf constructor: minimum abscissa values not the same for two PDFs."<<endl;
74  gSystem->Exit(EXIT_FAILURE);
75  }
76  if (pdfs_[0]->getMaxAbscissa() != (*iter)->getMaxAbscissa()) {
77  cerr<<"ERROR in LauDPDepMapPdf constructor: maximum abscissa values not the same for two PDFs."<<endl;
78  gSystem->Exit(EXIT_FAILURE);
79  }
80 
81  // Also check that both PDFs are expecting the same number of input variables
82  if (pdfs_[0]->nInputVars() != (*iter)->nInputVars()) {
83  cerr<<"ERROR in LauDPDepMapPdf constructor: number of input variables not the same for two PDFs."<<endl;
84  gSystem->Exit(EXIT_FAILURE);
85  }
86 
87  // Also check that both PDFs are expecting the same variable name(s)
88  if (pdfs_[0]->varNames() != (*iter)->varNames()) {
89  cerr<<"ERROR in LauDPDepMapPdf constructor: variable name(s) not the same for two PDFs."<<endl;
90  gSystem->Exit(EXIT_FAILURE);
91  }
92  }
93 
94  // Then we need to grab all the parameters and pass them to the base class.
95  // This is so that when we are asked for them they can be put into the fit.
96 
97 
98  for ( std::vector<LauAbsPdf*>::const_iterator iter = pdfs_.begin(); iter != pdfs_.end(); ++iter){
99  std::vector<LauAbsRValue*>& pdfpars = (*iter)->getParameters();
100  this->addParameters(pdfpars);
101 
102  }
103 
104  // Cache the normalisation factor
105  this->calcNorm();
106 }
107 
108 LauDPDepMapPdf::LauDPDepMapPdf(const std::vector<LauAbsPdf*>& pdfs,
109  const LauDaughters* daughters,
110  const TH1* dpAxisHisto,
111  DPAxis dpAxis) :
112  LauAbsPdf((!pdfs.empty() && pdfs[0]) ? pdfs[0]->varNames() : std::vector<TString>(), std::vector<LauAbsRValue*>(), (!pdfs.empty() && pdfs[0]) ? pdfs[0]->getMinAbscissas() : LauFitData(), (!pdfs.empty() && pdfs[0]) ? pdfs[0]->getMaxAbscissas() : LauFitData()),
113  daughters_( new LauDaughters(*daughters) ),
114  pdfs_(pdfs),
115  dpDependence_( 0 ),
116  dpAxisDependence_(dpAxisHisto ? dynamic_cast<TH1*>(dpAxisHisto->Clone()) : 0),
117  dpAxis_( dpAxis ),
118  indices_( 0 )
119 {
120  // Constructor for the PDFs map.
121  // The index into the PDF collection is read from one of
122  // the DP axes.
123 
124  if ( dpAxisDependence_ ) {
125  dpAxisDependence_->SetDirectory(0);
126  }
127 
128  // So the first thing we have to do is check the pointers are all valid.
129  for ( std::vector<LauAbsPdf*>::const_iterator iter = pdfs_.begin(); iter != pdfs_.end(); ++iter){
130 
131  if (!(*iter)) {
132  cerr<<"ERROR in LauDPDepMapPdf constructor: one of the PDF pointers is null."<<endl;
133  gSystem->Exit(EXIT_FAILURE);
134  }
135 
136  // Next check that the abscissa ranges are the same for each PDF
137  if (pdfs_[0]->getMinAbscissa() != (*iter)->getMinAbscissa()) {
138  cerr<<"ERROR in LauDPDepMapPdf constructor: minimum abscissa values not the same for two PDFs."<<endl;
139  gSystem->Exit(EXIT_FAILURE);
140  }
141  if (pdfs_[0]->getMaxAbscissa() != (*iter)->getMaxAbscissa()) {
142  cerr<<"ERROR in LauDPDepMapPdf constructor: maximum abscissa values not the same for two PDFs."<<endl;
143  gSystem->Exit(EXIT_FAILURE);
144  }
145 
146  // Also check that both PDFs are expecting the same number of input variables
147  if (pdfs_[0]->nInputVars() != (*iter)->nInputVars()) {
148  cerr<<"ERROR in LauDPDepMapPdf constructor: number of input variables not the same for two PDFs."<<endl;
149  gSystem->Exit(EXIT_FAILURE);
150  }
151 
152  // Also check that both PDFs are expecting the same variable name(s)
153  if (pdfs_[0]->varNames() != (*iter)->varNames()) {
154  cerr<<"ERROR in LauDPDepMapPdf constructor: variable name(s) not the same for two PDFs."<<endl;
155  gSystem->Exit(EXIT_FAILURE);
156  }
157  }
158 
159 
160  // Then we need to grab all the parameters and pass them to the base class.
161  // This is so that when we are asked for them they can be put into the fit.
162 
163  for ( std::vector<LauAbsPdf*>::const_iterator iter = pdfs_.begin(); iter != pdfs_.end(); ++iter){
164  std::vector<LauAbsRValue*>& pdfpars = (*iter)->getParameters();
165  this->addParameters(pdfpars);
166 
167  }
168 
169  // Cache the normalisation factor
170  this->calcNorm();
171 }
172 
174 {
175  // Destructor
176  delete daughters_; daughters_ = 0;
177  delete dpDependence_; dpDependence_ = 0;
179 }
180 
181 UInt_t LauDPDepMapPdf::determineDPRegion( Double_t m13Sq, Double_t m23Sq ) const
182 {
183  UInt_t regionIndex(0);
184 
185  LauKinematics* kinematics = daughters_->getKinematics();
186  kinematics->updateKinematics( m13Sq, m23Sq );
187 
188  if ( dpDependence_ ) {
189  if (daughters_->squareDP()){
190  Double_t mprime = kinematics->getmPrime();
191  Double_t thprime = kinematics->getThetaPrime();
192  regionIndex = static_cast<UInt_t>( dpDependence_->interpolateXY( mprime, thprime ) );
193  } else {
194  regionIndex = static_cast<UInt_t>( dpDependence_->interpolateXY( m13Sq, m23Sq ) );
195  }
196  } else if ( dpAxisDependence_ ) {
197  Double_t dpPos(0.0);
198  if ( dpAxis_ == M12 ) {
199  dpPos = kinematics->calcThirdMassSq(m13Sq,m23Sq);
200  } else if ( dpAxis_ == M13 ) {
201  dpPos = m13Sq;
202  } else if ( dpAxis_ == M23 ) {
203  dpPos = m23Sq;
204  } else if ( dpAxis_ == MMIN ) {
205  dpPos = TMath::Min( m13Sq, m23Sq );
206  } else if ( dpAxis_ == MMAX ) {
207  dpPos = TMath::Max( m13Sq, m23Sq );
208  } else {
209  dpPos = kinematics->distanceFromDPCentre(m13Sq,m23Sq);
210  }
211  Int_t bin = dpAxisDependence_->FindFixBin( dpPos );
212  regionIndex = static_cast<UInt_t>( dpAxisDependence_->GetBinContent( bin ) );
213  } else {
214  // This should never happen
215  cerr << "ERROR in LauDPDepMapPdf::determineDPRegion : No means of determining the region!" << endl;
216  gSystem->Exit(EXIT_FAILURE);
217  }
218 
219  return regionIndex;
220 }
221 
223 {
224  // Check that the given abscissa is within the allowed range
225  if (!this->checkRange(abscissas)) {
226  gSystem->Exit(EXIT_FAILURE);
227  }
228 
229  // Create a set of absissas that doesn't contain the DP variables
230  UInt_t nVars = this->nInputVars();
231  LauAbscissas noDPVars( nVars );
232  for ( UInt_t i(0); i < nVars; ++i ) {
233  noDPVars[i] = abscissas[i];
234  }
235 
236  // Find which region of the DP we're in
237  // The DP variables will be abscissas[nInputVars] and
238  // abscissas[nInputVars+1] (if present).
239  UInt_t regionIndex(0);
240  if ( abscissas.size() == nVars+2 ) {
241  Double_t m13Sq = abscissas[nVars];
242  Double_t m23Sq = abscissas[nVars+1];
243  regionIndex = this->determineDPRegion( m13Sq, m23Sq );
244  } else {
245  // This should never happen
246  cerr << "ERROR in LauDPDepMapPdf::calcLikelihoodInfo : DP vars not supplied, no means of determining the region!" << endl;
247  gSystem->Exit(EXIT_FAILURE);
248  }
249 
250  // Check that the region index is valid
251  if ( regionIndex >= pdfs_.size() ) {
252  cerr << "ERROR in LauDPDepMapPdf::calcLikelihoodInfo : No PDF supplied for region " << regionIndex << endl;
253  gSystem->Exit(EXIT_FAILURE);
254  }
255 
256  // Evaluate the normalised PDF values
257  LauAbsPdf* pdf = pdfs_[regionIndex];
258 
259  if ( pdf->isDPDependent() ) {
260  pdf->calcLikelihoodInfo(abscissas);
261  } else {
262  pdf->calcLikelihoodInfo(noDPVars);
263  }
264 
265  Double_t result = pdf->getUnNormLikelihood();
266  this->setUnNormPDFVal(result);
267 
268  Double_t norm = pdf->getNorm();
269  this->setNorm(norm);
270 }
271 
273 {
274  // Nothing to do here, since it is already normalized
275  this->setNorm(1.0);
276 }
277 
279 {
280  // This method gives you the maximum possible height of the PDF.
281  // It combines the maximum heights of the two individual PDFs.
282  // So it would give the true maximum if the two individual maxima coincided.
283  // It is guaranteed to always be >= the true maximum.
284 
285  Double_t m13Sq = kinematics->getm13Sq();
286  Double_t m23Sq = kinematics->getm23Sq();
287 
288  // Find which region of the DP we're in
289  UInt_t regionIndex = this->determineDPRegion( m13Sq, m23Sq );
290 
291  // Check that the region index is valid
292  if ( regionIndex >= pdfs_.size() ) {
293  cerr << "ERROR in LauDPDepMapPdf::calcPDFHeight : No PDF supplied for region " << regionIndex << endl;
294  gSystem->Exit(EXIT_FAILURE);
295  }
296 
297  // Evaluate the normalised PDF values
298  LauAbsPdf* pdf = pdfs_[regionIndex];
299 
300  // Update the heights of the individual PDFs
301  pdf->calcPDFHeight( kinematics );
302 
303  // Find the PDF maximum
304  Double_t height = pdf->getMaxHeight();
305  this->setMaxHeight(height);
306 }
307 
308 // Override the base class methods for cacheInfo and calcLikelihoodInfo(UInt_t iEvt).
309 // For both of these we delegate some functionality to the constituent PDFs.
310 
312 {
313  // delegate to the sub-PDFs to cache their information
314  for ( std::vector<LauAbsPdf*>::const_iterator iter = pdfs_.begin(); iter != pdfs_.end(); ++iter){
315  (*iter)->cacheInfo( inputData );
316  }
317 
318  // now check that the DP variables are included in the data
319  Bool_t hasBranch = inputData.haveBranch( "m13Sq" );
320  hasBranch &= inputData.haveBranch( "m23Sq" );
321  if (!hasBranch) {
322  cerr<<"ERROR in LauDPDepMapPdf::cacheInfo : Input data does not contain Dalitz plot variables m13Sq and/or m23Sq."<<endl;
323  return;
324  }
325 
326  // determine whether we are caching our PDF value
327  Bool_t doCaching( this->nFixedParameters() == this->nParameters() );
328  this->cachePDF( doCaching );
329 
330  if ( !doCaching ) {
331  // in this case we seem to be doing a fit where the parameters are floating
332  // so need to mark that the PDF height is no longer up to date
333  this->heightUpToDate(kFALSE);
334  }
335 
336  // clear the vector and reserve enough space
337  UInt_t nEvents = inputData.nEvents();
338  indices_.clear();
339  indices_.reserve(nEvents);
340 
341  // loop through the events, determine the fraction and store
342  for (UInt_t iEvt = 0; iEvt < nEvents; ++iEvt) {
343 
344  const LauFitData& dataValues = inputData.getData(iEvt);
345 
346  Double_t m13Sq = dataValues.find("m13Sq")->second;
347  Double_t m23Sq = dataValues.find("m23Sq")->second;
348 
349  UInt_t regionIndex = this->determineDPRegion( m13Sq, m23Sq );
350  indices_.push_back( regionIndex );
351  }
352 }
353 
355 {
356  // Get the fraction value for this event
357  UInt_t regionIndex = indices_[iEvt];
358 
359  // Evaluate the normalised PDF value
360  LauAbsPdf* pdf = pdfs_[regionIndex];
361  pdf->calcLikelihoodInfo(iEvt);
362 
363  Double_t result = pdf->getUnNormLikelihood();
364  this->setUnNormPDFVal(result);
365 
366  Double_t norm = pdf->getNorm();
367  this->setNorm(norm);
368 }
369 
virtual void setUnNormPDFVal(Double_t unNormPDFVal)
Set the unnormalised likelihood.
Definition: LauAbsPdf.hh:383
File containing declaration of LauDPDepMapPdf class.
virtual Double_t getMinAbscissa() const
Retrieve the minimum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:131
LauDaughters * daughters_
Daughter particles.
virtual Bool_t heightUpToDate() const
Check if the maximum height of the PDF is up to date.
Definition: LauAbsPdf.hh:278
ClassImp(LauAbsCoeffSet)
Lau2DAbsDP * dpDependence_
2D histogram - DP
Double_t getmPrime() const
Get m&#39; value.
Class that defines the particular 3-body decay under study.
Definition: LauDaughters.hh:47
virtual UInt_t nParameters() const
Retrieve the number of PDF parameters.
Definition: LauAbsPdf.hh:106
virtual Double_t getUnNormLikelihood() const
Retrieve the unnormalised likelihood value.
Definition: LauAbsPdf.hh:210
File containing declaration of LauDaughters class.
virtual void calcPDFHeight(const LauKinematics *kinematics)=0
Calculate the maximum height of the PDF.
UInt_t determineDPRegion(Double_t m13Sq, Double_t m23Sq) const
Determine the DP region.
virtual void calcPDFHeight(const LauKinematics *kinematics)
Calculate the PDF height.
virtual void setNorm(Double_t norm)
Set the normalisation factor.
Definition: LauAbsPdf.hh:339
virtual Bool_t checkRange(const LauAbscissas &abscissas) const
Check that all abscissas are within their allowed ranges.
Definition: LauAbsPdf.cc:227
TH1 * dpAxisDependence_
1D histogram - DP axis
virtual ~LauDPDepMapPdf()
Destructor.
virtual Double_t interpolateXY(Double_t x, Double_t y) const =0
Perform the interpolation.
std::map< TString, Double_t > LauFitData
Type for holding event data.
Double_t getm23Sq() const
Get the m23 invariant mass square.
Bool_t squareDP() const
Determine to use or not the square Dalitz plot.
Definition: LauDaughters.hh:98
std::vector< LauAbsPdf * > pdfs_
The PDFs.
Double_t distanceFromDPCentre() const
Calculate the distance from the currently set (m13Sq, m23Sq) point to the centre of the Dalitz plot (...
LauDPDepMapPdf(const std::vector< LauAbsPdf * > &pdfs, const LauDaughters *daughters, const TH2 *dpHisto, Bool_t upperHalf=kFALSE)
Constructor - map described by 2D histogram.
virtual Double_t getMaxHeight() const
Retrieve the maximum height.
Definition: LauAbsPdf.hh:235
std::vector< UInt_t > indices_
Cached indices values.
virtual void cacheInfo(const LauFitDataTree &inputData)
Cache information from data.
Double_t calcThirdMassSq(const Double_t firstMassSq, const Double_t secondMassSq) const
Calculate the third invariant mass square from the two provided (e.g. mjkSq from mijSq and mikSq) ...
File containing declaration of LauParameter class.
LauKinematics * getKinematics()
Retrieve the Dalitz plot kinematics.
virtual std::vector< TString > varNames() const
Retrieve the names of the abscissas.
Definition: LauAbsPdf.cc:117
virtual Double_t getMaxAbscissa() const
Retrieve the maximum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:137
virtual Bool_t isDPDependent() const
Specifies whether or not the PDF is DP dependent.
Definition: LauAbsPdf.hh:125
virtual void setMaxHeight(Double_t maxHeight)
Set the maximum height.
Definition: LauAbsPdf.hh:345
File containing declaration of Lau2DHistDP class.
virtual void addParameters(std::vector< LauAbsRValue * > &params)
Add parameters to the PDF.
Definition: LauAbsPdf.cc:437
virtual const std::vector< LauAbsRValue * > & getParameters() const
Retrieve the parameters of the PDF, e.g. so that they can be loaded into a fit.
Definition: LauAbsPdf.hh:253
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.
virtual Bool_t cachePDF() const
Check if the PDF is to be cached.
Definition: LauAbsPdf.hh:290
Double_t getm13Sq() const
Get the m13 invariant mass square.
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)=0
Calculate the likelihood (and all associated information) given value(s) of the abscissa(s) ...
Class for defining a 2D DP histogram.
Definition: Lau2DHistDP.hh:48
File containing LauConstants namespace.
Bool_t haveBranch(const TString &name) const
Check if the named branch is stored.
Double_t getThetaPrime() const
Get theta&#39; value.
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:55
Class for calculating 3-body kinematic quantities.
virtual UInt_t nFixedParameters() const
Retrieve the number of fixed PDF parameters.
Definition: LauAbsPdf.cc:127
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
UInt_t nEvents() const
Retrieve the number of events.
virtual void calcNorm()
Calculate the normalisation.
virtual UInt_t nInputVars() const
Retrieve the number of abscissas.
Definition: LauAbsPdf.hh:118
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:43
virtual Double_t getNorm() const
Retrieve the normalisation factor.
Definition: LauAbsPdf.hh:216
Class to allow having different PDFs in different regions of the DP.
Class to store the input fit variables.
DPAxis dpAxis_
The DP axis we depend on.
std::vector< Double_t > LauAbscissas
The type used for containing multiple abscissa values.
Definition: LauAbsPdf.hh:59
DPAxis
Define possibilties for the DP axes.