41 ClassImp(RooGExpModel);
45 RooGExpModel::RooGExpModel(
const char *name,
const char *title, RooRealVar& xIn,
46 RooAbsReal& _sigma, RooAbsReal& _rlife,
47 Bool_t nlo, Type type) :
48 RooResolutionModel(name,title,xIn),
49 sigma(
"sigma",
"Width",this,_sigma),
50 rlife(
"rlife",
"Life time",this,_rlife),
51 ssf(
"ssf",
"Sigma Scale Factor",this,(RooRealVar&)RooRealConstant::value(1)),
52 rsf(
"rsf",
"RLife Scale Factor",this,(RooRealVar&)RooRealConstant::value(1)),
53 _flip(type==Flipped),_nlo(nlo), _flatSFInt(kFALSE), _asympInt(kFALSE)
59 RooGExpModel::RooGExpModel(
const char *name,
const char *title, RooRealVar& xIn,
60 RooAbsReal& _sigma, RooAbsReal& _rlife,
62 Bool_t nlo, Type type) :
63 RooResolutionModel(name,title,xIn),
64 sigma(
"sigma",
"Width",this,_sigma),
65 rlife(
"rlife",
"Life time",this,_rlife),
66 ssf(
"ssf",
"Sigma Scale Factor",this,_rsSF),
67 rsf(
"rsf",
"RLife Scale Factor",this,_rsSF),
77 RooGExpModel::RooGExpModel(
const char *name,
const char *title, RooRealVar& xIn,
78 RooAbsReal& _sigma, RooAbsReal& _rlife,
79 RooAbsReal& _sigmaSF, RooAbsReal& _rlifeSF,
80 Bool_t nlo, Type type) :
81 RooResolutionModel(name,title,xIn),
82 sigma(
"sigma",
"Width",this,_sigma),
83 rlife(
"rlife",
"Life time",this,_rlife),
84 ssf(
"ssf",
"Sigma Scale Factor",this,_sigmaSF),
85 rsf(
"rsf",
"RLife Scale Factor",this,_rlifeSF),
95 RooGExpModel::RooGExpModel(
const RooGExpModel& other,
const char* name) :
96 RooResolutionModel(other,name),
97 sigma(
"sigma",this,other.sigma),
98 rlife(
"rlife",this,other.rlife),
99 ssf(
"ssf",this,other.ssf),
100 rsf(
"rsf",this,other.rsf),
103 _flatSFInt(other._flatSFInt),
104 _asympInt(other._asympInt)
111 RooGExpModel::~RooGExpModel()
117 Int_t RooGExpModel::basisCode(
const char* name)
const
119 if (!TString(
"exp(-@0/@1)").CompareTo(name))
return expBasisPlus ;
120 if (!TString(
"exp(@0/@1)").CompareTo(name))
return expBasisMinus ;
121 if (!TString(
"exp(-abs(@0)/@1)").CompareTo(name))
return expBasisSum ;
122 if (!TString(
"exp(-@0/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisPlus ;
123 if (!TString(
"exp(@0/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisMinus ;
124 if (!TString(
"exp(-abs(@0)/@1)*sin(@0*@2)").CompareTo(name))
return sinBasisSum ;
125 if (!TString(
"exp(-@0/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisPlus ;
126 if (!TString(
"exp(@0/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisMinus ;
127 if (!TString(
"exp(-abs(@0)/@1)*cos(@0*@2)").CompareTo(name))
return cosBasisSum ;
128 if (!TString(
"exp(-@0/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisPlus;
129 if (!TString(
"exp(@0/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisMinus;
130 if (!TString(
"exp(-abs(@0)/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasisSum;
131 if (!TString(
"exp(-@0/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisPlus;
132 if (!TString(
"exp(@0/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisMinus;
133 if (!TString(
"exp(-abs(@0)/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasisSum;
139 Double_t RooGExpModel::evaluate()
const
141 static Double_t root2(sqrt(2.)) ;
145 BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
146 BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;
148 Double_t fsign = _flip?-1:1 ;
150 Double_t sig = sigma*ssf ;
151 Double_t rtau = rlife*rsf ;
153 Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0. ;
155 if (basisType == coshBasis && _basisCode!=noBasis ) {
156 Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
157 if (dGamma==0) basisType = expBasis;
161 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
162 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName() <<
") 1st form" << endl ;
164 Double_t expArg = sig*sig/(2*rtau*rtau) + fsign*x/rtau ;
168 result = 1/(2*rtau) * exp(expArg) * RooMath::erfc(sig/(root2*rtau) + fsign*x/(root2*sig));
172 result = 1/(2*rtau) * exp(expArg + logErfC(sig/(root2*rtau) + fsign*x/(root2*sig))) ;
185 if (_basisCode!=0 && basisSign==Both) result *= 2 ;
192 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName() <<
") 2nd form" << endl ;
196 Double_t omega = (basisType!=expBasis)?((RooAbsReal*)basis().getParameter(2))->getVal():0. ;
199 if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
200 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName() <<
") 3d form tau=" << tau << endl ;
202 if (basisSign!=Minus) result += calcDecayConv(+1,tau,sig,rtau,fsign) ;
203 if (basisSign!=Plus) result += calcDecayConv(-1,tau,sig,rtau,fsign) ;
209 Double_t wt = omega *tau ;
210 if (basisType==sinBasis) {
211 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName() <<
") 4th form omega = "
212 << omega <<
", tau = " << tau << endl ;
214 if (wt==0.)
return result ;
215 if (basisSign!=Minus) result += -1*calcSinConv(+1,sig,tau,omega,rtau,fsign).imag() ;
216 if (basisSign!=Plus) result += -1*calcSinConv(-1,sig,tau,omega,rtau,fsign).imag() ;
222 if (basisType==cosBasis) {
223 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName()
224 <<
") 5th form omega = " << omega <<
", tau = " << tau << endl ;
226 if (basisSign!=Minus) result += calcSinConv(+1,sig,tau,omega,rtau,fsign).real() ;
227 if (basisSign!=Plus) result += calcSinConv(-1,sig,tau,omega,rtau,fsign).real() ;
234 if (basisType==sinhBasis) {
235 Double_t dgamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
237 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName()
238 <<
") 6th form = " << dgamma <<
", tau = " << tau << endl;
243 Double_t tau1 = 1/(1/tau-dgamma/2) ;
244 Double_t tau2 = 1/(1/tau+dgamma/2) ;
245 if (basisSign!=Minus) result += 0.5*(calcDecayConv(+1,tau1,sig,rtau,fsign)-calcDecayConv(+1,tau2,sig,rtau,fsign));
247 if (basisSign!=Plus) result += 0.5*(calcDecayConv(-1,tau2,sig,rtau,fsign)-calcDecayConv(-1,tau1,sig,rtau,fsign));
254 if (basisType==coshBasis) {
255 Double_t dgamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
257 if (verboseEval()>2) cout <<
"RooGExpModel::evaluate(" << GetName()
258 <<
") 7th form = " << dgamma <<
", tau = " << tau << endl;
263 Double_t tau1 = 1/(1/tau-dgamma/2) ;
264 Double_t tau2 = 1/(1/tau+dgamma/2) ;
265 if (basisSign!=Minus) result += 0.5*(calcDecayConv(+1,tau1,sig,rtau,fsign)+calcDecayConv(+1,tau2,sig,rtau,fsign));
267 if (basisSign!=Plus) result += 0.5*(calcDecayConv(-1,tau1,sig,rtau,fsign)+calcDecayConv(-1,tau2,sig,rtau,fsign));
279 Double_t RooGExpModel::logErfC(Double_t xx)
const
286 ans=log(t)+(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+
287 t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))));
289 ans=log(2.0-t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+
290 t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277))))))))));
297 std::complex<Double_t> RooGExpModel::calcSinConv(Double_t sign, Double_t sig, Double_t tau, Double_t omega, Double_t rtau, Double_t fsign)
const
299 static Double_t root2(sqrt(2.)) ;
301 Double_t s1= -sign*x/tau;
303 Double_t c1= sig/(root2*tau);
304 Double_t u1= s1/(2*c1);
306 Double_t c2= sig/(root2*rtau);
307 Double_t u2= fsign*s2/(2*c2) ;
310 std::complex<Double_t> eins(1,0);
311 std::complex<Double_t> k(1/tau,sign*omega);
314 return (evalCerf(-sign*omega*tau,u1,c1)+std::complex<Double_t>(evalCerfRe(u2,c2),0)*fsign*sign) / (eins + k*fsign*sign*rtau) ;
323 Double_t RooGExpModel::calcSinConv(Double_t sign, Double_t sig, Double_t tau, Double_t rtau, Double_t fsign)
const
325 static Double_t root2(sqrt(2.)) ;
327 Double_t s1= -sign*x/tau;
329 Double_t c1= sig/(root2*tau);
330 Double_t u1= s1/(2*c1);
332 Double_t c2= sig/(root2*rtau);
333 Double_t u2= fsign*s2/(2*c2) ;
338 return (evalCerfRe(u1,c1)+evalCerfRe(u2,c2)*fsign*sign) / (eins + k*fsign*sign*rtau) ;
345 Double_t RooGExpModel::calcDecayConv(Double_t sign, Double_t tau, Double_t sig, Double_t rtau, Double_t fsign)
const
348 static Double_t root2(sqrt(2.)) ;
349 static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
350 static Double_t rootpi(sqrt(atan2(0.,-1.)));
362 if ((sign<0)&&(fabs(tau-rtau)<tau/260)) {
364 Double_t MeanTau=0.5*(tau+rtau);
365 if (fabs(xp/MeanTau)>300) {
369 cFly=1./(MeanTau*MeanTau*root2pi) *
370 exp(-(-xp/MeanTau-sig*sig/(2*MeanTau*MeanTau)))
371 *(sig*exp(-1/(2*sig*sig)*TMath::Power((sig*sig/MeanTau+xp),2))
372 -(sig*sig/MeanTau+xp)*(rootpi/root2)*RooMath::erfc(sig/(root2*MeanTau)+xp/(root2*sig)));
375 Double_t epsilon=0.5*(tau-rtau);
376 Double_t a=sig/(root2*MeanTau)+xp/(root2*sig);
377 cFly += 1./(MeanTau*MeanTau)
378 *exp(-(-xp/MeanTau-sig*sig/(2*MeanTau*MeanTau)))
379 *0.5/MeanTau*epsilon*epsilon*
380 (exp(-a*a)*(sig/MeanTau*root2/rootpi
381 -(4*a*sig*sig)/(2*rootpi*MeanTau*MeanTau)
382 +(-4/rootpi+8*a*a/rootpi)/6
383 *TMath::Power(sig/(root2*MeanTau),3)
384 +2/rootpi*(sig*sig/(MeanTau*MeanTau)+xp/MeanTau)*
385 (sig/(root2*MeanTau)-a*(sig*sig)/(2*MeanTau*MeanTau))
386 +2/rootpi*((3*sig*sig)/(2*MeanTau*MeanTau)+xp/MeanTau+
387 0.5*TMath::Power(sig*sig/(MeanTau*MeanTau)+xp/MeanTau,2))*sig/(root2*MeanTau))
388 -(2*sig*sig/(MeanTau*MeanTau)+xp/MeanTau+(sig*sig/(MeanTau*MeanTau)+xp/MeanTau)*
389 (3*sig*sig/(2*MeanTau*MeanTau)+xp/MeanTau)
390 +TMath::Power(sig*sig/(MeanTau*MeanTau)+xp/MeanTau,3)/6)*RooMath::erfc(a));
395 Double_t expArg1 = sig*sig/(2*tau*tau)-sign*xp/tau ;
396 Double_t expArg2 = sig*sig/(2*rtau*rtau)+xp/rtau ;
398 Double_t term1, term2 ;
400 term1 = exp(expArg1) *RooMath::erfc(sig/(root2*tau)-sign*xp/(root2*sig)) ;
402 term1 = exp(expArg1+logErfC(sig/(root2*tau)-sign*xp/(root2*sig))) ; ;
405 term2 = exp(expArg2) *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)) ;
407 term2 = exp(expArg2+logErfC(sig/(root2*rtau)+xp/(root2*sig))) ; ;
410 cFly=(term1+sign*term2)/(2*(tau+sign*rtau));
428 Double_t RooGExpModel::calcCoshConv(Double_t sign, Double_t tau, Double_t dgamma, Double_t sig, Double_t rtau, Double_t fsign) const
432 static Double_t root2(sqrt(2.)) ;
433 static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
434 static Double_t rootpi(sqrt(atan2(0.,-1.)));
435 Double_t tau1 = 1/(1/tau-dgamma/2);
436 Double_t tau2 = 1/(1/tau+dgamma/2);
444 xp *= fsign ; // modified FMV,08/13/03
445 sign *= fsign ; // modified FMV,08/13/03
447 cFly=tau1*(exp(sig*sig/(2*tau1*tau1)-sign*xp/tau1)
448 *RooMath::erfc(sig/(root2*tau1)-sign*xp/(root2*sig))
449 +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
450 *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau1+sign*rtau))
451 +tau2*(exp(sig*sig/(2*tau2*tau2)-sign*xp/tau2)
452 *RooMath::erfc(sig/(root2*tau2)-sign*xp/(root2*sig))
453 +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
454 *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau2+sign*rtau));;
463 Double_t RooGExpModel::calcSinhConv(Double_t sign, Double_t sign1, Double_t sign2, Double_t tau, Double_t dgamma, Double_t sig, Double_t rtau, Double_t fsign) const
465 static Double_t root2(sqrt(2.)) ;
466 static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
467 static Double_t rootpi(sqrt(atan2(0.,-1.)));
468 Double_t tau1 = 1/(1/tau-dgamma/2);
469 Double_t tau2 = 1/(1/tau+dgamma/2);
478 xp *= fsign ; // modified FMV,08/13/03
479 sign1 *= fsign ; // modified FMV,08/13/03
480 sign2 *= fsign ; // modified FMV,08/13/03
482 cFly=sign1*tau1*(exp(sig*sig/(2*tau1*tau1)-sign*xp/tau1)
483 *RooMath::erfc(sig/(root2*tau1)-sign*xp/(root2*sig))
484 +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
485 *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau1+sign*rtau))
486 +sign2*tau2*(exp(sig*sig/(2*tau2*tau2)-sign*xp/tau2)
487 *RooMath::erfc(sig/(root2*tau2)-sign*xp/(root2*sig))
488 +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
489 *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau2+sign*rtau));;
496 Int_t RooGExpModel::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars,
const char* )
const
502 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
524 if (matchArgs(allVars,analVars,RooArgSet(convVar(),ssf.arg()))) {
529 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
538 Double_t RooGExpModel::analyticalIntegral(Int_t code,
const char* rangeName)
const
540 static Double_t root2 = sqrt(2.) ;
542 Double_t ssfInt(1.0) ;
545 R__ASSERT(code==1||code==2) ;
547 ssfInt = (ssf.max(rangeName)-ssf.min(rangeName)) ;
550 BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
551 BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;
553 Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0 ;
556 if (basisType == coshBasis && _basisCode!=noBasis ) {
557 Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
558 if (dGamma==0) basisType = expBasis;
560 Double_t fsign = _flip?-1:1 ;
561 Double_t sig = sigma*ssf ;
562 Double_t rtau = rlife*rsf ;
565 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
566 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName() <<
") 1st form" << endl ;
570 Double_t xpmin = x.min(rangeName)/rtau ;
571 Double_t xpmax = x.max(rangeName)/rtau ;
572 Double_t c = sig/(root2*rtau) ;
573 Double_t umin = xpmin/(2*c) ;
574 Double_t umax = xpmax/(2*c) ;
579 result = 0.5*evalCerfInt(-fsign,rtau,fsign*umin,fsign*umax,c)/rtau ;
582 if (_basisCode!=0 && basisSign==Both) result *= 2 ;
584 return result*ssfInt ;
587 Double_t omega = (basisType!=expBasis) ?((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;
592 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName() <<
") 2nd form" << endl ;
597 if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
602 if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,sig,rtau,fsign,rangeName);
603 if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,sig,rtau,fsign,rangeName);
605 return result*ssfInt ;
609 Double_t wt = omega * tau ;
610 if (basisType==sinBasis) {
611 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName() <<
") 4th form omega = "
612 << omega <<
", tau = " << tau << endl ;
615 if (wt==0)
return result ;
619 if (basisSign!=Minus) result += -1*calcSinConvNorm(+1,tau,omega,sig,rtau,fsign,rangeName).imag();
620 if (basisSign!=Plus) result += -1*calcSinConvNorm(-1,tau,omega,sig,rtau,fsign,rangeName).imag();
622 return result*ssfInt ;
626 if (basisType==cosBasis) {
627 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName()
628 <<
") 5th form omega = " << omega <<
", tau = " << tau << endl ;
634 if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,omega,sig,rtau,fsign,rangeName).real();
635 if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,omega,sig,rtau,fsign,rangeName).real();
637 return result*ssfInt ;
640 Double_t dgamma = ((basisType==coshBasis)||(basisType==sinhBasis))?((RooAbsReal*)basis().getParameter(2))->getVal():0 ;
643 if (basisType==sinhBasis) {
644 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName()
645 <<
") 6th form dgamma = " << dgamma <<
", tau = " << tau << endl ;
646 Double_t tau1 = 1/(1/tau-dgamma/2);
647 Double_t tau2 = 1/(1/tau+dgamma/2);
653 if (basisSign!=Minus) result += 0.5*(calcSinConvNorm(+1,tau1,sig,rtau,fsign,rangeName)-
654 calcSinConvNorm(+1,tau2,sig,rtau,fsign,rangeName));
655 if (basisSign!=Plus) result += 0.5*(calcSinConvNorm(-1,tau2,sig,rtau,fsign,rangeName)-
656 calcSinConvNorm(-1,tau1,sig,rtau,fsign,rangeName));
662 if (basisType==coshBasis) {
663 if (verboseEval()>0) cout <<
"RooGExpModel::analyticalIntegral(" << GetName()
664 <<
") 6th form dgamma = " << dgamma <<
", tau = " << tau << endl ;
666 Double_t tau1 = 1/(1/tau-dgamma/2);
667 Double_t tau2 = 1/(1/tau+dgamma/2);
672 if (basisSign!=Minus) result += 0.5*(calcSinConvNorm(+1,tau1,sig,rtau,fsign,rangeName)+
673 calcSinConvNorm(+1,tau2,sig,rtau,fsign,rangeName));
674 if (basisSign!=Plus) result += 0.5*(calcSinConvNorm(-1,tau1,sig,rtau,fsign,rangeName)+
675 calcSinConvNorm(-1,tau2,sig,rtau,fsign,rangeName));
692 std::complex<Double_t> RooGExpModel::calcSinConvNorm(Double_t sign, Double_t tau, Double_t omega,
693 Double_t sig, Double_t rtau, Double_t fsign,
const char* rangeName)
const
695 static Double_t root2(sqrt(2.)) ;
697 Double_t smin1= x.min(rangeName)/tau;
698 Double_t smax1= x.max(rangeName)/tau;
699 Double_t c1= sig/(root2*tau);
700 Double_t umin1= smin1/(2*c1);
701 Double_t umax1= smax1/(2*c1);
702 Double_t smin2= x.min(rangeName)/rtau;
703 Double_t smax2= x.max(rangeName)/rtau;
704 Double_t c2= sig/(root2*rtau);
705 Double_t umin2= smin2/(2*c2) ;
706 Double_t umax2= smax2/(2*c2) ;
708 std::complex<Double_t> eins(1,0);
709 std::complex<Double_t> k(1/tau,sign*omega);
710 std::complex<Double_t> term1 = evalCerfInt(sign,-sign*omega*tau, tau, -sign*umin1, -sign*umax1, c1);
712 std::complex<Double_t> term2 = std::complex<Double_t>(evalCerfInt(-fsign, rtau, fsign*umin2, fsign*umax2, c2)*fsign*sign,0);
713 return (term1+term2)/(eins + k*fsign*sign*rtau) ;
720 Double_t RooGExpModel::calcSinConvNorm(Double_t sign, Double_t tau, Double_t sig, Double_t rtau, Double_t fsign,
const char* rangeName)
const
722 static Double_t root2(sqrt(2.)) ;
724 Double_t smin1= x.min(rangeName)/tau;
725 Double_t smax1= x.max(rangeName)/tau;
726 Double_t c1= sig/(root2*tau);
727 Double_t umin1= smin1/(2*c1);
728 Double_t umax1= smax1/(2*c1);
729 Double_t smin2= x.min(rangeName)/rtau;
730 Double_t smax2= x.max(rangeName)/rtau;
731 Double_t c2= sig/(root2*rtau);
732 Double_t umin2= smin2/(2*c2) ;
733 Double_t umax2= smax2/(2*c2) ;
737 Double_t term1 = evalCerfInt(sign, tau, -sign*umin1, -sign*umax1, c1);
738 Double_t term2 = evalCerfInt(-fsign, rtau, fsign*umin2, fsign*umax2, c2)*fsign*sign;
741 if (fabs(tau-rtau)<1e-10 && fabs(term1+term2)<1e-10) {
742 cout <<
"epsilon method" << endl ;
743 static Double_t epsilon = 1e-4 ;
744 return calcSinConvNorm(sign,tau+epsilon,sig,rtau-epsilon,fsign,rangeName) ;
746 return (term1+term2)/(eins + k*fsign*sign*rtau) ;
752 std::complex<Double_t> RooGExpModel::evalCerfInt(Double_t sign, Double_t wt, Double_t tau, Double_t umin, Double_t umax, Double_t c)
const
754 std::complex<Double_t> diff;
756 diff = std::complex<Double_t>(2,0) ;
758 diff = std::complex<Double_t>(sign,0.)*(evalCerf(wt,umin,c) - evalCerf(wt,umax,c) + RooMath::erf(umin) - RooMath::erf(umax));
760 return std::complex<Double_t>(tau/(1.+wt*wt),0)*std::complex<Double_t>(1,wt)*diff;
766 Double_t RooGExpModel::evalCerfInt(Double_t sign, Double_t tau, Double_t umin, Double_t umax, Double_t c)
const
772 if ((umin<-8 && umax>8)||(umax<-8 && umin>8)) {
776 diff = sign*(evalCerfRe(umin,c) - evalCerfRe(umax,c) + RooMath::erf(umin) - RooMath::erf(umax));
787 std::complex<Double_t> RooGExpModel::evalCerfApprox(Double_t swt, Double_t u, Double_t c)
789 static Double_t rootpi= sqrt(atan2(0.,-1.));
790 std::complex<Double_t> z(swt*c,u+c);
791 std::complex<Double_t> zc(u+c,-swt*c);
792 std::complex<Double_t> zsq= z*z;
793 std::complex<Double_t> v= -zsq - u*u;
795 return std::exp(v)*(-std::exp(zsq)/(zc*rootpi) + 1.)*2.;
800 Int_t RooGExpModel::getGenerator(
const RooArgSet& directVars, RooArgSet &generateVars, Bool_t )
const
802 if (matchArgs(directVars,generateVars,x))
return 1 ;
808 void RooGExpModel::generateEvent(Int_t code)
813 Double_t xgau = RooRandom::randomGenerator()->Gaus(0,(sigma*ssf));
814 Double_t xexp = RooRandom::uniform();
815 if (!_flip) xgen= xgau + (rlife*rsf)*log(xexp);
816 else xgen= xgau - (rlife*rsf)*log(xexp);
817 if (xgen<x.max() && xgen>x.min()) {