SetBranchAddress in pyROOT


Surprisingly I did not find much info on this subject in this forum or the pyROOT uguide… Please point me to the correct place to look if I missed it.

I want to skim some data in pyroot with a user defined list of triggers. I don’t want to do something like this:

pass_skim = tree.trig_1 or tree.trig_2 …

Since I don’t know if said triggers will exist in our data. So I had a solution that seems to work:

[code]trigger_list = [ ‘trig_1’, ‘trig_2’, …]
trigger_buf = {}

def load_trig(tree) : ## this is a tree as opposed to a TChain
#clear trigger_buf if full of buffers from previous tree in chain
for trigger in trigger_list :
br = tree.GetBranch(trigger)
if not br : continue
trigger_buf[ trigger ] = [ br, ctypes.c_bool(0) ]
br.SetAddress( trigger_buf[ trigger ][1] ) ##mostly concerned with this line

def pass_trigger(i_entry) : ##entry in the local tree not the chain
for trigger in trigger_buf :
branch = trigger_buf[trigger] ##probably a better way to get this
if branch[0].GetReadEntry() != i_entry : branch[0].GetEntry[i_entry]
if branch[1] : return True

return False


I just want to make sure that I am not latching the branch address to some temporary undefined variable. I know for sure how to do this in c++, but not so sure about this in python.



with just a cursory look, I’d say this is fine: the trigger_buf global will keep the python-side objects alive. Normally, I prefer to make the python objects data members of the tree object, though. That way, the objects handed to Set(Branch)Address and the tree have the same life time.

Less sure about ctypes.c_bool, though (I’ve never tried it).


Hi Wim,

Thanks for the look.

I guess I was wary of using the python bool object since I thought that I read that some objects like float or double are of different sizes in python/c++. (Not a python expert)

What do you mean by this? If my tree were originally created in a c++ job I could still do what you suggest?

Looking more closely at your advice in other posts, namely:

I can just do:

Loop over Entries in Tree : passed_skim = False for trigger in list_of_triggers : if(getattr(ch, trigger)) : passed_skim = True break if passed_skim : do stuff...

Which is much simpler and easier to read! Should have looked more carefully at previous posts.
Speed is not an issue for this task.



yes that should work, with speed being the main issue: the branches are retrieved every time the variable is accessed on the tree, but that seems to be exactly what you want. If you’re running the code within ATLAS’ framework, however, they may be cached (I forget the details, and I don’t know whether you’re in ATLAS, of course :slight_smile: ); standalone ROOT is fine for your case.

What I meant by making the values data members, is to store them in the dict of the tree rather than in the global trigger_buf dict.

As for floats: python has a data type called ‘float’ (in python) that is implemented as a C ‘double’.