Cannot move TH1 object in dir using TProofOutputFile

Hello,

I am using root 5.28/00, trunk@37585.
I am using TProofOutputFile to store histograms in the output file, and it works fine.
The problem is that I can create new directories, but using the SetDirectory( TDirectory* ) method seems to produce no effect, and the histograms are saved outside the directory, although it is always present in the output file. I create dirs in the SlaveBegin() method, soon after the histos have been created.

Is it possible that somehow the information of the SetDirectory gets lost outside the SlaveBegin method?
Thank you very much in advance.

Cheers,
Federico

Hi,

You should provide an example of what you are doing so that we can understand what, in your opinion, does not work.
Also, if the problem is with saving objects in different directories inside a file, maybe, if you have not already done it, you can try the same thing on a local session and see if you get the expected behavior.

G. Ganis

Hi,
yes, you are right!
Inside the SlaveBegin() method ( ProofFile is a TProofOutputFile* and fout a TFile* ):


    ProofFile = new TProofOutputFile( SaveName.c_str(), TProofOutputFile::kMerge);
    ProofFile->SetOutputFileName( name.c_str() );
    TDirectory *savedir = gDirectory;

  // Workaround for the TProofOutputFile bug
    string tname;
    tname.clear();
    tname = SaveDir;
    tname.append( "/<ord>/" );
    tname.append( SaveName );
    TString fn( tname.c_str() );
    TProofServ::ResolveKeywords(fn);
    TString dirord = gSystem->DirName(fn);
    if (gSystem->AccessPathName(dirord)) gSystem->mkdir(dirord, kTRUE);

    fout = TFile::Open(fn, "RECREATE");
    if (fout && fout->IsZombie()) SafeDelete(fout);
    if (fout) ProofFile->AdoptFile(fout);
    cout << "\n\t---> file pointer: " << fout << endl << endl;
    fout->mkdir( "myDirectory" );
    fout->ls();
    savedir->cd();

    h_test = new TH1F("h_test", "Test histogram", 100, 0, 1);
    h_beta = new TH1F("h_beta", "Distribution of #beta for first electron", 100, 0.95, 1);

    h_beta->SetDirectory(0);
    dir = (TDirectory*)fout->Get("myDirectory");
    h_beta->SetDirectory( dir );

the workaround is discussed in this post, if you remember:

https://root-forum.cern.ch/t/cannot-write-object-to-file-with-tproofoutputfile/12160/1

because of a TProofOutputFile “bug” when accessing files via gpfs.

as you can see, I create 2 histograms and a TDirectory inside the output file.
The file, the directory and the histograms are correctly created, merged and saved, but the h_beta histogram is in the same root directory h_test is, and not inside “myDirectory” as I expected.
The result is invariant if you create the TH1Fs before or after the TProofOutputFile is created.

Thank you very much.
Cheers,
federico

Hi,
Can you try the following;


    ProofFile = new TProofOutputFile( SaveName.c_str(), TProofOutputFile::kMerge);
    ProofFile->SetOutputFileName( name.c_str() );
    TDirectory *savedir = gDirectory;

  // Workaround for the TProofOutputFile bug
    string tname;
    tname.clear();
    tname = SaveDir;
    tname.append( "/<ord>/" );
    tname.append( SaveName );
    TString fn( tname.c_str() );
    TProofServ::ResolveKeywords(fn);
    TString dirord = gSystem->DirName(fn);
    if (gSystem->AccessPathName(dirord)) gSystem->mkdir(dirord, kTRUE);

    fout = TFile::Open(fn, "RECREATE");
    if (fout && fout->IsZombie()) SafeDelete(fout);
    if (fout) ProofFile->AdoptFile(fout);
    cout << "\n\t---> file pointer: " << fout << endl << endl;
    fout->mkdir( "myDirectory" );
    fout->ls();
    fout->cd( "myDirectory" );

    h_test = new TH1F("h_test", "Test histogram", 100, 0, 1);
    h_beta = new TH1F("h_beta", "Distribution of #beta for first electron", 100, 0.95, 1);
    savedir->cd();

?
Gerri

Hello,

I have tried, but it does not work…
bye,
federico

Which means what ?

Have you tried to do locally what you want to do?

How do you write out the histogram in SlaveTerminate?

Gerri

Hello,

the problem is I cannot run the program locally.
Anyway, I have tried your suggestion, which does not work.
At the SlaveTerminte() level the histogram is saved as follows:


    TDirectory *savedir = gDirectory;
    fout->cd();

    h_beta->Write();
    ProofFile->Print();
    fOutput->Add( ProofFile );

    gDirectory = savedir;
    fout->Close();

bye,
federico

Hi,
a small update:
if I append the histogram to the directory in the SlaveBegin() like this:


    TDirectory *dir = fout->mkdir( "myDirectory" );
    fout->ls();
    dir->Append( h_beta );
    fout->Write();

I obtain an empty histogram at the right place, and a filled copy in the wrong place…

bye,
federico

Hello,

I found a partial solution.
Instead of setting the directory in the SlaveBegin method, I moved to it just before Writing objects in the SlaveTerminate():


   TDirectory *dir = fout->mkdir( "myDirectory" );
    fout->ls();
    fout->cd( "myDirectory" );

    h_beta->Write();

This way, I obtain the histogram inside “myDirectory”; using SetDirectory method does results in nothing, I must admit. Can anybody explain why or how?

federico

Hi,

SetDirectory controls where the object is registered in memory, but you will always write in the directory you are in. And this is controlled by cd(…) .

G. Ganis