If you have used Root and
RooFit, you will notice that the two system uses
apparently different plotting interfaces. This poses some problems when you are
attempting to plot RooFit objects together with Root objects. In particular,
using TLegend
objects
alongside RooFit objects.
Storing the plotted objects of Roofit
When plotting with RooFit, we typically use something below:
#include "RooFit.h"
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "TCanvas.h"
#include "RooPlot.h"
#include "TAxis.h"
using namespace RooFit ;
void rf101_basics()
{
RooRealVar x("x","x",-10,10) ;
RooRealVar mean("mean","mean of gaussian",1,-10,10) ;
RooRealVar sigma("sigma","width of gaussian",1,0.1,10) ;
RooGaussian gauss("gauss","gaussian PDF",x,mean,sigma) ;
RooPlot* xframe = x.frame(Title("Gaussian p.d.f.")) ;
gauss.plotOn(xframe) ;
sigma.setVal(3) ;
gauss.plotOn(xframe,LineColor(kRed)) ;
}
Now we suppose we want to generate a
TLegend
object to legend
the objects that are being plotted. If you are familiar with TLegend
, this is
done through the function:
tlegend_instance.AddEntry( <tobject_pointer> , "<Description_in_legend>" , "<plot_settings>")
The problem now is what are the TObject
pointer that we need to pass over to
the TLegend
method? It cannot be the gauss
instance in the code above,
since it is used twice in the plotting function, so what is it?
Getting the plotted objects
It turns out when you call the
plotOn()
method, it generates a
TGraph
object stored in
the RooPlot
instance.
You could actually get a list of all these objects by the simple snippet:
for( int i = 0 ; i < xframe->numItems() ; ++i ){
cout << xframe->getObject( i )->GetName();
}
But there is a much better way of getting this thing, without having to guess
which name corresponds to which object you have just plotted on the RooPlot
object. By directly getting storing the object after you have called the
plotOn()
method:
gauss.plotOn(xframe);
TGraph* gauss_graph = (TGraph*)xframe->getObject( xframe->numItems() - 1 );
There is another merit of using this method. You could manually define the plot
style using ROOT flavored methods rather than using stuffing it all in the
plotOn()
methods call!
gauss_graph->SetFillStyle(3004);
gauss->SetLineColor( kGreen );
This gives you much more flexibility on the plots you are getting! Since not
all TGraphPainter
are not accessible with the RooFit plotOn
methods.
So now we could use the TLegend
object as expected with this method!
TLegend l( 0.6, 0.6, 0.9, 0.9);
l.AddEntry( gauss_graph , "My Description" , "fl" );
l.Draw();
Hopefully this quick snippet has been useful!