laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauChebychevPdf.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2009 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/RooChebychev. *
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 "LauChebychevPdf.hh"
46 
47 #include "TMath.h"
48 #include "TSystem.h"
49 
50 #include <iostream>
51 #include <vector>
52 
53 LauChebychevPdf::LauChebychevPdf( const TString& theVarName,
54  const std::vector<LauAbsRValue*>& params,
55  Double_t minAbscissa,
56  Double_t maxAbscissa ) :
57  LauAbsPdf( theVarName, params, minAbscissa, maxAbscissa ),
58  coeffs_( params.size(), 0 )
59 {
60  // Constructor for the Chebychev Polynomial PDF.
61  //
62  // The parameters in params are the coefficients of the polynomial
63  // (polynomial can be anything from 0 to 7 orders).
64  // The last two arguments specify the range in which the PDF is defined, and the PDF
65  // will be normalised w.r.t. these limits.
66 
67  if ( ( this->nParameters() > 7 ) ) {
68  std::cerr << "ERROR in LauChebychevPdf constructor: Too many coeffs - can only cope with order <=7 polynomial."
69  << std::endl;
70  gSystem->Exit( EXIT_FAILURE );
71  }
72 
73  for ( UInt_t i( 0 ); i < this->nParameters(); ++i ) {
74  TString name = "c";
75  name += i + 1;
76  coeffs_[i] = this->findParameter( name );
77  }
78 
79  // Cache the normalisation factor
80  this->calcNorm();
81 }
82 
84 {
85  // Destructor
86 }
87 
88 //inline static double p0(double ,double a) { return a; }
89 inline static double p1( double t, double a, double b )
90 {
91  return a * t + b;
92 }
93 
94 inline static double p2( double t, double a, double b, double c )
95 {
96  return p1( t, p1( t, a, b ), c );
97 }
98 
99 inline static double p3( double t, double a, double b, double c, double d )
100 {
101  return p2( t, p1( t, a, b ), c, d );
102 }
103 
104 //inline static double p4(double t,double a,double b,double c,double d,double e) { return p3(t,p1(t,a,b),c,d,e); }
105 
107 {
108  // Check that the given abscissa is within the allowed range
109  if ( ! this->checkRange( abscissas ) ) {
110  gSystem->Exit( EXIT_FAILURE );
111  }
112 
113  // Get our abscissa
114  Double_t abscissa = abscissas[0];
115 
116  Double_t xmin = this->getMinAbscissa();
117  Double_t xmax = this->getMaxAbscissa();
118  Double_t x( -1.0 + 2.0 * ( abscissa - xmin ) / ( xmax - xmin ) );
119  Double_t x2( x * x );
120  Double_t sum( 0 );
121  switch ( coeffs_.size() ) {
122  case 7 :
123  sum += coeffs_[6]->unblindValue() * x * p3( x2, 64, -112, 56, -7 );
124  [[fallthrough]];
125  case 6 :
126  sum += coeffs_[5]->unblindValue() * p3( x2, 32, -48, 18, -1 );
127  [[fallthrough]];
128  case 5 :
129  sum += coeffs_[4]->unblindValue() * x * p2( x2, 16, -20, 5 );
130  [[fallthrough]];
131  case 4 :
132  sum += coeffs_[3]->unblindValue() * p2( x2, 8, -8, 1 );
133  [[fallthrough]];
134  case 3 :
135  sum += coeffs_[2]->unblindValue() * x * p1( x2, 4, -3 );
136  [[fallthrough]];
137  case 2 :
138  sum += coeffs_[1]->unblindValue() * p1( x2, 2, -1 );
139  [[fallthrough]];
140  case 1 :
141  sum += coeffs_[0]->unblindValue() * x;
142  [[fallthrough]];
143  case 0 :
144  sum += 1;
145  }
146 
147  this->setUnNormPDFVal( sum );
148 
149  // if the parameters are floating then we
150  // need to recalculate the normalisation
151  if ( ! this->cachePDF() && ! this->withinNormCalc() && ! this->withinGeneration() ) {
152  this->calcNorm();
153  }
154 }
155 
157 {
158  Double_t xmin = this->getMinAbscissa();
159  Double_t xmax = this->getMaxAbscissa();
160 
161  Double_t norm( 0 );
162  switch ( coeffs_.size() ) {
163  case 7 :
164  case 6 :
165  norm += coeffs_[5]->unblindValue() * ( -1 + 18. / 3. - 48. / 5. + 32. / 7. );
166  [[fallthrough]];
167  case 5 :
168  case 4 :
169  norm += coeffs_[3]->unblindValue() * ( 1 - 8. / 3. + 8. / 5. );
170  [[fallthrough]];
171  case 3 :
172  case 2 :
173  norm += coeffs_[1]->unblindValue() * ( -1 + 2. / 3. );
174  [[fallthrough]];
175  case 1 :
176  case 0 :
177  norm += 1;
178  }
179  norm *= xmax - xmin;
180 
181  this->setNorm( norm );
182 }
183 
184 void LauChebychevPdf::calcPDFHeight( const LauKinematics* /*kinematics*/ )
185 {
186  // TODO - this method can hopefully be improved
187  // At present it scans through the range and then increases by a 20% safety factor
188  // Maybe there's a better way?
189 
190  if ( this->heightUpToDate() ) {
191  return;
192  }
193 
194  // Calculate the PDF height
195  LauAbscissas maxPoint( 1 );
196 
197  Double_t minAbs = this->getMinAbscissa();
198  Double_t maxAbs = this->getMaxAbscissa();
199  Double_t range = maxAbs - minAbs;
200  Double_t maxHeight( 0.0 );
201 
202  // Just scan through the range
203  for ( Double_t point = minAbs; point <= maxAbs; point += range / 1000.0 ) {
204  maxPoint[0] = point;
205  this->calcLikelihoodInfo( maxPoint );
206  Double_t heightAtPoint = this->getUnNormLikelihood();
207  if ( heightAtPoint > maxHeight ) {
208  maxHeight = heightAtPoint;
209  }
210  }
211 
212  // Mutliply by 120% to be on the safe side
213  maxHeight *= 1.2;
214 
215  this->setMaxHeight( maxHeight );
216 }
virtual ~LauChebychevPdf()
Destructor.
std::vector< LauAbsRValue * > coeffs_
Coefficients of polynomial.
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
File containing declaration of LauChebychevPdf class.
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
virtual LauAbsRValue * findParameter(const TString &parName)
Retrieve the specified parameter.
Definition: LauAbsPdf.cc:431
virtual Bool_t withinNormCalc() const
Check whether the calcNorm method is running.
Definition: LauAbsPdf.hh:448
virtual void calcNorm()
Calculate the normalisation.
virtual void calcLikelihoodInfo(const LauAbscissas &abscissas)
Calculate the likelihood (and intermediate info) for a given abscissa.
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 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
LauChebychevPdf(const TString &theVarName, const std::vector< LauAbsRValue * > &params, Double_t minAbscissa, Double_t maxAbscissa)
Constructor.
const TString & name() const
The parameter name.
virtual void setMaxHeight(Double_t maxHeight)
Set the maximum height.
Definition: LauAbsPdf.hh:354
Double_t range() const
The range allowed for the parameter.
Class for calculating 3-body kinematic quantities.
virtual void calcPDFHeight(const LauKinematics *kinematics)
Calculate the PDF height.
virtual Double_t getUnNormLikelihood() const
Retrieve the unnormalised likelihood value.
Definition: LauAbsPdf.hh:218
virtual Bool_t heightUpToDate() const
Check if the maximum height of the PDF is up to date.
Definition: LauAbsPdf.hh:287
virtual Bool_t checkRange(const LauAbscissas &abscissas) const
Check that all abscissas are within their allowed ranges.
Definition: LauAbsPdf.cc:243