TGraphErrors and fit with associated error weights

I have a TGraphErrors object, i.e. a graph with both x and y errors supplied by me, but when I perform a linear fit,

g->Fit(“pol1”);

the weights given by the associated errors seem to be ignored by ROOT :confused:.

I’ve read in the Users Guide that the weights in histograms are computed as 1/sqrt(bin content), which is OK for histograms, but why does ROOT compute weights in TGraphErrors objects the same way? Shouldn’t the weights be given by dx and dy in the minimization of Chi^2? More importantly, how can I associate the weights to dx and dy when fitting a graph with errors?

I’m using ROOT v5.16/00

1 Like

see the NOTE in TGraph::Fit
root.cern.ch/root/html/TGraph.html#TGraph:Fit

Use option “F”

Rene

That actually did it. Thanks.

Sorry, I was too quick to reply. At first sight it did look like as if the “F” switch (not to be confused with the word) was doing the correct thing. It actually didn’t.

If I mess around with some points, yanking up the y errors, the fit stays the same, no matter what. Can I draw the conclusion from this that the weights are not taken from dy?

Hi Rene,

I found the problem. What happens is that the merging of two graphs does not pass along the errors.

Here are simple scripts to illustrate the issue.

{
  // four points are drawn and fit.

  Double_t x[4] = {2.,3.,4.,5.};
  Double_t dx[4] = {0.1,0.1,0.1,0.1};
  Double_t y[4] = {2.1,3.2,4.0,4.8};
  Double_t dy[4] = {0.1,0.3,0.2,0.2};

  gStyle->SetOptFit(111);

  TGraphErrors *g = new TGraphErrors(4,x,y,dx,dy);
  g->SetMarkerStyle(21);
  g->Draw("AP");
  g->Fit("pol1");
}

Change dy[0] to 0.3 and voila, the weight in the fit is changed.

{
  // four points are drawn and fit.
  // dy[0] changed to 0.3

  Double_t x[4] = {2.,3.,4.,5.};
  Double_t dx[4] = {0.1,0.1,0.1,0.1};
  Double_t y[4] = {2.1,3.2,4.0,4.8};
  Double_t dy[4] = {0.3,0.3,0.2,0.2};

  gStyle->SetOptFit(111);

  TGraphErrors *g = new TGraphErrors(4,x,y,dx,dy);
  g->SetMarkerStyle(21);
  g->Draw("AP");
  g->Fit("pol1");
}

Now the issue.

I split the points in two sets of arrays, then merge the graphs to fit all points. It seems the merging does not pass along the errors, just the points. Hence, a fit is done with calculated weights, as if option “W” or “WW” was given.

{
  Double_t x1[2] = {2.,4.};
  Double_t dx1[2] = {0.1,0.1};
  Double_t y1[2] = {2.1,4.0};
  Double_t dy1[2] = {0.3,0.2};

  Double_t x2[2] = {3.,5.};
  Double_t dx2[2] = {0.1,0.1};
  Double_t y2[2] = {3.2,4.8};
  Double_t dy2[2] = {0.3,0.2};

  gStyle->SetOptFit(0001);

  TGraphErrors *g1 = new TGraphErrors(2,x1,y1,dx1,dy1);
  g1->SetMarkerStyle(21);
  g1->SetMarkerColor(2);

  TGraphErrors *g2 = new TGraphErrors(2,x2,y2,dx2,dy2);
  g2->SetMarkerStyle(22);
  g2->SetMarkerColor(3);

  TList *myList = new TList();
  myList->Add(g1);
  myList->Add(g2);

  TGraphErrors *g = new TGraphErrors();
  g->Merge(myList);

  g->Draw("AP");
  g->Fit("pol1","F");

  g1->Draw("P same");
  g2->Draw("P same");

}

You should use the specialized class TMultiGraph for this job. See examples in $ROOTSYS/tutorials/fit/fitMultiGraph.C

Rene

Thanks Rene, but I already tried TMultiGraph and abandon it because I don’t seem to be able to fix the X range, and get the fit stat box.

The X range seems to be set by the last added graph and cannot be extended beyond that. (it can be within.)

Checkout this revised version.

{
  Double_t x1[2] = {2.,4.};
  Double_t dx1[2] = {0.1,0.1};
  Double_t y1[2] = {2.1,4.0};
  Double_t dy1[2] = {0.3,0.2};

  Double_t x2[2] = {3.,5.};
  Double_t dx2[2] = {0.1,0.1};
  Double_t y2[2] = {3.2,4.8};
  Double_t dy2[2] = {0.3,0.2};

  gStyle->SetOptFit(0001);

  TGraphErrors *g1 = new TGraphErrors(2,x1,y1,dx1,dy1);
  g1->SetMarkerStyle(21);
  g1->SetMarkerColor(2);

  TGraphErrors *g2 = new TGraphErrors(2,x2,y2,dx2,dy2);
  g2->SetMarkerStyle(22);
  g2->SetMarkerColor(3);
 
//   TList *myList = new TList();
//   myList->Add(g1);
//   myList->Add(g2);

//   TGraphErrors *g = new TGraphErrors();
//   g->Merge(myList);

  TMultiGraph *g = new TMultiGraph();
  g->Add(g1);
  g->Add(g2);

  g->Draw("AP");
  g->GetXaxis()->SetRangeUser(0,6);
  g->GetYaxis()->SetRangeUser(2,6);

  g->Fit("pol1","F");

//   g1->Draw("P same");
//   g2->Draw("P same");

}

We show plenty of examples in the tutorials about setting user defined ranges, using TPad::DrawFrame for example.
See one of these examples in $ROOTSYS/tutorials/graphs/gerrors2.C.
When setting your range in this way, you should not specify the option “a” when drawing your TGraphs or TMultiGraph.

Rene

A colleague and I tried the script in different machines, and only in the ROOT version I’m running is the range set weirdly. My version is 5.17/04.

The second plot is the same script ran in version 5.18/00.

OK, so it just happened that v 5.17/04 had this particular behavior.

Still, the fit stat box is not there. Is there a way to make it pop up?




I see that the drawing of the stats/fit box is not done in case of a TMultiGraph. We will fix this problem. As a workaround, I suggest adding the following statements at the end of your script, just after g->Fit()“pol1”,“F”).

//workaround to get the fit box. Move the function from gg to 1st graph
   TF1 *fpol = g->GetFunction("pol1");
   fpol->SetLineWidth(1);
   g->GetListOfFunctions()->Remove(fpol);
   g1->GetListOfFunctions()->Add(fpol);

Rene

The fit parameters painting is now implemented in TMultiGraph (in the svn trunk).