我是新来的连根拔起的人,我正在尝试完成一个相当简单的任务,但是我不确定如何做到这一点。本质上,我有一个根文件,其中包含一堆直方图和一个TTree,该TTree由8个分支组成,大约有400万个条目。
我需要做的是,创建一个新的根文件,然后将80%的TTree从原始文件复制到一个TTree(称为训练),并将其余20%的副本复制到同一新文件中的第二个TTree(称为测试)。
我尝试过的是在python中建立一个目录,我逐个分支地从原始文件中读取所有数据。然后,我使用该目录将数据写入两个新的TTree中。
这是一种工作,我正在获取具有所需结构的文件,由于以下两个原因,我并不完全满意:
任何帮助都将受到欢迎。谢谢!
答案 0 :(得分:0)
无论这些数组是在用户的控件中还是隐藏的,此任务始终涉及读入内存和写回。
有一个可能的例外,如果您想从一个文件中读取TBaskets,然后将它们写入另一个文件而不进行解压缩,那么它们仍在内存中但没有被解压缩,这可以提高性能。 ROOT可以将其作为“快速副本”执行,但是Uproot没有等效项。这样的副本将要求您不希望以任何方式修改TBasket中的数据,包括在任意事件边界处切片,如果您感兴趣的8 TB分支的TBasket不排队,则可能会出现问题。在常见事件边界。 (可以将这样的功能 添加到Uproot中-没有技术限制,但是此功能仅在某些情况下有用。)
因此,通过上述警告,从一个文件中读取数组并将其写入另一个文件的过程就差不多一样好。
我不确定“ Python中的目录”是什么意思。
要回答您的第二个问题,从一个TTree中读取的数组在某种意义上是对齐的,即一个TBranch的条目555
与另一个TBranch的条目555
属于同一事件。这是在NumPy中处理数组集的一种常用方法,尽管这是处理ROOT数据的一种罕见方法。在ROOT中,事件是一个对象,或者至少一次看不到一个以上的对象。
如果遇到内存问题(如果不是8 TBranches×4百万个事件,则不会出现锯齿;如果是双精度,则= 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的大小,因为每个TB分支每次调用extend
都会得到一个TBasket。上面的示例确保必须一起使用的一组TB分支最多包含1 GB。
与“快速复制”(请参见上文)不同,您要做的不仅是复制,还包括对数据进行重新分区,这可以在读取这些输出文件时提高性能。通常,较大的块(较大的TBasket)读取速度较快,但太大,则可能需要太多内存。