Dear ROOTers,
I was wondering how one could disable the use and filling of the various TLists of objects ROOT creates when its libraries are linked against a C++ application, or more precisely some of them. This garbage collection using TLists and iteratively looping over them is way too slow for my use case. Or perhaps I am using the wrong model.
I have a folder structure with the following depth
2x9x3x3 and each end folder contains ~7K histograms. When looping over my file to do some operations, like scaling those histograms and saving them in a new file, the first folders are being processed normally but as I proceed, it gets slower and slower, even with the fact I delete every histogram I get from TKey::ReadObj(). Should I be deleting the TKey as well or is this done automatically ?
When I interrupt the program in gdb, I see that most of the time is spend in RecursiveRemove() instead of doing any useful (to me) work. I understand the lists are useful of interactive ROOT but I don’t understand why it should slow me down when linking the ROOT libraries.
I already tried to use SetOwnership and Delete() the TLists when I exit a folder but that didn’t solve my problem.
I was also wondering how to add objects (histograms, canvases) to a current ROOT folder without causing infinite loops. I tried to clone the TList from TDirectory::GetListOfKeys() but without success. How should one go about this?
I tried the following, i.e. cloning the ListOfKeys() before starting, without success:
[code]void ScaleHistos( TDirectory *dir ) {
TList *listOfKeys = (TList*) dir->GetListOfKeys();//->Clone(); // Use of Clone() causes problems.
TIter next(listOfKeys);
while (TKey* key = (TKey*) next()) {
TObject *obj = key->ReadObj(); //<-- Segmentation fault if listOfKeys is a clone.
}
}[/code]
I also realized that cloning a TList does not change its name. Why is this intended ?
root [0] f = new TFile("tmp.root","recreate");
root [1] f->mkdir("tmpDir");
root [2] f->GetListOfKeys()->Print()
Collection name='THashList', class='THashList', size=1
TKey Name = tmpDir, Title = tmpDir, Cycle = 1
root [3] TList * tmpList = (TList*) f->GetListOfKeys()->Clone("tmpList");
root [4] tmpList->Print();
Collection name='THashList', class='THashList', size=1
TKey Name = tmpDir, Title = tmpDir, Cycle = 1
I understand that this is because the TList doesn’t inherit from TNamed.
I also thought of storing my histograms in a TTree but I get stuck when defining my branch because all my histograms do not have the same binning, and hence I need to use a generic TH1F pointer, which will point to the current histogram I want to fill. But then I cannot instantiate the branch using TTree::Branch with a NULL pointer. Any suggestion on how to do that ? I looked at the tutorial about storing histograms inside a ROOT tree but this is not the same use case. Perhaps it is not compatible with what I intend.
Thanks a lot for any suggestion,
Karolos