33 #include "RooRealConstant.h" 34 #include "RooRandom.h" 40 #if __cplusplus < 201102L 41 #define myunique_ptr std::auto_ptr 53 static const Double_t rootpi(sqrt(TMath::Pi())) ;
55 std::complex<double> evalApprox(Double_t x,
const std::complex<double>& z) {
60 static const std::complex<double> mi(0,-1);
61 std::complex<double> zp = mi*(z-x);
62 std::complex<double> zsq = zp*zp;
63 std::complex<double> v = -zsq - x*x;
64 std::complex<double> iz(z.imag()+x,z.real()-x);
65 return exp(v)*(exp(zsq)/(iz*rootpi) + 1.)*2. ;
69 Double_t evalRe(Double_t x,
const std::complex<double>& z) {
70 Double_t re = z.real()-x;
71 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,34,8) 72 return (re>-5.0) ? RooMath::faddeeva_fast(std::complex<double>(-z.imag(),re)).real()*exp(-x*x)
73 : evalApprox(x,z).real() ;
75 return (re>-5.0) ? RooMath::FastComplexErrFunc(RooComplex(-z.imag(),re)).re()*exp(-x*x)
76 : evalApprox(x,z).real() ;
81 Double_t evalIm(Double_t x,
const std::complex<double>& z) {
82 Double_t re = z.real()-x;
83 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,34,8) 84 return (re>-5.0) ? RooMath::faddeeva_fast(std::complex<double>(-z.imag(),re)).imag()*exp(-x*x)
85 : evalApprox(x,z).imag() ;
87 return (re>-5.0) ? RooMath::FastComplexErrFunc(RooComplex(-z.imag(),re)).im()*exp(-x*x)
88 : evalApprox(x,z).imag() ;
98 , RooAbsReal& _mean, RooAbsReal& _sigma )
99 : RooResolutionModel(name, title, x),
102 eff(
"eff",
"Spline describing efficiency",this,_eff),
103 mean(
"mean",
"Mean",this,_mean),
104 sigma(
"sigma",
"Width",this,_sigma),
105 msf(
"msf",
"Mean Scale Factor",this,RooRealConstant::value(1.0)),
106 ssf(
"ssf",
"Sigma Scale Factor",this,RooRealConstant::value(1.0))
109 myunique_ptr<RooArgSet> svar(
eff.arg().getVariables() );
110 assert( svar->contains( convVar() ) );
116 , RooAbsReal& _mean, RooAbsReal& _sigma
117 , RooAbsReal& _meanSF, RooAbsReal& _sigmaSF)
118 : RooResolutionModel(name,title,x),
121 eff(
"eff",
"Spline describing efficiency",this,_eff),
122 mean(
"mean",
"Mean",this,_mean),
123 sigma(
"sigma",
"Width",this,_sigma),
124 msf(
"msf",
"Mean Scale Factor",this,_meanSF),
125 ssf(
"ssf",
"Sigma Scale Factor",this,_sigmaSF)
128 myunique_ptr<RooArgSet> svar(
eff.arg().getVariables() );
129 assert( svar->contains( convVar() ) );
135 : RooResolutionModel(other,name),
137 _flatSFInt(other._flatSFInt),
138 eff(
"eff",this,other.eff),
139 mean(
"mean",this,other.mean),
140 sigma(
"sigma",this,other.sigma),
141 msf(
"msf",this,other.msf),
142 ssf(
"ssf",this,other.ssf)
155 if (!TString(
"exp(-@0/@1)" ).CompareTo(name))
return expBasis;
156 if (!TString(
"exp(-@0/@1)*sin(@0*@2)" ).CompareTo(name))
return sinBasis;
157 if (!TString(
"exp(-@0/@1)*cos(@0*@2)" ).CompareTo(name))
return cosBasis;
158 if (!TString(
"exp(-@0/@1)*cosh(@0*@2/2)").CompareTo(name))
return coshBasis;
159 if (!TString(
"exp(-@0/@1)*sinh(@0*@2/2)").CompareTo(name))
return sinhBasis;
173 return new RooArgSet(convVar());
178 Double_t scale, Double_t offset,
179 const std::complex<double>& z)
const 189 Double_t tau = (
basisCode!=
noBasis) ? ((RooAbsReal*)basis().getParameter(1))->getVal() : 0 ;
194 Double_t scale =
sigma*
ssf*TMath::Sqrt2();
195 Double_t u = (x-
mean*
msf)/scale;
198 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") 1st form" << endl ;
200 if (TMath::IsNaN(
eff))
201 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
202 <<
") got nan during efficiency " << endl;
203 return eff * exp(-u*u)/(scale*rootpi) ;
208 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") 2nd form" << endl ;
211 std::complex<double> z(
double(1)/tau, -omega ); z*=0.5*scale;
214 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") basisCode = " <<
basisCode <<
" z = " << z <<
", u = " << u << endl ;
222 val += z.imag()!=0 ? evalIm(u,z) : 0;
226 std::complex<double> y( scale * dGamma / 4 , 0 );
227 val += ( evalRe(u,z-y)
234 if (TMath::IsNaN(val))
235 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
236 <<
") got nan during basisCode = " <<
basisCode << endl;
238 if (TMath::IsNaN(_eff))
239 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
240 <<
") got nan during efficiency " << endl;
253 Double_t scale =
sigma*
ssf*TMath::Sqrt2();
254 Double_t u = (x-
mean*
msf)/scale;
257 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") 1st form" << endl ;
259 if (TMath::IsNaN(
eff))
260 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
261 <<
") got nan during efficiency " << endl;
262 return eff * exp(-u*u)/(scale*rootpi) ;
267 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") 2nd form" << endl ;
270 std::complex<double> z(
double(1)/tau, -omega ); z*=0.5*scale;
273 if (verboseEval()>2) cout <<
"RooGaussEfficiencyModel::evaluate(" << GetName() <<
") basisCode = " <<
basisCode <<
" z = " << z <<
", u = " << u << endl ;
281 val += z.imag()!=0 ? evalIm(u,z) : 0;
285 std::complex<double> y( scale * dGamma / 4 , 0 );
286 val += ( evalRe(u,z-y)
293 if (TMath::IsNaN(val))
294 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
295 <<
") got nan during basisCode = " <<
basisCode << endl;
297 if (TMath::IsNaN(_eff))
298 cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::evaluate(" << GetName()
299 <<
") got nan during efficiency " << endl;
312 if (
_flatSFInt && matchArgs(allVars,analVars,RooArgSet(convVar(),
ssf.arg())))
return 2 ;
313 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
323 if (
_flatSFInt && matchArgs(allVars,analVars,RooArgSet(convVar(),
ssf.arg())))
return 2 ;
324 if (matchArgs(allVars,analVars,convVar()))
return 1 ;
334 assert(code==1||code==2) ;
335 Double_t ssfInt( code==2 ? (
ssf.max(rangeName)-
ssf.min(rangeName)) : 1.0 );
338 Double_t tau = (
basisCode!=
noBasis) ? ((RooAbsReal*)basis().getParameter(1))->getVal() : 0 ;
343 Double_t scale =
sigma*
ssf*TMath::Sqrt2();
345 Double_t umin = (x.min(rangeName)-offset)/scale;
346 Double_t umax = (x.max(rangeName)-offset)/scale;
349 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") 1st form" << endl ;
350 Double_t result = 0.5*(RooMath::erf( umax )-RooMath::erf( umin )) ;
351 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") got nan during case 1 " << endl; }
352 return result*ssfInt ;
355 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") 2nd form" << endl ;
359 std::complex<double> z(
double(1)/tau, -omega ); z=0.5*z*scale;
361 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") basisCode = " <<
basisCode <<
" z = " << z << endl ;
367 result +=
evalInt(umin,umax,scale,offset,z).real();
370 result += z.imag()!=0 ?
evalInt(umin,umax,scale,offset,z).imag() : 0 ;
374 std::complex<double> y( scale * dGamma / 4 , 0 );
375 result += 0.5 * (
evalInt(umin,umax,scale,offset,z-y).real()
382 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::analyticalIntegral(" 383 << GetName() <<
") got nan for basisCode = " 386 return scale*result*ssfInt;
393 assert(code==1||code==2) ;
394 Double_t ssfInt( code==2 ? (
ssf.max(rangeName)-
ssf.min(rangeName)) : 1.0 );
402 Double_t scale =
sigma*
ssf*TMath::Sqrt2();
404 Double_t umin = (x.min(rangeName)-offset)/scale;
405 Double_t umax = (x.max(rangeName)-offset)/scale;
408 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") 1st form" << endl ;
409 Double_t result = 0.5*(RooMath::erf( umax )-RooMath::erf( umin )) ;
410 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") got nan during case 1 " << endl; }
411 return result*ssfInt ;
414 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") 2nd form" << endl ;
418 std::complex<double> z(
double(1)/tau, -omega ); z=0.5*z*scale;
420 if (verboseEval()>0) cout <<
"RooGaussEfficiencyModel::analyticalIntegral(" << GetName() <<
") basisCode = " <<
basisCode <<
" z = " << z << endl ;
426 result +=
evalInt(umin,umax,scale,offset,z).real();
429 result += z.imag()!=0 ?
evalInt(umin,umax,scale,offset,z).imag() : 0 ;
433 std::complex<double> y( scale * dGamma / 4 , 0 );
434 result += 0.5 * (
evalInt(umin,umax,scale,offset,z-y).real()
441 if (TMath::IsNaN(result)) { cxcoutE(Tracing) <<
"RooGaussEfficiencyModel::analyticalIntegral(" 442 << GetName() <<
") got nan for basisCode = " 445 return scale*result*ssfInt;
451 (
const RooAbsAnaConvPdf& convPdf,
const RooArgSet &vars,
const RooDataSet *prototype,
452 const RooArgSet* auxProto, Bool_t verbose)
const 460 return (!TString(convVar().GetName()).CompareTo(arg.GetName()))
461 || RooResolutionModel::isDirectGenSafe(arg);
467 if (matchArgs(directVars,generateVars,x)) {
return 1 ; }
475 coutE(InputArguments) <<
"RooGaussEfficiencyModel::generateEvent(" 476 << GetName()<<
"): argument \"code\" can only have value 1" 481 Double_t xmin = x.min();
482 Double_t xmax = x.max();
485 TRandom *generator = RooRandom::randomGenerator();
487 Double_t xgen = generator->Gaus(
m,
s);
488 if (xgen<xmax && xgen>xmin) {
virtual RooAbsGenContext * modelGenContext(const RooAbsAnaConvPdf &convPdf, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
virtual RooArgSet * observables() const
virtual Double_t evaluate() const
RooGaussEfficiencyModel()
std::complex< double > evalInt(Double_t xmin, Double_t xmax, Double_t scale, Double_t offset, const std::complex< double > &z) const
Bool_t isDirectGenSafe(const RooAbsArg &arg) const
void generateEvent(Int_t code)
virtual ~RooGaussEfficiencyModel()
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName) const
Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK) const
virtual std::complex< double > productAnalyticalIntegral(Double_t umin, Double_t umax, Double_t scale, Double_t offset, const std::complex< double > &z) const =0
virtual const RooAbsReal * efficiency() const
virtual Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=0) const
virtual Int_t basisCode(const char *name) const