Продолжение чтения данных дерева с проблемой сжатия при выкорчевывании - PullRequest
1 голос
/ 11 марта 2020

При чтении данных с помощью uproot из дерева, сжатого с помощью zlib, обнаруживаются некоторые ошибки сжатия из 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 пропускает проблемную запись * (1012 *) (или записи) и продолжает пытаться прочитать файл. В up root исключение zlib пропускается. Я ловлю это, но я не могу продолжить обработку файла. Существуют явные проблемы с файлом (кажется, из-за проблем со слиянием ROOT, которые находятся вне моего контроля), но есть ли способ root идентифицировать и пропустить проблемные записи c и продолжить с остальные данные? Я мог бы представить, что можно ограничить записи при чтении, но как бы я идентифицировал их с root без проб и ошибок? Я мог определить проблемную ветвь c, только прочитав каждую ветвь по одной в root, и это все еще не определяет, какие записи являются проблемой (или проверяя с помощью ROOT).

Спасибо!

1 Ответ

1 голос
/ 11 марта 2020

Данные в TTree сжимаются корзинами, поэтому, если сжатие корзины повреждено, никакие данные не могут быть прочитаны из этой корзины, но все остальные корзины потенциально исправны.

Up * Массив root функции чтения перестают работать, если какие-либо корзины вызывают ошибку, но вы можете использовать более низкоуровневый метод TBranch.basket, чтобы читать корзины одну за другой, перехватывая любые исключения по пути. Получите объект TBranch из TTree с доступом по типу dict (например, mytree["branch_name"]) и вызовите basket(i, ...) с теми же аргументами, которые вы передадите TTree.array, но дополнительно с номером корзины i. (Они начинаются с 0 и go вплоть до, но не включая TBranch.numbaskets.)

Также есть TBranch.iterate_baskets, но он вам здесь не поможет, потому что он перестанет выполнять итерации при попадании исключение. Вам нужно контролировать l oop над корзинами, чтобы обернуть его в try-catch logi c.

Есть еще одна проблема: вам может потребоваться сопоставить данные из разных веток, и их корзины могут не начаться и заканчиваются на те же номера записи. Если вы запрашиваете TTree.clusters(branches_list) с интересующими вас ветками, он даст вам начальные и конечные номера входа на границах корзины, которые являются общими для набора веток, который вы предоставляете. Использование этих номеров записей как entrystart и entrystop в обычном методе TTree.arrays будет считывать только запрошенные корзины, и вы можете поместить в них логи try-catch c.

...