TFile::Open and gDirectory

TFile::Open set gDirectory as side effect, this can be problematic in some case. Suppose I’ve a function like

TFile output_file("output_file.root", "RECREATE");
TH1F h(...);
...
h.Write();

suppose now that I call a function f which open another file

TFile output_file("output_file.root", "RECREATE");
TH1F h(...);
f();
...
h.Write();
void f() {
  TFile another_file("another_file.root")
}

so at the end of f gDirectory is set to “another_file.root” and so my histogram will be save on this file and not on “output_file.root”. My workaround is to wrap f function with


    TFile* old_file = gDirectory->GetFile();
     ...
     old_file->cd();

I don’t like it. Is there a way to prevent that TFile::Open set gDirectory?

Hi,

[quote]Is there a way to prevent that TFile::Open set gDirectory?[/quote]No, there is not.

[quote]My workaround is to wrap f function with[/quote]This is an option. You can also use the dedicated helper class:void f() { TDirectory::TContext ctxt(); // Will restore gDirectory to its 'current' value at the end of this scope/function/ TFile another_file("another_file.root") }If you code it directory, rather than recording the TFile of the TDirectory, I recommend to record the value of gDirectory itself:TDirectory* old_directory = gDirectory;
Another alternative is to cd to the output explicitly before doing any write:TFile output_file("output_file.root", "RECREATE"); TH1F h(...); ... output_file->cd(); h.Write();

Also, note that when doing:output_file("output_file.root", "RECREATE"); TH1F h(...);h is registered with(in) output_file (Histogram and TTree are automatically registered with the current directory) and thus the following code:TFile output_file("output_file.root", "RECREATE"); TH1F h(...); ... output_file.Write();does exist what you intended (for histogram and TTree objects) no matter what the value of gDirectory is at the time of the write.

Cheers,
Philippe.