In ROOT 6.09 the TRatioPlot constructor that accepts two TH1* objects will segfault if a TCanvas object does not exist in scope at the time the constructor is called.
Is there a specific reason that motivated this choice? If so, can the documentation please be updated to reflect this? If not, can this be changed? I only discovered this today while trying to pass the constructor as an argument to a user defined function and debugging the segfault.
As an example of what I’m talking about, the following will cause a segfault:
#include <TH1.h>
#include <TF1.h>
#include <TCanvas.h>
#include <TRatioPlot.h>
int main (int argc, char const *argv[]) {
// TCanvas c1("c1", "A ratio example");
TH1D h1("h1", "h1", 50, 0, 10);
TH1D h2("h2", "h2", 50, 0, 10);
TF1 f1("f1", "exp(- x/[0] )");
f1.SetParameter(0, 3);
h1.FillRandom("f1", 1900);
h2.FillRandom("f1", 2000);
h1.Sumw2();
h2.Scale(1.9 / 2.);
h1.GetXaxis()->SetTitle("x");
h1.GetYaxis()->SetTitle("y");
TRatioPlot rp(&h1, &h2);
return 0;
} // main
but the following will compile and run just fine:
#include <TH1.h>
#include <TF1.h>
#include <TCanvas.h>
#include <TRatioPlot.h>
int main (int argc, char const *argv[]) {
TCanvas c1("c1", "A ratio example");
TH1D h1("h1", "h1", 50, 0, 10);
TH1D h2("h2", "h2", 50, 0, 10);
TF1 f1("f1", "exp(- x/[0] )");
f1.SetParameter(0, 3);
h1.FillRandom("f1", 1900);
h2.FillRandom("f1", 2000);
h1.Sumw2();
h2.Scale(1.9 / 2.);
h1.GetXaxis()->SetTitle("x");
h1.GetYaxis()->SetTitle("y");
TRatioPlot rp(&h1, &h2);
c1.SetTicks(0, 1);
rp.Draw();
c1.Update();
c1.SaveAs("ratio_plot.pdf");
return 0;
} // main
My system Information:
$ uname -a
Linux mcf-ThinkPad-Edge-E540 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ root-config --version
6.09/01