116 _pdf(
"inputPdf",
"Function to be converted into a PDF", this, inputPdf),
120 throw std::invalid_argument(std::string(
"RooBinSamplingPDF(") + GetName()
121 +
"): The PDF " + _pdf->GetName() +
" needs to depend on the observable "
122 + _observable->GetName());
142 const double low =
_observable->getBinning().binLow(bin);
143 const double high =
_observable->getBinning().binHigh(bin);
164 std::span<double> output = ctx.
output();
174 for (
unsigned int i = 0; i < xValues.size(); ++i) {
175 const double x = xValues[i];
176 const auto upperIt = std::upper_bound(boundaries.begin(), boundaries.end(),
x);
177 const unsigned int bin = std::distance(boundaries.begin(), upperIt) - 1;
178 assert(bin < boundaries.size());
180 output[i] =
integrate(
nullptr, boundaries[bin], boundaries[bin + 1]) / (boundaries[bin + 1] - boundaries[bin]);
192 const double* boundaries = binning.
array();
215 coutE(Plotting) <<
"RooBinSamplingPdf::binBoundaries(" <<
GetName() <<
"): observable '" << obs.
GetName()
216 <<
"' is not the observable of this PDF ('" <<
_observable->GetName() <<
"')." << std::endl;
220 auto list =
new std::list<double>;
222 if (xlo <= val && val < xhi)
223 list->push_back(val);
238 coutE(Plotting) <<
"RooBinSamplingPdf::plotSamplingHint(" <<
GetName() <<
"): observable '" << obs.
GetName()
239 <<
"' is not the observable of this PDF ('" <<
_observable->GetName() <<
"')." << std::endl;
243 auto binEdges =
new std::list<double>;
246 for (
unsigned int bin=0, numBins =
static_cast<unsigned int>(binning.numBins()); bin < numBins; ++bin) {
247 const double low = std::max(binning.binLow(bin), xlo);
248 const double high = std::min(binning.binHigh(bin), xhi);
249 const double width = high - low;
256 binEdges->push_back(low + 0.001 * width);
257 binEdges->push_back(high - 0.001 * width);
279 _integrator = std::make_unique<ROOT::Math::IntegratorOneDim>(*
this,
315 std::unique_ptr<RooArgSet> funcObservables(
pdf.getObservables(data) );
316 const bool oneDimAndBinned = (1 == std::count_if(funcObservables->begin(), funcObservables->end(), [](
const RooAbsArg* arg) {
317 auto var = dynamic_cast<const RooRealVar*>(arg);
318 return var && var->numBins() > 1;
321 if (!oneDimAndBinned) {
322 if (precision > 0.) {
324 <<
"Integration over bins was requested, but this is currently only implemented for 1-D fits." << std::endl;
330 auto theObs = std::find_if(funcObservables->begin(), funcObservables->end(), [](
const RooAbsArg* arg){
331 return dynamic_cast<const RooAbsRealLValue*>(arg);
333 assert(theObs != funcObservables->end());
335 std::unique_ptr<RooAbsPdf> newPdf;
337 if (precision > 0.) {
339 newPdf = std::make_unique<RooBinSamplingPdf>(
340 (std::string(
pdf.GetName()) +
"_binSampling").c_str(),
pdf.GetTitle(),
342 }
else if (
dynamic_cast<RooDataHist const *
>(&data) !=
nullptr &&
343 precision == 0. && !
pdf.isBinnedDistribution(*data.get())) {
346 newPdf = std::make_unique<RooBinSamplingPdf>(
347 (std::string(
pdf.GetName()) +
"_binSampling").c_str(),
pdf.GetTitle(),
Disable all caches for sub-branches in an expression tree.
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
bool isShapeDirty() const
bool inhibitDirty() const
void clearShapeDirty() const
RooAbsArg()
Default constructor.
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.
RooArgSet const * _normSet
! Normalization set with for above integral
RooAbsPdf()
Default constructor.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
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.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
double integrate(const RooArgSet *normSet, double low, double high) const
Integrate the wrapped PDF using our current integrator, with 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.
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::unique_ptr< ROOT::Math::IntegratorOneDim > _integrator
! Integrator used to sample bins.
double _relEpsilon
Default integrator precision.
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.
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
const char * GetName() const override
Returns name of object.
@ kADAPTIVE
to be used for general functions without singularities