TTree::ChangeFile limitation for TTree in subdirectory

Hi,

I am hit by the ROOT limitation in TTree::ChangeFile(), where a tree is only split and moved to a new file if the tree is in the main directory. However, I have a tree inside a subdirectory, and therefore cannot split the files automatically via TTree::SetMaxTreeSize().

The job I am running is reading the Tree in a source file, cloning its structure to the destination file, and writes out only selected events in the cloned tree. The code looks a bit like this:

TFile * outFile = new TFile(outputFileName, “RECREATE”);
outFile->mkdir(“ACSkimAnalysis”);
outFile->cd(“ACSkimAnalysis”);
// clone tree structure, do not copy events…
TTree * outTree = chain->CloneTree(0);
// histograms belong to ROOT directory…
outFile->cd();
// here do the loop on all the tree entries, select events, fill tree…

// get currrent file - needed because of output tree spanning different
// files, via setting TTree::SetMaxTreeSize
outfile = outTree->getCurrentFile();
outFile->Write();
outFile->Close();
delete outFile;

Since the input files are not produced by me, and the output files need to have the same structure, I do not have the option to move the tree to the main directory, which would be the easiest task.The first idea I had was to derive my own class TMyTree : public TTree and overwrite the ChangeFile() method. However, I do not know how to initialize this class with the output of TTree::CloneTree, which I am using…

I also thought about patching ROOT (my preferred solution) to allow SaveFile() to recurse through subdirectories, but again it is not an option since it is a central installation that many users have to use.

Any help appreciated…

Martin

Hi,

[quote]The first idea I had was to derive my own class TMyTree : public TTree and overwrite the ChangeFile() method. However, I do not know how to initialize this class with the output of TTree::CloneTree, which I am using…[/quote]I don’t think this is a viable option (it would be quite hard to do).

Your best option is to set SetMaxTreeSize to a very large value and have only a single output file. Alternatively, you can implement the ChangeFile functionality externally: i.e inside your “here do the loop on all the tree entries, select events, fill tree.”, check the size of the file and when it reaches a certain limit, do the same type of operation as ChangeFile would do.

Cheers,
Philippe.

Yes, I have tried to implement ChangeFile externally. However it uses private / protected members & functions which I cannot access from outside a TTree. In the end, I gave up and just wrote a single output file.

The only viable solution I see is patching ROOT and adding a recursive loop inside TTree::ChangeFile(). BTW, I would appreciate if the documentation of SetMaxTreeSize() would be updated to say that this effectively only works when the tree is in the root directory of a TFile. This piece of information is missing and it took me quite some time to figure it out.

Martin