77 :
RooAbsPdf(
name, title), x_(
"x",
"Dependent", this,
x), x0_(
"x0",
"X0", this, x0),
78 sigmaL_(
"sigmaL",
"Left Sigma", this, sigmaL), sigmaR_(
"sigmaR",
"Right Sigma", this, sigmaR),
79 alphaL_{
"alphaL",
"Left Alpha", this, alphaL}, nL_{
"nL",
"Left Order", this, nL},
80 alphaR_{std::make_unique<
RooRealProxy>(
"alphaR",
"Right Alpha", this, alphaR)},
81 nR_{std::make_unique<
RooRealProxy>(
"nR",
"Right Order", this, nR)}
105 :
RooAbsPdf(
name, title), x_(
"x",
"Dependent", this,
x), x0_(
"x0",
"X0", this, x0),
106 sigmaL_(
"sigmaL",
"Left Sigma", this, sigmaLR), sigmaR_(
"sigmaR",
"Right Sigma", this, sigmaLR),
107 alphaL_{
"alphaL",
"Left Alpha", this, alphaL}, nL_{
"nL",
"Left Order", this, nL},
108 alphaR_{std::make_unique<
RooRealProxy>(
"alphaR",
"Right Alpha", this, alphaR)},
109 nR_{std::make_unique<
RooRealProxy>(
"nR",
"Right Order", this, nR)}
132 :
RooAbsPdf(
name, title), x_(
"x",
"Dependent", this,
x), x0_(
"x0",
"X0", this, x0),
133 sigmaL_{
"sigmaL",
"Left Sigma", this, sigmaLR}, sigmaR_{
"sigmaR",
"Right Sigma", this, sigmaLR},
134 alphaL_{
"alphaL",
"Left Alpha", this, alpha},
135 nL_{
"nL",
"Left Order", this,
n}
138 alphaR_ = std::make_unique<RooRealProxy>(
"alphaR",
"Right Alpha",
this, alpha);
139 nR_ = std::make_unique<RooRealProxy>(
"nR",
"Right Order",
this,
n);
152 :
RooAbsPdf(other,
name), x_(
"x", this, other.x_), x0_(
"x0", this, other.x0_),
153 sigmaL_(
"sigmaL", this, other.sigmaL_),
154 sigmaR_(
"sigmaR", this, other.sigmaR_), alphaL_{
"alphaL", this, other.alphaL_},
155 nL_{
"nL", this, other.nL_},
156 alphaR_{other.alphaR_ ? std::make_unique<
RooRealProxy>(
"alphaR", this, *other.alphaR_) : nullptr},
157 nR_{other.nR_ ? std::make_unique<
RooRealProxy>(
"nR", this, *other.nR_) : nullptr}
165inline double evaluateCrystalBallTail(
double t,
double alpha,
double n)
167 double a = std::pow(
n / alpha,
n) * std::exp(-0.5 * alpha * alpha);
168 double b =
n / alpha - alpha;
170 return a / std::pow(
b - t,
n);
173inline double integrateGaussian(
double sigmaL,
double sigmaR,
double tmin,
double tmax)
175 constexpr double sqrtPiOver2 = 1.2533141373;
176 constexpr double sqrt2 = 1.4142135624;
178 const double sigmaMin = tmin < 0 ? sigmaL : sigmaR;
179 const double sigmaMax = tmax < 0 ? sigmaL : sigmaR;
181 return sqrtPiOver2 * (sigmaMax * std::erf(tmax / sqrt2) - sigmaMin * std::erf(tmin / sqrt2));
184inline double integrateTailLogVersion(
double sigma,
double alpha,
double n,
double tmin,
double tmax)
186 double a = std::pow(
n / alpha,
n) * exp(-0.5 * alpha * alpha);
187 double b =
n / alpha - alpha;
189 return a *
sigma * (log(
b - tmin) - log(
b - tmax));
192inline double integrateTailRegular(
double sigma,
double alpha,
double n,
double tmin,
double tmax)
194 double a = std::pow(
n / alpha,
n) * exp(-0.5 * alpha * alpha);
195 double b =
n / alpha - alpha;
197 return a *
sigma / (1.0 -
n) * (1.0 / (std::pow(
b - tmin,
n - 1.0)) - 1.0 / (std::pow(
b - tmax,
n - 1.0)));
207 const double x0 =
x0_;
208 const double sigmaL = std::abs(
sigmaL_);
209 const double sigmaR = std::abs(
sigmaR_);
210 double alphaL = std::abs(
alphaL_);
212 double alphaR =
alphaR_ ? std::abs(*
alphaR_) : std::numeric_limits<double>::infinity();
213 double nR =
nR_ ? *
nR_ : 0.0;
218 std::swap(alphaL, alphaR);
222 const double t = (
x - x0) / (
x < x0 ? sigmaL : sigmaR);
225 return evaluateCrystalBallTail(t, alphaL, nL);
226 }
else if (t <= alphaR) {
227 return std::exp(-0.5 * t * t);
229 return evaluateCrystalBallTail(-t, alphaR, nR);
246 const double x0 =
x0_;
247 const double sigmaL = std::abs(
sigmaL_);
248 const double sigmaR = std::abs(
sigmaR_);
249 double alphaL = std::abs(
alphaL_);
251 double alphaR =
alphaR_ ? std::abs(*
alphaR_) : std::numeric_limits<double>::infinity();
252 double nR =
nR_ ? *
nR_ : 0.0;
257 std::swap(alphaL, alphaR);
261 constexpr double switchToLogThreshold = 1.0e-05;
265 const double tmin = (
xmin - x0) / (
xmin < x0 ? sigmaL : sigmaR);
266 const double tmax = (
xmax - x0) / (
xmax < x0 ? sigmaL : sigmaR);
270 if (tmin < -alphaL) {
271 auto integrateTailL = std::abs(nL - 1.0) < switchToLogThreshold ? integrateTailLogVersion : integrateTailRegular;
272 result += integrateTailL(sigmaL, alphaL, nL, tmin, std::min(tmax, -alphaL));
275 auto integrateTailR = std::abs(nR - 1.0) < switchToLogThreshold ? integrateTailLogVersion : integrateTailRegular;
276 result += integrateTailR(sigmaR, alphaR, nR, -tmax, std::min(-tmin, -alphaR));
278 if (tmin < alphaR && tmax > -alphaL) {
279 result += integrateGaussian(sigmaL, sigmaR, std::max(tmin, -alphaL), std::min(tmax, alphaR));
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Bool_t matchArgs(const RooArgSet &allDeps, RooArgSet &numDeps, const RooArgProxy &a) const
Utility function for use in getAnalyticalIntegral().
RooArgSet is a container object that can hold multiple RooAbsArg objects.
PDF implementing the generalized Asymmetrical Double-Sided Crystall Ball line shape.
std::unique_ptr< RooRealProxy > nR_
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
Double_t evaluate() const
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
virtual Double_t maxVal(Int_t code) const
Return maximum value for set of observables identified by code assigned in getMaxVal.
virtual Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=0) const
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported.
std::unique_ptr< RooRealProxy > alphaR_
virtual Int_t getMaxVal(const RooArgSet &vars) const
Advertise that we know the maximum of self for given (m0,alpha,n,sigma).
double min(const char *rname=0) const
Query lower limit of range. This requires the payload to be RooAbsRealLValue or derived.
double max(const char *rname=0) const
Query upper limit of range. This requires the payload to be RooAbsRealLValue or derived.
void checkRangeOfParameters(const RooAbsReal *callingClass, std::initializer_list< const RooAbsReal * > pars, double min=-std::numeric_limits< double >::max(), double max=std::numeric_limits< double >::max(), bool limitsInAllowedRange=false, std::string const &extraMessage="")
Check if the parameters have a range, and warn if the range extends below / above the set limits.