Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooBukinPdf.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitModels *
4  * @(#)root/roofit:$Id$
5  * Authors: *
6  * RW, Ruddick William UC Colorado wor@slac.stanford.edu *
7  * *
8  * Copyright (c) 2000-2005, Regents of the University of California *
9  * and Stanford University. All rights reserved. *
10  * *
11  * Redistribution and use in source and binary forms, *
12  * with or without modification, are permitted according to the terms *
13  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
14  *****************************************************************************/
15 
16 /** \class RooBukinPdf
17  \ingroup Roofit
18 
19 The RooBukinPdf implements the NovosibirskA function. For the parameters, see
20 RooBukinPdf().
21 
22 Credits:
23 May 26, 2003.
24 A.Bukin, Budker INP, Novosibirsk
25 
26 \image html RooBukin.png
27 http://www.slac.stanford.edu/BFROOT/www/Organization/CollabMtgs/2003/detJuly2003/Tues3a/bukin.ps
28 **/
29 
30 #include "RooBukinPdf.h"
31 #include "RooFit.h"
32 #include "RooRealVar.h"
33 #include "BatchHelpers.h"
34 #include "RooVDTHeaders.h"
35 #include "RooHelpers.h"
36 
37 #include <cmath>
38 using namespace std;
39 
40 ClassImp(RooBukinPdf);
41 
42 ////////////////////////////////////////////////////////////////////////////////
43 /// Construct a Bukin PDF.
44 /// \param name The name of the PDF for RooFit's bookeeping.
45 /// \param title The title for e.g. plotting it.
46 /// \param _x The variable.
47 /// \param _Xp The peak position.
48 /// \param _sigp The peak width as FWHM divided by 2*sqrt(2*log(2))=2.35
49 /// \param _xi Peak asymmetry. Use values around 0.
50 /// \param _rho1 Left tail. Use slightly negative starting values.
51 /// \param _rho2 Right tail. Use slightly positive starting values.
52 RooBukinPdf::RooBukinPdf(const char *name, const char *title,
53  RooAbsReal& _x, RooAbsReal& _Xp,
54  RooAbsReal& _sigp, RooAbsReal& _xi,
55  RooAbsReal& _rho1, RooAbsReal& _rho2) :
56  // The two addresses refer to our first dependent variable and
57  // parameter, respectively, as declared in the rdl file
58  RooAbsPdf(name, title),
59  x("x","x",this,_x),
60  Xp("Xp","Xp",this,_Xp),
61  sigp("sigp","sigp",this,_sigp),
62  xi("xi","xi",this,_xi),
63  rho1("rho1","rho1",this,_rho1),
64  rho2("rho2","rho2",this,_rho2)
65 {
66  RooHelpers::checkRangeOfParameters(this, {&_sigp}, 0.0);
67  RooHelpers::checkRangeOfParameters(this, {&_rho1},-1.0, 0.0);
68  RooHelpers::checkRangeOfParameters(this, {&_rho2}, 0.0, 1.0);
69  RooHelpers::checkRangeOfParameters(this, {&_xi}, -1.0, 1.0);
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Copy a Bukin PDF.
74 RooBukinPdf::RooBukinPdf(const RooBukinPdf& other, const char *name):
75  RooAbsPdf(other,name),
76  x("x",this,other.x),
77  Xp("Xp",this,other.Xp),
78  sigp("sigp",this,other.sigp),
79  xi("xi",this,other.xi),
80  rho1("rho1",this,other.rho1),
81  rho2("rho2",this,other.rho2)
82 
83 {
84 }
85 
86 ////////////////////////////////////////////////////////////////////////////////
87 /// Implementation
88 
89 Double_t RooBukinPdf::evaluate() const
90 {
91  const double consts = 2*sqrt(2*log(2.0));
92  double r1=0,r2=0,r3=0,r4=0,r5=0,hp=0;
93  double x1 = 0,x2 = 0;
94  double fit_result = 0;
95 
96  hp=sigp*consts;
97  r3=log(2.);
98  r4=sqrt(xi*xi+1);
99  r1=xi/r4;
100 
101  if(fabs(xi) > exp(-6.)){
102  r5=xi/log(r4+xi);
103  }
104  else
105  r5=1;
106 
107  x1 = Xp + (hp / 2) * (r1-1);
108  x2 = Xp + (hp / 2) * (r1+1);
109 
110  //--- Left Side
111  if(x < x1){
112  r2=rho1*(x-x1)*(x-x1)/(Xp-x1)/(Xp-x1)-r3 + 4 * r3 * (x-x1)/hp * r5 * r4/(r4-xi)/(r4-xi);
113  }
114 
115 
116  //--- Center
117  else if(x < x2) {
118  if(fabs(xi) > exp(-6.)) {
119  r2=log(1 + 4 * xi * r4 * (x-Xp)/hp)/log(1+2*xi*(xi-r4));
120  r2=-r3*r2*r2;
121  }
122  else{
123  r2=-4*r3*(x-Xp)*(x-Xp)/hp/hp;
124  }
125  }
126 
127 
128  //--- Right Side
129  else {
130  r2=rho2*(x-x2)*(x-x2)/(Xp-x2)/(Xp-x2)-r3 - 4 * r3 * (x-x2)/hp * r5 * r4/(r4+xi)/(r4+xi);
131  }
132 
133  if(fabs(r2) > 100){
134  fit_result = 0;
135  }
136  else{
137  //---- Normalize the result
138  fit_result = exp(r2);
139  }
140 
141  return fit_result;
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////////////
145 
146 namespace {
147 //Author: Emmanouil Michalainas, CERN 26 JULY 2019
148 
149 template<class Tx, class TXp, class TSigp, class Txi, class Trho1, class Trho2>
150 void compute( size_t batchSize,
151  double * __restrict output,
152  Tx X, TXp XP, TSigp SP, Txi XI, Trho1 R1, Trho2 R2)
153 {
154  const double r3 = log(2.0);
155  const double r6 = exp(-6.0);
156  const double r7 = 2*sqrt(2*log(2.0));
157 
158  for (size_t i=0; i<batchSize; i++) {
159  const double r1 = XI[i]/sqrt(XI[i]*XI[i]+1);
160  const double r4 = sqrt(XI[i]*XI[i]+1);
161  const double hp = 1 / (SP[i]*r7);
162  const double x1 = XP[i] + 0.5*SP[i]*r7*(r1-1);
163  const double x2 = XP[i] + 0.5*SP[i]*r7*(r1+1);
164 
165  double r5 = 1.0;
166  if (XI[i]>r6 || XI[i]<-r6) r5 = XI[i]/log(r4+XI[i]);
167 
168  double factor=1, y=X[i]-x1, Yp=XP[i]-x1, yi=r4-XI[i], rho=R1[i];
169  if (X[i]>=x2) {
170  factor = -1;
171  y = X[i]-x2;
172  Yp = XP[i]-x2;
173  yi = r4+XI[i];
174  rho = R2[i];
175  }
176 
177  output[i] = rho*y*y/Yp/Yp -r3 + factor*4*r3*y*hp*r5*r4/yi/yi;
178  if (X[i]>=x1 && X[i]<x2) {
179  output[i] = _rf_fast_log(1 + 4*XI[i]*r4*(X[i]-XP[i])*hp) / _rf_fast_log(1 +2*XI[i]*( XI[i]-r4 ));
180  output[i] *= -output[i]*r3;
181  }
182  if (X[i]>=x1 && X[i]<x2 && XI[i]<r6 && XI[i]>-r6) {
183  output[i] = -4*r3*(X[i]-XP[i])*(X[i]-XP[i])*hp*hp;
184  }
185  }
186  for (size_t i=0; i<batchSize; i++) {
187  output[i] = _rf_fast_exp(output[i]);
188  }
189 }
190 };
191 
192 
193 RooSpan<double> RooBukinPdf::evaluateBatch(std::size_t begin, std::size_t batchSize) const {
194  using namespace BatchHelpers;
195 
196  EvaluateInfo info = getInfo( {&x, &Xp, &sigp, &xi, &rho1, &rho2}, begin, batchSize );
197  if (info.nBatches == 0) {
198  return {};
199  }
200  auto output = _batchData.makeWritableBatchUnInit(begin, batchSize);
201  auto xData = x.getValBatch(begin, info.size);
202 
203  if (info.nBatches==1 && !xData.empty()) {
204  compute(info.size, output.data(), xData.data(),
205  BracketAdapter<double> (Xp),
206  BracketAdapter<double> (sigp),
207  BracketAdapter<double> (xi),
208  BracketAdapter<double> (rho1),
209  BracketAdapter<double> (rho2));
210  }
211  else {
212  compute(info.size, output.data(),
213  BracketAdapterWithMask (x,x.getValBatch(begin,info.size)),
214  BracketAdapterWithMask (Xp,Xp.getValBatch(begin,info.size)),
215  BracketAdapterWithMask (sigp,sigp.getValBatch(begin,info.size)),
216  BracketAdapterWithMask (xi,xi.getValBatch(begin,info.size)),
217  BracketAdapterWithMask (rho1,rho1.getValBatch(begin,info.size)),
218  BracketAdapterWithMask (rho2,rho2.getValBatch(begin,info.size)));
219  }
220  return output;
221 }