ROOT logo
/**
 * @file   ProofHelper.C
 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
 * @date   Tue Oct 16 18:58:37 2012
 * 
 * @brief  
 * 
 *
 * @ingroup pwglf_forward_trains_helper
 * 
 */
#ifndef PROOFHELPER_C
#define PROOFHELPER_C
#include "Helper.C"
#ifndef __CINT__
# include "OutputUtilities.C"
# include "ParUtilities.C"
# include "ChainBuilder.C"
# include <TUrl.h>
# include <TString.h>
# include <TProof.h>
# include <TProofLog.h>
# include <TProofDebug.h>
# include <AliAnalysisManager.h>
# include <TEnv.h>
# include <TChain.h>
// For SendFile
# include <TSystem.h>
# include <TSlave.h>
# include <TSocket.h>
# include <cerrno>
#else
class TUrl;
class TChain;
#endif

// ===================================================================
/**
 * Handle analysis on a Proof farm. 
 * 
 * This helper is triggered by URIs of the form 
 *
 * @code
 * proof://[<user>@]<host>[:<port>]/<dsname>[?<options>][#<treename>]
 * @endcode 
 * where 
 * <dl>
 *   <dt>&lt;user&gt;</dt>
 *   <dd>Optional user name</dd>
 *   <dt>&lt;host&gt;</dt>
 *   <dd>PROOF cluster master host</dd>
 *   <dt>&lt;port&gt;</dt>
 *   <dd>Optional PROOF cluster port on master host</dd>
 *   <dt>&lt;dsname&gt;</dt>
 *   <dd>Data set name</dd>
 *   <dt>&lt;treename&gt;</dt>
 *   <dd>Optional tree name in data set, often <tt>esdTree</tt> or
 *   <tt>aodTree</tt></dd>
 *   <dt>&lt;options&gt;</dt>
 *   <dd>List of options separated by an &amp;
 *     <dl>
 *       <dt><tt>workers=N[x]</tt></dt>
 *       <dd>Set the number of workers to use.  If <tt>x</tt> is appended, 
 *         then it's maximum number of workers per slave</dd>
 *       <dt><tt>dsname</tt>[=&lt;output dataset&gt;]</dt>
 *       <dd>Register tree output (e.g., AOD) as a new data set on the
 *         PROOF cluster. If &lt;output dataset&gt; is not specified, take
 *         the name of the train.</dd>
 *       <dt><tt>par[=all]</tt></dt>
 *       <dd>Use PAR files.  If the value <tt>all</tt> is given, then also 
 *         PAR files of STEERBase, ESD, AOD, ANALYSIS, OADB, ANALYSISalice 
 *         are used. </dd>
 *       <dt><tt>mode=[default,rec,sim,train,custom]</tt></dt>
 *       <dd>Set the AliROOT mode.  If not specified <tt>default</tt> 
 *         is assumed.  See also CreateAliROOTPar</dd>
 *       <dt><tt>storage=&lt;url&gt;</tt></dt>
 *       <dd>Specify a non-default storage location for special output
 *         (e.g., AOD trees).  &lt;url&gt; should be a valid XRootd 
 *         server URI accessible to the slaves - e.g., 
 *         <tt>root://lxplus.cern.ch:10930//tmp</tt>.</dd>
 *     </dl>
 *   </dd>
 * </dl>  
 *
 * @ingroup pwglf_forward_trains_helper
 */
struct ProofHelper : public Helper
{
  /** 
   * Constructor 
   * 
   * @param url  Url 
   * @param verbose Verbosity level
   */
  ProofHelper(const TUrl& url, Int_t verbose)
    : Helper(url, verbose), 
      fExtraLibs(""),
      fExtraPars(""),
      fExtraSrcs(""),
      fUsePars(false), 
      fBasePars(false),
      fTestBuild(true),
      fAuxFiles()
  {
    fOptions.Add("workers",  "N[x]", "Number of workers to use", 0);
    fOptions.Add("dsname",   "NAME", "Make output dataset", "");
    fOptions.Add("par",      "tasks|all", "Use par files",           "tasks");
    fOptions.Add("mode",     "default|rec|sim", "AliROOT mode",      "default");
    fOptions.Add("storage",  "URL", "Location for external storage", "");    
    fOptions.Add("wrapper",  "CMD", "Wrapper command", "");
    fOptions.Add("clear",    "PKGS", "Clear packages ','-separated", "");
    fOptions.Add("reset",    "soft|hard", "Reset cluster", "hard");
    fOptions.Add("feedback", "Enable feedback mechanism");
    fOptions.Add("env",      "SCRIPT", "Script to set-up environment","-none-");
    fOptions.Add("offset",   "EVENTS", "Skip this number of events", 0);
    fOptions.Add("testpar",  "Test build PARs");
    if (!fUrl.GetUser() || fUrl.GetUser()[0] == '\0') 
      fUrl.SetUser(gSystem->GetUserInfo()->fUser);
    fAuxFiles.SetOwner();
  }
  ProofHelper(const ProofHelper& o) 
    : Helper(o),
      fExtraLibs(""),
      fExtraPars(""),
      fExtraSrcs(""),
      fUsePars(false), 
      fBasePars(false),
      fTestBuild(true),
      fAuxFiles()
  {}
  ProofHelper& operator=(const ProofHelper& o) 
  {
    if (&o == this) return *this;
    Helper::operator=(o);
    fExtraLibs = o.fExtraLibs;
    fExtraPars = o.fExtraPars;
    fExtraSrcs = o.fExtraSrcs;
    fUsePars   = o.fUsePars;    
    fBasePars  = o.fBasePars;
    fTestBuild = o.fTestBuild;
    // fAuxFiles;
    return *this;
  }
  /** 
   * Destructor 
   */
  virtual ~ProofHelper() {}
  /** 
   * Load a library/PAR/script 
   * 
   * @param name   Name 
   * @param slaves If true, also load on slaves
   * 
   * @return true on success 
   */
  virtual Bool_t LoadLibrary(const TString& name, 
			     Bool_t slaves=true)
  {
    Bool_t isBase = false;
    if (!fBasePars) { 
      if (name.EqualTo("STEERBase")      || 
	  name.EqualTo("ESD")            || 
	  name.EqualTo("AOD")            || 
	  name.EqualTo("ANALYSIS")       || 
	  name.EqualTo("OADB")           || 
	  name.EqualTo("ANALYSISalice")) 
	isBase = true;
    }
    if (!fUsePars || isBase) {
      Int_t ret = gSystem->Load(MakeLibraryName(name));
      if (ret < 0) return false;
      if (slaves) fExtraLibs.Append(Form(":%s", name.Data()));
    }
    else { 
      if (!ParUtilities::Find(name)) { 
	Error("ProofHelper::LoadLibrary", "Failed to find PAR file %s", 
	      name.Data());
	return false;
      }
      if (fTestBuild && !ParUtilities::Build(name)) { 
	Error("ProofHelper::LoadLibrary", "Failed to build PAR file %s", 
	      name.Data());
	return false;
      }
      if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0) {
	Error("ProofHelper::LoadLibrary", "Failed to upload PAR file %s", 
	      name.Data());
	return false;
      }
      fExtraPars.Append(Form(":%s", name.Data()));
    }
    return true;
  }
  /** 
   * Load a source file, and compile it 
   * 
   * @param name Name of the source file 
   * @param copy If true, copy not link 
   * 
   * @return true on success
   */
  virtual Bool_t LoadSource(const TString& name, bool copy=false)
  {
    if (!Helper::LoadSource(name, copy)) return false;
    fExtraSrcs.Append(Form(":%s", gSystem->BaseName(name.Data())));
    return true;
  }
  /** 
   * Set-up to load the AliROOT libraries 
   * 
   * @return true on success
   */
  virtual Bool_t LoadAliROOT()
  {
    if (!gSystem->Getenv("ALICE_ROOT")) { 
      Error("ProofHelper::LoadAliROOT", "Local AliROOT not available");
      return false;
    }

    Bool_t tmp = fUsePars;
    fUsePars   = fBasePars;
    if (!LoadLibrary("STEERBase"))     return false;
    if (!LoadLibrary("ESD"))           return false;
    if (!LoadLibrary("AOD"))           return false;
    if (!LoadLibrary("ANALYSIS"))      return false;
    if (!LoadLibrary("OADB"))          return false;
    if (!LoadLibrary("ANALYSISalice")) return false;
    fUsePars = tmp;

    return CreateAliROOTPar();
  }
  /** 
   * Get the name of the AliROOT par file to use 
   * 
   * @return String 
   */
  virtual const char* AliROOTParName() const
  {
    return "ALIROOT";
  }
  /** 
   * Create an AliROOT par file from the executing AliROOT.  This PAR
   * file basically uses the environment of the client - that is, we
   * assume that the used AliROOT is accessible on the slaves - e.g.,
   * via an NFS export.
   * 
   * Note, the SETUP.C script take one argument - a TList of TNamed
   * parameters.  Parameters processed are	
   *
   * - ALIROOT_MODE=[default,aliroot,rec,sim,train]
   *   - default: Load base analysis libraries 
   *   - aliroot: Load $ALICE_ROOT/macros/loadlibs.C
   *   - rec:     Load $ALICE_ROOT/macros/loadlibsrec.C
   *   - sim:     Load $ALICE_ROOT/macros/loadlibssim.C
   * - ALIROOT_EXTRA_LIBS Colon separated list of additional (Ali)ROOT
   *   libraries to load on the slaves.
   * 
   * The generated PAR file is uploaded but not enabled until we have 
   * populated fExtraLibs.  The enabling takes place at the end of the 
   * set-up. 
   * 
   * @return true on success, false otherwise.     */
  virtual Bool_t CreateAliROOTPar()
  {
    if (fBasePars) return true;

    TString parName(AliROOTParName());
    TString parFile(Form("%s.par", parName.Data()));

    // --- Check if we have the drirectory already -------------------
    if (gSystem->AccessPathName(parName.Data()) == 0) { 
      // Let's remove it to get a clean slate 
      if (gSystem->Exec(Form("rm -rf %s", parName.Data())) != 0) {
	Error("ProofHelper", "Failed to remove %s", parName.Data());
	return false;
      }
    }
    // --- Check if the PAR file is there, and remove it if so -------
    if (gSystem->AccessPathName(parFile.Data()) == 0) { 
      if (gSystem->Unlink(parFile.Data()) != 0) { 
	Error("ProofHelper::CreateAliROOTPar", "Failed to remove %s", 
	      parFile.Data());
	return false;
      }
    }
      

    // Set-up directories 
    if (gSystem->MakeDirectory(parName) < 0) {
      Error("ProofHelper::CreateAliROOTPar", "Could not make directory '%s'", 
	    parName.Data());
      return false;
    }
    
    if (gSystem->MakeDirectory(Form("%s/PROOF-INF", parName.Data()))) {
      Error("ProofHelper::CreateAliROOTPar", 
	    "Could not make directory %s/PROOF-INF", 
	    parName.Data());
      return false;
    }

    std::ofstream b(Form("%s/PROOF-INF/BUILD.sh",parName.Data()));
    if (!b) { 
      Error("ProofHelper::CreateAliROOTPar", 
	    "Failed to make BUILD.sh shell script");
      return false;
    }
    b << "#!/bin/sh\n\n"
      << "# echo Nothing to do\n"
      << "exit 0\n"
      << std::endl;
    b.close();
    gSystem->Exec(Form("chmod a+x %s/PROOF-INF/BUILD.sh",parName.Data()));

    TString envScript = fOptions.Get("env");
    if (envScript.EqualTo("-none-", TString::kIgnoreCase)) 
      envScript = "";
    if (!envScript.IsNull()) { 
      // If an environment script was specified, copy that to the par
      if (gSystem->AccessPathName(envScript.Data()) == 0) { 
	// Copy script 
	if (gSystem->Exec(Form("cp %s %s/PROOF-INF/", envScript.Data(), 
			       parName.Data())) != 0) {
	  Error("ProofHelper", "Failed to copy %s", envScript.Data());
	  return false;
	}
      }
      else {
	Warning("CreateALIROOTPar", "Couldn't read %s", envScript.Data());
	envScript = "";
      }
    }
    std::ofstream s(Form("%s/PROOF-INF/SETUP.C", parName.Data()));
    if (!s) { 
      Error("ProofHelper::CreateAliROOTPar", 
	    "Failed to make SETUP.C ROOT script");
      return false;
    }
    s << "void SETUP(TList* opts) {\n";
    if (envScript.IsNull()) {
      s << "  gSystem->Setenv(\"ALICE\",\"" 
      << gSystem->Getenv("ALICE") << "\");\n"
      << "  gSystem->Setenv(\"ALICE_ROOT\",\"" 
      << gSystem->Getenv("ALICE_ROOT") << "\");\n"
      << "  gSystem->Setenv(\"ALICE_TARGET\",\"" 
	<< gSystem->Getenv("ALICE_TARGET") << "\");\n";
    if (gSystem->Getenv("OADB_PATH")) 
      s << "  gSystem->Setenv(\"OADB_PATH\",\"" 
	<< gSystem->Getenv("OADB_PATH") << "\");\n";
    }
    else { 
      s << "  gROOT->Macro(\"PROOF-INF/" << gSystem->BaseName(envScript.Data())
	<< "\");\n";
    }
    s  	<< "  gSystem->AddDynamicPath("
	<< "\"$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET)\");\n";
    s << "  \n"
      << "  // Info(\"SETUP\",\"Loading ROOT libraries\");\n"
      << "  gSystem->Load(\"libTree\");\n"
      << "  gSystem->Load(\"libGeom\");\n"
      << "  gSystem->Load(\"libVMC\");\n"
      << "  gSystem->Load(\"libPhysics\");\n"
      << "  gSystem->Load(\"libMinuit\");\n"
      << "  \n";
    s << "  // Info(\"SETUP\",\"Parameter list:\");\n"
      << "  if (!opts) return;\n"
      << "  //opts->ls();\n"
      << "  \n";
    s << "  TObject* par = opts->FindObject(\"ALIROOT_MODE\");\n"
      << "  if (par) {\n"
      << "    // Info(\"SETUP\",\"ALIROOT mode: %s\", par->GetTitle());\n"
      << "    TString mode(par->GetTitle());\n"
      << "    if (mode.EqualTo(\"default\",TString::kIgnoreCase)) {\n"
      << "      gSystem->Load(\"libSTEERBase\");\n"
      << "      gSystem->Load(\"libESD\");\n"
      << "      gSystem->Load(\"libAOD\");\n"
      << "      gSystem->Load(\"libANALYSIS\");\n"
      << "      gSystem->Load(\"libOADB\");\n"
      << "      gSystem->Load(\"libANALYSISalice\");\n"
      << "    }\n"
      << "    else if (mode.EqualTo(\"aliroot\",TString::kIgnoreCase)) \n"
      << "      gROOT->Macro(\"$ALICE_ROOT/macros/loadlibs.C\");\n"
      << "    else if (mode.EqualTo(\"rec\",TString::kIgnoreCase)) \n"
      << "      gROOT->Macro(\"$ALICE_ROOT/macros/loadlibsrec.C\");\n"
      << "    else if (mode.EqualTo(\"sim\",TString::kIgnoreCase)) \n"
      << "      gROOT->Macro(\"$ALICE_ROOT/macros/loadlibssim.C\");\n"
      << "    else if (mode.EqualTo(\"train\",TString::kIgnoreCase)) \n"
      << "      gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
      << "    else if (mode.EqualTo(\"custom\",TString::kIgnoreCase)) \n"
      << "      gROOT->Macro(\"$ALICE_ROOT/macros/loadlibstrain.C\");\n"
      << "  }\n"
      << "  \n";
    s << "  par = opts->FindObject(\"ALIROOT_EXTRA_LIBS\");\n"
      << "  if (par) {\n"
      << "    Info(\"SETUP\",\"Libaries to load: %s\\n\",par->GetTitle());\n"
      << "    TString tit(par->GetTitle());\n"
      << "    TObjArray* tokens = tit.Tokenize(\":\");\n"
      << "    TObject*   lib    = 0;\n"
      << "    TIter      next(tokens);\n"
      << "    while ((lib = next())) {\n"
      << "      TString libName(lib->GetName());\n"
      << "      if (!libName.BeginsWith(\"lib\")) libName.Prepend(\"lib\");\n"
      << "      // Info(\"SETUP\",\"Loading %s ...\",libName.Data());\n"
      << "      gSystem->Load(libName.Data());\n"
      << "    }\n"
      << "  }\n"
      << "}\n"
      << std::endl;
    s.close();

    Int_t ret = gSystem->Exec(Form("tar -czf %s %s",
				   parFile.Data(), parName.Data()));
    if (ret != 0) { 
      Error("ProofHelper::CreateAliROOTPar", "Failed to pack up PAR file %s",
	    parFile.Data());
      return false;
    }

    ret = gProof->UploadPackage(parFile.Data(),TProof::kRemoveOld);
    if (ret != 0) { 
      Error("ProofHelper::CreateAliROOTPar", 
	    "Failed to upload the AliROOT PAR file");
      return false;
    }
    // Note, the PAR isn't enabled until much later when we've
    // collected all the needed libraries in fExtraLibs
    return true;
  }
  /** 
   * Get the mode identifier 
   * 
   * @return Always kProof
   */
  virtual UShort_t Mode() const { return kProof; }
  /**
   * Get the mode string used for AliAnalysisManager::StartAnalysis
   */
  virtual const char* ModeString() const { return "proof"; }
  /** 
   * Set-up done before task set-ups 
   * 
   * @return true on success 
   */
  virtual Bool_t PreSetup()
  {
    // --- Set prefered GSI method ---------------------------------
    gEnv->SetValue("XSec.GSI.DelegProxy", "2");

    // --- Add ALICE_ROOT directory to search path for packages ----
    // Info("ProofHelper::PreSetup", "Set location of packages");
    gEnv->SetValue("Proof.GlobalPackageDirs", 
		   Form("%s:%s", 
			gEnv->GetValue("Proof.GlobalPackageDirs", "."), 
			gSystem->Getenv("ALICE_ROOT")));

    // --- Forming the URI we use to connect with --------------------
    TUrl connect(fUrl);
    connect.SetAnchor("");
    connect.SetFile("");
    connect.SetOptions("");

    // --- Check if we need to reset first ---------------------------
    if (fOptions.Has("reset")) { 
      TString reset = fOptions.Get("reset");
      Bool_t  hard  = (reset.IsNull() || 
		       reset.EqualTo("hard", TString::kIgnoreCase));
      Info("ProofHelper::PreSetup", "Doing a %s reset of %s", 
	   hard ? "hard" : "soft", connect.GetUrl());
      TProof::Reset(connect.GetUrl(), hard);
      Int_t secs = 3;
      Info("ProofHelper::PreSetup", 
	   "Waiting for %d second%s for things to settle", secs,
	   secs > 1 ? "s" : "");
      gSystem->Sleep(1000*secs);
    }
      
    // --- Check if we're using a wrapper ----------------------------
    if (fOptions.Has("wrapper")) { 
      TString wrapper = fOptions.Get("wrapper");
      if (wrapper.IsNull()) 
	// In case of no argument, use GDB 
	// Just run and backtrace 
	wrapper = "/usr/bin/gdb --batch -ex run -ex bt --args";
      Info("ProofHelper::PreSetup", "Using wrapper command: %s", 
	   wrapper.Data());
      TProof::AddEnvVar("PROOF_WRAPPERCMD", wrapper);
    }

    // --- PAR parameters --------------------------------------------
    fUsePars   = fOptions.Has("par");
    fBasePars  = (fUsePars && 
		  fOptions.Get("par").EqualTo("all",TString::kIgnoreCase));
    fTestBuild = fOptions.Has("testpar");

    // --- Connect to the cluster ------------------------------------
    TString opts;
    if (fOptions.Has("workers")) 
      opts.Append(Form("workers=%s", fOptions.Get("workers").Data()));
      
    Info("ProofHelper::PreSetup", "Connecting to %s with %soptions %s", 
	 connect.GetUrl(), 
	 opts.IsNull() ? "no " : "", 
	 opts.Data());
    TString proto(connect.GetProtocol());
    if (proto.BeginsWith("lite") && fOptions.Has("workers")) 
      TProof::Open(opts);
    else 
      TProof::Open(connect.GetUrl(), opts);
    // TProof::Open(connect.GetHost(), opts);
    if (!gProof) { 
      Error("ProofHelper::PreSetup", "Failed to open Proof connection %s", 
	    connect.GetUrl());
      return false;
    }
    
    // --- Check if we need to clear packages ------------------------
    if (fOptions.Has("clear")) {
      TString pkgs = fOptions.Get("clear");
      if (pkgs.IsNull() || pkgs.EqualTo("all", TString::kIgnoreCase)) { 
	// No value given, clear all 
	if (gProof->ClearPackages() != 0) 
	  Warning("ProofHelper::PreSetup", "Failed to lear all packages");
      }
      else { 
	// Tokenize on ',' and clear each package 
	TObjArray* pars = pkgs.Tokenize(",");
	TObject*   pkg  = 0;
	TIter      next(pars); 
	while ((pkg = next())) { 
	  if (gProof->ClearPackage(pkg->GetName()) != 0)
	    Warning("ProofHelper::PreSetup", "Failed to clear package %s", 
		    pkg->GetName());
	}
	pars->Delete();
      }
    }
    return true;
  }
  /** 
   * Set-up done after the task set-ups 
   *
   * @return true on success 
   */
  virtual Bool_t PostSetup() 
  {
    AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) { 
      Error("ProofHelper::PostSetup", "No analysis manager defined");
      return false;
    }

    // --- Check for output ------------------------------------------
    if (fOptions.Has("dsname")) 
      OutputUtilities::RegisterDataset(fOptions.Get("dsname"));
    if (fOptions.Has("storage"))
      OutputUtilities::RegisterStorage(fOptions.Get("storage"));

    // --- Check for feedback mechanism ------------------------------
    if (!fOptions.Has("feedback"))
      gProof->ClearFeedback();

    // --- If we are not using PARs for Base, enable special PAR -----
    if (!fBasePars) {
      TString tmp(fExtraLibs.Strip(TString::kBoth,':'));
      TList* params = new TList;
      params->SetOwner(true);
      params->Add(new TNamed("ALIROOT_EXTRA_LIBS", tmp.Data()));
      if (fOptions.Has("mode"))
	params->Add(new TNamed("ALIROOT_MODE", fOptions.Get("mode").Data()));
      else
	params->Add(new TNamed("ALIROOT_MODE", "default"));
      Int_t ret = gProof->EnablePackage(AliROOTParName(), params, true);
      if (ret < 0) {
	Error("ProofHelper::EnableAliROOT", "Failed to enable AliROOT PAR %s", 
	      AliROOTParName());
	return false;
      }
    }

    // --- Make PAR file of Aux Files --------------------------------
    if (fAuxFiles.GetEntries() > 0) { 
      TString name = TString::Format("%s_auxfiles", mgr->GetName());
      ParUtilities::MakeAuxFilePAR(fAuxFiles, name);

      if (gProof->UploadPackage(name.Data(), TProof::kRemoveOld) < 0) 
	Error("ProofHelper::PostSetup", "Failed to upload PAR file %s", 
	      name.Data());
      else 
	fExtraPars.Append(Form(":%s", name.Data()));
    }
    
    // --- Load par files --------------------------------------------
    TString    tmp  = fExtraPars.Strip(TString::kBoth,':');
    TObjArray* pars = tmp.Tokenize(":");
    TObject*   obj  = 0;
    TIter      next(pars);
    while ((obj = next())) { 
      // Enable the package, but do not build on client - already done
      Int_t ret = gProof->EnablePackage(obj->GetName(), true);
      if (ret < 0) { 
	Error("ProofHelper::PostSetup", "Failed to enable PAR %s",
	      obj->GetName());
	return false;
      }
    }
    
    // --- Load extra sources ----------------------------------------
    TString    tmp2 = fExtraSrcs.Strip(TString::kBoth, ':');
    TObjArray* srcs = tmp2.Tokenize(":");
    TIter      next2(srcs);
    while ((obj = next())) { 
      Int_t ret = gProof->Load(Form("%s++g", obj->GetName()), true);
      if (ret < 0) { 
	Error("ProofHelper::PostSetup", "Failed to compile %s", obj->GetName());
	return false;
      }
    }
    return true;
  }
  /** 
   * Start the analysis 
   * 
   * @param nEvents Number of events to analyse 
   * 
   * @return The return value of AliAnalysisManager::StartAnalysis
   */
  virtual Long64_t Run(Long64_t nEvents=-1) 
  {
    AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
    gProof->SetLogLevel(TMath::Max(fVerbose-2,0), 
			/* TProofDebug::kPacketizer| */
			TProofDebug::kLoop|
			/* TProofDebug::kSelector|
			TProofDebug::kOutput|
			TProofDebug::kInput|
			TProofDebug::kGlobal|*/
			TProofDebug::kPackage);
    TString dsName(fUrl.GetFile());
    // if (fUrl.GetAnchor() && fUrl.GetAnchor()[0] != '\0') 
    //   dsName.Append(Form("#%s", fUrl.GetAnchor()));
    // Info("Run", "Output objects registered with PROOF:");
    // gProof->GetOutputList()->ls();
    Long64_t off = fOptions.AsLong("offset", 0);
    if (nEvents > 0 && nEvents < off) {
      Warning("Run", "Number of events %lld < offset (%lld), stopping", 
	      nEvents, off);
      return 0;
    }
    Long64_t ret = mgr->StartAnalysis(fUrl.GetProtocol(), dsName, nEvents, off);
    
    if (fVerbose > 10) 
      TProof::Mgr(fUrl.GetUrl())->GetSessionLogs()->Save("*","proof.log");
    return ret;
  }
#if 0
  Bool_t AddMonitor(const TString& path)
  {
    if (path.IsNull()) return true;

    TObjArray* tokens  = path.Tokenize("/");
    Int_t      nTokens = tokens->GetEntries();
    if (nTokens < 2) { 
      Error("AddMonitor", "Monitors must be of the form:\n"
	    "  <task>[:<slot>]/<name>\n"
	    "  <task>[:<slot>]/<path>/<name>");
      return false;
    }
    // --- Get the manager 
    AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();

    // --- Extract task and possibly slot number 
    TString& sTask  = static_cast<TObjString*>(tokens->At(0))->String();
    Int_t    slotNo = 0;
    Ssiz_t   colon  = sTask.Index(":");
    if (colon != kNPOS) { 
      TString sSlot = sTask(colon+1, sTask.Length()-colon-1);
      if (!sSlot.IsNull()) slotNo = sSlot.Atoi();
      sTask.Remove(colon, sTask.Length()-colon);
    }
    
    AliAnalysisTask* task = mgr->GetTask(sTask);
    if (!task) { 
      Error("AddMonitor", "Task \"%s\" not registered with manager", 
	    sTask.Data());
      return false;
    }
    AliAnalysisDataSlot* slot = task->GetOutputSlot(slotNo);
    if (!slot) { 
      Error("AddMonitor", "Task \"%s\" does not have an output slot at %d",
	    task->GetName(), slotNo);
      return false;
    }
    AliAnalysisDataContainer* cont = slot->GetContainer();
    if (!cont) {
      Error("AddMonitor", "Output slot %d of task \"%s\" has no container",
	    slotNo, task->GetName());
      return false;
    }
    Int_t    idx   = 1;
    TString& first = static_cast<TObjString*>(tokens->At(idx))->String(); 
    if (first.EqualTo(cont->GetName())) {
      idx++;
    }
    TObject* data = cont->GetData();
    TObject* obj  = data; 
    for (; idx < nTokens; idx++) {
    }
    return true;
  }
#endif
  /** 
   * Print information to standard output
   * 
   * @param option 
   */
  virtual void Print(Option_t* option="") const 
  {
    Helper::Print(option);
    std::cout << std::boolalpha 
	      << "  --- Other settings -------\n"
	      << "  Extra libraries  : " << fExtraLibs << "\n"
	      << "  Extra PARs       : " << fExtraPars << "\n"
	      << "  Extra sources    : " << fExtraSrcs << "\n"
	      << "  Use PARs of tasks: " << fUsePars   << "\n"
	      << "  Use PARs of base : " << fBasePars  
	      << std::noboolalpha << std::endl;
  }
  /** 
   * Link an auxilary file to working directory 
   * 
   * @param name Name of the file
   * @param copy Copy rather than link
   *
   * @return true on success
   */
  virtual Bool_t AuxFile(const TString& name, bool copy=false)
  {
    Bool_t ret = Helper::AuxFile(name, copy);
    if (!name.BeginsWith("/")) {
      fAuxFiles.Add(new TObjString(name));
    }
#if 0
    if (ret && name.EndsWith(".root")) { 
      TFile* file = TFile::Open(name, "READ");
      if (file) {
	Info("AuxFile", "Adding input file %s", name.Data());
	gProof->AddInputData(file, true);
      }
    }
#endif
    return ret;
  }
  Int_t SendFile(const TString& fileName) 
  {
    Int_t    bufSize = 32768;
    Char_t   buf[bufSize];
    Long64_t size = 0;
    Long_t   id = 0, flags = 0, modtime = 0;
    if (gSystem->GetPathInfo(fileName.Data(), &id, &size, &flags, &modtime)==1 
	|| size <= 0) {
      Error("SendFile", "Cannot stat %s", fileName.Data());
      return -1;
    }
    TString fn(gSystem->BaseName(fileName.Data()));
    TList*  slaves = 0; // gProof->GetListOfActiveSlaves(); - protected
    TIter   next(slaves);
    TSlave* sl   = 0;
    Int_t   ret  = 0;
    Int_t   fd = open(fileName.Data(), O_RDONLY);
    while ((sl = static_cast<TSlave*>(next()))) {
      if (!sl->IsValid()) continue;
      if (sl->GetSlaveType() != TSlave::kSlave) continue;
      
      // Always binary (first 1), never forward (last 0).
      snprintf(buf,bufSize,"%s %d %lld %d", fn.Data(), 1, size, 0);
      if (sl->GetSocket()->Send(buf, kPROOF_SENDFILE) == -1) {
	Warning("SendFile", "Could not send kPROOF_SENDFILE request");
	continue;
      }

      // Go to the beginning of the file 
      lseek(fd, 0, SEEK_SET);
      Int_t len = 0;
      do { 
	while ((len = read(fd, buf, bufSize)) < 0 && 
	       TSystem::GetErrno() == EINTR)
	  TSystem::ResetErrno();
	if (len < 0) { 
	  Error("SendFile", "error reading input");
	  close(fd);
	  return -1;
	}
	if (len > 0 && sl->GetSocket()->SendRaw(buf, len) == -1) {
	  Error("SendFile", "error writing to slave");
	  sl = 0;
	  break;
	}
      } while (len > 0);
      ret ++;

      // Wait for slave - private
      // if (sl) gProof->Collect(sl,gEnv->GetValue("Proof.CollectTimeout",-1));
    }

    // Close the file 
    close(fd);

    return ret;
  }
  /** 
   * Path of output 
   * 
   * @return Path to output - possibly a data set
   */
  virtual TString OutputPath() const 
  {
    TString ret;
    if (fOptions.Has("dsname")) {
      ret = Form("/%s/%s/", gProof->GetGroup(), gProof->GetUser());
      ret.Append(OutputUtilities::RegisteredDataset());
    }
    return ret;
  }
  /** 
   * @return URL help string
   */
  virtual const Char_t* UrlHelp() const 
  {
    return "proof://<host>[:<port>]/[<dataset>|<path>][?<options>][#<treeName>]";
  }
  /** 
   * @return Short description 
   */
  virtual const char* Desc() const { return "PROOF"; }
  TString fExtraLibs;
  TString fExtraPars;
  TString fExtraSrcs;
  Bool_t  fUsePars;
  Bool_t  fBasePars;
  Bool_t  fTestBuild;
  TList   fAuxFiles;
};
#endif
//
// EOF
//
 ProofHelper.C:1
 ProofHelper.C:2
 ProofHelper.C:3
 ProofHelper.C:4
 ProofHelper.C:5
 ProofHelper.C:6
 ProofHelper.C:7
 ProofHelper.C:8
 ProofHelper.C:9
 ProofHelper.C:10
 ProofHelper.C:11
 ProofHelper.C:12
 ProofHelper.C:13
 ProofHelper.C:14
 ProofHelper.C:15
 ProofHelper.C:16
 ProofHelper.C:17
 ProofHelper.C:18
 ProofHelper.C:19
 ProofHelper.C:20
 ProofHelper.C:21
 ProofHelper.C:22
 ProofHelper.C:23
 ProofHelper.C:24
 ProofHelper.C:25
 ProofHelper.C:26
 ProofHelper.C:27
 ProofHelper.C:28
 ProofHelper.C:29
 ProofHelper.C:30
 ProofHelper.C:31
 ProofHelper.C:32
 ProofHelper.C:33
 ProofHelper.C:34
 ProofHelper.C:35
 ProofHelper.C:36
 ProofHelper.C:37
 ProofHelper.C:38
 ProofHelper.C:39
 ProofHelper.C:40
 ProofHelper.C:41
 ProofHelper.C:42
 ProofHelper.C:43
 ProofHelper.C:44
 ProofHelper.C:45
 ProofHelper.C:46
 ProofHelper.C:47
 ProofHelper.C:48
 ProofHelper.C:49
 ProofHelper.C:50
 ProofHelper.C:51
 ProofHelper.C:52
 ProofHelper.C:53
 ProofHelper.C:54
 ProofHelper.C:55
 ProofHelper.C:56
 ProofHelper.C:57
 ProofHelper.C:58
 ProofHelper.C:59
 ProofHelper.C:60
 ProofHelper.C:61
 ProofHelper.C:62
 ProofHelper.C:63
 ProofHelper.C:64
 ProofHelper.C:65
 ProofHelper.C:66
 ProofHelper.C:67
 ProofHelper.C:68
 ProofHelper.C:69
 ProofHelper.C:70
 ProofHelper.C:71
 ProofHelper.C:72
 ProofHelper.C:73
 ProofHelper.C:74
 ProofHelper.C:75
 ProofHelper.C:76
 ProofHelper.C:77
 ProofHelper.C:78
 ProofHelper.C:79
 ProofHelper.C:80
 ProofHelper.C:81
 ProofHelper.C:82
 ProofHelper.C:83
 ProofHelper.C:84
 ProofHelper.C:85
 ProofHelper.C:86
 ProofHelper.C:87
 ProofHelper.C:88
 ProofHelper.C:89
 ProofHelper.C:90
 ProofHelper.C:91
 ProofHelper.C:92
 ProofHelper.C:93
 ProofHelper.C:94
 ProofHelper.C:95
 ProofHelper.C:96
 ProofHelper.C:97
 ProofHelper.C:98
 ProofHelper.C:99
 ProofHelper.C:100
 ProofHelper.C:101
 ProofHelper.C:102
 ProofHelper.C:103
 ProofHelper.C:104
 ProofHelper.C:105
 ProofHelper.C:106
 ProofHelper.C:107
 ProofHelper.C:108
 ProofHelper.C:109
 ProofHelper.C:110
 ProofHelper.C:111
 ProofHelper.C:112
 ProofHelper.C:113
 ProofHelper.C:114
 ProofHelper.C:115
 ProofHelper.C:116
 ProofHelper.C:117
 ProofHelper.C:118
 ProofHelper.C:119
 ProofHelper.C:120
 ProofHelper.C:121
 ProofHelper.C:122
 ProofHelper.C:123
 ProofHelper.C:124
 ProofHelper.C:125
 ProofHelper.C:126
 ProofHelper.C:127
 ProofHelper.C:128
 ProofHelper.C:129
 ProofHelper.C:130
 ProofHelper.C:131
 ProofHelper.C:132
 ProofHelper.C:133
 ProofHelper.C:134
 ProofHelper.C:135
 ProofHelper.C:136
 ProofHelper.C:137
 ProofHelper.C:138
 ProofHelper.C:139
 ProofHelper.C:140
 ProofHelper.C:141
 ProofHelper.C:142
 ProofHelper.C:143
 ProofHelper.C:144
 ProofHelper.C:145
 ProofHelper.C:146
 ProofHelper.C:147
 ProofHelper.C:148
 ProofHelper.C:149
 ProofHelper.C:150
 ProofHelper.C:151
 ProofHelper.C:152
 ProofHelper.C:153
 ProofHelper.C:154
 ProofHelper.C:155
 ProofHelper.C:156
 ProofHelper.C:157
 ProofHelper.C:158
 ProofHelper.C:159
 ProofHelper.C:160
 ProofHelper.C:161
 ProofHelper.C:162
 ProofHelper.C:163
 ProofHelper.C:164
 ProofHelper.C:165
 ProofHelper.C:166
 ProofHelper.C:167
 ProofHelper.C:168
 ProofHelper.C:169
 ProofHelper.C:170
 ProofHelper.C:171
 ProofHelper.C:172
 ProofHelper.C:173
 ProofHelper.C:174
 ProofHelper.C:175
 ProofHelper.C:176
 ProofHelper.C:177
 ProofHelper.C:178
 ProofHelper.C:179
 ProofHelper.C:180
 ProofHelper.C:181
 ProofHelper.C:182
 ProofHelper.C:183
 ProofHelper.C:184
 ProofHelper.C:185
 ProofHelper.C:186
 ProofHelper.C:187
 ProofHelper.C:188
 ProofHelper.C:189
 ProofHelper.C:190
 ProofHelper.C:191
 ProofHelper.C:192
 ProofHelper.C:193
 ProofHelper.C:194
 ProofHelper.C:195
 ProofHelper.C:196
 ProofHelper.C:197
 ProofHelper.C:198
 ProofHelper.C:199
 ProofHelper.C:200
 ProofHelper.C:201
 ProofHelper.C:202
 ProofHelper.C:203
 ProofHelper.C:204
 ProofHelper.C:205
 ProofHelper.C:206
 ProofHelper.C:207
 ProofHelper.C:208
 ProofHelper.C:209
 ProofHelper.C:210
 ProofHelper.C:211
 ProofHelper.C:212
 ProofHelper.C:213
 ProofHelper.C:214
 ProofHelper.C:215
 ProofHelper.C:216
 ProofHelper.C:217
 ProofHelper.C:218
 ProofHelper.C:219
 ProofHelper.C:220
 ProofHelper.C:221
 ProofHelper.C:222
 ProofHelper.C:223
 ProofHelper.C:224
 ProofHelper.C:225
 ProofHelper.C:226
 ProofHelper.C:227
 ProofHelper.C:228
 ProofHelper.C:229
 ProofHelper.C:230
 ProofHelper.C:231
 ProofHelper.C:232
 ProofHelper.C:233
 ProofHelper.C:234
 ProofHelper.C:235
 ProofHelper.C:236
 ProofHelper.C:237
 ProofHelper.C:238
 ProofHelper.C:239
 ProofHelper.C:240
 ProofHelper.C:241
 ProofHelper.C:242
 ProofHelper.C:243
 ProofHelper.C:244
 ProofHelper.C:245
 ProofHelper.C:246
 ProofHelper.C:247
 ProofHelper.C:248
 ProofHelper.C:249
 ProofHelper.C:250
 ProofHelper.C:251
 ProofHelper.C:252
 ProofHelper.C:253
 ProofHelper.C:254
 ProofHelper.C:255
 ProofHelper.C:256
 ProofHelper.C:257
 ProofHelper.C:258
 ProofHelper.C:259
 ProofHelper.C:260
 ProofHelper.C:261
 ProofHelper.C:262
 ProofHelper.C:263
 ProofHelper.C:264
 ProofHelper.C:265
 ProofHelper.C:266
 ProofHelper.C:267
 ProofHelper.C:268
 ProofHelper.C:269
 ProofHelper.C:270
 ProofHelper.C:271
 ProofHelper.C:272
 ProofHelper.C:273
 ProofHelper.C:274
 ProofHelper.C:275
 ProofHelper.C:276
 ProofHelper.C:277
 ProofHelper.C:278
 ProofHelper.C:279
 ProofHelper.C:280
 ProofHelper.C:281
 ProofHelper.C:282
 ProofHelper.C:283
 ProofHelper.C:284
 ProofHelper.C:285
 ProofHelper.C:286
 ProofHelper.C:287
 ProofHelper.C:288
 ProofHelper.C:289
 ProofHelper.C:290
 ProofHelper.C:291
 ProofHelper.C:292
 ProofHelper.C:293
 ProofHelper.C:294
 ProofHelper.C:295
 ProofHelper.C:296
 ProofHelper.C:297
 ProofHelper.C:298
 ProofHelper.C:299
 ProofHelper.C:300
 ProofHelper.C:301
 ProofHelper.C:302
 ProofHelper.C:303
 ProofHelper.C:304
 ProofHelper.C:305
 ProofHelper.C:306
 ProofHelper.C:307
 ProofHelper.C:308
 ProofHelper.C:309
 ProofHelper.C:310
 ProofHelper.C:311
 ProofHelper.C:312
 ProofHelper.C:313
 ProofHelper.C:314
 ProofHelper.C:315
 ProofHelper.C:316
 ProofHelper.C:317
 ProofHelper.C:318
 ProofHelper.C:319
 ProofHelper.C:320
 ProofHelper.C:321
 ProofHelper.C:322
 ProofHelper.C:323
 ProofHelper.C:324
 ProofHelper.C:325
 ProofHelper.C:326
 ProofHelper.C:327
 ProofHelper.C:328
 ProofHelper.C:329
 ProofHelper.C:330
 ProofHelper.C:331
 ProofHelper.C:332
 ProofHelper.C:333
 ProofHelper.C:334
 ProofHelper.C:335
 ProofHelper.C:336
 ProofHelper.C:337
 ProofHelper.C:338
 ProofHelper.C:339
 ProofHelper.C:340
 ProofHelper.C:341
 ProofHelper.C:342
 ProofHelper.C:343
 ProofHelper.C:344
 ProofHelper.C:345
 ProofHelper.C:346
 ProofHelper.C:347
 ProofHelper.C:348
 ProofHelper.C:349
 ProofHelper.C:350
 ProofHelper.C:351
 ProofHelper.C:352
 ProofHelper.C:353
 ProofHelper.C:354
 ProofHelper.C:355
 ProofHelper.C:356
 ProofHelper.C:357
 ProofHelper.C:358
 ProofHelper.C:359
 ProofHelper.C:360
 ProofHelper.C:361
 ProofHelper.C:362
 ProofHelper.C:363
 ProofHelper.C:364
 ProofHelper.C:365
 ProofHelper.C:366
 ProofHelper.C:367
 ProofHelper.C:368
 ProofHelper.C:369
 ProofHelper.C:370
 ProofHelper.C:371
 ProofHelper.C:372
 ProofHelper.C:373
 ProofHelper.C:374
 ProofHelper.C:375
 ProofHelper.C:376
 ProofHelper.C:377
 ProofHelper.C:378
 ProofHelper.C:379
 ProofHelper.C:380
 ProofHelper.C:381
 ProofHelper.C:382
 ProofHelper.C:383
 ProofHelper.C:384
 ProofHelper.C:385
 ProofHelper.C:386
 ProofHelper.C:387
 ProofHelper.C:388
 ProofHelper.C:389
 ProofHelper.C:390
 ProofHelper.C:391
 ProofHelper.C:392
 ProofHelper.C:393
 ProofHelper.C:394
 ProofHelper.C:395
 ProofHelper.C:396
 ProofHelper.C:397
 ProofHelper.C:398
 ProofHelper.C:399
 ProofHelper.C:400
 ProofHelper.C:401
 ProofHelper.C:402
 ProofHelper.C:403
 ProofHelper.C:404
 ProofHelper.C:405
 ProofHelper.C:406
 ProofHelper.C:407
 ProofHelper.C:408
 ProofHelper.C:409
 ProofHelper.C:410
 ProofHelper.C:411
 ProofHelper.C:412
 ProofHelper.C:413
 ProofHelper.C:414
 ProofHelper.C:415
 ProofHelper.C:416
 ProofHelper.C:417
 ProofHelper.C:418
 ProofHelper.C:419
 ProofHelper.C:420
 ProofHelper.C:421
 ProofHelper.C:422
 ProofHelper.C:423
 ProofHelper.C:424
 ProofHelper.C:425
 ProofHelper.C:426
 ProofHelper.C:427
 ProofHelper.C:428
 ProofHelper.C:429
 ProofHelper.C:430
 ProofHelper.C:431
 ProofHelper.C:432
 ProofHelper.C:433
 ProofHelper.C:434
 ProofHelper.C:435
 ProofHelper.C:436
 ProofHelper.C:437
 ProofHelper.C:438
 ProofHelper.C:439
 ProofHelper.C:440
 ProofHelper.C:441
 ProofHelper.C:442
 ProofHelper.C:443
 ProofHelper.C:444
 ProofHelper.C:445
 ProofHelper.C:446
 ProofHelper.C:447
 ProofHelper.C:448
 ProofHelper.C:449
 ProofHelper.C:450
 ProofHelper.C:451
 ProofHelper.C:452
 ProofHelper.C:453
 ProofHelper.C:454
 ProofHelper.C:455
 ProofHelper.C:456
 ProofHelper.C:457
 ProofHelper.C:458
 ProofHelper.C:459
 ProofHelper.C:460
 ProofHelper.C:461
 ProofHelper.C:462
 ProofHelper.C:463
 ProofHelper.C:464
 ProofHelper.C:465
 ProofHelper.C:466
 ProofHelper.C:467
 ProofHelper.C:468
 ProofHelper.C:469
 ProofHelper.C:470
 ProofHelper.C:471
 ProofHelper.C:472
 ProofHelper.C:473
 ProofHelper.C:474
 ProofHelper.C:475
 ProofHelper.C:476
 ProofHelper.C:477
 ProofHelper.C:478
 ProofHelper.C:479
 ProofHelper.C:480
 ProofHelper.C:481
 ProofHelper.C:482
 ProofHelper.C:483
 ProofHelper.C:484
 ProofHelper.C:485
 ProofHelper.C:486
 ProofHelper.C:487
 ProofHelper.C:488
 ProofHelper.C:489
 ProofHelper.C:490
 ProofHelper.C:491
 ProofHelper.C:492
 ProofHelper.C:493
 ProofHelper.C:494
 ProofHelper.C:495
 ProofHelper.C:496
 ProofHelper.C:497
 ProofHelper.C:498
 ProofHelper.C:499
 ProofHelper.C:500
 ProofHelper.C:501
 ProofHelper.C:502
 ProofHelper.C:503
 ProofHelper.C:504
 ProofHelper.C:505
 ProofHelper.C:506
 ProofHelper.C:507
 ProofHelper.C:508
 ProofHelper.C:509
 ProofHelper.C:510
 ProofHelper.C:511
 ProofHelper.C:512
 ProofHelper.C:513
 ProofHelper.C:514
 ProofHelper.C:515
 ProofHelper.C:516
 ProofHelper.C:517
 ProofHelper.C:518
 ProofHelper.C:519
 ProofHelper.C:520
 ProofHelper.C:521
 ProofHelper.C:522
 ProofHelper.C:523
 ProofHelper.C:524
 ProofHelper.C:525
 ProofHelper.C:526
 ProofHelper.C:527
 ProofHelper.C:528
 ProofHelper.C:529
 ProofHelper.C:530
 ProofHelper.C:531
 ProofHelper.C:532
 ProofHelper.C:533
 ProofHelper.C:534
 ProofHelper.C:535
 ProofHelper.C:536
 ProofHelper.C:537
 ProofHelper.C:538
 ProofHelper.C:539
 ProofHelper.C:540
 ProofHelper.C:541
 ProofHelper.C:542
 ProofHelper.C:543
 ProofHelper.C:544
 ProofHelper.C:545
 ProofHelper.C:546
 ProofHelper.C:547
 ProofHelper.C:548
 ProofHelper.C:549
 ProofHelper.C:550
 ProofHelper.C:551
 ProofHelper.C:552
 ProofHelper.C:553
 ProofHelper.C:554
 ProofHelper.C:555
 ProofHelper.C:556
 ProofHelper.C:557
 ProofHelper.C:558
 ProofHelper.C:559
 ProofHelper.C:560
 ProofHelper.C:561
 ProofHelper.C:562
 ProofHelper.C:563
 ProofHelper.C:564
 ProofHelper.C:565
 ProofHelper.C:566
 ProofHelper.C:567
 ProofHelper.C:568
 ProofHelper.C:569
 ProofHelper.C:570
 ProofHelper.C:571
 ProofHelper.C:572
 ProofHelper.C:573
 ProofHelper.C:574
 ProofHelper.C:575
 ProofHelper.C:576
 ProofHelper.C:577
 ProofHelper.C:578
 ProofHelper.C:579
 ProofHelper.C:580
 ProofHelper.C:581
 ProofHelper.C:582
 ProofHelper.C:583
 ProofHelper.C:584
 ProofHelper.C:585
 ProofHelper.C:586
 ProofHelper.C:587
 ProofHelper.C:588
 ProofHelper.C:589
 ProofHelper.C:590
 ProofHelper.C:591
 ProofHelper.C:592
 ProofHelper.C:593
 ProofHelper.C:594
 ProofHelper.C:595
 ProofHelper.C:596
 ProofHelper.C:597
 ProofHelper.C:598
 ProofHelper.C:599
 ProofHelper.C:600
 ProofHelper.C:601
 ProofHelper.C:602
 ProofHelper.C:603
 ProofHelper.C:604
 ProofHelper.C:605
 ProofHelper.C:606
 ProofHelper.C:607
 ProofHelper.C:608
 ProofHelper.C:609
 ProofHelper.C:610
 ProofHelper.C:611
 ProofHelper.C:612
 ProofHelper.C:613
 ProofHelper.C:614
 ProofHelper.C:615
 ProofHelper.C:616
 ProofHelper.C:617
 ProofHelper.C:618
 ProofHelper.C:619
 ProofHelper.C:620
 ProofHelper.C:621
 ProofHelper.C:622
 ProofHelper.C:623
 ProofHelper.C:624
 ProofHelper.C:625
 ProofHelper.C:626
 ProofHelper.C:627
 ProofHelper.C:628
 ProofHelper.C:629
 ProofHelper.C:630
 ProofHelper.C:631
 ProofHelper.C:632
 ProofHelper.C:633
 ProofHelper.C:634
 ProofHelper.C:635
 ProofHelper.C:636
 ProofHelper.C:637
 ProofHelper.C:638
 ProofHelper.C:639
 ProofHelper.C:640
 ProofHelper.C:641
 ProofHelper.C:642
 ProofHelper.C:643
 ProofHelper.C:644
 ProofHelper.C:645
 ProofHelper.C:646
 ProofHelper.C:647
 ProofHelper.C:648
 ProofHelper.C:649
 ProofHelper.C:650
 ProofHelper.C:651
 ProofHelper.C:652
 ProofHelper.C:653
 ProofHelper.C:654
 ProofHelper.C:655
 ProofHelper.C:656
 ProofHelper.C:657
 ProofHelper.C:658
 ProofHelper.C:659
 ProofHelper.C:660
 ProofHelper.C:661
 ProofHelper.C:662
 ProofHelper.C:663
 ProofHelper.C:664
 ProofHelper.C:665
 ProofHelper.C:666
 ProofHelper.C:667
 ProofHelper.C:668
 ProofHelper.C:669
 ProofHelper.C:670
 ProofHelper.C:671
 ProofHelper.C:672
 ProofHelper.C:673
 ProofHelper.C:674
 ProofHelper.C:675
 ProofHelper.C:676
 ProofHelper.C:677
 ProofHelper.C:678
 ProofHelper.C:679
 ProofHelper.C:680
 ProofHelper.C:681
 ProofHelper.C:682
 ProofHelper.C:683
 ProofHelper.C:684
 ProofHelper.C:685
 ProofHelper.C:686
 ProofHelper.C:687
 ProofHelper.C:688
 ProofHelper.C:689
 ProofHelper.C:690
 ProofHelper.C:691
 ProofHelper.C:692
 ProofHelper.C:693
 ProofHelper.C:694
 ProofHelper.C:695
 ProofHelper.C:696
 ProofHelper.C:697
 ProofHelper.C:698
 ProofHelper.C:699
 ProofHelper.C:700
 ProofHelper.C:701
 ProofHelper.C:702
 ProofHelper.C:703
 ProofHelper.C:704
 ProofHelper.C:705
 ProofHelper.C:706
 ProofHelper.C:707
 ProofHelper.C:708
 ProofHelper.C:709
 ProofHelper.C:710
 ProofHelper.C:711
 ProofHelper.C:712
 ProofHelper.C:713
 ProofHelper.C:714
 ProofHelper.C:715
 ProofHelper.C:716
 ProofHelper.C:717
 ProofHelper.C:718
 ProofHelper.C:719
 ProofHelper.C:720
 ProofHelper.C:721
 ProofHelper.C:722
 ProofHelper.C:723
 ProofHelper.C:724
 ProofHelper.C:725
 ProofHelper.C:726
 ProofHelper.C:727
 ProofHelper.C:728
 ProofHelper.C:729
 ProofHelper.C:730
 ProofHelper.C:731
 ProofHelper.C:732
 ProofHelper.C:733
 ProofHelper.C:734
 ProofHelper.C:735
 ProofHelper.C:736
 ProofHelper.C:737
 ProofHelper.C:738
 ProofHelper.C:739
 ProofHelper.C:740
 ProofHelper.C:741
 ProofHelper.C:742
 ProofHelper.C:743
 ProofHelper.C:744
 ProofHelper.C:745
 ProofHelper.C:746
 ProofHelper.C:747
 ProofHelper.C:748
 ProofHelper.C:749
 ProofHelper.C:750
 ProofHelper.C:751
 ProofHelper.C:752
 ProofHelper.C:753
 ProofHelper.C:754
 ProofHelper.C:755
 ProofHelper.C:756
 ProofHelper.C:757
 ProofHelper.C:758
 ProofHelper.C:759
 ProofHelper.C:760
 ProofHelper.C:761
 ProofHelper.C:762
 ProofHelper.C:763
 ProofHelper.C:764
 ProofHelper.C:765
 ProofHelper.C:766
 ProofHelper.C:767
 ProofHelper.C:768
 ProofHelper.C:769
 ProofHelper.C:770
 ProofHelper.C:771
 ProofHelper.C:772
 ProofHelper.C:773
 ProofHelper.C:774
 ProofHelper.C:775
 ProofHelper.C:776
 ProofHelper.C:777
 ProofHelper.C:778
 ProofHelper.C:779
 ProofHelper.C:780
 ProofHelper.C:781
 ProofHelper.C:782
 ProofHelper.C:783
 ProofHelper.C:784
 ProofHelper.C:785
 ProofHelper.C:786
 ProofHelper.C:787
 ProofHelper.C:788
 ProofHelper.C:789
 ProofHelper.C:790
 ProofHelper.C:791
 ProofHelper.C:792
 ProofHelper.C:793
 ProofHelper.C:794
 ProofHelper.C:795
 ProofHelper.C:796
 ProofHelper.C:797
 ProofHelper.C:798
 ProofHelper.C:799
 ProofHelper.C:800
 ProofHelper.C:801
 ProofHelper.C:802
 ProofHelper.C:803
 ProofHelper.C:804
 ProofHelper.C:805
 ProofHelper.C:806
 ProofHelper.C:807
 ProofHelper.C:808
 ProofHelper.C:809
 ProofHelper.C:810
 ProofHelper.C:811
 ProofHelper.C:812
 ProofHelper.C:813
 ProofHelper.C:814
 ProofHelper.C:815
 ProofHelper.C:816
 ProofHelper.C:817
 ProofHelper.C:818
 ProofHelper.C:819
 ProofHelper.C:820
 ProofHelper.C:821
 ProofHelper.C:822
 ProofHelper.C:823
 ProofHelper.C:824
 ProofHelper.C:825
 ProofHelper.C:826
 ProofHelper.C:827
 ProofHelper.C:828
 ProofHelper.C:829
 ProofHelper.C:830
 ProofHelper.C:831
 ProofHelper.C:832
 ProofHelper.C:833
 ProofHelper.C:834
 ProofHelper.C:835
 ProofHelper.C:836
 ProofHelper.C:837
 ProofHelper.C:838
 ProofHelper.C:839
 ProofHelper.C:840
 ProofHelper.C:841
 ProofHelper.C:842
 ProofHelper.C:843
 ProofHelper.C:844
 ProofHelper.C:845
 ProofHelper.C:846
 ProofHelper.C:847