laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauDPDepBifurGaussPdf.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2007 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 using std::vector;
35 
36 #include "TMath.h"
37 #include "TRandom.h"
38 #include "TSystem.h"
39 
40 #include "Lau1DHistPdf.hh"
41 #include "LauConstants.hh"
42 #include "LauComplex.hh"
43 #include "LauDaughters.hh"
44 #include "LauFitDataTree.hh"
45 #include "LauKinematics.hh"
46 #include "LauDPDepBifurGaussPdf.hh"
47 
49 
50 
51 LauDPDepBifurGaussPdf::LauDPDepBifurGaussPdf(const TString& theVarName, const vector<LauAbsRValue*>& params,
52  Double_t minAbscissa, Double_t maxAbscissa,
53  const LauDaughters* daughters,
54  const vector<Double_t>& meanCoeffs,
55  const vector<Double_t>& sigmaLCoeffs,
56  const vector<Double_t>& sigmaRCoeffs,
57  DPAxis dpAxis) :
58  LauAbsPdf(theVarName, params, minAbscissa, maxAbscissa),
59  kinematics_(daughters ? daughters->getKinematics() : 0),
60  mean_(0),
61  sigmaL_(0),
62  sigmaR_(0),
63  meanVal_(0.0),
64  sigmaLVal_(0.0),
65  sigmaRVal_(0.0),
66  meanCoeffs_(meanCoeffs),
67  sigmaLCoeffs_(sigmaLCoeffs),
68  sigmaRCoeffs_(sigmaRCoeffs),
69  dpAxis_(dpAxis),
70  scaleMethod_(poly)
71 {
72  // Check we have a valid kinematics object
73  if ( ! kinematics_ ) {
74  cerr<<"ERROR in LauDPDepBifurGaussPdf::LauDPDepBifurGaussPdf : Have not been provided with a valid DP kinematics object."<<endl;
75  gSystem->Exit(EXIT_FAILURE);
76  }
77 
78  // The parameters are:
79  // - the mean, the sigmaL and the sigmaR of the Bifurcated Gaussian
80  //
81  // The next two arguments specify the range in which the PDF is defined,
82  // and the PDF will be normalised w.r.t. these limits.
83  //
84  // The final three argument define whether the BF Gaussian parameters should be scaled or not
85 
86  mean_ = this->findParameter("mean");
87  sigmaL_ = this->findParameter("sigmaL");
88  sigmaR_ = this->findParameter("sigmaR");
89 
90  if ((this->nParameters() != 3) || (mean_ == 0) || (sigmaL_ == 0) || (sigmaR_ == 0) ) {
91  cerr<<"ERROR in LauDPDepBifurGaussPdf constructor: LauDPDepBifurGaussPdf requires 3 parameters:"
92  <<" \"mean\", \"sigmaL\" and \"sigmaR\"."<<endl;
93  gSystem->Exit(EXIT_FAILURE);
94  }
95 
96  // Cache the normalisation factor
97  this->calcNorm();
98 }
99 
101 {
102  // Destructor
103 }
104 
106 {
107  // Check that the given abscissas are within the allowed range
108  if (!this->checkRange(abscissas)) {
109  gSystem->Exit(EXIT_FAILURE);
110  }
111 
112  // Get our abscissa
113  Double_t abscissa = abscissas[0];
114 
115  // Get the up to date parameter values
116  meanVal_ = mean_->unblindValue();
117  sigmaLVal_ = sigmaL_->unblindValue();
118  sigmaRVal_ = sigmaR_->unblindValue();
119 
120  // Find out the DP position
121  Double_t dpPos(0.0);
122  UInt_t nVars = this->nInputVars();
123  if ( abscissas.size() == nVars+2 ) {
124  Double_t m13Sq = abscissas[nVars];
125  Double_t m23Sq = abscissas[nVars+1];
126 
127  if ( dpAxis_ == M12 ) {
128  dpPos = kinematics_->calcThirdMassSq(m13Sq,m23Sq);
129  } else if ( dpAxis_ == M13 ) {
130  dpPos = m13Sq;
131  } else if ( dpAxis_ == M23 ) {
132  dpPos = m23Sq;
133  } else if ( dpAxis_ == MMIN ) {
134  dpPos = TMath::Min( m13Sq, m23Sq );
135  } else if ( dpAxis_ == MMAX ) {
136  dpPos = TMath::Max( m13Sq, m23Sq );
137  } else {
138  dpPos = kinematics_->distanceFromDPCentre(m13Sq,m23Sq);
139  }
140  }
141 
142  // Scale the gaussian parameters by the dpPos (if appropriate)
143  ScaleMethod scale = this->scaleMethod();
144  if ( scale==poly ) {
145  this->scalePars_poly(dpPos);
146  } else if ( scale==polyNegPower ) {
147  this->scalePars_polyNegPower(dpPos);
148  } else {
149  cerr<<"Scaling method unknown! Methods available: <poly> and <polyNegPower>."<<endl;
150  gSystem->Exit(EXIT_FAILURE);
151  }
152 
153  // Evaluate the Birfucated Gaussian PDF value
154  Double_t arg = abscissa - meanVal_;
155  Double_t coef(0.0);
156  Double_t value(0.0);
157 
158  if (arg < 0.0) {
159  if (TMath::Abs(sigmaLVal_) > 1e-30) {
160  coef = -0.5/(sigmaLVal_*sigmaLVal_);
161  }
162  } else {
163  if (TMath::Abs(sigmaRVal_) > 1e-30) {
164  coef = -0.5/(sigmaRVal_*sigmaRVal_);
165  }
166  }
167  value = TMath::Exp(coef*arg*arg);
168 
169  // Calculate the norm
170  Double_t xscaleL = LauConstants::root2*sigmaLVal_;
171  Double_t xscaleR = LauConstants::root2*sigmaRVal_;
172 
173  Double_t integral(0.0);
174  Double_t norm(0.0);
175  Double_t result(0.0);
176 
177 
178  if ( this->getMaxAbscissa() < meanVal_ ) {
179  integral = sigmaLVal_ * ( TMath::Erf((this->getMaxAbscissa() - meanVal_)/xscaleL) - TMath::Erf((this->getMinAbscissa() - meanVal_)/xscaleL));
180  } else if ( this->getMinAbscissa() > meanVal_ ) {
181  integral = sigmaRVal_ * (TMath::Erf((this->getMaxAbscissa() - meanVal_)/xscaleR) - TMath::Erf((this->getMinAbscissa() - meanVal_)/xscaleR));
182  } else {
183  integral = sigmaRVal_*TMath::Erf((this->getMaxAbscissa() -meanVal_)/xscaleR) - sigmaLVal_*TMath::Erf((this->getMinAbscissa() - meanVal_)/xscaleL);
184  }
185 
186  norm = LauConstants::rootPiBy2*integral;
187 
188  // the result
189  result = value/norm;
190  this->setUnNormPDFVal(result);
191 }
192 
194 {
195  Int_t power = 1;
196  for (vector<Double_t>::const_iterator iter = meanCoeffs_.begin(); iter != meanCoeffs_.end(); ++iter) {
197  Double_t coeff = (*iter);
198  meanVal_ += coeff * TMath::Power(dpPos,power);
199  ++power;
200  }
201 
202  power = 1;
203  for (vector<Double_t>::const_iterator iter = sigmaLCoeffs_.begin(); iter != sigmaLCoeffs_.end(); ++iter) {
204  Double_t coeff = (*iter);
205  sigmaLVal_ += coeff * TMath::Power(dpPos,power);
206  ++power;
207  }
208 
209  power = 1;
210  for (vector<Double_t>::const_iterator iter = sigmaRCoeffs_.begin(); iter != sigmaRCoeffs_.end(); ++iter) {
211  Double_t coeff = (*iter);
212  sigmaRVal_ += coeff * TMath::Power(dpPos,power);
213  ++power;
214  }
215 }
216 
218 {
219  Int_t power = -1;
220  for (vector<Double_t>::const_iterator iter = meanCoeffs_.begin(); iter != meanCoeffs_.end(); ++iter) {
221  Double_t coeff = (*iter);
222  meanVal_ += coeff * TMath::Power(dpPos,power);
223  --power;
224  }
225 
226  power = -1;
227  for (vector<Double_t>::const_iterator iter = sigmaLCoeffs_.begin(); iter != sigmaLCoeffs_.end(); ++iter) {
228  Double_t coeff = (*iter);
229  sigmaLVal_ += coeff * TMath::Power(dpPos,power);
230  --power;
231  }
232 
233  power = -1;
234  for (vector<Double_t>::const_iterator iter = sigmaRCoeffs_.begin(); iter != sigmaRCoeffs_.end(); ++iter) {
235  Double_t coeff = (*iter);
236  sigmaRVal_ += coeff * TMath::Power(dpPos,power);
237  --power;
238  }
239 }
240 
242 {
243  this->setNorm(1.0);
244 }
245 
247 {
248  // Get the up to date parameter values
249  meanVal_ = mean_->unblindValue();
250  sigmaLVal_ = sigmaL_->unblindValue();
251  sigmaRVal_ = sigmaR_->unblindValue();
252 
253  // Scale the gaussian parameters by the dpCentreDist (if appropriate)
254  Double_t dpCentreDist = kinematics->distanceFromDPCentre();
255  ScaleMethod scale = this->scaleMethod();
256  if ( scale==poly ) {
257  this->scalePars_poly(dpCentreDist);
258  } else if ( scale==polyNegPower ) {
259  this->scalePars_polyNegPower(dpCentreDist);
260  } else {
261  cerr<<"Scaling method unknown! Methods available: <poly> and <polyNegPower>."<<endl;
262  gSystem->Exit(EXIT_FAILURE);
263  }
264 
265  // Calculate the PDF height for the Bifurcated Gaussian function.
266  LauAbscissas maxPoint(3);
267  maxPoint[0] = meanVal_;
268  maxPoint[1] = kinematics->getm13Sq();
269  maxPoint[2] = kinematics->getm23Sq();
270  if ( meanVal_ > this->getMaxAbscissa() ) {
271  maxPoint[0] = this->getMaxAbscissa();
272  } else if ( meanVal_ < this->getMinAbscissa() ) {
273  maxPoint[0] = this->getMinAbscissa();
274  }
275  this->calcLikelihoodInfo(maxPoint);
276  Double_t height = this->getUnNormLikelihood();
277 
278  // Multiply by a small factor to avoid problems from rounding errors
279  height *= 1.001;
280 
281  this->setMaxHeight(height);
282 }
283 
Double_t sigmaLVal_
Left Gaussian sigma.
virtual ~LauDPDepBifurGaussPdf()
Destructor.
virtual void setUnNormPDFVal(Double_t unNormPDFVal)
Set the unnormalised likelihood.
Definition: LauAbsPdf.hh:383
File containing declaration of LauFitDataTree class.
virtual Double_t getMinAbscissa() const
Retrieve the minimum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:131
ClassImp(LauAbsCoeffSet)
Class that defines the particular 3-body decay under study.
Definition: LauDaughters.hh:47
const std::vector< Double_t > meanCoeffs_
Coefficients of Gaussian mean.
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)
Calculate the PDF height.
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
virtual void setNorm(Double_t norm)
Set the normalisation factor.
Definition: LauAbsPdf.hh:339
void scalePars_poly(Double_t perEventDist)
Scale the Gaussian parameters with polynomial method.
virtual Bool_t checkRange(const LauAbscissas &abscissas) const
Check that all abscissas are within their allowed ranges.
Definition: LauAbsPdf.cc:227
const LauKinematics * kinematics_
The current DP kinematics.
Double_t getm23Sq() const
Get the m23 invariant mass square.
void scalePars_polyNegPower(Double_t perEventDist)
Scale the Gaussian parameters with negative power polynomial method.
DPAxis dpAxis_
The DP axis we depend on.
Double_t distanceFromDPCentre() const
Calculate the distance from the currently set (m13Sq, m23Sq) point to the centre of the Dalitz plot (...
File containing declaration of LauKinematics class.
const Double_t rootPiBy2
Square root of Pi divided by two.
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) ...
const Double_t root2
Square root of two.
virtual Double_t getMaxAbscissa() const
Retrieve the maximum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:137
File containing declaration of LauComplex class.
File containing declaration of LauDPDepBifurGaussPdf class.
virtual void setMaxHeight(Double_t maxHeight)
Set the maximum height.
Definition: LauAbsPdf.hh:345
ScaleMethod scaleMethod() const
Retrieve scaling method information.
ScaleMethod
Define possibilties for the scaling method.
const std::vector< Double_t > sigmaLCoeffs_
Coefficients of left Gaussian sigma.
Double_t sigmaRVal_
Right Gaussian sigma.
Double_t getm13Sq() const
Get the m13 invariant mass square.
File containing LauConstants namespace.
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:55
const std::vector< Double_t > sigmaRCoeffs_
Coefficients of right Gaussian sigma.
Class for calculating 3-body kinematic quantities.
Double_t value() const
The value of the parameter.
virtual UInt_t nInputVars() const
Retrieve the number of abscissas.
Definition: LauAbsPdf.hh:118
virtual void calcNorm()
Calculate the normalisation.
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:43
std::vector< Double_t > LauAbscissas
The type used for containing multiple abscissa values.
Definition: LauAbsPdf.hh:59
Double_t meanVal_
Gaussian mean.
Class for defining a Bifurcated Gaussian PDF (DP dependent).
File containing declaration of Lau1DHistPdf class.