TTree::CopyTree() does not work

Hello,

file = TFile("SherpaNoCKKWUEHigh.root")
tree = file.Get("CBNT/t3333")
newtree = tree.CopyTree("1")

results in this error message:

Error in <TTree::Fill>: Failed filling branch:t3333.jetEC4McJets, nbytes=-1
Error in <TTree::Fill>: Failed filling branch:t3333.jetEtC4McJets, nbytes=-1
Error in <TTree::Fill>: Failed filling branch:t3333.jetMC4McJets, nbytes=-1
Error in <TTree::Fill>: Failed filling branch:t3333.jetEemC4McJets, nbytes=-1
Error in <TTree::Fill>: Failed filling branch:t3333.jetPtC4McJets, nbytes=-1
Error in <TTree::Fill>: Failed filling branch:t3333.Weight, nbytes=-1
 This error is symptomatic of a Tree created as a memory-resident Tree
Instead of doing:
    TTree *T = new TTree(...)
    TFile *f = new TFile(...)
 you should do:
    TFile *f = new TFile(...)
    TTree *T = new TTree(...)

what am i doing wrong with root Version 5.14?

Thank you in advance
Matthias

Before calling CopyTree you must create the output file.

Rene

I found it out myself now:
It was a problem with the directories, here is a working code example:

workdir=gDirectory.GetPath()
tmpinputfile=TFile ( inputfilename, "READ" )
tmptree = tmpinputfile.Get(self.treename)
gDirectory.Cd(workdir)
newtree = tmptree.CopyTree("1")

I really do not like those global pointers in ROOT. I have so much trouble with them. That is one of the most annoying things with root!

Cheers,
Matthias

You are creating the problem yourself. You do not have to use any globals in the example shown !

Rene

Hello Rene,

thanks for your quick replies. Sorry but i wrote my second post before your first answer.

You say that one does not have to use globals. But the problem is because ROOT is using them intenally (e.g. everytime it opens a file) one always has to be carefull in which order one opens files.

And when one is looping over several trees and wants to write the results all to one other tree, created earlier, one has to change those globals manually. Or did I get something completely wrong about this?

In the above example i tried a quick way to loop only over selected entries of a tree. This is of course a very bad way for large files, because the copied tree will resist in memory. Normally i had to use a TSelector instance for that. Is that Right?

regards
matthias

[quote]thanks for your quick replies. Sorry but i wrote my second post before your first answer. This #ROOT is… comment in the code was not meant to be posted somewhere. I forgot to remove it after copy&paste. I am sorry if someone found this insulting.
[/quote]
No problem! it is good to know when people say the truth ::slight_smile:

[quote]You say that one does not have to use globals. But the problem is because ROOT is using them intenally (e.g. everytime it opens a file) one always has to be carefull in which order one opens files.
[/quote]
There are very few cases where ROOT uses global internally (except gPad)
and this should not be a concern for you. In case of I/O ROOT knows about the current file/directory and this is used when creating a Tree, that’s all.
When reading several Trees, ROOT knows in which file a Tree resides,
you do not have to cd to the file before filling the Tree.
When calling TTree::Write you must cd to the file where you want to write
(or better call mytree.AutoSave instead of mytree.Write, AutoSave knows
where to save the tree header).

[quote]And when one is looping over several trees and wants to write the results all to one other tree, created earlier, one has to change those globals manually. Or did I get something completely wrong about this?
[/quote]
As I said above, you do not have to use any globals for that.

Your code was OK (I mean the call to CopyTree) providing you had open a file where to write the output Tree before. CopyTree is efficient when used with a simple selection. If you have a more complex selection that implies writing some code, you can call CloneTree(0) to create a clone of the Tree header and then make your own loop (with a TSelector or not) to filter your events.
TSelector is a good way to go if you want to use your code later in a parallel setup like PROOF.

Rene

Hello again,

I just could not imagine that to loop over some of the entries it is the best way to copy parts of the tree to a new file. But it works very nice now.

Thank you very much for your support Rene.
Matthias