From $ROOTSYS/tutorials/proof/ProofEventProc.C

#define ProofEventProc_cxx

//////////////////////////////////////////////////////////
//
// Example of TSelector implementation to process trees
// containing 'Event' structures, e.g. the files under
// http://root.cern.ch/files/data .
// See tutorials/proof/runProof.C, option "eventproc", for
// an example of how to run this selector.
//
//////////////////////////////////////////////////////////

#include "ProofEventProc.h"
#include <TStyle.h>
#include "TCanvas.h"
#include "TPad.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TParameter.h"
#include "TRandom.h"
#include "TNamed.h"
#include "TROOT.h"
#include "EmptyInclude.h"


//_____________________________________________________________________________
void ProofEventProc::Begin(TTree *)
{
   // 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();
   Info("Begin", "starting a simple exercise with process option: %s", option.Data());
}

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

   // How much to read
   fFullRead = kFALSE;
   TNamed *nm = 0;
   if (fInput) {
      if ((nm = dynamic_cast<TNamed *>(fInput->FindObject("ProofEventProc_Read")))) {
         if (!strcmp(nm->GetTitle(), "readall")) fFullRead = kTRUE;
      }
   }
   if (!nm) {
      // Check option
      if (option == "readall") fFullRead = kTRUE;
   }
   Info("SlaveBegin", "'%s' reading", (fFullRead ? "full" : "optimized"));

   fPtHist = new TH1F("pt_dist","p_{T} Distribution",100,0,5);
   fPtHist->SetDirectory(0);
   fPtHist->GetXaxis()->SetTitle("p_{T}");
   fPtHist->GetYaxis()->SetTitle("dN/p_{T}dp_{T}");

   fOutput->Add(fPtHist);

   fPzHist = new TH1F("pz_dist","p_{Z} Distribution",100,0,5.);
   fPzHist->SetDirectory(0);
   fPzHist->GetXaxis()->SetTitle("p_{Z}");
   fPzHist->GetYaxis()->SetTitle("dN/dp_{Z}");

   fOutput->Add(fPzHist);

   fPxPyHist = new TH2F("px_py","p_{X} vs p_{Y} Distribution",100,-5.,5.,100,-5.,5.);
   fPxPyHist->SetDirectory(0);
   fPxPyHist->GetXaxis()->SetTitle("p_{X}");
   fPxPyHist->GetYaxis()->SetTitle("p_{Y}");

   fOutput->Add(fPxPyHist);

   // Abort test, if any
   TParameter<Int_t> *pi = 0;
   if (fInput)
      pi = dynamic_cast<TParameter<Int_t> *>(fInput->FindObject("ProofEventProc_TestAbort"));
   if (pi) fTestAbort = pi->GetVal();
   if (fTestAbort < -1 || fTestAbort > 1) {
      Info("SlaveBegin", "unsupported value for the abort test: %d not in [-1,1] - ignore", fTestAbort);
      fTestAbort = -1;
   } else if (fTestAbort > -1) {
      Info("SlaveBegin", "running abort test: %d", fTestAbort);
   }

   if (fTestAbort == 0)
      Abort("Test abortion during init", kAbortProcess);
}

//_____________________________________________________________________________
Bool_t ProofEventProc::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 TTree::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.

   // WARNING when a selector is used with a TChain, you must use
   //  the pointer to the current TTree to call GetEntry(entry).
   //  The entry is always the local entry number in the current tree.
   //  Assuming that fChain is the pointer to the TChain being processed,
   //  use fChain->GetTree()->GetEntry(entry).

   if (fEntMin == -1 || entry < fEntMin) fEntMin = entry;
   if (fEntMax == -1 || entry > fEntMax) fEntMax = entry;

   if (fTestAbort == 1) {
      Double_t rr = gRandom->Rndm();
      if (rr > 0.999) {
         Info("Process", "%lld -> %f", entry, rr);
         Abort("Testing file abortion", kAbortFile);
         return kTRUE;
      }
   }

   if (fFullRead) {
      fChain->GetTree()->GetEntry(entry);
   } else {
      b_event_fNtrack->GetEntry(entry);
   }

   if (fNtrack > 0) {
      if (!fFullRead) b_fTracks->GetEntry(entry);
      if (fTracks) {
         for (Int_t j=0;j<fTracks->GetEntries();j++){
            Track *curtrack = dynamic_cast<Track*>(fTracks->At(j));
            if (curtrack) {
               fPtHist->Fill(curtrack->GetPt(),1./curtrack->GetPt());
               fPxPyHist->Fill(curtrack->GetPx(),curtrack->GetPy());
               if (j == 0) fPzHist->Fill(curtrack->GetPz());
            }
         }
         fTracks->Clear("C");
      }
   }

   return kTRUE;
}

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

   // Save information about previous element, if any
   if (fProcElem) fProcElem->Add(fEntMin, fEntMax);

   if (!fProcElems) {
      Warning("SlaveTerminate", "no proc elements list found!");
      return;
   }

   // Add proc elements to the output list
   TIter nxpe(fProcElems);
   TObject *o = 0;
   while ((o = nxpe())) { fOutput->Add(o); };
}

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

   // Check ranges
   CheckRanges();

   if (gROOT->IsBatch()) return;

   TCanvas* canvas = new TCanvas("event","event",800,10,700,780);
   canvas->Divide(2,2);
   TPad *pad1 = (TPad *) canvas->GetPad(1);
   TPad *pad2 = (TPad *) canvas->GetPad(2);
   TPad *pad3 = (TPad *) canvas->GetPad(3);
   TPad *pad4 = (TPad *) canvas->GetPad(4);

   // The number of tracks
   pad1->cd();
   pad1->SetLogy();
   TH1F *hi = dynamic_cast<TH1F*>(fOutput->FindObject("pz_dist"));
   if (hi) {
      hi->SetFillColor(30);
      hi->SetLineColor(9);
      hi->SetLineWidth(2);
      hi->DrawCopy();
   } else { Warning("Terminate", "no pz dist found"); }

   // The Pt distribution
   pad2->cd();
   pad2->SetLogy();
   TH1F *hf = dynamic_cast<TH1F*>(fOutput->FindObject("pt_dist"));
   if (hf) {
      hf->SetFillColor(30);
      hf->SetLineColor(9);
      hf->SetLineWidth(2);
      hf->DrawCopy();
   } else { Warning("Terminate", "no pt dist found"); }

   // The Px,Py distribution, color surface
   TH2F *h2f = dynamic_cast<TH2F*>(fOutput->FindObject("px_py"));
   if (h2f) {
      // Color surface
      pad3->cd();
      h2f->DrawCopy("SURF1 ");
      // Lego
      pad4->cd();
      h2f->DrawCopy("CONT2COL");
   } else {
      Warning("Terminate", "no px py found");
   }

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

//_____________________________________________________________________________
void ProofEventProc::CheckRanges()
{
   // Check the processed event ranges when there is enough information
   // The result is added to the output list

   // Must be something in output
   if (!fOutput || (fOutput && fOutput->GetSize() <= 0)) return;

   // Create the result object and add it to the list
   TNamed *nout = new TNamed("Range_Check", "OK");
   fOutput->Add(nout);

   // Get info to check from the input list
   if (!fInput || (fInput && fInput->GetSize() <= 0)) {
      nout->SetTitle("No input list");
      return;
   }
   TNamed *ffst = dynamic_cast<TNamed *>(fInput->FindObject("Range_First_File"));
   if (!ffst) {
      nout->SetTitle("No first file");
      return;
   }
   TNamed *flst = dynamic_cast<TNamed *>(fInput->FindObject("Range_Last_File"));
   if (!flst) {
      nout->SetTitle("No last file");
      return;
   }
   TParameter<Int_t> *fnum =
      dynamic_cast<TParameter<Int_t> *>(fInput->FindObject("Range_Num_Files"));
   if (!fnum) {
      nout->SetTitle("No number of files");
      return;
   }

   // Check first file
   TString fn(ffst->GetTitle()), sfst(ffst->GetTitle());
   Ssiz_t ifst = fn.Index("?fst=");
   if (ifst == kNPOS) {
      nout->SetTitle("No first entry information in first file name");
      return;
   }
   fn.Remove(ifst);
   sfst.Remove(0, ifst + sizeof("?fst=") - 1);
   if (!sfst.IsDigit()) {
      nout->SetTitle("Badly formatted first entry information in first file name");
      return;
   }
   Long64_t fst = (Long64_t) sfst.Atoi();
   ProcFileElements *pfef = dynamic_cast<ProcFileElements *>(fOutput->FindObject(fn));
   if (!pfef) {
      nout->SetTitle("ProcFileElements for first file not found in the output list");
      return;
   }
   if (pfef->GetFirst() != fst) {
      TString t = TString::Format("First entry differs {found: %lld, expected: %lld}", pfef->GetFirst(), fst);
      nout->SetTitle(t.Data());
      return;
   }

   // Check last file
   fn = flst->GetTitle();
   TString slst(flst->GetTitle());
   Ssiz_t ilst = fn.Index("?lst=");
   if (ilst == kNPOS) {
      nout->SetTitle("No last entry information in last file name");
      return;
   }
   fn.Remove(ilst);
   slst.Remove(0, ilst + sizeof("?lst=") - 1);
   if (!slst.IsDigit()) {
      nout->SetTitle("Badly formatted last entry information in last file name");
      return;
   }
   Long64_t lst = (Long64_t) slst.Atoi();
   ProcFileElements *pfel = dynamic_cast<ProcFileElements *>(fOutput->FindObject(fn));
   if (!pfel) {
      nout->SetTitle("ProcFileElements for last file not found in the output list");
      return;
   }
   if (pfel->GetLast() != lst) {
      nout->SetTitle("Last entry differs");
      return;
   }

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