I am trying to do something that i think should be extremely simple.
The big picture is that i have multiple (20+) files that each contain multiple trees (for different systematic variations) each with two cycles due to their size (these files are provided to me by someone else). Some of these files are for my signal and the rest is for my background.
What i need in the end is one file that contains two trees. One sould be the same of all the nominal trees of the background samples and the other should be the sum of the nominal trees of the signal sample.
So my idea what to just go through each file, copy the nominal tree to a new one and rename it there to Sig or Bkg depending on signal or background. and then hadd all of these files together to get what i need.
However i am already not managing to do the first step.
This is what one of the input files looks like
And this is the relevant part of the macro that i am running over it.
for (Int_t i = 0; i < n; i++) {
std::cout << filename[i] << std::endl;
TFile oldfile(filename[i]);
TTree *oldtree;
oldfile.GetObject("nominal", oldtree);
TFile newfile(newname[i], "recreate");
newfile.cd();
auto newtree = oldtree->CloneTree();
newtree->SetObject("PolSig","PolSig");
newfile.Write("PolSig");
newfile.Close();
}
and this is what the output file looks like
Those two are exactly the things i wanted to copy but one of them is not renamed properly. Does anyone know how to do this whole thing?
Is your 2nd picture showing what you have in “newfile” ?
If that’s the case I do not understand why you have nominalandPolSig in it and not only PolSig as it is the only one you wrote in “newfile” …
Our I/O expert, @pcanal , may have an idea about your problem.
@Wile_E_Coyote I am not sure why it would be related the number of cycles in the original file.
My guess is that in the code:
auto newtree = oldtree->CloneTree();
newtree->SetNameTitle("PolSig", "PolSig");
newfile.Write();
CloneTree does an autosave and/or write of the TTree with its "then current" name (i.e. nominal) so it works ‘as intended’.
The work-around that you provided is ‘correct’ (change the name before cloning it).
If one does not want to change the original tree name, then you can split the operationing:
auto newtree = oldtree->CloneTree(0); // copy just the structure.
newtree->SetObject("PolSig", "PolSig"); // Somehow SetNameTitle is not yet overloded in TTree :( ...
newtree->CopyEntries(oldtree, -1, "fast"); // "fast" is not the default in CopyEntries not in CloneTree :(
@pcanal I did a small test with the “hsmiple.root”. As soon as there are two “cycles” of the “ntuple” (note: you need to increase its number of entries; I tried with 2500000), the problem with “SetObject” appears.
We got a mystery on our hand … I just tried with v6.22/08 and got the same (good) result I got before …
One noticeable difference between your output and mine (in both master and v6.22/08) is the order of the keys in the input file, you get:
KEY: TNtuple ntuple;2 Demo ntuple
KEY: TNtuple ntuple;1 Demo ntuple
KEY: TH1F hpx;1 This is the px distribution
KEY: TH2F hpxpy;1 py vs px
KEY: TProfile hprof;1 Profile of pz versus px
while I get:
KEY: TH1F hpx;1 This is the px distribution
KEY: TH2F hpxpy;1 py vs px
KEY: TProfile hprof;1 Profile of pz versus px
KEY: TNtuple ntuple;2 Demo ntuple
KEY: TNtuple ntuple;1 Demo ntuple
So there is something different between your hsimple.root and mine. Could you send me yours?
const Int_t kUPDATE = 100000;
for (Int_t i = 0; i < 2500000; i++) {
Then:
rm -f hsimple.root # not really needed, of course
root -q hsimple.C # the modified macro which (re)creates "hsimple.root"
root -q hsimple_newfile.cxx # my test macro (output in my previous post)
@pcanal Let me know if you cannot reproduce this problem (I will then send you the “hsimple.root” file that I produced).