如何使用uproot加载引用值(TRefArray)
How to use uproot to load referenced values (TRefArray)
我正在尝试使用 uproot 从 Delphes .root 输出文件中进行一些基本选择。 Delphes 的 c++ 代码示例循环遍历事件并访问重构的 BranchElements,这些元素具有访问属于各种 classes 的分支元素的方法。
例如根文件包含一个 <TBranchElement b'Jet' at 0x7fb36526b3c8>
(在 C++ 中)Delphes 示例代码可用于在 "for" 循环中获取 object=jet->Constituents.At(i)
,然后如果此 object
是 object->IsA() == Tower::Class
然后调用 object->P4()
获得 4momentum。
因此,虽然使用 uproot 只能单独获取两个值,但在 Delphes 示例中,使用 Jet class 可以使用一种方法访问 Tower class(从中重建 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
?
如果你有一个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
开头的事实)。
如果您有一个 TRefArray
数组,如 this example、
t["Tower.Particles"].array()
# <ObjectArray [[[1414, 1418, 1471, 1571], [1447], [1572],
# ...,
# [864, 1325], [992, 1437], [1262, 1501]]]>
它实际上是一个ObjectArray
,它根据需要从数据中生成子数组(因为 ROOT 本身不存储双重锯齿数据)。您可以通过对它们调用 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]]]>
然后在任何双重锯齿状集合中使用这些双重锯齿状索引(其中所有元素的数量都排成一行,就像您引用的集合一样)。
我正在尝试使用 uproot 从 Delphes .root 输出文件中进行一些基本选择。 Delphes 的 c++ 代码示例循环遍历事件并访问重构的 BranchElements,这些元素具有访问属于各种 classes 的分支元素的方法。
例如根文件包含一个 <TBranchElement b'Jet' at 0x7fb36526b3c8>
(在 C++ 中)Delphes 示例代码可用于在 "for" 循环中获取 object=jet->Constituents.At(i)
,然后如果此 object
是 object->IsA() == Tower::Class
然后调用 object->P4()
获得 4momentum。
因此,虽然使用 uproot 只能单独获取两个值,但在 Delphes 示例中,使用 Jet class 可以使用一种方法访问 Tower class(从中重建 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
?
如果你有一个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
开头的事实)。
如果您有一个 TRefArray
数组,如 this example、
t["Tower.Particles"].array()
# <ObjectArray [[[1414, 1418, 1471, 1571], [1447], [1572],
# ...,
# [864, 1325], [992, 1437], [1262, 1501]]]>
它实际上是一个ObjectArray
,它根据需要从数据中生成子数组(因为 ROOT 本身不存储双重锯齿数据)。您可以通过对它们调用 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]]]>
然后在任何双重锯齿状集合中使用这些双重锯齿状索引(其中所有元素的数量都排成一行,就像您引用的集合一样)。