Simply write a component of a RooAddPDF

Hi ROOT experts,

I simply want to do the following:

  1. I created a RooAddPdf by adding together two RooHistPdf. The two RooHistPdf are allowed to be scaled as well as shifted along the x axis during the fit.
  2. I fit the RooAddPdf to the data.
  3. Now I want to get a single one of the RooHistPdf, scale it so that it fits the actual data, and write it to file.

How do I do this? None of the existing solutions helped. I do not want to plot the data, I want to write it to file. My idea is as follows:

// This should be the RooHistPdf after fit, meaning normalized to the correct value and potentially shifted along x:
RooHistPdf * histo_after_fit_ONE= (RooHistPdf*)sum_of_the_two_roohistpdfs.pdfList().at(0);
// This should be the corresponding scaling value that I could use:
Float_t scalingfactor = pdf_sum_of_gaussianONE_and_gaussianTWO.coefList().at(0);
// But I don't know how to typecast from RooAbsArg to Float_t. Any ideas?
// Then I woud proceed to scale the RooHistPdf, convert it to a TH1F and Write() it to file.

Am I on the right track?


Thanks for the interesting post.

In order to write out RooFit pdfs, the correct way to proceed is via the RooWorkSpace: it’s a very handy utility, which allows to perform that operation correctly (behind a seemingly simple pdf instance, one can have a very sophisticated model - the workspace is made to capture all the information in these cases!).

As for “scaling” a pdf, I think there could be a procedural clarification to make. A pdf, irrespective of its representation in ROOT, for its own nature, has a integral which is equal to 1 (we deal with probabilities). If you wish to fit it to some data and you want to also get the best value for the number of events, the procedure is to perform an extended maximum likelihood fit, which can be easily carried out with a RooExtendPdf, a wrapper around an existing PDF that adds a parameteric extended likelihood term to the PDF, optionally divided by a fractional term from a partial normalization of the PDF.

I hope this helps!


Hi Danilo,

thanks for the swift answer. I checked the documentation of RooWorkSpace, unfortunately it did not help me getting to an adequate solution.

I managed to get it to work in another way though. For anybody who is interested in this:

  • As soon as I initialize a RooHistPDF, I immediately typecast it into a (TH1F*) and write it to file:
RooDataHist roodatahist_of_a_normal_histogram("roodatahist_of_a_normal_histogram","roodatahist_of_a_normal_histogram",x,normal_histogram);
RooHistPdf roohistpdf_of_the_roodatahist("roohistpdf_of_the_roodatahist","roohistpdf_of_the_roodatahist",x,roodatahist_of_a_normal_histogram,0);
RooRealVar fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting("fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting", "fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting", 0., 0., upperlimit_for_fraction);
TH1F* pdf_converted_back_to_normalhisto = (TH1F*)(roohistpdf_of_the_roodatahist.createHistogram("x",highest_bin_of_roohistpdf));
  • As soon as I perform any action on the RooHistPDF, like fitting, summing or convoluting, I do the same procedure again. This helps me to keep track on how the current PDF actual looks like, for example to see whether it has been scaled or shifted already.
  • When I’m done with all the fitting, I identify the histogram of the PDF that has been shifted along the x axis after fitting. As it corresponds to a PDF, it is normalized to 1.
  • I then get the value of the parameter that has been used during the fit to scale the PDF to the value of the real data. In this case, this is ‘fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting’:
Float_t scalingfactorValue_after_fit = fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting.getValV();
Float_t scalingfactorError_after_fit = fraction_of_roohistpdf_of_the_roodatahist_that_is_needed_for_later_for_fitting.getError();
  • I then scale the histogram of the PDF that has been shifted along the x axis by this using the ->Scale() function:

This gives me the correct histogram of a spectrum that has been fitted to the real data, whereas the fit did allow for a scaling and for a shifting along the x axis.

Sidenote: In order to get a RooHistPDF that can be shifted along the x axis, you can do the following:

RooRealVar shift_along_xAxis("shift_along_xAxis","shift_along_xAxis",startingvalue_of_shift,allowedShift_lowerbound,allowedShift_higherbound);
RooFormulaVar combination_of_x_and_shiftAlongXAxis("combination_of_x_and_shiftAlongXAxis","x-shift_along_xAxis",RooArgSet(x,shift_along_xAxis));
RooHistPdf roohistpdf_of_the_roodatahist_withShift("roohistpdf_of_the_roodatahist_withShift","roohistpdf_of_the_roodatahist_withShift",combination_of_x_and_shiftAlongXAxis,x,roohistpdf_of_the_roodatahist,0);

The string “x-shift_along_xAxis” actually defines the new variable that enables the shift along x.

However, I think getting the correct histograms after fitting should be way simpler. If anybody has time for that, he or she could implement this whole procedure as a simple function in the next version of ROOFIT.

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