Evaluate PDF for set of events

Dear Experts,

For some of my studies I need to evaluate RooAbsPdf for

  • single event in my dataset
  • set of events from my dataset
  • all events form my dataset
    and to store the results of evaluation in some container.
    What is the recommended efficient way to do it?

Maybe @jonas can give some hints

I’ve found RooFunctor - a wrapper over the RooAbsPdf. It seems that probaby one can get at least the first item uinwg this construction. Is is OK? Am I am looking into right direction?

I don’t know, let’s ask @jonas

Dear @jonas
can you give an advise?
Thank you in advance

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

Dear @jonas
Thank you very much!

Hi @jonas,

I have a minot follow-up question.
Will the followinng connstruction work
(a bit schematically)

dataset = .... ## RooDataSet  
pdf  = .... ## RooAbsPdf 

observables = pdf.getObservables ( dataset ) ## here (1) 

for i in ... 
  
     entry = dataset.get ( i ) 
     observables.assign ( entry ) ## HERE (2) 
     value = pdf.getVal() 

In words - can gI get observables from the PDF and then assigne their values to get PDF value?
Thank you in advance

Hi, correct that works! It’s just like my example 2, only that you are getting the observables by matching the variables in the pdf against the variables in the dataset.

Excellnt! Thank you very much!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.