TTree::SetBranchAddress for TDatime in PyROOT


ROOT Version: ROOT 6.22/02
Platform: Red Hat Enterprise Linux Server 7.9 (Maipo)
Compiler: g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)


I’m proficient in python, but completely new to PyROOT. I’ve looked through the tutorials, searched this forum, and scanned the documentation, and am still struggling with how to translate TTree::SetBranchAddress from c++ to PyROOT.

If someone could fix my minimal working example below, that would be greatly appreciated. I know the fix involves the AddressOf method, but can’t figure it out. Another confusing thing is that most of the examples use AddressOf, but the documentation says a newer method addressof (all lowercase) should be used.

Anyways, here is my minimal working example:

#!/usr/bin/env python3

import numpy as np
import ROOT
import time

def make_tree():

    file = ROOT.TFile('output.root', 'RECREATE')
    tree = ROOT.TTree('tree', '')
    date_time = ROOT.TDatime()
    tree.Branch('date_time', date_time)

    for i in range(5):
        date_time = ROOT.TDatime()
        print(date_time)
        tree.Fill()
        time.sleep(1)

    tree.Write()

def read_tree():

    file = ROOT.TFile('output.root', 'READ')
    tree = file.Get("tree")
    date_time = ROOT.TDatime()
    tree.SetBranchAddress('date_time', date_time)
    #tree.SetBranchAddress('date_time', ROOT.AddressOf(date_time))

    for i in range(tree.GetEntries()):
        tree.GetEntry(i)
        print(date_time)

def main():
    make_tree()
    print('=====')
    read_tree()

if __name__ == '__main__':
    main()

Here is the output:

-bash-4.2$ ./minimal.py
Wed Dec  9 22:09:26 2020
Wed Dec  9 22:09:27 2020
Wed Dec  9 22:09:28 2020
Wed Dec  9 22:09:29 2020
Wed Dec  9 22:09:30 2020
=====
Fri Mar 23 07:46:48 2040
Fri Mar 23 07:46:48 2040
Fri Mar 23 07:46:48 2040
Fri Mar 23 07:46:48 2040
Fri Mar 23 07:46:48 2040

As you can see, the TDatimes from make_tree and read_tree are different, but I want them to be the same.

Hi,

The issue here is that, in make_tree, you do:

    date_time = ROOT.TDatime()
    tree.Branch('date_time', date_time)

So you tell ROOT that the branch date_time is linked to the object you just created. But inside the loop, you assign date_time to a new object (note that this does not invoke the operator= in C++), so the TDatime object that you used in Branch is garbage collected. What you would need to do is just create one TDatime object, you link it with the branch in Branch as you do now, and then inside the loop you modify that same object. You can do that via the setters of the TDatime class or, alternatively, you can do date_time.__assign__(ROOT.TDatime()) inside the loop of make_tree.

Side note: TTree has some documentation for its pythonizations in the reference guide, in case you want to have a look (you need to search for the PyROOT blue box after the C++ docs):

1 Like

Also another comment, instead of using SetBranchAddress in read_tree, you can use the getattr pythonization of TTree, like so:

def read_tree():

    file = ROOT.TFile('output.root', 'READ')
    tree = file.Get("tree")
    for entry in tree:
        print(entry.date_time)

Thank you!

Thanks for the suggestion. That’s very useful to know!

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