// @(#)root/proof:$Id$
// Author: G.Ganis, S.Ryu Feb 2011

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofBench                                                          //
//                                                                      //
// Steering class for PROOF benchmarks                                  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "RConfigure.h"

#include "TProofBench.h"
#include "Getline.h"
#include "TProofBenchRunCPU.h"
#include "TProofBenchRunDataRead.h"
#include "TProofBenchDataSet.h"
#include "TProofNodes.h"
#include "TClass.h"
#include "TFile.h"
#include "TFileCollection.h"
#include "TFileInfo.h"
#include "THashList.h"
#include "TKey.h"
#include "TObjString.h"
#include "TProof.h"
#include "TROOT.h"
#include "TSortedList.h"
#include "TTimeStamp.h"
#include "TUrl.h"

#include "TCanvas.h"
#include "TF1.h"
#include "TGraphErrors.h"
#include "TH1F.h"
#include "TMath.h"
#include "TProfile.h"
#include "TStyle.h"
#include "TLegend.h"
#ifdef WIN32
#include <io.h>
#endif

ClassImp(TProofBench)

// Functions for fitting

TF1 *TProofBench::fgFp1 = 0;
TF1 *TProofBench::fgFp1n = 0;
TF1 *TProofBench::fgFp2 = 0;
TF1 *TProofBench::fgFp2n = 0;
TF1 *TProofBench::fgFp3 = 0;
TF1 *TProofBench::fgFp3n = 0;
TF1 *TProofBench::fgFio = 0;
TF1 *TProofBench::fgFioV = 0;
static Int_t gFioVn0 = -1;             // Number of real cores for fgFioV
static Int_t gFioVn1 = -1;             // Number of real+hyper cores for fgFioV

TList *TProofBench::fgGraphs = new TList;

//_____________________________________________________________________
Double_t funp1(Double_t *xx, Double_t *par)
{
   // Simple polynomial 1st degree

   Double_t res = par[0] + par[1] * xx[0];
   return res;
}

//_____________________________________________________________________
Double_t funp2(Double_t *xx, Double_t *par)
{
   // Simple polynomial 2nd degree

   Double_t res = par[0] + par[1] * xx[0] + par[2] * xx[0] * xx[0];
   return res;
}

//_____________________________________________________________________
Double_t funp1n(Double_t *xx, Double_t *par)
{
   // Normalized 1st degree

   Double_t res = par[0] / xx[0] + par[1];
   return res;
}

//_____________________________________________________________________
Double_t funp2n(Double_t *xx, Double_t *par)
{
   // Normalized 2nd degree

   Double_t res = par[0] / xx[0] + par[1] + par[2] * xx[0];
   return res;
}

//_____________________________________________________________________
Double_t funio(Double_t *xx, Double_t *par)
{
   // I/O saturated rate function

   Double_t sat = par[0] / par[1] * (xx[0] * par[1] / par[2] - 1.);
   if (xx[0] < par[2] / par[1]) sat = 0.;
   Double_t res = par[0] * xx[0] / (1. + sat);
   return res;
}

//_____________________________________________________________________
Double_t funiov(Double_t *xx, Double_t *par)
{
   // I/O saturated rate function with varying Rcpu

   // par[0] = rio
   // par[1] = b1
   // par[2] = b2
   // par[3] = nc
   // par[4] = ri

   Double_t rio = par[0] / par[3] * xx[0];
   if (xx[0] > par[3]) rio = par[0];

   Double_t rcpu = par[1] * xx[0];
   if (xx[0] > gFioVn0) rcpu = par[1]*gFioVn0 + par[2]*(xx[0] - gFioVn0);
   if (xx[0] > gFioVn1) rcpu = par[1]*gFioVn0 + par[2]*(gFioVn1 - gFioVn0);

   Double_t res = 1. / (1./par[4] + 1./rio + 1./rcpu);

   return res;
}

//_____________________________________________________________________
Double_t funcpuv(Double_t *xx, Double_t *par)
{
   // Function with varying Rcpu

   // par[0] = offset
   // par[1] = rate contribution from real cores
   // par[2] = rate contribution from hyper cores

   Double_t n = (xx[0] - par[0]);
   Double_t rcpu = par[1] * n;
   if (xx[0] > gFioVn0) rcpu = par[1]*gFioVn0 + par[2]*(n - gFioVn0);
   if (xx[0] > gFioVn1) rcpu = par[1]*gFioVn0 + par[2]*(gFioVn1 - gFioVn0);

   return rcpu;
}

//_____________________________________________________________________
Double_t funcpuvn(Double_t *xx, Double_t *par)
{
   // Function with varying Rcpu normalized

   // par[0] = offset
   // par[1] = rate contribution from real cores
   // par[2] = rate contribution from hyper cores

   Double_t n = (xx[0] - par[0]);
   Double_t rcpu = par[1] * n;
   if (xx[0] > gFioVn0) rcpu = par[1]*gFioVn0 + par[2]*(n - gFioVn0);
   if (xx[0] > gFioVn1) rcpu = par[1]*gFioVn0 + par[2]*(gFioVn1 - gFioVn0);

   return rcpu / xx[0];
}

//______________________________________________________________________________
TProofBench::TProofBench(const char *url, const char *outfile, const char *proofopt)
            : fUnlinkOutfile(kFALSE), fProofDS(0), fOutFile(0),
              fNtries(4), fHistType(0), fNHist(16), fReadType(0),
              fDataSet("BenchDataSet"), fNFilesWrk(2), fReleaseCache(kTRUE),
              fDataGenSel(kPROOF_BenchSelDataGenDef),
              fRunCPU(0), fRunDS(0), fDS(0), fDebug(kFALSE), fDescription(0)
{
   // Constructor: check PROOF and load selectors PAR

   SetBit(kInvalidObject);
   if (!url) {
      Error("TProofBench", "specifying a PROOF master url is mandatory - cannot continue");
      return;
   }
   if (!(fProof = TProof::Open(url, proofopt)) || (fProof && !fProof->IsValid())) {
      Error("TProofBench", "could not open a valid PROOF session - cannot continue");
      return;
   }
   // Get the size of the cluster
   fNumWrkMax = fProof->GetParallel();
   if (fProof->UseDynamicStartup() && TProof::GetEnvVars()) {
      // It must be passed as PROOF option 'workers=N' and recorded in the envs vars
      TNamed *n = (TNamed *) TProof::GetEnvVars()->FindObject("PROOF_NWORKERS");
      if (!n) {
         Error("TProofBench", "dynamic mode: you must specify the max number of workers");
         fProof->Close();
         SafeDelete(fProof);
         return;
      }
      TString sn(n->GetTitle());
      if (sn.IsDigit()) fNumWrkMax = sn.Atoi();
      if (!sn.IsDigit()) {
         Error("TProofBench", "dynamic mode: wrong specification of the max number of"
                              " workers ('%s')", n->GetTitle());
         fProof->Close();
         SafeDelete(fProof);
         return;
      }
   }
   if (fNumWrkMax <= 0) {
      Error("TProofBench", "wrong max number of workers ('%d')", fNumWrkMax);
      fProof->Close();
      SafeDelete(fProof);
      return;
   }
   // By default we use the same instance for dataset actions
   fProofDS = fProof;
   // The object is now valid
   ResetBit(kInvalidObject);
   // Identifying string
   TUrl u(url);
   TString host(TString::Format("PROOF at %s", u.GetHost()));
   if (!strcmp(u.GetProtocol(), "lite")) host.Form("PROOF-Lite on %s", gSystem->HostName());
   fDescription = new TNamed("PB_description",
                             TString::Format("%s, %d workers", host.Data(), fNumWrkMax).Data());
   Printf(" Run description: %s", fDescription->GetTitle());
   // Set output file
   if (SetOutFile(outfile, kFALSE) != 0)
      Warning("TProofBench", "problems opening '%s' - ignoring: use SetOutFile to try"
                                   " again or with another file", outfile);
}

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

   CloseOutFile();
   if (fUnlinkOutfile) gSystem->Unlink(fOutFileName);
   SafeDelete(fReadType);
   SafeDelete(fRunCPU);
   SafeDelete(fRunDS);
   SafeDelete(fDescription);
}

//______________________________________________________________________________
Int_t TProofBench::OpenOutFile(Bool_t wrt, Bool_t verbose)
{
   // Set the otuput file
   // Return 0 on success, -1 on error

   // Remove any bad file
   if (fOutFile && fOutFile->IsZombie()) SafeDelete(fOutFile);

   Int_t rc = 0;
   if (!fOutFile && fOutFileName.Length() > 0) {
      const char *mode = 0;
      if (wrt)
         mode = gSystem->AccessPathName(fOutFileName) ? "RECREATE" : "UPDATE";
      else
         mode = "READ";
      if (!(fOutFile = TFile::Open(fOutFileName, mode)) || (fOutFile && fOutFile->IsZombie())) {
         if (verbose)
            Warning("OpenOutFile", "problems opening '%s' - ignoring: use SetOutFile to try"
                                   " again or with another file", fOutFileName.Data());
         rc = -1;
      }
      if (fOutFile) {
         gROOT->GetListOfFiles()->Remove(fOutFile);
         if (!strcmp(mode, "RECREATE")) {
            // Save the description string
            fOutFile->cd();
            fDescription->Write();
         }
      }
   }
   return rc;
}

//______________________________________________________________________________
Int_t TProofBench::SetOutFile(const char *outfile, Bool_t verbose)
{
   // Set the output file
   // Return 0 on success, -1 on error

   Int_t rc = 0;
   // Close existing file, if any
   if (fOutFile) {
      if (!fOutFile->IsZombie()) fOutFile->Close();
      SafeDelete(fOutFile);
   }

   fOutFileName = outfile;
   if (fOutFileName == "<default>") {
      // Default output file: proofbench-<master>-<DayMonthYear-hhmm>.root
      TDatime dat;
      const char *lite = (fProof->IsLite()) ? "-lite" : "";
      fOutFileName.Form("proofbench-%s%s-%dw-%d-%.2d%.2d.root",
                        fProof->GetMaster(), lite, fNumWrkMax,
                        dat.GetDate(), dat.GetHour(), dat.GetMinute());
      Info("SetOutFile", "using default output file: '%s'", fOutFileName.Data());
      fUnlinkOutfile = kTRUE;
   }
   if (!fOutFileName.IsNull()) {
      if ((rc = OpenOutFile(kTRUE, kFALSE)) != 0 && verbose)
         Warning("SetOutFile", "problems opening '%s' - ignoring: use SetOutFile to try"
                               " again or with another file", outfile);
   }
   return rc;
}

//______________________________________________________________________________
void TProofBench::CloseOutFile()
{
   // Close output file

   if (SetOutFile(0) != 0)
      Warning("CloseOutFile", "problems closing '%s'", fOutFileName.Data());
}

//______________________________________________________________________________
Int_t TProofBench::RunCPU(Long64_t nevents, Int_t start, Int_t stop, Int_t step)
{
   // Perform the CPU run
   // Return 0 on success, -1 on error

   // Open the file for the results
   if (OpenOutFile(kTRUE) != 0) {
      Error("RunCPU", "problems opening '%s' to save the result", fOutFileName.Data());
      return -1;
   }
   fUnlinkOutfile = kFALSE;

   SafeDelete(fRunCPU);
   TPBHistType *htype = new TPBHistType(TPBHistType::kHist1D); // Owned by the input list
   fRunCPU = new TProofBenchRunCPU(htype, fNHist, fOutFile);
   if (!fCPUSel.IsNull()) fRunCPU->SetSelName(fCPUSel);
   if (!fSelOption.IsNull()) fRunDS->SetSelOption(fSelOption);
   if (!fCPUPar.IsNull()) fRunCPU->SetParList(fCPUPar);
   fRunCPU->Run(nevents, start, stop, step, fNtries, fDebug, -1);

   // Close the file
   if (SetOutFile(0) != 0)
      Warning("RunCPU", "problems closing '%s'", fOutFileName.Data());

   // Done
   return 0;
}

//______________________________________________________________________________
Int_t TProofBench::RunCPUx(Long64_t nevents, Int_t start, Int_t stop)
{
   // Perform the CPU run scanning over the number of workers per node
   // Return 0 on success, -1 on error

   // Open the file for the results
   if (OpenOutFile(kTRUE) != 0) {
      Error("RunCPUx", "problems opening '%s' to save the result", fOutFileName.Data());
      return -1;
   }
   fUnlinkOutfile = kFALSE;

   SafeDelete(fRunCPU);
   TPBHistType *htype = new TPBHistType(TPBHistType::kHist1D); // Owned by the input list
   fRunCPU = new TProofBenchRunCPU(htype, fNHist, fOutFile);
   if (!fCPUSel.IsNull()) fRunCPU->SetSelName(fCPUSel);
   if (!fSelOption.IsNull()) fRunDS->SetSelOption(fSelOption);
   if (!fCPUPar.IsNull()) fRunCPU->SetParList(fCPUPar);
   fRunCPU->Run(nevents, start, stop, -2, fNtries, fDebug, -1);

   // Close the file
   if (SetOutFile(0) != 0)
      Warning("RunCPUx", "problems closing '%s'", fOutFileName.Data());

   // Done
   return 0;
}

//______________________________________________________________________________
void TProofBench::DrawCPU(const char *outfile, const char *opt, Bool_t verbose,
                          Int_t dofit, Int_t n0, Int_t n1)
{
   // Draw the CPU speedup plot.
   //  opt = 'typewhat', e.g. 'std:max:'
   //    type = 'std:'      draw standard evt/s plot
   //           'stdx:'     draw standard evt/s plot, 1 worker per node
   //           'norm:'     draw normalized plot
   //           'normx:'    draw normalized plot, 1 worker per node
   //    what = 'max:'      draw max rate
   //           'avg:'      draw average rate
   //           'all:'      draw max and average rate on same plot (default)
   //  dofit =  0           no fit
   //           1           fit with the relevant '1st degree related' function
   //           2           fit with the relevant '2nd degree related' function
   //           3           fit with varying rcpu function
   //     n0 = for dofit == 3, number of real cores
   //     n1 = for dofit == 3, number of total cores (real + hyperthreaded)
    //

   // Get the TProfile an create the graphs
   TFile *fout = TFile::Open(outfile, "READ");
   if (!fout || (fout && fout->IsZombie())) {
      ::Error("DrawCPU", "could not open file '%s' ...", outfile);
      return;
   }

   // Get description
   TString description("<not available>");
   TNamed *nmdesc = (TNamed *) fout->Get("PB_description");
   if (nmdesc) description = nmdesc->GetTitle();

   // Parse option
   TString oo(opt);
   Bool_t isNorm = (oo.Contains("norm")) ? kTRUE : kFALSE;
   Bool_t isX = (oo.Contains("stdx:") || oo.Contains("normx:")) ? kTRUE : kFALSE;
   Bool_t doAvg = kTRUE, doMax = kTRUE;
   if (oo.Contains("avg:")) doMax = kFALSE;
   if (oo.Contains("max:")) doAvg = kFALSE;

   const char *dirn = (isX) ? "RunCPUx" : "RunCPU";
   TDirectory *d = (TDirectory *) fout->Get(dirn);
   if (!d) {
      ::Error("DrawCPU", "could not find directory '%s' ...", dirn);
      fout->Close();
      delete fout;
      return;
   }
   d->cd();

   TString hprofn, hmaxn;
   const char *lx = (isX) ? "_x" : "";
   const char *ln = (isNorm) ? "Norm" : "Prof";
   hprofn.Form("%s%s_CPU_QR_Evts", ln, lx);
   hmaxn.Form("%s%s_CPU_PS_MaxEvts", ln, lx);

   Double_t xmin = -1., xmax = -1.;
   Double_t ami = -1., amx = -1., mmi = -1., mmx = -1.;
   Int_t kamx = -1, kmmx = -1, nbins = -1;
   Double_t ymx = -1., ymi = -1.;

   TProfile *pfav = 0;
   TGraphErrors *grav = 0;
   if (doAvg) {
      if (!(grav = GetGraph(d, hprofn, nbins, xmin, xmax, ami, amx, kamx, pfav))) {
         ::Error("DrawCPU", "could not find '%s' ...", hprofn.Data());
         fout->Close();
         delete fout;
         return;
      }
      ymx = amx;
      ymi = ami;
   }
   TProfile *pfmx = 0;
   TGraphErrors *grmx = 0;
   if (doMax) {
      if (!(grmx = GetGraph(d, hmaxn, nbins, xmin, xmax, mmi, mmx, kmmx, pfmx))) {
         ::Warning("DrawCPU", "could not find '%s': feature added in 5.34/11", hmaxn.Data());
         if (!grav) {
            // Nothing to do if not asked for the average
            fout->Close();
            delete fout;
            return;
         }
         doMax = kFALSE;
      }
      if (mmx > ymx) ymx = mmx;
      if ((ymi > 0 && mmi < ymi) || (ymi < 0.)) ymi = mmi;
   }

   TProfile *pf = (doMax) ? pfmx : pfav;
   Int_t kmx = (doMax) ? kmmx : kamx;

   // Create the canvas
   TCanvas *cpu = new TCanvas("cpu", "Rate vs wrks",204,69,1050,502);
   cpu->Range(-3.106332,0.7490716,28.1362,1.249867);

   TH1F *hgr = new TH1F("Graph-CPU"," CPU speed-up", nbins*4, xmin, xmax);
   hgr->SetMaximum(ymx + (ymx-ymi)*0.2);
   hgr->SetMinimum(0);
   if (isNorm) hgr->SetMaximum(ymx*1.2);
   hgr->SetDirectory(0);
   hgr->SetStats(0);
   hgr->GetXaxis()->SetTitle(pf->GetXaxis()->GetTitle());
   hgr->GetXaxis()->CenterTitle(true);
   hgr->GetXaxis()->SetLabelSize(0.05);
   hgr->GetXaxis()->SetTitleSize(0.06);
   hgr->GetXaxis()->SetTitleOffset(0.62);
   hgr->GetYaxis()->SetTitleSize(0.08);
   hgr->GetYaxis()->SetTitleOffset(0.52);
   hgr->GetYaxis()->SetTitle("Rate (events/s)");

   TLegend *leg = 0;
   if (isNorm) {
      leg = new TLegend(0.7, 0.8, 0.9, 0.9);
   } else {
      leg = new TLegend(0.1, 0.8, 0.3, 0.9);
   }

   gStyle->SetOptTitle(0);
   if (doAvg) {
      grav->SetFillColor(1);
      grav->SetLineColor(13);
      grav->SetMarkerColor(4);
      grav->SetMarkerStyle(21);
      grav->SetMarkerSize(1.2);
      grav->SetHistogram(hgr);

      if (verbose) grav->Print();
      grav->Draw("alp");
      leg->AddEntry(grav, "Average", "P");
   }
   if (doMax) {
      grmx->SetFillColor(1);
      grmx->SetLineColor(13);
      grmx->SetMarkerColor(2);
      grmx->SetMarkerStyle(29);
      grmx->SetMarkerSize(1.8);
      grmx->SetHistogram(hgr);

      if (verbose) grmx->Print();
      if (doAvg) {
         grmx->Draw("lpSAME");
      } else {
         grmx->Draw("alp");
      }
      leg->AddEntry(grmx, "Maximum", "P");
   }
   leg->Draw();
   gPad->Update();

   if (dofit > 0) {
      TGraphErrors *gr = (doMax) ? grmx : grav;
      // Make sure the fitting functions are defined
      Double_t xmi = 0.9;
      if (nbins > 5) xmi = 1.5;
      AssertFittingFun(xmi, nbins + .1);

      // Starting point for the parameters and fit
      Double_t normrate = -1.;
      if (dofit == 1) {
         if (isNorm) {
            fgFp1n->SetParameter(0, pf->GetBinContent(1));
            fgFp1n->SetParameter(1, pf->GetBinContent(nbins-1));
            gr->Fit(fgFp1n);
            if (verbose) fgFp1n->Print();
            normrate = fgFp1n->GetParameter(1);
         } else {
            fgFp1->SetParameter(0, 0.);
            fgFp1->SetParameter(1, pf->GetBinContent(1));
            gr->Fit(fgFp1);
            if (verbose) fgFp1->Print();
            normrate = fgFp1->Derivative(1.);
         }
      } else if (dofit == 2) {
         if (isNorm) {
            fgFp2n->SetParameter(0, pf->GetBinContent(1));
            fgFp2n->SetParameter(1, pf->GetBinContent(nbins-1));
            fgFp2n->SetParameter(2, 0.);
            gr->Fit(fgFp2n);
            if (verbose) fgFp2n->Print();
            normrate = fgFp2n->GetParameter(1);
         } else {
            fgFp2->SetParameter(0, 0.);
            fgFp2->SetParameter(1, pf->GetBinContent(1));
            fgFp2->SetParameter(2, 0.);
            gr->Fit(fgFp2);
            if (verbose) fgFp2->Print();
            normrate = fgFp2->Derivative(1.);
         }
      } else {
         // Starting point for the parameters and fit
         gFioVn0 = (n0 > 0) ? n0 : (Int_t) (nbins + .1)/2.;
         gFioVn1 = (n1 > 0) ? n1 : (Int_t) (nbins + .1);
         if (isNorm) {
            fgFp3n->SetParameter(0, 0.);
            fgFp3n->SetParameter(1, pf->GetBinContent(1));
            fgFp3n->SetParameter(2, pf->GetBinContent(nbins-1));
            gr->Fit(fgFp3n);
            if (verbose) fgFp3n->Print();
            normrate = pf->GetBinContent(1);
         } else {
            fgFp3->SetParameter(0, 0.);
            fgFp3->SetParameter(1, 0.);
            fgFp3->SetParameter(2, pf->GetBinContent(1));
            gr->Fit(fgFp3);
            if (verbose) fgFp3->Print();
            normrate = fgFp3->Derivative(1.);
         }
      }

      // Notify the cluster performance parameters
      if (!isNorm) {
         printf("* ************************************************************ *\n");
         printf("*                                                              *\r");
         printf("* Cluster: %s\n", description.Data());
         printf("* Performance measurement from scalability plot:               *\n");
         printf("*                                                              *\r");
         printf("*    rate max:         %.3f\tmegaRNGPS (@ %d workers)\n", ymx/1000000, kmx);
         printf("*                                                              *\r");
         printf("*    per-worker rate:  %.3f\tmegaRNGPS \n", normrate/1000000);
         printf("* ************************************************************ *\n");
      } else {
         printf("* ************************************************************ *\n");
         printf("*                                                              *\r");
         printf("* Cluster: %s\n", description.Data());
         printf("*                                                              *\r");
         printf("* Per-worker rate from normalized plot:  %.3f\tmegaRNGPS\n", normrate/1000000);
         printf("* ************************************************************ *\n");
      }
   }
   // Close the file
   fout->Close();
   if (grav) fgGraphs->Add(grav);
   if (grmx) fgGraphs->Add(grmx);
}

//______________________________________________________________________________
TGraphErrors *TProofBench::GetGraph(TDirectory *d, const char *pfn, Int_t &nb,
                                    Double_t &xmi, Double_t &xmx,
                                    Double_t &ymi, Double_t &ymx, Int_t &kmx, TProfile *&pf)
{
   // Get from TDirectory 'd' the TProfile named 'pfn' and create the graph.
   // Return also the max y in mx.

   // Sanity checks
   if (!d || !pfn || (pfn && strlen(pfn) <= 0)) {
      ::Error("TProofBench::GetGraph", "directory or name not defined!");
      return (TGraphErrors *)0;
   }

   TList *keylist = d->GetListOfKeys();
   TKey *key = 0;
   TIter nxk(keylist);
   while ((key = (TKey *) nxk())) {
      if (TString(key->GetName()).BeginsWith(pfn)) {
         pf = (TProfile *) d->Get(key->GetName());
         break;
      }
   }
   // Sanity checks
   if (!pf) {
      ::Error("TProofBench::GetGraph", "TProfile for '%s' not found in directory '%s'", pfn, d->GetName());
      return (TGraphErrors *)0;
   }

   nb = pf->GetNbinsX();
   TGraphErrors *gr = new TGraphErrors(nb);
   gr->SetName(TString::Format("Graph_%s", pfn));
   Double_t xx, ex, yy, ey;
   ymi = pf->GetBinContent(1);
   ymx = ymi;
   xmi = pf->GetBinCenter(1) - pf->GetBinWidth(1)/2. ;
   xmx = pf->GetBinCenter(nb) + pf->GetBinWidth(nb)/2. ;
   kmx = -1;
   for (Int_t k = 1;k <= nb; k++) {
      xx = pf->GetBinCenter(k);
      ex = pf->GetBinWidth(k) * .001;
      yy = pf->GetBinContent(k);
      ey = pf->GetBinError(k);
      if (k == 1) {
         ymi = yy;
         ymx = yy;
         kmx = k;
      } else {
         if (yy < ymi) ymi = yy;
         if (yy > ymx) { ymx = yy; kmx = k; }
      }
      gr->SetPoint(k-1, xx, yy);
      gr->SetPointError(k-1, ex, ey);
   }

   // Done
   return gr;
}

//______________________________________________________________________________
void TProofBench::AssertFittingFun(Double_t mi, Double_t mx)
{
   // Make sure that the fitting functions are defined

   if (!fgFp1) {
      fgFp1 = new TF1("funp1", funp1, mi, mx, 2);
      fgFp1->SetParNames("offset", "slope");
   }

   if (!fgFp1n) {
      fgFp1n = new TF1("funp1n", funp1n, mi, mx, 2);
      fgFp1n->SetParNames("decay", "norm rate");
   }

   if (!fgFp2) {
      fgFp2 = new TF1("funp2", funp2, mi, mx, 3);
      fgFp2->SetParNames("offset", "slope", "deviation");
   }

   if (!fgFp2n) {
      fgFp2n = new TF1("funp2n", funp2n, mi, mx, 3);
      fgFp2n->SetParNames("decay", "norm rate", "deviation");
   }

   if (!fgFp3) {
      fgFp3 = new TF1("funcpuv", funcpuv, mi, mx, 3);
      fgFp3->SetParNames("offset", "slope real", "slope hyper");
   }

   if (!fgFp3n) {
      fgFp3n = new TF1("funcpuvn", funcpuvn, mi, mx, 3);
      fgFp3n->SetParNames("offset", "slope real", "slope hyper");
   }

   if (!fgFio) {
      fgFio = new TF1("funio", funio, mi, mx, 3);
      fgFio->SetParNames("R1", "RIO", "TotIO");
   }
   if (!fgFioV) {
      fgFioV = new TF1("funiov", funiov, mi, mx, 5);
      fgFioV->SetParNames("rio", "b1", "b2", "nc", "ri");
   }

}

//______________________________________________________________________________
class fileDesc : public TNamed {
public:
   Long_t  fMtime; // Modification time
   TString fDesc; // Test description string, if any
   fileDesc(const char *n, const char *o,
            Long_t t, const char *d) : TNamed(n, o), fMtime(t), fDesc(d) { }
   Int_t   Compare(const TObject *o) const {
      const fileDesc *fd = static_cast<const fileDesc *>(o);
      if (!fd || (fd && fd->fMtime == fMtime)) return 0;
      if (fMtime < fd->fMtime) return -1;
      return 1;
   }
};

//______________________________________________________________________________
void TProofBench::GetPerfSpecs(const char *path, Int_t degfit)
{
   // Get performance specs. Check file 'path', or files in directory 'path'
   // (default current directory).
   // The degree of the polynomial used for the fit is 'degfit' (default 1).

   // Locate the file (ask if many)
   TString pp(path), fn, oo;
   if (pp.IsNull()) pp = gSystem->WorkingDirectory();
   FileStat_t st;
   if (gSystem->GetPathInfo(pp.Data(), st) != 0) {
      ::Error("TProofBench::GetPerfSpecs", "path '%s' could not be stat'ed - abort", pp.Data());
      return;
   }
   TSortedList filels;
   if (R_ISDIR(st.fMode)) {
      // Scan the directory
      void *dirp = gSystem->OpenDirectory(pp.Data());
      if (!dirp) {
         ::Error("TProofBench::GetPerfSpecs", "directory path '%s' could nto be open - abort", pp.Data());
         return;
      }
      const char *ent = 0;
      while ((ent = gSystem->GetDirEntry(dirp))) {
         if (!strcmp(ent, ".") || !strcmp(ent, "..")) continue;
         fn.Form("%s/%s", pp.Data(), ent);
         if (gSystem->GetPathInfo(fn.Data(), st) != 0) continue;
         if (!R_ISREG(st.fMode)) continue;
         fn += "?filetype=raw";
         TFile *f = TFile::Open(fn);
         if (!f) continue;
         char rr[5] = {0};
         if (!f->ReadBuffer(rr, 4)) {
            if (!strncmp(rr, "root", 4)) {
               SafeDelete(f);
               fn.ReplaceAll("?filetype=raw", "");
               if ((f = TFile::Open(fn))) {
                  TString desc("<no decription>");
                  TNamed *nmdesc = (TNamed *) f->Get("PB_description");
                  if (nmdesc) desc = nmdesc->GetTitle();
                  if (f->GetListOfKeys()->FindObject("RunCPU"))
                     filels.Add(new fileDesc(fn, "std:", st.fMtime, desc.Data()));
                  if (f->GetListOfKeys()->FindObject("RunCPUx"))
                     filels.Add(new fileDesc(fn, "stdx:", st.fMtime, desc.Data()));
               } else {
                  ::Warning("TProofBench::GetPerfSpecs", "problems opening '%s'", fn.Data());
               }
            }
         }
         SafeDelete(f);
      }
   } else if (!R_ISREG(st.fMode)) {
      ::Error("TProofBench::GetPerfSpecs",
              "path '%s' not a regular file nor a directory - abort", pp.Data());
      return;
   } else {
      // This is the file
      fn = pp;
      // Check it
      TString emsg;
      Bool_t isOk = kFALSE;
      if (gSystem->GetPathInfo(fn.Data(), st) == 0) {
         fn += "?filetype=raw";
         TFile *f = TFile::Open(fn);
         if (f) {
            char rr[5] = {0};
            if (!(f->ReadBuffer(rr, 4))) {
               if (!strncmp(rr, "root", 4)) {
                  fn.ReplaceAll("?filetype=raw", "");
                  if ((f = TFile::Open(fn))) {
                     if (f->GetListOfKeys()->FindObject("RunCPU")) oo = "std:";
                     if (f->GetListOfKeys()->FindObject("RunCPUx")) oo = "stdx:";
                     SafeDelete(f);
                     if (!oo.IsNull()) {
                        isOk = kTRUE;
                     } else {
                        emsg.Form("path '%s' does not contain the relevant dirs - abort", fn.Data());
                     }
                  } else {
                     emsg.Form("path '%s' cannot be open - abort", fn.Data());
                  }
               } else {
                  emsg.Form("'%s' is not a ROOT file - abort", fn.Data());
               }
            } else {
               emsg.Form("could not read first 4 bytes from '%s' - abort", fn.Data());
            }
            SafeDelete(f);
         } else {
            emsg.Form("path '%s' cannot be open in raw mode - abort", fn.Data());
         }
      } else {
         emsg.Form("path '%s' cannot be stated - abort", fn.Data());
      }
      if (!isOk) {
         ::Error("TProofBench::GetPerfSpecs", "%s", emsg.Data());
         return;
      }
   }

   fileDesc *nm = 0;
   // Ask the user, if more then 1
   if (filels.GetSize() == 1) {
      nm = (fileDesc *) filels.First();
      fn = nm->GetName();
      oo = nm->GetTitle();
   } else if (filels.GetSize() > 1) {
      TIter nxf(&filels);
      Int_t idx = 0;
      Printf("Several possible files found:");
      while ((nm = (fileDesc *) nxf())) {
         Printf("  %d\t%s\t%s\t%s (file: %s)", idx++, nm->GetTitle(),
                TTimeStamp(nm->fMtime).AsString("s"), nm->fDesc.Data(), nm->GetName());
      }
      TString a(Getline(TString::Format("Make your choice [%d] ", idx-1)));
      if (a.IsNull() || a[0] == '\n') a.Form("%d", idx-1);
      idx = a.Atoi();
      if ((nm = (fileDesc *) filels.At(idx))) {
         fn = nm->GetName();
         oo = nm->GetTitle();
      } else {
         ::Error("TProofBench::GetPerfSpecs", "chosen index '%d' does not exist - abort", idx);
         return;
      }
   } else {
      if (fn.IsNull()) {
         ::Error("TProofBench::GetPerfSpecs",
                 "path '%s' is a directory but no ROOT file found in it - abort", pp.Data());
         return;
      }
   }

   // Now get the specs
   TProofBench::DrawCPU(fn.Data(), oo.Data(), kFALSE, degfit);
}

//______________________________________________________________________________
Int_t TProofBench::RunDataSet(const char *dset,
                              Int_t start, Int_t stop, Int_t step)
{
   // Perform a test using dataset 'dset'
   // Return 0 on success, -1 on error
   // Open the file for the results

   if (OpenOutFile(kTRUE) != 0) {
      Error("RunDataSet", "problems opening '%s' to save the result", fOutFileName.Data());
      return -1;
   }
   fUnlinkOutfile = kFALSE;

   if (fReleaseCache) ReleaseCache(dset);
   SafeDelete(fRunDS);
   TPBReadType *readType = fReadType;
   if (!readType) readType = new TPBReadType(TPBReadType::kReadOpt);
   fRunDS = new TProofBenchRunDataRead(fDS, readType, fOutFile);
   if (!fDataSel.IsNull()) fRunDS->SetSelName(fDataSel);
   if (!fSelOption.IsNull()) fRunDS->SetSelOption(fSelOption);
   if (!fDataPar.IsNull()) fRunDS->SetParList(fDataPar);
   fRunDS->SetReleaseCache(fReleaseCache);
   fRunDS->Run(dset, start, stop, step, fNtries, fDebug, -1);
   if (!fReadType) SafeDelete(readType);

   // Close the file
   if (SetOutFile(0) != 0)
      Warning("RunDataSet", "problems closing '%s'", fOutFileName.Data());

   // Done
   return 0;
}

//______________________________________________________________________________
Int_t TProofBench::RunDataSetx(const char *dset, Int_t start, Int_t stop)
{
   // Perform a test using dataset 'dset' scanning over the number of workers
   // per node.
   // Return 0 on success, -1 on error
   // Open the file for the results

   if (OpenOutFile(kTRUE) != 0) {
      Error("RunDataSetx", "problems opening '%s' to save the result", fOutFileName.Data());
      return -1;
   }
   fUnlinkOutfile = kFALSE;

   ReleaseCache(dset);
   SafeDelete(fRunDS);
   TPBReadType *readType = fReadType;
   if (!readType) readType = new TPBReadType(TPBReadType::kReadOpt);
   fRunDS = new TProofBenchRunDataRead(fDS, readType, fOutFile);
   if (!fDataSel.IsNull()) fRunDS->SetSelName(fDataSel);
   if (!fSelOption.IsNull()) fRunDS->SetSelOption(fSelOption);
   if (!fDataPar.IsNull()) fRunDS->SetParList(fDataPar);
   fRunDS->Run(dset, start, stop, -2, fNtries, fDebug, -1);
   if (!fReadType) SafeDelete(readType);

   // Close the file
   if (SetOutFile(0) != 0)
      Warning("RunDataSetx", "problems closing '%s'", fOutFileName.Data());

   // Done
   return 0;
}

//______________________________________________________________________________
void TProofBench::DrawDataSet(const char *outfile,
                              const char *opt, const char *type, Bool_t verbose,
                              Int_t dofit, Int_t n0, Int_t n1)
{
   // Draw the CPU speedup plot.
   //  opt = 'typewhat', e.g. 'std:max:'
   //    type = 'std:'      draw standard plot
   //           'stdx:'     draw standard plot, 1 worker per node
   //           'norm:'     draw normalized plot
   //           'normx:'    draw normalized plot, 1 worker per node
   //    what = 'max:'      draw max rate
   //           'avg:'      draw average rate
   //           'all:'      draw max and average rate on same plot (default)
   // type =    'mbs'           MB/s scaling plots (default)
   //           'evts'          Event/s scaling plots
   //  dofit =  0           no fit
   //           1           fit with default 3 parameter saturated I/O formula
   //           2           fit with 4 parameter saturated I/O formula (varying Rcpu)
   //     n0 = for dofit == 2, number of real cores
   //     n1 = for dofit == 2, number of total cores (real + hyperthreaded)
   //

   // Get the TProfile an create the graphs
   TFile *fout = TFile::Open(outfile, "READ");
   if (!fout || (fout && fout->IsZombie())) {
      ::Error("DrawDataSet", "could not open file '%s' ...", outfile);
      return;
   }

   // Get description
   TString description("<not available>");
   TNamed *nmdesc = (TNamed *) fout->Get("PB_description");
   if (nmdesc) description = nmdesc->GetTitle();

   // Parse option
   TString oo(opt);
   Bool_t isNorm = (oo.Contains("norm")) ? kTRUE : kFALSE;
   Bool_t isX = (oo.Contains("stdx:") || oo.Contains("normx:")) ? kTRUE : kFALSE;
   Bool_t doAvg = kTRUE, doMax = kTRUE;
   if (oo.Contains("avg:")) doMax = kFALSE;
   if (oo.Contains("max:")) doAvg = kFALSE;

   const char *dirn = (isX) ? "RunDataReadx" : "RunDataRead";
   TDirectory *d = (TDirectory *) fout->Get(dirn);
   if (!d) {
      ::Error("DrawCPU", "could not find directory '%s' ...", dirn);
      fout->Close();
      delete fout;
      return;
   }
   d->cd();

   TString hprofn, hmaxn;
   const char *lx = (isX) ? "_x" : "";
   const char *ln = (isNorm) ? "Norm" : "Prof";
   Bool_t isIO = kTRUE;
   if (type && !strcmp(type, "evts")) {
      hprofn.Form("%s%s_DataRead_QR_Evts", ln, lx);
      hmaxn.Form("%s%s_DataRead_PS_MaxEvts", ln, lx);
      isIO = kFALSE;
   } else {
      hprofn.Form("%s%s_DataRead_QR_IO", ln, lx);
      hmaxn.Form("%s%s_DataRead_PS_MaxIO", ln, lx);
   }

   Double_t xmin = -1., xmax = -1.;
   Double_t ami = -1., amx = -1., mmi = -1., mmx = -1.;
   Int_t kamx = -1, kmmx = -1, nbins = -1;
   Double_t ymx = -1., ymi = -1.;

   TProfile *pfav = 0;
   TGraphErrors *grav = 0;
   if (doAvg) {
      if (!(grav = GetGraph(d, hprofn, nbins, xmin, xmax, ami, amx, kamx, pfav))) {
         ::Error("DrawCPU", "could not find '%s' ...", hprofn.Data());
         fout->Close();
         delete fout;
         return;
      }
      ymx = amx;
      ymi = ami;
   }
   TProfile *pfmx = 0;
   TGraphErrors *grmx = 0;
   if (doMax) {
      if (!(grmx = GetGraph(d, hmaxn, nbins, xmin, xmax, mmi, mmx, kmmx, pfmx))) {
         ::Warning("DrawCPU", "could not find '%s': feature added in 5.34/11", hmaxn.Data());
         if (!grav) {
            // Nothing to do if not asked for the average
            fout->Close();
            delete fout;
            return;
         }
         doMax = kFALSE;
      }
      if (mmx > ymx) ymx = mmx;
      if ((ymi > 0 && mmi < ymi) || (ymi < 0.)) ymi = mmi;
   }

   TProfile *pf = (doMax) ? pfmx : pfav;
   Int_t kmx = (doMax) ? kmmx : kamx;

   // Create the canvas
   TCanvas *cpu = new TCanvas("dataset", "Rate vs wrks",204,69,1050,502);
   cpu->Range(-3.106332,0.7490716,28.1362,1.249867);

   TH1F *hgr = new TH1F("Graph-DataSet"," Data Read speed-up", nbins*4, xmin, xmax);
   hgr->SetMaximum(ymx + (ymx-ymi)*0.2);
   hgr->SetMinimum(0);
   if (isNorm) hgr->SetMaximum(ymx*1.2);
   hgr->SetDirectory(0);
   hgr->SetStats(0);
   hgr->GetXaxis()->SetTitle(pf->GetXaxis()->GetTitle());
   hgr->GetXaxis()->CenterTitle(true);
   hgr->GetXaxis()->SetLabelSize(0.05);
   hgr->GetXaxis()->SetTitleSize(0.06);
   hgr->GetXaxis()->SetTitleOffset(0.62);
   hgr->GetYaxis()->SetLabelSize(0.06);
   hgr->GetYaxis()->SetTitleSize(0.08);
   hgr->GetYaxis()->SetTitleOffset(0.52);
   if (isIO) {
      hgr->GetYaxis()->SetTitle("Rate (MB/s)");
   } else {
      hgr->GetYaxis()->SetTitle("Rate (events/s)");
   }

   TLegend *leg = 0;
   if (isNorm) {
      leg = new TLegend(0.7, 0.8, 0.9, 0.9);
   } else {
      leg = new TLegend(0.1, 0.8, 0.3, 0.9);
   }

   if (doAvg) {
      grav->SetFillColor(1);
      grav->SetLineColor(13);
      grav->SetMarkerColor(4);
      grav->SetMarkerStyle(21);
      grav->SetMarkerSize(1.2);
      grav->SetHistogram(hgr);

      if (verbose) grav->Print();
      grav->Draw("alp");
      leg->AddEntry(grav, "Average", "P");
   }
   if (doMax) {
      grmx->SetFillColor(1);
      grmx->SetLineColor(13);
      grmx->SetMarkerColor(2);
      grmx->SetMarkerStyle(29);
      grmx->SetMarkerSize(1.8);
      grmx->SetHistogram(hgr);

      if (verbose) grmx->Print();
      if (doAvg) {
         grmx->Draw("lpSAME");
      } else {
         grmx->Draw("alp");
      }
      leg->AddEntry(grmx, "Maximum", "P");
   }
   leg->Draw();
   gPad->Update();

   Double_t normrate = -1.;
   if (dofit > 0) {
      TGraphErrors *gr = (doMax) ? grmx : grav;
      // Make sure the fitting functions are defined
      Double_t xmi = 0.9;
      if (nbins > 5) xmi = 1.5;
      AssertFittingFun(xmi, nbins + .1);

      if (dofit == 1) {
         // Starting point for the parameters and fit
         fgFio->SetParameter(0, pf->GetBinContent(1));
         fgFio->SetParameter(1, pf->GetBinContent(nbins-1));
         fgFio->SetParameter(2, pf->GetBinContent(nbins-1));
         gr->Fit(fgFio);
         if (verbose) fgFio->Print();
         normrate = fgFio->Derivative(1.);
      } else if (dofit > 1) {
         // Starting point for the parameters and fit
         gFioVn0 = (n0 > 0) ? n0 : (Int_t) (nbins + .1)/2.;
         gFioVn1 = (n1 > 0) ? n1 : (Int_t) (nbins + .1);
         fgFioV->SetParameter(0, 20.);
         fgFioV->SetParameter(1, pf->GetBinContent(1));
         fgFioV->SetParameter(2, pf->GetBinContent(1));
         fgFioV->SetParameter(3, 4.);
         fgFioV->SetParameter(4, 1000.);

         gr->Fit(fgFioV);
         if (verbose) fgFio->Print();
         normrate = fgFioV->Derivative(1.);
      }
   }

   // Notify the cluster performance parameters
   if (!isNorm) {
      printf("* ************************************************************ *\n");
      printf("*                                                              *\r");
      printf("* Cluster: %s\n", description.Data());
      printf("* Performance measurement from scalability plot:               *\n");
      printf("*                                                              *\r");
      if (isIO) {
         printf("*    rate max:         %.3f\tMB/s (@ %d workers)\n", ymx, kmx);
         printf("*                                                              *\r");
         printf("*    per-worker rate:  %.3f\tMB/s \n", normrate);
      } else {
         printf("*    rate max:         %.3f\tevts/s (@ %d workers)\n", ymx, kmx);
      }
      printf("* ************************************************************ *\n");
   }
   // Close the file
   fout->Close();
   if (grav) fgGraphs->Add(grav);
   if (grmx) fgGraphs->Add(grmx);
}

//______________________________________________________________________________
void TProofBench::DrawEfficiency(const char *outfile,
                                 const char *opt, Bool_t verbose)
{
   // Draw the efficiency plot.
   //  opt = 'cpu' or 'data' (default the first found)
   //

   // Get the TProfile an create the graphs
   TFile *fout = TFile::Open(outfile, "READ");
   if (!fout || (fout && fout->IsZombie())) {
      ::Error("DrawEfficiency", "could not open file '%s' ...", outfile);
      return;
   }

   // Get description
   TString description("<not available>");
   TNamed *nmdesc = (TNamed *) fout->Get("PB_description");
   if (nmdesc) description = nmdesc->GetTitle();

   // Parse option
   TString oo(opt), ln("CPU");
   const char *dirs[4] = { "RunCPU", "RunCPUx", "RunDataRead", "RunDataReadx"};
   const char *labs[4] = { "CPU", "CPU", "DataRead", "DataRead"};
   Int_t fst = 0, lst = 3;
   if (oo == "cpu") {
      lst = 0;
   } else if (oo == "cpux") {
      fst = 1;
      lst = 1;
   } else if (oo.BeginsWith("data")) {
      if (oo.EndsWith("x")) {
         fst = 3;
         lst = 3;
      } else {
         fst = 2;
         lst = 2;
      }
   }
   const char *dirn = 0;
   TDirectory *d = 0;
   for (Int_t i = fst; i <= lst; i++) {
      if ((d = (TDirectory *) fout->Get(dirs[i]))) {
         dirn = dirs[i];
         ln = labs[i];
         break;
      }
   }
   if (!d && !dirn) {
      ::Error("DrawEfficiency", "could not find directory ...");
      fout->Close();
      delete fout;
      return;
   }
   d->cd();

   TString hprof;
   hprof.Form("Prof_%s_CPU_eff", ln.Data());

   Double_t xmin = -1., xmax = -1.;
   Int_t kmx = -1, nbins = -1;
   Double_t ymx = -1., ymi = -1.;

   TProfile *pf = 0;
   TGraphErrors *gr = 0;
   if (!(gr = GetGraph(d, hprof, nbins, xmin, xmax, ymi, ymx, kmx, pf))) {
      ::Error("DrawEfficiency", "could not find '%s' ...", hprof.Data());
      fout->Close();
      delete fout;
      return;
   }

   // Create the canvas
   TCanvas *cpu = new TCanvas("efficiency", "efficiency vs wrks",204,69,1050,502);
   cpu->Range(-3.106332,0.7490716,28.1362,1.249867);

   TH1F *hgr = new TH1F("Graph-Efficiency","CPU effectiveness", nbins*4, xmin, xmax);
   hgr->SetMaximum(1.2);
   hgr->SetMinimum(0);
   hgr->SetDirectory(0);
   hgr->SetStats(0);
   hgr->GetXaxis()->SetTitle(pf->GetXaxis()->GetTitle());
   hgr->GetXaxis()->CenterTitle(true);
   hgr->GetXaxis()->SetLabelSize(0.05);
   hgr->GetXaxis()->SetTitleSize(0.06);
   hgr->GetXaxis()->SetTitleOffset(0.62);
   hgr->GetYaxis()->SetLabelSize(0.06);
   hgr->GetYaxis()->SetTitleSize(0.08);
   hgr->GetYaxis()->SetTitleOffset(0.52);
   hgr->GetYaxis()->SetTitle("CPU effectiveness");

   gr->SetFillColor(1);
   gr->SetLineColor(13);
   gr->SetMarkerColor(4);
   gr->SetMarkerStyle(21);
   gr->SetMarkerSize(1.2);
   gr->SetHistogram(hgr);

   if (verbose) gr->Print();
   gr->Draw("alp");

   // Notify the cluster performance parameters
   printf("* ************************************************************ *\n");
   printf("*                                                              *\r");
   printf("* Cluster: %s\n", description.Data());
   printf("* CPU effectiveness measurement:                               *\n");
   printf("*                                                              *\r");
   printf("*    effectiveness max:     %.3f (@ %d workers)\n", ymx, kmx);
   printf("*                                                              *\r");
   printf("* ************************************************************ *\n");
   // Close the file
   fout->Close();
   if (gr) fgGraphs->Add(gr);
}

//______________________________________________________________________________
Int_t TProofBench::ReleaseCache(const char *dset)
{
   // Release memory cache for dataset 'dset'
   // Return 0 on success, -1 on error

   // Do it via the dataset handler
   if (!fDS) fDS = new TProofBenchDataSet(fProofDS);
   return fDS ? fDS->ReleaseCache(dset) : -1;
}

//______________________________________________________________________________
Int_t TProofBench::RemoveDataSet(const char *dset)
{
   // Physically remove the dataset 'dset', i.e. remove the dataset and the files
   // it describes
   // Return 0 on success, -1 on error

   // Do it via the dataset handler
   if (!fDS) fDS = new TProofBenchDataSet(fProofDS);
   return fDS ? fDS->RemoveFiles(dset) : -1;
}

//______________________________________________________________________________
Int_t TProofBench::MakeDataSet(const char *dset, Long64_t nevt, const char *fnroot,
                               Bool_t regenerate)
{
   // Create the largest dataset for the run.
   // Defaults for
   //          dataset name, filename root
   // are
   //          "BenchDataSet", "event"
   // respectively.
   // These can be changed via dset and fnroot, respectively.
   // The string 'fnroot' defines the location of the files, interpreted as an URL.
   // Examples:
   //          fnroot             files
   //          'event'            <datadir>/event_<ord>_<#>.root
   //          '/mss/event'       /mss/event_<ord>_<#>.root
   //          'root://srv//mss/event?remote=1'
   //                             root://srv//mss/event_<ord>_<#>?remote=1.root
   // Default selector is TSelEventGen. Use SetDataGenSel and SetDataGenPar to change it
   // and to pass the list of PARs defining the alternative selector.
   // The argument 'nevt' controls the number of events per file (-1 for the default,
   // which is 30000).
   // Return 0 on success, -1 on error

   if (dset && strlen(dset) > 0) fDataSet = dset;

   // Load the selector, if needed
   if (!TClass::GetClass(fDataGenSel)) {
      // Is it the default selector?
      if (fDataGenSel == kPROOF_BenchSelDataGenDef) {
         // Load the parfile
#ifdef R__HAVE_CONFIG
         TString par = TString::Format("%s/%s%s.par", ROOTETCDIR, kPROOF_BenchParDir, kPROOF_BenchDataSelPar);
#else
         TString par = TString::Format("$ROOTSYS/etc/%s%s.par", kPROOF_BenchParDir, kPROOF_BenchDataSelPar);
#endif
         Info("MakeDataSet", "uploading '%s' ...", par.Data());
         if (fProof->UploadPackage(par) != 0) {
            Error("MakeDataSet", "problems uploading '%s' - cannot continue", par.Data());
            return -1;
         }
         Info("MakeDataSet", "enabling '%s' ...", kPROOF_BenchDataSelPar);
         if (fProof->EnablePackage(kPROOF_BenchDataSelPar) != 0) {
            Error("MakeDataSet", "problems enabling '%s' - cannot continue", kPROOF_BenchDataSelPar);
            return -1;
         }
      } else {
         if (fDataGenPar.IsNull()) {
            Error("MakeDataSet", "you should load the class '%s' before running the benchmark", fDataGenSel.Data());
            return -1;
         }
      }
      // Load additional PAR files, if any or required by the alternative selector
      TString par;
      Int_t from = 0;
      while (fDataGenPar.Tokenize(par, from, ",")) {
         Info("MakeDataSet", "Uploading '%s' ...", par.Data());
         if (fProof->UploadPackage(par) != 0) {
            Error("MakeDataSet", "problems uploading '%s' - cannot continue", par.Data());
            return -1;
         }
         Info("MakeDataSet", "Enabling '%s' ...", par.Data());
         if (fProof->EnablePackage(par) != 0) {
            Error("MakeDataSet", "problems enabling '%s' - cannot continue", par.Data());
            return -1;
         }
      }
      // Check
      if (!TClass::GetClass(fDataGenSel)) {
         Error("MakeDataSet", "failed to load '%s'", fDataGenSel.Data());
         return -1;
      }
   }

   // For files, 30000 evst each (about 600 MB total) per worker
   TString fn, fnr("event");
   Bool_t remote = kFALSE;
   if (fnroot && strlen(fnroot) > 0) {
      TUrl ur(fnroot, kTRUE);
      if (!strcmp(ur.GetProtocol(), "file") &&
         !gSystem->IsAbsoluteFileName(ur.GetFile())) {
         fnr = fnroot;
      } else {
         fnr = gSystem->BaseName(ur.GetFile());
         // We need to set the basedir
         TString bdir(gSystem->DirName(fnroot));
         bdir += "/<fn>";
         fProof->SetParameter("PROOF_BenchmarkBaseDir", bdir.Data());
         // Flag as remote, if so
         if (strcmp(ur.GetProtocol(), "file")) remote = kTRUE;
      }
   }
   TProofNodes pn(fProof);
   TMap *filesmap = new TMap;
   TMap *nodesmap = pn.GetMapOfNodes();
   TIter nxnd(nodesmap);
   TList *wli = 0;
   TObject *obj = 0;
   Int_t kf = 1;
   while ((obj = nxnd()) != 0) {
      if ((wli = dynamic_cast<TList *>(nodesmap->GetValue(obj)))) {
         THashList *fli = new THashList;
         Int_t nf = wli->GetSize() * fNFilesWrk;
         TSlaveInfo *wi = (TSlaveInfo *) wli->First();
         while (nf--) {
            fn.Form("%s-%s-%d.root", fnr.Data(), wi->GetName(), kf++);
            // Add to the node list for generation
            fli->Add(new TObjString(fn));
         }
         filesmap->Add(new TObjString(obj->GetName()), fli);
      }
   }
   filesmap->Print();
   // Prepare for file generation ... add map in the input list
   filesmap->SetName("PROOF_FilesToProcess");
   fProof->AddInput(filesmap);

   // Set parameters for processing
   TString oldpack;
   if (TProof::GetParameter(fProof->GetInputList(), "PROOF_Packetizer", oldpack) != 0) oldpack = "";
   fProof->SetParameter("PROOF_Packetizer", "TPacketizerFile");
   Int_t oldnotass = -1;
   if (TProof::GetParameter(fProof->GetInputList(), "PROOF_ProcessNotAssigned", oldnotass) != 0) oldnotass = -1;
   fProof->SetParameter("PROOF_ProcessNotAssigned", (Int_t)0);

   // Process
   Long64_t ne = (nevt > 0) ? nevt : 30000;
   fProof->SetParameter("PROOF_BenchmarkNEvents", ne);
   fProof->SetParameter("PROOF_BenchmarkRegenerate", Int_t(regenerate));
   fProof->Process(fDataGenSel, (Long64_t) 1);
   fProof->DeleteParameters("PROOF_BenchmarkNEvents");
   fProof->DeleteParameters("PROOF_BenchmarkRegenerate");
   fProof->DeleteParameters("PROOF_BenchmarkBaseDir");

   // Restore parameters
   if (!oldpack.IsNull())
      fProof->SetParameter("PROOF_Packetizer", oldpack);
   else
      fProof->DeleteParameters("PROOF_Packetizer");
   if (oldnotass != -1)
      fProof->SetParameter("PROOF_ProcessNotAssigned", oldnotass);
   else
      fProof->DeleteParameters("PROOF_ProcessNotAssigned");

   // Cleanup
   if (fProof->GetInputList()) fProof->GetInputList()->Remove(filesmap);
   filesmap->SetOwner(kTRUE);
   delete filesmap;

   // The dataset to be registered in the end with proper port
   TFileCollection *fc = new TFileCollection("dum", "dum");

   if (fProof->GetOutputList()) {
      fProof->GetOutputList()->Print();
      TIter nxout(fProof->GetOutputList());
      while ((obj = nxout())) {
         TList *fli = dynamic_cast<TList *>(obj);
         if (fli && TString(fli->GetName()).BeginsWith("PROOF_FilesGenerated_")) {
            TIter nxfg(fli);
            TFileInfo *fi = 0;
            while ((fi = (TFileInfo *) nxfg()))
               fc->Add(fi);
            fli->SetOwner(kFALSE);
         }
      }
      // Register the new dataset, overwriting any existing dataset wth the same name
      // trusting the existing information
      fc->Update();
      if (fc->GetNFiles() > 0) {
         if (remote) fc->SetBit(TFileCollection::kRemoteCollection);
         if (!(fProof->RegisterDataSet(fDataSet, fc, "OT")))
            Warning("MakeDataSet", "problems registering '%s'", dset);
      } else {
         Warning("MakeDataSet", "dataset '%s' is empty!", dset);
      }
   } else {
      Warning("MakeDataSet", "PROOF output list is empty!");
   }

   SafeDelete(fc);

   // Get updated information
   fc = fProof->GetDataSet(fDataSet);
   if (fc) {
      fc->Print("F");
   } else {
      Warning("MakeDataSet", "dataset '%s' was not generated!", fDataSet.Data());
   }

   SafeDelete(fc);

   // Done
   return 0;
}

//______________________________________________________________________________
Int_t TProofBench::CopyDataSet(const char *dset, const char *dsetdst, const char *destdir)
{
   // Copy the files of dataset 'dset' to 'destdir' and create a new dataset named 'dsetdst'
   // decribing them.
   // Return 0 on success, -1 on error

   // Make some checks
   if (!fProof) {
      Error("CopyDataSet", "no PROOF found - cannot continue");
      return -1;
   }
   if (!dset || (dset && !fProof->ExistsDataSet(dset))) {
      Error("CopyDataSet", "dataset '%s' does not exist", dset);
      return -1;
   }
   if (!dsetdst || (dsetdst && fProof->ExistsDataSet(dsetdst))) {
      if (isatty(0) != 0 && isatty(1) != 0) {
         Printf("Target dataset '%s' exists already:"
                                          " do you want to remove it first?", dsetdst);
         const char *a = Getline("[Y,n] ");
         Printf("a: %s", a);
         if (a[0] == 'Y' || a[0] == 'y' || a[0] == '\n') {
            Info("CopyDataSet", "removing dataset '%s' ...", dsetdst);
            RemoveDataSet(dsetdst);
         } else {
            return -1;
         }
      } else {
         Error("CopyDataSet", "destination dataset '%s' does already exist: remove it first", dsetdst);
         return -1;
      }
   }

   // The TFileCollection object for the new dataset
   TFileCollection *fc = fProof->GetDataSet(dset);
   if (!fc) {
      Error("CopyDataSet", "problems retrieving TFileCollection for dataset '%s'", dset);
      return -1;
   }
   TFileCollection *fcn = new TFileCollection(dsetdst, "");
   TString fn;
   TFileInfo *fi = 0;
   TIter nxfi(fc->GetList());
   while ((fi = (TFileInfo *) nxfi())) {
      fn.Form("%s/%s", destdir, gSystem->BaseName(fi->GetCurrentUrl()->GetFile()));
      Info("CopyDataSet", "adding info for file '%s'", fn.Data());
      fcn->Add(new TFileInfo(fn));
   }
   delete fc;

   // Do it via the dataset handler
   if (!fDS) fDS = new TProofBenchDataSet(fProofDS);
   if (fDS->CopyFiles(dset, destdir) != 0) {
      Error("CopyDataSet", "problems copying files of dataset '%s' to dest dir '%s'", dset, destdir);
      delete fcn;
      return -1;
   }

   // Register the new dataset, overwriting any existing dataset wth the same name
   // trusting the existing information
   Int_t rc = 0;
   if (!(fProof->RegisterDataSet(dsetdst, fcn, "OT"))) {
      Error("CopyDataSet", "problems registering and verifying '%s'", dsetdst);
      rc = -1;
   }
   delete fcn;

   // Done
   return rc;
}

//______________________________________________________________________________
void TProofBench::SetProofDS(TProof *pds)
{
   // Set the PROOF instance to be used for dataset operations, like releasing
   // cache ...
   // Use SetProofDS(0) to reset and using the default PROOF

   if (pds && !pds->IsValid()) {
      Error("SetProofDS", "trying to set an invalid PROOF instance");
      return;
   }
   fProofDS = pds ? pds : fProof;
   if (fProofDS) {
      SafeDelete(fDS);
      fDS = new TProofBenchDataSet(fProofDS);
   }
   // Done
   return;
}

 TProofBench.cxx:1
 TProofBench.cxx:2
 TProofBench.cxx:3
 TProofBench.cxx:4
 TProofBench.cxx:5
 TProofBench.cxx:6
 TProofBench.cxx:7
 TProofBench.cxx:8
 TProofBench.cxx:9
 TProofBench.cxx:10
 TProofBench.cxx:11
 TProofBench.cxx:12
 TProofBench.cxx:13
 TProofBench.cxx:14
 TProofBench.cxx:15
 TProofBench.cxx:16
 TProofBench.cxx:17
 TProofBench.cxx:18
 TProofBench.cxx:19
 TProofBench.cxx:20
 TProofBench.cxx:21
 TProofBench.cxx:22
 TProofBench.cxx:23
 TProofBench.cxx:24
 TProofBench.cxx:25
 TProofBench.cxx:26
 TProofBench.cxx:27
 TProofBench.cxx:28
 TProofBench.cxx:29
 TProofBench.cxx:30
 TProofBench.cxx:31
 TProofBench.cxx:32
 TProofBench.cxx:33
 TProofBench.cxx:34
 TProofBench.cxx:35
 TProofBench.cxx:36
 TProofBench.cxx:37
 TProofBench.cxx:38
 TProofBench.cxx:39
 TProofBench.cxx:40
 TProofBench.cxx:41
 TProofBench.cxx:42
 TProofBench.cxx:43
 TProofBench.cxx:44
 TProofBench.cxx:45
 TProofBench.cxx:46
 TProofBench.cxx:47
 TProofBench.cxx:48
 TProofBench.cxx:49
 TProofBench.cxx:50
 TProofBench.cxx:51
 TProofBench.cxx:52
 TProofBench.cxx:53
 TProofBench.cxx:54
 TProofBench.cxx:55
 TProofBench.cxx:56
 TProofBench.cxx:57
 TProofBench.cxx:58
 TProofBench.cxx:59
 TProofBench.cxx:60
 TProofBench.cxx:61
 TProofBench.cxx:62
 TProofBench.cxx:63
 TProofBench.cxx:64
 TProofBench.cxx:65
 TProofBench.cxx:66
 TProofBench.cxx:67
 TProofBench.cxx:68
 TProofBench.cxx:69
 TProofBench.cxx:70
 TProofBench.cxx:71
 TProofBench.cxx:72
 TProofBench.cxx:73
 TProofBench.cxx:74
 TProofBench.cxx:75
 TProofBench.cxx:76
 TProofBench.cxx:77
 TProofBench.cxx:78
 TProofBench.cxx:79
 TProofBench.cxx:80
 TProofBench.cxx:81
 TProofBench.cxx:82
 TProofBench.cxx:83
 TProofBench.cxx:84
 TProofBench.cxx:85
 TProofBench.cxx:86
 TProofBench.cxx:87
 TProofBench.cxx:88
 TProofBench.cxx:89
 TProofBench.cxx:90
 TProofBench.cxx:91
 TProofBench.cxx:92
 TProofBench.cxx:93
 TProofBench.cxx:94
 TProofBench.cxx:95
 TProofBench.cxx:96
 TProofBench.cxx:97
 TProofBench.cxx:98
 TProofBench.cxx:99
 TProofBench.cxx:100
 TProofBench.cxx:101
 TProofBench.cxx:102
 TProofBench.cxx:103
 TProofBench.cxx:104
 TProofBench.cxx:105
 TProofBench.cxx:106
 TProofBench.cxx:107
 TProofBench.cxx:108
 TProofBench.cxx:109
 TProofBench.cxx:110
 TProofBench.cxx:111
 TProofBench.cxx:112
 TProofBench.cxx:113
 TProofBench.cxx:114
 TProofBench.cxx:115
 TProofBench.cxx:116
 TProofBench.cxx:117
 TProofBench.cxx:118
 TProofBench.cxx:119
 TProofBench.cxx:120
 TProofBench.cxx:121
 TProofBench.cxx:122
 TProofBench.cxx:123
 TProofBench.cxx:124
 TProofBench.cxx:125
 TProofBench.cxx:126
 TProofBench.cxx:127
 TProofBench.cxx:128
 TProofBench.cxx:129
 TProofBench.cxx:130
 TProofBench.cxx:131
 TProofBench.cxx:132
 TProofBench.cxx:133
 TProofBench.cxx:134
 TProofBench.cxx:135
 TProofBench.cxx:136
 TProofBench.cxx:137
 TProofBench.cxx:138
 TProofBench.cxx:139
 TProofBench.cxx:140
 TProofBench.cxx:141
 TProofBench.cxx:142
 TProofBench.cxx:143
 TProofBench.cxx:144
 TProofBench.cxx:145
 TProofBench.cxx:146
 TProofBench.cxx:147
 TProofBench.cxx:148
 TProofBench.cxx:149
 TProofBench.cxx:150
 TProofBench.cxx:151
 TProofBench.cxx:152
 TProofBench.cxx:153
 TProofBench.cxx:154
 TProofBench.cxx:155
 TProofBench.cxx:156
 TProofBench.cxx:157
 TProofBench.cxx:158
 TProofBench.cxx:159
 TProofBench.cxx:160
 TProofBench.cxx:161
 TProofBench.cxx:162
 TProofBench.cxx:163
 TProofBench.cxx:164
 TProofBench.cxx:165
 TProofBench.cxx:166
 TProofBench.cxx:167
 TProofBench.cxx:168
 TProofBench.cxx:169
 TProofBench.cxx:170
 TProofBench.cxx:171
 TProofBench.cxx:172
 TProofBench.cxx:173
 TProofBench.cxx:174
 TProofBench.cxx:175
 TProofBench.cxx:176
 TProofBench.cxx:177
 TProofBench.cxx:178
 TProofBench.cxx:179
 TProofBench.cxx:180
 TProofBench.cxx:181
 TProofBench.cxx:182
 TProofBench.cxx:183
 TProofBench.cxx:184
 TProofBench.cxx:185
 TProofBench.cxx:186
 TProofBench.cxx:187
 TProofBench.cxx:188
 TProofBench.cxx:189
 TProofBench.cxx:190
 TProofBench.cxx:191
 TProofBench.cxx:192
 TProofBench.cxx:193
 TProofBench.cxx:194
 TProofBench.cxx:195
 TProofBench.cxx:196
 TProofBench.cxx:197
 TProofBench.cxx:198
 TProofBench.cxx:199
 TProofBench.cxx:200
 TProofBench.cxx:201
 TProofBench.cxx:202
 TProofBench.cxx:203
 TProofBench.cxx:204
 TProofBench.cxx:205
 TProofBench.cxx:206
 TProofBench.cxx:207
 TProofBench.cxx:208
 TProofBench.cxx:209
 TProofBench.cxx:210
 TProofBench.cxx:211
 TProofBench.cxx:212
 TProofBench.cxx:213
 TProofBench.cxx:214
 TProofBench.cxx:215
 TProofBench.cxx:216
 TProofBench.cxx:217
 TProofBench.cxx:218
 TProofBench.cxx:219
 TProofBench.cxx:220
 TProofBench.cxx:221
 TProofBench.cxx:222
 TProofBench.cxx:223
 TProofBench.cxx:224
 TProofBench.cxx:225
 TProofBench.cxx:226
 TProofBench.cxx:227
 TProofBench.cxx:228
 TProofBench.cxx:229
 TProofBench.cxx:230
 TProofBench.cxx:231
 TProofBench.cxx:232
 TProofBench.cxx:233
 TProofBench.cxx:234
 TProofBench.cxx:235
 TProofBench.cxx:236
 TProofBench.cxx:237
 TProofBench.cxx:238
 TProofBench.cxx:239
 TProofBench.cxx:240
 TProofBench.cxx:241
 TProofBench.cxx:242
 TProofBench.cxx:243
 TProofBench.cxx:244
 TProofBench.cxx:245
 TProofBench.cxx:246
 TProofBench.cxx:247
 TProofBench.cxx:248
 TProofBench.cxx:249
 TProofBench.cxx:250
 TProofBench.cxx:251
 TProofBench.cxx:252
 TProofBench.cxx:253
 TProofBench.cxx:254
 TProofBench.cxx:255
 TProofBench.cxx:256
 TProofBench.cxx:257
 TProofBench.cxx:258
 TProofBench.cxx:259
 TProofBench.cxx:260
 TProofBench.cxx:261
 TProofBench.cxx:262
 TProofBench.cxx:263
 TProofBench.cxx:264
 TProofBench.cxx:265
 TProofBench.cxx:266
 TProofBench.cxx:267
 TProofBench.cxx:268
 TProofBench.cxx:269
 TProofBench.cxx:270
 TProofBench.cxx:271
 TProofBench.cxx:272
 TProofBench.cxx:273
 TProofBench.cxx:274
 TProofBench.cxx:275
 TProofBench.cxx:276
 TProofBench.cxx:277
 TProofBench.cxx:278
 TProofBench.cxx:279
 TProofBench.cxx:280
 TProofBench.cxx:281
 TProofBench.cxx:282
 TProofBench.cxx:283
 TProofBench.cxx:284
 TProofBench.cxx:285
 TProofBench.cxx:286
 TProofBench.cxx:287
 TProofBench.cxx:288
 TProofBench.cxx:289
 TProofBench.cxx:290
 TProofBench.cxx:291
 TProofBench.cxx:292
 TProofBench.cxx:293
 TProofBench.cxx:294
 TProofBench.cxx:295
 TProofBench.cxx:296
 TProofBench.cxx:297
 TProofBench.cxx:298
 TProofBench.cxx:299
 TProofBench.cxx:300
 TProofBench.cxx:301
 TProofBench.cxx:302
 TProofBench.cxx:303
 TProofBench.cxx:304
 TProofBench.cxx:305
 TProofBench.cxx:306
 TProofBench.cxx:307
 TProofBench.cxx:308
 TProofBench.cxx:309
 TProofBench.cxx:310
 TProofBench.cxx:311
 TProofBench.cxx:312
 TProofBench.cxx:313
 TProofBench.cxx:314
 TProofBench.cxx:315
 TProofBench.cxx:316
 TProofBench.cxx:317
 TProofBench.cxx:318
 TProofBench.cxx:319
 TProofBench.cxx:320
 TProofBench.cxx:321
 TProofBench.cxx:322
 TProofBench.cxx:323
 TProofBench.cxx:324
 TProofBench.cxx:325
 TProofBench.cxx:326
 TProofBench.cxx:327
 TProofBench.cxx:328
 TProofBench.cxx:329
 TProofBench.cxx:330
 TProofBench.cxx:331
 TProofBench.cxx:332
 TProofBench.cxx:333
 TProofBench.cxx:334
 TProofBench.cxx:335
 TProofBench.cxx:336
 TProofBench.cxx:337
 TProofBench.cxx:338
 TProofBench.cxx:339
 TProofBench.cxx:340
 TProofBench.cxx:341
 TProofBench.cxx:342
 TProofBench.cxx:343
 TProofBench.cxx:344
 TProofBench.cxx:345
 TProofBench.cxx:346
 TProofBench.cxx:347
 TProofBench.cxx:348
 TProofBench.cxx:349
 TProofBench.cxx:350
 TProofBench.cxx:351
 TProofBench.cxx:352
 TProofBench.cxx:353
 TProofBench.cxx:354
 TProofBench.cxx:355
 TProofBench.cxx:356
 TProofBench.cxx:357
 TProofBench.cxx:358
 TProofBench.cxx:359
 TProofBench.cxx:360
 TProofBench.cxx:361
 TProofBench.cxx:362
 TProofBench.cxx:363
 TProofBench.cxx:364
 TProofBench.cxx:365
 TProofBench.cxx:366
 TProofBench.cxx:367
 TProofBench.cxx:368
 TProofBench.cxx:369
 TProofBench.cxx:370
 TProofBench.cxx:371
 TProofBench.cxx:372
 TProofBench.cxx:373
 TProofBench.cxx:374
 TProofBench.cxx:375
 TProofBench.cxx:376
 TProofBench.cxx:377
 TProofBench.cxx:378
 TProofBench.cxx:379
 TProofBench.cxx:380
 TProofBench.cxx:381
 TProofBench.cxx:382
 TProofBench.cxx:383
 TProofBench.cxx:384
 TProofBench.cxx:385
 TProofBench.cxx:386
 TProofBench.cxx:387
 TProofBench.cxx:388
 TProofBench.cxx:389
 TProofBench.cxx:390
 TProofBench.cxx:391
 TProofBench.cxx:392
 TProofBench.cxx:393
 TProofBench.cxx:394
 TProofBench.cxx:395
 TProofBench.cxx:396
 TProofBench.cxx:397
 TProofBench.cxx:398
 TProofBench.cxx:399
 TProofBench.cxx:400
 TProofBench.cxx:401
 TProofBench.cxx:402
 TProofBench.cxx:403
 TProofBench.cxx:404
 TProofBench.cxx:405
 TProofBench.cxx:406
 TProofBench.cxx:407
 TProofBench.cxx:408
 TProofBench.cxx:409
 TProofBench.cxx:410
 TProofBench.cxx:411
 TProofBench.cxx:412
 TProofBench.cxx:413
 TProofBench.cxx:414
 TProofBench.cxx:415
 TProofBench.cxx:416
 TProofBench.cxx:417
 TProofBench.cxx:418
 TProofBench.cxx:419
 TProofBench.cxx:420
 TProofBench.cxx:421
 TProofBench.cxx:422
 TProofBench.cxx:423
 TProofBench.cxx:424
 TProofBench.cxx:425
 TProofBench.cxx:426
 TProofBench.cxx:427
 TProofBench.cxx:428
 TProofBench.cxx:429
 TProofBench.cxx:430
 TProofBench.cxx:431
 TProofBench.cxx:432
 TProofBench.cxx:433
 TProofBench.cxx:434
 TProofBench.cxx:435
 TProofBench.cxx:436
 TProofBench.cxx:437
 TProofBench.cxx:438
 TProofBench.cxx:439
 TProofBench.cxx:440
 TProofBench.cxx:441
 TProofBench.cxx:442
 TProofBench.cxx:443
 TProofBench.cxx:444
 TProofBench.cxx:445
 TProofBench.cxx:446
 TProofBench.cxx:447
 TProofBench.cxx:448
 TProofBench.cxx:449
 TProofBench.cxx:450
 TProofBench.cxx:451
 TProofBench.cxx:452
 TProofBench.cxx:453
 TProofBench.cxx:454
 TProofBench.cxx:455
 TProofBench.cxx:456
 TProofBench.cxx:457
 TProofBench.cxx:458
 TProofBench.cxx:459
 TProofBench.cxx:460
 TProofBench.cxx:461
 TProofBench.cxx:462
 TProofBench.cxx:463
 TProofBench.cxx:464
 TProofBench.cxx:465
 TProofBench.cxx:466
 TProofBench.cxx:467
 TProofBench.cxx:468
 TProofBench.cxx:469
 TProofBench.cxx:470
 TProofBench.cxx:471
 TProofBench.cxx:472
 TProofBench.cxx:473
 TProofBench.cxx:474
 TProofBench.cxx:475
 TProofBench.cxx:476
 TProofBench.cxx:477
 TProofBench.cxx:478
 TProofBench.cxx:479
 TProofBench.cxx:480
 TProofBench.cxx:481
 TProofBench.cxx:482
 TProofBench.cxx:483
 TProofBench.cxx:484
 TProofBench.cxx:485
 TProofBench.cxx:486
 TProofBench.cxx:487
 TProofBench.cxx:488
 TProofBench.cxx:489
 TProofBench.cxx:490
 TProofBench.cxx:491
 TProofBench.cxx:492
 TProofBench.cxx:493
 TProofBench.cxx:494
 TProofBench.cxx:495
 TProofBench.cxx:496
 TProofBench.cxx:497
 TProofBench.cxx:498
 TProofBench.cxx:499
 TProofBench.cxx:500
 TProofBench.cxx:501
 TProofBench.cxx:502
 TProofBench.cxx:503
 TProofBench.cxx:504
 TProofBench.cxx:505
 TProofBench.cxx:506
 TProofBench.cxx:507
 TProofBench.cxx:508
 TProofBench.cxx:509
 TProofBench.cxx:510
 TProofBench.cxx:511
 TProofBench.cxx:512
 TProofBench.cxx:513
 TProofBench.cxx:514
 TProofBench.cxx:515
 TProofBench.cxx:516
 TProofBench.cxx:517
 TProofBench.cxx:518
 TProofBench.cxx:519
 TProofBench.cxx:520
 TProofBench.cxx:521
 TProofBench.cxx:522
 TProofBench.cxx:523
 TProofBench.cxx:524
 TProofBench.cxx:525
 TProofBench.cxx:526
 TProofBench.cxx:527
 TProofBench.cxx:528
 TProofBench.cxx:529
 TProofBench.cxx:530
 TProofBench.cxx:531
 TProofBench.cxx:532
 TProofBench.cxx:533
 TProofBench.cxx:534
 TProofBench.cxx:535
 TProofBench.cxx:536
 TProofBench.cxx:537
 TProofBench.cxx:538
 TProofBench.cxx:539
 TProofBench.cxx:540
 TProofBench.cxx:541
 TProofBench.cxx:542
 TProofBench.cxx:543
 TProofBench.cxx:544
 TProofBench.cxx:545
 TProofBench.cxx:546
 TProofBench.cxx:547
 TProofBench.cxx:548
 TProofBench.cxx:549
 TProofBench.cxx:550
 TProofBench.cxx:551
 TProofBench.cxx:552
 TProofBench.cxx:553
 TProofBench.cxx:554
 TProofBench.cxx:555
 TProofBench.cxx:556
 TProofBench.cxx:557
 TProofBench.cxx:558
 TProofBench.cxx:559
 TProofBench.cxx:560
 TProofBench.cxx:561
 TProofBench.cxx:562
 TProofBench.cxx:563
 TProofBench.cxx:564
 TProofBench.cxx:565
 TProofBench.cxx:566
 TProofBench.cxx:567
 TProofBench.cxx:568
 TProofBench.cxx:569
 TProofBench.cxx:570
 TProofBench.cxx:571
 TProofBench.cxx:572
 TProofBench.cxx:573
 TProofBench.cxx:574
 TProofBench.cxx:575
 TProofBench.cxx:576
 TProofBench.cxx:577
 TProofBench.cxx:578
 TProofBench.cxx:579
 TProofBench.cxx:580
 TProofBench.cxx:581
 TProofBench.cxx:582
 TProofBench.cxx:583
 TProofBench.cxx:584
 TProofBench.cxx:585
 TProofBench.cxx:586
 TProofBench.cxx:587
 TProofBench.cxx:588
 TProofBench.cxx:589
 TProofBench.cxx:590
 TProofBench.cxx:591
 TProofBench.cxx:592
 TProofBench.cxx:593
 TProofBench.cxx:594
 TProofBench.cxx:595
 TProofBench.cxx:596
 TProofBench.cxx:597
 TProofBench.cxx:598
 TProofBench.cxx:599
 TProofBench.cxx:600
 TProofBench.cxx:601
 TProofBench.cxx:602
 TProofBench.cxx:603
 TProofBench.cxx:604
 TProofBench.cxx:605
 TProofBench.cxx:606
 TProofBench.cxx:607
 TProofBench.cxx:608
 TProofBench.cxx:609
 TProofBench.cxx:610
 TProofBench.cxx:611
 TProofBench.cxx:612
 TProofBench.cxx:613
 TProofBench.cxx:614
 TProofBench.cxx:615
 TProofBench.cxx:616
 TProofBench.cxx:617
 TProofBench.cxx:618
 TProofBench.cxx:619
 TProofBench.cxx:620
 TProofBench.cxx:621
 TProofBench.cxx:622
 TProofBench.cxx:623
 TProofBench.cxx:624
 TProofBench.cxx:625
 TProofBench.cxx:626
 TProofBench.cxx:627
 TProofBench.cxx:628
 TProofBench.cxx:629
 TProofBench.cxx:630
 TProofBench.cxx:631
 TProofBench.cxx:632
 TProofBench.cxx:633
 TProofBench.cxx:634
 TProofBench.cxx:635
 TProofBench.cxx:636
 TProofBench.cxx:637
 TProofBench.cxx:638
 TProofBench.cxx:639
 TProofBench.cxx:640
 TProofBench.cxx:641
 TProofBench.cxx:642
 TProofBench.cxx:643
 TProofBench.cxx:644
 TProofBench.cxx:645
 TProofBench.cxx:646
 TProofBench.cxx:647
 TProofBench.cxx:648
 TProofBench.cxx:649
 TProofBench.cxx:650
 TProofBench.cxx:651
 TProofBench.cxx:652
 TProofBench.cxx:653
 TProofBench.cxx:654
 TProofBench.cxx:655
 TProofBench.cxx:656
 TProofBench.cxx:657
 TProofBench.cxx:658
 TProofBench.cxx:659
 TProofBench.cxx:660
 TProofBench.cxx:661
 TProofBench.cxx:662
 TProofBench.cxx:663
 TProofBench.cxx:664
 TProofBench.cxx:665
 TProofBench.cxx:666
 TProofBench.cxx:667
 TProofBench.cxx:668
 TProofBench.cxx:669
 TProofBench.cxx:670
 TProofBench.cxx:671
 TProofBench.cxx:672
 TProofBench.cxx:673
 TProofBench.cxx:674
 TProofBench.cxx:675
 TProofBench.cxx:676
 TProofBench.cxx:677
 TProofBench.cxx:678
 TProofBench.cxx:679
 TProofBench.cxx:680
 TProofBench.cxx:681
 TProofBench.cxx:682
 TProofBench.cxx:683
 TProofBench.cxx:684
 TProofBench.cxx:685
 TProofBench.cxx:686
 TProofBench.cxx:687
 TProofBench.cxx:688
 TProofBench.cxx:689
 TProofBench.cxx:690
 TProofBench.cxx:691
 TProofBench.cxx:692
 TProofBench.cxx:693
 TProofBench.cxx:694
 TProofBench.cxx:695
 TProofBench.cxx:696
 TProofBench.cxx:697
 TProofBench.cxx:698
 TProofBench.cxx:699
 TProofBench.cxx:700
 TProofBench.cxx:701
 TProofBench.cxx:702
 TProofBench.cxx:703
 TProofBench.cxx:704
 TProofBench.cxx:705
 TProofBench.cxx:706
 TProofBench.cxx:707
 TProofBench.cxx:708
 TProofBench.cxx:709
 TProofBench.cxx:710
 TProofBench.cxx:711
 TProofBench.cxx:712
 TProofBench.cxx:713
 TProofBench.cxx:714
 TProofBench.cxx:715
 TProofBench.cxx:716
 TProofBench.cxx:717
 TProofBench.cxx:718
 TProofBench.cxx:719
 TProofBench.cxx:720
 TProofBench.cxx:721
 TProofBench.cxx:722
 TProofBench.cxx:723
 TProofBench.cxx:724
 TProofBench.cxx:725
 TProofBench.cxx:726
 TProofBench.cxx:727
 TProofBench.cxx:728
 TProofBench.cxx:729
 TProofBench.cxx:730
 TProofBench.cxx:731
 TProofBench.cxx:732
 TProofBench.cxx:733
 TProofBench.cxx:734
 TProofBench.cxx:735
 TProofBench.cxx:736
 TProofBench.cxx:737
 TProofBench.cxx:738
 TProofBench.cxx:739
 TProofBench.cxx:740
 TProofBench.cxx:741
 TProofBench.cxx:742
 TProofBench.cxx:743
 TProofBench.cxx:744
 TProofBench.cxx:745
 TProofBench.cxx:746
 TProofBench.cxx:747
 TProofBench.cxx:748
 TProofBench.cxx:749
 TProofBench.cxx:750
 TProofBench.cxx:751
 TProofBench.cxx:752
 TProofBench.cxx:753
 TProofBench.cxx:754
 TProofBench.cxx:755
 TProofBench.cxx:756
 TProofBench.cxx:757
 TProofBench.cxx:758
 TProofBench.cxx:759
 TProofBench.cxx:760
 TProofBench.cxx:761
 TProofBench.cxx:762
 TProofBench.cxx:763
 TProofBench.cxx:764
 TProofBench.cxx:765
 TProofBench.cxx:766
 TProofBench.cxx:767
 TProofBench.cxx:768
 TProofBench.cxx:769
 TProofBench.cxx:770
 TProofBench.cxx:771
 TProofBench.cxx:772
 TProofBench.cxx:773
 TProofBench.cxx:774
 TProofBench.cxx:775
 TProofBench.cxx:776
 TProofBench.cxx:777
 TProofBench.cxx:778
 TProofBench.cxx:779
 TProofBench.cxx:780
 TProofBench.cxx:781
 TProofBench.cxx:782
 TProofBench.cxx:783
 TProofBench.cxx:784
 TProofBench.cxx:785
 TProofBench.cxx:786
 TProofBench.cxx:787
 TProofBench.cxx:788
 TProofBench.cxx:789
 TProofBench.cxx:790
 TProofBench.cxx:791
 TProofBench.cxx:792
 TProofBench.cxx:793
 TProofBench.cxx:794
 TProofBench.cxx:795
 TProofBench.cxx:796
 TProofBench.cxx:797
 TProofBench.cxx:798
 TProofBench.cxx:799
 TProofBench.cxx:800
 TProofBench.cxx:801
 TProofBench.cxx:802
 TProofBench.cxx:803
 TProofBench.cxx:804
 TProofBench.cxx:805
 TProofBench.cxx:806
 TProofBench.cxx:807
 TProofBench.cxx:808
 TProofBench.cxx:809
 TProofBench.cxx:810
 TProofBench.cxx:811
 TProofBench.cxx:812
 TProofBench.cxx:813
 TProofBench.cxx:814
 TProofBench.cxx:815
 TProofBench.cxx:816
 TProofBench.cxx:817
 TProofBench.cxx:818
 TProofBench.cxx:819
 TProofBench.cxx:820
 TProofBench.cxx:821
 TProofBench.cxx:822
 TProofBench.cxx:823
 TProofBench.cxx:824
 TProofBench.cxx:825
 TProofBench.cxx:826
 TProofBench.cxx:827
 TProofBench.cxx:828
 TProofBench.cxx:829
 TProofBench.cxx:830
 TProofBench.cxx:831
 TProofBench.cxx:832
 TProofBench.cxx:833
 TProofBench.cxx:834
 TProofBench.cxx:835
 TProofBench.cxx:836
 TProofBench.cxx:837
 TProofBench.cxx:838
 TProofBench.cxx:839
 TProofBench.cxx:840
 TProofBench.cxx:841
 TProofBench.cxx:842
 TProofBench.cxx:843
 TProofBench.cxx:844
 TProofBench.cxx:845
 TProofBench.cxx:846
 TProofBench.cxx:847
 TProofBench.cxx:848
 TProofBench.cxx:849
 TProofBench.cxx:850
 TProofBench.cxx:851
 TProofBench.cxx:852
 TProofBench.cxx:853
 TProofBench.cxx:854
 TProofBench.cxx:855
 TProofBench.cxx:856
 TProofBench.cxx:857
 TProofBench.cxx:858
 TProofBench.cxx:859
 TProofBench.cxx:860
 TProofBench.cxx:861
 TProofBench.cxx:862
 TProofBench.cxx:863
 TProofBench.cxx:864
 TProofBench.cxx:865
 TProofBench.cxx:866
 TProofBench.cxx:867
 TProofBench.cxx:868
 TProofBench.cxx:869
 TProofBench.cxx:870
 TProofBench.cxx:871
 TProofBench.cxx:872
 TProofBench.cxx:873
 TProofBench.cxx:874
 TProofBench.cxx:875
 TProofBench.cxx:876
 TProofBench.cxx:877
 TProofBench.cxx:878
 TProofBench.cxx:879
 TProofBench.cxx:880
 TProofBench.cxx:881
 TProofBench.cxx:882
 TProofBench.cxx:883
 TProofBench.cxx:884
 TProofBench.cxx:885
 TProofBench.cxx:886
 TProofBench.cxx:887
 TProofBench.cxx:888
 TProofBench.cxx:889
 TProofBench.cxx:890
 TProofBench.cxx:891
 TProofBench.cxx:892
 TProofBench.cxx:893
 TProofBench.cxx:894
 TProofBench.cxx:895
 TProofBench.cxx:896
 TProofBench.cxx:897
 TProofBench.cxx:898
 TProofBench.cxx:899
 TProofBench.cxx:900
 TProofBench.cxx:901
 TProofBench.cxx:902
 TProofBench.cxx:903
 TProofBench.cxx:904
 TProofBench.cxx:905
 TProofBench.cxx:906
 TProofBench.cxx:907
 TProofBench.cxx:908
 TProofBench.cxx:909
 TProofBench.cxx:910
 TProofBench.cxx:911
 TProofBench.cxx:912
 TProofBench.cxx:913
 TProofBench.cxx:914
 TProofBench.cxx:915
 TProofBench.cxx:916
 TProofBench.cxx:917
 TProofBench.cxx:918
 TProofBench.cxx:919
 TProofBench.cxx:920
 TProofBench.cxx:921
 TProofBench.cxx:922
 TProofBench.cxx:923
 TProofBench.cxx:924
 TProofBench.cxx:925
 TProofBench.cxx:926
 TProofBench.cxx:927
 TProofBench.cxx:928
 TProofBench.cxx:929
 TProofBench.cxx:930
 TProofBench.cxx:931
 TProofBench.cxx:932
 TProofBench.cxx:933
 TProofBench.cxx:934
 TProofBench.cxx:935
 TProofBench.cxx:936
 TProofBench.cxx:937
 TProofBench.cxx:938
 TProofBench.cxx:939
 TProofBench.cxx:940
 TProofBench.cxx:941
 TProofBench.cxx:942
 TProofBench.cxx:943
 TProofBench.cxx:944
 TProofBench.cxx:945
 TProofBench.cxx:946
 TProofBench.cxx:947
 TProofBench.cxx:948
 TProofBench.cxx:949
 TProofBench.cxx:950
 TProofBench.cxx:951
 TProofBench.cxx:952
 TProofBench.cxx:953
 TProofBench.cxx:954
 TProofBench.cxx:955
 TProofBench.cxx:956
 TProofBench.cxx:957
 TProofBench.cxx:958
 TProofBench.cxx:959
 TProofBench.cxx:960
 TProofBench.cxx:961
 TProofBench.cxx:962
 TProofBench.cxx:963
 TProofBench.cxx:964
 TProofBench.cxx:965
 TProofBench.cxx:966
 TProofBench.cxx:967
 TProofBench.cxx:968
 TProofBench.cxx:969
 TProofBench.cxx:970
 TProofBench.cxx:971
 TProofBench.cxx:972
 TProofBench.cxx:973
 TProofBench.cxx:974
 TProofBench.cxx:975
 TProofBench.cxx:976
 TProofBench.cxx:977
 TProofBench.cxx:978
 TProofBench.cxx:979
 TProofBench.cxx:980
 TProofBench.cxx:981
 TProofBench.cxx:982
 TProofBench.cxx:983
 TProofBench.cxx:984
 TProofBench.cxx:985
 TProofBench.cxx:986
 TProofBench.cxx:987
 TProofBench.cxx:988
 TProofBench.cxx:989
 TProofBench.cxx:990
 TProofBench.cxx:991
 TProofBench.cxx:992
 TProofBench.cxx:993
 TProofBench.cxx:994
 TProofBench.cxx:995
 TProofBench.cxx:996
 TProofBench.cxx:997
 TProofBench.cxx:998
 TProofBench.cxx:999
 TProofBench.cxx:1000
 TProofBench.cxx:1001
 TProofBench.cxx:1002
 TProofBench.cxx:1003
 TProofBench.cxx:1004
 TProofBench.cxx:1005
 TProofBench.cxx:1006
 TProofBench.cxx:1007
 TProofBench.cxx:1008
 TProofBench.cxx:1009
 TProofBench.cxx:1010
 TProofBench.cxx:1011
 TProofBench.cxx:1012
 TProofBench.cxx:1013
 TProofBench.cxx:1014
 TProofBench.cxx:1015
 TProofBench.cxx:1016
 TProofBench.cxx:1017
 TProofBench.cxx:1018
 TProofBench.cxx:1019
 TProofBench.cxx:1020
 TProofBench.cxx:1021
 TProofBench.cxx:1022
 TProofBench.cxx:1023
 TProofBench.cxx:1024
 TProofBench.cxx:1025
 TProofBench.cxx:1026
 TProofBench.cxx:1027
 TProofBench.cxx:1028
 TProofBench.cxx:1029
 TProofBench.cxx:1030
 TProofBench.cxx:1031
 TProofBench.cxx:1032
 TProofBench.cxx:1033
 TProofBench.cxx:1034
 TProofBench.cxx:1035
 TProofBench.cxx:1036
 TProofBench.cxx:1037
 TProofBench.cxx:1038
 TProofBench.cxx:1039
 TProofBench.cxx:1040
 TProofBench.cxx:1041
 TProofBench.cxx:1042
 TProofBench.cxx:1043
 TProofBench.cxx:1044
 TProofBench.cxx:1045
 TProofBench.cxx:1046
 TProofBench.cxx:1047
 TProofBench.cxx:1048
 TProofBench.cxx:1049
 TProofBench.cxx:1050
 TProofBench.cxx:1051
 TProofBench.cxx:1052
 TProofBench.cxx:1053
 TProofBench.cxx:1054
 TProofBench.cxx:1055
 TProofBench.cxx:1056
 TProofBench.cxx:1057
 TProofBench.cxx:1058
 TProofBench.cxx:1059
 TProofBench.cxx:1060
 TProofBench.cxx:1061
 TProofBench.cxx:1062
 TProofBench.cxx:1063
 TProofBench.cxx:1064
 TProofBench.cxx:1065
 TProofBench.cxx:1066
 TProofBench.cxx:1067
 TProofBench.cxx:1068
 TProofBench.cxx:1069
 TProofBench.cxx:1070
 TProofBench.cxx:1071
 TProofBench.cxx:1072
 TProofBench.cxx:1073
 TProofBench.cxx:1074
 TProofBench.cxx:1075
 TProofBench.cxx:1076
 TProofBench.cxx:1077
 TProofBench.cxx:1078
 TProofBench.cxx:1079
 TProofBench.cxx:1080
 TProofBench.cxx:1081
 TProofBench.cxx:1082
 TProofBench.cxx:1083
 TProofBench.cxx:1084
 TProofBench.cxx:1085
 TProofBench.cxx:1086
 TProofBench.cxx:1087
 TProofBench.cxx:1088
 TProofBench.cxx:1089
 TProofBench.cxx:1090
 TProofBench.cxx:1091
 TProofBench.cxx:1092
 TProofBench.cxx:1093
 TProofBench.cxx:1094
 TProofBench.cxx:1095
 TProofBench.cxx:1096
 TProofBench.cxx:1097
 TProofBench.cxx:1098
 TProofBench.cxx:1099
 TProofBench.cxx:1100
 TProofBench.cxx:1101
 TProofBench.cxx:1102
 TProofBench.cxx:1103
 TProofBench.cxx:1104
 TProofBench.cxx:1105
 TProofBench.cxx:1106
 TProofBench.cxx:1107
 TProofBench.cxx:1108
 TProofBench.cxx:1109
 TProofBench.cxx:1110
 TProofBench.cxx:1111
 TProofBench.cxx:1112
 TProofBench.cxx:1113
 TProofBench.cxx:1114
 TProofBench.cxx:1115
 TProofBench.cxx:1116
 TProofBench.cxx:1117
 TProofBench.cxx:1118
 TProofBench.cxx:1119
 TProofBench.cxx:1120
 TProofBench.cxx:1121
 TProofBench.cxx:1122
 TProofBench.cxx:1123
 TProofBench.cxx:1124
 TProofBench.cxx:1125
 TProofBench.cxx:1126
 TProofBench.cxx:1127
 TProofBench.cxx:1128
 TProofBench.cxx:1129
 TProofBench.cxx:1130
 TProofBench.cxx:1131
 TProofBench.cxx:1132
 TProofBench.cxx:1133
 TProofBench.cxx:1134
 TProofBench.cxx:1135
 TProofBench.cxx:1136
 TProofBench.cxx:1137
 TProofBench.cxx:1138
 TProofBench.cxx:1139
 TProofBench.cxx:1140
 TProofBench.cxx:1141
 TProofBench.cxx:1142
 TProofBench.cxx:1143
 TProofBench.cxx:1144
 TProofBench.cxx:1145
 TProofBench.cxx:1146
 TProofBench.cxx:1147
 TProofBench.cxx:1148
 TProofBench.cxx:1149
 TProofBench.cxx:1150
 TProofBench.cxx:1151
 TProofBench.cxx:1152
 TProofBench.cxx:1153
 TProofBench.cxx:1154
 TProofBench.cxx:1155
 TProofBench.cxx:1156
 TProofBench.cxx:1157
 TProofBench.cxx:1158
 TProofBench.cxx:1159
 TProofBench.cxx:1160
 TProofBench.cxx:1161
 TProofBench.cxx:1162
 TProofBench.cxx:1163
 TProofBench.cxx:1164
 TProofBench.cxx:1165
 TProofBench.cxx:1166
 TProofBench.cxx:1167
 TProofBench.cxx:1168
 TProofBench.cxx:1169
 TProofBench.cxx:1170
 TProofBench.cxx:1171
 TProofBench.cxx:1172
 TProofBench.cxx:1173
 TProofBench.cxx:1174
 TProofBench.cxx:1175
 TProofBench.cxx:1176
 TProofBench.cxx:1177
 TProofBench.cxx:1178
 TProofBench.cxx:1179
 TProofBench.cxx:1180
 TProofBench.cxx:1181
 TProofBench.cxx:1182
 TProofBench.cxx:1183
 TProofBench.cxx:1184
 TProofBench.cxx:1185
 TProofBench.cxx:1186
 TProofBench.cxx:1187
 TProofBench.cxx:1188
 TProofBench.cxx:1189
 TProofBench.cxx:1190
 TProofBench.cxx:1191
 TProofBench.cxx:1192
 TProofBench.cxx:1193
 TProofBench.cxx:1194
 TProofBench.cxx:1195
 TProofBench.cxx:1196
 TProofBench.cxx:1197
 TProofBench.cxx:1198
 TProofBench.cxx:1199
 TProofBench.cxx:1200
 TProofBench.cxx:1201
 TProofBench.cxx:1202
 TProofBench.cxx:1203
 TProofBench.cxx:1204
 TProofBench.cxx:1205
 TProofBench.cxx:1206
 TProofBench.cxx:1207
 TProofBench.cxx:1208
 TProofBench.cxx:1209
 TProofBench.cxx:1210
 TProofBench.cxx:1211
 TProofBench.cxx:1212
 TProofBench.cxx:1213
 TProofBench.cxx:1214
 TProofBench.cxx:1215
 TProofBench.cxx:1216
 TProofBench.cxx:1217
 TProofBench.cxx:1218
 TProofBench.cxx:1219
 TProofBench.cxx:1220
 TProofBench.cxx:1221
 TProofBench.cxx:1222
 TProofBench.cxx:1223
 TProofBench.cxx:1224
 TProofBench.cxx:1225
 TProofBench.cxx:1226
 TProofBench.cxx:1227
 TProofBench.cxx:1228
 TProofBench.cxx:1229
 TProofBench.cxx:1230
 TProofBench.cxx:1231
 TProofBench.cxx:1232
 TProofBench.cxx:1233
 TProofBench.cxx:1234
 TProofBench.cxx:1235
 TProofBench.cxx:1236
 TProofBench.cxx:1237
 TProofBench.cxx:1238
 TProofBench.cxx:1239
 TProofBench.cxx:1240
 TProofBench.cxx:1241
 TProofBench.cxx:1242
 TProofBench.cxx:1243
 TProofBench.cxx:1244
 TProofBench.cxx:1245
 TProofBench.cxx:1246
 TProofBench.cxx:1247
 TProofBench.cxx:1248
 TProofBench.cxx:1249
 TProofBench.cxx:1250
 TProofBench.cxx:1251
 TProofBench.cxx:1252
 TProofBench.cxx:1253
 TProofBench.cxx:1254
 TProofBench.cxx:1255
 TProofBench.cxx:1256
 TProofBench.cxx:1257
 TProofBench.cxx:1258
 TProofBench.cxx:1259
 TProofBench.cxx:1260
 TProofBench.cxx:1261
 TProofBench.cxx:1262
 TProofBench.cxx:1263
 TProofBench.cxx:1264
 TProofBench.cxx:1265
 TProofBench.cxx:1266
 TProofBench.cxx:1267
 TProofBench.cxx:1268
 TProofBench.cxx:1269
 TProofBench.cxx:1270
 TProofBench.cxx:1271
 TProofBench.cxx:1272
 TProofBench.cxx:1273
 TProofBench.cxx:1274
 TProofBench.cxx:1275
 TProofBench.cxx:1276
 TProofBench.cxx:1277
 TProofBench.cxx:1278
 TProofBench.cxx:1279
 TProofBench.cxx:1280
 TProofBench.cxx:1281
 TProofBench.cxx:1282
 TProofBench.cxx:1283
 TProofBench.cxx:1284
 TProofBench.cxx:1285
 TProofBench.cxx:1286
 TProofBench.cxx:1287
 TProofBench.cxx:1288
 TProofBench.cxx:1289
 TProofBench.cxx:1290
 TProofBench.cxx:1291
 TProofBench.cxx:1292
 TProofBench.cxx:1293
 TProofBench.cxx:1294
 TProofBench.cxx:1295
 TProofBench.cxx:1296
 TProofBench.cxx:1297
 TProofBench.cxx:1298
 TProofBench.cxx:1299
 TProofBench.cxx:1300
 TProofBench.cxx:1301
 TProofBench.cxx:1302
 TProofBench.cxx:1303
 TProofBench.cxx:1304
 TProofBench.cxx:1305
 TProofBench.cxx:1306
 TProofBench.cxx:1307
 TProofBench.cxx:1308
 TProofBench.cxx:1309
 TProofBench.cxx:1310
 TProofBench.cxx:1311
 TProofBench.cxx:1312
 TProofBench.cxx:1313
 TProofBench.cxx:1314
 TProofBench.cxx:1315
 TProofBench.cxx:1316
 TProofBench.cxx:1317
 TProofBench.cxx:1318
 TProofBench.cxx:1319
 TProofBench.cxx:1320
 TProofBench.cxx:1321
 TProofBench.cxx:1322
 TProofBench.cxx:1323
 TProofBench.cxx:1324
 TProofBench.cxx:1325
 TProofBench.cxx:1326
 TProofBench.cxx:1327
 TProofBench.cxx:1328
 TProofBench.cxx:1329
 TProofBench.cxx:1330
 TProofBench.cxx:1331
 TProofBench.cxx:1332
 TProofBench.cxx:1333
 TProofBench.cxx:1334
 TProofBench.cxx:1335
 TProofBench.cxx:1336
 TProofBench.cxx:1337
 TProofBench.cxx:1338
 TProofBench.cxx:1339
 TProofBench.cxx:1340
 TProofBench.cxx:1341
 TProofBench.cxx:1342
 TProofBench.cxx:1343
 TProofBench.cxx:1344
 TProofBench.cxx:1345
 TProofBench.cxx:1346
 TProofBench.cxx:1347
 TProofBench.cxx:1348
 TProofBench.cxx:1349
 TProofBench.cxx:1350
 TProofBench.cxx:1351
 TProofBench.cxx:1352
 TProofBench.cxx:1353
 TProofBench.cxx:1354
 TProofBench.cxx:1355
 TProofBench.cxx:1356
 TProofBench.cxx:1357
 TProofBench.cxx:1358
 TProofBench.cxx:1359
 TProofBench.cxx:1360
 TProofBench.cxx:1361
 TProofBench.cxx:1362
 TProofBench.cxx:1363
 TProofBench.cxx:1364
 TProofBench.cxx:1365
 TProofBench.cxx:1366
 TProofBench.cxx:1367
 TProofBench.cxx:1368
 TProofBench.cxx:1369
 TProofBench.cxx:1370
 TProofBench.cxx:1371
 TProofBench.cxx:1372
 TProofBench.cxx:1373
 TProofBench.cxx:1374
 TProofBench.cxx:1375
 TProofBench.cxx:1376
 TProofBench.cxx:1377
 TProofBench.cxx:1378
 TProofBench.cxx:1379
 TProofBench.cxx:1380
 TProofBench.cxx:1381
 TProofBench.cxx:1382
 TProofBench.cxx:1383
 TProofBench.cxx:1384
 TProofBench.cxx:1385
 TProofBench.cxx:1386
 TProofBench.cxx:1387
 TProofBench.cxx:1388
 TProofBench.cxx:1389
 TProofBench.cxx:1390
 TProofBench.cxx:1391
 TProofBench.cxx:1392
 TProofBench.cxx:1393
 TProofBench.cxx:1394
 TProofBench.cxx:1395
 TProofBench.cxx:1396
 TProofBench.cxx:1397
 TProofBench.cxx:1398
 TProofBench.cxx:1399
 TProofBench.cxx:1400
 TProofBench.cxx:1401
 TProofBench.cxx:1402
 TProofBench.cxx:1403
 TProofBench.cxx:1404
 TProofBench.cxx:1405
 TProofBench.cxx:1406
 TProofBench.cxx:1407
 TProofBench.cxx:1408
 TProofBench.cxx:1409
 TProofBench.cxx:1410
 TProofBench.cxx:1411
 TProofBench.cxx:1412
 TProofBench.cxx:1413
 TProofBench.cxx:1414
 TProofBench.cxx:1415
 TProofBench.cxx:1416
 TProofBench.cxx:1417
 TProofBench.cxx:1418
 TProofBench.cxx:1419
 TProofBench.cxx:1420
 TProofBench.cxx:1421
 TProofBench.cxx:1422
 TProofBench.cxx:1423
 TProofBench.cxx:1424
 TProofBench.cxx:1425
 TProofBench.cxx:1426
 TProofBench.cxx:1427
 TProofBench.cxx:1428
 TProofBench.cxx:1429
 TProofBench.cxx:1430
 TProofBench.cxx:1431
 TProofBench.cxx:1432
 TProofBench.cxx:1433
 TProofBench.cxx:1434
 TProofBench.cxx:1435
 TProofBench.cxx:1436
 TProofBench.cxx:1437
 TProofBench.cxx:1438
 TProofBench.cxx:1439
 TProofBench.cxx:1440
 TProofBench.cxx:1441
 TProofBench.cxx:1442
 TProofBench.cxx:1443
 TProofBench.cxx:1444
 TProofBench.cxx:1445
 TProofBench.cxx:1446
 TProofBench.cxx:1447
 TProofBench.cxx:1448
 TProofBench.cxx:1449
 TProofBench.cxx:1450
 TProofBench.cxx:1451
 TProofBench.cxx:1452
 TProofBench.cxx:1453
 TProofBench.cxx:1454
 TProofBench.cxx:1455
 TProofBench.cxx:1456
 TProofBench.cxx:1457
 TProofBench.cxx:1458
 TProofBench.cxx:1459
 TProofBench.cxx:1460
 TProofBench.cxx:1461
 TProofBench.cxx:1462
 TProofBench.cxx:1463
 TProofBench.cxx:1464
 TProofBench.cxx:1465
 TProofBench.cxx:1466
 TProofBench.cxx:1467
 TProofBench.cxx:1468
 TProofBench.cxx:1469
 TProofBench.cxx:1470
 TProofBench.cxx:1471
 TProofBench.cxx:1472
 TProofBench.cxx:1473
 TProofBench.cxx:1474
 TProofBench.cxx:1475
 TProofBench.cxx:1476
 TProofBench.cxx:1477
 TProofBench.cxx:1478
 TProofBench.cxx:1479
 TProofBench.cxx:1480
 TProofBench.cxx:1481
 TProofBench.cxx:1482
 TProofBench.cxx:1483
 TProofBench.cxx:1484
 TProofBench.cxx:1485
 TProofBench.cxx:1486
 TProofBench.cxx:1487
 TProofBench.cxx:1488
 TProofBench.cxx:1489
 TProofBench.cxx:1490
 TProofBench.cxx:1491
 TProofBench.cxx:1492
 TProofBench.cxx:1493
 TProofBench.cxx:1494
 TProofBench.cxx:1495
 TProofBench.cxx:1496
 TProofBench.cxx:1497
 TProofBench.cxx:1498
 TProofBench.cxx:1499
 TProofBench.cxx:1500
 TProofBench.cxx:1501
 TProofBench.cxx:1502
 TProofBench.cxx:1503
 TProofBench.cxx:1504
 TProofBench.cxx:1505
 TProofBench.cxx:1506
 TProofBench.cxx:1507
 TProofBench.cxx:1508
 TProofBench.cxx:1509
 TProofBench.cxx:1510
 TProofBench.cxx:1511
 TProofBench.cxx:1512
 TProofBench.cxx:1513
 TProofBench.cxx:1514
 TProofBench.cxx:1515
 TProofBench.cxx:1516
 TProofBench.cxx:1517
 TProofBench.cxx:1518
 TProofBench.cxx:1519
 TProofBench.cxx:1520
 TProofBench.cxx:1521
 TProofBench.cxx:1522
 TProofBench.cxx:1523
 TProofBench.cxx:1524
 TProofBench.cxx:1525
 TProofBench.cxx:1526
 TProofBench.cxx:1527
 TProofBench.cxx:1528
 TProofBench.cxx:1529
 TProofBench.cxx:1530
 TProofBench.cxx:1531
 TProofBench.cxx:1532
 TProofBench.cxx:1533
 TProofBench.cxx:1534
 TProofBench.cxx:1535
 TProofBench.cxx:1536
 TProofBench.cxx:1537
 TProofBench.cxx:1538
 TProofBench.cxx:1539
 TProofBench.cxx:1540
 TProofBench.cxx:1541
 TProofBench.cxx:1542
 TProofBench.cxx:1543
 TProofBench.cxx:1544
 TProofBench.cxx:1545
 TProofBench.cxx:1546
 TProofBench.cxx:1547
 TProofBench.cxx:1548
 TProofBench.cxx:1549
 TProofBench.cxx:1550
 TProofBench.cxx:1551
 TProofBench.cxx:1552
 TProofBench.cxx:1553
 TProofBench.cxx:1554
 TProofBench.cxx:1555
 TProofBench.cxx:1556
 TProofBench.cxx:1557
 TProofBench.cxx:1558
 TProofBench.cxx:1559
 TProofBench.cxx:1560
 TProofBench.cxx:1561
 TProofBench.cxx:1562
 TProofBench.cxx:1563
 TProofBench.cxx:1564
 TProofBench.cxx:1565
 TProofBench.cxx:1566
 TProofBench.cxx:1567
 TProofBench.cxx:1568
 TProofBench.cxx:1569
 TProofBench.cxx:1570
 TProofBench.cxx:1571
 TProofBench.cxx:1572
 TProofBench.cxx:1573
 TProofBench.cxx:1574
 TProofBench.cxx:1575
 TProofBench.cxx:1576
 TProofBench.cxx:1577
 TProofBench.cxx:1578
 TProofBench.cxx:1579
 TProofBench.cxx:1580
 TProofBench.cxx:1581
 TProofBench.cxx:1582
 TProofBench.cxx:1583
 TProofBench.cxx:1584
 TProofBench.cxx:1585
 TProofBench.cxx:1586
 TProofBench.cxx:1587
 TProofBench.cxx:1588