RootTalk


ROOT Discussion Forums

TTree.Draw() with custom function  SOLVED

Discuss PyROOT, the Python ROOT language binding, here.

Moderators: wlav, rootdev

TTree.Draw() with custom function

Unread postby salderwe » Thu Nov 29, 2012 17:14

Hi,

I'm using pyroot, with root v5.34/01, python v2.7.3 and gcc v4.7.2,

I'm trying to use a custom function for weights in the selection field of TTree.Draw(). My custom function is defined as a C-style root macro:
Code: Select all
#include <TH1F.h>
TH1F *h = 0;
double myfunction(double val = 0)
{
   if (!h)
       return 0.;
   return h->GetBinContent(h->FindBin(val));    
}


In the main program (below) I load the macro and use it in TTree.Draw(). This works fine (output reweighted.png looks fine), but (as far as I can judge) at the closing of my main function the program segfaults. My main concern is making this run cleanly, but maybe you can give me other suggestions to improve the method.

a) Why am I getting a segmentation fault and how do I solve it. Output is attached, but I don't understand where the error is coming from.

b) Is it possible to define my custom function in python, e.g. "def myfunction(): ..." syntax, in the main file? If so, how do I load it such that it is known to TTree.Draw().

Main (test) program:
Code: Select all
#!/usr/bin/env python

import ROOT

def main():
   f0 = ROOT.TFile("extra.root","read")
   f1 = ROOT.TFile("data.root","read")

   ROOT.gROOT.ProcessLineSync('.x myfunction.C+')

   f0.cd()
   h = f0.Get("inputdir/inputhist;1")
   h.SetName("h")
   ROOT.gDirectory.cd("inputdir")
   ROOT.gROOT.ProcessLineSync('TH1F *h = (TH1F*)gDirectory->Get("h")')

   canvas = ROOT.TCanvas("c","c")
   canvas.cd()

   t1 = f1.Get("mytree")
   t1.Draw("var","","",10000)
   t1.Draw("var","(myfunction(var))*1.0","same",10000)

   canvas.SaveAs("reweighted.png")
   canvas.Close()

   f0.Close()
   f1.Close()

if __name__ == "__main__":
   main()



Thanks,
Sara
Attachments
out.txt
program output
(6.13 KiB) Downloaded 7 times
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function

Unread postby salderwe » Fri Nov 30, 2012 11:32

Hi again,

Testing a bit I can see the error appears when I try to Close f0, after I have used it in TTree.Draw(). If I try to Close before the Draw() but after the ProcessLineSync()'s, I don't get a segmentation fault.

I believe the problem is related to where the h histogram is loaded in memory. Currently it's loaded under f0, if I try to load it under f1, the segmentation fault appears when closing f1 instead. Actively deleting the histogram before closing doesn't help.

Cheers,
Sara
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function

Unread postby salderwe » Fri Nov 30, 2012 13:10

Adding to my confusion, on lxplus this script runs fine, no segfault.

Any suggestions?

Sara
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function

Unread postby salderwe » Tue Dec 04, 2012 14:41

I'm problably starting to look a bit ridiculous, four updates without any input from someone else, but I really want to solve this issue. Is there no-one around with some pyroot/gdb experience to help point me in the right direction for a solution?

Meanwhile:
Reorganizing a bit to get rid of the extra cd()'s:
Code: Select all
#!/usr/bin/env python

import ROOT

def main():
   f0 = ROOT.TFile("extra.root","read")

   ROOT.gROOT.ProcessLineSync('.x myfunction.C+')

   h = f0.Get("inputdir/inputhist;1").Clone("h")
   ROOT.gROOT.ProcessLineSync('TH1F *h = (TH1F*)gDirectory->Get("h")')

   canvas = ROOT.TCanvas("c","c")
   canvas.cd()

   f1 = ROOT.TFile("data.root","read")
   t1 = f1.Get("mytree")
   t1.Draw("var","","",10000)
   t1.Draw("var","(myfunction(var))*1.0","same",10000)

   canvas.SaveAs("reweighted.png")
   canvas.Close()

   f0.Close()
   f1.Close()

if __name__ == "__main__":
   main()


Locally on my laptop I still get the segmentation fault, and attached is a more elaborate backtrace. Hopefully someone can help me fish the issue from that.

Sara
Attachments
out.txt
Backtrace
(35.39 KiB) Downloaded 3 times
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function

Unread postby wlav » Wed Dec 05, 2012 9:14

Sara,

sorry, I had too much on my plate; trying to catch up now.

I expect that the problem is that PyROOT tries to figure out where ownership should be and typically this works well when variables are passed around through normal function interfaces. This call, however:
Code: Select all
ROOT.gROOT.ProcessLineSync('TH1F *h = (TH1F*)gDirectory->Get("h")')
goes around the back of everything and so both python and C++ (b/c of the file ownership) think they own "h".

If that is indeed the problem, then
Code: Select all
ROOT.SetOwnership(h, False)
should solve the problem.

Cheers,
Wim
User avatar
wlav
 
Posts: 1393
Joined: Mon Jun 14, 2004 18:40
Location: Lawrence Berkeley National Lab

Re: TTree.Draw() with custom function

Unread postby salderwe » Wed Dec 05, 2012 10:54

No problem Wim.

A colleague suggested the same SetOwnership, but this does not solve the problem. If I add it, syntax like you wrote, I still get the segfault and the backtrace remains exactly the same.

Since the problem only appears on my local machine I suspect it has something to do either with the version of root/gcc I'm running, or with the way everything is linked. If you know which things to check there I can have a look.

Thanks,
Sara
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function

Unread postby wlav » Thu Dec 06, 2012 2:39

Sara,

does it help if you change the close order (i.e. close files in reverse order of opening them)?

One thing that will certainly help is if you use
Code: Select all
ROOT.SetOwnership(f0, False)
ROOT.SetOwnership(f1, False)
but that just doesn't seem right: I'm not certain whether the problem is deleting a TFile that has already gone dodo-bird, or whether the problem is in the objects it is holding, but not calling their dtors at all seems rather drastic.

Cheers,
Wim
User avatar
wlav
 
Posts: 1393
Joined: Mon Jun 14, 2004 18:40
Location: Lawrence Berkeley National Lab

Re: TTree.Draw() with custom function

Unread postby salderwe » Thu Dec 06, 2012 13:04

The order of closing doesn't change the error. The segfault always happens when you try to close the tfile under which th1f h is loaded.

With the code like I put it here first, h is in memory under tfile f0 (from which it was read too), and subsequently closing f0 gives the segfault. If I do some extra cd's and load the histogram to memory under f1, the segfault comes when closing f1.

Setting the ownership to False for both files I still get a segfault, but the bactrace is different. I attached it again.

Cheers,
Sara
Attachments
out2.txt
program output
(4.18 KiB) Downloaded 3 times
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium

Re: TTree.Draw() with custom function  SOLVED

Unread postby wlav » Thu Dec 06, 2012 19:40

Sara,

then it looks like it's not PyROOT related, but rather ROOT's internal cleanup on program shutdown. There's a similar discussion (very similar stack trace) going on at the roottalk mailing list (started by Chris Jones). Philippe can reproduce it and is looking into it.

Cheers,
Wim
User avatar
wlav
 
Posts: 1393
Joined: Mon Jun 14, 2004 18:40
Location: Lawrence Berkeley National Lab

Re: TTree.Draw() with custom function

Unread postby wlav » Thu Dec 06, 2012 20:18

Hi,

and according to Philippe, a fix has just gone in. Any chance you can try v5-34-00-patches?

Cheers,
Wim
User avatar
wlav
 
Posts: 1393
Joined: Mon Jun 14, 2004 18:40
Location: Lawrence Berkeley National Lab

Re: TTree.Draw() with custom function

Unread postby salderwe » Fri Dec 07, 2012 10:54

Hi Wim,

I just upgraded to the patched version and the segmentation fault is gone :). Thanks for pointing me to the fix.

Cheers,
Sara
salderwe
 
Posts: 19
Joined: Mon Apr 02, 2012 13:04
Location: Antwerp, Belgium


Return to PyROOT Support

Who is online

Users browsing this forum: No registered users and 1 guest