From $ROOTSYS/tutorials/proof/ProofSimpleFile.C

#define ProofSimpleFile_cxx
//////////////////////////////////////////////////////////
//
// Example of TSelector implementation to do generic processing
// (filling a set of histograms in this case) and merging via
// a file, with part of the objects saved in a sub-directory.
// See tutorials/proof/runProof.C, option "simplefile", for an
// example of how to run this selector.
//
//////////////////////////////////////////////////////////

#include "ProofSimpleFile.h"
#include <TCanvas.h>
#include <TFrame.h>
#include <TPaveText.h>
#include <TFormula.h>
#include <TF1.h>
#include <TH1F.h>
#include <TMath.h>
#include <TRandom3.h>
#include <TString.h>
#include <TStyle.h>
#include <TSystem.h>
#include <TParameter.h>
#include <TFile.h>
#include <TProofOutputFile.h>

//_____________________________________________________________________________
ProofSimpleFile::ProofSimpleFile()
{
   // Constructor

   fNhist = 16;
   fHistTop = 0;
   fHistDir = 0;
   fRandom = 0;
   fFile = 0;
   fProofFile = 0;
   fFileDir = 0;
}

//_____________________________________________________________________________
ProofSimpleFile::~ProofSimpleFile()
{
   // Destructor

   if (fRandom) delete fRandom;
}

//_____________________________________________________________________________
Int_t ProofSimpleFile::CreateHistoArrays()
{
   // Create the histogram arrays

   if (fNhist <= 0) {
      Error("CreateHistoArrays", "fNhist must be positive!");
      return -1;
   }
   // Histos array
   fHistTop = new TH1F*[fNhist];
   fHistDir = new TH1F*[fNhist];
   // Done
   return 0;
}

//_____________________________________________________________________________
void ProofSimpleFile::Begin(TTree * /*tree*/)
{
   // The Begin() function is called at the start of the query.
   // When running with PROOF Begin() is only called on the client.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();

   // Number of histograms (needed in terminate)
   Ssiz_t iopt = kNPOS;
   if (fInput->FindObject("ProofSimpleFile_NHist")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimpleFile_NHist"));
      fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
   } else if ((iopt = option.Index("nhist=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
   }
}

//_____________________________________________________________________________
void ProofSimpleFile::SlaveBegin(TTree * /*tree*/)
{
   // The SlaveBegin() function is called after the Begin() function.
   // When running with PROOF SlaveBegin() is called on each slave server.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();

   // Number of histograms (needed in terminate)
   Ssiz_t iopt = kNPOS;
   if (fInput->FindObject("ProofSimpleFile_NHist")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimpleFile_NHist"));
      fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
   } else if ((iopt = option.Index("nhist=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
   }
   
   // The file for merging
   fProofFile = new TProofOutputFile("SimpleFile.root", "M");
   TNamed *out = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE");
   if (out) fProofFile->SetOutputFileName(out->GetTitle());
   TDirectory *savedir = gDirectory;
   fFile = fProofFile->OpenFile("RECREATE");
   if (fFile && fFile->IsZombie()) SafeDelete(fFile);
   savedir->cd();

   // Cannot continue
   if (!fFile) {
      TString amsg = TString::Format("ProofSimpleFile::SlaveBegin: could not create '%s':"
                                     " instance is invalid!", fProofFile->GetName());
      Abort(amsg, kAbortProcess);
      return;
   }

   // Histos arrays
   if (CreateHistoArrays() != 0) {
      Abort("ProofSimpleFile::SlaveBegin: could not create histograms", kAbortProcess);
      return;
   }

   // Create directory
   if (!(fFileDir = fFile->mkdir("blue"))) {
      Abort("ProofSimpleFile::SlaveBegin: could not create directory 'blue' in file!",
            kAbortProcess);
      return;
   }
   
   // Create the histograms
   for (Int_t i=0; i < fNhist; i++) {
      fHistTop[i] = new TH1F(Form("ht%d",i), Form("ht%d",i), 100, -3., 3.);
      fHistTop[i]->SetFillColor(kRed);
      fHistTop[i]->SetDirectory(fFile);
      fHistDir[i] = new TH1F(Form("hd%d",i), Form("hd%d",i), 100, -3., 3.);
      fHistDir[i]->SetFillColor(kBlue);
      fHistDir[i]->SetDirectory(fFileDir);
   }

   // Set random seed
   fRandom = new TRandom3(0);
}

//_____________________________________________________________________________
Bool_t ProofSimpleFile::Process(Long64_t)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either ProofSimpleFile::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.
   //
   // The processing can be stopped by calling Abort().
   //
   // Use fStatus to set the return value of TTree::Process().
   //
   // The return value is currently not used.

   for (Int_t i=0; i < fNhist; i++) {
      if (fRandom && fHistTop[i] && fHistDir[i]) {
         fHistTop[i]->Fill(fRandom->Gaus(0.,1.));
         fHistDir[i]->Fill(fRandom->Gaus(0.,1.));
      }
   }

   return kTRUE;
}

//_____________________________________________________________________________
void ProofSimpleFile::SlaveTerminate()
{
   // The SlaveTerminate() function is called after all entries or objects
   // have been processed. When running with PROOF SlaveTerminate() is called
   // on each slave server.

   // Write histos to file
   if (fFile) {
      Bool_t cleanup = kTRUE;
      TDirectory *savedir = gDirectory;
      fFile->cd();
      for (Int_t i=0; i < fNhist; i++) {
         if (fHistTop[i] && fHistTop[i]->GetEntries() > 0) {
            fHistTop[i]->Write();
            fHistTop[i]->SetDirectory(0);
            cleanup = kFALSE;
         }
      }
      // Change to subdirectory
      fFileDir->cd();
      for (Int_t i=0; i < fNhist; i++) {
         if (fHistDir[i] && fHistDir[i]->GetEntries() > 0) {
            fHistDir[i]->Write();
            fHistDir[i]->SetDirectory(0);
            cleanup = kFALSE;
         }
      }
      gDirectory = savedir;
      fFile->Close();
      // Cleanup or register
      if (cleanup) {
         Info("SlaveTerminate", "nothing to save: just cleanup everything ...");
         TUrl uf(*(fFile->GetEndpointUrl()));
         SafeDelete(fFile);
         gSystem->Unlink(uf.GetFile());
         SafeDelete(fProofFile);
      } else {
         Info("SlaveTerminate", "objects saved into '%s%s': sending related TProofOutputFile ...",
                                fProofFile->GetFileName(), fProofFile->GetOptionsAnchor());
         fProofFile->Print();
         fOutput->Add(fProofFile);
      }
   }

}

//_____________________________________________________________________________
void ProofSimpleFile::Terminate()
{
   // The Terminate() function is the last function to be called during
   // a query. It always runs on the client, it can be used to present
   // the results graphically or save the results to file.

   // Get the histos from the file
   if ((fProofFile =
           dynamic_cast<TProofOutputFile*>(fOutput->FindObject("SimpleFile.root")))) {

      TString outputFile(fProofFile->GetOutputFileName());
      TString outputName(fProofFile->GetName());
      outputName += ".root";
      Printf("outputFile: %s", outputFile.Data());

      // Read the ntuple from the file
      if (!(fFile = TFile::Open(outputFile))) {
         Error("Terminate", "could not open file: %s", outputFile.Data());
         return;
      }

   } else {
      Error("Terminate", "TProofOutputFile not found");
      return;
   }

   // Histos arrays
   if (CreateHistoArrays() != 0) {
      Error("Terminate", "could not create histograms");
      return;
   }

   // Top histos
   PlotHistos(0);
   // Dir histos
   PlotHistos(1);
}

//_____________________________________________________________________________
void ProofSimpleFile::PlotHistos(Int_t opt)
{
   // Plot the histograms ina dedicated canvas

   // Create a canvas, with fNhist pads
   if (opt == 0) {
      TCanvas *c1 = new TCanvas("c1","ProofSimpleFile top dir canvas",200,10,700,700);
      Int_t nside = (Int_t)TMath::Sqrt((Float_t)fNhist);
      nside = (nside*nside < fNhist) ? nside+1 : nside;
      c1->Divide(nside,nside,0,0);

      for (Int_t i=0; i < fNhist; i++) {
         fHistTop[i] = (TH1F *) fFile->Get(TString::Format("ht%d",i));
         c1->cd(i+1);
         if (fHistTop[i])
            fHistTop[i]->Draw();
      }

      // Final update
      c1->cd();
      c1->Update();
   } else if (opt == 1) {
      TCanvas *c2 = new TCanvas("c2","ProofSimpleFile 'blue' sub-dir canvas",400,60,700,700);
      Int_t nside = (Int_t)TMath::Sqrt((Float_t)fNhist);
      nside = (nside*nside < fNhist) ? nside+1 : nside;
      c2->Divide(nside,nside,0,0);

      if ((fFileDir = (TDirectory *) fFile->Get("blue"))) {
         for (Int_t i=0; i < fNhist; i++) {
            fHistDir[i] = (TH1F *) fFileDir->Get(TString::Format("hd%d",i));
            c2->cd(i+1);
            if (fHistDir[i])
               fHistDir[i]->Draw();
         }
      } else {
         Error("PlotHistos", "directory 'blue' not found in output file");
      }

      // Final update
      c2->cd();
      c2->Update();
   } else {
      Error("PlotHistos", "unknown option: %d", opt);
   }
}
 ProofSimpleFile.C:1
 ProofSimpleFile.C:2
 ProofSimpleFile.C:3
 ProofSimpleFile.C:4
 ProofSimpleFile.C:5
 ProofSimpleFile.C:6
 ProofSimpleFile.C:7
 ProofSimpleFile.C:8
 ProofSimpleFile.C:9
 ProofSimpleFile.C:10
 ProofSimpleFile.C:11
 ProofSimpleFile.C:12
 ProofSimpleFile.C:13
 ProofSimpleFile.C:14
 ProofSimpleFile.C:15
 ProofSimpleFile.C:16
 ProofSimpleFile.C:17
 ProofSimpleFile.C:18
 ProofSimpleFile.C:19
 ProofSimpleFile.C:20
 ProofSimpleFile.C:21
 ProofSimpleFile.C:22
 ProofSimpleFile.C:23
 ProofSimpleFile.C:24
 ProofSimpleFile.C:25
 ProofSimpleFile.C:26
 ProofSimpleFile.C:27
 ProofSimpleFile.C:28
 ProofSimpleFile.C:29
 ProofSimpleFile.C:30
 ProofSimpleFile.C:31
 ProofSimpleFile.C:32
 ProofSimpleFile.C:33
 ProofSimpleFile.C:34
 ProofSimpleFile.C:35
 ProofSimpleFile.C:36
 ProofSimpleFile.C:37
 ProofSimpleFile.C:38
 ProofSimpleFile.C:39
 ProofSimpleFile.C:40
 ProofSimpleFile.C:41
 ProofSimpleFile.C:42
 ProofSimpleFile.C:43
 ProofSimpleFile.C:44
 ProofSimpleFile.C:45
 ProofSimpleFile.C:46
 ProofSimpleFile.C:47
 ProofSimpleFile.C:48
 ProofSimpleFile.C:49
 ProofSimpleFile.C:50
 ProofSimpleFile.C:51
 ProofSimpleFile.C:52
 ProofSimpleFile.C:53
 ProofSimpleFile.C:54
 ProofSimpleFile.C:55
 ProofSimpleFile.C:56
 ProofSimpleFile.C:57
 ProofSimpleFile.C:58
 ProofSimpleFile.C:59
 ProofSimpleFile.C:60
 ProofSimpleFile.C:61
 ProofSimpleFile.C:62
 ProofSimpleFile.C:63
 ProofSimpleFile.C:64
 ProofSimpleFile.C:65
 ProofSimpleFile.C:66
 ProofSimpleFile.C:67
 ProofSimpleFile.C:68
 ProofSimpleFile.C:69
 ProofSimpleFile.C:70
 ProofSimpleFile.C:71
 ProofSimpleFile.C:72
 ProofSimpleFile.C:73
 ProofSimpleFile.C:74
 ProofSimpleFile.C:75
 ProofSimpleFile.C:76
 ProofSimpleFile.C:77
 ProofSimpleFile.C:78
 ProofSimpleFile.C:79
 ProofSimpleFile.C:80
 ProofSimpleFile.C:81
 ProofSimpleFile.C:82
 ProofSimpleFile.C:83
 ProofSimpleFile.C:84
 ProofSimpleFile.C:85
 ProofSimpleFile.C:86
 ProofSimpleFile.C:87
 ProofSimpleFile.C:88
 ProofSimpleFile.C:89
 ProofSimpleFile.C:90
 ProofSimpleFile.C:91
 ProofSimpleFile.C:92
 ProofSimpleFile.C:93
 ProofSimpleFile.C:94
 ProofSimpleFile.C:95
 ProofSimpleFile.C:96
 ProofSimpleFile.C:97
 ProofSimpleFile.C:98
 ProofSimpleFile.C:99
 ProofSimpleFile.C:100
 ProofSimpleFile.C:101
 ProofSimpleFile.C:102
 ProofSimpleFile.C:103
 ProofSimpleFile.C:104
 ProofSimpleFile.C:105
 ProofSimpleFile.C:106
 ProofSimpleFile.C:107
 ProofSimpleFile.C:108
 ProofSimpleFile.C:109
 ProofSimpleFile.C:110
 ProofSimpleFile.C:111
 ProofSimpleFile.C:112
 ProofSimpleFile.C:113
 ProofSimpleFile.C:114
 ProofSimpleFile.C:115
 ProofSimpleFile.C:116
 ProofSimpleFile.C:117
 ProofSimpleFile.C:118
 ProofSimpleFile.C:119
 ProofSimpleFile.C:120
 ProofSimpleFile.C:121
 ProofSimpleFile.C:122
 ProofSimpleFile.C:123
 ProofSimpleFile.C:124
 ProofSimpleFile.C:125
 ProofSimpleFile.C:126
 ProofSimpleFile.C:127
 ProofSimpleFile.C:128
 ProofSimpleFile.C:129
 ProofSimpleFile.C:130
 ProofSimpleFile.C:131
 ProofSimpleFile.C:132
 ProofSimpleFile.C:133
 ProofSimpleFile.C:134
 ProofSimpleFile.C:135
 ProofSimpleFile.C:136
 ProofSimpleFile.C:137
 ProofSimpleFile.C:138
 ProofSimpleFile.C:139
 ProofSimpleFile.C:140
 ProofSimpleFile.C:141
 ProofSimpleFile.C:142
 ProofSimpleFile.C:143
 ProofSimpleFile.C:144
 ProofSimpleFile.C:145
 ProofSimpleFile.C:146
 ProofSimpleFile.C:147
 ProofSimpleFile.C:148
 ProofSimpleFile.C:149
 ProofSimpleFile.C:150
 ProofSimpleFile.C:151
 ProofSimpleFile.C:152
 ProofSimpleFile.C:153
 ProofSimpleFile.C:154
 ProofSimpleFile.C:155
 ProofSimpleFile.C:156
 ProofSimpleFile.C:157
 ProofSimpleFile.C:158
 ProofSimpleFile.C:159
 ProofSimpleFile.C:160
 ProofSimpleFile.C:161
 ProofSimpleFile.C:162
 ProofSimpleFile.C:163
 ProofSimpleFile.C:164
 ProofSimpleFile.C:165
 ProofSimpleFile.C:166
 ProofSimpleFile.C:167
 ProofSimpleFile.C:168
 ProofSimpleFile.C:169
 ProofSimpleFile.C:170
 ProofSimpleFile.C:171
 ProofSimpleFile.C:172
 ProofSimpleFile.C:173
 ProofSimpleFile.C:174
 ProofSimpleFile.C:175
 ProofSimpleFile.C:176
 ProofSimpleFile.C:177
 ProofSimpleFile.C:178
 ProofSimpleFile.C:179
 ProofSimpleFile.C:180
 ProofSimpleFile.C:181
 ProofSimpleFile.C:182
 ProofSimpleFile.C:183
 ProofSimpleFile.C:184
 ProofSimpleFile.C:185
 ProofSimpleFile.C:186
 ProofSimpleFile.C:187
 ProofSimpleFile.C:188
 ProofSimpleFile.C:189
 ProofSimpleFile.C:190
 ProofSimpleFile.C:191
 ProofSimpleFile.C:192
 ProofSimpleFile.C:193
 ProofSimpleFile.C:194
 ProofSimpleFile.C:195
 ProofSimpleFile.C:196
 ProofSimpleFile.C:197
 ProofSimpleFile.C:198
 ProofSimpleFile.C:199
 ProofSimpleFile.C:200
 ProofSimpleFile.C:201
 ProofSimpleFile.C:202
 ProofSimpleFile.C:203
 ProofSimpleFile.C:204
 ProofSimpleFile.C:205
 ProofSimpleFile.C:206
 ProofSimpleFile.C:207
 ProofSimpleFile.C:208
 ProofSimpleFile.C:209
 ProofSimpleFile.C:210
 ProofSimpleFile.C:211
 ProofSimpleFile.C:212
 ProofSimpleFile.C:213
 ProofSimpleFile.C:214
 ProofSimpleFile.C:215
 ProofSimpleFile.C:216
 ProofSimpleFile.C:217
 ProofSimpleFile.C:218
 ProofSimpleFile.C:219
 ProofSimpleFile.C:220
 ProofSimpleFile.C:221
 ProofSimpleFile.C:222
 ProofSimpleFile.C:223
 ProofSimpleFile.C:224
 ProofSimpleFile.C:225
 ProofSimpleFile.C:226
 ProofSimpleFile.C:227
 ProofSimpleFile.C:228
 ProofSimpleFile.C:229
 ProofSimpleFile.C:230
 ProofSimpleFile.C:231
 ProofSimpleFile.C:232
 ProofSimpleFile.C:233
 ProofSimpleFile.C:234
 ProofSimpleFile.C:235
 ProofSimpleFile.C:236
 ProofSimpleFile.C:237
 ProofSimpleFile.C:238
 ProofSimpleFile.C:239
 ProofSimpleFile.C:240
 ProofSimpleFile.C:241
 ProofSimpleFile.C:242
 ProofSimpleFile.C:243
 ProofSimpleFile.C:244
 ProofSimpleFile.C:245
 ProofSimpleFile.C:246
 ProofSimpleFile.C:247
 ProofSimpleFile.C:248
 ProofSimpleFile.C:249
 ProofSimpleFile.C:250
 ProofSimpleFile.C:251
 ProofSimpleFile.C:252
 ProofSimpleFile.C:253
 ProofSimpleFile.C:254
 ProofSimpleFile.C:255
 ProofSimpleFile.C:256
 ProofSimpleFile.C:257
 ProofSimpleFile.C:258
 ProofSimpleFile.C:259
 ProofSimpleFile.C:260
 ProofSimpleFile.C:261
 ProofSimpleFile.C:262
 ProofSimpleFile.C:263
 ProofSimpleFile.C:264
 ProofSimpleFile.C:265
 ProofSimpleFile.C:266
 ProofSimpleFile.C:267
 ProofSimpleFile.C:268
 ProofSimpleFile.C:269
 ProofSimpleFile.C:270
 ProofSimpleFile.C:271
 ProofSimpleFile.C:272
 ProofSimpleFile.C:273
 ProofSimpleFile.C:274
 ProofSimpleFile.C:275
 ProofSimpleFile.C:276
 ProofSimpleFile.C:277
 ProofSimpleFile.C:278
 ProofSimpleFile.C:279
 ProofSimpleFile.C:280
 ProofSimpleFile.C:281
 ProofSimpleFile.C:282
 ProofSimpleFile.C:283
 ProofSimpleFile.C:284
 ProofSimpleFile.C:285
 ProofSimpleFile.C:286
 ProofSimpleFile.C:287
 ProofSimpleFile.C:288
 ProofSimpleFile.C:289
 ProofSimpleFile.C:290
 ProofSimpleFile.C:291
 ProofSimpleFile.C:292
 ProofSimpleFile.C:293
 ProofSimpleFile.C:294
 ProofSimpleFile.C:295
 ProofSimpleFile.C:296
 ProofSimpleFile.C:297
 ProofSimpleFile.C:298
 ProofSimpleFile.C:299
 ProofSimpleFile.C:300
 ProofSimpleFile.C:301
 ProofSimpleFile.C:302
 ProofSimpleFile.C:303
 ProofSimpleFile.C:304
 ProofSimpleFile.C:305
 ProofSimpleFile.C:306
 ProofSimpleFile.C:307
 ProofSimpleFile.C:308
 ProofSimpleFile.C:309
 ProofSimpleFile.C:310
 ProofSimpleFile.C:311
 ProofSimpleFile.C:312
 ProofSimpleFile.C:313
 ProofSimpleFile.C:314
 ProofSimpleFile.C:315
 ProofSimpleFile.C:316