// @(#)root/treeplayer:$Id$
// Author: Rene Brun 29/10/09

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
//                       TTreePerfStats
//
//        TTree I/O performance measurement. see example of use below.
//
// The function FileReadEvent is called from TFile::ReadBuffer.
// For each call the following information is stored in fGraphIO
//     - x[i]  = Tree entry number
//     - y[i]  = 1e-6*(file position)
//     - ey[i] = 1e-9*number of bytes read
// For each call the following information is stored in fGraphTime
//     - x[i]  = Tree entry number
//     - y[i]  = Time now
//     - ey[i] = readtime, eg timenow - start
// The TTreePerfStats object can be saved in a ROOT file in such a way that
// its inspection can be done outside the job that generated it.
//
//       Example of use
// {
//   TFile *f = TFile::Open("RelValMinBias-GEN-SIM-RECO.root");
//   T = (TTree*)f->Get("Events");
//   Long64_t nentries = T->GetEntries();
//   T->SetCacheSize(10000000);
//   T->SetCacheEntryRange(0,nentries);
//   T->AddBranchToCache("*");
//
//   TTreePerfStats *ps= new TTreePerfStats("ioperf",T);
//
//   for (Int_t i=0;i<nentries;i++) {
//      T->GetEntry(i);
//   }
//   ps->SaveAs("cmsperf.root");
// }
//
// then, in a root interactive session, one can do:
//    root > TFile f("cmsperf.root");
//    root > ioperf->Draw();
//    root > ioperf->Print();
//
// The Draw or Print functions print the following information:
//   TreeCache = TTree cache size in MBytes
//   N leaves  = Number of leaves in the TTree
//   ReadTotal = Total number of zipped bytes read
//   ReadUnZip = Total number of unzipped bytes read
//   ReadCalls = Total number of disk reads
//   ReadSize  = Average read size in KBytes
//   Readahead = Readahead size in KBytes
//   Readextra = Readahead overhead in percent
//   Real Time = Real Time in seconds
//   CPU  Time = CPU Time in seconds
//   Disk Time = Real Time spent in pure raw disk IO
//   Disk IO   = Raw disk IO speed in MBytes/second
//   ReadUZRT  = Unzipped MBytes per RT second
//   ReadUZCP  = Unipped MBytes per CP second
//   ReadRT    = Zipped MBytes per RT second
//   ReadCP    = Zipped MBytes per CP second
//
//   NOTE1 : The ReadTotal value indicates the effective number of zipped bytes
//           returned to the application. The physical number of bytes read
//           from the device (as measured for example with strace) is
//           ReadTotal +ReadTotal*Readextra/100. Same for ReadSize.
//
//   NOTE2 : A consequence of NOTE1, the Disk I/O speed corresponds to the effective
//           number of bytes returned to the application per second.
//           The Physical disk speed is DiskIO + DiskIO*ReadExtra/100.
//
//////////////////////////////////////////////////////////////////////////


#include "TTreePerfStats.h"
#include "TROOT.h"
#include "TSystem.h"
#include "Riostream.h"
#include "TFile.h"
#include "TTree.h"
#include "TAxis.h"
#include "TBrowser.h"
#include "TVirtualPad.h"
#include "TPaveText.h"
#include "TGraphErrors.h"
#include "TStopwatch.h"
#include "TGaxis.h"
#include "TTimeStamp.h"
#include "TDatime.h"
#include "TMath.h"

ClassImp(TTreePerfStats)

//______________________________________________________________________________
TTreePerfStats::TTreePerfStats() : TVirtualPerfStats()
{
   // default constructor (used when reading an object only)

   fName      = "";
   fHostInfo  = "";
   fTree      = 0;
   fNleaves   = 0;
   fFile      = 0;
   fGraphIO   = 0;
   fGraphTime = 0;
   fWatch     = 0;
   fPave      = 0;
   fTreeCacheSize = 0;
   fReadCalls     = 0;
   fReadaheadSize = 0;
   fBytesRead     = 0;
   fBytesReadExtra= 0;
   fRealNorm      = 0;
   fRealTime      = 0;
   fCpuTime       = 0;
   fDiskTime      = 0;
   fUnzipTime     = 0;
   fCompress      = 0;
   fRealTimeAxis  = 0;
   fHostInfoText  = 0;
}

//______________________________________________________________________________
TTreePerfStats::TTreePerfStats(const char *name, TTree *T) : TVirtualPerfStats()
{
   // Create a TTree I/O perf stats object.

   fName   = name;
   fTree   = T;
   T->SetPerfStats(this);
   fNleaves= T->GetListOfLeaves()->GetEntries();
   fFile   = T->GetCurrentFile();
   fGraphIO  = new TGraphErrors(0);
   fGraphIO->SetName("ioperf");
   fGraphIO->SetTitle(Form("%s/%s",fFile->GetName(),T->GetName()));
   fGraphIO->SetUniqueID(999999999);
   fGraphTime = new TGraphErrors(0);
   fGraphTime->SetLineColor(kRed);
   fGraphTime->SetName("iotime");
   fGraphTime->SetTitle("Real time vs entries");
   fWatch  = new TStopwatch();
   fWatch->Start();
   fPave  = 0;
   fTreeCacheSize = 0;
   fReadCalls     = 0;
   fReadaheadSize = 0;
   fBytesRead     = 0;
   fBytesReadExtra= 0;
   fRealNorm      = 0;
   fRealTime      = 0;
   fCpuTime       = 0;
   fDiskTime      = 0;
   fUnzipTime     = 0;
   fRealTimeAxis  = 0;
   fCompress      = (T->GetTotBytes()+0.00001)/T->GetZipBytes();

   Bool_t isUNIX = strcmp(gSystem->GetName(), "Unix") == 0;
   if (isUNIX)
      fHostInfo = gSystem->GetFromPipe("uname -a");
   else
      fHostInfo = "Windows ";
   fHostInfo.Resize(20);
   fHostInfo += TString::Format("ROOT %s, Git: %s", gROOT->GetVersion(), gROOT->GetGitCommit());
   TDatime dt;
   fHostInfo += TString::Format(" %s",dt.AsString());
   fHostInfoText   = 0;

   gPerfStats = this;
}

//______________________________________________________________________________
TTreePerfStats::~TTreePerfStats()
{
   // Destructor

   fTree = 0;
   fFile = 0;
   delete fGraphIO;
   delete fGraphTime;
   delete fPave;
   delete fWatch;
   delete fRealTimeAxis;
   delete fHostInfoText;

   if (gPerfStats == this) {
      gPerfStats = 0;
   }
}


//______________________________________________________________________________
void TTreePerfStats::Browse(TBrowser * /*b*/)
{
   // Browse

   Draw();
   gPad->Update();
}

//______________________________________________________________________________
Int_t TTreePerfStats::DistancetoPrimitive(Int_t px, Int_t py)
{
   // Return distance to one of the objects in the TTreePerfStats

   const Int_t kMaxDiff = 7;
   Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
   Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
   Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
   Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
   if (py < puymax) return 9999;
   //on the fGraphIO ?
   Int_t distance = fGraphIO->DistancetoPrimitive(px,py);
   if (distance <kMaxDiff) {if (px > puxmin && py < puymin) gPad->SetSelected(fGraphIO); return distance;}
   // on the fGraphTime ?
   distance = fGraphTime->DistancetoPrimitive(px,py);
   if (distance <kMaxDiff) {if (px > puxmin && py < puymin) gPad->SetSelected(fGraphTime); return distance;}
   // on the pave ?
   distance = fPave->DistancetoPrimitive(px,py);
   if (distance <kMaxDiff) {gPad->SetSelected(fPave);  return distance;}
   // on the real time axis ?
   distance = fRealTimeAxis->DistancetoPrimitive(px,py);
   if (distance <kMaxDiff) {gPad->SetSelected(fRealTimeAxis);  return distance;}
   // on the host info label ?
   distance = fHostInfoText->DistancetoPrimitive(px,py);
   if (distance <kMaxDiff) {gPad->SetSelected(fHostInfoText);  return distance;}
   if (px > puxmax-300) return 2;
   return 999;
}

//______________________________________________________________________________
void TTreePerfStats::Draw(Option_t *option)
{
   // Draw the TTree I/O perf graph.
   // by default the graph is drawn with option "al"
   // Specify option ="ap" to show only the read blocks and not the line
   // connecting the blocks

   Finish();

   TString opt = option;
   if (strlen(option)==0) opt = "al";
   opt.ToLower();
   if (gPad) {
      if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
      //the following statement is necessary in case one attempts to draw
      //a temporary histogram already in the current pad
      if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
   } else {
      gROOT->MakeDefCanvas();
   }
   if (opt.Contains("a")) {
      gPad->SetLeftMargin(0.35);
      gPad->Clear();
      gPad->SetGridx();
      gPad->SetGridy();
   }
   AppendPad(opt.Data());
}

//______________________________________________________________________________
void TTreePerfStats::ExecuteEvent(Int_t /*event*/, Int_t /*px*/, Int_t /*py*/)
{
   // Return distance to one of the objects in the TTreePerfStats

}

//______________________________________________________________________________
void TTreePerfStats::FileReadEvent(TFile *file, Int_t len, Double_t start)
{
   // Record TTree file read event.
   // start is the TimeStamp before reading
   // len is the number of bytes read

   if (file == this->fFile){
      Long64_t offset = file->GetRelOffset();
      Int_t np = fGraphIO->GetN();
      Int_t entry = fTree->GetReadEntry();
      fGraphIO->SetPoint(np,entry,1e-6*offset);
      fGraphIO->SetPointError(np,0.001,1e-9*len);
      Double_t tnow = TTimeStamp();
      Double_t dtime = tnow-start;
      fDiskTime += dtime;
      fGraphTime->SetPoint(np,entry,tnow);
      fGraphTime->SetPointError(np,0.001,dtime);
      fReadCalls++;
      fBytesRead += len;
   }
}


//______________________________________________________________________________
void TTreePerfStats::UnzipEvent(TObject * tree, Long64_t /* pos */, Double_t start, Int_t /* complen */, Int_t /* objlen */)
{
   // Record TTree unzip event.
   // start is the TimeStamp before unzip
   // pos is where in the file the compressed buffer came from
   // complen is the length of the compressed buffer
   // objlen is the length of the de-compressed buffer

   if (tree == this->fTree){
      Double_t tnow = TTimeStamp();
      Double_t dtime = tnow-start;
      fUnzipTime += dtime;
   }
}

//______________________________________________________________________________
void TTreePerfStats::Finish()
{
   // When the run is finished this function must be called
   // to save the current parameters in the file and Tree in this object
   // the function is automatically called by Draw and Print

   if (fRealNorm)   return;  //has already been called
   if (!fFile)      return;
   if (!fTree)      return;
   fTreeCacheSize = fTree->GetCacheSize();
   fReadaheadSize = TFile::GetReadaheadSize();
   fBytesReadExtra= fFile->GetBytesReadExtra();
   fRealTime      = fWatch->RealTime();
   fCpuTime       = fWatch->CpuTime();
   Int_t npoints  = fGraphIO->GetN();
   if (!npoints) return;
   Double_t iomax = TMath::MaxElement(npoints,fGraphIO->GetY());
   fRealNorm      = iomax/fRealTime;
   fGraphTime->GetY()[0] = fRealNorm*fGraphTime->GetEY()[0];
   // we normalize the fGraphTime such that it can be drawn on top of fGraphIO
   for (Int_t i=1;i<npoints;i++) {
      fGraphTime->GetY()[i]   = fGraphTime->GetY()[i-1] +fRealNorm*fGraphTime->GetEY()[i];
      fGraphTime->GetEY()[i]  = 0;
   }
}


//______________________________________________________________________________
void TTreePerfStats::Paint(Option_t *option)
{
   // Draw the TTree I/O perf graph.

   Int_t npoints  = fGraphIO->GetN();
   if (!npoints) return;
   Double_t iomax = fGraphIO->GetY()[npoints-1];
   Double_t toffset=1;
   if (iomax >= 1e9) toffset = 1.2;
   fGraphIO->GetXaxis()->SetTitle("Tree entry number");
   fGraphIO->GetYaxis()->SetTitle("file position (MBytes)  ");
   fGraphIO->GetYaxis()->SetTitleOffset(toffset);
   fGraphIO->GetXaxis()->SetLabelSize(0.03);
   fGraphIO->GetYaxis()->SetLabelSize(0.03);
   fGraphIO->Paint(option);

   TString opts(option);
   opts.ToLower();
   Bool_t unzip = opts.Contains("unzip");

   //superimpose the time info (max 10 points)
   if (fGraphTime) {
      fGraphTime->Paint("l");
      TText tdisk(fGraphTime->GetX()[npoints-1],1.1*fGraphTime->GetY()[npoints-1],"RAW IO");
      tdisk.SetTextAlign(31);
      tdisk.SetTextSize(0.03);
      tdisk.SetTextColor(kRed);
      tdisk.Paint();
      if (!fRealTimeAxis) {
         Double_t uxmax = gPad->GetUxmax();
         Double_t uymax = gPad->GetUymax();
         Double_t rtmax = uymax/fRealNorm;
         fRealTimeAxis = new TGaxis(uxmax,0,uxmax,uymax,0.,rtmax,510,"+L");
         fRealTimeAxis->SetName("RealTimeAxis");
         fRealTimeAxis->SetLineColor(kRed);
         fRealTimeAxis->SetTitle("RealTime (s)  ");
         fRealTimeAxis->SetTitleColor(kRed);
         toffset = 1;
         if (fRealTime >=  100) toffset = 1.2;
         if (fRealTime >= 1000) toffset = 1.4;
         fRealTimeAxis->SetTitleOffset(toffset);
         fRealTimeAxis->SetLabelSize(0.03);
         fRealTimeAxis->SetLabelColor(kRed);
      }
      fRealTimeAxis->Paint();
   }

   Double_t extra = 100.*fBytesReadExtra/fBytesRead;
   if (!fPave) {
      fPave = new TPaveText(.01,.10,.24,.90,"brNDC");
      fPave->SetTextAlign(12);
      fPave->AddText(Form("TreeCache = %d MB",fTreeCacheSize/1000000));
      fPave->AddText(Form("N leaves  = %d",fNleaves));
      fPave->AddText(Form("ReadTotal = %g MB",1e-6*fBytesRead));
      fPave->AddText(Form("ReadUnZip = %g MB",1e-6*fBytesRead*fCompress));
      fPave->AddText(Form("ReadCalls = %d",fReadCalls));
      fPave->AddText(Form("ReadSize  = %7.3f KB",0.001*fBytesRead/fReadCalls));
      fPave->AddText(Form("Readahead = %d KB",fReadaheadSize/1000));
      fPave->AddText(Form("Readextra = %5.2f per cent",extra));
      fPave->AddText(Form("Real Time = %7.3f s",fRealTime));
      fPave->AddText(Form("CPU  Time = %7.3f s",fCpuTime));
      fPave->AddText(Form("Disk Time = %7.3f s",fDiskTime));
      if (unzip) {
         fPave->AddText(Form("UnzipTime = %7.3f s",fUnzipTime));
      }
      fPave->AddText(Form("Disk IO   = %7.3f MB/s",1e-6*fBytesRead/fDiskTime));
      fPave->AddText(Form("ReadUZRT  = %7.3f MB/s",1e-6*fCompress*fBytesRead/fRealTime));
      fPave->AddText(Form("ReadUZCP  = %7.3f MB/s",1e-6*fCompress*fBytesRead/fCpuTime));
      fPave->AddText(Form("ReadRT    = %7.3f MB/s",1e-6*fBytesRead/fRealTime));
      fPave->AddText(Form("ReadCP    = %7.3f MB/s",1e-6*fBytesRead/fCpuTime));
   }
   fPave->Paint();

   if (!fHostInfoText) {
      fHostInfoText = new TText(0.01,0.01,fHostInfo.Data());
      fHostInfoText->SetNDC();
      fHostInfoText->SetTextSize(0.025);
   }
   fHostInfoText->Paint();
}

//______________________________________________________________________________
void TTreePerfStats::Print(Option_t * option) const
{
   // Print the TTree I/O perf stats.

   TString opts(option);
   opts.ToLower();
   Bool_t unzip = opts.Contains("unzip");
   TTreePerfStats *ps = (TTreePerfStats*)this;
   ps->Finish();

   Double_t extra = 100.*fBytesReadExtra/fBytesRead;
   printf("TreeCache = %d MBytes\n",Int_t(fTreeCacheSize/1000000));
   printf("N leaves  = %d\n",fNleaves);
   printf("ReadTotal = %g MBytes\n",1e-6*fBytesRead);
   printf("ReadUnZip = %g MBytes\n",1e-6*fBytesRead*fCompress);
   printf("ReadCalls = %d\n",fReadCalls);
   printf("ReadSize  = %7.3f KBytes/read\n",0.001*fBytesRead/fReadCalls);
   printf("Readahead = %d KBytes\n",fReadaheadSize/1000);
   printf("Readextra = %5.2f per cent\n",extra);
   printf("Real Time = %7.3f seconds\n",fRealTime);
   printf("CPU  Time = %7.3f seconds\n",fCpuTime);
   printf("Disk Time = %7.3f seconds\n",fDiskTime);
   if (unzip) {
      printf("Strm Time = %7.3f seconds\n",fCpuTime-fUnzipTime);
      printf("UnzipTime = %7.3f seconds\n",fUnzipTime);
   }
   printf("Disk IO   = %7.3f MBytes/s\n",1e-6*fBytesRead/fDiskTime);
   printf("ReadUZRT  = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/fRealTime);
   printf("ReadUZCP  = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/fCpuTime);
   printf("ReadRT    = %7.3f MBytes/s\n",1e-6*fBytesRead/fRealTime);
   printf("ReadCP    = %7.3f MBytes/s\n",1e-6*fBytesRead/fCpuTime);
   if (unzip) {
      printf("ReadStrCP = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/(fCpuTime-fUnzipTime));
      printf("ReadZipCP = %7.3f MBytes/s\n",1e-6*fCompress*fBytesRead/fUnzipTime);
   }
}

//______________________________________________________________________________
void TTreePerfStats::SaveAs(const char *filename, Option_t * /*option*/) const
{
   // Save this object to filename

   TTreePerfStats *ps = (TTreePerfStats*)this;
   ps->Finish();
   ps->TObject::SaveAs(filename);
}

//______________________________________________________________________________
void TTreePerfStats::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
{
    // Save primitive as a C++ statement(s) on output stream out

   char quote = '"';
   out<<"   "<<std::endl;
   if (gROOT->ClassSaved(TTreePerfStats::Class())) {
      out<<"   ";
   } else {
      out<<"   TTreePerfStats *";
   }
   out<<"ps = new TTreePerfStats();"<<std::endl;
   out<<"   ps->SetName("<<quote<<GetName()<<quote<<");"<<std::endl;
   out<<"   ps->SetHostInfo("<<quote<<GetHostInfo()<<quote<<");"<<std::endl;
   out<<"   ps->SetTreeCacheSize("<<fTreeCacheSize<<");"<<std::endl;
   out<<"   ps->SetNleaves("<<fNleaves<<");"<<std::endl;
   out<<"   ps->SetReadCalls("<<fReadCalls<<");"<<std::endl;
   out<<"   ps->SetReadaheadSize("<<fReadaheadSize<<");"<<std::endl;
   out<<"   ps->SetBytesRead("<<fBytesRead<<");"<<std::endl;
   out<<"   ps->SetBytesReadExtra("<<fBytesReadExtra<<");"<<std::endl;
   out<<"   ps->SetRealNorm("<<fRealNorm<<");"<<std::endl;
   out<<"   ps->SetRealTime("<<fRealTime<<");"<<std::endl;
   out<<"   ps->SetCpuTime("<<fCpuTime<<");"<<std::endl;
   out<<"   ps->SetDiskTime("<<fDiskTime<<");"<<std::endl;
   out<<"   ps->SetUnzipTime("<<fUnzipTime<<");"<<std::endl;
   out<<"   ps->SetCompress("<<fCompress<<");"<<std::endl;

   Int_t i, npoints = fGraphIO->GetN();
   out<<"   TGraphErrors *psGraphIO = new TGraphErrors("<<npoints<<");"<<std::endl;
   out<<"   psGraphIO->SetName("<<quote<<fGraphIO->GetName()<<quote<<");"<<std::endl;
   out<<"   psGraphIO->SetTitle("<<quote<<fGraphIO->GetTitle()<<quote<<");"<<std::endl;
   out<<"   ps->SetGraphIO(psGraphIO);"<<std::endl;
   fGraphIO->SaveFillAttributes(out,"psGraphIO",0,1001);
   fGraphIO->SaveLineAttributes(out,"psGraphIO",1,1,1);
   fGraphIO->SaveMarkerAttributes(out,"psGraphIO",1,1,1);
   for (i=0;i<npoints;i++) {
      out<<"   psGraphIO->SetPoint("<<i<<","<<fGraphIO->GetX()[i]<<","<<fGraphIO->GetY()[i]<<");"<<std::endl;
      out<<"   psGraphIO->SetPointError("<<i<<",0,"<<fGraphIO->GetEY()[i]<<");"<<std::endl;
   }
   npoints = fGraphTime->GetN();
   out<<"   TGraphErrors *psGraphTime = new TGraphErrors("<<npoints<<");"<<std::endl;
   out<<"   psGraphTime->SetName("<<quote<<fGraphTime->GetName()<<quote<<");"<<std::endl;
   out<<"   psGraphTime->SetTitle("<<quote<<fGraphTime->GetTitle()<<quote<<");"<<std::endl;
   out<<"   ps->SetGraphTime(psGraphTime);"<<std::endl;
   fGraphTime->SaveFillAttributes(out,"psGraphTime",0,1001);
   fGraphTime->SaveLineAttributes(out,"psGraphTime",1,1,1);
   fGraphTime->SaveMarkerAttributes(out,"psGraphTime",1,1,1);
   for (i=0;i<npoints;i++) {
      out<<"   psGraphTime->SetPoint("<<i<<","<<fGraphTime->GetX()[i]<<","<<fGraphTime->GetY()[i]<<");"<<std::endl;
      out<<"   psGraphTime->SetPointError("<<i<<",0,"<<fGraphTime->GetEY()[i]<<");"<<std::endl;
   }

   out<<"   ps->Draw("<<quote<<option<<quote<<");"<<std::endl;
}
 TTreePerfStats.cxx:1
 TTreePerfStats.cxx:2
 TTreePerfStats.cxx:3
 TTreePerfStats.cxx:4
 TTreePerfStats.cxx:5
 TTreePerfStats.cxx:6
 TTreePerfStats.cxx:7
 TTreePerfStats.cxx:8
 TTreePerfStats.cxx:9
 TTreePerfStats.cxx:10
 TTreePerfStats.cxx:11
 TTreePerfStats.cxx:12
 TTreePerfStats.cxx:13
 TTreePerfStats.cxx:14
 TTreePerfStats.cxx:15
 TTreePerfStats.cxx:16
 TTreePerfStats.cxx:17
 TTreePerfStats.cxx:18
 TTreePerfStats.cxx:19
 TTreePerfStats.cxx:20
 TTreePerfStats.cxx:21
 TTreePerfStats.cxx:22
 TTreePerfStats.cxx:23
 TTreePerfStats.cxx:24
 TTreePerfStats.cxx:25
 TTreePerfStats.cxx:26
 TTreePerfStats.cxx:27
 TTreePerfStats.cxx:28
 TTreePerfStats.cxx:29
 TTreePerfStats.cxx:30
 TTreePerfStats.cxx:31
 TTreePerfStats.cxx:32
 TTreePerfStats.cxx:33
 TTreePerfStats.cxx:34
 TTreePerfStats.cxx:35
 TTreePerfStats.cxx:36
 TTreePerfStats.cxx:37
 TTreePerfStats.cxx:38
 TTreePerfStats.cxx:39
 TTreePerfStats.cxx:40
 TTreePerfStats.cxx:41
 TTreePerfStats.cxx:42
 TTreePerfStats.cxx:43
 TTreePerfStats.cxx:44
 TTreePerfStats.cxx:45
 TTreePerfStats.cxx:46
 TTreePerfStats.cxx:47
 TTreePerfStats.cxx:48
 TTreePerfStats.cxx:49
 TTreePerfStats.cxx:50
 TTreePerfStats.cxx:51
 TTreePerfStats.cxx:52
 TTreePerfStats.cxx:53
 TTreePerfStats.cxx:54
 TTreePerfStats.cxx:55
 TTreePerfStats.cxx:56
 TTreePerfStats.cxx:57
 TTreePerfStats.cxx:58
 TTreePerfStats.cxx:59
 TTreePerfStats.cxx:60
 TTreePerfStats.cxx:61
 TTreePerfStats.cxx:62
 TTreePerfStats.cxx:63
 TTreePerfStats.cxx:64
 TTreePerfStats.cxx:65
 TTreePerfStats.cxx:66
 TTreePerfStats.cxx:67
 TTreePerfStats.cxx:68
 TTreePerfStats.cxx:69
 TTreePerfStats.cxx:70
 TTreePerfStats.cxx:71
 TTreePerfStats.cxx:72
 TTreePerfStats.cxx:73
 TTreePerfStats.cxx:74
 TTreePerfStats.cxx:75
 TTreePerfStats.cxx:76
 TTreePerfStats.cxx:77
 TTreePerfStats.cxx:78
 TTreePerfStats.cxx:79
 TTreePerfStats.cxx:80
 TTreePerfStats.cxx:81
 TTreePerfStats.cxx:82
 TTreePerfStats.cxx:83
 TTreePerfStats.cxx:84
 TTreePerfStats.cxx:85
 TTreePerfStats.cxx:86
 TTreePerfStats.cxx:87
 TTreePerfStats.cxx:88
 TTreePerfStats.cxx:89
 TTreePerfStats.cxx:90
 TTreePerfStats.cxx:91
 TTreePerfStats.cxx:92
 TTreePerfStats.cxx:93
 TTreePerfStats.cxx:94
 TTreePerfStats.cxx:95
 TTreePerfStats.cxx:96
 TTreePerfStats.cxx:97
 TTreePerfStats.cxx:98
 TTreePerfStats.cxx:99
 TTreePerfStats.cxx:100
 TTreePerfStats.cxx:101
 TTreePerfStats.cxx:102
 TTreePerfStats.cxx:103
 TTreePerfStats.cxx:104
 TTreePerfStats.cxx:105
 TTreePerfStats.cxx:106
 TTreePerfStats.cxx:107
 TTreePerfStats.cxx:108
 TTreePerfStats.cxx:109
 TTreePerfStats.cxx:110
 TTreePerfStats.cxx:111
 TTreePerfStats.cxx:112
 TTreePerfStats.cxx:113
 TTreePerfStats.cxx:114
 TTreePerfStats.cxx:115
 TTreePerfStats.cxx:116
 TTreePerfStats.cxx:117
 TTreePerfStats.cxx:118
 TTreePerfStats.cxx:119
 TTreePerfStats.cxx:120
 TTreePerfStats.cxx:121
 TTreePerfStats.cxx:122
 TTreePerfStats.cxx:123
 TTreePerfStats.cxx:124
 TTreePerfStats.cxx:125
 TTreePerfStats.cxx:126
 TTreePerfStats.cxx:127
 TTreePerfStats.cxx:128
 TTreePerfStats.cxx:129
 TTreePerfStats.cxx:130
 TTreePerfStats.cxx:131
 TTreePerfStats.cxx:132
 TTreePerfStats.cxx:133
 TTreePerfStats.cxx:134
 TTreePerfStats.cxx:135
 TTreePerfStats.cxx:136
 TTreePerfStats.cxx:137
 TTreePerfStats.cxx:138
 TTreePerfStats.cxx:139
 TTreePerfStats.cxx:140
 TTreePerfStats.cxx:141
 TTreePerfStats.cxx:142
 TTreePerfStats.cxx:143
 TTreePerfStats.cxx:144
 TTreePerfStats.cxx:145
 TTreePerfStats.cxx:146
 TTreePerfStats.cxx:147
 TTreePerfStats.cxx:148
 TTreePerfStats.cxx:149
 TTreePerfStats.cxx:150
 TTreePerfStats.cxx:151
 TTreePerfStats.cxx:152
 TTreePerfStats.cxx:153
 TTreePerfStats.cxx:154
 TTreePerfStats.cxx:155
 TTreePerfStats.cxx:156
 TTreePerfStats.cxx:157
 TTreePerfStats.cxx:158
 TTreePerfStats.cxx:159
 TTreePerfStats.cxx:160
 TTreePerfStats.cxx:161
 TTreePerfStats.cxx:162
 TTreePerfStats.cxx:163
 TTreePerfStats.cxx:164
 TTreePerfStats.cxx:165
 TTreePerfStats.cxx:166
 TTreePerfStats.cxx:167
 TTreePerfStats.cxx:168
 TTreePerfStats.cxx:169
 TTreePerfStats.cxx:170
 TTreePerfStats.cxx:171
 TTreePerfStats.cxx:172
 TTreePerfStats.cxx:173
 TTreePerfStats.cxx:174
 TTreePerfStats.cxx:175
 TTreePerfStats.cxx:176
 TTreePerfStats.cxx:177
 TTreePerfStats.cxx:178
 TTreePerfStats.cxx:179
 TTreePerfStats.cxx:180
 TTreePerfStats.cxx:181
 TTreePerfStats.cxx:182
 TTreePerfStats.cxx:183
 TTreePerfStats.cxx:184
 TTreePerfStats.cxx:185
 TTreePerfStats.cxx:186
 TTreePerfStats.cxx:187
 TTreePerfStats.cxx:188
 TTreePerfStats.cxx:189
 TTreePerfStats.cxx:190
 TTreePerfStats.cxx:191
 TTreePerfStats.cxx:192
 TTreePerfStats.cxx:193
 TTreePerfStats.cxx:194
 TTreePerfStats.cxx:195
 TTreePerfStats.cxx:196
 TTreePerfStats.cxx:197
 TTreePerfStats.cxx:198
 TTreePerfStats.cxx:199
 TTreePerfStats.cxx:200
 TTreePerfStats.cxx:201
 TTreePerfStats.cxx:202
 TTreePerfStats.cxx:203
 TTreePerfStats.cxx:204
 TTreePerfStats.cxx:205
 TTreePerfStats.cxx:206
 TTreePerfStats.cxx:207
 TTreePerfStats.cxx:208
 TTreePerfStats.cxx:209
 TTreePerfStats.cxx:210
 TTreePerfStats.cxx:211
 TTreePerfStats.cxx:212
 TTreePerfStats.cxx:213
 TTreePerfStats.cxx:214
 TTreePerfStats.cxx:215
 TTreePerfStats.cxx:216
 TTreePerfStats.cxx:217
 TTreePerfStats.cxx:218
 TTreePerfStats.cxx:219
 TTreePerfStats.cxx:220
 TTreePerfStats.cxx:221
 TTreePerfStats.cxx:222
 TTreePerfStats.cxx:223
 TTreePerfStats.cxx:224
 TTreePerfStats.cxx:225
 TTreePerfStats.cxx:226
 TTreePerfStats.cxx:227
 TTreePerfStats.cxx:228
 TTreePerfStats.cxx:229
 TTreePerfStats.cxx:230
 TTreePerfStats.cxx:231
 TTreePerfStats.cxx:232
 TTreePerfStats.cxx:233
 TTreePerfStats.cxx:234
 TTreePerfStats.cxx:235
 TTreePerfStats.cxx:236
 TTreePerfStats.cxx:237
 TTreePerfStats.cxx:238
 TTreePerfStats.cxx:239
 TTreePerfStats.cxx:240
 TTreePerfStats.cxx:241
 TTreePerfStats.cxx:242
 TTreePerfStats.cxx:243
 TTreePerfStats.cxx:244
 TTreePerfStats.cxx:245
 TTreePerfStats.cxx:246
 TTreePerfStats.cxx:247
 TTreePerfStats.cxx:248
 TTreePerfStats.cxx:249
 TTreePerfStats.cxx:250
 TTreePerfStats.cxx:251
 TTreePerfStats.cxx:252
 TTreePerfStats.cxx:253
 TTreePerfStats.cxx:254
 TTreePerfStats.cxx:255
 TTreePerfStats.cxx:256
 TTreePerfStats.cxx:257
 TTreePerfStats.cxx:258
 TTreePerfStats.cxx:259
 TTreePerfStats.cxx:260
 TTreePerfStats.cxx:261
 TTreePerfStats.cxx:262
 TTreePerfStats.cxx:263
 TTreePerfStats.cxx:264
 TTreePerfStats.cxx:265
 TTreePerfStats.cxx:266
 TTreePerfStats.cxx:267
 TTreePerfStats.cxx:268
 TTreePerfStats.cxx:269
 TTreePerfStats.cxx:270
 TTreePerfStats.cxx:271
 TTreePerfStats.cxx:272
 TTreePerfStats.cxx:273
 TTreePerfStats.cxx:274
 TTreePerfStats.cxx:275
 TTreePerfStats.cxx:276
 TTreePerfStats.cxx:277
 TTreePerfStats.cxx:278
 TTreePerfStats.cxx:279
 TTreePerfStats.cxx:280
 TTreePerfStats.cxx:281
 TTreePerfStats.cxx:282
 TTreePerfStats.cxx:283
 TTreePerfStats.cxx:284
 TTreePerfStats.cxx:285
 TTreePerfStats.cxx:286
 TTreePerfStats.cxx:287
 TTreePerfStats.cxx:288
 TTreePerfStats.cxx:289
 TTreePerfStats.cxx:290
 TTreePerfStats.cxx:291
 TTreePerfStats.cxx:292
 TTreePerfStats.cxx:293
 TTreePerfStats.cxx:294
 TTreePerfStats.cxx:295
 TTreePerfStats.cxx:296
 TTreePerfStats.cxx:297
 TTreePerfStats.cxx:298
 TTreePerfStats.cxx:299
 TTreePerfStats.cxx:300
 TTreePerfStats.cxx:301
 TTreePerfStats.cxx:302
 TTreePerfStats.cxx:303
 TTreePerfStats.cxx:304
 TTreePerfStats.cxx:305
 TTreePerfStats.cxx:306
 TTreePerfStats.cxx:307
 TTreePerfStats.cxx:308
 TTreePerfStats.cxx:309
 TTreePerfStats.cxx:310
 TTreePerfStats.cxx:311
 TTreePerfStats.cxx:312
 TTreePerfStats.cxx:313
 TTreePerfStats.cxx:314
 TTreePerfStats.cxx:315
 TTreePerfStats.cxx:316
 TTreePerfStats.cxx:317
 TTreePerfStats.cxx:318
 TTreePerfStats.cxx:319
 TTreePerfStats.cxx:320
 TTreePerfStats.cxx:321
 TTreePerfStats.cxx:322
 TTreePerfStats.cxx:323
 TTreePerfStats.cxx:324
 TTreePerfStats.cxx:325
 TTreePerfStats.cxx:326
 TTreePerfStats.cxx:327
 TTreePerfStats.cxx:328
 TTreePerfStats.cxx:329
 TTreePerfStats.cxx:330
 TTreePerfStats.cxx:331
 TTreePerfStats.cxx:332
 TTreePerfStats.cxx:333
 TTreePerfStats.cxx:334
 TTreePerfStats.cxx:335
 TTreePerfStats.cxx:336
 TTreePerfStats.cxx:337
 TTreePerfStats.cxx:338
 TTreePerfStats.cxx:339
 TTreePerfStats.cxx:340
 TTreePerfStats.cxx:341
 TTreePerfStats.cxx:342
 TTreePerfStats.cxx:343
 TTreePerfStats.cxx:344
 TTreePerfStats.cxx:345
 TTreePerfStats.cxx:346
 TTreePerfStats.cxx:347
 TTreePerfStats.cxx:348
 TTreePerfStats.cxx:349
 TTreePerfStats.cxx:350
 TTreePerfStats.cxx:351
 TTreePerfStats.cxx:352
 TTreePerfStats.cxx:353
 TTreePerfStats.cxx:354
 TTreePerfStats.cxx:355
 TTreePerfStats.cxx:356
 TTreePerfStats.cxx:357
 TTreePerfStats.cxx:358
 TTreePerfStats.cxx:359
 TTreePerfStats.cxx:360
 TTreePerfStats.cxx:361
 TTreePerfStats.cxx:362
 TTreePerfStats.cxx:363
 TTreePerfStats.cxx:364
 TTreePerfStats.cxx:365
 TTreePerfStats.cxx:366
 TTreePerfStats.cxx:367
 TTreePerfStats.cxx:368
 TTreePerfStats.cxx:369
 TTreePerfStats.cxx:370
 TTreePerfStats.cxx:371
 TTreePerfStats.cxx:372
 TTreePerfStats.cxx:373
 TTreePerfStats.cxx:374
 TTreePerfStats.cxx:375
 TTreePerfStats.cxx:376
 TTreePerfStats.cxx:377
 TTreePerfStats.cxx:378
 TTreePerfStats.cxx:379
 TTreePerfStats.cxx:380
 TTreePerfStats.cxx:381
 TTreePerfStats.cxx:382
 TTreePerfStats.cxx:383
 TTreePerfStats.cxx:384
 TTreePerfStats.cxx:385
 TTreePerfStats.cxx:386
 TTreePerfStats.cxx:387
 TTreePerfStats.cxx:388
 TTreePerfStats.cxx:389
 TTreePerfStats.cxx:390
 TTreePerfStats.cxx:391
 TTreePerfStats.cxx:392
 TTreePerfStats.cxx:393
 TTreePerfStats.cxx:394
 TTreePerfStats.cxx:395
 TTreePerfStats.cxx:396
 TTreePerfStats.cxx:397
 TTreePerfStats.cxx:398
 TTreePerfStats.cxx:399
 TTreePerfStats.cxx:400
 TTreePerfStats.cxx:401
 TTreePerfStats.cxx:402
 TTreePerfStats.cxx:403
 TTreePerfStats.cxx:404
 TTreePerfStats.cxx:405
 TTreePerfStats.cxx:406
 TTreePerfStats.cxx:407
 TTreePerfStats.cxx:408
 TTreePerfStats.cxx:409
 TTreePerfStats.cxx:410
 TTreePerfStats.cxx:411
 TTreePerfStats.cxx:412
 TTreePerfStats.cxx:413
 TTreePerfStats.cxx:414
 TTreePerfStats.cxx:415
 TTreePerfStats.cxx:416
 TTreePerfStats.cxx:417
 TTreePerfStats.cxx:418
 TTreePerfStats.cxx:419
 TTreePerfStats.cxx:420
 TTreePerfStats.cxx:421
 TTreePerfStats.cxx:422
 TTreePerfStats.cxx:423
 TTreePerfStats.cxx:424
 TTreePerfStats.cxx:425
 TTreePerfStats.cxx:426
 TTreePerfStats.cxx:427
 TTreePerfStats.cxx:428
 TTreePerfStats.cxx:429
 TTreePerfStats.cxx:430
 TTreePerfStats.cxx:431
 TTreePerfStats.cxx:432
 TTreePerfStats.cxx:433
 TTreePerfStats.cxx:434
 TTreePerfStats.cxx:435
 TTreePerfStats.cxx:436
 TTreePerfStats.cxx:437
 TTreePerfStats.cxx:438
 TTreePerfStats.cxx:439
 TTreePerfStats.cxx:440
 TTreePerfStats.cxx:441
 TTreePerfStats.cxx:442
 TTreePerfStats.cxx:443
 TTreePerfStats.cxx:444
 TTreePerfStats.cxx:445
 TTreePerfStats.cxx:446
 TTreePerfStats.cxx:447
 TTreePerfStats.cxx:448
 TTreePerfStats.cxx:449
 TTreePerfStats.cxx:450
 TTreePerfStats.cxx:451
 TTreePerfStats.cxx:452
 TTreePerfStats.cxx:453
 TTreePerfStats.cxx:454
 TTreePerfStats.cxx:455
 TTreePerfStats.cxx:456
 TTreePerfStats.cxx:457
 TTreePerfStats.cxx:458
 TTreePerfStats.cxx:459
 TTreePerfStats.cxx:460
 TTreePerfStats.cxx:461
 TTreePerfStats.cxx:462
 TTreePerfStats.cxx:463
 TTreePerfStats.cxx:464
 TTreePerfStats.cxx:465
 TTreePerfStats.cxx:466
 TTreePerfStats.cxx:467
 TTreePerfStats.cxx:468
 TTreePerfStats.cxx:469
 TTreePerfStats.cxx:470
 TTreePerfStats.cxx:471
 TTreePerfStats.cxx:472
 TTreePerfStats.cxx:473
 TTreePerfStats.cxx:474
 TTreePerfStats.cxx:475
 TTreePerfStats.cxx:476
 TTreePerfStats.cxx:477
 TTreePerfStats.cxx:478
 TTreePerfStats.cxx:479
 TTreePerfStats.cxx:480
 TTreePerfStats.cxx:481
 TTreePerfStats.cxx:482
 TTreePerfStats.cxx:483
 TTreePerfStats.cxx:484
 TTreePerfStats.cxx:485
 TTreePerfStats.cxx:486
 TTreePerfStats.cxx:487
 TTreePerfStats.cxx:488
 TTreePerfStats.cxx:489
 TTreePerfStats.cxx:490
 TTreePerfStats.cxx:491
 TTreePerfStats.cxx:492
 TTreePerfStats.cxx:493
 TTreePerfStats.cxx:494
 TTreePerfStats.cxx:495
 TTreePerfStats.cxx:496
 TTreePerfStats.cxx:497
 TTreePerfStats.cxx:498
 TTreePerfStats.cxx:499
 TTreePerfStats.cxx:500
 TTreePerfStats.cxx:501
 TTreePerfStats.cxx:502
 TTreePerfStats.cxx:503
 TTreePerfStats.cxx:504
 TTreePerfStats.cxx:505
 TTreePerfStats.cxx:506
 TTreePerfStats.cxx:507
 TTreePerfStats.cxx:508
 TTreePerfStats.cxx:509
 TTreePerfStats.cxx:510
 TTreePerfStats.cxx:511
 TTreePerfStats.cxx:512
 TTreePerfStats.cxx:513
 TTreePerfStats.cxx:514
 TTreePerfStats.cxx:515
 TTreePerfStats.cxx:516
 TTreePerfStats.cxx:517
 TTreePerfStats.cxx:518
 TTreePerfStats.cxx:519
 TTreePerfStats.cxx:520
 TTreePerfStats.cxx:521
 TTreePerfStats.cxx:522
 TTreePerfStats.cxx:523
 TTreePerfStats.cxx:524
 TTreePerfStats.cxx:525
 TTreePerfStats.cxx:526