Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
ProofEventProc.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_ProofEventProc
3 ///
4 /// Selector to process trees containing Event structures
5 ///
6 /// \macro_code
7 ///
8 /// \author Gerardo Ganis (gerardo.ganis@cern.ch)
9 
10 #define ProofEventProc_cxx
11 
12 #include "ProofEventProc.h"
13 #include <TStyle.h>
14 #include "TCanvas.h"
15 #include "TPad.h"
16 #include "TH1F.h"
17 #include "TH2F.h"
18 #include "TParameter.h"
19 #include "TRandom.h"
20 #include "TNamed.h"
21 #include "TROOT.h"
22 #include "EmptyInclude.h"
23 
24 
25 //_____________________________________________________________________________
26 void ProofEventProc::Begin(TTree *)
27 {
28  // The Begin() function is called at the start of the query.
29  // When running with PROOF Begin() is only called on the client.
30  // The tree argument is deprecated (on PROOF 0 is passed).
31 
32  TString option = GetOption();
33  Info("Begin", "starting a simple exercise with process option: %s", option.Data());
34 }
35 
36 //_____________________________________________________________________________
37 void ProofEventProc::SlaveBegin(TTree * /*tree*/)
38 {
39  // The SlaveBegin() function is called after the Begin() function.
40  // When running with PROOF SlaveBegin() is called on each slave server.
41  // The tree argument is deprecated (on PROOF 0 is passed).
42 
43  TString option = GetOption();
44 
45  // How much to read
46  fFullRead = kFALSE;
47  TNamed *nm = 0;
48  if (fInput) {
49  if ((nm = dynamic_cast<TNamed *>(fInput->FindObject("ProofEventProc_Read")))) {
50  if (!strcmp(nm->GetTitle(), "readall")) fFullRead = kTRUE;
51  }
52  }
53  if (!nm) {
54  // Check option
55  if (option == "readall") fFullRead = kTRUE;
56  }
57  Info("SlaveBegin", "'%s' reading", (fFullRead ? "full" : "optimized"));
58 
59  fPtHist = new TH1F("pt_dist","p_{T} Distribution",100,0,5);
60  fPtHist->SetDirectory(0);
61  fPtHist->GetXaxis()->SetTitle("p_{T}");
62  fPtHist->GetYaxis()->SetTitle("dN/p_{T}dp_{T}");
63 
64  fOutput->Add(fPtHist);
65 
66  fPzHist = new TH1F("pz_dist","p_{Z} Distribution",100,0,5.);
67  fPzHist->SetDirectory(0);
68  fPzHist->GetXaxis()->SetTitle("p_{Z}");
69  fPzHist->GetYaxis()->SetTitle("dN/dp_{Z}");
70 
71  fOutput->Add(fPzHist);
72 
73  fPxPyHist = new TH2F("px_py","p_{X} vs p_{Y} Distribution",100,-5.,5.,100,-5.,5.);
74  fPxPyHist->SetDirectory(0);
75  fPxPyHist->GetXaxis()->SetTitle("p_{X}");
76  fPxPyHist->GetYaxis()->SetTitle("p_{Y}");
77 
78  fOutput->Add(fPxPyHist);
79 
80  // Abort test, if any
81  TParameter<Int_t> *pi = 0;
82  if (fInput)
83  pi = dynamic_cast<TParameter<Int_t> *>(fInput->FindObject("ProofEventProc_TestAbort"));
84  if (pi) fTestAbort = pi->GetVal();
85  if (fTestAbort < -1 || fTestAbort > 1) {
86  Info("SlaveBegin", "unsupported value for the abort test: %d not in [-1,1] - ignore", fTestAbort);
87  fTestAbort = -1;
88  } else if (fTestAbort > -1) {
89  Info("SlaveBegin", "running abort test: %d", fTestAbort);
90  }
91 
92  if (fTestAbort == 0)
93  Abort("Test abortion during init", kAbortProcess);
94 }
95 
96 //_____________________________________________________________________________
97 Bool_t ProofEventProc::Process(Long64_t entry)
98 {
99  // The Process() function is called for each entry in the tree (or possibly
100  // keyed object in the case of PROOF) to be processed. The entry argument
101  // specifies which entry in the currently loaded tree is to be processed.
102  // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
103  // to read either all or the required parts of the data. When processing
104  // keyed objects with PROOF, the object is already loaded and is available
105  // via the fObject pointer.
106  //
107  // This function should contain the "body" of the analysis. It can contain
108  // simple or elaborate selection criteria, run algorithms on the data
109  // of the event and typically fill histograms.
110 
111  // WARNING when a selector is used with a TChain, you must use
112  // the pointer to the current TTree to call GetEntry(entry).
113  // The entry is always the local entry number in the current tree.
114  // Assuming that fChain is the pointer to the TChain being processed,
115  // use fChain->GetTree()->GetEntry(entry).
116 
117  if (fEntMin == -1 || entry < fEntMin) fEntMin = entry;
118  if (fEntMax == -1 || entry > fEntMax) fEntMax = entry;
119 
120  if (fTestAbort == 1) {
121  Double_t rr = gRandom->Rndm();
122  if (rr > 0.999) {
123  Info("Process", "%lld -> %f", entry, rr);
124  Abort("Testing file abortion", kAbortFile);
125  return kTRUE;
126  }
127  }
128 
129  if (fFullRead) {
130  fChain->GetTree()->GetEntry(entry);
131  } else {
132  b_event_fNtrack->GetEntry(entry);
133  }
134 
135  if (fNtrack > 0) {
136  if (!fFullRead) b_fTracks->GetEntry(entry);
137  if (fTracks) {
138  for (Int_t j=0;j<fTracks->GetEntries();j++){
139  Track *curtrack = dynamic_cast<Track*>(fTracks->At(j));
140  if (curtrack) {
141  fPtHist->Fill(curtrack->GetPt(),1./curtrack->GetPt());
142  fPxPyHist->Fill(curtrack->GetPx(),curtrack->GetPy());
143  if (j == 0) fPzHist->Fill(curtrack->GetPz());
144  }
145  }
146  fTracks->Clear("C");
147  }
148  }
149 
150  return kTRUE;
151 }
152 
153 //_____________________________________________________________________________
154 void ProofEventProc::SlaveTerminate()
155 {
156  // The SlaveTerminate() function is called after all entries or objects
157  // have been processed. When running with PROOF SlaveTerminate() is called
158  // on each slave server.
159 
160  // Save information about previous element, if any
161  if (fProcElem) fProcElem->Add(fEntMin, fEntMax);
162 
163  if (!fProcElems) {
164  Warning("SlaveTerminate", "no proc elements list found!");
165  return;
166  }
167 
168  // Add proc elements to the output list
169  TIter nxpe(fProcElems);
170  TObject *o = 0;
171  while ((o = nxpe())) { fOutput->Add(o); };
172 }
173 
174 //_____________________________________________________________________________
175 void ProofEventProc::Terminate()
176 {
177  // The Terminate() function is the last function to be called during
178  // a query. It always runs on the client, it can be used to present
179  // the results graphically or save the results to file.
180 
181  // Check ranges
182  CheckRanges();
183 
184  if (gROOT->IsBatch()) return;
185 
186  TCanvas* canvas = new TCanvas("event","event",800,10,700,780);
187  canvas->Divide(2,2);
188  TPad *pad1 = (TPad *) canvas->GetPad(1);
189  TPad *pad2 = (TPad *) canvas->GetPad(2);
190  TPad *pad3 = (TPad *) canvas->GetPad(3);
191  TPad *pad4 = (TPad *) canvas->GetPad(4);
192 
193  // The number of tracks
194  pad1->cd();
195  pad1->SetLogy();
196  TH1F *hi = dynamic_cast<TH1F*>(fOutput->FindObject("pz_dist"));
197  if (hi) {
198  hi->SetFillColor(30);
199  hi->SetLineColor(9);
200  hi->SetLineWidth(2);
201  hi->DrawCopy();
202  } else { Warning("Terminate", "no pz dist found"); }
203 
204  // The Pt distribution
205  pad2->cd();
206  pad2->SetLogy();
207  TH1F *hf = dynamic_cast<TH1F*>(fOutput->FindObject("pt_dist"));
208  if (hf) {
209  hf->SetFillColor(30);
210  hf->SetLineColor(9);
211  hf->SetLineWidth(2);
212  hf->DrawCopy();
213  } else { Warning("Terminate", "no pt dist found"); }
214 
215  // The Px,Py distribution, color surface
216  TH2F *h2f = dynamic_cast<TH2F*>(fOutput->FindObject("px_py"));
217  if (h2f) {
218  // Color surface
219  pad3->cd();
220  h2f->DrawCopy("SURF1 ");
221  // Lego
222  pad4->cd();
223  h2f->DrawCopy("CONT2COL");
224  } else {
225  Warning("Terminate", "no px py found");
226  }
227 
228  // Final update
229  canvas->cd();
230  canvas->Update();
231 }
232 
233 //_____________________________________________________________________________
234 void ProofEventProc::CheckRanges()
235 {
236  // Check the processed event ranges when there is enough information
237  // The result is added to the output list
238 
239  // Must be something in output
240  if (!fOutput || (fOutput && fOutput->GetSize() <= 0)) return;
241 
242  // Create the result object and add it to the list
243  TNamed *nout = new TNamed("Range_Check", "OK");
244  fOutput->Add(nout);
245 
246  // Get info to check from the input list
247  if (!fInput || (fInput && fInput->GetSize() <= 0)) {
248  nout->SetTitle("No input list");
249  return;
250  }
251  TNamed *ffst = dynamic_cast<TNamed *>(fInput->FindObject("Range_First_File"));
252  if (!ffst) {
253  nout->SetTitle("No first file");
254  return;
255  }
256  TNamed *flst = dynamic_cast<TNamed *>(fInput->FindObject("Range_Last_File"));
257  if (!flst) {
258  nout->SetTitle("No last file");
259  return;
260  }
261  TParameter<Int_t> *fnum =
262  dynamic_cast<TParameter<Int_t> *>(fInput->FindObject("Range_Num_Files"));
263  if (!fnum) {
264  nout->SetTitle("No number of files");
265  return;
266  }
267 
268  // Check first file
269  TString fn(ffst->GetTitle()), sfst(ffst->GetTitle());
270  Ssiz_t ifst = fn.Index("?fst=");
271  if (ifst == kNPOS) {
272  nout->SetTitle("No first entry information in first file name");
273  return;
274  }
275  fn.Remove(ifst);
276  sfst.Remove(0, ifst + sizeof("?fst=") - 1);
277  if (!sfst.IsDigit()) {
278  nout->SetTitle("Badly formatted first entry information in first file name");
279  return;
280  }
281  Long64_t fst = (Long64_t) sfst.Atoi();
282  ProcFileElements *pfef = dynamic_cast<ProcFileElements *>(fOutput->FindObject(fn));
283  if (!pfef) {
284  nout->SetTitle("ProcFileElements for first file not found in the output list");
285  return;
286  }
287  if (pfef->GetFirst() != fst) {
288  TString t = TString::Format("First entry differs {found: %lld, expected: %lld}", pfef->GetFirst(), fst);
289  nout->SetTitle(t.Data());
290  return;
291  }
292 
293  // Check last file
294  fn = flst->GetTitle();
295  TString slst(flst->GetTitle());
296  Ssiz_t ilst = fn.Index("?lst=");
297  if (ilst == kNPOS) {
298  nout->SetTitle("No last entry information in last file name");
299  return;
300  }
301  fn.Remove(ilst);
302  slst.Remove(0, ilst + sizeof("?lst=") - 1);
303  if (!slst.IsDigit()) {
304  nout->SetTitle("Badly formatted last entry information in last file name");
305  return;
306  }
307  Long64_t lst = (Long64_t) slst.Atoi();
308  ProcFileElements *pfel = dynamic_cast<ProcFileElements *>(fOutput->FindObject(fn));
309  if (!pfel) {
310  nout->SetTitle("ProcFileElements for last file not found in the output list");
311  return;
312  }
313  if (pfel->GetLast() != lst) {
314  nout->SetTitle("Last entry differs");
315  return;
316  }
317 
318  // Check Number of files
319  Int_t nproc = 0;
320  TIter nxo(fOutput);
321  TObject *o = 0;
322  while ((o = nxo())) {
323  if (dynamic_cast<ProcFileElements *>(o)) nproc++;
324  }
325  if (fnum->GetVal() != nproc) {
326  nout->SetTitle("Number of processed files differs");
327  return;
328  }
329 }