Search code examples
c++data-analysisroot-framework

CERN root - error when filtering events for subtree based on time


I asked this question before on the official root (CERN) forum, but so far the problem remains unsolved. Maybe anyone here can help, either by pointing out my mistake or suggesting an alternative method?

I have a TTree with events; the TTree has one branch with the UNIX time of each event and some other branches. I want to select a subset of the events based on a time interval so I can analyse these separately. To make the selection, I create another tree and copy all the entries within the right time interval.

The following code works perfectly fine and copies all the events from tree to subtree:

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

The problem occurs when I replace if(true) by an actual condition:

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

I receive the error: "Error: illegal pointer to class object subtree 0x0 3084 c:/.... * Interpreter error recovered *"

The error line refers to (*subtree) -> Fill(), the same code that worked perfectly fine in the first example. For any condition not involving t or any if-body not referring to subtree, the code works. Can anyone explain what goes wrong here?

Thank you!

(For reference, a link to the original question: http://root.cern.ch/phpBB3/posting.php?mode=edit&f=3&p=79722)


Solution

  • With thanks to Asen Christov, here is a working version of the function. I put the two for loops in a while loop in case the events are not in chronological order; this should work but is not extensively tested. I can't really believe this is the best way to do such a common task, so any 'standard' way of doing this is still welcomed.

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