ROOT  6.06/09
Reference Guide
RooNovosibirsk.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitModels *
4  * @(#)root/roofit:$Id$
5  * Authors: *
6  * DB, Dieter Best, UC Irvine, best@slac.stanford.edu *
7  * HT, Hirohisa Tanaka SLAC tanaka@slac.stanford.edu *
8  * *
9  * Updated version with analytical integral *
10  * MP, Marko Petric, J. Stefan Institute, marko.petric@ijs.si *
11  * *
12  * Copyright (c) 2000-2013, Regents of the University of California *
13  * and Stanford University. All rights reserved. *
14  * *
15  * Redistribution and use in source and binary forms, *
16  * with or without modification, are permitted according to the terms *
17  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
18  *****************************************************************************/
19 
20 //////////////////////////////////////////////////////////////////////////////
21 //
22 // BEGIN_HTML
23 //
24 // RooNovosibirsk implements the Novosibirsk function
25 //
26 // Function taken from H. Ikeda et al. NIM A441 (2000), p. 401 (Belle Collaboration)
27 //
28 // END_HTML
29 //
30 
31 
32 #include "RooFit.h"
33 
34 #include <math.h>
35 #include "TMath.h"
36 
37 #include "RooNovosibirsk.h"
38 #include "RooRealVar.h"
39 
40 using namespace std;
41 
43 
44 
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 
48 RooNovosibirsk::RooNovosibirsk(const char *name, const char *title,
49  RooAbsReal& _x, RooAbsReal& _peak,
50  RooAbsReal& _width, RooAbsReal& _tail) :
51  // The two addresses refer to our first dependent variable and
52  // parameter, respectively, as declared in the rdl file
53  RooAbsPdf(name, title),
54  x("x","x",this,_x),
55  width("width","width",this,_width),
56  peak("peak","peak",this,_peak),
57  tail("tail","tail",this,_tail)
58 {
59 }
60 
61 
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 
66  RooAbsPdf(other,name),
67  x("x",this,other.x),
68  width("width",this,other.width),
69  peak("peak",this,other.peak),
70  tail("tail",this,other.tail)
71 {
72 }
73 
74 
75 
76 ////////////////////////////////////////////////////////////////////////////////
77 ///If tail=eta=0 the Belle distribution becomes gaussian
78 
80 {
81  if (TMath::Abs(tail) < 1.e-7) {
82  return TMath::Exp( -0.5 * TMath::Power( ( (x - peak) / width ), 2 ));
83  }
84 
85  Double_t arg = 1.0 - ( x - peak ) * tail / width;
86 
87  if (arg < 1.e-7) {
88  //Argument of logaritem negative. Real continuation -> function equals zero
89  return 0.0;
90  }
91 
92  Double_t log = TMath::Log(arg);
93  static const Double_t xi = 2.3548200450309494; // 2 Sqrt( Ln(4) )
94 
95  Double_t width_zero = ( 2.0 / xi ) * TMath::ASinH( tail * xi * 0.5 );
96  Double_t width_zero2 = width_zero * width_zero;
97  Double_t exponent = ( -0.5 / (width_zero2) * log * log ) - ( width_zero2 * 0.5 );
98 
99  return TMath::Exp(exponent) ;
100 }
101 
102 
103 
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 
107 Int_t RooNovosibirsk::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* ) const
108 {
109  if (matchArgs(allVars,analVars,x)) return 1 ;
110  if (matchArgs(allVars,analVars,peak)) return 2 ;
111 
112  //The other two integrals over tali and width are not integrable
113 
114  return 0 ;
115 }
116 
117 
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 
121 Double_t RooNovosibirsk::analyticalIntegral(Int_t code, const char* rangeName) const
122 {
123  assert(code==1 || code==2) ;
124 
125  //The range is defined as [A,B]
126 
127  //Numerical values need for the evaluation of the integral
128  static const Double_t sqrt2 = 1.4142135623730950; // Sqrt(2)
129  static const Double_t sqlog2 = 0.832554611157697756; //Sqrt( Log(2) )
130  static const Double_t sqlog4 = 1.17741002251547469; //Sqrt( Log(4) )
131  static const Double_t log4 = 1.38629436111989062; //Log(2)
132  static const Double_t rootpiby2 = 1.2533141373155003; // Sqrt(pi/2)
133  static const Double_t sqpibylog2 = 2.12893403886245236; //Sqrt( pi/Log(2) )
134 
135  if (code==1) {
136  Double_t A = x.min(rangeName);
137  Double_t B = x.max(rangeName);
138 
139  Double_t result = 0;
140 
141 
142  //If tail==0 the function becomes gaussian, thus we return a gassian integral
143  if (TMath::Abs(tail) < 1.e-7) {
144 
145  Double_t xscale = sqrt2*width;
146 
147  result = rootpiby2*width*(TMath::Erf((B-peak)/xscale)-TMath::Erf((A-peak)/xscale));
148 
149  return result;
150 
151  }
152 
153  // If the range is not defined correctly the function becomes complex
154  Double_t log_argument_A = ( (peak - A)*tail + width ) / width ;
155  Double_t log_argument_B = ( (peak - B)*tail + width ) / width ;
156 
157  //lower limit
158  if ( log_argument_A < 1.e-7) {
159  log_argument_A = 1.e-7;
160  }
161 
162  //upper limit
163  if ( log_argument_B < 1.e-7) {
164  log_argument_B = 1.e-7;
165  }
166 
167  Double_t term1 = TMath::ASinH( tail * sqlog4 );
168  Double_t term1_2 = term1 * term1;
169 
170  //Calculate the error function arguments
171  Double_t erf_termA = ( term1_2 - log4 * TMath::Log( log_argument_A ) ) / ( 2 * term1 * sqlog2 );
172  Double_t erf_termB = ( term1_2 - log4 * TMath::Log( log_argument_B ) ) / ( 2 * term1 * sqlog2 );
173 
174  result = 0.5 / tail * width * term1 * ( TMath::Erf(erf_termB) - TMath::Erf(erf_termA)) * sqpibylog2;
175 
176  return result;
177 
178  } else if (code==2) {
179  Double_t A = x.min(rangeName);
180  Double_t B = x.max(rangeName);
181 
182  Double_t result = 0;
183 
184 
185  //If tail==0 the function becomes gaussian, thus we return a gassian integral
186  if (TMath::Abs(tail) < 1.e-7) {
187 
188  Double_t xscale = sqrt2*width;
189 
190  result = rootpiby2*width*(TMath::Erf((B-x)/xscale)-TMath::Erf((A-x)/xscale));
191 
192  return result;
193 
194  }
195 
196  // If the range is not defined correctly the function becomes complex
197  Double_t log_argument_A = ( (A - x)*tail + width ) / width;
198  Double_t log_argument_B = ( (B - x)*tail + width ) / width;
199 
200  //lower limit
201  if ( log_argument_A < 1.e-7) {
202  log_argument_A = 1.e-7;
203  }
204 
205  //upper limit
206  if ( log_argument_B < 1.e-7) {
207  log_argument_B = 1.e-7;
208  }
209 
210  Double_t term1 = TMath::ASinH( tail * sqlog4 );
211  Double_t term1_2 = term1 * term1;
212 
213  //Calculate the error function arguments
214  Double_t erf_termA = ( term1_2 - log4 * TMath::Log( log_argument_A ) ) / ( 2 * term1 * sqlog2 );
215  Double_t erf_termB = ( term1_2 - log4 * TMath::Log( log_argument_B ) ) / ( 2 * term1 * sqlog2 );
216 
217  result = 0.5 / tail * width * term1 * ( TMath::Erf(erf_termB) - TMath::Erf(erf_termA)) * sqpibylog2;
218 
219  return result;
220 
221  }
222 
223  // Emit fatal error
224  coutF(Eval) << "Error in RooNovosibirsk::analyticalIntegral" << std::endl;
225 
226  // Put dummy return here to avoid compiler warnings
227  return 1.0 ;
228 }
RooRealProxy peak
static double B[]
Double_t Log(Double_t x)
Definition: TMath.h:526
#define assert(cond)
Definition: unittest.h:542
int Int_t
Definition: RtypesCore.h:41
STL namespace.
static double A[]
RooRealProxy width
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
Double_t x[n]
Definition: legend1.C:17
ClassImp(RooNovosibirsk) RooNovosibirsk
Double_t ASinH(Double_t)
Definition: TMath.cxx:67
Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral. ...
Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=0) const
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported...
Double_t Erf(Double_t x)
Computation of the error function erf(x).
Definition: TMath.cxx:187
RooRealProxy tail
#define coutF(a)
Definition: RooMsgService.h:36
Double_t evaluate() const
If tail=eta=0 the Belle distribution becomes gaussian.
RooRealProxy x
Double_t Exp(Double_t x)
Definition: TMath.h:495
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
#define name(a, b)
Definition: linkTestLib0.cpp:5
Vc_INTRINSIC Vc_CONST m256 exponent(param256 v)
Definition: vectorhelper.h:37
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
Double_t min(const char *rname=0) const
Definition: RooRealProxy.h:56
double result[121]
Bool_t matchArgs(const RooArgSet &allDeps, RooArgSet &numDeps, const RooArgProxy &a) const
Utility function for use in getAnalyticalIntegral().
Double_t max(const char *rname=0) const
Definition: RooRealProxy.h:57
double log(double)