Simultaneous fits

Hello all,

I am trying to implement a simultaneous chi2 fit to two RooDataHist’s. The RooDataHists share a commmon parameter “f_sig” whose value
needs to be returned by the fit. I am trying to do this by: (1) using RooHistPdf’s to model the data, and (2) by using an analytical
function defined using a RooAddPdf.

=============================================================================
(1) Using RooHistPdfs, I have tried the following:

The PDF’s that will be used to fit the data are obtained from MC using RooHistPdfs. For variable “A” (aka “Var_A”),
I obtain the signal (“sig_A”) and background (“bkd_A”) RooHistPdfs as follows:

TH1* Hist_sig_A = Tree_sig_A->createHistogram(“Hist_sig_A”, Var_A, Binning(5));
RooDataHist* DataHist_sig_A = new RooDataHist(“DataHist_sig_A”, “DataHist_sig_A”, RooArgList(Var_A), Hist_sig_A);
RooHistPdf* HistPdf_sig_A = new RooHistPdf( “HistPdf_sig_A” , “HistPdf_sig_A” , RooArgList(Var_A), *DataHist_sig_A, 0);

TH1* Hist_bkd_A = Tree_bkd_A->createHistogram(“Hist_bkd_A”, Var_A, Binning(5));
RooDataHist* DataHist_bkd_A = new RooDataHist(“DataHist_bkd_A”, “DataHist_bkd_A”, RooArgList(Var_A), Hist_bkd_A);
RooHistPdf* HistPdf_bkd_A = new RooHistPdf( “HistPdf_bkd_A” , “HistPdf_bkd_A” , RooArgList(Var_A), *DataHist_bkd_A, 0);

Likewise for variable “B”:

TH1* Hist_sig_B = Tree_sig_B->createHistogram(“Hist_sig_B”, Var_B, Binning(4));
RooDataHist* DataHist_sig_B = new RooDataHist(“DataHist_sig_B”, “DataHist_sig_B”, RooArgList(Var_B), Hist_sig_B);
RooHistPdf* HistPdf_sig_B = new RooHistPdf( “HistPdf_sig_B” , “HistPdf_sig_B” , RooArgList(Var_B), *DataHist_sig_B, 0);

TH1* Hist_bkd_B = Tree_bkd_B->createHistogram(“Hist_bkd_B”, Var_B, Binning(4));
RooDataHist* DataHist_bkd_B = new RooDataHist(“DataHist_bkd_B”, “DataHist_bkd_B”, RooArgList(Var_B), Hist_bkd_B);
RooHistPdf* HistPdf_bkd_B = new RooHistPdf( “HistPdf_bkd_B” , “HistPdf_bkd_B” , RooArgList(Var_B), *DataHist_bkd_B, 0);

I then create RooDataHist’s out of the data that I need to fit:

TH1F *Hist_data_A = new TH1F("", “”, 5,-0.80,1.00);
Hist_data_A->Sumw2();
Hist_data_A->SetBinContent( 1, val_1); Hist_data_A->SetBinError( 1, err_1);

RooDataHist *DataHist_data_A = new RooDataHist("", “”, RooArgList(Var_A), Hist_data_A);

TH1F *Hist_data_B = new TH1F("", “”, 4,-1.00,1.00);
Hist_data_B->Sumw2();
Hist_data_B->SetBinContent( 1, val_1); Hist_data_B->SetBinError( 1, err_1);

RooDataHist *DataHist_data_B = new RooDataHist("", “”, RooArgList(Var_B), Hist_data_B);

Finally, I define the PDF that I want to fit the data with:

RooRealVar f_sig(“f_sig”, “f_sig”, 0.5, 0.0, 1.0);

RooAddPdf PDF_var_A("", “”, RooArgList(*HistPdf_sig_A, *HistPdf_bkd_A), f_sig);
RooAddPdf PDF_var_B("", “”, RooArgList(*HistPdf_sig_B, *HistPdf_bkd_B), f_sig);

As you can see, both PDF’s contain the same variable f_sig. Here is where I run into trouble. If there were only PDF_var_A,
I would simply write the following:

RooChi2Var chi2_var_A("","", PDF_var_A, *DataHist_data_A);
RooMinuit m2_var_A(chi2_var_A);
m2_var_A.migrad();

However, what I think I need to do now is have two chi2 variables, combine them, then minimize the total chi2. I cannot find any documentation
regarding adding or combining chi2 variables. Am I missing something? Or is there another way to do this?

=============================================================================
(2) Using an analytical function defined by RooAddPdf:

The RooDataHist’s that I need to fit are defined in the same way as stated above (*Hist_data_A and *Hist_data_B).

The PDF I need to use to fit the RooDataHist’s is defined as follows:

RooArgSet Vars(Var_A,Var_B);
RooGenericPdf sig_PDF("", “function”, Vars);
RooGenericPdf bkd_PDF("", “function”, Vars);

RooRealVar f_sig(“f_sig”, “f_sig”, 0.5, 0.0, 1.0);

RooAddPdf sum_PDF("", “”, RooArgList(sig_PDF, bkd_PDF), RooArgList(f_sig));

What I would like to do now is perform a simultaneous chi2 fit to Var_A and Var_B, using the same PDF (sum_PDF), and extract f_sig from the fit.
The problem is that the “function” defined in the RooGenericPdf is a function of BOTH Var_A and Var_B. I’ve tried the following:

RooCategory variables(“variables”,“variables”);
variables.defineType(“1”,1); //for Var_A
variables.defineType(“2”,2); //for Var_B

//“datafile” is an ASCII file which flags Var_A with “1” and Var_B with "2"
RooDataSet *data = RooDataSet::read(datafile, RooArgList(Var_A, Var_B, variables));

RooSimultaneous Simult_PDF(“Simult_PDF”, “Simult_PDF”, variables);
Simult_PDF.addPdf(sum_PDF,“1”);
Simult_PDF.addPdf(sum_PDF,“2”);

RooChi2Var chi2(“chi2”,“chi2”,Simult_PDF, *data);
RooMinuit m2(chi2);
m2.migrad();

However, this does not work, since it seems that RooChi2Var needs to take a RooDataHist as an argument, not a RooDataSet. Does anyone know
how to do this?

Thank you in advance,
Pablo

Hi Pablo,

You’re very close in both cases.

The solution for scenario 1) is very simple: use class RooAddition or class RooFormulaVar to construct the sum of the likelihoods or chi2. In RooFit a likelihood or chi2 are also RooAbsReal-derived objects themselves and it is also a RooAbsReal that RooMinuit expects, thus:

RooAddition sumchi2(“sumchi2”,“sum of chi2 terms”,RooArgSet(chi2A,chi2B)) ;

or

RooFormulaVar sumchi2(“sumchi2”,"@0+@1",RooArgSet(chi2A,chi2B)) ;

Then you can feed the sumchi2 object into RooMinuit.

The solution for scenario 2) is that you can explicitly construct a
RooDataHist from a RooDataSet:

RooDataHist(const char *name, const char *title, const RooArgSet& vars, const RooAbsData& data, Double_t initWgt=1.0) ;

i.e.

RooDataHist dh(“dh”,“dh”,*d.get(),d) ; // with a RooDataSet d

Wouter

Hi Wouter,

Thank you very much for your help! I was able to successfully add the chi2 variables using RooAddition.

Many thanks,
Pablo