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