Python and ROOT Tricks: vectors of vectors

Many thanks to Matt Bellis for this tip!

You can write very complex objects to a ROOT TTree. For instance, you might encounter a TBranch in a TTree that is of type

std::vector< std::vector<float> >

This is a C++ STL vector object nested inside another such object. How do you handle this in Python?

The trick, outlined below, may or may not work with your particular combination of ROOT and Python. For instance, when I tried this with ROOT 5.26.00e and Python 2.4 (the default combination in Scientific Linux 5), I got all kinds of errors. When I switched to 5.28 and Python 2.4 or 2.7, it worked great. So, your mileage may vary.

Here is the trick. You need to tell Python and ROOT how to handle such TBranch types. To do this, you need to write an external ROOT C++ macro which can be loaded and compiled by CINT; this then directs ROOT on just what is a vector of a vector. Here is the macro:

// stl_loader.h
#include<vector>

#ifdef __CINT__
#pragma link C++ class vector<vector<float> >;
#else
template class std::vector<std::vector<float> >;
#endif

Now you need to have your Python program load and compile this file into a library at the very beginning of the program:

import ROOT
ROOT.gROOT.LoadMacro("load_stl.h+")

Now you can access the vector of vectors in your code as follows:

// Assume the TBranch in your TTree is called "VecOfVecFloat"
TheVectorOfVectors = aTree.VecOfVecFloat
print len(TheVectorOfVectors)
if len(TheVectorOfVectors) > 0:
    VectorOfFloats = TheVectorOfVectors[0]
    print len(VectorOfFloats)
    if len(VectorOfFloats) > 0:
        aFloat = VectorOfFloats[0]
        print aFloat

Now you should be able to use those floats buried in a vector buried inside another vector. Good luck!

 

2 Replies to “Python and ROOT Tricks: vectors of vectors”

  1. Thanks for your post. How can I select Entry number. For example I need VecOfVecFloat in Entry 10?

  2. If I understand your question correctly, you can load an event into memory from the TTree using:

    TTree::GetEntry(Int_t entry)

    So if you TTree object is named “mytree”:

    mytree.GetEntry(10)

    Then when you access the vector> branch, its values will pertain to those associated with entry 10.

Leave a Reply

Your email address will not be published. Required fields are marked *