38 ClassImp(RooGaussModel);
42 RooGaussModel::RooGaussModel(
const char *name,
const char *title, RooRealVar& xIn,
43 RooAbsReal& _mean, RooAbsReal& _sigma) :
44 RooResolutionModel(name,title,xIn),
47 mean(
"mean",
"Mean",this,_mean),
48 sigma(
"sigma",
"Width",this,_sigma),
49 msf(
"msf",
"Mean Scale Factor",this,(RooRealVar&)RooRealConstant::value(1)),
50 ssf(
"ssf",
"Sigma Scale Factor",this,(RooRealVar&)RooRealConstant::value(1))
56 RooGaussModel::RooGaussModel(
const char *name,
const char *title, RooRealVar& xIn,
57 RooAbsReal& _mean, RooAbsReal& _sigma,
59 RooResolutionModel(name,title,xIn),
62 mean(
"mean",
"Mean",this,_mean),
63 sigma(
"sigma",
"Width",this,_sigma),
64 msf(
"msf",
"Mean Scale Factor",this,_msSF),
65 ssf(
"ssf",
"Sigma Scale Factor",this,_msSF)
71 RooGaussModel::RooGaussModel(
const char *name,
const char *title, RooRealVar& xIn,
72 RooAbsReal& _mean, RooAbsReal& _sigma,
73 RooAbsReal& _meanSF, RooAbsReal& _sigmaSF) :
74 RooResolutionModel(name,title,xIn),
77 mean(
"mean",
"Mean",this,_mean),
78 sigma(
"sigma",
"Width",this,_sigma),
79 msf(
"msf",
"Mean Scale Factor",this,_meanSF),
80 ssf(
"ssf",
"Sigma Scale Factor",this,_sigmaSF)
86 RooGaussModel::RooGaussModel(
const RooGaussModel& other,
const char* name) :
87 RooResolutionModel(other,name),
88 _flatSFInt(other._flatSFInt),
89 _asympInt(other._asympInt),
90 mean(
"mean",this,other.mean),
91 sigma(
"sigma",this,other.sigma),
92 msf(
"msf",this,other.msf),
93 ssf(
"ssf",this,other.ssf)
100 RooGaussModel::~RooGaussModel()
106 Int_t RooGaussModel::basisCode(
const char* name)
const
108 if (!TString(
"exp(-@0/@1)").CompareTo(name))
return expBasisPlus ;
109 if (!TString(
"exp(@0/@1)").CompareTo(name))
return expBasisMinus ;
110 if (!TString(
"exp(-abs(@0)/@1)").CompareTo(name))
return expBasisSum ;
111 if (!TString(
"exp(-@0/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisPlus ;
112 if (!TString(
"exp(@0/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisMinus ;
113 if (!TString(
"exp(-abs(@0)/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisSum ;
114 if (!TString(
"exp(-@0/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisPlus ;
115 if (!TString(
"exp(@0/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisMinus ;
116 if (!TString(
"exp(-abs(@0)/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisSum ;
117 if (!TString(
"(@0/@1)*exp(-@0/@1)").CompareTo(name))
return linBasisPlus ;
118 if (!TString(
"(@0/@1)*(@0/@1)*exp(-@0/@1)").CompareTo(name))
return quadBasisPlus ;
119 if (!TString(
"exp(-@0/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisPlus;
120 if (!TString(
"exp(@0/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisMinus;
121 if (!TString(
"exp(-abs(@0)/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisSum;
122 if (!TString(
"exp(-@0/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisPlus;
123 if (!TString(
"exp(@0/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisMinus;
124 if (!TString(
"exp(-abs(@0)/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisSum;
130 Double_t RooGaussModel::evaluate()
const
133 static Double_t root2(std::sqrt(2.)) ;
134 static Double_t root2pi(std::sqrt(2.*std::atan2(0.,-1.))) ;
135 static Double_t rootpi(std::sqrt(std::atan2(0.,-1.))) ;
137 BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
138 BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;
140 Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0 ;
141 if (basisType == coshBasis && _basisCode!=noBasis ) {
142 Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
143 if (dGamma==0) basisType = expBasis;
146 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
147 Double_t xprime = (x-(mean*msf))/(sigma*ssf) ;
148 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 1st form" << endl ;
150 Double_t result = std::exp(-0.5*xprime*xprime)/(sigma*ssf*root2pi) ;
151 if (_basisCode!=0 && basisSign==Both) result *= 2 ;
157 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 2nd form" << endl ;
162 Double_t omega = (basisType==sinBasis || basisType==cosBasis) ? ((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;
163 Double_t dgamma = (basisType==sinhBasis || basisType==coshBasis) ? ((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;
164 Double_t _x = omega *tau ;
165 Double_t _y = tau*dgamma/2;
166 Double_t xprime = (x-(mean*msf))/tau ;
167 Double_t c = (sigma*ssf)/(root2*tau) ;
168 Double_t u = xprime/(2*c) ;
170 if (basisType==expBasis || (basisType==cosBasis && _x==0.)) {
171 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 3d form tau=" << tau << endl ;
173 if (basisSign!=Minus) result += evalCerf(0,-u,c).real();
174 if (basisSign!=Plus) result += evalCerf(0, u,c).real();
175 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::getVal(" << GetName() <<
") got nan during case 1 " << endl; }
180 if (basisType==sinBasis) {
181 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 4th form omega = " << omega <<
", tau = " << tau << endl ;
183 if (_x==0.)
return result ;
184 if (basisSign!=Minus) result += -evalCerf(-_x,-u,c).imag();
185 if (basisSign!=Plus) result += -evalCerf( _x, u,c).imag();
186 if (TMath::IsNaN(result)) cxcoutE(Tracing) <<
"RooGaussModel::getVal(" << GetName() <<
") got nan during case 3 " << endl;
191 if (basisType==cosBasis) {
192 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 5th form omega = " << omega <<
", tau = " << tau << endl ;
194 if (basisSign!=Minus) result += evalCerf(-_x,-u,c).real();
195 if (basisSign!=Plus) result += evalCerf( _x, u,c).real();
196 if (TMath::IsNaN(result)) cxcoutE(Tracing) <<
"RooGaussModel::getVal(" << GetName() <<
") got nan during case 4 " << endl;
201 if (basisType==coshBasis || basisType ==sinhBasis) {
202 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 8th form tau = " << tau << endl ;
204 int sgn = ( basisType == coshBasis ? +1 : -1 );
205 if (basisSign!=Minus) result += 0.5*( evalCerf(0,-u,c*(1-_y)).real()+sgn*evalCerf(0,-u,c*(1+_y)).real()) ;
206 if (basisSign!=Plus) result += 0.5*(sgn*evalCerf(0, u,c*(1-_y)).real()+ evalCerf(0, u,c*(1+_y)).real()) ;
207 if (TMath::IsNaN(result)) cxcoutE(Tracing) <<
"RooGaussModel::getVal(" << GetName() <<
") got nan during case 8 " << endl;
212 if (basisType==linBasis) {
213 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 6th form tau = " << tau << endl ;
214 R__ASSERT(basisSign==Plus);
216 Double_t f0 = std::exp(-xprime+c*c) * RooMath::erfc(-u+c);
217 Double_t f1 = std::exp(-u*u);
218 return (xprime - 2*c*c)*f0 + (2*c/rootpi)*f1 ;
222 if (basisType==quadBasis) {
223 if (verboseEval()>2) cout <<
"RooGaussModel::evaluate(" << GetName() <<
") 7th form tau = " << tau << endl ;
224 R__ASSERT(basisSign==Plus);
226 Double_t f0 = std::exp(-xprime+c*c) * RooMath::erfc(-u+c);
227 Double_t f1 = std::exp(-u*u);
228 Double_t x2c2 = xprime - 2*c*c;
229 return ( x2c2*x2c2*f0 + (2*c/rootpi)*x2c2*f1 + 2*c*c*f0 );
238 Int_t RooGaussModel::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
247 if (matchArgs(allVars,analVars,RooArgSet(convVar(),ssf.arg())))
return 2 ;
250 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
275 if (matchArgs(allVars,analVars,RooArgSet(convVar(),ssf.arg()))) {
280 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
289 Double_t RooGaussModel::analyticalIntegral(Int_t code,
const char* rangeName)
const
291 static const Double_t root2 = std::sqrt(2.) ;
293 static const Double_t rootpi = std::sqrt(std::atan2(0.0,-1.0));
294 Double_t ssfInt(1.0) ;
297 R__ASSERT(code==1||code==2) ;
298 if (code==2) ssfInt = (ssf.max(rangeName)-ssf.min(rangeName)) ;
300 BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
301 BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;
304 Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0 ;
305 if (basisType == coshBasis && _basisCode!=noBasis ) {
306 Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
307 if (dGamma==0) basisType = expBasis;
309 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
310 Double_t xscale = root2*(sigma*ssf);
311 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 1st form" << endl ;
313 Double_t xpmin = (x.min(rangeName)-(mean*msf))/xscale ;
314 Double_t xpmax = (x.max(rangeName)-(mean*msf))/xscale ;
320 result = 0.5*(RooMath::erf(xpmax)-RooMath::erf(xpmin)) ;
323 if (_basisCode!=0 && basisSign==Both) result *= 2 ;
325 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") got nan during case 1 " << endl; }
326 return result*ssfInt ;
330 Double_t omega = ((basisType==sinBasis)||(basisType==cosBasis)) ? ((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;
331 Double_t dgamma =((basisType==sinhBasis)||(basisType==coshBasis)) ? ((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;
335 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 2nd form" << endl ;
340 Double_t c = (sigma*ssf)/(root2*tau) ;
341 Double_t xpmin = (x.min(rangeName)-(mean*msf))/tau ;
342 Double_t xpmax = (x.max(rangeName)-(mean*msf))/tau ;
343 Double_t umin = xpmin/(2*c) ;
344 Double_t umax = xpmax/(2*c) ;
346 if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
347 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 3d form tau=" << tau << endl ;
349 if (basisSign!=Minus) result += evalCerfInt(+1,0,tau,-umin,-umax,c).real();
350 if (basisSign!=Plus) result += evalCerfInt(-1,0,tau, umin, umax,c).real();
351 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") got nan during case 3 " << endl; }
352 return result*ssfInt ;
356 Double_t _x = omega * tau ;
357 Double_t _y = tau*dgamma/2;
359 if (basisType==sinBasis) {
360 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 4th form omega = " << omega <<
", tau = " << tau << endl ;
362 if (_x==0)
return result*ssfInt ;
363 if (basisSign!=Minus) result += -1*evalCerfInt(+1,-_x,tau,-umin,-umax,c).imag();
364 if (basisSign!=Plus) result += -1*evalCerfInt(-1, _x,tau, umin, umax,c).imag();
365 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") got nan during case 4 " << endl; }
366 return result*ssfInt ;
370 if (basisType==cosBasis) {
371 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 5th form omega = " << omega <<
", tau = " << tau << endl ;
373 if (basisSign!=Minus) result += evalCerfInt(+1,-_x,tau,-umin,-umax,c).real();
374 if (basisSign!=Plus) result += evalCerfInt(-1, _x,tau, umin, umax,c).real();
375 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") got nan during case 5 " << endl; }
376 return result*ssfInt ;
381 if (basisType==coshBasis || basisType == sinhBasis) {
382 if (verboseEval()>0) {cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 8th form tau=" << tau << endl ; }
384 int sgn = ( basisType == coshBasis ? +1 : -1 );
385 if (basisSign!=Minus) result += 0.5*( evalCerfInt(+1,0,tau/(1-_y),-umin,-umax,c*(1-_y)).real()+ sgn*evalCerfInt(+1,0,tau/(1+_y),-umin,-umax,c*(1+_y)).real());
386 if (basisSign!=Plus) result += 0.5*(sgn*evalCerfInt(-1,0,tau/(1-_y), umin, umax,c*(1-_y)).real()+ evalCerfInt(-1,0,tau/(1+_y), umin, umax,c*(1+_y)).real());
387 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") got nan during case 6 " << endl; }
388 return result*ssfInt ;
392 if (basisType==linBasis) {
393 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 6th form tau=" << tau << endl ;
395 Double_t f0 = RooMath::erf(-umax) - RooMath::erf(-umin);
396 Double_t f1 = std::exp(-umax*umax) - std::exp(-umin*umin);
398 Double_t tmp1 = std::exp(-xpmax)*RooMath::erfc(-umax + c);
399 Double_t tmp2 = std::exp(-xpmin)*RooMath::erfc(-umin + c);
401 Double_t f2 = tmp1 - tmp2;
402 Double_t f3 = xpmax*tmp1 - xpmin*tmp2;
404 Double_t expc2 = std::exp(c*c);
408 (1 - 2*c*c)*expc2*f2 +
414 if (basisType==quadBasis) {
415 if (verboseEval()>0) cout <<
"RooGaussModel::analyticalIntegral(" << GetName() <<
") 7th form tau=" << tau << endl ;
417 Double_t f0 = RooMath::erf(-umax) - RooMath::erf(-umin);
419 Double_t tmpA1 = std::exp(-umax*umax);
420 Double_t tmpA2 = std::exp(-umin*umin);
422 Double_t f1 = tmpA1 - tmpA2;
423 Double_t f2 = umax*tmpA1 - umin*tmpA2;
425 Double_t tmpB1 = std::exp(-xpmax)*RooMath::erfc(-umax + c);
426 Double_t tmpB2 = std::exp(-xpmin)*RooMath::erfc(-umin + c);
428 Double_t f3 = tmpB1 - tmpB2;
429 Double_t f4 = xpmax*tmpB1 - xpmin*tmpB2;
430 Double_t f5 = xpmax*xpmax*tmpB1 - xpmin*xpmin*tmpB2;
432 Double_t expc2 = std::exp(c*c);
435 (4*c/rootpi)*((1-c*c)*f1 + c*f2) +
436 (2*c*c*(2*c*c-1) + 2)*expc2*f3 - (4*c*c-2)*expc2*f4 + expc2*f5
448 std::complex<Double_t> RooGaussModel::evalCerfApprox(Double_t _x, Double_t u, Double_t c)
450 static const Double_t rootpi= std::sqrt(std::atan2(0.,-1.));
451 const std::complex<Double_t> z(_x * c, u + c);
452 const std::complex<Double_t> zc(u + c, - _x * c);
453 const std::complex<Double_t> zsq((z.real() + z.imag()) * (z.real() - z.imag()),
454 2. * z.real() * z.imag());
455 const std::complex<Double_t> v(-zsq.real() - u*u, -zsq.imag());
456 const std::complex<Double_t> ev = std::exp(v);
457 const std::complex<Double_t> mez2zcrootpi = -std::exp(zsq)/(zc*rootpi);
459 return 2. * (ev * (mez2zcrootpi + 1.));
464 std::complex<Double_t> RooGaussModel::evalCerfInt(Double_t sign, Double_t _x, Double_t tau, Double_t umin, Double_t umax, Double_t c)
const
466 std::complex<Double_t> diff(2., 0.);
468 diff = evalCerf(_x,umin,c);
469 diff -= evalCerf(_x,umax,c);
470 diff += RooMath::erf(umin) - RooMath::erf(umax);
473 diff *= std::complex<Double_t>(1., _x);
474 diff *= tau / (1.+_x*_x);
480 Int_t RooGaussModel::getGenerator(
const RooArgSet& directVars, RooArgSet &generateVars, Bool_t )
const
482 if (matchArgs(directVars,generateVars,x))
return 1 ;
488 void RooGaussModel::generateEvent(Int_t code)
491 Double_t xmin = x.min();
492 Double_t xmax = x.max();
493 TRandom *generator = RooRandom::randomGenerator();
495 Double_t xgen = generator->Gaus(mean*msf,sigma*ssf);
496 if (xgen<xmax && xgen>xmin) {