Equivalent of TH1::AddDirectory(kFALSE); for TTree?

Dear all,

I need to read a TObject from a TFile without prior knowledge of its specific class (TH1, TTree, Tgraph, …).

My problem is that I have to pass this object to another actor and close the file. Even if I clone, the resulting object is still owned by the directory of the file in case of TH1, TTree and TEventList as per the documentation. As a result, closing the file and using the object causes a crash.

For the TH1, I simply do TH1::AddDirectory(kFALSE); before the copy. Is there an equivalent for TTree and TEventList ?

If not, what is the best strategy ?
Thank you,
Barth


ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi,
I think t->SetDirectory(nullptr) should do the job. It should work for many types, at least for TH1, TTree and TEventList. There is no global switch as far as I know.

Cheers,
Enrico

Hi,
Thank you for your reply.
I considered this option, however the problem I have is that I don’t know what is the type of the object. What I end up doing now is :

if(string(result->ClassName()) == "TTree") {
    TTree *tree = dynamic_cast<TTree*>(result);
    tree->SetDirectory(0);
}

but it means that I have to have these (ugly) conditions for each class for which it could happen.
I would rather set gDirectory to nullptr before copy, then restore it after but it does not seem to work that way.
Cheers,

As far as I know, the TTree does not attach to gDirectory but to the file it’s from, so maybe that’s why it doesn’t work.

What I know for sure is that there is no generic way to detach objects from the file they are from.

You can try to avoid deletion when the file is closed with obj->ResetBit(kCanDelete), which can be called on any TObject. But I’m not sure if this is robust – e.g. I’m not sure what happens when you read data from a TTree that is connected to a file that has been closed.

@pcanal or @Axel might be able to provide a deeper insight.

Cheers,
Enrico

To retract TFile/TDirectory’s ownership of an object, you can do (for any TObject):

dirptr->Remove(obj); // where dirptr can be gDirectory

Note that this works nicely for every but TTree. For TTree it’s actully data is stored in the file and so unless you preload it all in memory, the TTree is ‘usless’ after the call to ‘SetDirectory(0)’.

If you can not keep the TFile around then you will need to a have a special case for TTree (to either load all its data or clone it into a in-memory TTree).

Cheers,
Philippe.

1 Like

Hi Philippe,
Thanks for the help, it is very useful.
I will follow the road of cloning the TTree in memory because I am not able to keep the file opened.
Best regards,
Barth

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.