Mkdir on TProofLite

Dear ROOTers,

I’m trying to “adjust” the quite complex analysis tool of my experiment to work with TProofLite (and later with TProof…).

This analysis tool makes a lot of things to managecuts and histogram but the main and firts feature is simply to create directories and putting histograms into them (mainly because I have histograms with the same name [but filled after different cuts…] put in different directories).

Now I’m passing to the TSelector (my analysis tool now is a daughter of TSelector…) an external file created in the macro I use to launch the TProofLite session:

    TFile* f = new TFile("Output.root","RECREATE");
    prof->AddInput(f);

where prof is a TProofLite object.

and then I retrieve it into the TSelector using:

  for (int ii=0; ii<fInput->GetEntries(); ii++){
    TObject* obj = (fInput->At(ii));
    if (obj) {
      if (obj->InheritsFrom("TFile")){
        fFile = (TFile*)obj;
      }
    }
  }

where fFile is a TFile*.

The problem is that is I try to create directory structures (TFile::mkdir()) when booking histograms (in the SlaveBegin()) I have crashes or simply nothing is done.

I think the problem is related with the fact that if I use TH1::SetDirectory(fFile) in the SlaveBegin() with my histos however them are as I made SetDirectory(0)…

How Can I create and manage directory structures in TProof?!

Thanks,
Matteo

Dear Matteo,

The problem is that the worker, where SlaveBegin is executed, is another process an the TFile created on the main process is only usable on the same process.
You have to create one file for each worker using TProofOutputFile (see $ROOTSYS/tutorials/ProofNtuple.C and the steering macro run Proof.C in there for an example). On each worker you create the directories as you wish. The files should then be merged in the final file automatically.

Alternatively you call your histograms with the full directory path structure, which must be unique, and then restore the desired naming scheme which saving the histos in Terminate(); e.g., in pseudo code, something like

MySel::SlaveBegin()
...
fMyHistOne = new TH1F("dir_one/myhist", "histos", 100, 0., 1.)
fMyHistTwo = new TH1F("dir_two/myhist", "histos", 100, 0., 1.)
...
fOutput->Add(fMyHistOne);
fOutput->Add(fMyHistTwo);

MySel::Terminate()
...
TFile *outfile = new TFile("myfile.root", "RECREATE")

outfile->mkdir(gSystem->DirName(fMyHistOne->GetName()));
outfile->cd(gSystem->DirName(fMyHistOne->GetName()));
fMyHistOne->SetName(gSystem->BaseName(fMyHistOne->GetName()));
fMyHistOne->Write();

outfile->mkdir(gSystem->DirName(fMyHistTwo->GetName()));
outfile->cd(gSystem->DirName(fMyHistTwo->GetName()));
fMyHistTwo->SetName(gSystem->BaseName(fMyHistTwo->GetName()));
fMyHistTwo->Write();

Please try and let us know.

G. Ganis

Ok,

with the help of your indications (the first, the seconds are probably more quick but also more dirty for me…) and of the examples I was able to create dir structures to store mi histograms and the to merge the files created by workers into one single file…

I needed some time because I use root 5.22…

I have yet the problem that the final file seems not closed and when I read it root needs to recover the keys…

But ok for me is not a great problem because my next step is to write the Merge method for all the class used in my software and use it instead of merging files… Up to now this approach was however not possible since I needed however to crate dir structures to store histograms with same names…

Thanks again,
Matteo