CERN root — ошибка при фильтрации событий для поддерева по времени

Я задавал этот вопрос раньше на официальном форуме root (CERN), но пока проблема остается нерешенной. Может быть, кто-нибудь здесь может помочь, указав на мою ошибку или предложив альтернативный метод?

У меня есть TTree с событиями; TTree имеет одну ветку с UNIX-временем каждого события и некоторыми другими ветвями. Я хочу выбрать подмножество событий на основе временного интервала, чтобы я мог анализировать их отдельно. Чтобы сделать выбор, я создаю другое дерево и копирую все записи в нужный интервал времени.

Следующий код прекрасно работает и копирует все события из дерева в поддерево:

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
*subtree = tree->CloneTree(0);
Int_t t;
tree->SetBranchAddress("UNIX time", &t);
for(Long64_t i = 0; i<tree->GetEntries(); i++){
tree->GetEntry(i);
if (true)
{
(*subtree)->Fill();
}
}
cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
return;
}

Проблема возникает, когда я заменяю if (true) фактическим условием:

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
*subtree = tree->CloneTree(0);
Int_t t;
tree->SetBranchAddress("UNIX time", &t);
for(Long64_t i = 0; i<tree->GetEntries(); i++){
tree->GetEntry(i);
if (t > time_i && t < time_f) //-> the condition
{
(*subtree)->Fill(); //-> this line now gives an error
}
}
cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
return;
}

Я получаю сообщение об ошибке: «Ошибка: недопустимый указатель на поддерево объекта класса 0x0 3084 c: / …. * Устранена ошибка интерпретатора *«

Строка ошибки ссылается на (* subtree) -> Fill (), тот же код, который отлично работал в первом примере. Для любого условия, не связанного с t, или любого if-тела, не ссылающегося на поддерево, код работает. Кто-нибудь может объяснить, что здесь происходит не так?

Спасибо!

(Для справки ссылка на оригинальный вопрос: http://root.cern.ch/phpBB3/posting.php?mode=edit&е = 3&р = 79722)

1

Решение

Я думаю, что это проблема переводчика, на мой взгляд, ошибка.

Я могу воспроизвести вашу ошибку, когда первый раз макрос проходит мимо (*subtree)->Fill(); это ничего не заполняет. Странно, потому что туда не входит, но …

Я смог решить это, сделав две петли:
первый цикл повторяется до тех пор, пока не найдет первое событие, которое пройдет разрез, а затем остановится.
второй, где (*subtree)->Fill(); is начинается с этого события, убедившись, что первое обработанное событие проходит разрез и заполняется.

2

Другие решения

Благодаря Асену Кристову, вот рабочая версия функции. Я помещаю два цикла for в цикл while, если события не в хронологическом порядке; это должно работать, но не было тщательно протестировано. Я не могу поверить, что это лучший способ выполнить такую ​​общую задачу, поэтому любой «стандартный» способ все еще приветствуется.

void tree_time_filter(TTree* tree, TTree** subtree, Int_t time_i, Int_t time_f){
*subtree = tree->CloneTree(0);
Int_t t;
tree->SetBranchAddress("UNIX time", &t);
Long64_t i = 0;
while (i < tree->GetEntries())
{
for(i; i<tree->GetEntries(); i++){
tree->GetEntry(i);
if (t > time_i && t < time_f) break;
}
for (i; i<tree->GetEntries(); i++){
tree->GetEntry(i);
(*subtree)->Fill();
if (!(t > time_i && t < time_f)) break;
}
}
cout<<"Tree filtered. "<<(*subtree)->GetEntries()<< " entries were selected.\n";
return;
}
0

По вопросам рекламы [email protected]