Skip to content

Latest commit

 

History

History
416 lines (377 loc) · 21 KB

cern-roofit.org

File metadata and controls

416 lines (377 loc) · 21 KB

RooFit tips

TOC

Nothing interesting

Version

ROOT v6.24

Roo1DTable

It implements a one-dimensional table. A table is the category equivalent of a plot. To create a table use the RooDataSet::table method.

RooAbsAnaConvPdf

It is the base class for PDFs that represent a physics model that can be analytically convolved with a resolution model.

RooAbsArg

RooAbsArg is the common abstract base class for objects that represent a value and a “shape” in RooFit.

Therefore, RooAbsArg provides functionality to connect objects of type RooAbsArg into a computation graph to pass values between those objects.

RooAbsBinning

RooAbsBinning is the abstract base class for RooRealVar binning definitions.

The class defines the interface to retrieve bin boundaries, ranges etc.

RooAbsCache

RooAbsCachedPdf

It is the abstract class for p.d.f.s that need or want to cache their evaluate output in a RooHistPdf defined in terms of the used observables.

RooAbsCachedReal

It is the abstract base class for functions that need or want to cache their evaluate output in a RoohistFunc defined in terms of the used observables.

RooAbsCacheElement

It is the abstract base class for objects to be stored in RooAbsCache cache manager objects.

RooAbsCategory

It is the base class for objects that represent a discrete value with a finite number of states.

Each state is denoted by an integer and a name. Both can be used to retrieve and set states, but referring to states by index is more efficient. Conversion between index and name can be done using lookupName or lookupIndex. It is possible to iterate through all defined states using begin and end.

RooAbsCategoryLValue

It is the common abstract base class for objects that represent a discrete value that can be set from the outside, i.e. that may appear on the left hand side of an assignment (lvalue).

RooAbsCollection

It is an abstract object that can hold multiple RooAbsArg.

RooAbsData

It is the is the common abstract base class for binned and unbinned datasets.

Global observables

Create histograms from RooAbsData

Make use of createHistogram().

Fill a histogram

Make use of fillHistogram().

Make plots

Make use of plotOn(). Several arguments can be specified. Please check the link.

Statistic analysis

Make use of mean(), sigma(), skewness(), moment(), correlationMatrix(), correlation(), covarianceMatrix(), covariance(), corrcov(), and corrcovMatrix().

Apply cuts and create a subset

Make use of reduce().

Add a row

Make use of add().

Storage

vector storage
make use of convertToVectorStore().
tree storage
make use of convertToTreeStore().

RooAbsDataStore

It is the abstract base class for data collection that use a TTree as internal storage mechanism.

RooAbsFunc

Abstract interface for evaluating a real-valued function of one real variable and performing numerical algorithms on it.

RooAbsGenContext

Related to generator contexts.

RooAbsHiddenReal

A base class for objects that want to hide their return value from interactive use, e.g. for implementations of parameter unblinding functions.

RooAbsIntegrator

the abstract interface for integrators of real-valued functions that implement the RooAbsFunc interface.

RooAbsLValue

Abstract base class for objects that are lvalues, i.e. objects whose value can be modified directly. This class implements abstract methods for binned fits that return the number of fit bins and change the value of the object to the central value of a given fit bin, regardless of the type of value.

RooAbsMCStudyModule

RooAbsMCStudyModule is a base class for add-on modules to RooMCStudy that can perform additional calculations on each generate+fit cycle managed by RooMCStudy.

RooAbsMoment

RooAbsMoment represents the first, second, or third order derivative of any RooAbsReal as calculated (numerically) by the MathCore Richardson derivator class.

RooAbsNumGenerator

Class RooAbsNumGenerator is the abstract base class for MC event generator implementations like RooAcceptReject and RooFoam.

RooAbsOptTestStatistic

RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a function or PDF at each point of a given dataset.

RooAbsPdf

RooAbsPdf is the abstract interface for all probability density functions. The class provides hybrid analytical/numerical normalization for its implementations, error tracing and a MC generator interface.

A Minimal PDF Implementation

A minimal implementation of a PDF class derived from RooAbsPdf should override the evaluate() function. This function should return the PDF’s value (which does not need to be normalized).

Normalization/Integration

Although the normalization of a PDF is an integral part of a probability density function, normalization is treated separately in RooAbsPdf. The reason is that a RooAbsPdf object is more than a PDF: it can be a building block for a more complex, composite PDF if any of its variables are functions instead of variables. In such cases the normalization of the composite may not be simply the integral over the dependents of the top level PDF as these are functions with potentially non-trivial Jacobian terms themselves.

Therefore, no explicit attempt should be made to normalize the function output in evaluate(). In particular, normalization constants can be omitted to speed up the function evaluations, and included later in the integration of the PDF (see below), which is called rarely in comparison to the evaluate() function.

In addition, RooAbsPdf objects do not have a static concept of what variables are parameters and what variables are dependents (which need to be integrated over for a correct PDF normalization). Instead, the choice of normalization is always specified each time a normalized value is requested from the PDF via the getVal() method.

RooAbsPdf manages the entire normalization logic of each PDF with help of a RooRealIntegral object, which coordinates the integration of a given choice of normalization. By default, RooRealIntegral will perform a fully numeric integration of all dependents. However, PDFs can advertise one or more (partial) analytical integrals of their function, and these will be used by RooRealIntegral, if it determines that this is safe (i.e. no hidden Jacobian terms, multiplication with other PDFs that have one or more dependents in commen etc).

The integration range for each dependent to be integrated can be obtained from the dependent’s proxy functions min() and max(). Never call these proxy functions for any proxy not known to be a dependent via the integration code. Doing so may be ill-defined, e.g. in case the proxy holds a function, and will trigger an assert. Integrated category dependents should always be summed over all of their states.

Direct generation of observables

Distributions for any PDF can be generated with the accept/reject method, but for certain PDFs, more efficient methods may be implemented. To implement direct generation of one or more observables, two functions need to be implemented, similar to those for analytical integrals: getGenerator and generateEvent.

The first function advertises observables, for which distributions can be generated, similar to the way analytical integrals are advertised. The second function implements the actual generator for the advertised observables.

The generated dependent values should be stored in the proxy objects. For this, the assignment operator can be used (i.e. xProxy = 3.0 ). Never call assign to any proxy not known to be a dependent via the generation code. Doing so may be ill-defined, e.g. in case the proxy holds a function, and will trigger an assert.

Batched function evaluations

To speed up computations with large numbers of data events in unbinned fits, it is beneficial to override evaluateSpan(). Like this, large spans of computations can be done, without having to call evaluate() for each single data event. evaluateSpan() should execute the same computation as evaluate(), but it may choose an implementation that is capable of SIMD computations. If evaluateSpan is not implemented, the classic and slower evaluate() will be called for each data event.

RooAbsProxy

RooAbsProxy is the abstact interface for proxy classes.

Proxy classes hold pointers to other Roofit objects and process serverRedirect changes so that the proxied pointers are updated accordingly on a clone or copy of of the owning class.

RoxoAbsReal

RooAbsReal is the common abstract base class for objects that represent a real value and implements functionality common to all real-valued objects such as the ability to plot them, to construct integrals of them, the ability to advertise (partial) analytical integrals etc.

RooAbsRealLValue

RooAbsRealLValue is the common abstract base class for objects that represent a real value that may appear on the left hand side of an equation (lvalue).

RooAbsRootFinder

RooAbsRootFinder is the abstract interface for finding roots of real-valued 1-dimensional function that implements the RooAbsFunc interface.

RooAbsSelfCachedPdf

RooAbsSelfCachedPdf is an abstract base class for probability density functions whose output is cached in terms of a histogram in all observables between getVal() and evaluate().

RooAbsSelfCachedReal

RooAbsSelfCachedReal is an abstract base class for functions whose output is cached in terms of a histogram in all observables between getVal() and evaluate().

RooAbsStudy

RooAbsStudy is an abstract base class for RooStudyManager modules.

RooAbsTestStatistic

RooAbsTestStatistic is the abstract base class for all test statistics.

Miscellaneous

Plot PDF with expected yields

[2022-01-31 Mon 16:48]

You may want to make use option RooFit::Normalization(1.0, RooAbsReal::RelativeExpected). Please refer to rf202_extendedmlfit.C in RooFit tutorial.

Plot filled area in RooFit

[2022-01-31 Mon 15:28]

You have several things to do:

  • If you want draw with filled area, you must enable DrawOption("F"). This is because RooCurve inherits from TGraph.
  • In principle, you must add VLines() in the arguments for plotOn. But it does not work until the version 6.26. A work around is below:
    /**
       A workaround for VLine bug.
    
       Please check the post https://root-forum.cern.ch/t/unexpected-behavior-of-drawoption-f/44851
       and the PR https://github.com/root-project/root/pull/8198
    
       The function assume the x for points in RooCurve are in increasing
       order. And then, two more points will be placed at the largest x
       and then smallest x. These points then will construct a polygon
       in the filling area.
     */
    
    void setVLines(RooCurve* curve)
    {
      double xlo = curve->GetPointX(0);
      double xhi = curve->GetPointX(curve->GetN()-1);
      curve->addPoint(xhi, 0);
      curve->addPoint(xlo, 0);
    }
        
  • If you just want transparent color in output image, do either way as below:
    • Make use of TColor::GetColorTransparent(kRed, 0.3) in RooFit::FillColor.
      gaus.plotOn(frame, DrawOption("F"), FillColor(TColor::GetColorTransparent(kRed, 0.3)));
              
    • Make use of the following blocks:
      gaus.plotOn(frame, Name("curve_gaus"), DrawOption("F"), FillColor(kRed));
      auto curve_gaus = frame->getCurve("curve_gaus");
      curve_gaus->SetFillColorAlpha(kRed, 0.3);
              
  • If you want to show transparency in a ROOT pop-up window, enable OpenGL. Two ways separately to achieve this:
    • gStyle->SetCanvasPreferGL->(kTRUE) in macros.
    • OpenGL.CanvasPreferGL: 1 in .rootrc

Merge datasets row-wise

[2021-11-14 Sun 20:51]

The append() function addes two datasets row-wise. See the tutorial.

Message services with RooMsgService

[2022-02-01 Tue 15:46]

Please consult the tutorial and descriptions in reference guide. The tutorial shows how to make use of addStream to obtain the printout. However, I guess I can only find specific level in the output. For example, addStream(DEBUG, OutputFile("debug.txt")) will redirect the [#3] DEBUG: to the debug.txt. And addStream(DEBUG, Topic(Tracing), OutputFile("debug.txt")) will redirect the [#3] DEBUG:Tracing to the debug.txt.

However, I do not know

  • if it is safe to use the same name at the same time like the following:
    addStream(DEBUG, OutputFile("debug.txt"))
    addStream(WARNING, OutputFile("debug.txt"))
        
  • if it will redirect the message along with the higher level message together to the output file.

Options for plotting

  • You can use RooFit::Range option in RooDataSet.plotOn. I tested with Range("name") and Range(low, high). The former one will give:
    ERROR: unrecognized command: RangeWithName
        

    The later one will give:

    ERROR: unrecognized command: Range
        

Generate binned data from unbinned one

Basically, you could try binnedClone. It will produce a RooDataHist. I guess the RooDataHist is in multi-dimension. This might be the reason it will consume a lot of memory resources.

I usually use createHistogram to produce 1-D histogram. There are several implementations. Try the one you want. After having the histogram object, I create a correspond RooDataHist.

Template fit in RooFit

As said in the documentation

The histogram distribution is explicitly normalized by RooHistPdf and can have an arbitrary number of real or discrete dimensions.

I checked the source code in version 6.26/10. The RooHistPdf relies on the its link to RooDataHist. The evaluate method calculate the value as suggested in documentation:

Return the current value: The value of the bin enclosing the current coordinates of the observables, normalized by the histograms contents.

In practice, it makes use of RooDataHist::weightFast. See here. The _unitNorm flag seems always false.

If you want to use RooHistPdf, you must ensure the lifetime of the input RooDataSet linked with RooHistPdf. And you also needs to give a template histogram without normalizing it by bin widths.

How to create binned dataset?

I have no idea. It seems that creating a dataset from a TH1 pointer in constructor will not correct for the bin width by default. See here. The choice of choose desnsity or counts can be found in Import option. See here. I do not understand their descriptions. I made several tests:

  • Given the histogram with the variable bin size, I do not normalize it. And then I tried different method of initializing the dataset:
    • TH1 pointer: I got the same results using h->GetBinContent(1) and dh.weight(0).
    • Import(h, kFALSE): I got the same results using h->GetBinContent(1) and dh.weight(0).
    • Import(h, kTRUE): I get the same results using h->GetBinContent(1)*h->GetBinWidth(1) and dh.weight(0).

    My conclusion is that

    • The correction is done by multiplying the bin content with the bin width. This is natural since the dataset should contain counts. Note, here it is operation *, while in the weightFast, the weight will be divided by bin width if the correction is enabled.
    • Passing false to Import will yield the same result of histogram itself.
  • Given the histogram with and without normalization, I tried to plot the distributions and generate RooDataHist. The histogram with normalization cannot be drawn properly if Import(h, kFALSE) is given.

I can convert the dataset to density by hand. But I do not see significantly differences in the template fit.

I will go with histogram without normalization in the template fit because the plotting is correct only for histograms without normalizations.

I also do not know how RooFit make the plot. It seems that RooFit always plot the density of data.

A few words for RooDataHist

Be clear if you will pass the normalized histogram in

I must be careful about the normalization of histograms with uneven binning.

It is a class holding the “data”. I guess the concept drive the design of this class that it holds the “counts” in weight for each bin.

To be consistent with the concept (I may be wrong), I need to do

  • Pass the histogram without normalization (h->Scale(1, "width") using pointer or Import(h, kFALSE).
  • Pass the histogram with normalization using Import(h, kTRUE).

See also the discussion in this link. He made a few examples. I have not gone through them. I will do it later.

Normalization and plotting.

In RooFit, RooDataHist::plotOn will plot the density of data.