Various fixes
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 19 Oct 2012 14:31:39 +0000 (14:31 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 19 Oct 2012 14:31:39 +0000 (14:31 +0000)
13 files changed:
PWGLF/FORWARD/trains/AAFPluginHelper.C
PWGLF/FORWARD/trains/Helper.C
PWGLF/FORWARD/trains/LiteHelper.C
PWGLF/FORWARD/trains/LocalHelper.C
PWGLF/FORWARD/trains/MakeAODTrain.C
PWGLF/FORWARD/trains/MakedNdetaTrain.C
PWGLF/FORWARD/trains/Option.C
PWGLF/FORWARD/trains/ParUtilities.C
PWGLF/FORWARD/trains/PluginHelper.C
PWGLF/FORWARD/trains/ProofHelper.C
PWGLF/FORWARD/trains/RunTrain.C
PWGLF/FORWARD/trains/TrainSetup.C
PWGLF/FORWARD/trains/trainMain.cxx

index b55b7b7..07fad19 100644 (file)
@@ -83,6 +83,9 @@ struct AAFPluginHelper : public PluginHelper
   {
     fOptions.Add("workers", "N[x]", "Number of workers to use", "0");
     fOptions.Add("dsname",  "NAME", "Make output dataset", "");
+    fOptions.Add("wrapper", "CMD", "Wrapper command", "");
+    fOptions.Add("clear",   "Clear all packages");
+    fOptions.Add("reset",   "soft|hard", "Reset cluster", "hard");
 
   }
   /** 
@@ -96,10 +99,13 @@ struct AAFPluginHelper : public PluginHelper
    */
   virtual Bool_t PreSetup()
   {
+    // --- Handle software options -----------------------------------
     TString root = fOptions.Get("root");
     fHandler->SetRootVersionForProof(Form("VO_ALICE@ROOT::%s", root.Data()));
     fHandler->SetProofCluster(fUrl.GetHost());
     fHandler->SetProofDataSet(fUrl.GetFile());
+
+    // --- Handle worker options -------------------------------------
     if (fOptions.Has("workers")) {
       TString nwork = fOptions.Get("workers");
       if (nwork.EndsWith("x")) 
@@ -107,6 +113,32 @@ struct AAFPluginHelper : public PluginHelper
       else 
        fHandler->SetNproofWorkers(nwork.Atoi());
     }
+    
+    // --- 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);
+    }
+    
+    // --- Check if we need to clear packages ------------------------
+    fHandler->SetClearPackages(fOptions.Has("clear"));
+
+    // --- 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("AAFPluginHelper::PreSetup", "Will do a %s reset of %s", 
+          hard ? "hard" : "soft", fUrl.GetHost());
+      fHandler->SetProofReset(hard ? 2 : 1);
+    }
+    
     return PluginHelper::PreSetup();
   }
   /** 
index b46b7a2..c46471e 100644 (file)
@@ -306,7 +306,8 @@ struct Helper
       gSystem->Load("libProof");
       gSystem->Load("libProofPlayer");
     }
-    gROOT->LoadMacro(Form("%s.C+",cl.Data()));
+    // Always recompile and with debug symbols 
+    gROOT->LoadMacro(Form("%s.C++g",cl.Data()));
     Long_t ptr = gROOT->ProcessLine(Form("new %s(\"%s\", %d);", 
                                         cl.Data(), url.GetUrl(), verbose));
     if (verbose > 3) gSystem->RedirectOutput(0);
@@ -408,9 +409,17 @@ protected:
     if (!path.BeginsWith("/")) path.Prepend("../");
     if (gSystem->AccessPathName(path.Data())) { 
       // File not accessible
-      Warning("Helper::LoadSource", "File %s not accessible", path.Data());
+      Warning("Helper::AuxFile", "File %s not accessible", path.Data());
       return false;
     }
+    TString base(gSystem->BaseName(path.Data()));
+    if (gSystem->AccessPathName(base.Data()) == 0) { 
+      // File or link exists - remove it 
+      if (gSystem->Unlink(base) != 0) { 
+       Error("Helper::AuxFile", "Failed to remove old %s", base.Data());
+       return false;
+      }
+    }
     gSystem->Exec(Form("ln -s %s .", path.Data()));
     return true;
   }
index 163d774..0814da8 100644 (file)
@@ -87,6 +87,32 @@ struct LiteHelper : public ProofHelper
     fOptions.Remove("dsname");
     fOptions.Remove("storage");
   }
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
+  LiteHelper(const LiteHelper& o) 
+    : ProofHelper(o), fChain(o.fChain)
+  {}
+  /** 
+   * Assignment operator 
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this 
+   */
+  LiteHelper& operator=(const LiteHelper& o) 
+  {
+    if (&o == this) return *this;
+    ProofHelper::operator=(o);
+    fChain = o.fChain;
+    return *this;
+  }
+  /** 
+   * Destructor 
+   */
+  virtual ~LiteHelper() {}
   /** 
    * Set-up done before task set-ups 
    * 
index d5f8017..c5fa245 100644 (file)
@@ -77,6 +77,28 @@ struct LocalHelper : public Helper
     fOptions.Add("recursive","Scan recursive");
     fOptions.Add("pattern",  "GLOB", "File name pattern", "*.root");
   }
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
+  LocalHelper(const LocalHelper& o) 
+    : Helper(o), fChain(o.fChain)
+  {}
+  /** 
+   * Assignment operator 
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this 
+   */
+  LocalHelper& operator=(const LocalHelper& o) 
+  {
+    if (&o == this) return *this;
+    Helper::operator=(o);
+    fChain = o.fChain;
+    return *this;
+  }
   /** 
    * Destructor 
    */
index b3eb10c..8a77060 100644 (file)
@@ -169,7 +169,8 @@ protected:
     opts.Add("trig", "TRIGGER", "Trigger type", "");
     opts.Add("vzMin", "CENTIMETER", "Lower bound on Ip Z", "-10");
     opts.Add("vzMax", "CENTIMETER", "Upper bound on Ip Z", "+10");
-    opts.Add("scheme", "FLAGS", "Normalization scheme", "EVENT BACKGROUND");
+    opts.Add("scheme", "FLAGS", "Normalization scheme", 
+            "TRIGGER EVENT BACKGROUND");
     opts.Add("cut-edges", "Cut edges of acceptance");
     opts.Add("trigEff", "EFFICIENCY", "Trigger efficiency", "1");
     opts.Add("trigEff0", "EFFICIENCY", "0-bin trigger efficiency", "1");
@@ -177,8 +178,7 @@ protected:
     if (out.IsNull()) out = fEscapedName;
     opts.Set("url", out);
     opts.Set("type", "AOD");
-    // opts.Show(std::cout);
-
+  
     SaveSetupROOT("dNdeta", cls, name, opts);
     if (asShellScript) 
       SaveSetupShell("dndeta", cls, name, opts);
index 90bc8d6..cb864aa 100644 (file)
@@ -94,6 +94,61 @@ protected:
   AliVEventHandler* CreateOutputHandler(UShort_t) { return 0; }
   //__________________________________________________________________
   const char* ClassName() const { return "MakedNdetaTrain"; }
+  //__________________________________________________________________
+  /** 
+   * Overloaded to create new draw.C 
+   * 
+   * @param asShellScript 
+   */
+  void SaveSetup(Bool_t asShellScript)
+  {
+    TrainSetup::SaveSetup(asShellScript);
+
+    std::ofstream o("draw.C");
+    if (!o) { 
+      Error("MakedNdetaTrain::SaveSetup", "Failed to open draw.C");
+      return;
+    }
+
+    o << "// Created by " << ClassName() << "\n"
+      << "// \n"
+      << "// Will draw dN/deta results from produced file\n"
+      << "// \n"
+      << "// Options can be specified as needed. To get help, pass the\n"
+      << "// string \"help\" for the title\n"
+      << "// \n"
+      << "void draw(const TString& title="",\n"
+      << "          UShort_t       rebin=5,\n"
+      << "          UShort_t       others=0x7,\n"
+      << "          UShort_t       flags=0xD87,\n"
+      << "          UShort_t       sNN=0,\n"
+      << "          UShort_t       sys=0,\n"
+      << "          UShort_t       trg=0,\n"
+      << "          Float_t        vzMin=999,"
+      << "          Float_t        vzMax=-999)\n"
+      << "{\n"
+      << "   gROOT->LoadMacro(\"$ALICE_ROOT/PWGLF/FORWARD/analysis2/"
+      << "DrawdNdeta.C++\");\n\n"
+      << "  if (title.EqualTo(\"help\",TString::kIgnoreCase)) {\n"
+      << "    DrawdNdeta(\"help\"); // Get the help\n"
+      << "    return;\n"
+      << "  }\n\n"
+      << "  DrawdNdeta(\"forward_dndeta.root\",\n"
+      << "             title,\n"
+      << "             rebin,\n"
+      << "             others,\n"
+      << "             flags,\n"
+      << "             sNN,\n"
+      << "             sys,\n"
+      << "             trg,\n"
+      << "             vzMin,\n"
+      << "             vzMax);\n"
+      << "}\n"
+      << "//\n"
+      << "// EOF\n"
+      << "//" << std::endl;
+    o.close();
+  }
 };
 //
 // EOF
index 7a384e5..089f087 100644 (file)
@@ -225,6 +225,20 @@ struct OptionList
       if (fNext) fNext->fPrev = fPrev;
       delete fThis;
     }
+    Link(const Link& o)
+      : fPrev(o.fPrev), 
+       fNext(o.fNext), 
+       fThis(o.fThis)
+    {
+    }
+    Link& operator=(const Link& o)
+    {
+      if (&o == this) return *this;
+      fPrev = o.fPrev;
+      fNext = o.fNext;
+      fThis = o.fThis;
+      return *this;
+    }  
   };
   /** 
    * Constructor 
index 1432462..2d6d57b 100644 (file)
@@ -34,7 +34,7 @@ struct ParUtilities
 {
   /** 
    * Find PAR file (either in current or parent directory or directly 
-   * in $ALICE_ROOT), and copy/link here
+   * in $ALICE_ROOT), and link it here
    * 
    * @param what PAR file name (sans .par)
    * 
@@ -48,24 +48,39 @@ struct ParUtilities
     if (!parFile.EndsWith(".par")) parFile.Append(".par");
     if (gSystem->AccessPathName(parFile.Data())) { 
       // If not found
-      if (gSystem->AccessPathName(Form("../%s.par", parFile.Data()))) { 
+      TString src;
+      if (gSystem->AccessPathName(Form("../%s.par", parFile.Data())) == 0) 
+       src.Form("../%s", parFile.Data());
+      else {
        // If not found 
        TString aliParFile = 
          gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
-       if (gSystem->AccessPathName(aliParFile.Data())) { 
+       if (gSystem->AccessPathName(aliParFile.Data()) == 0) 
+         src = aliParFile;
+      }
+      if (src.IsNull()) {
          Error("ParUtilities::Find", 
                "PAR file %s not found in current or parent "
                "directory nor in $(ALICE_ROOT)", parFile.Data());
          return false;
-       }
-       // Copy to current directory 
-       TFile::Cp(aliParFile, parFile);
       }
-      else 
-       gSystem->Exec(Form("ln -s %s .", parFile.Data()));
+      // Copy to current directory 
+      // TFile::Copy(aliParFile, parFile);
+      if (gSystem->Exec(Form("ln -s %s %s", src.Data(), parFile.Data())) != 0){
+       Error("ParUtilities::Find", "Failed to symlink %s to %s", 
+             src.Data(), parFile.Data());
+       return false;
+      }
     }
     return true;
   }
+  /** 
+   * Unpack and load a PAR file previously found with Find.
+   * 
+   * @param name PAR file name 
+   * @deprecated Use Find  and Build instead
+   * @return true on success
+   */
   static Bool_t Load(const TString& name) 
   {
     if (name.IsNull()) return true;
index 98707b3..28e70aa 100644 (file)
@@ -80,6 +80,32 @@ struct PluginHelper : public Helper
     fOptions.Add("storage", "URL", "Location for external storage", "");    
     fOptions.Add("plugin", "Use AliEn handler");
   }
+  /** 
+   * Copy constructor 
+   * 
+   * @param o Object to copy from 
+   */
+  PluginHelper(const PluginHelper& o) 
+    : Helper(o), fHandler(o.fHandler), fUsePars(o.fUsePars)
+  {}
+  /** 
+   * Assignment operator 
+   * 
+   * @param o Object to assign from 
+   * 
+   * @return Reference to this 
+   */
+  PluginHelper& operator=(const PluginHelper& o) 
+  {
+    if (&o == this) return *this;
+    Helper::operator=(o);
+    fHandler = o.fHandler;
+    fUsePars = o.fUsePars;
+    return *this;
+  }
+  /** 
+   * Destructor 
+   */
   virtual ~PluginHelper() {}
   /** 
    * Load a library/PAR/script 
index b0d55f7..f1b1aa4 100644 (file)
@@ -95,6 +95,9 @@ struct ProofHelper : public Helper
    */
   ProofHelper(const TUrl& url, Int_t verbose)
     : Helper(url, verbose), 
+      fExtraLibs(""),
+      fExtraPars(""),
+      fExtraSrcs(""),
       fUsePars(false), 
       fBasePars(false)
   {
@@ -103,10 +106,15 @@ struct ProofHelper : public Helper
     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");
     if (!fUrl.GetUser() || fUrl.GetUser()[0] == '\0') 
       fUrl.SetUser(gSystem->GetUserInfo()->fUser);
   }
+  /** 
+   * Destructor 
+   */
   virtual ~ProofHelper() {}
   /** 
    * Load a library/PAR/script 
@@ -220,6 +228,26 @@ struct ProofHelper : public Helper
     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'", 
@@ -319,15 +347,15 @@ struct ProofHelper : public Helper
       << std::endl;
     s.close();
 
-    Int_t ret = gSystem->Exec(Form("tar -czf %s.par %s",
-                                  parName.Data(), parName.Data()));
+    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 files");
+      Error("ProofHelper::CreateAliROOTPar", "Failed to pack up PAR file %s",
+           parFile.Data());
       return false;
     }
 
-    ret = gProof->UploadPackage(Form("./%s.par", parName.Data()),
-                               TProof::kRemoveOld);
+    ret = gProof->UploadPackage(parFile.Data(),TProof::kRemoveOld);
     if (ret != 0) { 
       Error("ProofHelper::CreateAliROOTPar", 
            "Failed to upload the AliROOT PAR file");
@@ -357,23 +385,52 @@ struct ProofHelper : public Helper
     // --- 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");
+    // --- 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));
 
     // --- Connect to the cluster ------------------------------------
-    TUrl connect(fUrl);
-    connect.SetAnchor("");
-    connect.SetFile("");
-    connect.SetOptions("");
     TString opts;
     if (fOptions.Has("workers")) 
       opts.Append(Form("workers=%s", fOptions.Get("workers").Data()));
@@ -393,8 +450,28 @@ struct ProofHelper : public Helper
            connect.GetUrl());
       return false;
     }
-    Info("ProofHelper::PreSetup", "Using progress dialog=%d",   
-        gProof->TestBit(TProof::kUseProgressDialog));
+    
+    // --- 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;
   }
   /** 
@@ -440,7 +517,8 @@ struct ProofHelper : public Helper
     TObject*   obj  = 0;
     TIter      next(pars);
     while ((obj = next())) { 
-      Int_t ret = gProof->EnablePackage(obj->GetName());
+      // 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());
@@ -484,7 +562,7 @@ struct ProofHelper : public Helper
     //   dsName.Append(Form("#%s", fUrl.GetAnchor()));
     Long64_t ret = mgr->StartAnalysis(fUrl.GetProtocol(), dsName, nEvents);
     
-    if (fVerbose > 2
+    if (fVerbose > 10
       TProof::Mgr(fUrl.GetUrl())->GetSessionLogs()->Save("*","proof.log");
     return ret;
   }
index 6e394f1..b2f43f9 100644 (file)
@@ -47,7 +47,8 @@ BuildScript(const char* name, Bool_t verbose, Bool_t force, Bool_t debug)
  * @ingroup pwglf_forward_trains
  */
 Bool_t
-BuildHelpers(Bool_t verbose, Bool_t force, Bool_t debug)
+BuildHelpers(Bool_t verbose, Bool_t force, Bool_t debug,
+            Bool_t all=false)
 {
   gSystem->AddIncludePath("-I$ALICE_ROOT/include");
   gSystem->Load("libANALYSIS");
@@ -58,14 +59,14 @@ BuildHelpers(Bool_t verbose, Bool_t force, Bool_t debug)
                            "OutputUtilities", 
                            "Option",
                            "Helper", 
-                           "LocalHelper", 
+                           "TrainSetup",
+                           (all ? "LocalHelper" : 0), 
                            "ProofHelper", 
-                           "LiteHelper",
+                           "LiteHelper", 
                            "AAFHelper", 
-                           "PluginHelper",
+                           "PluginHelper", 
                            "AAFPluginHelper", 
-                           "GridHelper",
-                           "TrainSetup",
+                           "GridHelper", 
                            0 };
   const char** ptr = scripts;
   while ((*ptr)) {
@@ -106,7 +107,8 @@ Bool_t RunTrain(const TString& name, const TString& cls,
 {
   // Check for help 
   if (name.IsNull() || name.EqualTo("help", TString::kIgnoreCase) || 
-      cls.IsNull()  || cls.EqualTo("help", TString::kIgnoreCase)) {
+      cls.IsNull()  || cls.EqualTo("help", TString::kIgnoreCase) || 
+      uri.IsNull()) {
     PlainUsage();
     return true;
   }
@@ -120,7 +122,7 @@ Bool_t RunTrain(const TString& name, const TString& cls,
   opts.Append("url="); 
   opts.Append(uri);
   TObjArray* optList = opts.Tokenize(",");
-  return TrainSetup::Main(name, cls, optList);
+  return TrainSetup::Main(name, cls, optList, false);
 }
 /*
  * EOF
index aee24c3..3dce85c 100644 (file)
@@ -32,6 +32,7 @@
 # include <AliAODInputHandler.h>
 # include <AliAODHandler.h>
 # include <AliMCEventHandler.h>
+# include <ctime>
 #else 
 struct Helper;
 struct OptionList;
@@ -62,6 +63,7 @@ struct TrainSetup
   TrainSetup(const TString& name)
     : fName(name), 
       fEscapedName(name),
+      fOptions(),
       fHelper(0)
   {
     fOptions.Add("help", "Show help");
@@ -75,6 +77,22 @@ struct TrainSetup
     fOptions.Add("type", "ESD|AOD|USER", "Input data stype", "");
     fEscapedName = EscapeName(fName, "");
   }
+  TrainSetup(const TrainSetup& o) 
+    : fName(o.fName), 
+      fEscapedName(o.fEscapedName), 
+      fOptions(o.fOptions), 
+      fHelper(o.fHelper)
+  {}
+  TrainSetup& operator=(const TrainSetup& o) 
+  {
+    if (&o == this) return *this;
+    fName        = o.fName;
+    fEscapedName = o.fEscapedName;
+    fOptions     = o.fOptions;
+    fHelper      = o.fHelper;
+    return *this;
+  }
+  
   /** 
    * Destructor
    */
@@ -103,6 +121,7 @@ struct TrainSetup
       return false;
     }
 
+    // --- Check the type, if possible -------------------------------
     UShort_t type    = fHelper->InputType();
     if (fOptions.Has("type")) { 
       const TString& it = fOptions.Get("type");
@@ -112,6 +131,12 @@ struct TrainSetup
        type = Helper::kUser;
     }
 
+    // --- Rewrite the escpaed name ----------------------------------
+    if (fOptions.Has("date")) { 
+      TString date = fOptions.Get("date");
+      fEscapedName = EscapeName(fName, date);
+    }
+    
     // --- Get current directory and set-up sub-directory ------------
     TString cwd = gSystem->WorkingDirectory();
     if (!SetupWorkingDirectory()) return false;
@@ -494,15 +519,39 @@ protected:
     char  c[] = { ' ', '/', '@', 0 };
     char* p   = c;
     while (*p) { 
-      escaped.ReplaceAll(Form("%c", *p), "_");
+      char tmp[] = { *p, '\0' };
+      escaped.ReplaceAll(tmp, "_");
       p++;
     }
     if (!datimeStr.IsNull()) {
       TDatime datime;
       if (datimeStr.EqualTo("now", TString::kIgnoreCase)) 
        datime.Set();
-      else 
-       datime.Set(datimeStr.Data());
+      else {
+       // Try various formats 
+       struct tm t;
+       const char* formats[] = { "%Ec", // Locale 
+                                 "%c", // Locale 
+                                 "%Ex EX", // Locale 
+                                 "%x %X", // Locale 
+                                 "%F %R", // ISO standard, no seconds 
+                                 0 };
+       const char** f = formats;
+       Bool_t found = false;
+       while (*f && !found) { 
+         // Reset needed fields 
+         t.tm_year  = 0;
+         t.tm_mon   = 0;
+         t.tm_mday  = 0;
+         t.tm_hour  = 0;
+         t.tm_min   = 0;
+         // Stop processing on first match 
+         if (strptime(datimeStr.Data(), *f, &t) != 0) found = true;
+         f++;
+       }
+       if (found) 
+         datime.Set(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, 0); 
+      }
       if (datime.GetYear() <= 1995 ||
          datime.GetMonth() == 0 || 
          datime.GetDay() == 0) return escaped;
@@ -567,9 +616,11 @@ protected:
    */
   virtual void SaveSetup(Bool_t asShellScript)
   {
+    OptionList tmp(fOptions);
+    if (tmp.Find("overwrite")) tmp.Set("overwrite");
     if (asShellScript) 
-      SaveSetupShell("rerun", ClassName(), fName, fOptions);
-    SaveSetupROOT("ReRun", ClassName(), fName, fOptions);
+      SaveSetupShell("rerun", ClassName(), fName, tmp);
+    SaveSetupROOT("ReRun", ClassName(), fName, tmp);
   }
   /** 
    * Save a setup as a shell script 
@@ -626,6 +677,19 @@ protected:
       << "  TString opts(";
     tmp.Store(o, "\"", ",\"\n               ", false);
     o << ");\n\n"
+      << "  TString path(";
+    TString     path(gROOT->GetMacroPath());
+    TObjArray*  elements = path.Tokenize(":");
+    TObjString* element = 0;
+    TIter       next(elements);
+    while ((element = static_cast<TObjString*>(next()))) {
+      if (element->String().IsNull()) continue;
+      o << "\n               \"" << element->GetName() << ":\"";
+    }
+    elements->Delete();
+    o << ");\n"
+      << "  path.Append(\"$ALICE_ROOT/PWGLF/FORWARD/trains\");\n"
+      << "  gROOT->SetMacroPath(path);\n\n"
       << "  gROOT->LoadMacro(\"RunTrain.C\");\n\n"
       << "  return RunTrain(name, cls, uri, opts);\n"
       << "}\n" 
index 3c06f95..9b2f62f 100644 (file)
@@ -48,6 +48,20 @@ struct Deferred : public TTimer
   {
     Start(1000, true);
   }
+  Deferred(const Deferred& o)
+    : TTimer(), 
+      fName(o.fName),
+      fClass(o.fClass),
+      fOptions(o.fOptions)
+  {}
+  Deferred& operator=(const Deferred& o) 
+  { 
+    if (&o == this) return *this;
+    fName    = o.fName;
+    fClass   = o.fClass;
+    fOptions = o.fOptions;
+    return *this; 
+  }
   Bool_t Notify()
   {
     // gSystem->RemoveTimer(this);