[Bug] TTree -> Fill() returns error only when put under if()

Hello all,

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) { (*subtree)->Fill(); } } 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. Can anyone explain what goes wrong here?

Thank you!

PS. the problem is in the Int_t t; if I use 1<2 as condition all events are copied. If I actually print t, it prints proper UNIX timestrings.

Maybe it is because the subtree object is of type TTree* while (*subtree) is of type TTree so you cannot use (*subtree)->Fill(); but you should use (*subtree).Fill(); or subtree->Fill(); instead. I have no idea why it works on the code above though, but still you can try with this and see if it works.

Cheers
Guido

Thanks for the reply Guido! subtree is actually of the type TTree**; this was necessary to be able to access the underlying object in my main loop properly. Here is how I call the function:

TTree* subtree; tree_time_filter(tree,&subtree,time_i,time_f);

So (*subtree)->Fill() should be correct; again, everything works fine without the condition. Any other suggestions? Or maybe an alternative method to achieve a filtering of events? I’m new to root, but this should be a fairly common task I suppose?

Thank you!

You’re welcome, I’m new to root also, and didn’t notice the declaration of your function actually… :blush:
But I don’t see your point, you could still pass a TTree* object to your function instead of a TTree** one (properly modifying the code inside, of course) and then in your main loop (where you need it if I understood well) define another TTree** object as a pointer to the other one and use it, like

TTree* subtree;
TTree** psubtree=&subtree;
tree_time_filter(tree,&subtree,time_i,time_f);

If I misunderstood what did you mean by [quote]this was necessary to be able to access the underlying object in my main loop properly[/quote] ?

Guido

Hi Guido,

Haha can happen. I actually wrote the code with TTree* subtree at first, but if I then tried to access subtree in my main loop, I got an error. That’s why I made it a second order pointer; and that works. It is really just the condition that gives me trouble. Something about the fact that both t and the subtree are related to TTree* tree (via SetBranchAddress and CloneTree, respectively), seems to produce the error. Any other condition unrelated to t, or any other body of the if unrelated to subtree, works fine.

Hey people,

I asked the question on stackoverflow as well (stackoverflow.com/questions/2630 … 5#26340465).

Here is a working version of the function; the original error seems very much like a bug in the interpreter (I have no authorization to report bugs as I am not in CERN)

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