我正在尝试使用uproot从Delphes .root输出文件中进行一些基本选择。 Delphes的c ++代码示例遍历事件并访问重构的BranchElement,这些重构的BranchElement具有访问属于各种类的分支元素的方法。
例如根文件包含<TBranchElement b'Jet' at 0x7fb36526b3c8>
(在c ++中),Delphes示例代码可用于在“ for”循环中获取object=jet->Constituents.At(i)
,然后如果此object
是object->IsA() == Tower::Class
,则一个人呼叫object->P4()
以获得4动量。
因此,虽然使用根目录只能单独获得两个值,但在Delphes示例中,一个方法使用Jet类来访问对Tower类(从中重建了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>
对于连根来说,如果将TBranchElement作为数组加载,则只能访问Jet.Constituents[i]
中的数组元素,这些元素是数字列表。
我如何能够以引用其中包含的Jet.Constituents
(或eta,phi等)值的方式加载Tower.PT
?
答案 0 :(得分:1)
如果您有TRefs
数组,则可以将它们直接用作另一个集合上的整数索引。 (请参阅this tutorial,从In[29]
开始,以了解有关Numpy和Awkward Array中整数数组索引的一般介绍。)
也就是说,如果您有TRef
的数组,例如this example,
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]]>
选择感兴趣的pt
值(纠正这些索引以1
开头和Python索引以0
开头的事实。
如果您有this example中的TRefArray
数组,
t["Tower.Particles"].array()
# <ObjectArray [[[1414, 1418, 1471, 1571], [1447], [1572],
# ...,
# [864, 1325], [992, 1437], [1262, 1501]]]>
它实际上是一个ObjectArray
,可以根据需要从数据生成子数组(因为ROOT本身并不存储双重锯齿数据)。您可以通过在它们上调用JaggedArrays
将它们转换为本地awkward.fromiter
:
import awkward
a = awkward.fromiter(t["Tower.Particles"].array())
# <JaggedArray [[[1414 1418 1471 1571] [1447] [1572]
# ...
# [864 1325] [992 1437] [1262 1501]]]>
,然后在任何双重锯齿状的集合中使用这些双重锯齿状的索引(其中所有元素的数量都与您要引用的集合对齐)。