ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
runProof.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup proof
3 ///
4 /// Macro to run examples of analysis on PROOF, corresponding to the TSelector
5 /// implementations found under <ROOTSYS>/tutorials/proof .
6 /// This macro uses an existing PROOF session or starts one at the indicated URL.
7 /// In the case non existing PROOF session is found and no URL is given, the
8 /// macro tries to start a local PROOF session.
9 ///
10 /// To run the macro:
11 ///
12 /// root[] .L proof/runProof.C+
13 /// root[] runProof("<analysis>")
14 ///
15 /// Currently available analysis are (to see how all this really works check
16 /// the scope for the specified option inside the macro):
17 ///
18 /// 1. "simple"
19 ///
20 /// Selector: ProofSimple.h.C
21 ///
22 /// root[] runProof("simple")
23 ///
24 /// This will create a local PROOF session and run an analysis filling
25 /// 100 histos with 100000 gaussian random numbers, and displaying them
26 /// in a canvas with 100 pads (10x10).
27 /// The number of histograms can be passed as argument 'nhist' to 'simple',
28 /// e.g. to fill 16 histos with 1000000 entries use
29 ///
30 /// root[] runProof("simple(nevt=1000000,nhist=16)")
31 ///
32 /// The argument nhist3 controls the creation of 3d histos to simulate
33 /// merging load. By default, no 3D hitogram is created.
34 ///
35 /// 2. "h1"
36 ///
37 /// Selector: tutorials/tree/h1analysis.h.C
38 ///
39 /// root[] runProof("h1")
40 ///
41 /// This runs the 'famous' H1 analysis from $ROOTSYS/tree/h1analysis.C.h.
42 /// By default the data are read from the HTTP server at root.cern.ch,
43 /// the data source can be changed via the argument 'h1src', e.g.
44 ///
45 /// root[] runProof("h1,h1src=/data/h1")
46 ///
47 /// (the directory specified must contain the 4 H1 files).
48 ///
49 /// The 'h1' example is also used to show how to use entry-lists in PROOF.
50 /// To fill the list for the events used for the final plots add the option
51 /// 'fillList':
52 ///
53 /// root[] runProof("h1,fillList")
54 ///
55 /// To use the list previously created for the events used for the
56 /// final plots add the option 'useList':
57 ///
58 /// root[] runProof("h1,useList")
59 ///
60 /// 3. "event"
61 ///
62 /// Selector: ProofEvent.h,.C
63 ///
64 /// This is an example of using PROOF par files.
65 /// It runs event generation and simple analysis based on the 'Event'
66 /// class found under test.
67 ///
68 /// root[] runProof("event")
69 ///
70 /// 4. "eventproc"
71 ///
72 /// Selector: ProofEventProc.h.C
73 ///
74 /// This is an example of using PROOF par files and process 'event'
75 /// data from the ROOT HTTP server. It runs the ProofEventProc selector
76 /// which is derived from the EventTree_Proc one found under
77 /// test/ProofBench. The following specific arguments are available:
78 /// - 'readall' to read the whole event, by default only the branches
79 /// needed by the analysis are read (read 25% more bytes)
80 /// - 'datasrc=<dir-with-files>' to read the files from another server,
81 /// the files must be named 'event_<num>.root' where <num>=1,2,...
82 /// or
83 /// - 'datasrc=<file-with-files>' to take the file content from a text file,
84 /// specified one file per line; usefull when testing differences
85 /// between several sources and distributions
86 /// - 'files=N' to change the number of files to be analysed (default
87 /// is 10, max is 50 for the HTTP server).
88 /// - 'uneven' to process uneven entries from files following the scheme
89 /// {50000,5000,5000,5000,5000} and so on
90 ///
91 /// root[] runProof("eventproc")
92 ///
93 /// 5. "pythia8"
94 ///
95 /// Selector: ProofPythia.h.C
96 ///
97 /// This runs Pythia8 generation based on main03.cc example in Pythia 8.1
98 ///
99 /// To run this analysis ROOT must be configured with pythia8.
100 ///
101 /// Note that before executing this analysis, the env variable PYTHIA8
102 /// must point to the pythia8100 (or newer) directory, in particular,
103 /// $PYTHIA8/xmldoc must contain the file Index.xml. The tutorial assumes
104 /// that the Pythia8 directory is the same on all machines, i.e. local
105 /// and worker ones.
106 ///
107 /// root[] runProof("pythia8")
108 ///
109 /// 6. "ntuple"
110 ///
111 /// Selector: ProofNtuple.h.C
112 ///
113 /// This is an example of final merging via files created on the workers,
114 /// using TProofOutputFile. The final file is called ProofNtuple.root
115 /// and it is created in the directory where the tutorial is run. If
116 /// the PROOF cluster is remote, the file is received by a local xrootd
117 /// daemon started for the purpose. Because of this, this example can be
118 /// run only on unix clients.
119 ///
120 /// root[] runProof("ntuple")
121 ///
122 /// By default the random numbers are generate anew. There is the
123 /// possibility use a file of random numbers (to have reproducible results)
124 /// by specify the option 'inputrndm', e.g.
125 ///
126 /// root[] runProof("ntuple(inputrndm)")
127 ///
128 /// By default the output will be saved in the local file SimpleNtuple.root;
129 /// location and name of the file can be changed via the argument 'outfile',
130 /// e.g.
131 ///
132 /// root[] runProof("simplefile(outfile=/data0/testntuple.root)")
133 /// root[] runProof("simplefile(outfile=root://aserver//data/testntuple.root)")
134 ///
135 /// 7. "dataset"
136 ///
137 /// Selector: ProofNtuple.h.C
138 ///
139 /// This is an example of automatic creation of a dataset from files
140 /// created on the workers, using TProofOutputFile. The dataset is
141 /// called testNtuple and it is automatically registered and verified.
142 /// The files contain the same ntuple as in previous example/tutorial 6
143 /// (the same selector ProofNTuple is used with a slightly different
144 /// configuration). The dataset is then used to produce the same plot
145 /// as in 5 but using the DrawSelect methods of PROOF, which also show
146 /// how to set style, color and other drawing attributes in PROOF.
147 /// Depending on the relative worker perforance, some of the produced
148 /// files may result in having no entries. If this happens, the file
149 /// will be added to the missing (skipped) file list. Increasing the
150 /// number of events (via nevt=...) typically solves this issue.
151 ///
152 /// root[] runProof("dataset")
153 ///
154 /// 8. "friends"
155 ///
156 /// Selectors: ProofFriends.h(.C), ProofAux.h(.C)
157 ///
158 /// This is an example of TTree friend processing in PROOF. It also shows
159 /// how to use the TPacketizerFile to steer creation of files.
160 ///
161 /// root[] runProof("friends")
162 ///
163 /// The trees are by default created in separate files; to create
164 /// them in the same file use option 'samefile', e.g.
165 ///
166 /// root[] runProof("friends(samefile)")
167 ///
168 /// 9. "simplefile"
169 ///
170 /// Selector: ProofSimpleFile.h.C
171 ///
172 /// root[] runProof("simplefile")
173 ///
174 /// This will create a local PROOF session and run an analysis filling
175 /// 16+16 histos with 100000 gaussian random numbers. The merging of
176 /// these histos goes via file; 16 histos are saved in the top directory,
177 /// the other 16 into a subdirectory called 'blue'. The final display
178 /// is done in two canvanses, one for each set of histograms and with
179 /// 16 pads each (4x4).
180 /// The number of histograms in each set can be passed as argument
181 /// 'nhist' to 'simplefile', e.g. to fill 25 histos with 1000000 entries use
182 ///
183 /// root[] runProof("simplefile(nevt=1000000,nhist=25)")
184 ///
185 /// By default the output will be saved in the local file SimpleFile.root;
186 /// location and name of the file can be changed via the argument 'outfile',
187 /// e.g.
188 ///
189 /// root[] runProof("simplefile(outfile=/data0/testsimple.root)")
190 /// root[] runProof("simplefile(outfile=root://aserver//data/testsimple.root)")
191 ///
192 /// 10. "stdvec"
193 ///
194 /// Selector: ProofStdVect.h.C
195 ///
196 /// This is an example of using standard vectors (vector<vector<bool> > and
197 /// vector<vector<float> >) in a TSelector. The same selector is run twice:
198 /// in 'create' mode it creates a dataset with the tree 'stdvec' containing
199 /// 3 branches, a vector<vector<bool> > and two vector<vector<float> >. The
200 /// tree is saved into a file on each worker and a dataset is created with
201 /// these files (the dataset is called 'TestStdVect'); in 'read' mode the
202 /// dataset is read and a couple fo histograms filled and displayed.
203 ///
204 /// root[] runProof("stdvec")
205 ///
206 /// General arguments
207 /// -----------------
208 ///
209 /// The following arguments are valid for all examples (the ones specific
210 /// to each tutorial have been explained above)
211 ///
212 /// 1. ACLiC mode
213 ///
214 /// By default all processing is done with ACLiC mode '+', i.e. compile
215 /// if changed. However, this may lead to problems if the available
216 /// selector libs were compiled in previous sessions with a different
217 /// set of loaded libraries (this is a general problem in ROOT). When
218 /// this happens the best solution is to force recompilation (ACLiC
219 /// mode '++'). To do this just add one or more '+' to the name of the
220 /// tutorial, e.g. runProof("simple++")
221 ///
222 /// 2. debug=[what:]level
223 ///
224 /// Controls verbosity; 'level' is an integer number and the optional string
225 /// 'what' one or more of the enum names in TProofDebug.h .
226 /// e.g. runProof("eventproc(debug=kPacketizer|kCollect:2)") runs 'eventproc' enabling
227 /// all printouts matching TProofDebug::kPacketizer and having level
228 /// equal or larger than 2 .
229 ///
230 /// 3. nevt=N and/or first=F
231 ///
232 /// Set the number of entries to N, eventually (when it makes sense, i.e. when
233 /// processing existing files) starting from F
234 /// e.g. runProof("simple(nevt=1000000000)") runs simple with 1000000000
235 /// runProof("eventproc(first=65000)") runs eventproc processing
236 /// starting with event 65000
237 /// runProof("eventproc(nevt=100000,first=65000)") runs eventproc processing
238 /// 100000 events starting with event 65000
239 ///
240 /// 4. asyn
241 ///
242 /// Run in non blocking mode
243 /// e.g. root[] runProof("h1(asyn)")
244 ///
245 /// 5. nwrk=N
246 ///
247 /// Set the number of active workers to N, usefull to test performance
248 /// on a remote cluster where control about the number of workers is
249 /// not possible, e.g. runProof("event(nwrk=2)") runs 'event' with
250 /// 2 workers.
251 ///
252 /// 6. punzip
253 ///
254 /// Use parallel unzipping in reading files where relevant
255 /// e.g. root[] runProof("eventproc(punzip)")
256 ///
257 /// 7. cache=<bytes> (or <kbytes>K or <mbytes>M)
258 ///
259 /// Change the size of the tree cache; 0 or <0 disables the cache,
260 /// value cane be in bytes (no suffix), kilobytes (suffix 'K') or
261 /// megabytes (suffix 'M'), e.g. root[] runProof("eventproc(cache=0)")
262 ///
263 /// 8. submergers[=S]
264 ///
265 /// Enabling merging via S submergers or the optimal number if S is
266 /// not specified, e.g. root[] runProof("simple(hist=1000,submergers)")
267 ///
268 /// 9. rateest=average
269 ///
270 /// Enable processed entries estimation for constant progress reporting based on
271 /// the measured average. This may screw up the progress bar in some cases, which
272 /// is the reason why it is not on by default .
273 /// e.g. root[] runProof("eventproc(rateest=average)")
274 ///
275 /// 10. perftree=perftreefile.root
276 ///
277 /// Generate the perfomance tree and save it to file 'perftreefile.root',
278 /// e.g. root[] runProof("eventproc(perftree=perftreefile.root)")
279 ///
280 /// 11. feedback=name1[,name2,name3,...]|off
281 ///
282 /// Enable feedback for the specified names or switch it off; by default it is
283 /// enabled for the 'stats' histograms (events,packest, packets-being processed).
284 ///
285 /// In all cases, to run on a remote PROOF cluster, the master URL must
286 /// be passed as second argument; e.g.
287 ///
288 /// root[] runProof("simple","master.do.main")
289 ///
290 /// A rough parsing of the URL is done to determine the locality of the cluster.
291 /// If using a tunnel the URL can start by localhost even for external clusters:
292 /// in such cases the default locality determination will be wrong, so one has
293 /// to tell explicity that the cluster is external via the option field, e.g.
294 ///
295 /// root[] runProof("simple","localhost:33002/?external")
296 ///
297 /// In the case of local running it is possible to specify the number of
298 /// workers to start as third argument (the default is the number of cores
299 /// of the machine), e.g.
300 ///
301 /// root[] runProof("simple",0,4)
302 ///
303 /// will start 4 workers. Note that the real number of workers is changed
304 /// only the first time you call runProof into a ROOT session. Following
305 /// calls can reduce the number of active workers, but not increase it.
306 /// For example, in the same session of the call above starting 4 workers,
307 /// this
308 ///
309 /// root[] runProof("simple",0,8)
310 ///
311 /// will still use 4 workers, while this
312 ///
313 /// root[] runProof("simple",0,2)
314 ///
315 /// will disable 2 workers and use the other 2.
316 ///
317 /// Finally, it is possible to pass as 4th argument a list of objects to be added
318 /// to the input list to further control the PROOF behaviour:
319 ///
320 /// root [] TList *ins = new TList
321 /// root [] ins->Add(new TParameter<Int_t>("MyParm", 3))
322 /// root [] runProof("simple",0,4,ins)
323 ///
324 /// the content of 'ins' will then be copied to the input list before processing.
325 ///
326 ///
327 /// \macro_code
328 ///
329 /// \author Gerardo Ganis
330 
331 
332 #include "TCanvas.h"
333 #include "TChain.h"
334 #include "TDSet.h"
335 #include "TEnv.h"
336 #include "TEntryList.h"
337 #include "TFile.h"
338 #include "TFileCollection.h"
339 #include "TFrame.h"
340 #include "THashList.h"
341 #include "TList.h"
342 #include "TPad.h"
343 #include "TPaveText.h"
344 #include "TProof.h"
345 #include "TProofDebug.h"
346 #include "TString.h"
347 
348 #include "getProof.C"
349 void plotNtuple(TProof *p, const char *ds, const char *ntptitle);
350 void SavePerfTree(TProof *proof, const char *fn);
351 
352 // Variable used to locate the Pythia8 directory for the Pythia8 example
353 const char *pythia8dir = 0;
354 const char *pythia8data = 0;
355 
356 void runProof(const char *what = "simple",
357  const char *masterurl = "proof://localhost:40000",
358  Int_t nwrks = -1, TList *ins = 0)
359 {
360 #ifdef __CINT__
361  Printf("runProof: this script can only be executed via ACliC:");
362  Printf("runProof: root [] .x <path>/runProof.C+");
363  Printf("runProof: or root [] .L <path>/runProof.C+");
364  Printf("runProof: root [] runProof(...)");
365  return;
366 #endif
367  gEnv->SetValue("Proof.StatsHist",1);
368 
369  TString u(masterurl);
370  // Determine locality of this session
371  Bool_t isProofLocal = kFALSE;
372  if (!u.IsNull() && u != "lite://") {
373  TUrl uu(masterurl);
374  TString uopts(uu.GetOptions());
375  if ((!strcmp(uu.GetHost(), "localhost") && !uopts.Contains("external")) ||
376  !strcmp(uu.GetHostFQDN(), TUrl(gSystem->HostName()).GetHostFQDN())) {
377  isProofLocal = kTRUE;
378  }
379  // Adjust URL
380  if (!u.BeginsWith(uu.GetProtocol())) uu.SetProtocol("proof");
381  uopts.ReplaceAll("external", "");
382  uu.SetOptions(uopts.Data());
383  u = uu.GetUrl();
384  }
385  const char *url = u.Data();
386 
387  // Temp dir for PROOF tutorials
388  // Force "/tmp/<user>" whenever possible to avoid length problems on MacOsX
389  TString tmpdir("/tmp");
390  if (gSystem->AccessPathName(tmpdir, kWritePermission)) tmpdir = gSystem->TempDirectory();
391  TString us;
393  if (!ug) {
394  Printf("runProof: could not get user info");
395  return;
396  }
397  us.Form("/%s", ug->fUser.Data());
398  if (!tmpdir.EndsWith(us.Data())) tmpdir += us;
399  gSystem->mkdir(tmpdir.Data(), kTRUE);
400  if (gSystem->AccessPathName(tmpdir, kWritePermission)) {
401  Printf("runProof: unable to get a writable tutorial directory (tried: %s)"
402  " - cannot continue", tmpdir.Data());
403  return;
404  }
405  TString tutdir = Form("%s/.proof-tutorial", tmpdir.Data());
406  if (gSystem->AccessPathName(tutdir)) {
407  Printf("runProof: creating the temporary directory"
408  " for the tutorial (%s) ... ", tutdir.Data());
409  if (gSystem->mkdir(tutdir, kTRUE) != 0) {
410  Printf("runProof: could not assert / create the temporary directory"
411  " for the tutorial (%s)", tutdir.Data());
412  return;
413  }
414  }
415 
416  // For the Pythia8 example we need to set some environment variable;
417  // This must be done BEFORE starting the PROOF session
418  if (what && !strncmp(what, "pythia8", 7)) {
419  // We assume that the remote location of Pythia8 is the same as the local one
420  pythia8dir = gSystem->Getenv("PYTHIA8");
421  if (!pythia8dir || strlen(pythia8dir) <= 0) {
422  Printf("runProof: pythia8: environment variable PYTHIA8 undefined:"
423  " it must contain the path to pythia81xx root directory (local and remote) !");
424  return;
425  }
426  pythia8data = gSystem->Getenv("PYTHIA8DATA");
427  if (!pythia8data || strlen(pythia8data) <= 0) {
428  gSystem->Setenv("PYTHIA8DATA", Form("%s/xmldoc", pythia8dir));
429  pythia8data = gSystem->Getenv("PYTHIA8DATA");
430  if (!pythia8data || strlen(pythia8data) <= 0) {
431  Printf("runProof: pythia8: environment variable PYTHIA8DATA undefined:"
432  " it one must contain the path to pythia81xx/xmldoc"
433  " subdirectory (local and remote) !");
434  return;
435  }
436  }
437  TString env = Form("echo export PYTHIA8=%s; export PYTHIA8DATA=%s",
438  pythia8dir, pythia8data);
439  TProof::AddEnvVar("PROOF_INITCMD", env.Data());
440  }
441 
442  Printf("tutorial dir:\t%s", tutdir.Data());
443 
444  // Get the PROOF Session
445  TProof *proof = getProof(url, nwrks, tutdir.Data(), "ask");
446  if (!proof) {
447  Printf("runProof: could not start/attach a PROOF session");
448  return;
449  }
450 
451  // Refine locality (PROOF-Lite always local)
452  if (proof->IsLite()) isProofLocal = kTRUE;
453 
454 #ifdef WIN32
455  if (isProofLocal && what && !strcmp(what, "ntuple", 6)) {
456  // Not support on windows
457  Printf("runProof: the 'ntuple' example needs to run xrootd to receive the output file, \n"
458  " but xrootd is not supported on Windows - cannot continue");
459  return;
460  }
461 #endif
462 
463  TString proofsessions(Form("%s/sessions",tutdir.Data()));
464  // Save tag of the used session
465  FILE *fs = fopen(proofsessions.Data(), "a");
466  if (!fs) {
467  Printf("runProof: could not create files for sessions tags");
468  } else {
469  fprintf(fs,"session-%s\n", proof->GetSessionTag());
470  fclose(fs);
471  }
472  if (!proof) {
473  Printf("runProof: could not start/attach a PROOF session");
474  return;
475  }
476 
477  // Set the number of workers (may only reduce the number of active workers
478  // in the session)
479  if (nwrks > 0)
480  proof->SetParallel(nwrks);
481 
482  // Where is the code to run
483  char *rootbin = gSystem->Which(gSystem->Getenv("PATH"), "root.exe", kExecutePermission);
484  if (!rootbin) {
485  Printf("runProof: root.exe not found: please check the environment!");
486  return;
487  }
488  TString rootsys(gSystem->DirName(rootbin));
489  rootsys = gSystem->DirName(rootsys);
490  TString tutorials(Form("%s/tutorials", rootsys.Data()));
491  delete[] rootbin;
492 
493  // Parse 'what'; it is in the form 'analysis(arg1,arg2,...)'
494  TString args(what);
495  args.ReplaceAll("("," ");
496  args.ReplaceAll(")"," ");
497  args.ReplaceAll(","," ");
498  Ssiz_t from = 0;
499  TString act, tok;
500  if (!args.Tokenize(act, from, " ")) {
501  // Cannot continue
502  Printf("runProof: action not found: check your arguments (%s)", what);
503  return;
504  }
505  // Extract ACLiC mode
506  TString aMode = "+";
507  if (act.EndsWith("+")) {
508  aMode += "+";
509  while (act.EndsWith("+")) { act.Remove(TString::kTrailing,'+'); }
510  }
511  Printf("runProof: %s: ACLiC mode: '%s'", act.Data(), aMode.Data());
512 
513  // Parse out number of events and 'asyn' option, used almost by every test
514  TString aNevt, aFirst, aNwrk, opt, sel, punzip("off"), aCache, aOutFile,
515  aH1Src("http://root.cern.ch/files/h1"),
516  aDebug, aDebugEnum, aRateEst, aPerfTree("perftree.root"),
517  aFeedback("fb=stats");
518  Long64_t suf = 1;
519  Int_t aSubMg = -1;
520  Bool_t useList = kFALSE, makePerfTree = kFALSE;
521  while (args.Tokenize(tok, from, " ")) {
522  // Debug controllers
523  if (tok.BeginsWith("debug=")) {
524  aDebug = tok;
525  aDebug.ReplaceAll("debug=","");
526  Int_t icol = kNPOS;
527  if ((icol = aDebug.Index(":")) != kNPOS) {
528  aDebugEnum = aDebug(0, icol);
529  aDebug.Remove(0, icol+1);
530  }
531  if (!aDebug.IsDigit()) {
532  Printf("runProof: %s: error parsing the 'debug=' option (%s) - ignoring", act.Data(), tok.Data());
533  aDebug = "";
534  aDebugEnum = "";
535  }
536  }
537  // Number of events
538  if (tok.BeginsWith("nevt=")) {
539  aNevt = tok;
540  aNevt.ReplaceAll("nevt=","");
541  if (!aNevt.IsDigit()) {
542  Printf("runProof: %s: error parsing the 'nevt=' option (%s) - ignoring", act.Data(), tok.Data());
543  aNevt = "";
544  }
545  }
546  // First event
547  if (tok.BeginsWith("first=")) {
548  aFirst = tok;
549  aFirst.ReplaceAll("first=","");
550  if (!aFirst.IsDigit()) {
551  Printf("runProof: %s: error parsing the 'first=' option (%s) - ignoring", act.Data(), tok.Data());
552  aFirst = "";
553  }
554  }
555  // Sync or async ?
556  if (tok.BeginsWith("asyn"))
557  opt = "ASYN";
558  // Number of workers
559  if (tok.BeginsWith("nwrk=")) {
560  aNwrk = tok;
561  aNwrk.ReplaceAll("nwrk=","");
562  if (!aNwrk.IsDigit()) {
563  Printf("runProof: %s: error parsing the 'nwrk=' option (%s) - ignoring", act.Data(), tok.Data());
564  aNwrk = "";
565  }
566  }
567  // Parallel unzipping ?
568  if (tok.BeginsWith("punzip"))
569  punzip = "on";
570  // Number of workers
571  if (tok.BeginsWith("cache=")) {
572  aCache = tok;
573  aCache.ReplaceAll("cache=","");
574  if (aCache.EndsWith("k")) { aCache.Remove(TString::kTrailing, 'k'); suf = 1024; }
575  if (aCache.EndsWith("K")) { aCache.Remove(TString::kTrailing, 'K'); suf = 1024; }
576  if (aCache.EndsWith("M")) { aCache.Remove(TString::kTrailing, 'M'); suf = 1024*1024; }
577  if (!aCache.IsDigit()) {
578  Printf("runProof: %s: error parsing the 'cache=' option (%s) - ignoring", act.Data(), tok.Data());
579  aCache = "";
580  }
581  }
582  // Use submergers?
583  if (tok.BeginsWith("submergers")) {
584  tok.ReplaceAll("submergers","");
585  aSubMg = 0;
586  if (tok.BeginsWith("=")) {
587  tok.ReplaceAll("=","");
588  if (tok.IsDigit()) aSubMg = tok.Atoi();
589  }
590  }
591  // H1: use entry-lists ?
592  if (tok.BeginsWith("useList")) {
593  useList = kTRUE;
594  }
595  if (tok.BeginsWith("fillList")) {
596  opt += "fillList";
597  }
598  // H1: change location of files?
599  if (tok.BeginsWith("h1src=")) {
600  tok.ReplaceAll("h1src=","");
601  if (!(tok.IsNull())) aH1Src = tok;
602  Printf("runProof: %s: reading data files from '%s'", act.Data(), aH1Src.Data());
603  }
604  // Rate estimation technique
605  if (tok.BeginsWith("rateest=")) {
606  tok.ReplaceAll("rateest=","");
607  if (!(tok.IsNull())) aRateEst = tok;
608  Printf("runProof: %s: progress-bar rate estimation option: '%s'", act.Data(), aRateEst.Data());
609  }
610  // Create and save the preformance tree?
611  if (tok.BeginsWith("perftree")) {
612  makePerfTree = kTRUE;
613  if (tok.BeginsWith("perftree=")) {
614  tok.ReplaceAll("perftree=","");
615  if (!(tok.IsNull())) aPerfTree = tok;
616  }
617  Printf("runProof: %s: saving performance tree to '%s'", act.Data(), aPerfTree.Data());
618  }
619  // Location of the output file, if any
620  if (tok.BeginsWith("outfile")) {
621  if (tok.BeginsWith("outfile=")) {
622  tok.ReplaceAll("outfile=","");
623  if (!(tok.IsNull())) aOutFile = tok;
624  }
625  Printf("runProof: %s: output file: '%s'", act.Data(), aOutFile.Data());
626  }
627  // Feedback
628  if (tok.BeginsWith("feedback=")) {
629  tok.ReplaceAll("feedback=","");
630  if (tok == "off" || tok == "OFF" || tok == "0") {
631  aFeedback = "";
632  } else if (!(tok.IsNull())) {
633  if (tok.BeginsWith("+")) {
634  tok[0] = ',';
635  aFeedback += tok;
636  } else {
637  aFeedback.Form("fb=%s", tok.Data());
638  }
639  }
640  Printf("runProof: %s: feedback: '%s'", act.Data(), aFeedback.Data());
641  }
642  }
643  Long64_t nevt = (aNevt.IsNull()) ? -1 : aNevt.Atoi();
644  Long64_t first = (aFirst.IsNull()) ? 0 : aFirst.Atoi();
645  Long64_t nwrk = (aNwrk.IsNull()) ? -1 : aNwrk.Atoi();
646  from = 0;
647 
648  // Set number workers
649  if (nwrk > 0) {
650  if (proof->GetParallel() < nwrk) {
651  Printf("runProof: %s: request for a number of workers larger then available - ignored", act.Data());
652  } else {
653  proof->SetParallel(nwrk);
654  }
655  }
656 
657  // Debug controllers
658  if (!aDebug.IsNull()) {
659  Int_t dbg = aDebug.Atoi();
660  Int_t scope = TProofDebug::kAll;
661  if (!aDebugEnum.IsNull()) scope = getDebugEnum(aDebugEnum.Data());
662  proof->SetLogLevel(dbg, scope);
663  Printf("runProof: %s: verbose mode for '%s'; level: %d", act.Data(), aDebugEnum.Data(), dbg);
664  }
665 
666  // Have constant progress reporting based on estimated info
667  // (NB: may screw up the progress bar in some cases)
668  if (aRateEst == "average")
669  proof->SetParameter("PROOF_RateEstimation", aRateEst);
670 
671  // Parallel unzip
672  if (punzip == "on") {
673  proof->SetParameter("PROOF_UseParallelUnzip", (Int_t)1);
674  Printf("runProof: %s: parallel unzip enabled", act.Data());
675  } else {
676  proof->SetParameter("PROOF_UseParallelUnzip", (Int_t)0);
677  }
678 
679  // Tree cache
680  if (!aCache.IsNull()) {
681  Long64_t cachesz = aCache.Atoi() * suf;
682  if (cachesz <= 0) {
683  proof->SetParameter("PROOF_UseTreeCache", (Int_t)0);
684  Printf("runProof: %s: disabling tree cache", act.Data());
685  } else {
686  proof->SetParameter("PROOF_UseTreeCache", (Int_t)1);
687  proof->SetParameter("PROOF_CacheSize", cachesz);
688  Printf("runProof: %s: setting cache size to %lld", act.Data(), cachesz);
689  }
690  } else {
691  // Use defaults
692  proof->DeleteParameters("PROOF_UseTreeCache");
693  proof->DeleteParameters("PROOF_CacheSize");
694  }
695 
696  // Enable submergers, if required
697  if (aSubMg >= 0) {
698  proof->SetParameter("PROOF_UseMergers", aSubMg);
699  if (aSubMg > 0) {
700  Printf("runProof: %s: enabling merging via %d sub-mergers", act.Data(), aSubMg);
701  } else {
702  Printf("runProof: %s: enabling merging via sub-mergers (optimal number)", act.Data());
703  }
704  } else {
705  proof->DeleteParameters("PROOF_UseMergers");
706  }
707 
708  // The performance tree
709  if (makePerfTree) {
710  proof->SetParameter("PROOF_StatsHist", "");
711  proof->SetParameter("PROOF_StatsTrace", "");
712  proof->SetParameter("PROOF_SlaveStatsTrace", "");
713  }
714 
715  // Additional inputs from the argument 'ins'
716  if (ins && ins->GetSize() > 0) {
717  TObject *oin = 0;
718  TIter nxo(ins);
719  while ((oin = nxo())) { proof->AddInput(oin); }
720  }
721 
722  // Full lits of inputs so far
723  proof->GetInputList()->Print();
724 
725  // Action
726  if (act == "simple") {
727  // ProofSimple is an example of non-data driven analysis; it
728  // creates and fills with random numbers a given number of histos
729 
730  if (first > 0)
731  // Meaningless for this tutorial
732  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
733  " - ignored", act.Data());
734 
735  // Default 10000 events
736  nevt = (nevt < 0) ? 100000 : nevt;
737  // Find out the number of histograms
738  TString aNhist, aNhist3;
739  while (args.Tokenize(tok, from, " ")) {
740  // Number of histos
741  if (tok.BeginsWith("nhist=")) {
742  aNhist = tok;
743  aNhist.ReplaceAll("nhist=","");
744  if (!aNhist.IsDigit()) {
745  Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
746  aNhist = "";
747  }
748  } else if (tok.BeginsWith("nhist3=")) {
749  aNhist3 = tok;
750  aNhist3.ReplaceAll("nhist3=","");
751  if (!aNhist3.IsDigit()) {
752  Printf("runProof: error parsing the 'nhist3=' option (%s) - ignoring", tok.Data());
753  aNhist3 = "";
754  }
755  }
756  }
757  Int_t nhist = (aNhist.IsNull()) ? 100 : aNhist.Atoi();
758  Int_t nhist3 = (aNhist3.IsNull()) ? -1 : aNhist3.Atoi();
759  Printf("\nrunProof: running \"simple\" with nhist= %d, nhist3=%d and nevt= %lld\n", nhist, nhist3, nevt);
760 
761  // The number of histograms is added as parameter in the input list
762  proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
763  // The number of histograms is added as parameter in the input list
764  if (nhist3 > 0) proof->SetParameter("ProofSimple_NHist3", (Long_t)nhist3);
765  // The selector string
766  sel.Form("%s/proof/ProofSimple.C%s", tutorials.Data(), aMode.Data());
767  //
768  // Run it for nevt times
769  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
770  proof->Process(sel.Data(), nevt, xopt);
771 
772  } else if (act == "h1") {
773  // This is the famous 'h1' example analysis run on Proof reading the
774  // data from the ROOT http server.
775 
776  // Create the chain
777  TChain *chain = new TChain("h42");
778  chain->Add(TString::Format("%s/dstarmb.root", aH1Src.Data()));
779  chain->Add(TString::Format("%s/dstarp1a.root", aH1Src.Data()));
780  chain->Add(TString::Format("%s/dstarp1b.root", aH1Src.Data()));
781  chain->Add(TString::Format("%s/dstarp2.root", aH1Src.Data()));
782  chain->ls();
783  // We run on Proof
784  chain->SetProof();
785  // Set entrylist, if required
786  if (useList) {
787  TString eln("elist"), elfn("elist.root");
788  if (gSystem->AccessPathName(elfn)) {
789  Printf("\nrunProof: asked to use an entry list but '%s' not found or not readable", elfn.Data());
790  Printf("\nrunProof: did you forget to run with 'fillList=%s'?\n", elfn.Data());
791  } else {
792  TFile f(elfn);
793  if (!(f.IsZombie())) {
794  TEntryList *elist = (TEntryList *)f.Get(eln);
795  if (elist) {
796  elist->SetDirectory(0); //otherwise the file destructor will delete elist
797  chain->SetEntryList(elist);
798  } else {
799  Printf("\nrunProof: could not find entry-list '%s' in file '%s': ignoring",
800  eln.Data(), elfn.Data());
801  }
802  } else {
803  Printf("\nrunProof: requested entry-list file '%s' not existing (or not readable):"
804  " ignoring", elfn.Data());
805  }
806  }
807  }
808  // The selector
809  sel.Form("%s/tree/h1analysis.C%s", tutorials.Data(), aMode.Data());
810  // Run it
811  Printf("\nrunProof: running \"h1\"\n");
812  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
813  chain->Process(sel.Data(),xopt,nevt,first);
814  // Cleanup the input list
815  gProof->ClearInputData("elist");
816  gProof->ClearInputData("elist.root");
817  TIter nxi(gProof->GetInputList());
818  TObject *o = 0;
819  while ((o = nxi())) {
820  if (!strncmp(o->GetName(), "elist", 5)) {
821  gProof->GetInputList()->Remove(o);
822  delete o;
823  }
824  }
825 
826  } else if (act == "pythia8") {
827 
828  if (first > 0)
829  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
830  " - ignored", act.Data());
831 
832  TString path(Form("%s/Index.xml", pythia8data));
833  gSystem->ExpandPathName(path);
834  if (gSystem->AccessPathName(path)) {
835  Printf("runProof: pythia8: PYTHIA8DATA directory (%s) must"
836  " contain the Index.xml file !", pythia8data);
837  return;
838  }
839  TString pythia8par = TString::Format("%s/proof/pythia8.par", tutorials.Data());
840  if (gSystem->AccessPathName(pythia8par.Data())) {
841  Printf("runProof: pythia8: par file not found (tried %s)", pythia8par.Data());
842  return;
843  }
844  proof->UploadPackage(pythia8par);
845  proof->EnablePackage("pythia8");
846  // Show enabled packages
847  proof->ShowEnabledPackages();
848  Printf("runProof: pythia8: check settings:");
849  proof->Exec(".!echo hostname = `hostname`; echo \"ls pythia8:\"; ls pythia8");
850  // Loading libraries needed
851  if (gSystem->Load("libEG.so") < 0) {
852  Printf("runProof: pythia8: libEG not found \n");
853  return;
854  }
855  if (gSystem->Load("libEGPythia8.so") < 0) {
856  Printf("runProof: pythia8: libEGPythia8 not found \n");
857  return;
858  }
859  // Setting the default number of events, if needed
860  nevt = (nevt < 0) ? 100 : nevt;
861  Printf("\nrunProof: running \"Pythia01\" nevt= %lld\n", nevt);
862  // The selector string
863  sel.Form("%s/proof/ProofPythia.C%s", tutorials.Data(), aMode.Data());
864  // Run it for nevt times
865  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
866  proof->Process(sel.Data(), nevt, xopt);
867 
868  } else if (act == "event") {
869 
870  if (first > 0)
871  // Meaningless for this tutorial
872  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
873  " - ignored", act.Data());
874 
875  TString eventpar = TString::Format("%s/proof/event.par", tutorials.Data());
876  if (gSystem->AccessPathName(eventpar.Data())) {
877  Printf("runProof: event: par file not found (tried %s)", eventpar.Data());
878  return;
879  }
880 
881  proof->UploadPackage(eventpar);
882  proof->EnablePackage("event");
883  Printf("Enabled packages...\n");
884  proof->ShowEnabledPackages();
885 
886  // Setting the default number of events, if needed
887  nevt = (nevt < 0) ? 100 : nevt;
888  Printf("\nrunProof: running \"event\" nevt= %lld\n", nevt);
889  // The selector string
890  sel.Form("%s/proof/ProofEvent.C%s", tutorials.Data(), aMode.Data());
891  // Run it for nevt times
892  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
893  proof->Process(sel.Data(), nevt, xopt);
894 
895  } else if (act == "eventproc") {
896 
897  TString eventpar = TString::Format("%s/proof/event.par", tutorials.Data());
898  gSystem->ExpandPathName(eventpar);
899  if (gSystem->AccessPathName(eventpar.Data())) {
900  Printf("runProof: eventproc: par file not found (tried %s)", eventpar.Data());
901  return;
902  }
903 
904  proof->UploadPackage(eventpar);
905  proof->EnablePackage("event");
906  Printf("Enabled packages...\n");
907  proof->ShowEnabledPackages();
908 
909  // Load ProcFileElements (to check processed ranges)
910  TString pfelem = TString::Format("%s/proof/ProcFileElements.C", tutorials.Data());
911  gSystem->ExpandPathName(pfelem);
912  if (gSystem->AccessPathName(pfelem.Data())) {
913  Printf("runProof: eventproc: ProcFileElements.C not found (tried %s)", pfelem.Data());
914  return;
915  }
916  pfelem += aMode;
917  // Add include to test trasmission
918  pfelem += TString::Format(",%s/proof/EmptyInclude.h", tutorials.Data());
919  proof->Load(pfelem);
920 
921  // Extract the number of files to process, data source and
922  // other parameters controlling the run ...
923  Bool_t uneven = kFALSE;
924  TString aFiles, aDataSrc("http://root.cern.ch/files/data"), aPartitions;
925  proof->SetParameter("ProofEventProc_Read", "optimized");
926  while (args.Tokenize(tok, from, " ")) {
927  // Number of events
928  if (tok.BeginsWith("files=")) {
929  aFiles = tok;
930  aFiles.ReplaceAll("files=","");
931  if (!aFiles.IsDigit()) {
932  Printf("runProof: error parsing the 'files=' option (%s) - ignoring", tok.Data());
933  aFiles = "";
934  }
935  } else if (tok.BeginsWith("datasrc=")) {
936  tok.ReplaceAll("datasrc=","");
937  if (tok.IsDigit()) {
938  Printf("runProof: error parsing the 'datasrc=' option (%s) - ignoring", tok.Data());
939  } else {
940  aDataSrc = tok;
941  Printf("runProof: reading files from: %s", aDataSrc.Data());
942  }
943  } else if (tok == "readall") {
944  proof->SetParameter("ProofEventProc_Read", "readall");
945  Printf("runProof: eventproc: reading the full event");
946  } else if (tok == "uneven") {
947  uneven = kTRUE;
948  } else if (tok.BeginsWith("partitions=")) {
949  tok.ReplaceAll("partitions=","");
950  if (tok.IsDigit()) {
951  Printf("runProof: error parsing the 'partitions=' option (%s) - ignoring", tok.Data());
952  } else {
953  aPartitions = tok;
954  Printf("runProof: partitions: %s included in packetizer operations", aPartitions.Data());
955  }
956  }
957  }
958  Int_t nFiles = (aFiles.IsNull()) ? 10 : aFiles.Atoi();
959  Printf("runProof: found aFiles: '%s', nFiles: %d", aFiles.Data(), nFiles);
960  if (nFiles > 50) {
961  Printf("runProof: max number of files is 50 - resizing request");
962  nFiles = 50;
963  }
964 
965  // We create the chain now
966  TChain *c = new TChain("EventTree");
967 
968  FileStat_t fst;
969  if (gSystem->GetPathInfo(aDataSrc, fst) == 0 && R_ISREG(fst.fMode) &&
970  !gSystem->AccessPathName(aDataSrc, kReadPermission)) {
971  // It is a local file, we get the TFileCollection and we inject it into the chain
972  TFileCollection *fc = new TFileCollection("", "", aDataSrc, nFiles);
973  c->AddFileInfoList(fc->GetList());
974  delete fc;
975 
976  } else {
977 
978  // Tokenize the source: if more than 1 we rotate the assignment. More sources can be specified
979  // separating them by a '|'
980  TObjArray *dsrcs = aDataSrc.Tokenize("|");
981  Int_t nds = dsrcs->GetEntries();
982 
983  // Fill the chain
984  Int_t i = 1, k = 0;
985  TString fn;
986  for (i = 1; i <= nFiles; i++) {
987  k = (i - 1) % nds;
988  TObjString *os = (TObjString *) (*dsrcs)[k];
989  if (os) {
990  fn.Form("%s/event_%d.root", os->GetName(), i);
991  if (uneven) {
992  if ((i - 1)%5 == 0)
993  c->AddFile(fn.Data(), 50000);
994  else
995  c->AddFile(fn.Data(), 5000);
996  } else {
997  c->AddFile(fn.Data());
998  }
999  }
1000  }
1001  dsrcs->SetOwner();
1002  delete dsrcs;
1003  }
1004  // Show the chain
1005  c->ls();
1006  c->SetProof();
1007 
1008  // Only validate the files really needed for the analysis
1009  proof->SetParameter("PROOF_ValidateByFile", 1);
1010 
1011  // Send over the partition information, if any
1012  if (!aPartitions.IsNull()) {
1013  aPartitions.ReplaceAll("|", ",");
1014  proof->SetParameter("PROOF_PacketizerPartitions", aPartitions);
1015  }
1016 
1017  // The selector
1018  sel.Form("%s/proof/ProofEventProc.C%s", tutorials.Data(), aMode.Data());
1019  // Run it
1020  Printf("\nrunProof: running \"eventproc\"\n");
1021  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
1022  c->Process(sel.Data(), xopt, nevt, first);
1023 
1024  } else if (act == "ntuple") {
1025 
1026  // ProofNtuple is an example of non-data driven analysis; it
1027  // creates and fills a disk resident ntuple with automatic file merging
1028 
1029  if (first > 0)
1030  // Meaningless for this tutorial
1031  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
1032  " - ignored", act.Data());
1033 
1034  // Set the default number of events, if needed
1035  nevt = (nevt < 0) ? 1000 : nevt;
1036  Printf("\nrunProof: running \"ntuple\" with nevt= %lld\n", nevt);
1037 
1038  // Which randoms to use
1039  Bool_t usentprndm = kFALSE;
1040  while (args.Tokenize(tok, from, " ")) {
1041  if (tok == "inputrndm") {
1042  usentprndm = kTRUE;
1043  break;
1044  }
1045  }
1046  if (usentprndm) Printf("runProof: taking randoms from input ntuple\n");
1047 
1048  // Output file
1049  TString fout(aOutFile);
1050  if (fout.IsNull()) {
1051  fout.Form("%s/ProofNtuple.root", gSystem->WorkingDirectory());
1052  // Cleanup any existing instance of the output file
1053  gSystem->Unlink(fout);
1054 
1055  if (!isProofLocal) {
1056  // Setup a local basic xrootd to receive the file
1057  Bool_t xrdok = kFALSE;
1058  Int_t port = 9000;
1059  while (port < 9010) {
1060  if (checkXrootdAt(port) != 1) {
1061  if (startXrootdAt(port, gSystem->WorkingDirectory(), kTRUE) == 0) {
1062  xrdok = kTRUE;
1063  break;
1064  }
1065  }
1066  port++;
1067  }
1068  if (!xrdok) {
1069  Printf("runProof: could not start basic xrootd on ports 9000-9009 - cannot continue");
1070  return;
1071  }
1072  fout.Insert(0, TString::Format("root://%s:%d/", TUrl(gSystem->HostName()).GetHostFQDN(), port));
1073  // Make a copy of the files on the master before merging
1074  proof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION", "LOCAL"));
1075  }
1076  }
1077  proof->AddInput(new TNamed("PROOF_OUTPUTFILE", fout.Data()));
1078 
1079  // If using the 'NtpRndm' for a fixed values of randoms, send over the file
1080  if (usentprndm) {
1081  // The file with 'NtpRndm'
1082  TString fnr = TString::Format("%s/proof/ntprndm.root", tutorials.Data());
1083  // Set as input data
1084  proof->SetInputDataFile(fnr);
1085  // Set the related parameter
1086  proof->SetParameter("PROOF_USE_NTP_RNDM","yes");
1087  // Notify
1088  Printf("runProof: taking randoms from '%s'", fnr.Data());
1089  }
1090 
1091  // The selector string
1092  sel.Form("%s/proof/ProofNtuple.C%s", tutorials.Data(), aMode.Data());
1093 
1094  // Run it for nevt times
1095  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
1096  proof->Process(sel.Data(), nevt, xopt);
1097 
1098  // Reset input variables
1099  if (usentprndm) {
1100  proof->DeleteParameters("PROOF_USE_NTP_RNDM");
1101  proof->SetInputDataFile(0);
1102  }
1103 
1104  } else if (act == "dataset") {
1105 
1106  // This is an example of analysis creating data files on each node which are
1107  // automatically registered as dataset; the newly created dataset is used to create
1108  // the final plots. The data are of the same type as for the 'ntuple' example.
1109  // Selector used: ProofNtuple
1110 
1111  if (first > 0)
1112  // Meaningless for this tutorial
1113  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
1114  " - ignored", act.Data());
1115 
1116  // Set the default number of events, if needed
1117  nevt = (nevt < 0) ? 1000000 : nevt;
1118  Printf("\nrunProof: running \"dataset\" with nevt= %lld\n", nevt);
1119 
1120  // Ask for registration of the dataset (the default is the the TFileCollection is return
1121  // without registration; the name of the TFileCollection is the name of the dataset
1122  proof->SetParameter("SimpleNtuple.root","testNtuple");
1123 
1124  // Do not plot the ntuple at this level
1125  proof->SetParameter("PROOF_NTUPLE_DONT_PLOT", "");
1126 
1127  // The selector string
1128  sel.Form("%s/proof/ProofNtuple.C%s", tutorials.Data(), aMode.Data());
1129  //
1130  // Run it for nevt times
1131  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
1132  proof->Process(sel.Data(), nevt, xopt);
1133 
1134  // The TFileCollection must be in the output
1135  if (proof->GetOutputList()->FindObject("testNtuple")) {
1136 
1137  // Plot the ntuple via PROOF (example of drawing PROOF actions)
1138  plotNtuple(proof, "testNtuple", "proof ntuple from dataset");
1139 
1140  } else {
1141  Printf("runProof: dataset 'testNtuple' not found in the output list");
1142  }
1143  // Do not plot the ntuple at this level
1144  proof->DeleteParameters("PROOF_NTUPLE_DONT_PLOT");
1145  proof->DeleteParameters("SimpleNtuple.root");
1146 
1147  } else if (act == "friends") {
1148 
1149  // This is an example of analysis creating two data files on each node (the main tree
1150  // and its friend) which are then processed as 'friends' to create the final plots.
1151  // Selector used: ProofFriends, ProofAux
1152 
1153  if (first > 0)
1154  // Meaningless for this tutorial
1155  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
1156  " - ignored", act.Data());
1157 
1158  // Find out whether to use the same file or separate files
1159  Bool_t sameFile = kFALSE;
1160  while (args.Tokenize(tok, from, " ")) {
1161  // Number of histos
1162  if (tok == "samefile") {
1163  sameFile = kTRUE;
1164  break;
1165  }
1166  }
1167 
1168  // File generation: we use TPacketizerFile in here to create two files per node
1169  TList *wrks = proof->GetListOfSlaveInfos();
1170  if (!wrks) {
1171  Printf("runProof: could not get the list of information about the workers");
1172  return;
1173  }
1174  // Create the map
1175  TString fntree;
1176  TMap *files = new TMap;
1177  files->SetName("PROOF_FilesToProcess");
1178  TIter nxwi(wrks);
1179  TSlaveInfo *wi = 0;
1180  while ((wi = (TSlaveInfo *) nxwi())) {
1181  fntree.Form("tree_%s.root", wi->GetOrdinal());
1182  THashList *wrklist = (THashList *) files->GetValue(wi->GetName());
1183  if (!wrklist) {
1184  wrklist = new THashList;
1185  wrklist->SetName(wi->GetName());
1186  files->Add(new TObjString(wi->GetName()), wrklist);
1187  }
1188  wrklist->Add(new TObjString(fntree));
1189  }
1190 
1191  // Generate the files
1192  proof->AddInput(files);
1193  if (sameFile) {
1194  Printf("runProof: friend tree stored in the same file as the main tree");
1195  proof->SetParameter("ProofAux_Action", "GenerateTreesSameFile");
1196  } else {
1197  proof->SetParameter("ProofAux_Action", "GenerateTrees");
1198  }
1199  // Default 1000 events
1200  nevt = (nevt < 0) ? 10000 : nevt;
1201  proof->SetParameter("ProofAux_NEvents", (Long64_t)nevt);
1202  // Special Packetizer
1203  proof->SetParameter("PROOF_Packetizer", "TPacketizerFile");
1204  // Now process
1205  sel.Form("%s/proof/ProofAux.C%s", tutorials.Data(), aMode.Data());
1206  proof->Process(sel.Data(), 1);
1207  // Remove the packetizer specifications
1208  proof->DeleteParameters("PROOF_Packetizer");
1209 
1210  // Print the lists and create the TDSet objects
1211  TDSet *dset = new TDSet("Tmain", "Tmain");
1212  TDSet *dsetf = new TDSet("Tfrnd", "Tfrnd");
1213  if (proof->GetOutputList()) {
1214  TIter nxo(proof->GetOutputList());
1215  TObject *o = 0;
1216  TObjString *os = 0;
1217  while ((o = nxo())) {
1218  TList *l = dynamic_cast<TList *> (o);
1219  if (l && !strncmp(l->GetName(), "MainList-", 9)) {
1220  TIter nxf(l);
1221  while ((os = (TObjString *) nxf()))
1222  dset->Add(os->GetName());
1223  }
1224  }
1225  nxo.Reset();
1226  while ((o = nxo())) {
1227  TList *l = dynamic_cast<TList *> (o);
1228  if (l && !strncmp(l->GetName(), "FriendList-", 11)) {
1229  TIter nxf(l);
1230  while ((os = (TObjString *) nxf()))
1231  dsetf->Add(os->GetName());
1232  }
1233  }
1234  }
1235  // Process with friends
1236  dset->AddFriend(dsetf, "friend");
1237  sel.Form("%s/proof/ProofFriends.C%s", tutorials.Data(), aMode.Data());
1238  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
1239  dset->Process(sel, xopt);
1240  // Clear the files created by this run
1241  proof->ClearData(TProof::kUnregistered | TProof::kForceClear);
1242 
1243  } else if (act == "simplefile") {
1244 
1245  // ProofSimpleFile is an example of non-data driven analysis with merging
1246  // via file and objcets saved in different directories; it creates and
1247  // fills with random numbers two sets of a given number of histos
1248 
1249  if (first > 0)
1250  // Meaningless for this tutorial
1251  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
1252  " - ignored", act.Data());
1253 
1254  // Default 100000 events
1255  nevt = (nevt < 0) ? 1000000 : nevt;
1256  // Find out the number of histograms
1257  TString aNhist;
1258  while (args.Tokenize(tok, from, " ")) {
1259  // Number of histos
1260  if (tok.BeginsWith("nhist=")) {
1261  aNhist = tok;
1262  aNhist.ReplaceAll("nhist=","");
1263  if (!aNhist.IsDigit()) {
1264  Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
1265  aNhist = "";
1266  }
1267  }
1268  }
1269  Int_t nhist = (aNhist.IsNull()) ? 16 : aNhist.Atoi();
1270  Printf("\nrunProof: running \"simplefile\" with nhist= %d and nevt= %lld\n", nhist, nevt);
1271 
1272  // The number of histograms is added as parameter in the input list
1273  proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
1274 
1275  // Output file
1276  TString fout(aOutFile);
1277  if (fout.IsNull()) {
1278  fout.Form("%s/SimpleFile.root", gSystem->WorkingDirectory());
1279  // Cleanup any existing instance of the output file
1280  gSystem->Unlink(fout);
1281 
1282  if (!isProofLocal) {
1283  // Setup a local basic xrootd to receive the file
1284  Bool_t xrdok = kFALSE;
1285  Int_t port = 9000;
1286  while (port < 9010) {
1287  if (checkXrootdAt(port) != 1) {
1288  if (startXrootdAt(port, gSystem->WorkingDirectory(), kTRUE) == 0) {
1289  xrdok = kTRUE;
1290  break;
1291  }
1292  }
1293  port++;
1294  }
1295  if (!xrdok) {
1296  Printf("runProof: could not start basic xrootd on ports 9000-9009 - cannot continue");
1297  return;
1298  }
1299  fout.Insert(0, TString::Format("root://%s:%d/", TUrl(gSystem->HostName()).GetHostFQDN(), port));
1300  // Make a copy of the files on the master before merging
1301  proof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION", "LOCAL"));
1302  }
1303  }
1304  proof->AddInput(new TNamed("PROOF_OUTPUTFILE", fout.Data()));
1305 
1306  // The selector string
1307  sel.Form("%s/proof/ProofSimpleFile.C%s", tutorials.Data(), aMode.Data());
1308  //
1309  // Run it for nevt times
1310  TString xopt = TString::Format("%s %s", aFeedback.Data(), opt.Data());
1311  proof->Process(sel.Data(), nevt, xopt);
1312 
1313  } else if (act == "stdvec") {
1314 
1315  // This is an example of runnign a TSelector using standard vectors
1316  // Selector used: ProofStdVect
1317 
1318  if (first > 0)
1319  // Meaningless for this tutorial
1320  Printf("runProof: %s: warning concept of 'first' meaningless for this tutorial"
1321  " - ignored", act.Data());
1322 
1323  // Set the default number of events, if needed
1324  nevt = (nevt < 0) ? 50000 * proof->GetParallel() : nevt;
1325  Printf("\nrunProof: running \"stdvec\" with nevt= %lld\n", nevt);
1326 
1327  // The selector string
1328  sel.Form("%s/proof/ProofStdVect.C%s", tutorials.Data(), aMode.Data());
1329 
1330  TString xopt;
1331  // Create the dataset 'TestStdVect' with 'nevt' events
1332  xopt.Form("%s %s create", aFeedback.Data(), opt.Data());
1333  proof->Process(sel.Data(), nevt, xopt);
1334 
1335  // The dataset must have been registered
1336  if (proof->ExistsDataSet("TestStdVect")) {
1337 
1338  // Use dataset 'TestStdVect'
1339  xopt.Form("%s %s", aFeedback.Data(), opt.Data());
1340  proof->Process("TestStdVect", sel.Data(), xopt);
1341 
1342  } else {
1343  Printf("runProof: dataset 'TestStdVect' not available!");
1344  }
1345 
1346  } else {
1347  // Do not know what to run
1348  Printf("runProof: unknown tutorial: %s", what);
1349  }
1350 
1351  // Save the performance tree
1352  if (makePerfTree) {
1353  SavePerfTree(proof, aPerfTree.Data());
1354  // Cleanup parameters
1355  gProof->DeleteParameters("PROOF_StatsHist");
1356  gProof->DeleteParameters("PROOF_StatsTrace");
1357  gProof->DeleteParameters("PROOF_SlaveStatsTrace");
1358  }
1359 }
1360 
1361 //_______________________________________________________________________________________
1362 void plotNtuple(TProof *p, const char *ds, const char *ntptitle)
1363 {
1364  // Make some plots from the ntuple 'ntp' via PROOF
1365 
1366  //
1367  // Create a canvas, with 2 pads
1368  //
1369  TCanvas *c1 = new TCanvas(Form("cv-%s", ds), ntptitle,800,10,700,780);
1370  c1->Divide(1,2);
1371  TPad *pad1 = (TPad *) c1->GetPad(1);
1372  TPad *pad2 = (TPad *) c1->GetPad(2);
1373  //
1374  // Display a function of one ntuple column imposing a condition
1375  // on another column.
1376  pad1->cd();
1377  pad1->SetGrid();
1378  pad1->SetLogy();
1379  pad1->GetFrame()->SetFillColor(15);
1380 
1381  p->SetParameter("PROOF_LineColor", (Int_t)1);
1382  p->SetParameter("PROOF_FillStyle", (Int_t)1001);
1383  p->SetParameter("PROOF_FillColor", (Int_t)45);
1384  p->DrawSelect(ds, "3*px+2","px**2+py**2>1");
1385  p->SetParameter("PROOF_FillColor", (Int_t)38);
1386  p->DrawSelect(ds, "2*px+2","pz>2","same");
1387  p->SetParameter("PROOF_FillColor", (Int_t)5);
1388  p->DrawSelect(ds, "1.3*px+2","(px^2+py^2>4) && py>0","same");
1389  pad1->RedrawAxis();
1390 
1391  //
1392  // Display a 3-D scatter plot of 3 columns. Superimpose a different selection.
1393  pad2->cd();
1394  p->DrawSelect(ds, "pz:py:px","(pz<10 && pz>6)+(pz<4 && pz>3)");
1395  p->SetParameter("PROOF_MarkerColor", (Int_t)4);
1396  p->DrawSelect(ds, "pz:py:px","pz<6 && pz>4","same");
1397  p->SetParameter("PROOF_MarkerColor", (Int_t)5);
1398  p->DrawSelect(ds, "pz:py:px","pz<4 && pz>3","same");
1399  TPaveText *l2 = new TPaveText(0.,0.6,0.9,0.95);
1400  l2->SetFillColor(42);
1401  l2->SetTextAlign(12);
1402  l2->AddText("You can interactively rotate this view in 2 ways:");
1403  l2->AddText(" - With the RotateCube in clicking in this pad");
1404  l2->AddText(" - Selecting View with x3d in the View menu");
1405  l2->Draw();
1406 
1407  // Final update
1408  c1->cd();
1409  c1->Update();
1410 
1411  // Clear parameters used for the plots
1412  p->DeleteParameters("PROOF_*Color");
1413  p->DeleteParameters("PROOF_*Style");
1414 }
1415 
1416 //______________________________________________________________________________
1417 void SavePerfTree(TProof *proof, const char *fn)
1418 {
1419  // Save PROOF timing information from TPerfStats to file 'fn'
1420 
1421  if (!proof) {
1422  Printf("PROOF must be run to save output performance information");;
1423  return;
1424  }
1425  if (!proof->GetOutputList() || proof->GetOutputList()->GetSize() <= 0) {
1426  Printf("PROOF outputlist undefined or empty");;
1427  return;
1428  }
1429 
1430  TFile f(fn, "RECREATE");
1431  if (f.IsZombie()) {
1432  Printf("ERROR: could not open file '%s' for writing", fn);;
1433  } else {
1434  f.cd();
1435  TIter nxo(proof->GetOutputList());
1436  TObject* obj = 0;
1437  while ((obj = nxo())) {
1438  TString objname(obj->GetName());
1439  if (objname.BeginsWith("PROOF_")) {
1440  // Must list the objects since other PROOF_ objects exist
1441  // besides timing objects
1442  if (objname == "PROOF_PerfStats" ||
1443  objname == "PROOF_PacketsHist" ||
1444  objname == "PROOF_EventsHist" ||
1445  objname == "PROOF_NodeHist" ||
1446  objname == "PROOF_LatencyHist" ||
1447  objname == "PROOF_ProcTimeHist" ||
1448  objname == "PROOF_CpuTimeHist")
1449  obj->Write();
1450  }
1451  }
1452  f.Close();
1453  }
1454 
1455 }
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1213
An array of TObjects.
Definition: TObjArray.h:39
virtual void Draw(Option_t *option="")
Draw this pavetext with its current attributes.
Definition: TPaveText.cxx:211
long long Long64_t
Definition: RtypesCore.h:69
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:865
virtual const char * GetName() const
Return name of this collection.
virtual Long64_t DrawSelect(TDSet *dset, const char *varexp, const char *selection="", Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0)
Execute the specified drawing action on a data set (TDSet).
Definition: TProof.cxx:6144
Attaches to a PROOF session, possibly at the indicated URL.
Collectable string class.
Definition: TObjString.h:32
virtual Long64_t Process(TSelector *selector, Option_t *option="", Long64_t nentries=-1, Long64_t firstentry=0, TObject *enl=0)
Process TDSet on currently active PROOF session.
Definition: TDSet.cxx:897
This class represents a WWW compatible URL.
Definition: TUrl.h:41
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1311
This class implements a data set to be used for PROOF processing.
Definition: TDSet.h:153
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void SetParameter(const char *par, const char *value)
Set input list parameter.
Definition: TProof.cxx:10400
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:659
TList * GetOutputList()
Get list with all object created during processing (see Process()).
Definition: TProof.cxx:10386
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:160
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
void Add(TObject *obj)
This function may not be used (but we need to provide it since it is a pure virtual in TCollection)...
Definition: TMap.cxx:53
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1766
const char * GetOrdinal() const
Definition: TProof.h:258
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1395
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:980
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1459
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
TFile * f
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:129
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:884
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=0)
Set the value of a resource or create a new resource.
Definition: TEnv.cxx:749
Int_t fMode
Definition: TSystem.h:138
virtual void SetDirectory(TDirectory *dir)
Add reference to directory dir. dir can be 0.
virtual Int_t AddFileInfoList(TCollection *list, Long64_t nfiles=TTree::kMaxEntries)
Add all files referenced in the list to the chain.
Definition: TChain.cxx:530
const char * Data() const
Definition: TString.h:349
static struct mg_connection * fc(struct mg_context *ctx)
Definition: civetweb.c:839
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1294
TVirtualPad * cd(Int_t subpadnumber=0)
Set Current pad.
Definition: TPad.cxx:514
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2321
virtual void ls(Option_t *option="") const
List the chain.
Definition: TChain.cxx:1752
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:36
TFrame * GetFrame()
Get frame.
Definition: TPad.cxx:2729
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void SetGrid(Int_t valuex=1, Int_t valuey=1)
Definition: TPad.h:326
virtual void SetEntryList(TEntryList *elist, Option_t *opt="")
Set the input entry list (processing the entries of the chain will then be limited to the entries in ...
Definition: TChain.cxx:2497
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1575
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition: TMap.cxx:235
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1511
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1951
virtual void RedrawAxis(Option_t *option="")
Redraw the frame axis Redrawing axis may be necessary in case of superimposed histograms when one or ...
Definition: TPad.cxx:4705
Int_t getProof(const char *where, Int_t verbose=1)
Open a PROOF session at gUrl.
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
TString fUser
Definition: TSystem.h:152
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1559
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2207
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
virtual void SetFillColor(Color_t fcolor)
Definition: TAttFill.h:50
THashList * GetList()
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:675
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
Enable/Disable PROOF processing on the current default Proof (gProof).
Definition: TChain.cxx:2734
The most important graphics class in the ROOT system.
Definition: TPad.h:46
char * Form(const char *fmt,...)
bool first
Definition: line3Dfit.C:48
static void AddEnvVar(const char *name, const char *value)
Add an variable to the list of environment variables passed to proofserv on the master and slaves...
Definition: TProof.cxx:12338
Bool_t IsNull() const
Definition: TString.h:387
void SetName(const char *name)
Definition: TCollection.h:116
#define Printf
Definition: TGeoToOCC.h:18
virtual Int_t AddFile(const char *name, Long64_t nentries=TTree::kMaxEntries, const char *tname="")
Add a new file to this chain.
Definition: TChain.cxx:433
void ClearInputData(TObject *obj=0)
Remove obj form the input data list; if obj is null (default), clear the input data info...
Definition: TProof.cxx:10116
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
The Canvas class.
Definition: TCanvas.h:48
TList * GetInputList()
Get input list.
Definition: TProof.cxx:10331
R__EXTERN TProof * gProof
Definition: TProof.h:1113
virtual Int_t GetSize() const
Definition: TCollection.h:95
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:35
void DeleteParameters(const char *wildcard)
Delete the input list parameters specified by a wildcard (e.g.
Definition: TProof.cxx:10511
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:307
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition: TMap.h:44
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
This class controls a Parallel ROOT Facility, PROOF, cluster.
Definition: TProof.h:342
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
virtual Int_t GetUid(const char *user=0)
Returns the user's id. If user = 0, returns current user's id.
Definition: TSystem.cxx:1472
const char * GetName() const
Returns name of object.
Definition: TProof.h:257
Mother of all ROOT objects.
Definition: TObject.h:58
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition: TString.cxx:1793
virtual TVirtualPad * GetPad(Int_t subpadnumber) const
Get a pointer to subpadnumber of this pad.
Definition: TPad.cxx:2770
virtual Bool_t Add(const char *file, const char *objname=0, const char *dir=0, Long64_t first=0, Long64_t num=-1, const char *msd=0)
Add file to list of files to be analyzed.
Definition: TDSet.cxx:1030
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Process all entries in this chain, calling functions in filename.
Definition: TChain.cxx:2140
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1073
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Class that contains a list of TFileInfo's and accumulated meta data information about its entries...
A chain is a collection of files containg TTree objects.
Definition: TChain.h:35
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1191
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2179
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void AddFriend(TDSet *friendset, const char *alias)
Add friend dataset to this set.
Definition: TDSet.cxx:1313
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
virtual Int_t Add(TChain *chain)
Add all files referenced by the passed chain to this chain.
Definition: TChain.cxx:210
virtual void Close(Option_t *option="")
Close a file.
Definition: TFile.cxx:898
virtual void SetLogy(Int_t value=1)
Set Lin/Log scale for Y.
Definition: TPad.cxx:5314