How to initialize roo-vars in a gui framework

The difficulty I’m having is in knowing how to treat roo variables similarly or differently from standard c++ ones. As objects they could all be deleted and reinstanced everytime, but is this needed?

The following code seems to loose context and other necessary info to compile and I’m unable to discern what to change.

The code below is a paired down version, which attempts to get the roo part working first. I’ve already got the gui working.

The main goal is to get my roovars initialized and scoping properly.

Thanks,
Dave

[code]// rooInit.C

#include <TGClient.h>
#include <TGFrame.h>
#include “TMath.h”
#include “TCanvas.h”
#include “TF1.h”
#include “RooRealVar.h”
#include “RooGaussian.h”

#include <RQ_OBJECT.h>

class MyMainFrame {

RQ_OBJECT(“MyMainFrame”)

private:
TGMainFrame *fMain;
TGCompositeFrame *cframe2;

// — Observables —
UInt_t xsig;
UInt_t xmean;
UInt_t rmin;
UInt_t rmx;

// — Observables —
RooRealVar sigmes();
RooRealVar qdcmes();
RooRealVar x();
RooRealVar mean();
RooRealVar sigma();

public:
MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h);
virtual ~MyMainFrame();
void MyVars(UInt_t xmean, UInt_t xsig, UInt_t rmin, UInt_t rmx);
void MyGauss(UInt_t xmean, UInt_t xsig, UInt_t rmin, UInt_t rmx);
ClassDef(MyMainFrame, 0)
};

MyMainFrame::MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h)
{
// Create a main frame
fMain = new TGMainFrame(p, w, h, kFitWidth | kFitHeight); // p,w,h connected?
cframe2 = new TGCompositeFrame(fMain,50,50, kVerticalFrame | kLHintsLeft); // ineffective

// Create buttons and inputs with calls to MyGauss();

fMain->AddFrame(cframe2, new TGLayoutHints(kLHintsExpandX, 20, 20, 5, 5));
fMain->SetWindowName(“rooInit”);
TGDimension size = fMain->GetDefaultSize();
fMain->Resize(size);
fMain->MapSubwindows();
fMain->Resize(fMain->GetDefaultSize());
fMain->MapWindow();
}

MyMainFrame::~MyMainFrame()
{
// Clean up all widgets, frames and layouthints that were used
fMain->Cleanup();
delete fMain;
}

void MyMainFrame::MyGauss(UInt_t xmean,UInt_t xsig,UInt_t rmin,UInt_t rmx)
{
// — Observables —
x.setRange(rmin,rmx);
mean.setVal(xmean);
sigma.setVal(xsig);

RooGaussian gauss(“gauss”,“gauss(x,mean,sigma)”,x,mean,sigma);
RooDataSet *data = gauss.generate(x,10000); // deletes every time
xframe=x.frame();
data->plotOn(xframe);
xframe->Draw();

delete data;
delete gauss;
}

void rooInit(){
// Test fit of a single Gaussian
gSystem->Load(“libRooFit”);
using namespace RooFit;
RooTrace::active(1);
// Popup the GUI
new MyMainFrame(gClient->GetRoot(),300,300);
MyMainFrame::MyGauss(2000,50,100,4000);
}[/code]

Hi,

I think you need to keep the RooData object for as long as you want its information to be displayed.

Cheers,
Philippe.

Philippe,
The main problem I’m having is getting the variables initialized. Who owns them? They either loose context or they never had it to begin with.
The code above doesn’t seem to behave the way a normal c++ routine would.

Dave

Hi Dave,

The problem you have in your example is mostly that you use the
default constructor for RooRealVars which does not define a functional
object. If you substitute the usual constructors with name,title and
initial range the code should work fine. The default construct exists
only to support ROOT persistence of these classes.

You might also want to have a look at class RooWorkspace as container for Roofit function objects. The added value of this class is that you are
able to persist entire (composite) p.d.f.s into a file through ROOT persistence. Look e.g. at examples $ROOTSYS/tutorials/roofit/rf502_wspacewrite.C and rf503_wspaceread.C

Wouter

Wouter,
Thanks for looking over the previous code. I know your time is a valuable resource.

Below is the current version that still has some unknowns on my part. I think that it is closer to right and I hope this code better communicates my beginner’s needs.

It does not run with “.C+” but will pop up a small window in “.C” mode.

Lastly, after reviewing the tutorials on RooWorkspace containers I realize I can use them to store the plotted results and this will be very useful once the more involved version of the code that fits the real-world histograms is complete.

Dave

[quote]Info in TUnixSystem::ACLiC: creating shared library /hep-root/guiroot/./rooInit_C.so
dlopen error: /hep-root/guiroot/./rooInit_C.so: undefined symbol: ZN5TListaSERKS
Load Error: Failed to load Dynamic link library /hep-root/guiroot/./rooInit_C.so
/usr/lib/gcc/i386-redhat-linux/3.4.3/…/…/…/crt1.o(.text+0x18): In function _start': : undefined reference tomain’
/hep-root/guiroot/./fileS8hsQ5.o(.gnu.linkonce.t.ZN9RooAbsArgaSERKS+0xbb): In function RooAbsArg::operator=(RooAbsArg const&)': : undefined reference toTList::operator=(TList const&)'
collect2: ld returned 1 exit status
*** Interpreter error recovered ***[/quote]

[code]// rooInit.C

#include <TGClient.h>
#include <TGFrame.h>
#include “TMath.h”
#include “TCanvas.h”
#include “TF1.h”
#include “RooRealVar.h”
#include “RooGaussian.h”
#include “RooDataSet.h”
#include “RooPlot.h”

#include <RQ_OBJECT.h>

using namespace RooFit ;

class MyMainFrame {

RQ_OBJECT(“MyMainFrame”)

private:
TGMainFrame *fMain;
TGCompositeFrame *cframe2;

// — Parameters —
UInt_t xsig;
UInt_t xmean;
UInt_t rmin;
UInt_t rmx;

// — Observables —
RooRealVar x;
RooRealVar mean;
RooRealVar sigma;
RooGaussian gauss;
RooDataSet *data;
RooPlot *xframe;

public:
MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h);
virtual ~MyMainFrame();
void MyGauss(UInt_t xmean, UInt_t xsig, UInt_t rmin, UInt_t rmx);
ClassDef(MyMainFrame, 0)
};

MyMainFrame::MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h)
{
// Create a main frame
fMain = new TGMainFrame(p, w, h, kFitWidth | kFitHeight); // p,w,h connected?
cframe2 = new TGCompositeFrame(fMain,50,50, kVerticalFrame | kLHintsLeft); // ineffective

// Create buttons and inputs with calls to MyGauss();

fMain->AddFrame(cframe2, new TGLayoutHints(kLHintsExpandX, 20, 20, 5, 5));
fMain->SetWindowName(“rooInit”);
TGDimension size = fMain->GetDefaultSize();
fMain->Resize(size);
fMain->MapSubwindows();
fMain->Resize(fMain->GetDefaultSize());
fMain->MapWindow();

// Create the roofit objects
x = RooRealVar(“x”,“x”,1000,4000,“x”);
mean = RooRealVar(“mean”,“Mean of Gaussian”,2100,1000.0,3000.0);
sigma = RooRealVar(“sigma”,“Sigma of Gaussian”,100,0.1,500.0);
gauss = RooGaussian(“gauss”,“gauss(x,mean,sigma)”,x,mean,sigma);
xframe = x.frame();

data = gauss.generate(x,10000);
data->plotOn(xframe);
xframe->Draw();
}

MyMainFrame::~MyMainFrame()
{
// Clean up all widgets, frames and layouthints that were used
fMain->Cleanup();
delete fMain;
}

void MyMainFrame::MyGauss(UInt_t xmean,UInt_t xsig,UInt_t rmin,UInt_t rmx)
{
// — Observables —
x.setRange(rmin,rmx);
mean.setVal(xmean);
sigma.setVal(xsig);

data = gauss.generate(x,10000);
data->plotOn(xframe);
xframe->Draw();

// delete data; // how to null without deleting?
}

void rooInit(){
// Test fit of a single Gaussian
// gSystem->Load(“libRooFit”);

// Popup the GUI
MyMainFrame mf = MyMainFrame(gClient->GetRoot(),300,300);
mf.MyGauss(2000,50,2000,3500);
}[/code]

Hi Dave,

The linkage error is peculiar. I will look into it as that should not happen.

But your solution is still not completely OK. You should not use the assignment operator to initialize data members, but use the initialization formalism:

MyMainFrame::MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h) :
x(“x”,“x”,1000,4000,“x”),
mean(“mean”,“Mean of Gaussian”,2100,1000.0,3000.0),
sigma(“sigma”,“Sigma of Gaussian”,100,0.1,500.0),
gauss(“gauss”,“gauss(x,mean,sigma)”,x,mean,sigma),
{
// remainder of constructor goes here.
}

Wouter