1

我是连根拔起的新手,我正在尝试完成一项相当简单的任务,但我不知道该怎么做。本质上,我有一个根文件,其中包含一堆直方图和一个 TTree,它由 8 个分支组成,大约有 400 万个条目。

我需要做的是,创建一个新的根文件,并将 80% 的 TTree 从原始文件复制到一个 TTree(称为训练),将剩余的 20% 复制到同一个新文件中的第二个 TTree(称为测试)。

我尝试的是在python中创建一个目录,我从原始文件分支中读取所有数据。然后我使用这个目录将数据写入两个新的 TTree。

这是一种工作,我得到了一个具有我想要的结构的文件,我并不完全满意,原因有两个:

  • 肯定有更直接的方法吗?首先将数据读入python,然后将其写入文件似乎非常麻烦且占用大量内存。
  • 老实说,我对 root 不是很有经验,但根据我的理解,在我的原始文件中,我有一棵树,其中包含我的 400 万个事件。每个事件的每个分支都有一个值,所以当我说“让我输入 555!”时,我得到 8 个值(每个分支 1 个)。如果我只是按照我的方式复制分支,我会丢失这个结构还是目录中所有数组的索引都会替换条目号?那么,从索引 555 的所有数组中获取值与之前返回条目 555 相同吗?

欢迎任何帮助。谢谢!

4

1 回答 1

0

这个任务总是涉及读入内存和写回,无论这些数组是在用户的控制中还是隐藏的。

有一个可能的例外,如果您想从一个文件读取 TBasket 并将它们写入另一个文件而不解压缩它们 - 那么它们仍在内存中但未解压缩,这可以提高性能。ROOT 可以作为“快速复制”来执行此操作,但 Uproot 没有等效项。这样的副本将要求您不想以任何方式修改 TBasket 中的数据,包括在任意事件边界处切片,如果您感兴趣的 8 个 TBranches 的 TBasket 不排队,这可能是一个问题在共同的事件边界。(这样的功能可以添加到 Uproot 中——没有技术限制,但此功能仅在某些情况下有用。)

因此,从一个文件中读取数组并将它们写入另一个文件的过程几乎与上面的警告一样好。

我不确定“Python 中的目录”是什么意思。

要回答您的第二个问题,从 TTree 中读取的数组是对齐的,因为555一个 TBranch 的条目与另一个 TBranch 的条目属于同一事件555。这是在 NumPy 中处理数组集的一种常见方式,尽管它是处理 ROOT 数据的一种不常见方式;在 ROOT 中,事件是一个对象,或者至少您一次不会看到多个对象。

如果您有内存问题(可能不是 8 TBranches × 400 万个事件,不是锯齿状的,如果双精度 = 244 MB RAM),那么您可以考虑迭代:

numtraining = int(0.8*ttree.numentries)
numtest = ttree.numentries - numtraining

for chunk in ttree.iterate("*", entrysteps="1 GB", entrystop=numtraining):
    training.extend(chunk)

for chunk in ttree.iterate("*", entrysteps="1 GB", entrystart=numtraining):
    test.extend(chunk)

这使您可以控制输出 TBasket 的大小,因为每个 TBranch 每次调用都会获得一个 TBasket extend。上面的示例确保必须一起使用的一组 TBranches 总共最多包含 1 GB。

与“快速复制”(见上文)不同,您所做的不仅仅是复制,它还对数据进行了重新分区,这可以在您读取这些输出文件时提高性能。通常,较大的块(较大的 TBasket)读取速度更快,但太大并且它们可能需要太多内存。

于 2020-04-17T16:15:15.553 回答