我正在尝试使用uproot从Delphes .root输出文件中进行一些基本选择。Delphes的c++代码示例是在事件上循环并访问重新构造的BranchElements,这些and具有访问属于各种类的分支元素的方法。
例如,根文件包含一个<TBranchElement b'Jet' at 0x7fb36526b3c8>,(在c++中) Delphes示例代码可以使用它在"for“循环中获取object=jet->Constituents.At(i),然后如果这个object是一个object->IsA() == Tower::Class,则调用object->P4()来获取4momentum。因此,虽然使用uproot只能分别获取这两个值,但在Delphes示例中,使用Jet类可以使用一个方法访问塔类( Jet就是从这个类重新构造的)。
我看到的信息是:
Jet_size (no streamer) asdtype('>i4')
Jet TStreamerInfo asdtype('>i4')
Jet.fUniqueID TStreamerBasicType asjagged(asdtype('>u4'))
.
.
.
Jet.Constituents TStreamerInfo asgenobj(SimpleArray(TRefArray))
<TBranchElement b'Jet' at 0x7fb3657825f8>
<TBranchElement b'Jet.Constituents' at 0x7fb47840cba8>对于uproot,如果将TBranchElement作为数组加载,则只能访问Jet.Constituents[i]中的数组元素,即数字列表。我如何才能以引用Tower.PT (或eta、phi等)的方式加载Jet.Constituents?它包含的值?
发布于 2019-10-12 00:36:13
如果您有一个TRefs数组,则可以将它们直接用作另一个集合上的整数索引。(有关整数数组索引的一般介绍,请参阅this tutorial,从In[29]开始,在Numpy和尴尬数组中都是如此。)
也就是说,如果像在this example中那样有一个TRef数组,
import uproot
t = uproot.open("issue324.root")["Delphes"]
refs = t["Track.Particle"].array()
refs.id
# <JaggedArray [
# [752 766 780 ... 1813 1367 1666]
# ...
# [745 762 783 ... 1863 1713 1717]]>为您提供索引和
pt = t["Particle.PT"].array()要引用的数组,因此
pt[refs.id - 1]
# <JaggedArray [
# [0.7637838 1.1044897 5.463864 ... 4.252923 1.9702696 9.213475]
# ...
# [1.2523094 0.37887865 0.7390242 ... 1.0288503 3.4785874 1.804613]]>选择感兴趣的Python值(更正了这些索引以1开头,而pt索引以0开头的事实)。
如果您有一个像this example一样TRefArray数组,
t["Tower.Particles"].array()
# <ObjectArray [[[1414, 1418, 1471, 1571], [1447], [1572],
# ...,
# [864, 1325], [992, 1437], [1262, 1501]]]>它实际上是一个根据需要从数据生成子数组的根(因为ObjectArray本身并不存储双重锯齿数据)。您可以通过对它们调用awkward.fromiter将它们转换为原生JaggedArrays:
import awkward
a = awkward.fromiter(t["Tower.Particles"].array())
# <JaggedArray [[[1414 1418 1471 1571] [1447] [1572]
# ...
# [864 1325] [992 1437] [1262 1501]]]>然后在任何双重锯齿集合中使用这些双重锯齿索引(其中所有数量的元素都排成一列,就像您引用的集合一样)。
https://stackoverflow.com/questions/58291817
复制相似问题