I am a newbie to ROOT and I am just discovering its usage, so please excuse if this is obvious or already answered. I wonder, if there is a generic script for conversion of ROOT files generated by 5.22 to 5.26 version to benefit from improvements in file data format. I understand that one has to load all trees stored in the source file and clone them to a new file, and I have also read the example of copytree, but I am not sure how to do it in generic way(i.e. not knowing the number of trees and type of the class it represents). Could you please shed some light on me?
[code]void reclust() {
// this script takes an input file generated with root5.22 or older
// and rewrite it using root5.27/04. The resulting file is expected
// to be much faster when reading.
//
//load the ATLAS classes from the fake library
//to automatically generate the fake lib aod.so in subdirectory aod, do
// TFile f = TFile::Open(“InDetRecAOD_old_1.root”);
// f->MakeProject(“aod”,"",“recreate++”);
gSystem->Load(“aod/aod”);
TFile f = TFile::Open(“InDetRecAOD_old_1.root”);
T = (TTree)f->Get(“CollectionTree”);
T->OptimizeBaskets(40000000,1,“d”);
TFile *f2 = new TFile(“atlas2.root”,“recreate”);
TTree *T2 = T->CloneTree(0);
Long64_t nentries = T->GetEntries();
for (Int_t i=0;i<nentries;i++) {
T->GetEntry(i);
T2->Fill();
}
T2->Write();
T2->Print();
}
[/code]
thank you for the example! I was missing the “MakeProject” function call. Because I don’t know apriori name of the trees, I end up doing something like this:
[code]void reclust(TString fileName) {
// this script takes an input file generated with root5.22 or older
// and rewrite it using root5.27/04. The resulting file is expected
// to be much faster when reading.
//
//load the ATLAS classes from the fake library
//to automatically generate the fake lib aod.so in subdirectory aod, do
TFile f = TFile::Open(fileName);
f->MakeProject(“aod”,"",“recreate++”);
TFile *f2 = new TFile(newFileName, “recreate”);
while ((key = (TKey ) next())) {
if ( key->ReadObj()->InheritsFrom(“TTree”)) {
cout << key->GetName() << endl;
TTree * T = (TTree)key->ReadObj();
T->OptimizeBaskets(40000000,1,“d”);
TTree *T2 = T->CloneTree(0);
Long64_t nentries = T->GetEntries();
for (Int_t i=0;i<nentries;i++) {
T->GetEntry(i);
T2->Fill();
}
T2->Write();
T2->Print();
}
}
f2->Close();
}[/code]
Which works, but create 260MB file instead of 180MB original one, which is a bit suspicious. Should I be worried about it, or it could be just a result of a new file format?
The new file should be at least 5 per cent smaller. It looks like your input Tree has a ridicilous value for AutoSave.
Before the loop I suggest to call
T2->SetAutoSave(1000000000);
thank you for the suggestion, but it wasn’t the case. The value of autosave was set to the exact same value you’ve proposed. I think that the problem is in the way the file is created and then reclusted. The original file contains these object:
When reclusted, the tree was doubled, ie. stored twice. For what I want to achieve, it is sufficient to know that only newer version of the tree should be stored. However, just for my curiosity, how could one reclust such files?
BTW: I have also seen files where there were two versions of a tree, that translated to the same value of pointer, but with different number of entries in it. I suppose that one tree was a sub-tree of the another. Does ROOT support something like that?