Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TProofPerfAnalysis.cxx
Go to the documentation of this file.
1// @(#)root/proofx:$Id$
2// Author: G.Ganis Nov 2011
3
4/*************************************************************************
5 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12
13/** \class TProofPerfAnalysis
14\ingroup proofbench
15
16Set of tools to analyse the performance tree
17
18*/
19
20#include <errno.h>
21
22#include "TProofPerfAnalysis.h"
23#include "TCanvas.h"
24#include "TFile.h"
25#include "TGraph.h"
26#include "TH1F.h"
27#include "TH2F.h"
28#include "THashList.h"
29#include "TKey.h"
30#include "TList.h"
31#include "TSortedList.h"
32#include "TObjString.h"
33#include "TPerfStats.h"
34#include "TRegexp.h"
35#include "TStyle.h"
36#include "TSystem.h"
37#include "TTree.h"
38#include "TMath.h"
39
40//
41// Auxilliary internal classes
42////////////////////////////////////////////////////////////////////////////////
43
45public:
46 TWrkInfo(const char *ord, const char *name) :
48 fBytesRead(0), fLatency(0), fProcTime(0), fCpuTime(0), fStart(0), fStop(-1),
53
54 Int_t fPackets; // Number of packets processed
55 Int_t fRemotePackets; // Number of processed packet from non-local files
56 Long64_t fEventsProcessed; // Tot events processed
57 Long64_t fBytesRead; // Tot bytes read
58 Double_t fLatency; // Tot latency
59 Double_t fProcTime; // Tot proc time
60 Double_t fCpuTime; // Tot CPU time
61
62 Float_t fStart; // Start time
63 Float_t fStop; // Stop time
64
65 TGraph *fRateT; // Event processing rate vs time
66 TGraph *fRateRemoteT; // Event processing rate of remote packets vs time
67 TGraph *fMBRateT; // Byte processing rate vs time
68 TGraph *fMBRateRemoteT; // Byte processing rate of remote packets vs time
69 TGraph *fLatencyT; // Packet latency vs time
70
71 Double_t AvgRate() { if (fProcTime > 0) return (fEventsProcessed/fProcTime); return -1.; }
72 Double_t AvgIO() { if (fProcTime > 0) return (fBytesRead/fProcTime); return -1.; }
73
74 void Print(Option_t * = "") const {
75 Printf(" +++ TWrkInfo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
76 Printf(" +++ Worker: %s, %s", GetName(), GetTitle());
77 Printf(" +++ Activity interval: %f -> %f", fStart, fStop);
78 Printf(" +++ Amounts processed: %d packets (%d remote), %lld evts, %lld bytes",
80 if (fProcTime) {
81 Printf(" +++ Processing time: %f s (CPU: %f s)", fProcTime, fCpuTime);
82 Printf(" +++ Averages: %f evts/s, %f MB/s", (Double_t)fEventsProcessed / fProcTime, (Double_t)fBytesRead /1024./1024./fProcTime);
83 }
84 Printf(" +++ Total latency: %f", fLatency);
85 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
86 }
87
88 Int_t Compare(const TObject *o) const { TWrkInfo *wi = (TWrkInfo *)o;
89 if (wi) {
90 if (fStop < wi->fStop) {
91 return -1;
92 } else if (fStop == wi->fStop) {
93 return 0;
94 }
95 }
96 return 1; }
97};
98
99
101public:
102 TPackInfo(const char *ord, const char *host) : TNamed(ord, host), fStart(0), fStop(-1), fSize(0), fMBRate(0.) { }
103 TPackInfo(const char *ord, const char *host, Float_t start, Float_t stop, Long64_t sz, Double_t mbr)
104 : TNamed(ord, host), fStart(start), fStop(stop), fSize(sz), fMBRate(mbr) { }
105 Float_t fStart; // When the packet has been assigned
106 Float_t fStop; // When the packet has been finished
107 Long64_t fSize; // Packet size
108 Double_t fMBRate; // Processing rate MB/s
109 void Print(Option_t *opt= "") const {
110 if (!strcmp(opt, "S")) {
111 Printf(" \t%10lld evts, \t%12.2f MB/s, \t%12.3f -> %12.3f s", fSize, fMBRate, fStart, fStop);
112 } else {
113 Printf(" %s:\t%s \t%10lld evts, \t%12.2f MB/s, \t%12.3f -> %12.3f s", GetTitle(), GetName(), fSize, fMBRate, fStart, fStop);
114 }
115 }
116};
117
119public:
120 TWrkInfoFile(const char *ord, const char *name) : TNamed(ord, name) { }
122 TList fPackets; // Packest from this file processed by this worker
123 void Print(Option_t *opt= "") const {
124 if (!strcmp(opt, "R")) {
125 Printf(" Worker: %s,\tpacket(s): %d", GetName(), fPackets.GetSize());
126 } else {
127 Printf(" Worker: %s,\t%d packet(s) from file: %s", GetName(), fPackets.GetSize(), GetTitle());
128 }
129 TIter nxp(&fPackets);
130 TObject *o = 0;
131 while ((o = nxp())) { o->Print("S"); }
132 }
133};
134
136public:
138 Double_t fXx; // Bin center
139 Double_t fEvtRate; // Event processing rate from this worker for this packet
140 Double_t fMBRate; // I/O processing rate from this worker for this packet
141 Double_t fProcTime; // Processing time
142 void Print(Option_t * = "") const { Printf("%.4f \t%.3f evt/s \t%.3f MB/s \t%.3f s ", fXx, fEvtRate, fMBRate, fProcTime); }
143};
144
145////////////////////////////////////////////////////////////////////////////////
146
148public:
149 TFileInfo(const char *name, const char *srv) :
150 TNamed(name, srv), fPackets(0), fRPackets(0), fStart(0), fStop(-1),
151 fSizeAvg(0), fSizeMax(-1.), fSizeMin(-1.),
152 fMBRateAvg(0), fMBRateMax(-1.), fMBRateMin(-1.), fSizeP(0),
153 fRateP(0), fRatePRemote(0), fMBRateP(0), fMBRatePRemote(0) { }
160
161 Int_t fPackets; // Number of packets from this file
162 Int_t fRPackets; // Number of different remote workers processing this file
163
164 TList fPackList; // List of packet info
165 TList fWrkList; // List of worker names processing this packet
166 TList fRWrkList; // List of remote worker names processing this packet
167
168 Float_t fStart; // When the first packet has been assigned
169 Float_t fStop; // When the last packet has been finished
170
171 Long64_t fSizeAvg; // Average Packet size
172 Long64_t fSizeMax; // Max packet size
173 Long64_t fSizeMin; // Min packet size
174
175 Double_t fMBRateAvg; // Average MB rate
176 Double_t fMBRateMax; // Max MB rate
177 Double_t fMBRateMin; // Min MB rate
178
179 TGraph *fSizeP; // Packet size vs packet (all)
180 TGraph *fRateP; // Event processing rate vs packet (all)
181 TGraph *fRatePRemote; // Event processing rate vs packet (remote workers)
182 TGraph *fMBRateP; // Byte processing rate vs packet (all)
183 TGraph *fMBRatePRemote; // Byte processing rate vs packet (remote workers)
184
185 void Print(Option_t *opt = "") const {
186 Printf(" +++ TFileInfo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
187 Printf(" +++ Server: %s", GetTitle());
188 Printf(" +++ File: %s", GetName());
189 Printf(" +++ Processing interval: %f -> %f", fStart, fStop);
190 Printf(" +++ Packets: %d (%d remote)", fPackets, fRPackets);
191 Printf(" +++ Processing wrks: %d (%d remote)", fWrkList.GetSize(), fRWrkList.GetSize());
192 if (!strcmp(opt, "P")) fPackList.Print();
193 if (!strcmp(opt, "WP")) fWrkList.Print("R");
194 if (fPackets > 0) {
195 Printf(" +++ MB rates: %f MB/s (avg), %f MB/s (min), %f MB/s (max)",
197 Printf(" +++ Sizes: %lld (avg), %lld (min), %lld (max)",
199 }
200 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
201 }
202
203 Int_t Compare(const TObject *o) const { TFileInfo *wi = (TFileInfo *)o;
204 if (wi) {
205 if (fStop < wi->fStop) {
206 return -1;
207 } else if (fStop == wi->fStop) {
208 return 0;
209 }
210 }
211 return 1; }
212};
213
215////////////////////////////////////////////////////////////////////////////////
216/// Constructor: open the file and attach to the tree
217
219 const char *title, const char *treename)
220 : TNamed(perffile, title), fFile(0), fTreeName(treename), fTree(0),
221 fInitTime(-1.), fMergeTime(-1.), fMaxTime(-1.),
222 fEvents(0), fPackets(0),
223 fEvtRateMax(-1.), fMBRateMax(-1.), fLatencyMax(-1.),
224 fEvtRate(0), fEvtRateRun(0), fMBRate(0), fMBRateRun(0),
225 fEvtRateAvgMax(-1.), fMBRateAvgMax(-1.),
226 fEvtRateAvg(-1.), fMBRateAvg(0),
227 fFileResult(""), fSaveResult(kFALSE),
228 fDebug(0)
229{
230 // Use default title, if not specified
231 if (!title) SetTitle("PROOF Performance Analysis");
232
233 fTree = 0;
234 fFile = TFile::Open(perffile);
235 if (!fFile || (fFile && fFile->IsZombie())) {
237 Error("TProofPerfAnalysis", "problems opening file '%s'",
238 perffile ? perffile : "<undef>");
240 return;
241 }
242
243 // Set the subdirectory name, if any
244 if (fTreeName.Contains("/")) {
247 }
248
249 // Adjust the name, if requested
250 if (fTreeName.BeginsWith("+"))
251 fTreeName.Replace(0, 1, "PROOF_PerfStats");
252
253 // Point to the right TDirectory
254 TDirectory *dir = fFile;
255 if (!fDirName.IsNull()) {
256 if (!(dir = dynamic_cast<TDirectory *>(fFile->Get(fDirName)))) {
257 Error("TProofPerfAnalysis", "directory '%s' not found or not loadable", fDirName.Data());
258 fFile->Close();
261 return;
262 }
263 }
264
265 // Load the performance tree
266 LoadTree(dir);
267 if (!fTree) {
268 Error("TProofPerfAnalysis", "tree '%s' not found or not loadable", fTreeName.Data());
269 fFile->Close();
272 return;
273 }
274 if (fgDebug)
275 Printf(" +++ TTree '%s' has %lld entries", fTreeName.Data(), fTree->GetEntries());
276
277 // Init worker information
278 FillWrkInfo();
279
280 // Init file information
281 FillFileInfo();
282
283 // Done
284 return;
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// Constructor: open the file and attach to the tree
289
291 : TNamed("", title), fFile(0), fTree(0),
292 fInitTime(-1.), fMergeTime(-1.), fMaxTime(-1.),
293 fEvents(0), fPackets(0),
294 fEvtRateMax(-1.), fMBRateMax(-1.), fLatencyMax(-1.),
295 fEvtRate(0), fEvtRateRun(0), fMBRate(0), fMBRateRun(0),
296 fEvtRateAvgMax(-1.), fMBRateAvgMax(-1.),
297 fEvtRateAvg(-1.), fMBRateAvg(0),
298 fDebug(0)
299{
300 // The tree must be defined
301 if (!tree) {
303 return;
304 }
305
306 // Use default title, if not specified
307 if (!title) SetTitle("PROOF Performance Analysis");
308
309 fTree = tree;
311 SetName(TString::Format("heap_%s", fTreeName.Data()));
312
313 // Adjust the name, if requested
314 if (fTreeName.BeginsWith("+"))
315 fTreeName.Replace(0, 1, "PROOF_PerfStats");
316
317 if (fgDebug)
318 Printf(" +++ TTree '%s' has %lld entries", fTreeName.Data(), fTree->GetEntries());
319
320 // Init worker information
321 FillWrkInfo();
322
323 // Init file information
324 FillFileInfo();
325
326 // Done
327 return;
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Destructor: detach the tree and close the file
332
334{
337 if (fFile) fFile->Close();
339}
340
341////////////////////////////////////////////////////////////////////////////////
342/// If defined, add '- <this title>' to the canvas title 't'
343
345{
346 if (fTitle.IsNull()) return TString(t);
347
348 TString newt;
349 if (t && strlen(t) > 0) {
350 newt.Form("%s - %s", t, GetTitle());
351 } else {
352 newt = GetTitle();
353 }
354 // Done
355 return newt;
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Load tree fTreeName from directory 'dir'. If not found, look for the
360/// first TTree in the directory (and sub-directories) with the name containing
361/// fTreeName.
362/// The tree pointer is saved in fTree.
363
365{
366 fTree = 0;
367 if (!dir) return;
368
369 // Try first the full name in the top directory
370 if ((fTree = dynamic_cast<TTree *>(dir->Get(fTreeName)))) return;
371
372 TRegexp re(fTreeName);
373 // Now look inside: iter on the list of keys first
374 TIter nxk(dir->GetListOfKeys());
375 TKey *k = 0;
376 while ((k = (TKey *) nxk())) {
377 if (!strcmp(k->GetClassName(), "TDirectoryFile")) {
378 TDirectory *kdir = (TDirectory *) dir->Get(k->GetName());
379 LoadTree(kdir);
380 if (fTree) return;
381 } else if (!strcmp(k->GetClassName(), "TTree")) {
382 TString tn(k->GetName());
383 if (tn.Index(re) != kNPOS) {
384 if ((fTree = dynamic_cast<TTree *>(dir->Get(tn)))) {
385 fTreeName = tn;
386 if (fgDebug) Printf(" +++ Found and loaded TTree '%s'", tn.Data());
387 return;
388 }
389 }
390 }
391 }
392
393 // Nothing found
394 return;
395}
396
397////////////////////////////////////////////////////////////////////////////////
398/// Analyse the file distribution. If writedet, underling details are
399/// written out to a text file.
400
402{
403 if (!IsValid()) {
404 Error("FileDist","not a valid instance - do nothing");
405 return;
406 }
407
408 // Fill file info
409 TList *wrkList = new TList;
410 TList *srvList = new TList;
411 GetWrkFileList(wrkList, srvList);
412 Info("FileDist", "%d workers were active during this query", wrkList->GetSize());
413 Info("FileDist", "%d servers were active during this query", srvList->GetSize());
414
415 // Fill the worker-data server mapping
416 TIter nxs(srvList);
417 TIter nxw(wrkList);
418 TNamed *sn = 0, *wn = 0;
419 while ((sn = (TNamed *)nxs())) {
420 nxw.Reset();
421 while ((wn = (TNamed *) nxw())) {
422 if (!strcmp(TUrl(sn->GetName()).GetHostFQDN(), wn->GetTitle())) {
423 sn->SetTitle(wn->GetName());
424 }
425 }
426 }
427
428 // Reorder the lists following the title
429 TList *nwl = new TList;
430 TList *nsl = new TList;
431 nxw.Reset();
432 while ((wn = (TNamed *) nxw())) {
433 TIter nnxw(nwl);
434 TNamed *nwn = 0;
435 while ((nwn = (TNamed *) nnxw())) {
436 if (CompareOrd(wn->GetName(), nwn->GetName()) < 0) {
437 nwl->AddBefore(nwn, wn);
438 break;
439 }
440 }
441 if (!nwn) nwl->Add(wn);
442 // Find the server name, if any
443 nxs.Reset();
444 while ((sn = (TNamed *)nxs())) {
445 if (!strcmp(sn->GetTitle(), wn->GetName())) {
446 TIter nnxs(nsl);
447 TNamed *nsn = 0;
448 while ((nsn = (TNamed *) nnxs())) {
449 if (CompareOrd(sn->GetTitle(), nsn->GetTitle()) < 0) {
450 nsl->AddBefore(nsn, sn);
451 break;
452 }
453 }
454 if (!nsn) nsl->Add(sn);
455 break;
456 }
457 }
458 if (sn) srvList->Remove(sn);
459 }
460 // Add remaining servers at the end
461 nxs.Reset();
462 while ((sn = (TNamed *)nxs())) {
463 nsl->Add(sn);
464 }
465 // Clean the orginal lists
466 wrkList->SetOwner(kFALSE);
467 srvList->SetOwner(kFALSE);
468 delete wrkList;
469 delete srvList;
470 wrkList = nwl;
471 srvList = nsl;
472
473 // Notify
474 wrkList->ls();
475 srvList->ls();
476
477 // Separate out the case with only one file server
478 if (srvList->GetSize() == 1) {
479
480 Printf("\n +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ");
481 Printf(" + Only one data server found: full analysis meaningful + ");
482 Printf(" + only when there are more file servers + ");
483 Printf(" +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n");
484
485
486 // Create a 1D histo for cross packets
487 TH1F *hxpak = new TH1F("hxpak", "MBytes / Worker",
488 wrkList->GetSize(), 0., (Double_t)wrkList->GetSize());
489 hxpak->SetDirectory(0);
490 hxpak->SetMinimum(0.);
491 hxpak->GetXaxis()->SetTitle("Worker");
492
493 // Set the labels
494 Int_t j = 1;
495 TIter nxsw(wrkList);
496 while ((wn = (TNamed *)nxsw())) {
497 hxpak->GetXaxis()->SetBinLabel(j++, wn->GetName());
498 }
499
500 // Fill the histograms
501 FillFileDistOneSrv(hxpak, writedet);
502
503 // Display histos
504 gStyle->SetOptStat(0);
505
506 TCanvas *c2 = new TCanvas("cv-hxpak", GetCanvasTitle(hxpak->GetTitle()), 800,350,700,700);
507 c2->cd();
508 DoDraw(hxpak);
509 c2->Update();
510
511 } else {
512 // Create a 1D histo for file distribution
513 TH1F *hfdis = new TH1F("hfdis", "Packet dist",
514 srvList->GetSize(), 0., (Double_t)srvList->GetSize());
515 hfdis->SetDirectory(0);
516 hfdis->SetMinimum(0);
517 hfdis->GetXaxis()->SetTitle("Server");
518 TH1F *hbdis = new TH1F("hbdis", "MBytes dist",
519 srvList->GetSize(), 0., (Double_t)srvList->GetSize());
520 hbdis->SetDirectory(0);
521 hbdis->SetMinimum(0);
522 hbdis->GetXaxis()->SetTitle("Server");
523 // Create a 2D histo for cross packets
524 TH2F *hxpak = new TH2F("hxpak", "MBytes / {Worker,Server}",
525 srvList->GetSize(), 0., (Double_t)srvList->GetSize(),
526 wrkList->GetSize(), 0., (Double_t)wrkList->GetSize());
527 hxpak->SetDirectory(0);
528 hxpak->GetYaxis()->SetTitle("Worker");
529 hxpak->GetXaxis()->SetTitle("Server");
530 hxpak->GetXaxis()->SetTitleOffset(1.4);
531 hxpak->GetYaxis()->SetTitleOffset(1.7);
532
533 // Set the labels
534 Int_t j = 1;
535 TIter nxsw(wrkList);
536 while ((wn = (TNamed *)nxsw())) {
537 hxpak->GetYaxis()->SetBinLabel(j++, wn->GetName());
538 }
539 j = 1;
540 TIter nxss(srvList);
541 while ((sn = (TNamed *)nxss())) {
542 hfdis->GetXaxis()->SetBinLabel(j, sn->GetName());
543 hbdis->GetXaxis()->SetBinLabel(j, sn->GetName());
544 hxpak->GetXaxis()->SetBinLabel(j++, sn->GetName());
545 }
546
547 // Fill the histograms
548 FillFileDist(hfdis, hbdis, hxpak, writedet);
549
550 j = 1;
551 nxss.Reset();
552 while ((sn = (TNamed *)nxss())) {
553 TString lab(sn->GetName());
554 lab = TUrl(sn->GetName()).GetHost();
555 if (strcmp(sn->GetTitle(), "remote") && lab.Index(".") != kNPOS) lab.Remove(lab.Index("."));
556 hfdis->GetXaxis()->SetBinLabel(j, lab);
557 hbdis->GetXaxis()->SetBinLabel(j, lab);
558 hxpak->GetXaxis()->SetBinLabel(j++, lab);
559 }
560
561 // Display histos
562 gStyle->SetOptStat(0);
563
564 TCanvas *c1 = new TCanvas("cv-hfdis", GetCanvasTitle(hfdis->GetTitle()), 800,50,700,700);
565 c1->Divide(1,2);
566 TPad *pad1 = (TPad *) c1->GetPad(1);
567 TPad *pad2 = (TPad *) c1->GetPad(2);
568 pad1->cd();
569 DoDraw(hfdis);
570 pad2->cd();
571 DoDraw(hbdis);
572 c1->Update();
573
574 TCanvas *c2 = new TCanvas("cv-hxpak", GetCanvasTitle(hxpak->GetTitle()), 500,350,700,700);
575 c2->cd();
576 DoDraw(hxpak, "lego");
577 c2->Update();
578 }
579 // Done
580 return;
581}
582
583////////////////////////////////////////////////////////////////////////////////
584/// Fill file info
585
587{
588 if (!wl || !sl) return;
589
590 // Extract information
591 TPerfEvent pe;
592 TPerfEvent* pep = &pe;
593 fTree->SetBranchAddress("PerfEvents", &pep);
594 Long64_t entries = fTree->GetEntries();
595 TNamed *wn = 0, *sn = 0;
596 for (Long64_t k=0; k<entries; k++) {
597 fTree->GetEntry(k);
598 // Analyse only packets
599 if (pe.fType != TVirtualPerfStats::kPacket) continue;
600 // Find out the worker instance
602 wn = (TNamed *) wl->FindObject(pe.fSlave.Data());
603 if (!wn) {
604 wn = new TNamed(pe.fSlave.Data(), wrk.Data());
605 wl->Add(wn);
606 }
607 // Find out the file server instance
608 TUrl uf(pe.fFileName);
609 TString srv(uf.GetUrl());
610 Int_t ifn = srv.Index(uf.GetFile());
611 if (ifn != kNPOS) srv.Remove(ifn);
612 sn = (TNamed *) sl->FindObject(srv.Data());
613 if (!sn) {
614 sn = new TNamed(srv.Data(), "remote");
615 sl->Add(sn);
616 }
617 }
618
619 // Done
620 return;
621}
622
623////////////////////////////////////////////////////////////////////////////////
624/// Return -1 if ord1 comes before ord2, 0 i they are equal,
625/// 1 if ord1 comes after ord2
626
627Int_t TProofPerfAnalysis::CompareOrd(const char *ord1, const char *ord2)
628{
629 TString o1(ord1), o2(ord2), p1, p2;
630 Int_t o1d = 0, o2d = 0;
631 if ((o1d = o1.CountChar('.')) > (o2d = o2.CountChar('.'))) {
632 return 1;
633 } else if (o1d < o2d) {
634 return -1;
635 } else {
636 o1.ReplaceAll(".", " ");
637 o2.ReplaceAll(".", " ");
638 Bool_t b1 = o1.Tokenize(p1, o1d, " ");
639 Bool_t b2 = o2.Tokenize(p2, o2d, " ");
640 while (b1 && b2) {
641 if (p1.Atoi() > p2.Atoi()) {
642 return 1;
643 } else if (p1.Atoi() < p2.Atoi()) {
644 return -1;
645 } else {
646 b1 = o1.Tokenize(p1, o1d, " ");
647 b2 = o2.Tokenize(p2, o2d, " ");
648 }
649 }
650 if (b1 && !b2) {
651 return 1;
652 } else if (b2 && !b1) {
653 return -1;
654 } else {
655 return 0;
656 }
657 }
658}
659
660////////////////////////////////////////////////////////////////////////////////
661/// Fill file info
662
664{
665 if (!hf || !hb || !hx) return;
666
667 TString fnout;
668 FILE *fout = 0;
669 if (wdet) {
670 fnout.Form("%s-FileDist-Details.txt", GetName());
671 if (!(fout = fopen(fnout.Data(), "w"))) {
672 Warning("FillFileDist", "asked to save details in '%s' but file could"
673 " not be open (errno: %d)", fnout.Data(), (int)errno);
674 } else {
675 Info("FillFileDist", "saving details to '%s'", fnout.Data());
676 }
677 }
678 // Extract information
679 TPerfEvent pe;
680 TPerfEvent* pep = &pe;
681 fTree->SetBranchAddress("PerfEvents",&pep);
682 Long64_t entries = fTree->GetEntries();
683 for (Long64_t k=0; k<entries; k++) {
684 fTree->GetEntry(k);
685 // Analyse only packets
686 if (pe.fType != TVirtualPerfStats::kPacket) continue;
687 // Find out the labels ...
688 TString wrk(pe.fSlave.Data());
689 TUrl uf(pe.fFileName);
690 TString srv(uf.GetUrl());
691 Int_t ifn = srv.Index(uf.GetFile());
692 if (ifn != kNPOS) srv.Remove(ifn);
693 // ... and the bins
694 Double_t xhf = hf->GetXaxis()->GetBinCenter(hf->GetXaxis()->FindBin(srv.Data()));
695 Double_t xhx = hx->GetXaxis()->GetBinCenter(hx->GetXaxis()->FindBin(srv.Data()));
696 Double_t yhx = hx->GetYaxis()->GetBinCenter(hx->GetYaxis()->FindBin(wrk.Data()));
697 // Save details, if asked
698 if (fout)
699 fprintf(fout, "%s,%s -> %f,%f (%f)\n",
700 srv.Data(), wrk.Data(), xhx, yhx, pe.fBytesRead / 1024.);
701 // Fill now
702 hf->Fill(xhf);
703 hb->Fill(xhf, pe.fBytesRead / 1024. / 1024.);
704 hx->Fill(xhx, yhx, pe.fBytesRead / 1024. / 1024.);
705 }
706 if (fout) fclose(fout);
707 // Done
708 return;
709}
710
711////////////////////////////////////////////////////////////////////////////////
712/// Fill file info when there is only one file server
713
715{
716 if (!hx) return;
717
718 TString fnout;
719 FILE *fout = 0;
720 if (wdet) {
721 fnout.Form("%s-FileDist-Details.txt", GetName());
722 if (!(fout = fopen(fnout.Data(), "w"))) {
723 Warning("FillFileDistOneSrv", "asked to save details in '%s' but file could"
724 " not be open (errno: %d)", fnout.Data(), (int)errno);
725 } else {
726 Info("FillFileDistOneSrv", "saving details to '%s'", fnout.Data());
727 }
728 }
729 // Extract information
730 TPerfEvent pe;
731 TPerfEvent* pep = &pe;
732 fTree->SetBranchAddress("PerfEvents",&pep);
733 Long64_t entries = fTree->GetEntries();
734 for (Long64_t k=0; k<entries; k++) {
735 fTree->GetEntry(k);
736 // Analyse only packets
737 if (pe.fType != TVirtualPerfStats::kPacket) continue;
738 // Find out the labels ...
739 TString wrk(pe.fSlave.Data());
740 TUrl uf(pe.fFileName);
741 TString srv(uf.GetUrl());
742 Int_t ifn = srv.Index(uf.GetFile());
743 if (ifn != kNPOS) srv.Remove(ifn);
744 // ... and the bins
745 Double_t xhx = hx->GetXaxis()->GetBinCenter(hx->GetXaxis()->FindBin(wrk.Data()));
746 // Save details, if asked
747 if (fout)
748 fprintf(fout, "%s,%s -> %f (%f)\n",
749 srv.Data(), wrk.Data(), xhx, pe.fBytesRead / 1024.);
750 // Fill now
751 hx->Fill(xhx, pe.fBytesRead / 1024. / 1024.);
752 }
753 if (fout) fclose(fout);
754 // Done
755 return;
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Measure the worker activity
760
762{
763 if (!IsValid()) {
764 Error("WorkerActivity","not a valid instance - do nothing");
765 return;
766 }
767
768 // Fill basic worker info
769 if (!WrkInfoOK()) FillWrkInfo();
770 if (!WrkInfoOK()) {
771 Error("WorkerActivity", "workers information not available - do nothing");
772 return;
773 }
774
775 TObject *o = 0;
776 // Create the histograms with activity vs time
777 if ((o = gDirectory->FindObject("act10"))) delete o;
778 Float_t t0 = fMergeTime - 2.* (fMaxTime - fMergeTime);
779 Float_t t1 = 2.*fInitTime;
780 if (t1 > t0) t1 = t0;
781 TH1F *hact10 = new TH1F("act10", "Worker activity start (seconds)", 50, 0., t1);
782 hact10->GetXaxis()->SetTitle("Query Processing Time (s)");
783 if ((o = gDirectory->FindObject("act11"))) delete o;
784 TH1F *hact11 = new TH1F("act11", "Worker activity stop (seconds)", 50, t0, fMaxTime);
785 hact11->GetXaxis()->SetTitle("Query Processing Time (s)");
786 if ((o = gDirectory->FindObject("act2"))) delete o;
787 TH1F *hact2 = new TH1F("act2", "End of activity (seconds)", 50, t0, fMaxTime);
788 hact2->GetXaxis()->SetTitle("Query Processing Time (s)");
789
790 // Fine-tune stat printing
791 Int_t curoptstat = gStyle->GetOptStat();
792 gStyle->SetOptStat(1100);
793
794 // Create the sorted list
795 TIter nxw(&fWrksInfo);
796 TWrkInfo *wi = 0;
797 while ((wi = (TWrkInfo *)nxw())) {
798 Int_t j = 0;
799 for (j = 1; j < hact10->GetNbinsX()+1 ; j++) {
800 if (wi->fStart < hact10->GetBinLowEdge(j))
801 hact10->Fill(hact10->GetBinCenter(j));
802 }
803 for (j = 1; j < hact11->GetNbinsX()+1 ; j++) {
804 if (wi->fStop > hact11->GetBinLowEdge(j))
805 hact11->Fill(hact11->GetBinCenter(j));
806 }
807 hact2->Fill(wi->fStop);
808 }
809
810 // Display histos
811 TCanvas *c1 = new TCanvas("perf", GetCanvasTitle("Activity histos"), 800,10,700,780);
812 c1->Divide(1,2);
813 TPad *pad1 = (TPad *) c1->GetPad(1);
814 pad1->Divide(2,1);
815 TPad *pad10 = (TPad *) pad1->GetPad(1);
816 TPad *pad11 = (TPad *) pad1->GetPad(2);
817 pad10->cd();
818 DoDraw(hact10);
819 pad11->cd();
820 DoDraw(hact11);
821 TPad *pad2 = (TPad *) c1->GetPad(2);
822 pad2->cd();
823 DoDraw(hact2);
824 c1->cd();
825 c1->Update();
826
827 // Restore stat options
828 gStyle->SetOptStat(curoptstat);
829
830 // Done
831 return;
832}
833
834////////////////////////////////////////////////////////////////////////////////
835/// Print information for all or the slowest showlast workers.
836/// Use showlast < 0 to print all
837
839{
840 // Create the sorted list
841 Int_t k = fWrksInfo.GetSize();
842 TIter nxw(&fWrksInfo);
843 TWrkInfo *wi = 0;
844 while ((wi = (TWrkInfo *)nxw())) {
845 // Print info about slowest workers
846 k--;
847 if (showlast < 0 || k < showlast) wi->Print();
848 }
849}
850
851////////////////////////////////////////////////////////////////////////////////
852/// Print information for worker 'wn' (ordinal) or on the machine whose
853/// ordinal or fqdn matches 'wn'. Multiple specifications separated by ','
854/// or ' ' are supported, as well as wildcards '*', e.g. '0.2*,lxb10* lxf2323.doma.in"
855
857{
858 if (!wn || (wn && strlen(wn) <= 0)) {
859 Error("PrintWrkInfo", "worker name or host must be defined!");
860 return;
861 }
862
863 // Check exact name
865 if (wi) {
866 wi->Print();
867 } else {
868 // Check matching
869 TString ww(wn), w;
870 TIter nxw(&fWrksInfo);
871 while ((wi = (TWrkInfo *)nxw())) {
872 TString n(wi->GetName()), t(wi->GetTitle());
873 Ssiz_t from = 0;
874 while (ww.Tokenize(w, from, "[, ]")) {
875 TRegexp re(w, kTRUE);
876 if (n.Index(re) != kNPOS || t.Index(re) != kNPOS) wi->Print();
877 }
878 }
879 }
880}
881
882////////////////////////////////////////////////////////////////////////////////
883/// Print information for all or the slowest showlast workers.
884/// Use showlast < 0 to print all
885
886void TProofPerfAnalysis::PrintFileInfo(Int_t showlast, const char *opt, const char *out)
887{
889 if (out && strlen(out) > 0) gSystem->RedirectOutput(out, "w", &rh);
890
891 // Create the sorted list
893 TIter nxf(&fFilesInfo);
894 TFileInfo *fi = 0;
895 while ((fi = (TFileInfo *)nxf())) {
896 // Print info about files processed last
897 k--;
898 if (showlast < 0 || k < showlast) fi->Print(opt);
899 }
900
901 if (out && strlen(out) > 0) gSystem->RedirectOutput(0, 0, &rh);
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Print information for file 'fn' (path including directory) or server 'fn'.
906/// Multiple specifications separated by ','
907/// or ' ' are supported, as well as wildcards '*', e.g. 'pippo.root, h4mu*,lxb10*"
908
909void TProofPerfAnalysis::PrintFileInfo(const char *fn, const char *opt, const char *out)
910{
911 if (!fn || (fn && strlen(fn) <= 0)) {
912 Error("PrintFileInfo", "file path must be defined!");
913 return;
914 }
915
917 if (out && strlen(out) > 0) gSystem->RedirectOutput(out, "w", &rh);
918
919 // Check exact name
921 if (fi) {
922 fi->Print(opt);
923 } else {
924 // Check matching
925 TString fw(fn), f;
926 TIter nxf(&fFilesInfo);
927 while ((fi = (TFileInfo *)nxf())) {
928 TString n(fi->GetName()), s(fi->GetTitle());
929 Ssiz_t from = 0;
930 while (fw.Tokenize(f, from, "[, ]")) {
931 TRegexp re(f, kTRUE);
932 if (n.Index(re) != kNPOS || s.Index(re) != kNPOS) fi->Print(opt);
933 }
934 }
935 }
936
937 if (out && strlen(out) > 0) gSystem->RedirectOutput(0, 0, &rh);
938}
939
940////////////////////////////////////////////////////////////////////////////////
941/// Fill basic worker info; if 'force' rescan the TTree even already done
942
944{
945 // Nothing to do if already called
946 if (fWrksInfo.GetSize() > 0 && !force) return;
947
948 // Cleanup existing information
951 fInitTime = -1.;
952 fMergeTime = -1.;
953 fMaxTime = -1.;
954 fEvtRateMax = -1.;
955 fMBRateMax = -1.;
956 fLatencyMax = -1.;
957
958 TList *wl = new TList;
959 // Extract worker information
960 TPerfEvent pe;
961 TPerfEvent* pep = &pe;
962 fTree->SetBranchAddress("PerfEvents",&pep);
963 Long64_t entries = fTree->GetEntries();
964
965 // First determine binning for global rates
966 Int_t nraw = entries * 2, jj = 0, kk = 0;
967 Double_t *xraw = new Double_t[nraw];
968 for (Long64_t k=0; k<entries; k++) {
969 fTree->GetEntry(k);
970 // Analyse only packets
972 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
973 Float_t start = stop - pe.fProcTime;
974 // Bins
975 xraw[jj++] = start;
976 xraw[jj++] = stop;
977 }
978 }
979 Int_t nbins = jj;
980 Int_t *jidx = new Int_t[nbins];
981 memset(jidx, 0, nbins * sizeof(Int_t));
982 TMath::Sort(nbins, xraw, jidx, kFALSE);
983 Double_t *xbins = new Double_t[nbins];
984 jj = 0;
985 for (kk = 0; kk < nbins; kk++) {
986 Double_t xtmp = xraw[jidx[kk]];
987 if (jj == 0 || xtmp > xbins[jj - 1] + .5) {
988 xbins[jj] = xtmp;
989 jj++;
990 }
991 }
992 nbins = jj;
993 delete [] xraw;
994 delete [] jidx;
995
996 // Create the global histograms
997 Int_t nbin = nbins - 1;
998 TObject *o = 0;
999 if ((o = gDirectory->FindObject("gEvtRate"))) delete o;
1000 fEvtRate = new TH1F("gEvtRate", "Total event processing rate (evt/s)", nbin, xbins);
1001 fEvtRate->SetMinimum(0.);
1004 fEvtRate->GetXaxis()->SetTitle("Query Processing Time (s)");
1005 if ((o = gDirectory->FindObject("gEvtRateAvg"))) delete o;
1006 fEvtRateRun = new TH1F("gEvtRateAvg", "Event processing rate running average (evt/s)", nbin, xbins);
1010 fEvtRateRun->GetXaxis()->SetTitle("Query Processing Time (s)");
1011 if ((o = gDirectory->FindObject("gMBRate"))) delete o;
1012 fMBRate = new TH1F("gMBRate", "Total processing rate (MB/s)", nbin, xbins);
1013 fMBRate->SetMinimum(0.);
1016 fMBRate->GetXaxis()->SetTitle("Query Processing Time (s)");
1017 if ((o = gDirectory->FindObject("gMBRateAvg"))) delete o;
1018 fMBRateRun = new TH1F("gMBRateAvg", "Processing rate running average (MB/s)", nbin, xbins);
1022 fMBRateRun->GetXaxis()->SetTitle("Query Processing Time (s)");
1023 // Not needed any longer
1024 delete [] xbins;
1025
1026 THashList gBins;
1027 TList *gwl = 0, *gbl = 0;
1028
1029 // Extract the worker info now
1030 TWrkInfo *wi = 0;
1031 for (Long64_t k=0; k<entries; k++) {
1032 fTree->GetEntry(k);
1033 // Analyse only packets
1035 // Find out the worker instance
1036 if (!(wi = (TWrkInfo *) wl->FindObject(pe.fSlave.Data()))) {
1037 wi = new TWrkInfo(pe.fSlave.Data(), pe.fSlaveName.Data());
1038 wl->Add(wi);
1039 wi->fRateT = new TGraph(100);
1040 wi->fRateRemoteT = new TGraph(100);
1041 wi->fMBRateT = new TGraph(100);
1042 wi->fMBRateRemoteT = new TGraph(100);
1043 wi->fLatencyT = new TGraph(100);
1044 }
1045 // Add Info now
1046 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1047 Float_t start = stop - pe.fProcTime;
1048 if (wi->fPackets <= 0) {
1049 wi->fStart = start;
1050 } else {
1051 wi->fStop = stop;
1052 }
1053 TUrl uf(pe.fFileName), uw(pe.fSlaveName);
1054 fMaxTime = stop;
1056 wi->fBytesRead += pe.fBytesRead;
1057 wi->fLatency += pe.fLatency;
1058 wi->fProcTime += pe.fProcTime;
1059 wi->fCpuTime += pe.fCpuTime;
1060 // Fill graphs
1061 Double_t tt = stop;
1062 Double_t ert = pe.fEventsProcessed / pe.fProcTime ;
1063 Double_t brt = pe.fBytesRead / pe.fProcTime / 1024. / 1024. ;
1064 wi->fRateT->SetPoint(wi->fPackets, tt, ert);
1065 if (brt > 0.) wi->fMBRateT->SetPoint(wi->fPackets, tt, brt);
1066 wi->fLatencyT->SetPoint(wi->fPackets, tt, pe.fLatency);
1067 if (!pe.fFileName.IsNull() && strcmp(uf.GetHostFQDN(), uw.GetHostFQDN())) {
1068 wi->fRateRemoteT->SetPoint(wi->fRemotePackets, tt, ert);
1069 wi->fMBRateRemoteT->SetPoint(wi->fRemotePackets, tt, brt);
1070 wi->fRemotePackets++;
1071 }
1072 wi->fPackets++;
1073 if (ert > fEvtRateMax) fEvtRateMax = ert;
1074 if (brt > fMBRateMax) fMBRateMax = brt;
1076
1077 // Fill global rate histos
1078 for (kk = 1; kk <= nbins; kk++) {
1080 if (mi > stop) break;
1081 Double_t wd = fEvtRate->GetBinWidth(kk);
1082 Double_t mx = mi + wd;
1083 Double_t xx = fEvtRate->GetBinCenter(kk);
1084 // Overlap length
1085 Double_t olap = stop - mi;
1086 if (start > mi) olap = mx - start;
1087 if (olap >= 0) {
1088 TString sb = TString::Format("%d", kk);
1089 if (!(gbl = (TList *) gBins.FindObject(sb))) {
1090 gbl = new TList;
1091 gbl->SetName(sb);
1092 gBins.Add(gbl);
1093 }
1094 if (!(gwl = (TList *) gbl->FindObject(pe.fSlave))) {
1095 gwl = new TList;
1096 gwl->SetName(pe.fSlave);
1097 gbl->Add(gwl);
1098 }
1099 gwl->Add(new TWrkEntry(xx, ert, brt, pe.fProcTime));
1100 }
1101 }
1102
1103 // Notify
1104 if (fDebug > 1) {
1105 if (pe.fProcTime > 0.) {
1106 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs evts:%lld bytes:%lld (rates:%f evt/s, %f MB/s)",
1107 wi->GetName(), wi->fPackets, fMaxTime - pe.fProcTime,
1109 ert, brt);
1110 } else {
1111 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs rate:-- evt/s (-- bytes/s)",
1112 wi->GetName(), wi->fPackets, fMaxTime, pe.fLatency, pe.fProcTime);
1113 }
1114 }
1115 } else if (pe.fType == TVirtualPerfStats::kStart) {
1116 Float_t start = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1117 if (fDebug > 1) Printf(" +++ %s Start: %f s", pe.fEvtNode.Data(), start);
1118 } else if (pe.fType == TVirtualPerfStats::kStop) {
1119 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1120 if (fDebug > 1) Printf(" +++ %s Stop: %f s", pe.fEvtNode.Data(), stop);
1121 } else {
1122 if (fDebug > 2) Printf(" +++ Event type: %d", pe.fType);
1123 }
1124 }
1125
1126 TIter nxb(&gBins);
1127 gbl = 0;
1128 while ((gbl = (TList *) nxb())) {
1129 gwl = 0;
1130 TIter nxw(gbl);
1131 while ((gwl = (TList *) nxw())) {
1132 Double_t er = 0, br = 0, pt = 0, xx = 0;
1133 TIter nxp(gwl);
1134 TWrkEntry *we = 0;
1135 while ((we = (TWrkEntry *) nxp())) {
1136 if (we->fProcTime > 0) {
1137 er += we->fEvtRate * we->fProcTime;
1138 br += we->fMBRate * we->fProcTime;
1139 pt += we->fProcTime;
1140 }
1141 xx = we->fXx;
1142 }
1143 if (pt > 0.) {
1144 er /= pt;
1145 br /= pt;
1146 fEvtRate->Fill(xx, er);
1147 if (br > 0.) fMBRate->Fill(xx, br);
1148 }
1149 }
1150 }
1151
1152 // Running averages
1153 Double_t er = 0, br = 0, pt = 0;
1154 for (kk = 1; kk < nbins; kk++) {
1155 Double_t wd = fEvtRate->GetBinWidth(kk);
1156 Double_t wx = fEvtRate->GetBinCenter(kk);
1157 Double_t wer = fEvtRate->GetBinContent(kk);
1158 Double_t wbr = fMBRate->GetBinContent(kk);
1159
1160 if (kk == 1) {
1161 er = wer;
1162 br = wbr;
1163 pt = wd;
1164 } else {
1165 er *= pt;
1166 br *= pt;
1167 pt += wd;
1168 er += wer * wd;
1169 br += wbr * wd;
1170 er /= pt;
1171 br /= pt;
1172 }
1173 if (er > fEvtRateAvgMax) fEvtRateAvgMax = er;
1174 if (br > fMBRateAvgMax) fMBRateAvgMax = br;
1175 fEvtRateAvg = er;
1176 fMBRateAvg = br;
1177 // Fill
1178 fEvtRateRun->Fill(wx, er);
1179 fMBRateRun->Fill(wx, br);
1180 }
1181
1182
1183 // Final analysis to find relevant times
1184 TIter nxw(wl);
1185 while ((wi = (TWrkInfo *) nxw())) {
1186 fWrksInfo.Add(wi);
1187 if (wi->fStart > fInitTime) fInitTime = wi->fStart;
1188 // Resize the graphs
1189 wi->fRateT->Set(wi->fPackets);
1191 wi->fLatencyT->Set(wi->fPackets);
1192 wi->fMBRateT->Set(wi->fPackets);
1194 }
1195 wl->SetOwner(kFALSE);
1196 delete wl;
1197
1198 // Final analysis to find relevant times
1200 Int_t rsw = (fWrksInfo.GetSize() > 1) ? 2 : 1, ksw = 0;
1201 TIter nxsw(&fWrksInfo);
1202 while ((wi = (TWrkInfo *) nxsw())) {
1203 if (wi->fStop > 0.) ksw++;
1204 if (ksw == rsw) break;
1205 }
1206 if (wi) fMergeTime = wi->fStop;
1207
1208 // (Re-)create the event and packet distribution histograms
1211 fEvents = new TH1F("hevents", "Events per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1213 fPackets = new TH1F("hpackets", "Packets per worker", fWrksInfo.GetSize(), -.5, fWrksInfo.GetSize()-.5);
1215 Int_t j = 0;
1216 TIter nxwi(&fWrksInfo);
1217 while ((wi = (TWrkInfo *)nxwi())) {
1218 fEvents->GetXaxis()->SetBinLabel(j+1, wi->GetName());
1219 fEvents->Fill(j, wi->fEventsProcessed);
1220 fPackets->GetXaxis()->SetBinLabel(j+1, wi->GetName());
1221 fPackets->Fill(j++, wi->fPackets);
1222 }
1223 fEvents->SetMinimum(0.);
1224 fPackets->SetMinimum(0.);
1225 fEvents->SetFillColor(38);
1227 fEvents->GetYaxis()->SetTitle("Events");
1228 fEvents->GetXaxis()->SetTitle("Worker");
1229 fPackets->GetYaxis()->SetTitle("Packets");
1230 fPackets->GetXaxis()->SetTitle("Worker");
1231
1232 // Print summary
1233 if (fgDebug) Summary();
1234}
1235
1236////////////////////////////////////////////////////////////////////////////////
1237/// Print summary of query. Use opt = 'S' for compact version.
1238/// Output to 'out' or to screen.
1239
1240void TProofPerfAnalysis::Summary(Option_t *opt, const char *out)
1241{
1242 TString o(out);
1244 if (!o.IsNull()) {
1245 const char *m = (o.BeginsWith("+")) ? "a" : "w";
1246 o.Remove(TString::kLeading, '+');
1247 gSystem->RedirectOutput(o, m, &rh);
1248 }
1249
1250 // Print summary
1251 if (!strcmp(opt, "S")) {
1252 // Short version
1253 Printf("%d %f %f %f %f %f %f %f",
1256 } else {
1257 // Long version
1258 Printf(" +++ %d workers were active during this query", fWrksInfo.GetSize());
1259 Printf(" +++ Total query time: %f secs (init: %f secs, merge: %f secs)",
1261 Printf(" +++ Avg processing rates: %.4f evts/s, %.4f MB/s", fEvtRateAvg, fMBRateAvg);
1262 Printf(" +++ Max processing rates: %.4f evts/s, %.4f MB/s", fEvtRateAvgMax, fMBRateAvgMax);
1263 }
1264
1265 if (!o.IsNull()) gSystem->RedirectOutput(0, 0, &rh);
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Fill basic worker info; if 'force' rescan the TTree even already done
1270
1272{
1273 // Nothing to do if already called
1274 if (fFilesInfo.GetSize() > 0 && !force) return;
1275
1276 // Cleanup existing information
1278 fFilesInfo.Clear();
1279
1280 TList *fl = new TList;
1281 // Extract worker information
1282 TPerfEvent pe;
1283 TPerfEvent* pep = &pe;
1284 fTree->SetBranchAddress("PerfEvents",&pep);
1285 Long64_t entries = fTree->GetEntries();
1286 TFileInfo *fi = 0;
1287 for (Long64_t k=0; k<entries; k++) {
1288 fTree->GetEntry(k);
1289 // Analyse only packets
1291 TUrl uf(pe.fFileName);
1292 TString srv(uf.GetUrl());
1293 Int_t ifn = srv.Index(uf.GetFile());
1294 if (ifn != kNPOS) srv.Remove(ifn);
1295 // Find out the file instance
1296 fi = (TFileInfo *) fl->FindObject(uf.GetFile());
1297 if (!fi) {
1298 fi = new TFileInfo(uf.GetFile(), srv.Data());
1299 fl->Add(fi);
1300 fi->fSizeP = new TGraph(10);
1301 fi->fRateP = new TGraph(10);
1302 fi->fRatePRemote = new TGraph(10);
1303 fi->fMBRateP = new TGraph(10);
1304 fi->fMBRatePRemote = new TGraph(10);
1305 }
1306 // Add Info now
1307 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1308 Float_t start = stop - pe.fProcTime;
1309 if (fi->fPackets <= 0) {
1310 fi->fStart = start;
1311 } else {
1312 fi->fStop = stop;
1313 }
1314 TUrl uw(pe.fSlaveName);
1315
1316 // Fill size graphs
1318 fi->fSizeAvg += pe.fEventsProcessed;
1319 if (pe.fEventsProcessed > fi->fSizeMax || fi->fSizeMax < 0.) fi->fSizeMax = pe.fEventsProcessed;
1320 if (pe.fEventsProcessed < fi->fSizeMin || fi->fSizeMin < 0.) fi->fSizeMin = pe.fEventsProcessed;
1321
1322 // Fill rate graphs
1324 Double_t ert = pe.fEventsProcessed / pe.fProcTime ;
1325 Double_t brt = pe.fBytesRead / pe.fProcTime / 1024. / 1024. ;
1326 fi->fRateP->SetPoint(fi->fPackets, tt, ert);
1327 if (brt > 0.) fi->fMBRateP->SetPoint(fi->fPackets, tt, brt);
1328 if (!pe.fFileName.IsNull() && strcmp(uf.GetHostFQDN(), uw.GetHostFQDN())) {
1329 if (!(fi->fRWrkList.FindObject(pe.fSlave))) fi->fRWrkList.Add(new TNamed(pe.fSlave, pe.fSlaveName));
1330 fi->fRatePRemote->SetPoint(fi->fRPackets, tt, ert);
1331 fi->fMBRatePRemote->SetPoint(fi->fRPackets, tt, brt);
1332 fi->fRPackets++;
1333 }
1334 fi->fPackets++;
1335 if (brt > 0) {
1336 fi->fMBRateAvg += brt;
1337 if (brt > fi->fMBRateMax || fi->fMBRateMax < 0.) fi->fMBRateMax = brt;
1338 if (brt < fi->fMBRateMin || fi->fMBRateMin < 0.) fi->fMBRateMin = brt;
1339 }
1340
1341 // Packet info
1342 TPackInfo *pi = new TPackInfo(pe.fSlave, pe.fSlaveName, start, stop, pe.fEventsProcessed, brt);
1343 fi->fPackList.Add(pi);
1344 TWrkInfoFile *wif = 0;
1345 if (!(wif = (TWrkInfoFile *) fi->fWrkList.FindObject(pe.fSlave))) {
1346 wif = new TWrkInfoFile(pe.fSlave, uf.GetFile());
1347 fi->fWrkList.Add(wif);
1348 }
1349 wif->fPackets.Add(pi);
1350
1351 // Notify
1352 if (fDebug > 1) {
1353 if (pe.fProcTime > 0.) {
1354 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs evts:%lld bytes:%lld (rates:%f evt/s, %f MB/s)",
1355 fi->GetName(), fi->fPackets, fMaxTime - pe.fProcTime,
1357 ert, brt);
1358 } else {
1359 Printf(" +++ %s #:%d at:%fs lat:%fs proc:%fs rate:-- evt/s (-- bytes/s)",
1360 fi->GetName(), fi->fPackets, fMaxTime, pe.fLatency, pe.fProcTime);
1361 }
1362 }
1363 } else if (pe.fType == TVirtualPerfStats::kStart) {
1364 Float_t start = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1365 if (fDebug > 1) Printf(" +++ %s Start: %f s", pe.fEvtNode.Data(), start);
1366 } else if (pe.fType == TVirtualPerfStats::kStop) {
1367 Float_t stop = pe.fTimeStamp.GetSec() + 1e-9*pe.fTimeStamp.GetNanoSec();
1368 if (fDebug > 1) Printf(" +++ %s Stop: %f s", pe.fEvtNode.Data(), stop);
1369 } else {
1370 if (fDebug > 2) Printf(" +++ Event type: %d", pe.fType);
1371 }
1372 }
1373 // Final analysis to find relevant times
1374 TIter nxf(fl);
1375 while ((fi = (TFileInfo *) nxf())) {
1376 fFilesInfo.Add(fi);
1377 // Resize the graphs
1378 fi->fRateP->Set(fi->fPackets);
1379 fi->fRatePRemote->Set(fi->fRPackets);
1380 fi->fMBRateP->Set(fi->fPackets);
1381 fi->fMBRatePRemote->Set(fi->fRPackets);
1382 }
1383 fl->SetOwner(kFALSE);
1384 delete fl;
1385
1386 // Print summary
1387 if (fgDebug)
1388 Printf(" +++ %d files were processed during this query", fFilesInfo.GetSize());
1389}
1390
1391////////////////////////////////////////////////////////////////////////////////
1392/// Static setter for the verbosity level
1393
1395{
1396 fDebug = d;
1397}
1398
1399////////////////////////////////////////////////////////////////////////////////
1400/// Draw object 'o' with options 'opt'
1401/// Save it with 'name' if in saving mode (see SetSaveResult)
1402
1404{
1405 // Draw
1406 o->Draw(opt);
1407
1408 // Save the result
1409 if (fSaveResult) {
1410 // Preparation is done in SetSaveResult, here we just update
1411 TDirectory *curdir = gDirectory;
1412 TFile *f = TFile::Open(fFileResult, "UPDATE");
1413 if (f && !f->IsZombie()) {
1414 const char *n = (name && strlen(name) > 0) ? name : 0;
1415 o->Write(n);
1416 f->Close();
1417 }
1418 if (f) delete f;
1419 gDirectory = curdir;
1420 }
1421}
1422
1423////////////////////////////////////////////////////////////////////////////////
1424/// Set save result mode and validate 'file' according to 'mode'.
1425/// Return 0 on success, -1 if any problem with the file is encountered
1426/// (save result mode is not enabled in such a case).
1427/// If 'file' is null saving is disabled.
1428
1430{
1431 // A null 'file' indicates the will to disable
1432 if (!file) {
1433 fFileResult = "";
1435 // Notify
1436 Printf("Drawn objects saving disabled");
1437 return 0;
1438 }
1439
1440 // Check if there is a change
1441 if (!fFileResult.IsNull() && fFileResult == file) {
1442 // No change
1444 return 0;
1445 }
1446 // New or changed file: validate
1447 fFileResult = "";
1449 TDirectory *curdir = gDirectory;
1450 TFile *f = TFile::Open(file, mode);
1451 if (!f || f->IsZombie()) {
1452 if (f) delete f;
1453 fFileResult = "";
1454 Error("SetSaveResult", "could not open file '%s' in mode '%s'", file, mode);
1455 gDirectory = curdir;
1456 return -1;
1457 }
1458 f->Close();
1459 delete f;
1460 gDirectory = curdir;
1461 // Ok
1462 fFileResult = file;
1464 // Notify
1465 Printf("Drawn objects will be saved in file '%s'", file);
1466 return 0;
1467}
1468
1469////////////////////////////////////////////////////////////////////////////////
1470/// Static setter for the verbosity level
1471
1473{
1474 fgDebug = on;
1475}
1476////////////////////////////////////////////////////////////////////////////////
1477/// Display event and packet distribution
1478
1480{
1481 if (!fEvents || !fPackets) {
1482 Error("EventDist", "distributions not initialized - do nothing");
1483 }
1484
1485 // Display histos
1486 TCanvas *c1 = new TCanvas("evtdist", GetCanvasTitle("Event distributions"),800,10,700,780);
1487 c1->Divide(1,2);
1488 TPad *pad1 = (TPad *) c1->GetPad(1);
1489 pad1->cd();
1491 DoDraw(fEvents);
1492 TPad *pad2 = (TPad *) c1->GetPad(2);
1493 pad2->cd();
1496 c1->cd();
1497 c1->Update();
1498
1499}
1500
1501////////////////////////////////////////////////////////////////////////////////
1502/// Show event processing or MB processing rate plot vs time
1503
1504void TProofPerfAnalysis::RatePlot(const char *wrks)
1505{
1506 Bool_t global = (wrks && !strcmp(wrks, "global")) ? kTRUE : kFALSE;
1507
1508 TH1F *hrt1 = 0, *hrt2 = 0;
1509 if (global) {
1510 hrt1 = fEvtRate;
1511 hrt2 = fMBRate;
1512 } else {
1513 // Create the histograms
1514 TObject *o = 0;
1515 if ((o = gDirectory->FindObject("rt1"))) delete o;
1516 hrt1 = new TH1F("rt1", "Evt processing rate (evt/s)", 100, 0., fMaxTime);
1517 hrt1->SetMinimum(0.);
1518 hrt1->SetMaximum(1.05*fEvtRateMax);
1519 hrt1->SetStats(kFALSE);
1520 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1521 if ((o = gDirectory->FindObject("rt2"))) delete o;
1522 hrt2 = new TH1F("rt2", "MB processing rate (MB/s)", 100, 0., fMaxTime);
1523 hrt2->SetMinimum(0.);
1524 hrt2->SetMaximum(1.05*fMBRateMax);
1525 hrt2->SetStats(kFALSE);
1526 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1527 }
1528
1529 // Display histo frames
1530 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("Processing rates"), 800,10,700,780);
1531 c1->Divide(1,2);
1532 TPad *pad1 = (TPad *) c1->GetPad(1);
1533 pad1->cd();
1534 hrt1->Draw();
1535 if (global) DoDraw(fEvtRateRun, "SAME", "EvtRateRun");
1536 TPad *pad2 = (TPad *) c1->GetPad(2);
1537 pad2->cd();
1538 hrt2->Draw();
1539 if (global) DoDraw(fMBRateRun, "SAME", "MBRateRun");
1540 c1->cd();
1541 c1->Update();
1542
1543 // Done if global
1544 if (global) return;
1545
1546 // Which workers?
1547 THashList *wl = 0;
1548 TString ww(wrks);
1549 if (!ww.IsNull() && ww != "*" && ww != "all") {
1550 TString w;
1551 Ssiz_t from = 0;
1552 while ((ww.Tokenize(w, from, ","))) {
1553 if (!wl) wl = new THashList();
1554 wl->Add(new TObjString(w.Data()));
1555 }
1556 }
1557
1558 // Now plot the graphs per worker
1559 Int_t ci = 40, cir = 30, ic = 0;
1560 TIter nxw(&fWrksInfo);
1561 TWrkInfo *wi = 0;
1562 while ((wi = (TWrkInfo *) nxw())) {
1563 if (wl && !wl->FindObject(wi->GetName())) continue;
1564 if (wi->fRateT && wi->fRateT->GetN() > 0) {
1565 wi->fRateT->SetNameTitle(wi->GetName(), wi->GetTitle());
1566 pad1->cd();
1567 wi->fRateT->SetLineColor(ci);
1568 DoDraw(wi->fRateT, "L", TString::Format("RateT-%s", wi->fRateT->GetName()));
1569 }
1570 if (wi->fRateRemoteT && wi->fRateRemoteT->GetN() > 0) {
1571 wi->fRateRemoteT->SetNameTitle(wi->GetName(), wi->GetTitle());
1572 pad1->cd();
1573 wi->fRateRemoteT->SetLineColor(cir);
1574 DoDraw(wi->fRateRemoteT, "L", TString::Format("RateRemoteT-%s", wi->fRateRemoteT->GetName()));
1575 }
1576 if (wi->fMBRateT && wi->fMBRateT->GetN() > 0) {
1577 wi->fMBRateT->SetNameTitle(wi->GetName(), wi->GetTitle());
1578 pad2->cd();
1579 wi->fMBRateT->SetLineColor(ci);
1580 DoDraw(wi->fMBRateT, "L", TString::Format("MBRateT-%s", wi->fMBRateT->GetName()));
1581 }
1582 if (wi->fMBRateRemoteT && wi->fMBRateRemoteT->GetN() > 0) {
1583 wi->fMBRateRemoteT->SetNameTitle(wi->GetName(), wi->GetTitle());
1584 pad2->cd();
1585 wi->fMBRateRemoteT->SetLineColor(cir);
1586 DoDraw(wi->fMBRateRemoteT, "L", TString::Format("MBRateRemoteT-%s", wi->fMBRateRemoteT->GetName()));
1587 }
1588 ic++;
1589 ci = ic%10 + 40;
1590 cir = ic%10 + 30;
1591 c1->cd();
1592 c1->Update();
1593 }
1594
1595 // Cleanup
1596 if (wl) {
1597 wl->SetOwner(kTRUE);
1598 delete wl;
1599 }
1600}
1601
1602////////////////////////////////////////////////////////////////////////////////
1603/// Show event processing or MB processing rate plot vs time
1604/// Create the histograms
1605
1607{
1608 TObject *o = 0;
1609 if ((o = gDirectory->FindObject("lt1"))) delete o;
1610 TH1F *hlt1 = new TH1F("lt1", "Packet retrieval latency", 100, 0., fMaxTime);
1611 hlt1->SetMinimum(0.);
1612 hlt1->SetMaximum(1.05*fLatencyMax);
1613 hlt1->SetStats(kFALSE);
1614 hlt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1615 hlt1->GetYaxis()->SetTitle("Latency (s)");
1616
1617 // Display histo frames
1618 TCanvas *c1 = new TCanvas("latency", GetCanvasTitle("Packet Retrieval Latency"), 800,10,700,780);
1619 hlt1->Draw();
1620 c1->cd();
1621 c1->Update();
1622
1623 // Which workers?
1624 THashList *wl = 0;
1625 TString ww(wrks);
1626 if (!ww.IsNull() && ww != "*" && ww != "all") {
1627 TString w;
1628 Ssiz_t from = 0;
1629 while ((ww.Tokenize(w, from, ","))) {
1630 if (!wl) wl = new THashList();
1631 wl->Add(new TObjString(w.Data()));
1632 }
1633 }
1634
1635 // Now plot the graphs per worker
1636 Int_t ci = 40, ic = 0;
1637 TIter nxw(&fWrksInfo);
1638 TWrkInfo *wi = 0;
1639 while ((wi = (TWrkInfo *) nxw())) {
1640 if (wl && !wl->FindObject(wi->GetName())) continue;
1641 if (wi->fLatencyT) {
1642 wi->fLatencyT->SetNameTitle(wi->GetName(), wi->GetTitle());
1643 wi->fLatencyT->SetLineColor(ci);
1644 DoDraw(wi->fLatencyT, "L", TString::Format("LatencyT-%s", wi->fLatencyT->GetName()));
1645 }
1646 ic++;
1647 ci = ic%10 + 40;
1648 c1->cd();
1649 c1->Update();
1650 }
1651
1652 // Cleanup
1653 if (wl) {
1654 wl->SetOwner(kTRUE);
1655 delete wl;
1656 }
1657}
1658
1659////////////////////////////////////////////////////////////////////////////////
1660/// Show event processing or MB processing rate plot vs time
1661
1662void TProofPerfAnalysis::FileProcPlot(const char *fn, const char *out)
1663{
1664 if (!fn || strlen(fn) <= 0) {
1665 Error("FileRatePlot", "file name is mandatory!");
1666 return;
1667 }
1668 // Get the file info object
1670 if (!fi) {
1671 Error("FileRatePlot", "TFileInfo object for '%s' not found!", fn);
1672 return;
1673 }
1674
1675 // Output text file, if required
1676 FILE *fo = stdout;
1677 if (out && strlen(out) > 0) {
1678 if (!(fo = fopen(out, "w"))) {
1679 Warning("FileRatePlot", "problems creating '%s': logging to stdout", out);
1680 fo = stdout;
1681 } else {
1682 Printf(" Details logged to %s", out);
1683 }
1684 }
1685
1686 // Get bins
1687 Int_t nbins = fi->fPackList.GetSize() * 2;
1688 Double_t *xraw = new Double_t[nbins];
1689 Int_t jj = 0;
1690 TPackInfo *pi = 0;
1691 TIter nxp(&(fi->fPackList));
1692 while ((pi = (TPackInfo *) nxp())) {
1693 // Bins
1694 xraw[jj++] = pi->fStart;
1695 xraw[jj++] = pi->fStop;
1696 }
1697 Int_t *jidx = new Int_t[nbins];
1698 memset(jidx, 0, nbins * sizeof(Int_t));
1699 TMath::Sort(nbins, xraw, jidx, kFALSE);
1700 Double_t *xbins = new Double_t[nbins];
1701 Int_t kk =0;
1702 for (kk = 0; kk < nbins; kk++) {
1703 xbins[kk] = xraw[jidx[kk]];
1704 }
1705 delete [] xraw;
1706 delete [] jidx;
1707
1708 // Create the histograms
1709 Int_t nbin = nbins - 1;
1710 TObject *o = 0;
1711 if ((o = gDirectory->FindObject("rt1"))) delete o;
1712 TH1F *hrt1 = new TH1F("rt1", "Total processing rate (MB/s)", nbins - 1, xbins);
1713 hrt1->SetMinimum(0.);
1714 hrt1->SetStats(kFALSE);
1715 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1716 if ((o = gDirectory->FindObject("rt2"))) delete o;
1717 TH1F *hrt2 = new TH1F("rt2", "Number of processing workers", nbins - 1, xbins);
1718 hrt2->SetMinimum(0.);
1719 hrt2->SetMaximum(1.2*fWrksInfo.GetSize());
1720 hrt2->SetStats(kFALSE);
1721 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1722 if ((o = gDirectory->FindObject("rt3"))) delete o;
1723 TH1F *hrt3 = new TH1F("rt3", "Total processing events", nbins - 1, xbins);
1724 hrt3->SetMinimum(0.);
1725 hrt3->SetStats(kFALSE);
1726 hrt3->GetXaxis()->SetTitle("Query Processing Time (s)");
1727 if ((o = gDirectory->FindObject("rt4"))) delete o;
1728 TH1F *hrt4 = new TH1F("rt4", "Weighted processing rate (MB/s)", nbins - 1, xbins);
1729 hrt4->SetMinimum(0.);
1730 hrt4->SetStats(kFALSE);
1731 hrt4->GetXaxis()->SetTitle("Query Processing Time (s)");
1732 // Not needed any longer
1733 delete [] xbins;
1734
1735 // Fill histos now
1736 Int_t ii = 0;
1737 for (ii = 1; ii <= nbin; ii++) {
1738 Double_t mi = hrt1->GetBinLowEdge(ii);
1739 Double_t wd = hrt1->GetBinWidth(ii);
1740 Double_t mx = mi + wd;
1741 Double_t xx = hrt1->GetBinCenter(ii);
1742 fprintf(fo, " Bin: %d/%d [%f, %f]\n", ii, nbin, mi, mx);
1743 pi = 0;
1744 kk = 0;
1745 nxp.Reset();
1746 while ((pi = (TPackInfo *) nxp())) {
1747 // Overlap length
1748 Double_t olap = pi->fStop - mi;
1749 if (pi->fStart > mi) olap = mx - pi->fStart;
1750 if (olap >= 0) {
1751 hrt1->Fill(xx, pi->fMBRate);
1752 hrt2->Fill(xx, 1.);
1753 hrt3->Fill(xx, pi->fSize);
1754 hrt4->Fill(xx, pi->fMBRate * pi->fSize);
1755 fprintf(fo, " %d: %s \t%lld \tevts \t%f \tMB/s\n", kk++, pi->GetName(), pi->fSize, pi->fMBRate);
1756 }
1757 }
1758 }
1759 if (fo != stdout) fclose(fo);
1760
1761 // Display histo frames
1762 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("File processing info"), 800,10,700,780);
1763 c1->Divide(1,3);
1764 TPad *pad1 = (TPad *) c1->GetPad(1);
1765 pad1->cd();
1766 DoDraw(hrt1);
1767 TPad *pad2 = (TPad *) c1->GetPad(2);
1768 pad2->cd();
1769 DoDraw(hrt2);
1770 TPad *pad4 = (TPad *) c1->GetPad(3);
1771 pad4->cd();
1772 hrt4->Divide(hrt3);
1773 DoDraw(hrt4);
1774 c1->cd();
1775 c1->Update();
1776}
1777
1778////////////////////////////////////////////////////////////////////////////////
1779/// Show MB processing rate plot per file vs time
1780
1782{
1783 // Create the histograms
1784 TObject *o = 0;
1785 if ((o = gDirectory->FindObject("rt1"))) delete o;
1786 TH1F *hrt1 = new TH1F("rt1", "Event processing rate per packet (evt/s)", 100, 0., fMaxTime);
1787 hrt1->SetMinimum(0.);
1788 hrt1->SetMaximum(1.05*fEvtRateMax);
1789 hrt1->SetStats(kFALSE);
1790 hrt1->GetXaxis()->SetTitle("Query Processing Time (s)");
1791 if ((o = gDirectory->FindObject("rt2"))) delete o;
1792 TH1F *hrt2 = new TH1F("rt2", "I/O processing rate per packet (MB/s)", 100, 0., fMaxTime);
1793 hrt2->SetMinimum(0.);
1794 hrt2->SetMaximum(1.05*fMBRateMax);
1795 hrt2->SetStats(kFALSE);
1796 hrt2->GetXaxis()->SetTitle("Query Processing Time (s)");
1797
1798 // Display histo frames
1799 TCanvas *c1 = new TCanvas("rates", GetCanvasTitle("Processing rates"), 800,10,700,780);
1800 c1->Divide(1,2);
1801 TPad *pad1 = (TPad *) c1->GetPad(1);
1802 pad1->cd();
1803 hrt1->Draw();
1804 TPad *pad2 = (TPad *) c1->GetPad(2);
1805 pad2->cd();
1806 hrt2->Draw();
1807 c1->cd();
1808 c1->Update();
1809
1810 // Which workers?
1811 THashList *fl = 0;
1812 TString fw(fns);
1813 if (!fw.IsNull() && fw != "*" && fw != "all") {
1814 TString w;
1815 Ssiz_t from = 0;
1816 while ((fw.Tokenize(w, from, ","))) {
1817 if (!fl) fl = new THashList();
1818 fl->Add(new TObjString(w.Data()));
1819 }
1820 }
1821
1822 // Now plot the graphs per worker
1823 Int_t ci = 40, cir = 30, ic = 0;
1824 TIter nxf(&fFilesInfo);
1825 TFileInfo *fi = 0;
1826 while ((fi = (TFileInfo *) nxf())) {
1827 if (fl && !fl->FindObject(fi->GetName())) continue;
1828 if (fi->fRateP && fi->fRateP->GetN() > 0) {
1829 fi->fRateP->SetNameTitle(fi->GetName(), fi->GetTitle());
1830 pad1->cd();
1831 fi->fRateP->SetLineColor(ci);
1832 DoDraw(fi->fRateP, "L", TString::Format("RateP-%d", ic));
1833 }
1834 if (fi->fRatePRemote && fi->fRatePRemote->GetN() > 0) {
1835 fi->fRatePRemote->SetNameTitle(fi->GetName(), fi->GetTitle());
1836 pad1->cd();
1837 fi->fRatePRemote->SetLineColor(cir);
1838 DoDraw(fi->fRatePRemote, "L", TString::Format("RatePRemote-%d", ic));
1839 }
1840 if (fi->fMBRateP && fi->fMBRateP->GetN() > 0) {
1841 fi->fMBRateP->SetNameTitle(fi->GetName(), fi->GetTitle());
1842 pad2->cd();
1843 fi->fMBRateP->SetLineColor(ci);
1844 DoDraw(fi->fMBRateP, "L", TString::Format("MBRateP-%d", ic));
1845 }
1846 if (fi->fMBRatePRemote && fi->fMBRatePRemote->GetN() > 0) {
1847 fi->fMBRatePRemote->SetNameTitle(fi->GetName(), fi->GetTitle());
1848 pad2->cd();
1849 fi->fMBRatePRemote->SetLineColor(cir);
1850 DoDraw(fi->fMBRatePRemote, "L", TString::Format("MBRatePRemote-%d", ic));
1851 }
1852 ic++;
1853 ci = ic%10 + 40;
1854 cir = ic%10 + 30;
1855 c1->cd();
1856 c1->Update();
1857 }
1858
1859 // Cleanup
1860 if (fl) {
1861 fl->SetOwner(kTRUE);
1862 delete fl;
1863 }
1864}
#define SafeDelete(p)
Definition RConfig.hxx:537
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define e(i)
Definition RSha256.hxx:103
const Ssiz_t kNPOS
Definition RtypesCore.h:124
const Bool_t kFALSE
Definition RtypesCore.h:101
bool Bool_t
Definition RtypesCore.h:63
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
const char Option_t
Definition RtypesCore.h:66
@ kCyan
Definition Rtypes.h:66
@ kBlue
Definition Rtypes.h:66
#define gDirectory
Definition TDirectory.h:385
char name[80]
Definition TGX11.cxx:110
void Printf(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition TStyle.h:413
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
Definition TAttAxis.cxx:302
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:37
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition TAxis.cxx:823
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:293
The Canvas class.
Definition TCanvas.h:23
virtual void ls(Option_t *option="") const
List (ls) all objects in this collection.
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Close(Option_t *option="")
Delete all objects from memory and directory structure itself.
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual TList * GetListOfKeys() const
Definition TDirectory.h:223
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4025
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:899
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2298
virtual void SetNameTitle(const char *name="", const char *title="")
Set graph name and title.
Definition TGraph.cxx:2373
Int_t GetN() const
Definition TGraph.h:125
virtual void Set(Int_t n)
Set number of points in the graph Existing coordinates are preserved New coordinates above fNpoints a...
Definition TGraph.cxx:2233
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:575
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:8767
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:8971
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition TH1.h:320
virtual Int_t GetNbinsX() const
Definition TH1.h:296
virtual void SetMaximum(Double_t maximum=-1111)
Definition TH1.h:398
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3351
TAxis * GetYaxis()
Definition TH1.h:321
virtual void SetMinimum(Double_t minimum=-1111)
Definition TH1.h:399
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:8982
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition TH1.cxx:3074
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:4994
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:8993
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
Definition TH1.cxx:2829
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:8820
2-D histogram with a float per channel (see TH1 documentation)}
Definition TH2.h:251
Int_t Fill(Double_t)
Invalid Fill method.
Definition TH2.cxx:358
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition THashList.h:34
TObject * FindObject(const char *name) const
Find object using its name.
void Reset()
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual const char * GetClassName() const
Definition TKey.h:76
A doubly linked list.
Definition TList.h:38
virtual void Add(TObject *obj)
Definition TList.h:81
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition TList.cxx:822
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition TList.cxx:196
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition TList.cxx:402
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
TString fTitle
Definition TNamed.h:33
TNamed()
Definition TNamed.h:36
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:868
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:393
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:766
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:267
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:622
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:72
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
The most important graphics class in the ROOT system.
Definition TPad.h:26
void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0) override
Automatic pad generation by division.
Definition TPad.cxx:1178
TVirtualPad * cd(Int_t subpadnumber=0) override
Set Current pad.
Definition TPad.cxx:604
TVirtualPad * GetPad(Int_t subpadnumber) const override
Get a pointer to subpadnumber of this pad.
Definition TPad.cxx:2911
TString fEvtNode
Definition TPerfStats.h:42
TString fSlaveName
Definition TPerfStats.h:45
Double_t fCpuTime
Definition TPerfStats.h:55
Double_t fLatency
Definition TPerfStats.h:53
TString fSlave
Definition TPerfStats.h:49
TString fFileName
Definition TPerfStats.h:47
TVirtualPerfStats::EEventType fType
Definition TPerfStats.h:44
Double_t fProcTime
Definition TPerfStats.h:54
Long64_t fBytesRead
Definition TPerfStats.h:51
TTimeStamp fTimeStamp
Definition TPerfStats.h:43
Long64_t fEventsProcessed
Definition TPerfStats.h:50
Int_t Compare(const TObject *o) const
Compare two TNamed objects.
void Print(Option_t *opt="") const
Print TNamed name and title.
TFileInfo(const char *name, const char *srv)
TPackInfo(const char *ord, const char *host)
void Print(Option_t *opt="") const
Print TNamed name and title.
TPackInfo(const char *ord, const char *host, Float_t start, Float_t stop, Long64_t sz, Double_t mbr)
void Print(Option_t *="") const
This method must be overridden when a class wants to print itself.
TWrkEntry(Double_t xx, Double_t er, Double_t mbr, Double_t pt)
void Print(Option_t *opt="") const
Print TNamed name and title.
TWrkInfoFile(const char *ord, const char *name)
void Print(Option_t *="") const
Print TNamed name and title.
Int_t Compare(const TObject *o) const
Compare two TNamed objects.
TWrkInfo(const char *ord, const char *name)
void FileRatePlot(const char *fns=0)
Show MB processing rate plot per file vs time.
void FileProcPlot(const char *fn, const char *out=0)
Show event processing or MB processing rate plot vs time.
void FillFileInfo(Bool_t force=kFALSE)
Fill basic worker info; if 'force' rescan the TTree even already done.
void SetDebug(Int_t d=0)
Static setter for the verbosity level.
TProofPerfAnalysis(const char *perffile, const char *title="", const char *treename="PROOF_PerfStats")
Constructor: open the file and attach to the tree.
void PrintWrkInfo(Int_t showlast=10)
Print information for all or the slowest showlast workers.
void LatencyPlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time Create the histograms.
void WorkerActivity()
Measure the worker activity.
void FileDist(Bool_t writedet=kFALSE)
Analyse the file distribution.
Int_t SetSaveResult(const char *file="results.root", Option_t *mode="RECREATE")
Set save result mode and validate 'file' according to 'mode'.
void GetWrkFileList(TList *wl, TList *sl)
Fill file info.
Bool_t WrkInfoOK() const
void EventDist()
Display event and packet distribution.
TString GetCanvasTitle(const char *t)
If defined, add '- <this title>' to the canvas title 't'.
static void SetgDebug(Bool_t on=kTRUE)
Static setter for the verbosity level.
Int_t CompareOrd(const char *ord1, const char *ord2)
Return -1 if ord1 comes before ord2, 0 i they are equal, 1 if ord1 comes after ord2.
void LoadTree(TDirectory *dir)
Load tree fTreeName from directory 'dir'.
void DoDraw(TObject *o, Option_t *opt="", const char *name=0)
Draw object 'o' with options 'opt' Save it with 'name' if in saving mode (see SetSaveResult)
void PrintFileInfo(Int_t showlast=10, const char *opt="", const char *out=0)
Print information for all or the slowest showlast workers.
void FillFileDistOneSrv(TH1F *hx, Bool_t wdet=kFALSE)
Fill file info when there is only one file server.
void FillWrkInfo(Bool_t force=kFALSE)
Fill basic worker info; if 'force' rescan the TTree even already done.
virtual ~TProofPerfAnalysis()
Destructor: detach the tree and close the file.
void Summary(Option_t *opt="", const char *out="")
Print summary of query.
void RatePlot(const char *wrks=0)
Show event processing or MB processing rate plot vs time.
void FillFileDist(TH1F *hf, TH1F *hb, TH2F *hx, Bool_t wdet=kFALSE)
Fill file info.
Regular expression class.
Definition TRegexp.h:31
void Add(TObject *obj)
Add object in sorted list.
Basic string class.
Definition TString.h:136
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1946
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition TString.h:682
const char * Data() const
Definition TString.h:369
@ kLeading
Definition TString.h:267
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2222
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
Bool_t IsNull() const
Definition TString.h:407
TString & Remove(Ssiz_t pos)
Definition TString.h:673
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:2336
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2314
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:639
Int_t GetOptStat() const
Definition TStyle.h:236
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition TStyle.cxx:1589
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition TSystem.cxx:1713
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:935
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
time_t GetSec() const
Definition TTimeStamp.h:135
Int_t GetNanoSec() const
Definition TTimeStamp.h:136
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition TTree.cxx:5622
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=0)
Change branch address, dealing with clone trees properly.
Definition TTree.cxx:8356
virtual Long64_t GetEntries() const
Definition TTree.h:460
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:389
const char * GetFile() const
Definition TUrl.h:69
const char * GetHost() const
Definition TUrl.h:67
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition TUrl.cxx:471
void Draw(Option_t *option="") override=0
Default Draw method for all objects.
TPaveText * pt
return c1
Definition legend1.C:41
const Int_t n
Definition legend1.C:16
return c2
Definition legend2.C:14
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Definition TMathBase.h:358
Definition file.py:1
Definition tree.py:1
auto * m
Definition textangle.C:8
auto * tt
Definition textangle.C:16
auto * t1
Definition textangle.C:20