From $ROOTSYS/tutorials/proof/ProofNtuple.C

#define ProofNtuple_cxx

//////////////////////////////////////////////////////////
//
// Example of TSelector implementation to do generic
// processing (filling a simple ntuple, in this case).
// See tutorials/proof/runProof.C, option "ntuple", for an
// example of how to run this selector.
//
//////////////////////////////////////////////////////////

#include "ProofNtuple.h"
#include <TCanvas.h>
#include <TFrame.h>
#include <TPaveText.h>
#include <TMath.h>
#include <TNtuple.h>
#include <TRandom3.h>
#include <TROOT.h>
#include <TString.h>
#include <TStyle.h>
#include <TSystem.h>
#include <TFile.h>
#include <TProofOutputFile.h>

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

   SafeDelete(fNtp);
   SafeDelete(fNtp2);
   SafeDelete(fFile);
   SafeDelete(fRandom);
}

//_____________________________________________________________________________
void ProofNtuple::PlotNtuple(TNtuple *ntp, const char *ntptitle)
{
   // Make some plots from the ntuple 'ntp'

   //
   // Create a canvas, with 2 pads
   //
   TCanvas *c1 = new TCanvas(Form("cv-%s", ntp->GetName()), ntptitle,800,10,700,780);
   c1->Divide(1,2);
   TPad *pad1 = (TPad *) c1->GetPad(1);
   TPad *pad2 = (TPad *) c1->GetPad(2);
   //
   // Display a function of one ntuple column imposing a condition
   // on another column.
   pad1->cd();
   pad1->SetGrid();
   pad1->SetLogy();
   pad1->GetFrame()->SetFillColor(15);
   ntp->SetLineColor(1);
   ntp->SetFillStyle(1001);
   ntp->SetFillColor(45);
   ntp->Draw("3*px+2","px**2+py**2>1");
   ntp->SetFillColor(38);
   ntp->Draw("2*px+2","pz>2","same");
   ntp->SetFillColor(5);
   ntp->Draw("1.3*px+2","(px^2+py^2>4) && py>0","same");
   pad1->RedrawAxis();

   //
   // Display a 3-D scatter plot of 3 columns. Superimpose a different selection.
   pad2->cd();
   ntp->Draw("pz:py:px","(pz<10 && pz>6)+(pz<4 && pz>3)");
   ntp->SetMarkerColor(4);
   ntp->Draw("pz:py:px","pz<6 && pz>4","same");
   ntp->SetMarkerColor(5);
   ntp->Draw("pz:py:px","pz<4 && pz>3","same");
   TPaveText *l2 = new TPaveText(0.,0.6,0.9,0.95);
   l2->SetFillColor(42);
   l2->SetTextAlign(12);
   l2->AddText("You can interactively rotate this view in 2 ways:");
   l2->AddText("  - With the RotateCube in clicking in this pad");
   l2->AddText("  - Selecting View with x3d in the View menu");
   l2->Draw();

   // Final update
   c1->cd();
   c1->Update();
}

//_____________________________________________________________________________
void ProofNtuple::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();

   TNamed *out = (TNamed *) fInput->FindObject("PROOF_NTUPLE_DONT_PLOT");
   if (out) fPlotNtuple = kFALSE;
}

//_____________________________________________________________________________
void ProofNtuple::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();

   // We may be creating a dataset or a merge file: check it
   TNamed *nm = dynamic_cast<TNamed *>(fInput->FindObject("SimpleNtuple.root"));
   if (nm) {
      // Just create the object
      UInt_t opt = TProofOutputFile::kRegister | TProofOutputFile::kOverwrite | TProofOutputFile::kVerify;
      fProofFile = new TProofOutputFile("SimpleNtuple.root",
                                        TProofOutputFile::kDataset, opt, nm->GetTitle());
   } else {
      // For the ntuple, we use the automatic file merging facility
      // Check if an output URL has been given
      TNamed *out = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE_LOCATION");
      Info("SlaveBegin", "PROOF_OUTPUTFILE_LOCATION: %s", (out ? out->GetTitle() : "undef"));
      fProofFile = new TProofOutputFile("SimpleNtuple.root", (out ? out->GetTitle() : "M"));
      out = (TNamed *) fInput->FindObject("PROOF_OUTPUTFILE");
      if (out) fProofFile->SetOutputFileName(out->GetTitle());
   }

   // Open the file
   fFile = fProofFile->OpenFile("RECREATE");
   if (fFile && fFile->IsZombie()) SafeDelete(fFile);

   // Cannot continue
   if (!fFile) {
      Info("SlaveBegin", "could not create '%s': instance is invalid!", fProofFile->GetName());
      return;
   }

   // Now we create the ntuple
   fNtp = new TNtuple("ntuple","Demo ntuple","px:py:pz:random:i");
   // File resident
   fNtp->SetDirectory(fFile);
   fNtp->AutoSave();

   // Now we create the second ntuple
   fNtp2 = new TNtuple("ntuple2","Demo ntuple2","vx:vy:vz");
   // File resident
   fNtp2->SetDirectory(fFile);
   fNtp2->AutoSave();

   // Should we generate the random numbers or take them from the ntuple ?
   TNamed *unr = (TNamed *) fInput->FindObject("PROOF_USE_NTP_RNDM");
   if (unr) {
      // Get the ntuple from the input list
      if (!(fNtpRndm = dynamic_cast<TNtuple *>(fInput->FindObject("NtpRndm")))) {
         Warning("SlaveBegin",
                 "asked to use rndm ntuple but 'NtpRndm' not found in the"
                 " input list! Using the random generator");
         fInput->Print();
      } else {
         Info("SlaveBegin", "taking randoms from input ntuple 'NtpRndm'");
      }
   }

   // Init the random generator, if required
   if (!fNtpRndm) fRandom = new TRandom3(0);
}

//_____________________________________________________________________________
Bool_t ProofNtuple::Process(Long64_t entry)
{
   // 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 ProofNtuple::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.

   if (!fNtp) return kTRUE;

   // Fill ntuple
   Float_t px, py, random;
   if (fNtpRndm) {
      // Get the entry
      Float_t *ar = fNtpRndm->GetArgs();
      Long64_t ent = entry % fNtpRndm->GetEntries(); 
      fNtpRndm->GetEntry(ent);
      random = ar[0];
      px = (Float_t) TMath::ErfInverse((Double_t)(ar[1]*2 - 1.)) * TMath::Sqrt(2.);
      py = (Float_t) TMath::ErfInverse((Double_t)(ar[2]*2 - 1.)) * TMath::Sqrt(2.);
   } else if (fRandom) {
      fRandom->Rannor(px,py);
      random = fRandom->Rndm();
   } else {
      Abort("no way to get random numbers! Stop processing", kAbortProcess);
      return kTRUE;
   }
   Float_t pz = px*px + py*py;
   Int_t i = (Int_t) entry;
   fNtp->Fill(px,py,pz,random,i);

   if (!fNtp2) return kTRUE;
   
   // The second ntuple
   Float_t vz = random * 2. - 1.;
   fNtp2->Fill(px,py,vz);

   return kTRUE;
}

//_____________________________________________________________________________
void ProofNtuple::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 the ntuple to the file
   if (fFile) {
      if (!fNtp) {
         Error("SlaveTerminate", "'ntuple' is undefined!");
         return;
      }
      Bool_t cleanup = kFALSE;
      TDirectory *savedir = gDirectory;
      if (fNtp->GetEntries() > 0) {
         fFile->cd();
         fNtp->Write(0, TObject::kOverwrite);
         if (fNtp2 && fNtp2->GetEntries() > 0) fNtp2->Write(0, TObject::kOverwrite);
         fProofFile->Print();
         fOutput->Add(fProofFile);
      } else {
         cleanup = kTRUE;
      }
      fNtp->SetDirectory(0);
      if (fNtp2) fNtp2->SetDirectory(0);
      gDirectory = savedir;
      fFile->Close();
      // Cleanup, if needed
      if (cleanup) {
         TUrl uf(*(fFile->GetEndpointUrl()));
         SafeDelete(fFile);
         gSystem->Unlink(uf.GetFile());
         SafeDelete(fProofFile);
      }
   }
}

//_____________________________________________________________________________
void ProofNtuple::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.

   // Do nothing is not requested (dataset creation run)
   if (!fPlotNtuple) return;

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

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

      // Read the ntuple from the file
      fFile = TFile::Open(outputFile);
      if (fFile) {
         Printf("Managed to open file: %s", outputFile.Data());
         fNtp = (TNtuple *) fFile->Get("ntuple");
      } else {
         Error("Terminate", "could not open file: %s", outputFile.Data());
      }
      if (!fFile) return; 

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

   // Plot ntuples
   if (fNtp) PlotNtuple(fNtp, "proof ntuple");

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