继续读取带有 uproot 压缩问题的树数据
Continuing to read tree data with compression issue with uproot
当从用 zlib 压缩的树中用 uproot
读取数据时,我发现 zlib 有一些压缩错误,例如: Error -3 while decompressing data: incorrect data check
或 Error -5 while decompressing data: incomplete or truncated stream.
当我打开文件时在 ROOT 中,我从 zlib 得到了类似的错误:
R__unzip: error -3 in inflate (zlib)
Error in <TBasket::ReadBasketBuffers>: fNbytes = 20102, fKeylen = 199, fObjlen = 28540, noutot = 0, nout=0, nin=19903, nbuf=28540
Error in <TBranchElement::GetBasket>: File: Stage_1_files/AnalysisResults.31.root at byte:51212830, branch:data.fJetConstituents.fPt, entry:133851, badread=1, nerrors=1, basketnumber=189
...
但是,ROOT 会跳过有问题的条目(或多个条目)并继续尝试读取文件。在 uproot 中,zlib 异常被向上传递。我明白了,但我无法继续处理该文件。该文件显然存在潜在问题(似乎是我无法控制的 ROOT 合并问题),但是有没有办法让 uproot 识别并跳过有问题的条目并继续处理其余数据?我可以想象在阅读时限制条目,但我如何在不反复试验的情况下用 uproot 识别它们?我只能通过在 uproot 中一个一个地读取每个分支来确定有问题的分支,并且仍然不能确定哪些条目是问题的(或通过 ROOT 检查)。
谢谢!
TTrees 中的数据由篮子压缩,因此如果篮子的压缩损坏,则无法从该篮子中读取任何数据,但所有其他篮子都可能正常。
Uproot 的数组读取函数会在任何篮子引发错误时放弃,但您可以使用更底层的 TBranch.basket
方法一个一个地读取篮子,并在此过程中捕获任何异常。从 TTree 中获取一个 TBranch 对象,具有类似字典的访问权限(例如 mytree["branch_name"]
),并使用与传递给 TTree.array
的相同参数调用 basket(i, ...)
,但另外还有篮子编号 i
. (它们从 0
开始,一直到 TBranch.numbaskets
,但不包括 TBranch.numbaskets
。)
还有一个TBranch.iterate_baskets
,但它在这里对你没有帮助,因为它会在遇到异常时停止迭代。您需要控制篮子上的循环以将其包装在 try-catch 逻辑中。
还有一个问题:您可能需要关联来自不同分支机构的数据,并且它们的篮子可能不会以相同的条目编号开始和结束。如果您使用您感兴趣的分支请求 TTree.clusters(branches_list)
,它将为您提供篮子边界处的入场开始和停止编号,这些编号对于您提供的分支集是常见的。在正常的 TTree.arrays
方法中将这些条目编号用作 entrystart
和 entrystop
将只读取请求的篮子,您可以围绕它放置 try-catch 逻辑。
当从用 zlib 压缩的树中用 uproot
读取数据时,我发现 zlib 有一些压缩错误,例如: Error -3 while decompressing data: incorrect data check
或 Error -5 while decompressing data: incomplete or truncated stream.
当我打开文件时在 ROOT 中,我从 zlib 得到了类似的错误:
R__unzip: error -3 in inflate (zlib)
Error in <TBasket::ReadBasketBuffers>: fNbytes = 20102, fKeylen = 199, fObjlen = 28540, noutot = 0, nout=0, nin=19903, nbuf=28540
Error in <TBranchElement::GetBasket>: File: Stage_1_files/AnalysisResults.31.root at byte:51212830, branch:data.fJetConstituents.fPt, entry:133851, badread=1, nerrors=1, basketnumber=189
...
但是,ROOT 会跳过有问题的条目(或多个条目)并继续尝试读取文件。在 uproot 中,zlib 异常被向上传递。我明白了,但我无法继续处理该文件。该文件显然存在潜在问题(似乎是我无法控制的 ROOT 合并问题),但是有没有办法让 uproot 识别并跳过有问题的条目并继续处理其余数据?我可以想象在阅读时限制条目,但我如何在不反复试验的情况下用 uproot 识别它们?我只能通过在 uproot 中一个一个地读取每个分支来确定有问题的分支,并且仍然不能确定哪些条目是问题的(或通过 ROOT 检查)。
谢谢!
TTrees 中的数据由篮子压缩,因此如果篮子的压缩损坏,则无法从该篮子中读取任何数据,但所有其他篮子都可能正常。
Uproot 的数组读取函数会在任何篮子引发错误时放弃,但您可以使用更底层的 TBranch.basket
方法一个一个地读取篮子,并在此过程中捕获任何异常。从 TTree 中获取一个 TBranch 对象,具有类似字典的访问权限(例如 mytree["branch_name"]
),并使用与传递给 TTree.array
的相同参数调用 basket(i, ...)
,但另外还有篮子编号 i
. (它们从 0
开始,一直到 TBranch.numbaskets
,但不包括 TBranch.numbaskets
。)
还有一个TBranch.iterate_baskets
,但它在这里对你没有帮助,因为它会在遇到异常时停止迭代。您需要控制篮子上的循环以将其包装在 try-catch 逻辑中。
还有一个问题:您可能需要关联来自不同分支机构的数据,并且它们的篮子可能不会以相同的条目编号开始和结束。如果您使用您感兴趣的分支请求 TTree.clusters(branches_list)
,它将为您提供篮子边界处的入场开始和停止编号,这些编号对于您提供的分支集是常见的。在正常的 TTree.arrays
方法中将这些条目编号用作 entrystart
和 entrystop
将只读取请求的篮子,您可以围绕它放置 try-catch 逻辑。