00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #include "TTreePerfStats.h"
00083 #include "TROOT.h"
00084 #include "TSystem.h"
00085 #include "Riostream.h"
00086 #include "TFile.h"
00087 #include "TTree.h"
00088 #include "TAxis.h"
00089 #include "TBrowser.h"
00090 #include "TVirtualPad.h"
00091 #include "TPaveText.h"
00092 #include "TGraphErrors.h"
00093 #include "TStopwatch.h"
00094 #include "TGaxis.h"
00095 #include "TTimeStamp.h"
00096 #include "TDatime.h"
00097 #include "TMath.h"
00098
00099 const Double_t kScaleTime = 1e-20;
00100
00101 ClassImp(TTreePerfStats)
00102
00103
00104 TTreePerfStats::TTreePerfStats() : TVirtualPerfStats()
00105 {
00106
00107
00108 fName = "";
00109 fHostInfo = "";
00110 fTree = 0;
00111 fNleaves = 0;
00112 fFile = 0;
00113 fGraphIO = 0;
00114 fGraphTime = 0;
00115 fWatch = 0;
00116 fPave = 0;
00117 fTreeCacheSize = 0;
00118 fReadCalls = 0;
00119 fReadaheadSize = 0;
00120 fBytesRead = 0;
00121 fBytesReadExtra= 0;
00122 fRealNorm = 0;
00123 fRealTime = 0;
00124 fCpuTime = 0;
00125 fDiskTime = 0;
00126 fCompress = 0;
00127 fRealTimeAxis = 0;
00128 fHostInfoText = 0;
00129 }
00130
00131
00132 TTreePerfStats::TTreePerfStats(const char *name, TTree *T) : TVirtualPerfStats()
00133 {
00134
00135
00136 fName = name;
00137 fTree = T;
00138 fNleaves= T->GetListOfLeaves()->GetEntries();
00139 fFile = T->GetCurrentFile();
00140 fGraphIO = new TGraphErrors(0);
00141 fGraphIO->SetName("ioperf");
00142 fGraphIO->SetTitle(Form("%s/%s",fFile->GetName(),T->GetName()));
00143 fGraphIO->SetUniqueID(999999999);
00144 fGraphTime = new TGraphErrors(0);
00145 fGraphTime->SetLineColor(kRed);
00146 fGraphTime->SetName("iotime");
00147 fGraphTime->SetTitle("Real time vs entries");
00148 fWatch = new TStopwatch();
00149 fWatch->Start();
00150 fPave = 0;
00151 fTreeCacheSize = 0;
00152 fReadCalls = 0;
00153 fReadaheadSize = 0;
00154 fBytesRead = 0;
00155 fBytesReadExtra= 0;
00156 fRealNorm = 0;
00157 fRealTime = 0;
00158 fCpuTime = 0;
00159 fDiskTime = 0;
00160 fRealTimeAxis = 0;
00161 fCompress = (T->GetTotBytes()+0.00001)/T->GetZipBytes();
00162
00163 Bool_t isUNIX = strcmp(gSystem->GetName(), "Unix") == 0;
00164 if (isUNIX) fHostInfo = gSystem->GetFromPipe("uname -a");
00165 else fHostInfo = "Windows ";
00166 fHostInfo.Resize(20);
00167 fHostInfo += Form("Root%s, SVN :%d",gROOT->GetVersion(),gROOT->GetSvnRevision());
00168 TDatime dt;
00169 fHostInfo += Form(" %s",dt.AsString());
00170 fHostInfoText = 0;
00171
00172 gPerfStats = this;
00173 }
00174
00175
00176 TTreePerfStats::~TTreePerfStats()
00177 {
00178
00179
00180 fTree = 0;
00181 fFile = 0;
00182 delete fGraphIO;
00183 delete fGraphTime;
00184 delete fPave;
00185 delete fWatch;
00186 delete fRealTimeAxis;
00187 delete fHostInfoText;
00188
00189 if (gPerfStats == this) {
00190 gPerfStats = 0;
00191 }
00192 }
00193
00194
00195
00196 void TTreePerfStats::Browse(TBrowser * )
00197 {
00198
00199
00200 Draw();
00201 gPad->Update();
00202 }
00203
00204
00205 Int_t TTreePerfStats::DistancetoPrimitive(Int_t px, Int_t py)
00206 {
00207
00208
00209 const Int_t kMaxDiff = 7;
00210 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00211 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00212 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00213 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00214 if (py < puymax) return 9999;
00215
00216 Int_t distance = fGraphIO->DistancetoPrimitive(px,py);
00217 if (distance <kMaxDiff) {if (px > puxmin && py < puymin) gPad->SetSelected(fGraphIO); return distance;}
00218
00219 distance = fGraphTime->DistancetoPrimitive(px,py);
00220 if (distance <kMaxDiff) {if (px > puxmin && py < puymin) gPad->SetSelected(fGraphTime); return distance;}
00221
00222 distance = fPave->DistancetoPrimitive(px,py);
00223 if (distance <kMaxDiff) {gPad->SetSelected(fPave); return distance;}
00224
00225 distance = fRealTimeAxis->DistancetoPrimitive(px,py);
00226 if (distance <kMaxDiff) {gPad->SetSelected(fRealTimeAxis); return distance;}
00227
00228 distance = fHostInfoText->DistancetoPrimitive(px,py);
00229 if (distance <kMaxDiff) {gPad->SetSelected(fHostInfoText); return distance;}
00230 if (px > puxmax-300) return 2;
00231 return 999;
00232 }
00233
00234
00235 void TTreePerfStats::Draw(Option_t *option)
00236 {
00237
00238
00239
00240
00241
00242 Finish();
00243
00244 TString opt = option;
00245 if (strlen(option)==0) opt = "al";
00246 opt.ToLower();
00247 if (gPad) {
00248 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
00249
00250
00251 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
00252 } else {
00253 gROOT->MakeDefCanvas();
00254 }
00255 if (opt.Contains("a")) {
00256 gPad->SetLeftMargin(0.35);
00257 gPad->Clear();
00258 gPad->SetGridx();
00259 gPad->SetGridy();
00260 }
00261 AppendPad(opt.Data());
00262 }
00263
00264
00265 void TTreePerfStats::ExecuteEvent(Int_t , Int_t , Int_t )
00266 {
00267
00268
00269 }
00270
00271
00272 void TTreePerfStats::FileReadEvent(TFile *file, Int_t len, Double_t start)
00273 {
00274
00275
00276
00277
00278 Long64_t offset = file->GetRelOffset();
00279 Int_t np = fGraphIO->GetN();
00280 Int_t entry = fTree->GetReadEntry();
00281 fGraphIO->SetPoint(np,entry,1e-6*offset);
00282 fGraphIO->SetPointError(np,0.001,1e-9*len);
00283 Double_t tnow = TTimeStamp();
00284 Double_t dtime = tnow-start;
00285 fDiskTime += dtime;
00286 fGraphTime->SetPoint(np,entry,tnow);
00287 fGraphTime->SetPointError(np,0.001,dtime);
00288 }
00289
00290
00291 void TTreePerfStats::Finish()
00292 {
00293
00294
00295
00296
00297 if (fReadCalls) return;
00298 if (!fFile) return;
00299 if (!fTree) return;
00300 fReadCalls = fFile->GetReadCalls();
00301 fTreeCacheSize = fTree->GetCacheSize();
00302 fReadaheadSize = TFile::GetReadaheadSize();
00303 fBytesRead = fFile->GetBytesRead();
00304 fBytesReadExtra= fFile->GetBytesReadExtra();
00305 fRealTime = fWatch->RealTime();
00306 fCpuTime = fWatch->CpuTime();
00307 Int_t npoints = fGraphIO->GetN();
00308 if (!npoints) return;
00309 Double_t iomax = TMath::MaxElement(npoints,fGraphIO->GetY());
00310 fRealNorm = iomax/fRealTime;
00311 fGraphTime->GetY()[0] = fRealNorm*fGraphTime->GetEY()[0];
00312
00313 for (Int_t i=1;i<npoints;i++) {
00314 fGraphTime->GetY()[i] = fGraphTime->GetY()[i-1] +fRealNorm*fGraphTime->GetEY()[i];
00315 fGraphTime->GetEY()[i] = 0;
00316 }
00317 }
00318
00319
00320
00321 void TTreePerfStats::Paint(Option_t *option)
00322 {
00323
00324
00325 Int_t npoints = fGraphIO->GetN();
00326 if (!npoints) return;
00327 Double_t iomax = fGraphIO->GetY()[npoints-1];
00328 Double_t toffset=1;
00329 if (iomax >= 1e9) toffset = 1.2;
00330 fGraphIO->GetXaxis()->SetTitle("Tree entry number");
00331 fGraphIO->GetYaxis()->SetTitle("file position (MBytes) ");
00332 fGraphIO->GetYaxis()->SetTitleOffset(toffset);
00333 fGraphIO->GetXaxis()->SetLabelSize(0.03);
00334 fGraphIO->GetYaxis()->SetLabelSize(0.03);
00335 fGraphIO->Paint(option);
00336
00337
00338 if (fGraphTime) {
00339 fGraphTime->Paint("l");
00340 TText tdisk(fGraphTime->GetX()[npoints-1],1.1*fGraphTime->GetY()[npoints-1],"RAW IO");
00341 tdisk.SetTextAlign(31);
00342 tdisk.SetTextSize(0.03);
00343 tdisk.SetTextColor(kRed);
00344 tdisk.Paint();
00345 if (!fRealTimeAxis) {
00346 Double_t uxmax = gPad->GetUxmax();
00347 Double_t uymax = gPad->GetUymax();
00348 Double_t rtmax = uymax/fRealNorm;
00349 fRealTimeAxis = new TGaxis(uxmax,0,uxmax,uymax,0.,rtmax,510,"+L");
00350 fRealTimeAxis->SetName("RealTimeAxis");
00351 fRealTimeAxis->SetLineColor(kRed);
00352 fRealTimeAxis->SetTitle("RealTime (s) ");
00353 fRealTimeAxis->SetTitleColor(kRed);
00354 toffset = 1;
00355 if (fRealTime >= 100) toffset = 1.2;
00356 if (fRealTime >= 1000) toffset = 1.4;
00357 fRealTimeAxis->SetTitleOffset(toffset);
00358 fRealTimeAxis->SetLabelSize(0.03);
00359 fRealTimeAxis->SetLabelColor(kRed);
00360 }
00361 fRealTimeAxis->Paint();
00362 }
00363
00364 Double_t extra = 100.*fBytesReadExtra/fBytesRead;
00365 if (!fPave) {
00366 fPave = new TPaveText(.01,.10,.24,.90,"brNDC");
00367 fPave->SetTextAlign(12);
00368 fPave->AddText(Form("TreeCache = %d MB",fTreeCacheSize/1000000));
00369 fPave->AddText(Form("N leaves = %d",fNleaves));
00370 fPave->AddText(Form("ReadTotal = %g MB",1e-6*fBytesRead));
00371 fPave->AddText(Form("ReadUnZip = %g MB",1e-6*fBytesRead*fCompress));
00372 fPave->AddText(Form("ReadCalls = %d",fReadCalls));
00373 fPave->AddText(Form("ReadSize = %7.3f KB",0.001*fBytesRead/fReadCalls));
00374 fPave->AddText(Form("Readahead = %d KB",fReadaheadSize/1000));
00375 fPave->AddText(Form("Readextra = %5.2f per cent",extra));
00376 fPave->AddText(Form("Real Time = %7.3f s",fRealTime));
00377 fPave->AddText(Form("CPU Time = %7.3f s",fCpuTime));
00378 fPave->AddText(Form("Disk Time = %7.3f s",fDiskTime));
00379 fPave->AddText(Form("Disk IO = %7.3f MB/s",1e-6*fBytesRead/fDiskTime));
00380 fPave->AddText(Form("ReadUZRT = %7.3f MB/s",1e-6*fCompress*fBytesRead/fRealTime));
00381 fPave->AddText(Form("ReadUZCP = %7.3f MB/s",1e-6*fCompress*fBytesRead/fCpuTime));
00382 fPave->AddText(Form("ReadRT = %7.3f MB/s",1e-6*fBytesRead/fRealTime));
00383 fPave->AddText(Form("ReadCP = %7.3f MB/s",1e-6*fBytesRead/fCpuTime));
00384 }
00385 fPave->Paint();
00386
00387 if (!fHostInfoText) {
00388 fHostInfoText = new TText(0.01,0.01,fHostInfo.Data());
00389 fHostInfoText->SetNDC();
00390 fHostInfoText->SetTextSize(0.025);
00391 }
00392 fHostInfoText->Paint();
00393 }
00394
00395
00396 void TTreePerfStats::Print(Option_t * ) const
00397 {
00398
00399
00400 TTreePerfStats *ps = (TTreePerfStats*)this;
00401 ps->Finish();
00402
00403 Double_t extra = 100.*fBytesReadExtra/fBytesRead;
00404 printf("TreeCache = %d MBytes\n",Int_t(fTreeCacheSize/1000000));
00405 printf("N leaves = %d\n",fNleaves);
00406 printf("ReadTotal = %g MBytes\n",1e-6*fBytesRead);
00407 printf("ReadUnZip = %g MBytes\n",1e-6*fBytesRead*fCompress);
00408 printf("ReadCalls = %d\n",fReadCalls);
00409 printf("ReadSize = %7.3f KBytes/read\n",0.001*fBytesRead/fReadCalls);
00410 printf("Readahead = %d KBytes\n",fReadaheadSize/1000);
00411 printf("Readextra = %5.2f per cent\n",extra);
00412 printf("Real Time = %7.3f seconds\n",fRealTime);
00413 printf("CPU Time = %7.3f seconds\n",fCpuTime);
00414 printf("Disk Time = %7.3f seconds\n",fDiskTime);
00415 printf("Disk IO = %7.3f MBytes/s\n",1e-6*fBytesRead/fDiskTime);
00416 printf("ReadUZRT = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/fRealTime);
00417 printf("ReadUZCP = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/fCpuTime);
00418 printf("ReadRT = %7.3f MBytes/s\n",1e-6*fBytesRead/fRealTime);
00419 printf("ReadCP = %7.3f MBytes/s\n",1e-6*fBytesRead/fCpuTime);
00420 }
00421
00422
00423 void TTreePerfStats::SaveAs(const char *filename, Option_t * ) const
00424 {
00425
00426
00427 TTreePerfStats *ps = (TTreePerfStats*)this;
00428 ps->Finish();
00429 ps->TObject::SaveAs(filename);
00430 }
00431
00432
00433 void TTreePerfStats::SavePrimitive(ostream &out, Option_t *option )
00434 {
00435
00436
00437 char quote = '"';
00438 out<<" "<<endl;
00439 if (gROOT->ClassSaved(TTreePerfStats::Class())) {
00440 out<<" ";
00441 } else {
00442 out<<" TTreePerfStats *";
00443 }
00444 out<<"ps = new TTreePerfStats();"<<endl;
00445 out<<" ps->SetName("<<quote<<GetName()<<quote<<");"<<endl;
00446 out<<" ps->SetHostInfo("<<quote<<GetHostInfo()<<quote<<");"<<endl;
00447 out<<" ps->SetTreeCacheSize("<<fTreeCacheSize<<");"<<endl;
00448 out<<" ps->SetNleaves("<<fNleaves<<");"<<endl;
00449 out<<" ps->SetReadCalls("<<fReadCalls<<");"<<endl;
00450 out<<" ps->SetReadaheadSize("<<fReadaheadSize<<");"<<endl;
00451 out<<" ps->SetBytesRead("<<fBytesRead<<");"<<endl;
00452 out<<" ps->SetBytesReadExtra("<<fBytesReadExtra<<");"<<endl;
00453 out<<" ps->SetRealNorm("<<fRealNorm<<");"<<endl;
00454 out<<" ps->SetRealTime("<<fRealTime<<");"<<endl;
00455 out<<" ps->SetCpuTime("<<fCpuTime<<");"<<endl;
00456 out<<" ps->SetDiskTime("<<fDiskTime<<");"<<endl;
00457 out<<" ps->SetCompress("<<fCompress<<");"<<endl;
00458
00459 Int_t i, npoints = fGraphIO->GetN();
00460 out<<" TGraphErrors *psGraphIO = new TGraphErrors("<<npoints<<");"<<endl;
00461 out<<" psGraphIO->SetName("<<quote<<fGraphIO->GetName()<<quote<<");"<<endl;
00462 out<<" psGraphIO->SetTitle("<<quote<<fGraphIO->GetTitle()<<quote<<");"<<endl;
00463 out<<" ps->SetGraphIO(psGraphIO);"<<endl;
00464 fGraphIO->SaveFillAttributes(out,"psGraphIO",0,1001);
00465 fGraphIO->SaveLineAttributes(out,"psGraphIO",1,1,1);
00466 fGraphIO->SaveMarkerAttributes(out,"psGraphIO",1,1,1);
00467 for (i=0;i<npoints;i++) {
00468 out<<" psGraphIO->SetPoint("<<i<<","<<fGraphIO->GetX()[i]<<","<<fGraphIO->GetY()[i]<<");"<<endl;
00469 out<<" psGraphIO->SetPointError("<<i<<",0,"<<fGraphIO->GetEY()[i]<<");"<<endl;
00470 }
00471 npoints = fGraphTime->GetN();
00472 out<<" TGraphErrors *psGraphTime = new TGraphErrors("<<npoints<<");"<<endl;
00473 out<<" psGraphTime->SetName("<<quote<<fGraphTime->GetName()<<quote<<");"<<endl;
00474 out<<" psGraphTime->SetTitle("<<quote<<fGraphTime->GetTitle()<<quote<<");"<<endl;
00475 out<<" ps->SetGraphTime(psGraphTime);"<<endl;
00476 fGraphTime->SaveFillAttributes(out,"psGraphTime",0,1001);
00477 fGraphTime->SaveLineAttributes(out,"psGraphTime",1,1,1);
00478 fGraphTime->SaveMarkerAttributes(out,"psGraphTime",1,1,1);
00479 for (i=0;i<npoints;i++) {
00480 out<<" psGraphTime->SetPoint("<<i<<","<<fGraphTime->GetX()[i]<<","<<fGraphTime->GetY()[i]<<");"<<endl;
00481 out<<" psGraphTime->SetPointError("<<i<<",0,"<<fGraphTime->GetEY()[i]<<");"<<endl;
00482 }
00483
00484 out<<" ps->Draw("<<quote<<option<<quote<<");"<<endl;
00485 }