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&f=3&p=79722)

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;
}

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

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

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

Другие вопросы по тегам