GetParError returns 0?

Hello,

I am very very new to C in general and even more out of my depth with Roofit. For the project that I am working on there is a C script that does the Chi2FitTo for a given model. Now when I run the code in terminal, I see the 5 parameters and their errors well and good. But I was interested in extracting them to do further operations.

As seen below the GetParameter(i) works well, but when I run GetParError(i), I get 0 for all of them. I looked at the documentation and it is supposed to return 0 when either i <0 or i > NPar (number of parameters), which is decidedly not happening. I am not sure why I am getting 0s, and would appreciate any help in this regard. Thank you.

// This sets the starting parameters for the fit 

   RooRealVar FF_ga("FF_ga", "FF_ga", .146, 0, 10);
    RooRealVar FF_tau_a("FF_tau_a", "FF_tau_a", 45 ,0, 2000);
    //RooRealVar FF_tau_a("FF_tau_a", "FF_tau_a", 52.8 ,52.8, 52.8);
   RooRealVar FF_gY("FF_gY", "FF_gY", .096, 0, 200);
    RooRealVar FF_tau_Y("FF_tau_Y", "FF_tau_Y", 1000, 0, 20000);
    //  RooRealVar FF_tau_Y("FF_tau_Y", "FF_tau_Y", 2296, 2296, 2296);
   RooRealVar FF_gC("FF_gC", "FF_gC", .2,0, 100);

// This defines the function to be fitted
// Neff is a function defined earlier
// 
   TF1 *Neff_CCE  = new TF1("Neff_CCE",Neff,0.,+200000, 5);
// This binds the RootFit variable f to function Neff_CCE from TF1 above
 
// Create an observable
// Create binding of above TF1 to observable

   RooArgSet pars(FF_ga,FF_tau_a,FF_gY,FF_tau_Y,FF_gC); // 
   RooAbsReal *CCE = bindFunction(Neff_CCE, xt, pars);
 
// Print CCE definition
   CCE->Print();

    // try approach from fitgen3 exampl

   // RooDataHist* db = new RooDataHist("db", "db", RooArgSet(xt,yt) ) ;
   // RooChi2Var chi2("chi2", "chi2", CCE, db);
   //
  RooPlot *frame3 = xt.frame(Title("Leena Data  2e15 at 40 degree ;Annealing Time in min; Collected Charge in ke"));
 
// P e r f o r m   c h i 2   f i t   t o   X + / - d x   a n d   Y + / - d Y   v a l u e s
// --------------------------------------------------------------------------------------
// Plot dataset in X-Y interpretation
  RooPlot *frame4 = xt.frame(Title("Chi^2 fit of function set of (X#pmdX,Y#pmdY) values"));
   
   dxy.plotOnXY(frame4, YVar(yt));
   cout << " After dxy.Plot    " << endl;
   
   //   Fit chi^2 using X and Y errors
   CCE->chi2FitTo(dxy, YVar(yt), "Q", Save(1));
   cout << "After Chi2 fit" << endl;
   
   // Overlay fitted function
    CCE->plotOn(frame3, LineColor(kGreen));
   Double_t ga  = Neff_CCE->GetParameter(0);
   Double_t tau_a  = Neff_CCE->GetParameter(1);
   Double_t  gY = Neff_CCE->GetParameter(2);
   Double_t tau_Y  = Neff_CCE->GetParameter(3);
   Double_t  gC  = Neff_CCE->GetParameter(4);
   Double_t covMatrix = Neff_CCE->GetParError(0);
   cout << "#### ERROR 1 ### " << Neff_CCE -> GetParameter(0) << endl;
   cout << "#### ERROR 2 ### " << Neff_CCE -> GetParError(1) << endl;
   cout << "#### ERROR 3 ### " << Neff_CCE -> GetParError(2) << endl; 
   cout << "#### ERROR 4 ### " << Neff_CCE -> GetParError(3) << endl;
   cout << "#### ERROR 5 ### " << Neff_CCE -> GetParError(5) << endl;

Hello @Devey_Singh_Rathore; I am sure @jonas can provide an answer to this issue.

Cheers,
J.

Hello,

In your case you are doing a fit using RooFit using a pdf (a probability density function) which is built using a TF1 object. After fitting. the fit results are not copied in the TF1.
You can print the result of the fit by doing:

RooFitResult *res = CCE->chi2FitTo(dxy, YVar(yt), "Q", Save(1));
res->Print(); 

and if you want to print some individual parameter you can access by doing :

for ( auto &p : res->floatParsFinal() ) { 
  auto v = (RooRealVar *) p; 
  std::cout << "parameter " << v->GetName() << " : " << v->getVal() << " +/- " << v->getError() << std::endl;
}

Cheers

 Lorenzo
1 Like

Thank you Lorenzo!
Worked like a charm. So I know very little about how C works, I’d like to know more. I understand the concept of * being a pointer, and that

RooFitResult *res = CCE->chi2FitTo(dxy, YVar(yt), "Q", Save(1));

stores the address of result of the fit which is then called later on (like in the next line). Would you mind explaining what is happening under the hood in:

auto &p : res-> floatParsFinal()

and

auto v =  (RooRealVar *) p;

Specifically, what is the purpose of &p, and (RooRealVar *) p? I apologize if this is not the right place for these, but I’d be grateful for better understanding.

For the original problem, I really appreciate your help!

Thanks!
Devey

Hello,

for ( auto &p : res->floatParsFinal() ) {...}

This is a C++ range loop , available in C++, you find all explanations on the Web, see for example
https://en.cppreference.com/w/cpp/language/range-for

Note that this is possible from the RooFit lists (e.g. the RooArgList returned from RooFitResult::floatParsFinal() when using a rather recent version of ROOT.

This RooArgList contains pointer objects of type RooAbsArg which is a base class for many RooFit classes.
Ini this particular case, the objects contained are the derived RooRealVar (the fit parameters).
The auto v = (RooRealVar *) p; is just a downcast from the base class to the derived class in order to call functions like RooRealVar::getVal() or RooRealVar::getError() which are not available in the base class.
I hope this is clear now,
Best regards

Lorenzo

Thank you Lorenzo!

Really helped me understand this better.

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