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

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.