ROOT logo

From $ROOTSYS/tutorials/proof/runProof.C

//
// Macro to run examples of analysis on PROOF, corresponding to the TSelector
// implementations found under <ROOTSYS>/tutorials/proof .
// This macro uses an existing PROOF session or starts one at the indicated URL.
// In the case non existing PROOF session is found and no URL is given, the
// macro tries to start a local PROOF session.
//
// To run the macro:
//
//   root[] .L proof/runProof.C+
//   root[] runProof("<analysis>")
//
//   Currently available analysis are (to see how all this really works check
//   the scope for the specified option inside the macro):
//
//   1. "simple"
//
//      Selector: ProofSimple.h.C
//
//      root[] runProof("simple")
//
//      This will create a local PROOF session and run an analysis filling
//      100 histos with 100000 gaussian random numbers, and displaying them
//      in a canvas with 100 pads (10x10).
//      The number of histograms can be passed as argument 'nhist' to 'simple',
//      e.g. to fill 16 histos with 1000000 entries use
//
//      root[] runProof("simple(nevt=1000000,nhist=16)")
//
//      The argument nhist3 controls the creation of 3d histos to simulate
//      merging load. By default, no 3D hitogram is created.
//
//   2. "h1"
//
//      Selector: tutorials/tree/h1analysis.h.C
//
//      root[] runProof("h1")
//
//      This runs the 'famous' H1 analysis from $ROOTSYS/tree/h1analysis.C.h.
//      By default the data are read from the HTTP server at root.cern.ch,
//      the data source can be changed via the argument 'h1src', e.g.
//
//      root[] runProof("h1,h1src=/data/h1")
//
//      (the directory specified must contain the 4 H1 files).
//
//      The 'h1' example is also used to show how to use entry-lists in PROOF.
//      To fill the list for the events used for the final plots add the option
//      'fillList':
//
//      root[] runProof("h1,fillList")
//
//      To use the list previously created for the events used for the 
//      final plots add the option 'useList':
//
//      root[] runProof("h1,useList")
//
//  3. "event"
//
//      Selector: ProofEvent.h,.C
//
//      This is an example of using PROOF par files.
//      It runs event generation and simple analysis based on the 'Event'
//      class found under test.
//
//      root[] runProof("event")
//
//  4. "eventproc"
//
//      Selector: ProofEventProc.h.C
//
//      This is an example of using PROOF par files and process 'event'
//      data from the ROOT HTTP server. It runs the ProofEventProc selector
//      which is derived from the EventTree_Proc one found under
//      test/ProofBench. The following specific arguments are available:
//      - 'readall'  to read the whole event, by default only the branches
//                   needed by the analysis are read (read 25% more bytes)
//      - 'datasrc=<dir-with-files>' to read the files from another server,
//                   the files must be named 'event_<num>.root' where <num>=1,2,...
//        or
//      - 'datasrc=<file-with-files>' to take the file content from a text file,
//                   specified one file per line; usefull when testing differences
//                   between several sources and distributions
//      - 'files=N'  to change the number of files to be analysed (default
//                   is 10, max is 50 for the HTTP server).
//      - 'uneven'   to process uneven entries from files following the scheme
//                   {50000,5000,5000,5000,5000} and so on
//
//      root[] runProof("eventproc")
//
//  5. "pythia8"
//
//      Selector: ProofPythia.h.C
//
//      This runs Pythia8 generation based on main03.cc example in Pythia 8.1 
//
//      To run this analysis ROOT must be configured with pythia8.
//
//      Note that before executing this analysis, the env variable PYTHIA8
//      must point to the pythia8100 (or newer) directory, in particular,
//      $PYTHIA8/xmldoc must contain the file Index.xml. The tutorial assumes
//      that the Pythia8 directory is the same on all machines, i.e. local
//      and worker ones.
//
//      root[] runProof("pythia8")
//
//  6. "ntuple"
//
//      Selector: ProofNtuple.h.C
//
//      This is an example of final merging via files created on the workers,
//      using TProofOutputFile. The final file is called ProofNtuple.root
//      and it is created in the directory where the tutorial is run. If
//      the PROOF cluster is remote, the file is received by a local xrootd
//      daemon started for the purpose. Because of this, this example can be
//      run only on unix clients.
//
//      root[] runProof("ntuple")
//
//  7. "dataset"
//
//      Selector: ProofNtuple.h.C
//
//      This is an example of automatic creation of a dataset from files
//      created on the workers, using TProofOutputFile. The dataset is
//      called testNtuple and it is automatically registered and verified.
//      The files contain the same ntuple as in previous example/tutorial 6
//      (the same selector ProofNTuple is used with a slightly different
//      configuration). The dataset is then used to produce the same plot
//      as in 5 but using the DrawSelect methods of PROOF, which also show
//      how to set style, color and other drawing attributes in PROOF.
//      Depending on the relative worker perforance, some of the produced
//      files may result in having no entries. If this happens, the file
//      will be added to the missing (skipped) file list. Increasing the
//      number of events (via nevt=...) typically solves this issue.
//
//      root[] runProof("dataset")
//
//  8. "friends"
//
//      Selectors: ProofFriends.h(.C), ProofAux.h(.C)
//
//      This is an example of TTree friend processing in PROOF. It also shows
//      how to use the TPacketizerFile to steer creation of files.
//
//      root[] runProof("friends")
//
//      The trees are by default created in separate files; to create
//      them in the same file use option 'samefile', e.g.
//
//      root[] runProof("friends(samefile)")
//
//   9. "simplefile"
//
//      Selector: ProofSimpleFile.h.C
//
//      root[] runProof("simplefile")
//
//      This will create a local PROOF session and run an analysis filling
//      16+16 histos with 100000 gaussian random numbers. The merging of
//      these histos goes via file; 16 histos are saved in the top directory,
//      the other 16 into a subdirectory called 'blue'. The final display
//      is done in two canvanses, one for each set of histograms and with
//      16 pads each (4x4).
//      The number of histograms in each set can be passed as argument
//      'nhist' to 'simplefile', e.g. to fill 25 histos with 1000000 entries use
//
//      root[] runProof("simplefile(nevt=1000000,nhist=25)")
//
//
//   General arguments
//   -----------------
//
//   The following arguments are valid for all examples (the ones specific
//   to each tutorial have been explained above)
//
//   0. ACLiC mode
//      By default all processing is done with ACLiC mode '+', i.e. compile
//      if changed. However, this may lead to problems if the available
//      selector libs were compiled in previous sessions with a different
//      set of loaded libraries (this is a general problem in ROOT). When
//      this happens the best solution is to force recompilation (ACLiC
//      mode '++'). To do this just add one or more '+' to the name of the
//      tutorial, e.g. runProof("simple++")
//
//   1. debug=[what:]level
//
//      Controls verbosity; 'level' is an integer number and the optional string
//      'what' one or more of the enum names in TProofDebug.h .
//      e.g. runProof("eventproc(debug=kPacketizer|kCollect:2)") runs 'eventproc' enabling
//           all printouts matching TProofDebug::kPacketizer and having level
//           equal or larger than 2 .
//
//   2. nevt=N
//
//      Set the number of entries to N
//      e.g. runProof("simple(nevt=1000000000)") runs simple with 1000000000
//
//   3. asyn
//
//      Run in non blocking mode
//      e.g. root[] runProof("h1(asyn)")
//
//   4. nwrk=N
//
//      Set the number of active workers to N, usefull to test performance
//      on a remote cluster where control about the number of workers is
//      not possible, e.g. runProof("event(nwrk=2)") runs 'event' with
//      2 workers.
//
//   5. punzip
//
//      Use parallel unzipping in reading files where relevant
//      e.g. root[] runProof("eventproc(punzip)")
//
//   6. cache=<bytes> (or <kbytes>K or <mbytes>M) 
//
//      Change the size of the tree cache; 0 or <0 disables the cache,
//      value cane be in bytes (no suffix), kilobytes (suffix 'K') or
//      megabytes (suffix 'M'), e.g. root[] runProof("eventproc(cache=0)") 
//
//   7. submergers[=S]
//
//      Enabling merging via S submergers or the optimal number if S is
//      not specified, e.g. root[] runProof("simple(hist=1000,submergers)") 
//
//   8. rateest=average
//
//      Enable processed entries estimation for constant progress reporting based on
//      the measured average. This may screw up the progress bar in some cases, which
//      is the reason why it is not on by default .
//      e.g. root[] runProof("eventproc(rateest=average)")
//
//   In all cases, to run on a remote PROOF cluster, the master URL must
//   be passed as second argument; e.g.
//
//      root[] runProof("simple","master.do.main")
//
//   In the case of local running it is possible to specify the number of
//   workers to start as third argument (the default is the number of cores
//   of the machine), e.g.
//
//      root[] runProof("simple",0,4)
//
//   will start 4 workers. Note that the real number of workers is changed
//   only the first time you call runProof into a ROOT session. Following
//   calls can reduce the number of active workers, but not increase it.
//   For example, in the same session of the call above starting 4 workers,
//   this
//
//   root[] runProof("simple",0,8)
//
//   will still use 4 workers, while this
//
//   root[] runProof("simple",0,2)
//
//   will disable 2 workers and use the other 2.
//


#include "TCanvas.h"
#include "TChain.h"
#include "TDrawFeedback.h"
#include "TDSet.h"
#include "TEnv.h"
#include "TEntryList.h"
#include "TFile.h"
#include "TFileCollection.h"
#include "TFrame.h"
#include "THashList.h"
#include "TList.h"
#include "TPad.h"
#include "TPaveText.h"
#include "TProof.h"
#include "TProofDebug.h"
#include "TString.h"

#include "getProof.C"
void plotNtuple(TProof *p, const char *ds, const char *ntptitle);
int getDebugEnum(const char *what);

TDrawFeedback *fb = 0;

// Variable used to locate the Pythia8 directory for the Pythia8 example
const char *pythia8dir = 0;
const char *pythia8data = 0;

void runProof(const char *what = "simple",
              const char *url = "proof://localhost:40000",
              Int_t nwrks = -1)
{
#ifdef __CINT__
   Printf("runProof: this script can only be executed via ACliC:");
   Printf("runProof:      root [] .x <path>/runProof.C+");
   Printf("runProof: or   root [] .L <path>/runProof.C+");
   Printf("runProof:      root [] runProof(...)");
   return;
#endif
   gEnv->SetValue("Proof.StatsHist",1);

   // Temp dir for PROOF tutorials
   // Force "/tmp/<user>" whenever possible to avoid length problems on MacOsX
   TString tmpdir("/tmp");
   if (gSystem->AccessPathName(tmpdir, kWritePermission)) tmpdir = gSystem->TempDirectory();
   TString us;
   UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid());
   if (!ug) {
      Printf("runProof: could not get user info");
      return;
   }
   us.Form("/%s", ug->fUser.Data());
   if (!tmpdir.EndsWith(us.Data())) tmpdir += us;
   gSystem->mkdir(tmpdir.Data(), kTRUE);
   if (gSystem->AccessPathName(tmpdir, kWritePermission)) {
      Printf("runProof: unable to get a writable tutorial directory (tried: %s)"
             " - cannot continue", tmpdir.Data());
      return;
   }
   TString tutdir = Form("%s/.proof-tutorial", tmpdir.Data());
   if (gSystem->AccessPathName(tutdir)) {
      Printf("runProof: creating the temporary directory"
                " for the tutorial (%s) ... ", tutdir.Data());
      if (gSystem->mkdir(tutdir, kTRUE) != 0) {
         Printf("runProof: could not assert / create the temporary directory"
                " for the tutorial (%s)", tutdir.Data());
         return;
      }
   }

   // For the Pythia8 example we need to set some environment variable;
   // This must be done BEFORE starting the PROOF session
   if (what && !strncmp(what, "pythia8", 7)) {
      // We assume that the remote location of Pythia8 is the same as the local one
      pythia8dir = gSystem->Getenv("PYTHIA8");
      if (!pythia8dir || strlen(pythia8dir) <= 0) {
         Printf("runProof: pythia8: environment variable PYTHIA8 undefined:"
                  " it must contain the path to pythia81xx root directory (local and remote) !");
         return;
      }
      pythia8data = gSystem->Getenv("PYTHIA8DATA");
      if (!pythia8data || strlen(pythia8data) <= 0) {
         gSystem->Setenv("PYTHIA8DATA", Form("%s/xmldoc", pythia8dir));
         pythia8data = gSystem->Getenv("PYTHIA8DATA");
         if (!pythia8data || strlen(pythia8data) <= 0) {
            Printf("runProof: pythia8: environment variable PYTHIA8DATA undefined:"
                   " it one must contain the path to pythia81xx/xmldoc"
                   " subdirectory (local and remote) !");
            return;
         }
      }
      TString env = Form("echo export PYTHIA8=%s; export PYTHIA8DATA=%s",
                         pythia8dir, pythia8data);
      TProof::AddEnvVar("PROOF_INITCMD", env.Data());
   }

   Printf("tutorial dir:\t%s", tutdir.Data());

   // Get the PROOF Session
   TProof *proof = getProof(url, nwrks, tutdir.Data(), "ask");
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }

   // Determine locality of this session
   Bool_t isProofLocal = kFALSE;
   TUrl uu(url);
   if (!strcmp(uu.GetHost(), "localhost") || proof->IsLite() ||
       !strcmp(uu.GetHostFQDN(), TUrl(gSystem->HostName()).GetHostFQDN())) {
      isProofLocal = kTRUE;
   }
#ifdef WIN32
   if (isProofLocal && what && !strcmp(what, "ntuple", 6)) {
      // Not support on windows
      Printf("runProof: the 'ntuple' example needs to run xrootd to receive the output file, \n"
             "          but xrootd is not supported on Windows - cannot continue");
      return;
   }
#endif

   TString proofsessions(Form("%s/sessions",tutdir.Data()));
   // Save tag of the used session
   FILE *fs = fopen(proofsessions.Data(), "a");
   if (!fs) {
      Printf("runProof: could not create files for sessions tags");
   } else {
      fprintf(fs,"session-%s\n", proof->GetSessionTag());
      fclose(fs);
   }
   if (!proof) {
      Printf("runProof: could not start/attach a PROOF session");
      return;
   }

   // Set the number of workers (may only reduce the number of active workers
   // in the session)
   if (nwrks > 0)
      proof->SetParallel(nwrks);

   // Where is the code to run
   char *rootbin = gSystem->Which(gSystem->Getenv("PATH"), "root.exe", kExecutePermission);
   if (!rootbin) {
      Printf("runProof: root.exe not found: please check the environment!");
      return;
   }
   TString rootsys(gSystem->DirName(rootbin));
   rootsys = gSystem->DirName(rootsys);
   TString tutorials(Form("%s/tutorials", rootsys.Data()));
   delete[] rootbin;

   // Create feedback displayer
   if (!fb) {
      new TCanvas("PROOF_EventsHist_canvas", "Events per Worker", 100, 600, 600, 400);
      fb = new TDrawFeedback(proof);
   }
   if (!proof->GetFeedbackList() || !proof->GetFeedbackList()->FindObject("PROOF_EventsHist")) {
      // Number of events per worker
      proof->AddFeedback("PROOF_EventsHist");
   }

   // Parse 'what'; it is in the form 'analysis(arg1,arg2,...)'
   TString args(what);
   args.ReplaceAll("("," "); 
   args.ReplaceAll(")"," "); 
   args.ReplaceAll(","," "); 
   Ssiz_t from = 0;
   TString act, tok;
   if (!args.Tokenize(act, from, " ")) {
      // Cannot continue
      Printf("runProof: action not found: check your arguments (%s)", what);
      return;
   }
   // Extract ACLiC mode
   TString aMode = "+";
   if (act.EndsWith("+")) {
      aMode += "+";
      while (act.EndsWith("+")) { act.Remove(TString::kTrailing,'+'); }
   }
   Printf("runProof: %s: ACLiC mode: '%s'", act.Data(), aMode.Data());

   // Parse out number of events and  'asyn' option, used almost by every test
   TString aNevt, aNwrk, opt, sel, punzip("off"), aCache, aH1Src("http://root.cern.ch/files/h1"),
           aDebug, aDebugEnum, aRateEst;
   Long64_t suf = 1;
   Int_t aSubMg = -1;
   Bool_t fillList = kFALSE, useList = kFALSE;
   while (args.Tokenize(tok, from, " ")) {
      // Debug controllers
      if (tok.BeginsWith("debug=")) {
         aDebug = tok;
         aDebug.ReplaceAll("debug=","");
         Int_t icol = kNPOS;
         if ((icol = aDebug.Index(":")) != kNPOS) {
            aDebugEnum = aDebug(0, icol);
            aDebug.Remove(0, icol+1);
         }
         if (!aDebug.IsDigit()) {
            Printf("runProof: %s: error parsing the 'debug=' option (%s) - ignoring", act.Data(), tok.Data());
            aDebug = "";
            aDebugEnum = "";
         }
      }
      // Number of events
      if (tok.BeginsWith("nevt=")) {
         aNevt = tok;
         aNevt.ReplaceAll("nevt=","");
         if (!aNevt.IsDigit()) {
            Printf("runProof: %s: error parsing the 'nevt=' option (%s) - ignoring", act.Data(), tok.Data());
            aNevt = "";
         }
      }
      // Sync or async ?
      if (tok.BeginsWith("asyn"))
         opt = "ASYN";
      // Number of workers
      if (tok.BeginsWith("nwrk=")) {
         aNwrk = tok;
         aNwrk.ReplaceAll("nwrk=","");
         if (!aNwrk.IsDigit()) {
            Printf("runProof: %s: error parsing the 'nwrk=' option (%s) - ignoring", act.Data(), tok.Data());
            aNwrk = "";
         }
      }
      // Parallel unzipping ?
      if (tok.BeginsWith("punzip"))
         punzip = "on";
      // Number of workers
      if (tok.BeginsWith("cache=")) {
         aCache = tok;
         aCache.ReplaceAll("cache=","");
         if (aCache.EndsWith("k")) { aCache.Remove(TString::kTrailing, 'k'); suf = 1024; }
         if (aCache.EndsWith("K")) { aCache.Remove(TString::kTrailing, 'K'); suf = 1024; }
         if (aCache.EndsWith("M")) { aCache.Remove(TString::kTrailing, 'M'); suf = 1024*1024; }
         if (!aCache.IsDigit()) {
            Printf("runProof: %s: error parsing the 'cache=' option (%s) - ignoring", act.Data(), tok.Data());
            aCache = "";
         }
      }
      // Use submergers?
      if (tok.BeginsWith("submergers")) {
         tok.ReplaceAll("submergers","");
         aSubMg = 0;
         if (tok.BeginsWith("=")) {
            tok.ReplaceAll("=","");
            if (tok.IsDigit()) aSubMg = tok.Atoi();
         }
      }
      // H1: use entry-lists ?
      if (tok.BeginsWith("useList")) {
         useList = kTRUE;
      }
      if (tok.BeginsWith("fillList")) {
         fillList = kTRUE;
         opt += "fillList";
      }
      // H1: change location of files?
      if (tok.BeginsWith("h1src=")) {
         tok.ReplaceAll("h1src=","");
         if (!(tok.IsNull())) aH1Src = tok;
         Printf("runProof: %s: reading data files from '%s'", act.Data(), aH1Src.Data());
      }
      // Rate estimation technique
      if (tok.BeginsWith("rateest=")) {
         tok.ReplaceAll("rateest=","");
         if (!(tok.IsNull())) aRateEst = tok;
         Printf("runProof: %s: progress-bar rate estimation option: '%s'", act.Data(), aRateEst.Data());
      }
   }
   Long64_t nevt = (aNevt.IsNull()) ? -1 : aNevt.Atoi();
   Long64_t nwrk = (aNwrk.IsNull()) ? -1 : aNwrk.Atoi();
   from = 0;

   // Set number workers
   if (nwrk > 0) {
      if (proof->GetParallel() < nwrk) {
         Printf("runProof: %s: request for a number of workers larger then available - ignored", act.Data());
      } else {
         proof->SetParallel(nwrk);
      }
   }

   // Debug controllers
   if (!aDebug.IsNull()) {
      Int_t dbg = aDebug.Atoi();
      Int_t scope = TProofDebug::kAll;
      if (!aDebugEnum.IsNull()) scope = getDebugEnum(aDebugEnum.Data());
      proof->SetLogLevel(dbg, scope);
      Printf("runProof: %s: verbose mode for '%s'; level: %d", act.Data(), aDebugEnum.Data(), dbg);
   }

   // Have constant progress reporting based on estimated info
   // (NB: may screw up the progress bar in some cases)
   if (aRateEst == "average")
      proof->SetParameter("PROOF_RateEstimation", aRateEst);

   // Parallel unzip
   if (punzip == "on") {
      proof->SetParameter("PROOF_UseParallelUnzip", (Int_t)1);
      Printf("runProof: %s: parallel unzip enabled", act.Data());
   } else {
      proof->SetParameter("PROOF_UseParallelUnzip", (Int_t)0);
   }

   // Tree cache
   if (!aCache.IsNull()) {
      Long64_t cachesz = aCache.Atoi() * suf;
      if (cachesz <= 0) {
         proof->SetParameter("PROOF_UseTreeCache", (Int_t)0);
         Printf("runProof: %s: disabling tree cache", act.Data());
      } else {
         proof->SetParameter("PROOF_UseTreeCache", (Int_t)1);
         proof->SetParameter("PROOF_CacheSize", cachesz);
         Printf("runProof: %s: setting cache size to %lld", act.Data(), cachesz);
      }
   } else {
      // Use defaults
      proof->DeleteParameters("PROOF_UseTreeCache");
      proof->DeleteParameters("PROOF_CacheSize");
   }

   // Enable submergers, if required
   if (aSubMg >= 0) {
      gProof->SetParameter("PROOF_UseMergers", aSubMg);
      if (aSubMg > 0) {
         Printf("runProof: %s: enabling merging via %d sub-mergers", act.Data(), aSubMg);
      } else {
         Printf("runProof: %s: enabling merging via sub-mergers (optimal number)", act.Data());
      }
   } else {
      gProof->DeleteParameters("PROOF_UseMergers");
   }

   // Action
   if (act == "simple") {
      // ProofSimple is an example of non-data driven analysis; it
      // creates and fills with random numbers a given number of histos

      // Default 10000 events
      nevt = (nevt < 0) ? 100000 : nevt;
      // Find out the number of histograms
      TString aNhist, aNhist3;
      while (args.Tokenize(tok, from, " ")) {
         // Number of histos
         if (tok.BeginsWith("nhist=")) {
            aNhist = tok;
            aNhist.ReplaceAll("nhist=","");
            if (!aNhist.IsDigit()) {
               Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
               aNhist = "";
            }
         } else if (tok.BeginsWith("nhist3=")) {
            aNhist3 = tok;
            aNhist3.ReplaceAll("nhist3=","");
            if (!aNhist3.IsDigit()) {
               Printf("runProof: error parsing the 'nhist3=' option (%s) - ignoring", tok.Data());
               aNhist3 = "";
            }
         }
      }
      Int_t nhist = (aNhist.IsNull()) ? 100 : aNhist.Atoi();
      Int_t nhist3 = (aNhist3.IsNull()) ? -1 : aNhist3.Atoi();
      Printf("\nrunProof: running \"simple\" with nhist= %d, nhist3=%d and nevt= %lld\n", nhist, nhist3, nevt);

      // The number of histograms is added as parameter in the input list
      proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
      // The number of histograms is added as parameter in the input list
      if (nhist3 > 0) proof->SetParameter("ProofSimple_NHist3", (Long_t)nhist3);
      // The selector string
      sel.Form("%s/proof/ProofSimple.C%s", tutorials.Data(), aMode.Data());
      //
      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

   } else if (act == "h1") {
      // This is the famous 'h1' example analysis run on Proof reading the
      // data from the ROOT http server.

      // Create the chain
      TChain *chain = new TChain("h42");
      chain->Add(TString::Format("%s/dstarmb.root", aH1Src.Data()));
      chain->Add(TString::Format("%s/dstarp1a.root", aH1Src.Data()));
      chain->Add(TString::Format("%s/dstarp1b.root", aH1Src.Data()));
      chain->Add(TString::Format("%s/dstarp2.root", aH1Src.Data()));
      chain->ls();
      // We run on Proof
      chain->SetProof();
      // Set entrylist, if required
      if (useList) {
         TString eln("elist"), elfn("elist.root");
         if (gSystem->AccessPathName(elfn)) {
            Printf("\nrunProof: asked to use an entry list but '%s' not found or not readable", elfn.Data());
            Printf("\nrunProof: did you forget to run with 'fillList=%s'?\n", elfn.Data());
         } else {
            TFile f(elfn);
            if (!(f.IsZombie())) {
               TEntryList *elist = (TEntryList *)f.Get(eln);
               if (elist) {
                  elist->SetDirectory(0); //otherwise the file destructor will delete elist
                  chain->SetEntryList(elist);
               } else {
                  Printf("\nrunProof: could not find entry-list '%s' in file '%s': ignoring",
                         eln.Data(), elfn.Data());
               }
            } else {
               Printf("\nrunProof: requested entry-list file '%s' not existing (or not readable):"
                      " ignoring", elfn.Data());
            }
         }
      }
      // The selector
      sel.Form("%s/tree/h1analysis.C%s", tutorials.Data(), aMode.Data());
      // Run it 
      Printf("\nrunProof: running \"h1\"\n");
      chain->Process(sel.Data(),opt);
      // Cleanup the input list
      gProof->ClearInputData("elist");
      gProof->ClearInputData("elist.root");
      TIter nxi(gProof->GetInputList());
      TObject *o = 0;
      while ((o = nxi())) {
         if (!strncmp(o->GetName(), "elist", 5)) {
            gProof->GetInputList()->Remove(o);
            delete o;
         }
      }

   } else if (act == "pythia8") {

      TString path(Form("%s/Index.xml", pythia8data));
      gSystem->ExpandPathName(path);
      if (gSystem->AccessPathName(path)) {
         Printf("runProof: pythia8: PYTHIA8DATA directory (%s) must"
                " contain the Index.xml file !", pythia8data);
         return;
      }
      TString pythia8par = TString::Format("%s/proof/pythia8.par", tutorials.Data());
      if (gSystem->AccessPathName(pythia8par.Data())) {
         Printf("runProof: pythia8: par file not found (tried %s)", pythia8par.Data());
         return;
      }
      proof->UploadPackage(pythia8par);
      proof->EnablePackage("pythia8");
      // Show enabled packages
      proof->ShowEnabledPackages();
      Printf("runProof: pythia8: check settings:");
      proof->Exec(".!echo hostname = `hostname`; echo \"ls pythia8:\"; ls pythia8");
      // Loading libraries needed
      if (gSystem->Load("libEG.so") < 0) {
         Printf("runProof: pythia8: libEG not found \n");
         return;
      }
      if (gSystem->Load("libEGPythia8.so") < 0) {
         Printf("runProof: pythia8: libEGPythia8 not found \n");
         return;
      }
      // Setting the default number of events, if needed
      nevt = (nevt < 0) ? 100 : nevt;
      Printf("\nrunProof: running \"Pythia01\" nevt= %lld\n", nevt);
      // The selector string
      sel.Form("%s/proof/ProofPythia.C%s", tutorials.Data(), aMode.Data());
      // Run it for nevt times
      proof->Process(sel.Data(), nevt);

  } else if (act == "event") {

      TString eventpar = TString::Format("%s/proof/event.par", tutorials.Data());
      if (gSystem->AccessPathName(eventpar.Data())) {
         Printf("runProof: event: par file not found (tried %s)", eventpar.Data());
         return;
      }

      proof->UploadPackage(eventpar);
      proof->EnablePackage("event");
      Printf("Enabled packages...\n");
      proof->ShowEnabledPackages(); 

      // Setting the default number of events, if needed
      nevt = (nevt < 0) ? 100 : nevt;
      Printf("\nrunProof: running \"event\" nevt= %lld\n", nevt);
      // The selector string
      sel.Form("%s/proof/ProofEvent.C%s", tutorials.Data(), aMode.Data());
      // Run it for nevt times
      proof->Process(sel.Data(), nevt);

  } else if (act == "eventproc") {

      TString eventpar = TString::Format("%s/proof/event.par", tutorials.Data());
      gSystem->ExpandPathName(eventpar);
      if (gSystem->AccessPathName(eventpar.Data())) {
         Printf("runProof: event: par file not found (tried %s)", eventpar.Data());
         return;
      }

      proof->UploadPackage(eventpar);
      proof->EnablePackage("event");
      Printf("Enabled packages...\n");
      proof->ShowEnabledPackages(); 

      // Extract the number of files to process, data source and
      // other parameters controlling the run ...
      Bool_t uneven = kFALSE;
      TString aFiles, aDataSrc("http://root.cern.ch/files/data"), aPartitions;
      proof->SetParameter("ProofEventProc_Read", "optimized");
      while (args.Tokenize(tok, from, " ")) {
         // Number of events
         if (tok.BeginsWith("files=")) {
            aFiles = tok;
            aFiles.ReplaceAll("files=","");
            if (!aFiles.IsDigit()) {
               Printf("runProof: error parsing the 'files=' option (%s) - ignoring", tok.Data());
               aFiles = "";
            }
         } else if (tok.BeginsWith("datasrc=")) {
            tok.ReplaceAll("datasrc=","");
            if (tok.IsDigit()) {
               Printf("runProof: error parsing the 'datasrc=' option (%s) - ignoring", tok.Data());
            } else {
               aDataSrc = tok;
               Printf("runProof: reading files from: %s", aDataSrc.Data());
            }
         } else if (tok == "readall") {
            proof->SetParameter("ProofEventProc_Read", "readall");
            Printf("runProof: eventproc: reading the full event");
         } else if (tok == "uneven") {
            uneven = kTRUE;
         } else if (tok.BeginsWith("partitions=")) {
            tok.ReplaceAll("partitions=","");
            if (tok.IsDigit()) {
               Printf("runProof: error parsing the 'partitions=' option (%s) - ignoring", tok.Data());
            } else {
               aPartitions = tok;
               Printf("runProof: partitions: %s included in packetizer operations", aPartitions.Data());
            }
         }
      }
      Int_t nFiles = (aFiles.IsNull()) ? 10 : aFiles.Atoi();
         Printf("runProof: found aFiles: '%s', nFiles: %d", aFiles.Data(), nFiles);
      if (nFiles > 50) {
         Printf("runProof: max number of files is 50 - resizing request");
         nFiles = 50;
      }

      // We create the chain now
      TChain *c = new TChain("EventTree");

      FileStat_t fst;
      if (gSystem->GetPathInfo(aDataSrc, fst) == 0 && R_ISREG(fst.fMode) &&
         !gSystem->AccessPathName(aDataSrc, kReadPermission)) {
         // It is a local file, we get the TFileCollection and we inject it into the chain
         TFileCollection *fc = new TFileCollection("", "", aDataSrc, nFiles);
         c->AddFileInfoList(fc->GetList());
         delete fc;

      } else {

         // Tokenize the source: if more than 1 we rotate the assignment. More sources can be specified
         // separating them by a '|'
         TObjArray *dsrcs = aDataSrc.Tokenize("|");
         Int_t nds = dsrcs->GetEntries();

         // Fill the chain
         Int_t i = 1, k = 0;
         TString fn;
         for (i = 1; i <= nFiles; i++) {
            k = (i - 1) % nds;
            TObjString *os = (TObjString *) (*dsrcs)[k];
            if (os) {
               fn.Form("%s/event_%d.root", os->GetName(), i);
               if (uneven) {
                  if ((i - 1)%5 == 0)
                     c->AddFile(fn.Data(), 50000);
                  else
                     c->AddFile(fn.Data(), 5000);
               } else {
                  c->AddFile(fn.Data());
               }
            }
         }
         dsrcs->SetOwner();
         delete dsrcs;
      }
      // Show the chain
      c->ls();
      c->SetProof();

      // Only validate the files really needed for the analysis
      proof->SetParameter("PROOF_ValidateByFile", 1);

      // Send over the  partition information, if any
      if (!aPartitions.IsNull()) {
         aPartitions.ReplaceAll("|", ",");
         proof->SetParameter("PROOF_PacketizerPartitions", aPartitions);
      }

      // The selector
      sel.Form("%s/proof/ProofEventProc.C%s", tutorials.Data(), aMode.Data());
      // Run it
      Printf("\nrunProof: running \"eventproc\"\n");
      c->Process(sel.Data(), opt, nevt);

   } else if (act == "ntuple") {

      // ProofNtuple is an example of non-data driven analysis; it
      // creates and fills a disk resident ntuple with automatic file merging 

      // Set the default number of events, if needed
      nevt = (nevt < 0) ? 1000 : nevt;
      Printf("\nrunProof: running \"ntuple\" with nevt= %lld\n", nevt);

      // Output file
      TString fout = TString::Format("%s/ProofNtuple.root", gSystem->WorkingDirectory());
      // Cleanup any existing instance of the output file
      gSystem->Unlink(fout);

      if (!isProofLocal) {
         // Setup a local basic xrootd to receive the file
         Bool_t xrdok = kFALSE;
         Int_t port = 9000;
         while (port < 9010) {
            if (checkXrootdAt(port) != 1) {
               if (startXrootdAt(port, gSystem->WorkingDirectory(), kTRUE) == 0) {
                  xrdok = kTRUE;
                  break;
               }
            }
            port++;
         }
         if (!xrdok) {
            Printf("runProof: could not start basic xrootd on ports 9000-9009 - cannot continue");
            return;
         }
         fout.Insert(0, TString::Format("root://%s:%d/", TUrl(gSystem->HostName()).GetHostFQDN(), port));
         // Make a copy of the files on the master before merging
         proof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION", "LOCAL"));
      }
      proof->AddInput(new TNamed("PROOF_OUTPUTFILE", fout.Data()));

      // The selector string
      sel.Form("%s/proof/ProofNtuple.C%s", tutorials.Data(), aMode.Data());

      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

   } else if (act == "dataset") {

      // This is an example of analysis creating data files on each node which are
      // automatically registered as dataset; the newly created dataset is used to create
      // the final plots. The data are of the same type as for the 'ntuple' example.
      // Selector used: ProofNtuple

      // Set the default number of events, if needed
      nevt = (nevt < 0) ? 1000000 : nevt;
      Printf("\nrunProof: running \"dataset\" with nevt= %lld\n", nevt);

      // Ask for registration of the dataset (the default is the the TFileCollection is return
      // without registration; the name of the TFileCollection is the name of the dataset
      proof->SetParameter("SimpleNtuple.root","testNtuple");

      // Do not plot the ntuple at this level
      proof->SetParameter("PROOF_NTUPLE_DONT_PLOT", "");

      // The selector string
      sel.Form("%s/proof/ProofNtuple.C%s", tutorials.Data(), aMode.Data());
      //
      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

      // The TFileCollection must be in the output
      if (proof->GetOutputList()->FindObject("testNtuple")) {

         // Plot the ntuple via PROOF (example of drawing PROOF actions)
         plotNtuple(proof, "testNtuple", "proof ntuple from dataset");

      } else {
         Printf("runProof: dataset 'testNtuple' not found in the output list");
      }
      // Do not plot the ntuple at this level
      proof->DeleteParameters("PROOF_NTUPLE_DONT_PLOT");
      proof->DeleteParameters("SimpleNtuple.root");

   } else if (act == "friends") {

      // This is an example of analysis creating two data files on each node (the main tree
      // and its friend) which are then processed as 'friends' to create the final plots.
      // Selector used: ProofFriends, ProofAux

      // Find out whether to use the same file or separate files
      Bool_t sameFile = kFALSE;
      while (args.Tokenize(tok, from, " ")) {
         // Number of histos
         if (tok == "samefile") {
            sameFile = kTRUE;
            break;
         }
      }

      // File generation: we use TPacketizerFile in here to create two files per node
      TList *wrks = proof->GetListOfSlaveInfos();
      if (!wrks) {
         Printf("runProof: could not get the list of information about the workers");
         return;
      }
      // Create the map
      TString fntree;
      TMap *files = new TMap;
      files->SetName("PROOF_FilesToProcess");
      TIter nxwi(wrks);
      TSlaveInfo *wi = 0;
      while ((wi = (TSlaveInfo *) nxwi())) {
         fntree.Form("tree_%s.root", wi->GetOrdinal());
         THashList *wrklist = (THashList *) files->GetValue(wi->GetName());
         if (!wrklist) {
            wrklist = new THashList;
            wrklist->SetName(wi->GetName());
            files->Add(new TObjString(wi->GetName()), wrklist);
         }
         wrklist->Add(new TObjString(fntree));
      }

      // Generate the files
      proof->AddInput(files);
      if (sameFile) {
         Printf("runProof: friend tree stored in the same file as the main tree");
         proof->SetParameter("ProofAux_Action", "GenerateTreesSameFile");
      } else {
         proof->SetParameter("ProofAux_Action", "GenerateTrees");
      }
      // Default 1000 events
      nevt = (nevt < 0) ? 10000 : nevt;
      proof->SetParameter("ProofAux_NEvents", (Long64_t)nevt);
      // Special Packetizer
      proof->SetParameter("PROOF_Packetizer", "TPacketizerFile");
      // Now process
      sel.Form("%s/proof/ProofAux.C%s", tutorials.Data(), aMode.Data());
      proof->Process(sel.Data(), 1);
      // Remove the packetizer specifications
      proof->DeleteParameters("PROOF_Packetizer");

      // Print the lists and create the TDSet objects
      TDSet *dset = new TDSet("Tmain", "Tmain");
      TDSet *dsetf = new TDSet("Tfrnd", "Tfrnd");
      if (proof->GetOutputList()) {
         TIter nxo(proof->GetOutputList());
         TObject *o = 0;
         TObjString *os = 0;
         while ((o = nxo())) {
            TList *l = dynamic_cast<TList *> (o);
            if (l && !strncmp(l->GetName(), "MainList-", 9)) {
               TIter nxf(l);
               while ((os = (TObjString *) nxf()))
                  dset->Add(os->GetName());
            }
         }
         nxo.Reset();
         while ((o = nxo())) {
            TList *l = dynamic_cast<TList *> (o);
            if (l && !strncmp(l->GetName(), "FriendList-", 11)) {
               TIter nxf(l);
               while ((os = (TObjString *) nxf()))
                  dsetf->Add(os->GetName());
            }
         }
      }
      // Process with friends
      dset->AddFriend(dsetf, "friend");
      sel.Form("%s/proof/ProofFriends.C%s", tutorials.Data(), aMode.Data());
      dset->Process(sel);
      // Clear the files created by this run
      proof->ClearData(TProof::kUnregistered | TProof::kForceClear);

   } else if (act == "simplefile") {
      
      // ProofSimpleFile is an example of non-data driven analysis with merging
      // via file and objcets saved in different directories; it creates and
      // fills with random numbers two sets of a given number of histos

      // Default 100000 events
      nevt = (nevt < 0) ? 1000000 : nevt;
      // Find out the number of histograms
      TString aNhist;
      while (args.Tokenize(tok, from, " ")) {
         // Number of histos
         if (tok.BeginsWith("nhist=")) {
            aNhist = tok;
            aNhist.ReplaceAll("nhist=","");
            if (!aNhist.IsDigit()) {
               Printf("runProof: error parsing the 'nhist=' option (%s) - ignoring", tok.Data());
               aNhist = "";
            }
         }
      }
      Int_t nhist = (aNhist.IsNull()) ? 16 : aNhist.Atoi();
      Printf("\nrunProof: running \"simplefile\" with nhist= %d and nevt= %lld\n", nhist, nevt);

      // The number of histograms is added as parameter in the input list
      proof->SetParameter("ProofSimple_NHist", (Long_t)nhist);
      
      // Output file
      TString fout = TString::Format("%s/SimpleFile.root", gSystem->WorkingDirectory());
      // Cleanup any existing instance of the output file
      gSystem->Unlink(fout);

      if (!isProofLocal) {
         // Setup a local basic xrootd to receive the file
         Bool_t xrdok = kFALSE;
         Int_t port = 9000;
         while (port < 9010) {
            if (checkXrootdAt(port) != 1) {
               if (startXrootdAt(port, gSystem->WorkingDirectory(), kTRUE) == 0) {
                  xrdok = kTRUE;
                  break;
               }
            }
            port++;
         }
         if (!xrdok) {
            Printf("runProof: could not start basic xrootd on ports 9000-9009 - cannot continue");
            return;
         }
         fout.Insert(0, TString::Format("root://%s:%d/", TUrl(gSystem->HostName()).GetHostFQDN(), port));
         // Make a copy of the files on the master before merging
         proof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION", "LOCAL"));
      }
      proof->AddInput(new TNamed("PROOF_OUTPUTFILE", fout.Data()));
      
      // The selector string
      sel.Form("%s/proof/ProofSimpleFile.C%s", tutorials.Data(), aMode.Data());
      //
      // Run it for nevt times
      proof->Process(sel.Data(), nevt, opt);

   } else {
      // Do not know what to run
      Printf("runProof: unknown tutorial: %s", what);
   }
}

//_______________________________________________________________________________________
void plotNtuple(TProof *p, const char *ds, const char *ntptitle)
{
   // Make some plots from the ntuple 'ntp' via PROOF

   //
   // Create a canvas, with 2 pads
   //
   TCanvas *c1 = new TCanvas(Form("cv-%s", ds), ntptitle,800,10,700,780);
   c1->Divide(1,2);
   TPad *pad1 = (TPad *) c1->GetPad(1);
   TPad *pad2 = (TPad *) c1->GetPad(2);
   //
   // Display a function of one ntuple column imposing a condition
   // on another column.
   pad1->cd();
   pad1->SetGrid();
   pad1->SetLogy();
   pad1->GetFrame()->SetFillColor(15);

   p->SetParameter("PROOF_LineColor", (Int_t)1);
   p->SetParameter("PROOF_FillStyle", (Int_t)1001);
   p->SetParameter("PROOF_FillColor", (Int_t)45);
   p->DrawSelect(ds, "3*px+2","px**2+py**2>1");
   p->SetParameter("PROOF_FillColor", (Int_t)38);
   p->DrawSelect(ds, "2*px+2","pz>2","same");
   p->SetParameter("PROOF_FillColor", (Int_t)5);
   p->DrawSelect(ds, "1.3*px+2","(px^2+py^2>4) && py>0","same");
   pad1->RedrawAxis();

   //
   // Display a 3-D scatter plot of 3 columns. Superimpose a different selection.
   pad2->cd();
   p->DrawSelect(ds, "pz:py:px","(pz<10 && pz>6)+(pz<4 && pz>3)");
   p->SetParameter("PROOF_MarkerColor", (Int_t)4);
   p->DrawSelect(ds, "pz:py:px","pz<6 && pz>4","same");
   p->SetParameter("PROOF_MarkerColor", (Int_t)5);
   p->DrawSelect(ds, "pz:py:px","pz<4 && pz>3","same");
   TPaveText *l2 = new TPaveText(0.,0.6,0.9,0.95);
   l2->SetFillColor(42);
   l2->SetTextAlign(12);
   l2->AddText("You can interactively rotate this view in 2 ways:");
   l2->AddText("  - With the RotateCube in clicking in this pad");
   l2->AddText("  - Selecting View with x3d in the View menu");
   l2->Draw();

   // Final update
   c1->cd();
   c1->Update();

   // Clear parameters used for the plots
   p->DeleteParameters("PROOF_*Color");
   p->DeleteParameters("PROOF_*Style");
}

int getDebugEnum(const char *what)
{
   // Check if 'what' matches one of the TProofDebug enum and return the corresponding
   // integer. Relies on a perfect synchronization with the content of TProofDebug.h .

   TString sws(what), sw;
   int rcmask = 0;
   int from = 0;
   while (sws.Tokenize(sw, from , "|")) {
      if (sw.BeginsWith("k")) sw.Remove(0,1);

      if (sw == "None") {
         rcmask |= TProofDebug::kNone;
      } else if (sw == "Packetizer") {
         rcmask |= TProofDebug::kPacketizer;
      } else if (sw == "Loop") {
         rcmask |= TProofDebug::kLoop;
      } else if (sw == "Selector") {
         rcmask |= TProofDebug::kSelector;
      } else if (sw == "Output") {
         rcmask |= TProofDebug::kOutput;
      } else if (sw == "Input") {
         rcmask |= TProofDebug::kInput;
      } else if (sw == "Global") {
         rcmask |= TProofDebug::kGlobal;
      } else if (sw == "Package") {
         rcmask |= TProofDebug::kPackage;
      } else if (sw == "Feedback") {
         rcmask |= TProofDebug::kFeedback;
      } else if (sw == "Condor") {
         rcmask |= TProofDebug::kCondor;
      } else if (sw == "Draw") {
         rcmask |= TProofDebug::kDraw;
      } else if (sw == "Asyn") {
         rcmask |= TProofDebug::kAsyn;
      } else if (sw == "Cache") {
         rcmask |= TProofDebug::kCache;
      } else if (sw == "Collect") {
         rcmask |= TProofDebug::kCollect;
      } else if (sw == "Dataset") {
         rcmask |= TProofDebug::kDataset;
      } else if (sw == "Submerger") {
         rcmask |= TProofDebug::kSubmerger;
      } else if (sw == "All") {
         rcmask |= TProofDebug::kAll;
      } else if (!sw.IsNull()) {
         Printf("WARNING: requested debug enum name '%s' does not exist: assuming 'All'", sw.Data());
         rcmask |= TProofDebug::kAll;
      }
   }
   // Done
   return rcmask;
}
 runProof.C:1
 runProof.C:2
 runProof.C:3
 runProof.C:4
 runProof.C:5
 runProof.C:6
 runProof.C:7
 runProof.C:8
 runProof.C:9
 runProof.C:10
 runProof.C:11
 runProof.C:12
 runProof.C:13
 runProof.C:14
 runProof.C:15
 runProof.C:16
 runProof.C:17
 runProof.C:18
 runProof.C:19
 runProof.C:20
 runProof.C:21
 runProof.C:22
 runProof.C:23
 runProof.C:24
 runProof.C:25
 runProof.C:26
 runProof.C:27
 runProof.C:28
 runProof.C:29
 runProof.C:30
 runProof.C:31
 runProof.C:32
 runProof.C:33
 runProof.C:34
 runProof.C:35
 runProof.C:36
 runProof.C:37
 runProof.C:38
 runProof.C:39
 runProof.C:40
 runProof.C:41
 runProof.C:42
 runProof.C:43
 runProof.C:44
 runProof.C:45
 runProof.C:46
 runProof.C:47
 runProof.C:48
 runProof.C:49
 runProof.C:50
 runProof.C:51
 runProof.C:52
 runProof.C:53
 runProof.C:54
 runProof.C:55
 runProof.C:56
 runProof.C:57
 runProof.C:58
 runProof.C:59
 runProof.C:60
 runProof.C:61
 runProof.C:62
 runProof.C:63
 runProof.C:64
 runProof.C:65
 runProof.C:66
 runProof.C:67
 runProof.C:68
 runProof.C:69
 runProof.C:70
 runProof.C:71
 runProof.C:72
 runProof.C:73
 runProof.C:74
 runProof.C:75
 runProof.C:76
 runProof.C:77
 runProof.C:78
 runProof.C:79
 runProof.C:80
 runProof.C:81
 runProof.C:82
 runProof.C:83
 runProof.C:84
 runProof.C:85
 runProof.C:86
 runProof.C:87
 runProof.C:88
 runProof.C:89
 runProof.C:90
 runProof.C:91
 runProof.C:92
 runProof.C:93
 runProof.C:94
 runProof.C:95
 runProof.C:96
 runProof.C:97
 runProof.C:98
 runProof.C:99
 runProof.C:100
 runProof.C:101
 runProof.C:102
 runProof.C:103
 runProof.C:104
 runProof.C:105
 runProof.C:106
 runProof.C:107
 runProof.C:108
 runProof.C:109
 runProof.C:110
 runProof.C:111
 runProof.C:112
 runProof.C:113
 runProof.C:114
 runProof.C:115
 runProof.C:116
 runProof.C:117
 runProof.C:118
 runProof.C:119
 runProof.C:120
 runProof.C:121
 runProof.C:122
 runProof.C:123
 runProof.C:124
 runProof.C:125
 runProof.C:126
 runProof.C:127
 runProof.C:128
 runProof.C:129
 runProof.C:130
 runProof.C:131
 runProof.C:132
 runProof.C:133
 runProof.C:134
 runProof.C:135
 runProof.C:136
 runProof.C:137
 runProof.C:138
 runProof.C:139
 runProof.C:140
 runProof.C:141
 runProof.C:142
 runProof.C:143
 runProof.C:144
 runProof.C:145
 runProof.C:146
 runProof.C:147
 runProof.C:148
 runProof.C:149
 runProof.C:150
 runProof.C:151
 runProof.C:152
 runProof.C:153
 runProof.C:154
 runProof.C:155
 runProof.C:156
 runProof.C:157
 runProof.C:158
 runProof.C:159
 runProof.C:160
 runProof.C:161
 runProof.C:162
 runProof.C:163
 runProof.C:164
 runProof.C:165
 runProof.C:166
 runProof.C:167
 runProof.C:168
 runProof.C:169
 runProof.C:170
 runProof.C:171
 runProof.C:172
 runProof.C:173
 runProof.C:174
 runProof.C:175
 runProof.C:176
 runProof.C:177
 runProof.C:178
 runProof.C:179
 runProof.C:180
 runProof.C:181
 runProof.C:182
 runProof.C:183
 runProof.C:184
 runProof.C:185
 runProof.C:186
 runProof.C:187
 runProof.C:188
 runProof.C:189
 runProof.C:190
 runProof.C:191
 runProof.C:192
 runProof.C:193
 runProof.C:194
 runProof.C:195
 runProof.C:196
 runProof.C:197
 runProof.C:198
 runProof.C:199
 runProof.C:200
 runProof.C:201
 runProof.C:202
 runProof.C:203
 runProof.C:204
 runProof.C:205
 runProof.C:206
 runProof.C:207
 runProof.C:208
 runProof.C:209
 runProof.C:210
 runProof.C:211
 runProof.C:212
 runProof.C:213
 runProof.C:214
 runProof.C:215
 runProof.C:216
 runProof.C:217
 runProof.C:218
 runProof.C:219
 runProof.C:220
 runProof.C:221
 runProof.C:222
 runProof.C:223
 runProof.C:224
 runProof.C:225
 runProof.C:226
 runProof.C:227
 runProof.C:228
 runProof.C:229
 runProof.C:230
 runProof.C:231
 runProof.C:232
 runProof.C:233
 runProof.C:234
 runProof.C:235
 runProof.C:236
 runProof.C:237
 runProof.C:238
 runProof.C:239
 runProof.C:240
 runProof.C:241
 runProof.C:242
 runProof.C:243
 runProof.C:244
 runProof.C:245
 runProof.C:246
 runProof.C:247
 runProof.C:248
 runProof.C:249
 runProof.C:250
 runProof.C:251
 runProof.C:252
 runProof.C:253
 runProof.C:254
 runProof.C:255
 runProof.C:256
 runProof.C:257
 runProof.C:258
 runProof.C:259
 runProof.C:260
 runProof.C:261
 runProof.C:262
 runProof.C:263
 runProof.C:264
 runProof.C:265
 runProof.C:266
 runProof.C:267
 runProof.C:268
 runProof.C:269
 runProof.C:270
 runProof.C:271
 runProof.C:272
 runProof.C:273
 runProof.C:274
 runProof.C:275
 runProof.C:276
 runProof.C:277
 runProof.C:278
 runProof.C:279
 runProof.C:280
 runProof.C:281
 runProof.C:282
 runProof.C:283
 runProof.C:284
 runProof.C:285
 runProof.C:286
 runProof.C:287
 runProof.C:288
 runProof.C:289
 runProof.C:290
 runProof.C:291
 runProof.C:292
 runProof.C:293
 runProof.C:294
 runProof.C:295
 runProof.C:296
 runProof.C:297
 runProof.C:298
 runProof.C:299
 runProof.C:300
 runProof.C:301
 runProof.C:302
 runProof.C:303
 runProof.C:304
 runProof.C:305
 runProof.C:306
 runProof.C:307
 runProof.C:308
 runProof.C:309
 runProof.C:310
 runProof.C:311
 runProof.C:312
 runProof.C:313
 runProof.C:314
 runProof.C:315
 runProof.C:316
 runProof.C:317
 runProof.C:318
 runProof.C:319
 runProof.C:320
 runProof.C:321
 runProof.C:322
 runProof.C:323
 runProof.C:324
 runProof.C:325
 runProof.C:326
 runProof.C:327
 runProof.C:328
 runProof.C:329
 runProof.C:330
 runProof.C:331
 runProof.C:332
 runProof.C:333
 runProof.C:334
 runProof.C:335
 runProof.C:336
 runProof.C:337
 runProof.C:338
 runProof.C:339
 runProof.C:340
 runProof.C:341
 runProof.C:342
 runProof.C:343
 runProof.C:344
 runProof.C:345
 runProof.C:346
 runProof.C:347
 runProof.C:348
 runProof.C:349
 runProof.C:350
 runProof.C:351
 runProof.C:352
 runProof.C:353
 runProof.C:354
 runProof.C:355
 runProof.C:356
 runProof.C:357
 runProof.C:358
 runProof.C:359
 runProof.C:360
 runProof.C:361
 runProof.C:362
 runProof.C:363
 runProof.C:364
 runProof.C:365
 runProof.C:366
 runProof.C:367
 runProof.C:368
 runProof.C:369
 runProof.C:370
 runProof.C:371
 runProof.C:372
 runProof.C:373
 runProof.C:374
 runProof.C:375
 runProof.C:376
 runProof.C:377
 runProof.C:378
 runProof.C:379
 runProof.C:380
 runProof.C:381
 runProof.C:382
 runProof.C:383
 runProof.C:384
 runProof.C:385
 runProof.C:386
 runProof.C:387
 runProof.C:388
 runProof.C:389
 runProof.C:390
 runProof.C:391
 runProof.C:392
 runProof.C:393
 runProof.C:394
 runProof.C:395
 runProof.C:396
 runProof.C:397
 runProof.C:398
 runProof.C:399
 runProof.C:400
 runProof.C:401
 runProof.C:402
 runProof.C:403
 runProof.C:404
 runProof.C:405
 runProof.C:406
 runProof.C:407
 runProof.C:408
 runProof.C:409
 runProof.C:410
 runProof.C:411
 runProof.C:412
 runProof.C:413
 runProof.C:414
 runProof.C:415
 runProof.C:416
 runProof.C:417
 runProof.C:418
 runProof.C:419
 runProof.C:420
 runProof.C:421
 runProof.C:422
 runProof.C:423
 runProof.C:424
 runProof.C:425
 runProof.C:426
 runProof.C:427
 runProof.C:428
 runProof.C:429
 runProof.C:430
 runProof.C:431
 runProof.C:432
 runProof.C:433
 runProof.C:434
 runProof.C:435
 runProof.C:436
 runProof.C:437
 runProof.C:438
 runProof.C:439
 runProof.C:440
 runProof.C:441
 runProof.C:442
 runProof.C:443
 runProof.C:444
 runProof.C:445
 runProof.C:446
 runProof.C:447
 runProof.C:448
 runProof.C:449
 runProof.C:450
 runProof.C:451
 runProof.C:452
 runProof.C:453
 runProof.C:454
 runProof.C:455
 runProof.C:456
 runProof.C:457
 runProof.C:458
 runProof.C:459
 runProof.C:460
 runProof.C:461
 runProof.C:462
 runProof.C:463
 runProof.C:464
 runProof.C:465
 runProof.C:466
 runProof.C:467
 runProof.C:468
 runProof.C:469
 runProof.C:470
 runProof.C:471
 runProof.C:472
 runProof.C:473
 runProof.C:474
 runProof.C:475
 runProof.C:476
 runProof.C:477
 runProof.C:478
 runProof.C:479
 runProof.C:480
 runProof.C:481
 runProof.C:482
 runProof.C:483
 runProof.C:484
 runProof.C:485
 runProof.C:486
 runProof.C:487
 runProof.C:488
 runProof.C:489
 runProof.C:490
 runProof.C:491
 runProof.C:492
 runProof.C:493
 runProof.C:494
 runProof.C:495
 runProof.C:496
 runProof.C:497
 runProof.C:498
 runProof.C:499
 runProof.C:500
 runProof.C:501
 runProof.C:502
 runProof.C:503
 runProof.C:504
 runProof.C:505
 runProof.C:506
 runProof.C:507
 runProof.C:508
 runProof.C:509
 runProof.C:510
 runProof.C:511
 runProof.C:512
 runProof.C:513
 runProof.C:514
 runProof.C:515
 runProof.C:516
 runProof.C:517
 runProof.C:518
 runProof.C:519
 runProof.C:520
 runProof.C:521
 runProof.C:522
 runProof.C:523
 runProof.C:524
 runProof.C:525
 runProof.C:526
 runProof.C:527
 runProof.C:528
 runProof.C:529
 runProof.C:530
 runProof.C:531
 runProof.C:532
 runProof.C:533
 runProof.C:534
 runProof.C:535
 runProof.C:536
 runProof.C:537
 runProof.C:538
 runProof.C:539
 runProof.C:540
 runProof.C:541
 runProof.C:542
 runProof.C:543
 runProof.C:544
 runProof.C:545
 runProof.C:546
 runProof.C:547
 runProof.C:548
 runProof.C:549
 runProof.C:550
 runProof.C:551
 runProof.C:552
 runProof.C:553
 runProof.C:554
 runProof.C:555
 runProof.C:556
 runProof.C:557
 runProof.C:558
 runProof.C:559
 runProof.C:560
 runProof.C:561
 runProof.C:562
 runProof.C:563
 runProof.C:564
 runProof.C:565
 runProof.C:566
 runProof.C:567
 runProof.C:568
 runProof.C:569
 runProof.C:570
 runProof.C:571
 runProof.C:572
 runProof.C:573
 runProof.C:574
 runProof.C:575
 runProof.C:576
 runProof.C:577
 runProof.C:578
 runProof.C:579
 runProof.C:580
 runProof.C:581
 runProof.C:582
 runProof.C:583
 runProof.C:584
 runProof.C:585
 runProof.C:586
 runProof.C:587
 runProof.C:588
 runProof.C:589
 runProof.C:590
 runProof.C:591
 runProof.C:592
 runProof.C:593
 runProof.C:594
 runProof.C:595
 runProof.C:596
 runProof.C:597
 runProof.C:598
 runProof.C:599
 runProof.C:600
 runProof.C:601
 runProof.C:602
 runProof.C:603
 runProof.C:604
 runProof.C:605
 runProof.C:606
 runProof.C:607
 runProof.C:608
 runProof.C:609
 runProof.C:610
 runProof.C:611
 runProof.C:612
 runProof.C:613
 runProof.C:614
 runProof.C:615
 runProof.C:616
 runProof.C:617
 runProof.C:618
 runProof.C:619
 runProof.C:620
 runProof.C:621
 runProof.C:622
 runProof.C:623
 runProof.C:624
 runProof.C:625
 runProof.C:626
 runProof.C:627
 runProof.C:628
 runProof.C:629
 runProof.C:630
 runProof.C:631
 runProof.C:632
 runProof.C:633
 runProof.C:634
 runProof.C:635
 runProof.C:636
 runProof.C:637
 runProof.C:638
 runProof.C:639
 runProof.C:640
 runProof.C:641
 runProof.C:642
 runProof.C:643
 runProof.C:644
 runProof.C:645
 runProof.C:646
 runProof.C:647
 runProof.C:648
 runProof.C:649
 runProof.C:650
 runProof.C:651
 runProof.C:652
 runProof.C:653
 runProof.C:654
 runProof.C:655
 runProof.C:656
 runProof.C:657
 runProof.C:658
 runProof.C:659
 runProof.C:660
 runProof.C:661
 runProof.C:662
 runProof.C:663
 runProof.C:664
 runProof.C:665
 runProof.C:666
 runProof.C:667
 runProof.C:668
 runProof.C:669
 runProof.C:670
 runProof.C:671
 runProof.C:672
 runProof.C:673
 runProof.C:674
 runProof.C:675
 runProof.C:676
 runProof.C:677
 runProof.C:678
 runProof.C:679
 runProof.C:680
 runProof.C:681
 runProof.C:682
 runProof.C:683
 runProof.C:684
 runProof.C:685
 runProof.C:686
 runProof.C:687
 runProof.C:688
 runProof.C:689
 runProof.C:690
 runProof.C:691
 runProof.C:692
 runProof.C:693
 runProof.C:694
 runProof.C:695
 runProof.C:696
 runProof.C:697
 runProof.C:698
 runProof.C:699
 runProof.C:700
 runProof.C:701
 runProof.C:702
 runProof.C:703
 runProof.C:704
 runProof.C:705
 runProof.C:706
 runProof.C:707
 runProof.C:708
 runProof.C:709
 runProof.C:710
 runProof.C:711
 runProof.C:712
 runProof.C:713
 runProof.C:714
 runProof.C:715
 runProof.C:716
 runProof.C:717
 runProof.C:718
 runProof.C:719
 runProof.C:720
 runProof.C:721
 runProof.C:722
 runProof.C:723
 runProof.C:724
 runProof.C:725
 runProof.C:726
 runProof.C:727
 runProof.C:728
 runProof.C:729
 runProof.C:730
 runProof.C:731
 runProof.C:732
 runProof.C:733
 runProof.C:734
 runProof.C:735
 runProof.C:736
 runProof.C:737
 runProof.C:738
 runProof.C:739
 runProof.C:740
 runProof.C:741
 runProof.C:742
 runProof.C:743
 runProof.C:744
 runProof.C:745
 runProof.C:746
 runProof.C:747
 runProof.C:748
 runProof.C:749
 runProof.C:750
 runProof.C:751
 runProof.C:752
 runProof.C:753
 runProof.C:754
 runProof.C:755
 runProof.C:756
 runProof.C:757
 runProof.C:758
 runProof.C:759
 runProof.C:760
 runProof.C:761
 runProof.C:762
 runProof.C:763
 runProof.C:764
 runProof.C:765
 runProof.C:766
 runProof.C:767
 runProof.C:768
 runProof.C:769
 runProof.C:770
 runProof.C:771
 runProof.C:772
 runProof.C:773
 runProof.C:774
 runProof.C:775
 runProof.C:776
 runProof.C:777
 runProof.C:778
 runProof.C:779
 runProof.C:780
 runProof.C:781
 runProof.C:782
 runProof.C:783
 runProof.C:784
 runProof.C:785
 runProof.C:786
 runProof.C:787
 runProof.C:788
 runProof.C:789
 runProof.C:790
 runProof.C:791
 runProof.C:792
 runProof.C:793
 runProof.C:794
 runProof.C:795
 runProof.C:796
 runProof.C:797
 runProof.C:798
 runProof.C:799
 runProof.C:800
 runProof.C:801
 runProof.C:802
 runProof.C:803
 runProof.C:804
 runProof.C:805
 runProof.C:806
 runProof.C:807
 runProof.C:808
 runProof.C:809
 runProof.C:810
 runProof.C:811
 runProof.C:812
 runProof.C:813
 runProof.C:814
 runProof.C:815
 runProof.C:816
 runProof.C:817
 runProof.C:818
 runProof.C:819
 runProof.C:820
 runProof.C:821
 runProof.C:822
 runProof.C:823
 runProof.C:824
 runProof.C:825
 runProof.C:826
 runProof.C:827
 runProof.C:828
 runProof.C:829
 runProof.C:830
 runProof.C:831
 runProof.C:832
 runProof.C:833
 runProof.C:834
 runProof.C:835
 runProof.C:836
 runProof.C:837
 runProof.C:838
 runProof.C:839
 runProof.C:840
 runProof.C:841
 runProof.C:842
 runProof.C:843
 runProof.C:844
 runProof.C:845
 runProof.C:846
 runProof.C:847
 runProof.C:848
 runProof.C:849
 runProof.C:850
 runProof.C:851
 runProof.C:852
 runProof.C:853
 runProof.C:854
 runProof.C:855
 runProof.C:856
 runProof.C:857
 runProof.C:858
 runProof.C:859
 runProof.C:860
 runProof.C:861
 runProof.C:862
 runProof.C:863
 runProof.C:864
 runProof.C:865
 runProof.C:866
 runProof.C:867
 runProof.C:868
 runProof.C:869
 runProof.C:870
 runProof.C:871
 runProof.C:872
 runProof.C:873
 runProof.C:874
 runProof.C:875
 runProof.C:876
 runProof.C:877
 runProof.C:878
 runProof.C:879
 runProof.C:880
 runProof.C:881
 runProof.C:882
 runProof.C:883
 runProof.C:884
 runProof.C:885
 runProof.C:886
 runProof.C:887
 runProof.C:888
 runProof.C:889
 runProof.C:890
 runProof.C:891
 runProof.C:892
 runProof.C:893
 runProof.C:894
 runProof.C:895
 runProof.C:896
 runProof.C:897
 runProof.C:898
 runProof.C:899
 runProof.C:900
 runProof.C:901
 runProof.C:902
 runProof.C:903
 runProof.C:904
 runProof.C:905
 runProof.C:906
 runProof.C:907
 runProof.C:908
 runProof.C:909
 runProof.C:910
 runProof.C:911
 runProof.C:912
 runProof.C:913
 runProof.C:914
 runProof.C:915
 runProof.C:916
 runProof.C:917
 runProof.C:918
 runProof.C:919
 runProof.C:920
 runProof.C:921
 runProof.C:922
 runProof.C:923
 runProof.C:924
 runProof.C:925
 runProof.C:926
 runProof.C:927
 runProof.C:928
 runProof.C:929
 runProof.C:930
 runProof.C:931
 runProof.C:932
 runProof.C:933
 runProof.C:934
 runProof.C:935
 runProof.C:936
 runProof.C:937
 runProof.C:938
 runProof.C:939
 runProof.C:940
 runProof.C:941
 runProof.C:942
 runProof.C:943
 runProof.C:944
 runProof.C:945
 runProof.C:946
 runProof.C:947
 runProof.C:948
 runProof.C:949
 runProof.C:950
 runProof.C:951
 runProof.C:952
 runProof.C:953
 runProof.C:954
 runProof.C:955
 runProof.C:956
 runProof.C:957
 runProof.C:958
 runProof.C:959
 runProof.C:960
 runProof.C:961
 runProof.C:962
 runProof.C:963
 runProof.C:964
 runProof.C:965
 runProof.C:966
 runProof.C:967
 runProof.C:968
 runProof.C:969
 runProof.C:970
 runProof.C:971
 runProof.C:972
 runProof.C:973
 runProof.C:974
 runProof.C:975
 runProof.C:976
 runProof.C:977
 runProof.C:978
 runProof.C:979
 runProof.C:980
 runProof.C:981
 runProof.C:982
 runProof.C:983
 runProof.C:984
 runProof.C:985
 runProof.C:986
 runProof.C:987
 runProof.C:988
 runProof.C:989
 runProof.C:990
 runProof.C:991
 runProof.C:992
 runProof.C:993
 runProof.C:994
 runProof.C:995
 runProof.C:996
 runProof.C:997
 runProof.C:998
 runProof.C:999
 runProof.C:1000
 runProof.C:1001
 runProof.C:1002
 runProof.C:1003
 runProof.C:1004
 runProof.C:1005
 runProof.C:1006
 runProof.C:1007
 runProof.C:1008
 runProof.C:1009
 runProof.C:1010
 runProof.C:1011
 runProof.C:1012
 runProof.C:1013
 runProof.C:1014
 runProof.C:1015
 runProof.C:1016
 runProof.C:1017
 runProof.C:1018
 runProof.C:1019
 runProof.C:1020
 runProof.C:1021
 runProof.C:1022
 runProof.C:1023
 runProof.C:1024
 runProof.C:1025
 runProof.C:1026
 runProof.C:1027
 runProof.C:1028
 runProof.C:1029
 runProof.C:1030
 runProof.C:1031
 runProof.C:1032
 runProof.C:1033
 runProof.C:1034
 runProof.C:1035
 runProof.C:1036
 runProof.C:1037
 runProof.C:1038
 runProof.C:1039
 runProof.C:1040
 runProof.C:1041
 runProof.C:1042
 runProof.C:1043
 runProof.C:1044
 runProof.C:1045
 runProof.C:1046
 runProof.C:1047
 runProof.C:1048
 runProof.C:1049
 runProof.C:1050
 runProof.C:1051
 runProof.C:1052
 runProof.C:1053
 runProof.C:1054
 runProof.C:1055
 runProof.C:1056
 runProof.C:1057
 runProof.C:1058
 runProof.C:1059
 runProof.C:1060
 runProof.C:1061
 runProof.C:1062
 runProof.C:1063
 runProof.C:1064
 runProof.C:1065
 runProof.C:1066
 runProof.C:1067
 runProof.C:1068
 runProof.C:1069
 runProof.C:1070
 runProof.C:1071
 runProof.C:1072
 runProof.C:1073
 runProof.C:1074
 runProof.C:1075
 runProof.C:1076
 runProof.C:1077
 runProof.C:1078
 runProof.C:1079
 runProof.C:1080
 runProof.C:1081
 runProof.C:1082
 runProof.C:1083
 runProof.C:1084
 runProof.C:1085
 runProof.C:1086
 runProof.C:1087
 runProof.C:1088
 runProof.C:1089
 runProof.C:1090
 runProof.C:1091
 runProof.C:1092
 runProof.C:1093
 runProof.C:1094
 runProof.C:1095
 runProof.C:1096
 runProof.C:1097
 runProof.C:1098
 runProof.C:1099
 runProof.C:1100
 runProof.C:1101
 runProof.C:1102
 runProof.C:1103
 runProof.C:1104
 runProof.C:1105
 runProof.C:1106
 runProof.C:1107
 runProof.C:1108
 runProof.C:1109
 runProof.C:1110
 runProof.C:1111
 runProof.C:1112
 runProof.C:1113
 runProof.C:1114
 runProof.C:1115
 runProof.C:1116
 runProof.C:1117
 runProof.C:1118
 runProof.C:1119
 runProof.C:1120
 runProof.C:1121
 runProof.C:1122
 runProof.C:1123
 runProof.C:1124
 runProof.C:1125
 runProof.C:1126
 runProof.C:1127
 runProof.C:1128
 runProof.C:1129
 runProof.C:1130
 runProof.C:1131
 runProof.C:1132
 runProof.C:1133
 runProof.C:1134
 runProof.C:1135
 runProof.C:1136
 runProof.C:1137
 runProof.C:1138
 runProof.C:1139
 runProof.C:1140
 runProof.C:1141
 runProof.C:1142
 runProof.C:1143
 runProof.C:1144
 runProof.C:1145
 runProof.C:1146
 runProof.C:1147
 runProof.C:1148
 runProof.C:1149
 runProof.C:1150
 runProof.C:1151
 runProof.C:1152
 runProof.C:1153
 runProof.C:1154
 runProof.C:1155
 runProof.C:1156
 runProof.C:1157
 runProof.C:1158
 runProof.C:1159
 runProof.C:1160
 runProof.C:1161
 runProof.C:1162
 runProof.C:1163
 runProof.C:1164
 runProof.C:1165
 runProof.C:1166
 runProof.C:1167
 runProof.C:1168
 runProof.C:1169
 runProof.C:1170
 runProof.C:1171
 runProof.C:1172
 runProof.C:1173
 runProof.C:1174
 runProof.C:1175
 runProof.C:1176
 runProof.C:1177
 runProof.C:1178
 runProof.C:1179
 runProof.C:1180
 runProof.C:1181
 runProof.C:1182
 runProof.C:1183
 runProof.C:1184
 runProof.C:1185
 runProof.C:1186
 runProof.C:1187
 runProof.C:1188
 runProof.C:1189
 runProof.C:1190
 runProof.C:1191
 runProof.C:1192
 runProof.C:1193
 runProof.C:1194
 runProof.C:1195
 runProof.C:1196
 runProof.C:1197
 runProof.C:1198
 runProof.C:1199
 runProof.C:1200
 runProof.C:1201
 runProof.C:1202
 runProof.C:1203
 runProof.C:1204
 runProof.C:1205
 runProof.C:1206