I’m afraid you need to loop over all objects from your TObjArray and for each of them call “SetDirectory(gDirectory)”.
Maybe a better solution would be to make sure that all histograms are “associated” with “gROOT” or with “nothing” at their creation time. Before you call “new Something(…)” make sure that you “gROOT->cd();”, or after you call “new Something(…)” make sure that you call “SetDirectory(gROOT)” or “SetDirectory(0)” for this newly created object.
You could also execute the static method TDirectory::AddDirectory(kFALSE); in advance, before you create any histograms (then there’s no need to call “SetDirectory(0)” for them).
BTW. If an object / class has no “SetDirectory” method then you don’t need to care about it at all, I believe (unless it’s a “container” which keeps objects which do have this method, of course).
Actually I did not have to loop through the TObjArray elements. As a matter of fact, I did not have to use the SetDirectory method either. This is what I did. There are two sections. One where I create all my dir hierarchy:
You are right. I got confused by something else, sorry.
However, I don’t really understand then why you got problems with the source code from your first post here. On second thought, I see no problem in it (there should be no real difference with respect to the source code from your last post here).
The problem I was having boiled down to the function mkdir. In my first post, it was not creating the folders and all my objects were stored in the root (Top) directory. Then after doing some browsing I changed my statement file->mkdir(…) to gDirectory->mkdir(…) and everything worked as a charm. At the same time I had already included in my code the setDirectory to my TH1 objects. After few trials and errors, I just realized I have to set my folder right before I save (write) my objects and nothing more. Your comments were very appreciated though.
Iin a nutshell, I don’t know why mkdir didn’t work in the first place. Interesting enough, initially I tried a combination of mkdir() and cd() commands in different funny orders to see if I could make it work and the last thing that worked was the gDirectory call.
I realise this post is quite old but it helped me understand why my directory structure was not working now 7 years later and I wanted to add my findings.
What caused the problems with mkdir for me is shown with the following code:
//create test file
TFile *outFile = new TFile("dirTest.root","RECREATE");
//create test dir
TDirectory* d = outFile->mkdir("test");
//check if returned pointer points to test dir
std::cout << "test: " << d << ", " << d->GetName() << std::endl;
//move to test dir
std::cout << "Tried to move to test, moved to: " << gDirectory->GetDirectory(0)->GetPath() << std::endl;
//make test2 subdir
TDirectory* d2 = outFile->mkdir("test/test2");
//check if returned pointer points to test2 subdir
std::cout << "test2: " << d2 << ", " << d2->GetName() << std::endl;
//try to move to test2 subdir
std::cout << "Tried to move to test2, moved to: " << gDirectory->GetDirectory(0)->GetPath() << std::endl;
//rebase (because paths in cd() are relative) and move to test2 subdir via gDirectory and explicit path
//check location again
std::cout << "test2: " << gDirectory->GetDirectory(0) << ", " << gDirectory->GetDirectory(0)->GetName() << std::endl;
std::cout << "Tried to move to test2 via gDirectory and path, moved to: " << gDirectory->GetDirectory(0)->GetPath() << std::endl;
The output is then:
test: 0x4fa7e30, test
Tried to move to test, moved to: dirTest.root:/test
test2: 0x4fa7e30, test
Tried to move to test2, moved to: dirTest.root:/test
test2: 0x4c5b900, test2
Tried to move to test2 via gDirectory and path, moved to: dirTest.root:/test/test2
In the second mkdir call the sub-directory is created, but a pointer to the mother directory is returned. We can see this from the literal pointer being the same and from the output. Would it not make more sense if “mkdir” returned a pointer to the actually created directory? This would allways be the last directory in a hierarchy “a/b/c/…” anyway and no undefined behavior should result, right? And if that sub-directory cannot be created, return 0 and a warning?