120 _pdf(
"inputPdf",
"Function to be converted into a PDF",
this,
inputPdf),
121 _observable(
"observable",
"Observable to integrate over",
this, observable,
true,
true),
122 _relEpsilon(epsilon) {
124 throw std::invalid_argument(std::string(
"RooBinSamplingPDF(") +
GetName()
125 +
"): The PDF " +
_pdf->
GetName() +
" needs to depend on the observable "
138 _observable(
"observable",
this,
other._observable),
139 _relEpsilon(
other._relEpsilon) { }
168 std::span<double> output =
ctx.output();
178 for (
unsigned int i = 0; i <
xValues.size(); ++i) {
180 const auto upperIt = std::upper_bound(boundaries.begin(), boundaries.end(),
x);
181 const unsigned int bin = std::distance(boundaries.begin(),
upperIt) - 1;
184 output[i] =
integrate(
nullptr, boundaries[
bin], boundaries[
bin + 1]) / (boundaries[
bin + 1] - boundaries[
bin]);
196 const double* boundaries = binning.
array();
219 coutE(Plotting) <<
"RooBinSamplingPdf::binBoundaries(" <<
GetName() <<
"): observable '" << obs.
GetName()
220 <<
"' is not the observable of this PDF ('" <<
_observable->
GetName() <<
"')." << std::endl;
224 auto list =
new std::list<double>;
226 if (xlo <= val && val < xhi)
227 list->push_back(val);
242 coutE(Plotting) <<
"RooBinSamplingPdf::plotSamplingHint(" <<
GetName() <<
"): observable '" << obs.
GetName()
243 <<
"' is not the observable of this PDF ('" <<
_observable->
GetName() <<
"')." << std::endl;
247 auto binEdges =
new std::list<double>;
250 for (
unsigned int bin=0, numBins =
static_cast<unsigned int>(binning.numBins());
bin < numBins; ++
bin) {
251 const double low = std::max(binning.binLow(
bin), xlo);
252 const double high = std::min(binning.binHigh(
bin), xhi);
253 const double width = high - low;
260 binEdges->push_back(low + 0.001 *
width);
261 binEdges->push_back(high - 0.001 *
width);
283 _integrator = std::make_unique<ROOT::Math::IntegratorOneDim>(*
this,
334 coutI(NumIntegration) <<
"RooBinSamplingPdf::integrate(" <<
GetName()
335 <<
"): using the analytical integral of " <<
_pdf->
GetName()
336 <<
" to sample the bins instead of the numeric integrator." << std::endl;
376 auto var = dynamic_cast<const RooRealVar*>(arg);
377 return var && var->numBins() > 1;
381 if (precision > 0.) {
383 <<
"Integration over bins was requested, but this is currently only implemented for 1-D fits." << std::endl;
390 return dynamic_cast<const RooAbsRealLValue*>(arg);
394 std::unique_ptr<RooAbsPdf>
newPdf;
396 if (precision > 0.) {
398 newPdf = std::make_unique<RooBinSamplingPdf>(
399 (std::string(
pdf.GetName()) +
"_binSampling").c_str(),
pdf.GetTitle(),
402 precision == 0. && !
pdf.isBinnedDistribution(*
data.get())) {
405 newPdf = std::make_unique<RooBinSamplingPdf>(
406 (std::string(
pdf.GetName()) +
"_binSampling").c_str(),
pdf.GetTitle(),
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
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
Disable all caches for sub-branches in an expression tree.
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
bool isShapeDirty() const
bool inhibitDirty() const
void clearShapeDirty() const
Abstract base class for RooRealVar binning definitions.
virtual Int_t numBoundaries() const =0
virtual double * array() const =0
Abstract base class for binned and unbinned datasets.
Abstract interface for all probability density functions.
RooArgSet const * _normSet
! Normalization set with for above integral
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Int_t getBin(const char *rangeName=nullptr) const override
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
virtual const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const =0
Retrieve binning configuration with given name or default binning.
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
The RooBinSamplingPdf is supposed to be used as an adapter between a continuous PDF and a binned dist...
double integrate(const RooArgSet *normSet, double low, double high) const
Integrate the wrapped PDF over a single bin, with the given norm set and limits.
RooTemplateProxy< RooAbsPdf > _pdf
std::vector< double > _binBoundaries
! Workspace to store data for bin sampling
void doEval(RooFit::EvalContext &) const override
Integrate the PDF over all its bins, and return a batch with those values.
void initializeAnalyticalIntegral(const RooArgSet *normSet) const
Check once whether the wrapped PDF can integrate over the observable analytically.
std::unique_ptr< ROOT::Math::IntegratorOneDim > & integrator() const
Direct access to the unique_ptr holding the integrator that's used to sample the bins.
RooTemplateProxy< RooAbsRealLValue > _observable
std::string _analyticalIntegralRangeName
! Name of the range used for the per-bin analytical integration.
std::unique_ptr< ROOT::Math::IntegratorOneDim > _integrator
! Integrator used to sample bins.
double _relEpsilon
Default integrator precision.
Int_t _analyticalIntegralCode
! Analytical integral code of the wrapped pdf over the observable (-1: not yet determined,...
std::span< const double > binBoundaries() const
Get the bin boundaries for the observable.
static std::unique_ptr< RooAbsPdf > create(RooAbsPdf &pdf, RooAbsData const &data, double precision)
Creates a wrapping RooBinSamplingPdf if appropriate.
double operator()(double x) const
Binding used by the integrator to evaluate the PDF.
double evaluate() const override
Integrate the PDF over the current bin of the observable.
const RooAbsPdf & pdf() const
std::list< double > * plotSamplingHint(RooAbsRealLValue &obs, double xlo, double xhi) const override
Return a list of all bin edges, so the PDF is plotted as a step function.
const RooAbsReal & observable() const
Container class to hold N-dimensional binned data.
Variable that can be changed from the outside.
void setRange(const char *name, double min, double max, bool shared=true)
Set a fit or plotting range.
const char * GetName() const override
Returns name of object.
@ kADAPTIVE
to be used for general functions without singularities