laura is hosted by Hepforge, IPPP Durham
Laura++  v3r5
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauCrystalBallPdf.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 /*****************************************************************************
30  * Class based on RooFit/RooCBShape. *
31  * Original copyright given below. *
32  *****************************************************************************
33  * Authors: *
34  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
35  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
36  * *
37  * Copyright (c) 2000-2005, Regents of the University of California *
38  * and Stanford University. All rights reserved. *
39  * *
40  * Redistribution and use in source and binary forms, *
41  * with or without modification, are permitted according to the terms *
42  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
43  *****************************************************************************/
44 
45 #include <iostream>
46 #include <vector>
47 using std::cout;
48 using std::cerr;
49 using std::endl;
50 using std::vector;
51 
52 #include "TMath.h"
53 #include "TSystem.h"
54 
55 #include "LauConstants.hh"
56 #include "LauCrystalBallPdf.hh"
57 
59 
60 
61 LauCrystalBallPdf::LauCrystalBallPdf(const TString& theVarName, const vector<LauAbsRValue*>& params, Double_t minAbscissa, Double_t maxAbscissa) :
62  LauAbsPdf(theVarName, params, minAbscissa, maxAbscissa),
63  mean_(0),
64  sigma_(0),
65  alpha_(0),
66  n_(0)
67 {
68  // Constructor for the Crystal Ball PDF, which is a gaussian and a decaying tail
69  // smoothly matched up. The tail goes as a 1/x^n
70  //
71  // The parameters in params are the mean and the sigma (half the width) of the gaussian,
72  // the distance from the mean in which the gaussian and the tail are matched up (which
73  // can be negative or positive), and the power "n" for the tail.
74  // The last two arguments specify the range in which the PDF is defined, and the PDF
75  // will be normalised w.r.t. these limits.
76 
77  mean_ = this->findParameter("mean");
78  sigma_ = this->findParameter("sigma");
79  alpha_ = this->findParameter("alpha");
80  n_ = this->findParameter("order");
81 
82  if ((this->nParameters() != 4) || (mean_ == 0) || (sigma_ == 0) || (alpha_ == 0) || (n_ == 0)) {
83  cerr<<"ERROR in LauCrystalBallPdf constructor: LauCrystalBallPdf requires 4 parameters: \"mean\", \"sigma\", \"alpha\" and \"order\"."<<endl;
84  gSystem->Exit(EXIT_FAILURE);
85  }
86 
87  // Cache the normalisation factor
88  this->calcNorm();
89 }
90 
92 {
93  // Destructor
94 }
95 
97 {
98  // Check that the given abscissa is within the allowed range
99  if (!this->checkRange(abscissas)) {
100  gSystem->Exit(EXIT_FAILURE);
101  }
102 
103  // Get our abscissa
104  Double_t abscissa = abscissas[0];
105 
106  // Get the up to date parameter values
107  Double_t mean = mean_->unblindValue();
108  Double_t sigma = sigma_->unblindValue();
109  Double_t alpha = alpha_->unblindValue();
110  Double_t n = n_->unblindValue();
111 
112  Double_t result(0.0);
113  Double_t t = (abscissa - mean)/sigma;
114  if (alpha < 0.0) {
115  t = -t;
116  }
117 
118  Double_t absAlpha = TMath::Abs(alpha);
119 
120  if (t >= -absAlpha) {
121  result = TMath::Exp(-0.5*t*t);
122  } else {
123  Double_t a = TMath::Power(n/absAlpha,n)*TMath::Exp(-0.5*absAlpha*absAlpha);
124  Double_t b = n/absAlpha - absAlpha;
125 
126  result = a/TMath::Power(b - t, n);
127  }
128 
129  this->setUnNormPDFVal(result);
130 
131  // if the parameters are floating then we
132  // need to recalculate the normalisation
133  if (!this->cachePDF() && !this->withinNormCalc() && !this->withinGeneration()) {
134  this->calcNorm();
135  }
136 
137 }
138 
140 {
141  // Get the up to date parameter values
142  Double_t mean = mean_->unblindValue();
143  Double_t sigma = sigma_->unblindValue();
144  Double_t alpha = alpha_->unblindValue();
145  Double_t n = n_->unblindValue();
146 
147  Double_t result = 0.0;
148  Bool_t useLog = kFALSE;
149 
150  if ( TMath::Abs(n-1.0) < 1.0e-05 ) {
151  useLog = kTRUE;
152  }
153 
154  Double_t sig = TMath::Abs(sigma);
155 
156  Double_t tmin = (this->getMinAbscissa() - mean)/sig;
157  Double_t tmax = (this->getMaxAbscissa() - mean)/sig;
158 
159  if (alpha < 0) {
160  Double_t tmp = tmin;
161  tmin = -tmax;
162  tmax = -tmp;
163  }
164 
165  Double_t absAlpha = TMath::Abs(alpha);
166 
167  if ( tmin >= -absAlpha ) {
168  result += sig*LauConstants::rootPiBy2*( this->approxErf( tmax / LauConstants::root2 )
169  - approxErf( tmin / LauConstants::root2 ) );
170  } else if ( tmax <= -absAlpha ) {
171  Double_t a = TMath::Power(n/absAlpha, n)*TMath::Exp( -0.5*absAlpha*absAlpha);
172  Double_t b = n/absAlpha - absAlpha;
173 
174  if ( useLog == kTRUE ) {
175  result += a*sig*( TMath::Log(b - tmin) - TMath::Log(b - tmax) );
176  } else {
177  result += a*sig/(1.0 - n)*( 1.0/(TMath::Power( b - tmin, n - 1.0))
178  - 1.0/(TMath::Power( b - tmax, n - 1.0)) );
179  }
180  } else {
181  Double_t a = TMath::Power(n/absAlpha, n)*TMath::Exp( -0.5*absAlpha*absAlpha );
182  Double_t b = n/absAlpha - absAlpha;
183 
184  Double_t term1 = 0.0;
185  if ( useLog == kTRUE )
186  term1 = a*sig*( TMath::Log(b - tmin) - TMath::Log(n / absAlpha));
187  else
188  term1 = a*sig/(1.0 - n)*( 1.0/(TMath::Power( b - tmin, n - 1.0))
189  - 1.0/(TMath::Power( n/absAlpha, n - 1.0)) );
190 
191  Double_t term2 = sig*LauConstants::rootPiBy2*( this->approxErf( tmax / LauConstants::root2 )
192  - this->approxErf( -absAlpha / LauConstants::root2 ) );
193 
194  result += term1 + term2;
195  }
196  this->setNorm(result);
197 }
198 
199 void LauCrystalBallPdf::calcPDFHeight( const LauKinematics* /*kinematics*/ )
200 {
201  if (this->heightUpToDate()) {
202  return;
203  }
204 
205  // Get the up to date parameter values
206  Double_t mean = mean_->unblindValue();
207 
208  // The Crystall Ball function is a Gaussian with an exponentially decaying tail
209  // Therefore, calculate the PDF height for the Gaussian function.
210  LauAbscissas abscissa(1);
211  abscissa[0] = mean;
212  this->calcLikelihoodInfo(abscissa);
213 
214  Double_t height = this->getUnNormLikelihood();
215  this->setMaxHeight(height);
216 }
217 
218 Double_t LauCrystalBallPdf::approxErf(Double_t arg) const
219 {
220  static const Double_t erflim = 5.0;
221  if ( arg > erflim ) {
222  return 1.0;
223  }
224  if ( arg < -erflim ) {
225  return -1.0;
226  }
227 
228  return TMath::Erf(arg);
229 }
230 
virtual void calcNorm()
Calculate the normalisation.
virtual void setUnNormPDFVal(Double_t unNormPDFVal)
Set the unnormalised likelihood.
Definition: LauAbsPdf.hh:383
virtual ~LauCrystalBallPdf()
Destructor.
virtual Double_t getMinAbscissa() const
Retrieve the minimum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:131
Double_t approxErf(Double_t arg) const
Calculate the approximate error function of argument.
virtual Bool_t heightUpToDate() const
Check if the maximum height of the PDF is up to date.
Definition: LauAbsPdf.hh:278
ClassImp(LauAbsCoeffSet)
File containing declaration of LauCrystalBallPdf class.
virtual Double_t getUnNormLikelihood() const
Retrieve the unnormalised likelihood value.
Definition: LauAbsPdf.hh:210
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
virtual void calcPDFHeight(const LauKinematics *kinematics)
Calculate the PDF height.
virtual Bool_t withinNormCalc() const
Check whether the calcNorm method is running.
Definition: LauAbsPdf.hh:437
const Double_t rootPiBy2
Square root of Pi divided by two.
const Double_t root2
Square root of two.
Class for defining a Crystal Ball PDF.
virtual Double_t getMaxAbscissa() const
Retrieve the maximum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:137
virtual void setMaxHeight(Double_t maxHeight)
Set the maximum height.
Definition: LauAbsPdf.hh:345
virtual Bool_t withinGeneration() const
Check whether the generate method is running.
Definition: LauAbsPdf.hh:449
virtual Bool_t cachePDF() const
Check if the PDF is to be cached.
Definition: LauAbsPdf.hh:290
File containing LauConstants namespace.
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:55
Class for calculating 3-body kinematic quantities.
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
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