laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
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::cerr;
48 using std::cout;
49 using std::endl;
50 
51 #include "LauConstants.hh"
52 #include "LauCrystalBallPdf.hh"
53 
54 #include "TMath.h"
55 #include "TSystem.h"
56 
57 LauCrystalBallPdf::LauCrystalBallPdf( const TString& theVarName,
58  const std::vector<LauAbsRValue*>& params,
59  Double_t minAbscissa,
60  Double_t maxAbscissa ) :
61  LauAbsPdf( theVarName, params, minAbscissa, maxAbscissa ),
62  mean_( 0 ),
63  sigma_( 0 ),
64  alpha_( 0 ),
65  n_( 0 )
66 {
67  // Constructor for the Crystal Ball PDF, which is a gaussian and a decaying tail
68  // smoothly matched up. The tail goes as a 1/x^n
69  //
70  // The parameters in params are the mean and the sigma (half the width) of the gaussian,
71  // the distance from the mean in which the gaussian and the tail are matched up (which
72  // can be negative or positive), and the power "n" for the tail.
73  // The last two arguments specify the range in which the PDF is defined, and the PDF
74  // will be normalised w.r.t. these limits.
75 
76  mean_ = this->findParameter( "mean" );
77  sigma_ = this->findParameter( "sigma" );
78  alpha_ = this->findParameter( "alpha" );
79  n_ = this->findParameter( "order" );
80 
81  if ( ( this->nParameters() != 4 ) || ( mean_ == 0 ) || ( sigma_ == 0 ) || ( alpha_ == 0 ) ||
82  ( n_ == 0 ) ) {
83  cerr << "ERROR in LauCrystalBallPdf constructor: LauCrystalBallPdf requires 4 parameters: \"mean\", \"sigma\", \"alpha\" and \"order\"."
84  << endl;
85  gSystem->Exit( EXIT_FAILURE );
86  }
87 
88  // Cache the normalisation factor
89  this->calcNorm();
90 }
91 
93 {
94  // Destructor
95 }
96 
98 {
99  // Check that the given abscissa is within the allowed range
100  if ( ! this->checkRange( abscissas ) ) {
101  gSystem->Exit( EXIT_FAILURE );
102  }
103 
104  // Get our abscissa
105  Double_t abscissa = abscissas[0];
106 
107  // Get the up to date parameter values
108  Double_t mean = mean_->unblindValue();
109  Double_t sigma = sigma_->unblindValue();
110  Double_t alpha = alpha_->unblindValue();
111  Double_t n = n_->unblindValue();
112 
113  Double_t result( 0.0 );
114  Double_t t = ( abscissa - mean ) / sigma;
115  if ( alpha < 0.0 ) {
116  t = -t;
117  }
118 
119  Double_t absAlpha = TMath::Abs( alpha );
120 
121  if ( t >= -absAlpha ) {
122  result = TMath::Exp( -0.5 * t * t );
123  } else {
124  Double_t a = TMath::Power( n / absAlpha, n ) * TMath::Exp( -0.5 * absAlpha * absAlpha );
125  Double_t b = n / absAlpha - absAlpha;
126 
127  result = a / TMath::Power( b - t, n );
128  }
129 
130  this->setUnNormPDFVal( result );
131 
132  // if the parameters are floating then we
133  // need to recalculate the normalisation
134  if ( ! this->cachePDF() && ! this->withinNormCalc() && ! this->withinGeneration() ) {
135  this->calcNorm();
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 *
169  ( this->approxErf( tmax / LauConstants::root2 ) -
170  approxErf( tmin / LauConstants::root2 ) );
171  } else if ( tmax <= -absAlpha ) {
172  Double_t a = TMath::Power( n / absAlpha, n ) * TMath::Exp( -0.5 * absAlpha * absAlpha );
173  Double_t b = n / absAlpha - absAlpha;
174 
175  if ( useLog == kTRUE ) {
176  result += a * sig * ( TMath::Log( b - tmin ) - TMath::Log( b - tmax ) );
177  } else {
178  result += a * sig / ( 1.0 - n ) *
179  ( 1.0 / ( TMath::Power( b - tmin, n - 1.0 ) ) -
180  1.0 / ( TMath::Power( b - tmax, n - 1.0 ) ) );
181  }
182  } else {
183  Double_t a = TMath::Power( n / absAlpha, n ) * TMath::Exp( -0.5 * absAlpha * absAlpha );
184  Double_t b = n / absAlpha - absAlpha;
185 
186  Double_t term1 = 0.0;
187  if ( useLog == kTRUE )
188  term1 = a * sig * ( TMath::Log( b - tmin ) - TMath::Log( n / absAlpha ) );
189  else
190  term1 = a * sig / ( 1.0 - n ) *
191  ( 1.0 / ( TMath::Power( b - tmin, n - 1.0 ) ) -
192  1.0 / ( TMath::Power( n / absAlpha, n - 1.0 ) ) );
193 
194  Double_t term2 = sig * LauConstants::rootPiBy2 *
195  ( this->approxErf( tmax / LauConstants::root2 ) -
196  this->approxErf( -absAlpha / LauConstants::root2 ) );
197 
198  result += term1 + term2;
199  }
200  this->setNorm( result );
201 }
202 
203 void LauCrystalBallPdf::calcPDFHeight( const LauKinematics* /*kinematics*/ )
204 {
205  if ( this->heightUpToDate() ) {
206  return;
207  }
208 
209  // Get the up to date parameter values
210  Double_t mean = mean_->unblindValue();
211 
212  // The Crystall Ball function is a Gaussian with an exponentially decaying tail
213  // Therefore, calculate the PDF height for the Gaussian function.
214  LauAbscissas abscissa( 1 );
215  abscissa[0] = mean;
216  this->calcLikelihoodInfo( abscissa );
217 
218  Double_t height = this->getUnNormLikelihood();
219  this->setMaxHeight( height );
220 }
221 
222 Double_t LauCrystalBallPdf::approxErf( Double_t arg ) const
223 {
224  static const Double_t erflim = 5.0;
225  if ( arg > erflim ) {
226  return 1.0;
227  }
228  if ( arg < -erflim ) {
229  return -1.0;
230  }
231 
232  return TMath::Erf( arg );
233 }
LauAbsRValue * alpha_
Alpha - distance from the mean in which the Gaussian and the tail are matched up.
File containing declaration of LauCrystalBallPdf class.
virtual Double_t getMaxAbscissa() const
Retrieve the maximum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:141
virtual Double_t getMinAbscissa() const
Retrieve the minimum value of the (primary) abscissa.
Definition: LauAbsPdf.hh:135
LauCrystalBallPdf(const TString &theVarName, const std::vector< LauAbsRValue * > &params, Double_t minAbscissa, Double_t maxAbscissa)
Constructor.
Double_t approxErf(Double_t arg) const
Calculate the approximate error function of argument.
virtual Bool_t cachePDF() const
Check if the PDF is to be cached.
Definition: LauAbsPdf.hh:299
std::vector< Double_t > LauAbscissas
The type used for containing multiple abscissa values.
Definition: LauAbsPdf.hh:58
LauAbsRValue * mean_
Gaussian mean.
LauAbsRValue * n_
Power for tail (goes as 1/x^n)
virtual LauAbsRValue * findParameter(const TString &parName)
Retrieve the specified parameter.
Definition: LauAbsPdf.cc:431
virtual void calcPDFHeight(const LauKinematics *kinematics)
Calculate the PDF height.
const Double_t root2
Square root of two.
virtual Bool_t withinNormCalc() const
Check whether the calcNorm method is running.
Definition: LauAbsPdf.hh:448
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.
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
virtual Bool_t withinGeneration() const
Check whether the generate method is running.
Definition: LauAbsPdf.hh:460
File containing LauConstants namespace.
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.
virtual void calcNorm()
Calculate the normalisation.
virtual Double_t getUnNormLikelihood() const
Retrieve the unnormalised likelihood value.
Definition: LauAbsPdf.hh:218
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
LauAbsRValue * sigma_
Gaussian sigma.
virtual Bool_t heightUpToDate() const
Check if the maximum height of the PDF is up to date.
Definition: LauAbsPdf.hh:287
virtual ~LauCrystalBallPdf()
Destructor.
virtual Bool_t checkRange(const LauAbscissas &abscissas) const
Check that all abscissas are within their allowed ranges.
Definition: LauAbsPdf.cc:243