TRatioPlot in TPad segmentation fault

Dear experts,

I am trying to draw two TRatioPlots using pyROOT on two separate TPads within the same TCanvas. Below is the MWE code I use that should reproduce the segfault, and the segfault trace it produces. Is there something I am not doing correctly?

Thank you very much.

Sébastien.

from ROOT import *

cnv = TCanvas('c_2st_eta_phi','',1000,500)
cnv.Divide(2,1)
pads = []
for i in range(1, 3):
    pads.append(cnv.cd(i))

h1 = TH1D("h1", "h1", 50, 0, 10)
h2 = TH1D("h2", "h2", 50, 0, 10)
f1 = TF1("f1", "exp(- x/[0] )")
f1.SetParameter(0, 3);
h1.FillRandom("f1", 1900);
h2.FillRandom("f1", 2000);

h2.GetXaxis().SetTitle("x");
h2.GetYaxis().SetTitle("y");
   
for i in range(0,2):
    pads[i].cd()
    pads[i].SetTicks(1, 1)

    rp = TRatioPlot(h2, h1)

    # Works fine if I just draw the histograms
    #h1.Draw()
    #h2.Draw('same')
    # Segfaults if drawing TRatioPlots
    rp.Draw()

    pads[i].RedrawAxis()
    pads[i].Update()

cnv.Update()
cnv.SaveAs('rp.pdf')
Sebastiens-MacBook-Pro:~ Sebastien$ python rp.py 

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[/root6/build/lib/libCling.so] TClingCallFunc::exec(void*, void*) /root6/root-6.12.06/interpreter/llvm/src/include/llvm/ADT/SmallVector.h:88
[/root6/build/lib/libCore.so] TQConnection::SendSignal() /root6/root-6.12.06/core/base/src/TQConnection.cxx:290
[/root6/build/lib/libGpad.so] void TQObject::EmitVA<>(char const*, int) /root6/build/include/TQObject.h:135
[/root6/build/lib/libHistPainter.so] THistPainter::PaintFrame() /root6/root-6.12.06/hist/histpainter/src/THistPainter.cxx:6374
[/root6/build/lib/libHistPainter.so] THistPainter::Paint(char const*) /root6/root-6.12.06/hist/histpainter/src/THistPainter.cxx:4222
[/root6/build/lib/libGpad.so] TPad::PaintModified() /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:3829
[/root6/build/lib/libGpad.so] TPad::PaintModified() /root6/root-6.12.06/graf2d/gpad/src/TPad.cxx:3629
[/root6/build/lib/libGpad.so] TPad::PaintModified() /root6/root-6.12.06/graf2d/gpad/src/TPad.cxx:3629
[/root6/build/lib/libGpad.so] TCanvas::Update() /root6/root-6.12.06/graf2d/gpad/src/TCanvas.cxx:2287
[<unknown binary>] (no debug info)
[/root6/build/lib/libPyROOT.so] FastCall(long, void*, void*, void*) /root6/root-6.12.06/bindings/pyroot/src/Cppyy.cxx:407
[/root6/build/lib/libPyROOT.so] PyROOT::TVoidExecutor::Execute(long, void*, PyROOT::TCallContext*) /root6/root-6.12.06/bindings/pyroot/src/Executors.cxx:46
[/root6/build/lib/libPyROOT.so] PyROOT::TMethodHolder::CallFast(void*, long, PyROOT::TCallContext*) /root6/root-6.12.06/bindings/pyroot/src/TMethodHolder.cxx:110
[/root6/build/lib/libPyROOT.so] PyROOT::TMethodHolder::CallSafe(void*, long, PyROOT::TCallContext*) /root6/root-6.12.06/bindings/pyroot/src/TMethodHolder.cxx:122
[/root6/build/lib/libPyROOT.so] PyROOT::TMethodHolder::Execute(void*, long, PyROOT::TCallContext*) /root6/root-6.12.06/bindings/pyroot/src/TMethodHolder.cxx:0
[/root6/build/lib/libPyROOT.so] PyROOT::TMethodHolder::Call(PyROOT::ObjectProxy*&, _object*, _object*, PyROOT::TCallContext*) /root6/root-6.12.06/bindings/pyroot/src/TMethodHolder.cxx:585
[/root6/build/lib/libPyROOT.so] PyROOT::(anonymous namespace)::mp_call(PyROOT::MethodProxy*, _object*, _object*) /root6/root-6.12.06/bindings/pyroot/src/MethodProxy.cxx:598
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyObject_Call (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyEval_EvalFrameEx (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyEval_EvalCodeEx (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyEval_EvalCode (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyRun_FileExFlags (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] PyRun_SimpleFileExFlags (no debug info)
[/System/Library/Frameworks/Python.framework/Versions/2.7/Python] Py_Main (no debug info)
[/usr/lib/system/libdyld.dylib] start (no debug info)
[<unknown binary>] (no debug info)
Traceback (most recent call last):
  File "rp.py", line 32, in <module>
    pads[i].Update()
SystemError: void TPad::Update() =>
    problem in C++; program state has been reset

ROOT Version: 6.12/06
Platform: macosx64
Compiler: Not Provided


Hi Sebastien,

the key is to make your ratio plots survive the scope of the loop. Here a simplified (same result, less lines) version of your program, which now works (basically only 2 lines were missing!):

from ROOT import *

cnv = TCanvas('c_2st_eta_phi','',1000,500)
cnv.Divide(2,1)

h1 = TH1D("h1", "h1", 50, 0, 10)
h2 = TH1D("h2", "h2", 50, 0, 10)
f1 = TF1("f1", "exp(- x/[0] )")
f1.SetParameter(0, 3)
h1.FillRandom("f1", 1900)
h2.FillRandom("f1", 2000)

h2.GetXaxis().SetTitle("x")
h2.GetYaxis().SetTitle("y")


rps = []
for i in (1,2):
    cnv.cd(i).SetTicks(1, 1)

    rp = TRatioPlot(h2, h1)
    rps.append(rp)
    rp.Draw()

cnv.SaveAs('rp.pdf')

Works like a charm, thank you so much!

1 Like

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