Hi @ibelyaev,
Sorry for the late reply! This is actually a standard procedure in RooFit. In RooFit, whenever you update the value of a variable with setVal()
, the dependent pdf or function will re-evaluate itself when you call getVal()
. Another useful function is RooArgSet::assign()
if you want to sync values from one ArgSet (from data) to another (of the model for re-evaluation).
Here are some examples of what you can do with RooFit, using a Gaussian model:
RooRealVar x("x", "x", -10, 10);
RooRealVar mean("mean", "mean of gaussian", 0, -10, 10);
RooRealVar sigma("sigma", "width of gaussian", 1, 0.1, 10);
RooGaussian gauss("gauss", "gaussian PDF", x, mean, sigma);
// Which variables are the observables
RooArgSet observables{x};
// Which variables the pdf should be normalized over
// Unless you are doing a conditional fit,
// this coincides with the observables.
RooArgSet normSet{observables};
Example 0: evaluate for single value
double xVal = 2.0;
x.setVal(xVal);
double pdfVal = gauss.getVal(normSet);
Example 1: evaluate for data from std::vector
std::vector<double> xVals{-1.0, -0.5, 0.0, 0.5, 1.0};
std::vector<double> pdfVals(xVals.size());
for (std::size_t i = 0; i < xVals.size(); ++i) {
x.setVal(xVals[i]);
pdfVals[i] = gauss.getVal(normSet);
}
Example 2: evaluate for data from RooDataSet
std::unique_ptr<RooDataSet> data{gauss.generate(x, 100)};
std::vector<double> pdfVals(data->numEntries());
for (std::size_t i = 0; i < data->numEntries(); ++i) {
// The data->get() returns the internal RooArgSet of the RooDataSet.
// With "assign", we are syncing the values of our observables
// in the model with the one of the dataset.
observables.assign(*data->get(i));
pdfVals[i] = gauss.getVal(normSet);
}
Example 3: evaluate for subset of RooDataSet
std::unique_ptr<RooDataSet> data{gauss.generate(x, 100)};
// The difference is that we are first creating a new dataset that is a
// subset of the original.
std::unique_ptr<RooDataSet> dataSel{
static_cast<RooDataSet*>(data->reduce("std::abs(x) < 0.5"))};
std::vector<double> pdfVals(dataSel->numEntries());
for (std::size_t i = 0; i < dataSel->numEntries(); ++i) {
observables.assign(*dataSel->get(i));
pdfVals[i] = gauss.getVal(normSet);
}
I hope this gives you some ideas!
Cheers,
Jonas