72enum BasisSign { Both = 0, Plus = +1, Minus = -1 };
74BasisType getBasisType(
int basisCode)
76 return static_cast<BasisType
>(basisCode == 0 ? 0 : (basisCode / 10) + 1);
109 mean(
"mean",
"Mean",this,_mean),
110 sigma(
"sigma",
"Width",this,_sigma),
111 msf(
"msf",
"Mean Scale Factor",this,_meanSF),
112 ssf(
"ssf",
"Sigma Scale Factor",this,_sigmaSF)
120 _flatSFInt(other._flatSFInt),
121 _asympInt(other._asympInt),
122 mean(
"mean",this,other.mean),
124 msf(
"msf",this,other.msf),
125 ssf(
"ssf",this,other.ssf)
133 std::string str =
name;
136 str.erase(remove(str.begin(),str.end(),
' '),str.end());
138 if (str ==
"exp(-@0/@1)")
return expBasisPlus ;
139 if (str ==
"exp(@0/@1)")
return expBasisMinus ;
140 if (str ==
"exp(-abs(@0)/@1)")
return expBasisSum ;
141 if (str ==
"exp(-@0/@1)*sin(@0*@2)")
return sinBasisPlus ;
142 if (str ==
"exp(@0/@1)*sin(@0*@2)")
return sinBasisMinus ;
143 if (str ==
"exp(-abs(@0)/@1)*sin(@0*@2)")
return sinBasisSum ;
144 if (str ==
"exp(-@0/@1)*cos(@0*@2)")
return cosBasisPlus ;
145 if (str ==
"exp(@0/@1)*cos(@0*@2)")
return cosBasisMinus ;
146 if (str ==
"exp(-abs(@0)/@1)*cos(@0*@2)")
return cosBasisSum ;
147 if (str ==
"(@0/@1)*exp(-@0/@1)")
return linBasisPlus ;
148 if (str ==
"(@0/@1)*(@0/@1)*exp(-@0/@1)")
return quadBasisPlus ;
149 if (str ==
"exp(-@0/@1)*cosh(@0*@2/2)")
return coshBasisPlus;
150 if (str ==
"exp(@0/@1)*cosh(@0*@2/2)")
return coshBasisMinus;
151 if (str ==
"exp(-abs(@0)/@1)*cosh(@0*@2/2)")
return coshBasisSum;
152 if (str ==
"exp(-@0/@1)*sinh(@0*@2/2)")
return sinhBasisPlus;
153 if (str ==
"exp(@0/@1)*sinh(@0*@2/2)")
return sinhBasisMinus;
154 if (str ==
"exp(-abs(@0)/@1)*sinh(@0*@2/2)")
return sinhBasisSum;
165 double param1 = arg1 ? arg1->
getVal() : 0.0;
166 double param2 = arg2 ? arg2->getVal() : 0.0;
172 std::span<double> output = ctx.
output();
173 std::size_t
size = output.size();
175 auto xVals = ctx.
at(
x);
176 auto meanVals = ctx.
at(
mean);
177 auto meanSfVals = ctx.
at(
msf);
178 auto sigmaVals = ctx.
at(
sigma);
179 auto sigmaSfVals = ctx.
at(
ssf);
183 const double zeroVal = 0.0;
184 auto param1Vals = param1 ? ctx.
at(param1) : std::span<const double>{&zeroVal, 1};
185 auto param2Vals = param2 ? ctx.
at(param2) : std::span<const double>{&zeroVal, 1};
187 BasisType basisType = getBasisType(
_basisCode);
188 double basisSign =
_basisCode - 10 * (basisType - 1) - 2;
194 if (basisType == expBasis) {
195 std::array<double, 1> extraArgs{basisSign};
197 {xVals, meanVals, meanSfVals, sigmaVals, sigmaSfVals, param1Vals}, extraArgs);
202 if (xVals.size() !=
size || meanVals.size() != 1 || meanSfVals.size() != 1 || sigmaVals.size() != 1 ||
203 sigmaSfVals.size() != 1 || param1Vals.size() != 1 || param2Vals.size() != 1) {
207 for (
unsigned int i = 0; i <
size; ++i) {
208 output[i] =
evaluate(xVals[i], meanVals[0] * meanSfVals[0], sigmaVals[0] * sigmaSfVals[0], param1Vals[0],
216 static double root2(std::sqrt(2.)) ;
217 static double root2pi(std::sqrt(2.*std::atan2(0.,-1.))) ;
218 static double rootpi(std::sqrt(std::atan2(0.,-1.))) ;
220 BasisType basisType = getBasisType(
basisCode);
221 BasisSign basisSign = (BasisSign)(
basisCode - 10*(basisType-1) - 2 ) ;
223 double tau = (
basisCode!=noBasis) ? param1 : 0.0;
224 if (basisType == coshBasis &&
basisCode!=noBasis ) {
225 double dGamma = param2;
226 if (dGamma==0) basisType = expBasis;
229 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
231 double result = std::exp(-0.5*xprime*xprime)/(
sigma*root2pi) ;
242 double omega = (basisType==sinBasis || basisType==cosBasis) ? param2 : 0 ;
243 double dgamma = (basisType==sinhBasis || basisType==coshBasis) ? param2 : 0 ;
244 double _x = omega *tau ;
245 double _y = tau*dgamma/2;
246 double xprime = (
x-
mean)/tau ;
247 double c =
sigma/(root2*tau) ;
248 double u = xprime/(2*
c) ;
250 if (basisType==expBasis || (basisType==cosBasis && _x==0.)) {
252 if (basisSign!=Minus)
result += evalCerf(0,-u,
c).real();
253 if (basisSign!=Plus)
result += evalCerf(0, u,
c).real();
258 if (basisType==sinBasis) {
260 if (_x==0.)
return result ;
261 if (basisSign!=Minus)
result += -evalCerf(-_x,-u,
c).imag();
262 if (basisSign!=Plus)
result += -evalCerf( _x, u,
c).imag();
267 if (basisType==cosBasis) {
269 if (basisSign!=Minus)
result += evalCerf(-_x,-u,
c).real();
270 if (basisSign!=Plus)
result += evalCerf( _x, u,
c).real();
275 if (basisType==coshBasis || basisType ==sinhBasis) {
277 int sgn = ( basisType == coshBasis ? +1 : -1 );
278 if (basisSign!=Minus)
result += 0.5*( evalCerf(0,-u,
c*(1-_y)).real()+sgn*evalCerf(0,-u,
c*(1+_y)).real()) ;
279 if (basisSign!=Plus)
result += 0.5*(sgn*evalCerf(0, u,
c*(1-_y)).real()+ evalCerf(0, u,
c*(1+_y)).real()) ;
284 if (basisType==linBasis) {
288 double f1 = std::exp(-u*u);
289 return (xprime - 2*
c*
c)*f0 + (2*
c/rootpi)*
f1 ;
293 if (basisType==quadBasis) {
297 double f1 = std::exp(-u*u);
298 double x2c2 = xprime - 2*
c*
c;
299 return ( x2c2*x2c2*f0 + (2*
c/rootpi)*x2c2*
f1 + 2*
c*
c*f0 );
361 static const double root2 = std::sqrt(2.) ;
363 static const double rootpi = std::sqrt(std::atan2(0.0,-1.0));
368 if (code==2) ssfInt = (
ssf.
max(rangeName)-
ssf.
min(rangeName)) ;
371 BasisSign basisSign = (BasisSign)(
_basisCode - 10*(basisType-1) - 2 ) ;
375 if (basisType == coshBasis &&
_basisCode!=noBasis ) {
377 if (dGamma==0) basisType = expBasis;
379 if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
381 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 1st form" << std::endl ;
383 double xpmin = (
x.
min(rangeName)-(
mean*
msf))/xscale ;
384 double xpmax = (
x.
max(rangeName)-(
mean*
msf))/xscale ;
400 double omega = ((basisType==sinBasis)||(basisType==cosBasis)) ? (
static_cast<RooAbsReal*
>(
basis().
getParameter(2)))->getVal() : 0 ;
401 double dgamma =((basisType==sinhBasis)||(basisType==coshBasis)) ? (
static_cast<RooAbsReal*
>(
basis().
getParameter(2)))->getVal() : 0 ;
405 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 2nd form" << std::endl ;
413 double umin = xpmin/(2*
c) ;
414 double umax = xpmax/(2*
c) ;
416 if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
417 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 3d form tau=" << tau << std::endl ;
426 double _x = omega * tau ;
427 double _y = tau*dgamma/2;
429 if (basisType==sinBasis) {
430 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 4th form omega = " << omega <<
", tau = " << tau << std::endl ;
432 if (_x==0)
return result*ssfInt ;
440 if (basisType==cosBasis) {
441 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 5th form omega = " << omega <<
", tau = " << tau << std::endl ;
451 if (basisType==coshBasis || basisType == sinhBasis) {
452 if (
verboseEval()>0) {std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 8th form tau=" << tau << std::endl ; }
454 int sgn = ( basisType == coshBasis ? +1 : -1 );
455 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());
456 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());
462 if (basisType==linBasis) {
463 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 6th form tau=" << tau << std::endl ;
466 double f1 = std::exp(-umax*umax) - std::exp(-umin*umin);
471 double f2 = tmp1 - tmp2;
472 double f3 = xpmax*tmp1 - xpmin*tmp2;
474 double expc2 = std::exp(
c*
c);
478 (1 - 2*
c*
c)*expc2*f2 +
484 if (basisType==quadBasis) {
485 if (
verboseEval()>0) std::cout <<
"RooGaussModel::analyticalIntegral(" <<
GetName() <<
") 7th form tau=" << tau << std::endl ;
489 double tmpA1 = std::exp(-umax*umax);
490 double tmpA2 = std::exp(-umin*umin);
492 double f1 = tmpA1 - tmpA2;
493 double f2 = umax*tmpA1 - umin*tmpA2;
498 double f3 = tmpB1 - tmpB2;
499 double f4 = xpmax*tmpB1 - xpmin*tmpB2;
500 double f5 = xpmax*xpmax*tmpB1 - xpmin*xpmin*tmpB2;
502 double expc2 = std::exp(
c*
c);
505 (4*
c/rootpi)*((1-
c*
c)*
f1 +
c*f2) +
506 (2*
c*
c*(2*
c*
c-1) + 2)*expc2*f3 - (4*
c*
c-2)*expc2*f4 + expc2*f5
518 std::complex<double> diff(2., 0.);
520 diff = evalCerf(_x,umin,
c);
521 diff -= evalCerf(_x,umax,
c);
525 diff *= std::complex<double>(1., _x);
526 diff *= tau / (1.+_x*_x);
534 return matchArgs(directVars,generateVars,
x) ? 1 : 0;
547 if (xgen<xmax && xgen>
xmin) {
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
static int verboseEval()
Return global level of verbosity for p.d.f. evaluations.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
virtual void doEval(RooFit::EvalContext &) const
Base function for computing multiple values of a RooAbsReal.
bool matchArgs(const RooArgSet &allDeps, RooArgSet &analDeps, const RooArgProxy &a, const Proxies &... proxies) const
RooArgSet is a container object that can hold multiple RooAbsArg objects.
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
RooBatchCompute::Config config(RooAbsArg const *arg) const
Class RooGaussModel implements a RooResolutionModel that models a Gaussian distribution.
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
std::complex< double > evalCerfInt(double sign, double wt, double tau, double umin, double umax, double c) const
void doEval(RooFit::EvalContext &) const override
Base function for computing multiple values of a RooAbsReal.
Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=nullptr) const override
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported.
void generateEvent(Int_t code) override
Interface for generation of an event using the algorithm corresponding to the specified code.
bool canComputeBatchWithCuda() const override
Int_t basisCode(const char *name) const override
Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool staticInitOK=true) const override
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
double analyticalIntegral(Int_t code, const char *rangeName) const override
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
static std::complex< double > erfc(const std::complex< double > z)
complex erfc function
static std::complex< double > erf(const std::complex< double > z)
complex erf function
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Provides static functions to create and keep track of RooRealVar constants.
RooResolutionModel is the base class for PDFs that represent a resolution model that can be convolute...
Int_t _basisCode
Identifier code for selected basis function.
RooAbsRealLValue & convVar() const
Return the convolution variable of the resolution model.
const RooFormulaVar & basis() const
RooTemplateProxy< RooAbsRealLValue > x
Dependent/convolution variable.
double max(const char *rname=nullptr) const
Query upper limit of range. This requires the payload to be RooAbsRealLValue or derived.
const T & arg() const
Return reference to object held in proxy.
double min(const char *rname=nullptr) const
Query lower limit of range. This requires the payload to be RooAbsRealLValue or derived.
const char * GetName() const override
Returns name of object.
This is the base class for the ROOT Random number generators.
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
void compute(Config cfg, Computer comp, std::span< double > output, VarSpan vars, ArgSpan extraArgs={})
STD::complex< double > evalCerf(double swt, double u, double c)
STD::complex< double > evalCerfApprox(double _x, double u, double c)
use the approximation: erf(z) = exp(-z*z)/(STD::sqrt(pi)*z) to explicitly cancel the divergent exp(y*...