Доступ к вложенным контейнерам в TTree с помощью PyROOT
В PyROOT достаточно просто прочитать значения из дерева, т.е. напечатать лист val
:
file = TFile('file.root')
tree = file.Get('tree')
for entry in tree:
print entry.val
Также легко читать значения из STL vector<float>
, vec
:
for entry in tree:
print entry.vec[1]
Но как насчет вложенных векторов, т.е. nested
типа vector<vector<float> >
? Бег
for entry in tree:
print entry.nested[0][0]
бросит TypeError: 'vector<vector<float> >' object is unindexable
,
Каков наилучший способ справиться с этим? (лучше, если он не требует загрузки в ROOT-словарь)
1 ответ
Это работает для меня с использованием индексации в Python.
>>>from ROOT import *
>>>vec1 = std.vector('double')()
>>>vec2 = std.vector('double')()
>>>vec_vec = std.vector(std.vector('double'))()
>>>for i in range(3):
>>> vec1.push_back(i)
>>>for i in range(5):
>>> vec2.push_back(i)
>>>vec_vec.push_back(vec1)
>>>vec_vec.push_back(vec2)
>>>len(vec_vec)
2
>>>len(vec_vec[0])
3
>>>len(vec_vec[1])
5
>>>vec_vec[1][2]
2.0
В вашем примере ошибка говорит:
TypeError: 'vector<vector<float> >' object is unindexable
После вызова конструктора std.vector(type)() у вас есть разные типы, которые указывают, что распределитель для пространства памяти работает.
>>>type(vec1)
<class 'ROOT.vector<double,allocator<double> >'>
>>>type(vec_vec)
<class 'ROOT.vector<vector<double,allocator<double> >,allocator<vector<double,allocator<double> > > >'>
Чтобы импортировать такие векторы из TTree, используйте setBranchAddress, как в этом примере:
>>>tree = file.Get('tree')
>>>tree.SetBranchAddress("nested",vec_vec)
>>>N = tree.GetEntries()
>>>for i in range(N):
>>> vec_vec.clear()
>>> tree.GetEntry(i)
>>> print vec_vec[0][0]
Также обратите внимание, что это может быть значительно быстрее после использования
>>>tree.setBranchStatus('*',0)
>>>tree.setBranchStatus('nested',1)