]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Various fixes
authorcholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 17 Sep 2013 09:17:02 +0000 (09:17 +0000)
committercholm <cholm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 17 Sep 2013 09:17:02 +0000 (09:17 +0000)
PWGLF/FORWARD/trains/GridDownload.C
PWGLF/FORWARD/trains/GridHelper.C
PWGLF/FORWARD/trains/GridTerminate.C
PWGLF/FORWARD/trains/GridWatch.C
PWGLF/FORWARD/trains/TrainSetup.C

index 971775cc3d840383dbd36676f56576f3530f0d5f..ce2845e08f1c631923e0faa34a25f5ec16f49cbd 100644 (file)
@@ -29,22 +29,27 @@ class TString;
  * 
  * @return true on success 
  */
-Bool_t GetOne(const TString& base, const TString& dir)
+Bool_t GetOne(const TString& base, const TString& dir, Bool_t unpack)
 {
   TString src(gSystem->ConcatFileName(base,dir));
   src = gSystem->ConcatFileName(src,"root_archive.zip");
+  TString name;
+  name.Form("root_archive_%s",dir.Data());
   TString dest;
-  dest.Form("root_archive_%s.zip",dir.Data());
+  dest.Form("%s.zip",name.Data());
 
   if (!TFile::Cp(src, dest)) {
     Error("GetOne","Failed to download %s -> %s",
           src.Data(), dest.Data());
     return false;
   }
+  if (!unpack) return true;
+  gSystem->Exec(Form("mkdir -p %s && (cd %s && unzip ../%s)", 
+                    name.Data(), name.Data(), dest.Data()));
   return true;
 }
 
-void GridDownload(const TString& base, const TString& runs)
+void GridDownload(const TString& base, const TString& runs, Bool_t unpack)
 {
   gEnv->SetValue("XSec.GSI.DelegProxy", "2");
   if (!TGrid::Connect("alien://")) {
@@ -56,7 +61,7 @@ void GridDownload(const TString& base, const TString& runs)
   TObjString* run      = 0;
   TIter       next(runArray);
   while ((run = static_cast<TObjString*>(next()))) {
-    GetOne(base, run->String());
+    GetOne(base, run->String(), unpack);
   }
 }
 // EOF
index baaf8f66f305755cb5f48779c93700c23ddf450a..ee66e3201b3406a1730acd4f08f606606cd21e07 100644 (file)
@@ -654,13 +654,13 @@ struct GridHelper : public PluginHelper
       return;
     }
     d << "// Generated by GridHelper\n"
-      << "void Download()\n"
+      << "void Download(Bool_t unpack=true)\n"
       << "{\n"
       << "  TString base = \"" << fUrl.GetProtocol() << "://" 
       << OutputPath() << "\";\n"
       << "  TString runs = \"" << runs << "\";\n\n"
       << "  gROOT->LoadMacro(\"" << macDir << "/GridDownload.C\");\n\n"
-      << "  GridDownload(base, runs);\n"
+      << "  GridDownload(base, runs, unpack);\n"
       << "}\n"
       << "// EOF\n"
       << std::endl;
index 44fcb8a2e7ae4eaa5c55ba75d946bb09f17dee23..f82c8c38e57006c651b8fef16bd02bd780b6ed58 100644 (file)
@@ -136,6 +136,14 @@ Bool_t GridTerminate(const TString& name,
     }
   }
 
+  // Connect to the grid
+  gEnv->SetValue("XSec.GSI.DelegProxy", "2");
+  // TGrid::Connect("alien://");
+  // if (!gGrid) {
+  //   Error("GridTerminate", "Failed to connect to AliEn");
+  //   return false;
+  // }
+
   // Load the analysis manager from file
   TString base(name);
   base.Append(".root");
@@ -148,7 +156,6 @@ Bool_t GridTerminate(const TString& name,
     }
     base = sub;
   }
-  gEnv->SetValue("XSec.GSI.DelegProxy", "2");
   AliAnalysisManager* mgr= AliAnalysisAlien::LoadAnalysisManager(base);
   if (!mgr) {
     Error("GridTerminate", "Failed to load manager from %s",base.Data());
index a407de33ec2ba1ea4e147627a21670a19ce89987..f32eb85dbcb5d89893042518f1e98aa8715000ca 100644 (file)
@@ -34,9 +34,9 @@ class TString;
  * @return Formatted string
  * @ingroup pwglf_forward_trains_helper
  */
-TString TokenName(const TString& name, 
-                  const TString& ext, 
-                  Bool_t merge=false)
+TString CacheFileName(const TString& name, 
+                     const TString& ext, 
+                     Bool_t merge=false)
 {
   return TString::Format("%s%s.%s", name.Data(), 
                         (merge ? "_merge" : ""), ext.Data());
@@ -51,12 +51,12 @@ TString TokenName(const TString& name,
  * @return true if file exits
  * @ingroup pwglf_forward_trains_helper
  */
-Bool_t CheckTokens(const TString& name, 
-                  const TString& ext, 
-                  Bool_t merge=false)
+Bool_t CheckCacheFile(const TString& name, 
+                     const TString& ext, 
+                     Bool_t merge=false)
 {
   // TSystem::AccessPathName return false if file is there 
-  return !gSystem->AccessPathName(TokenName(name, ext, merge));
+  return !gSystem->AccessPathName(CacheFileName(name, ext, merge));
 }
 /** 
  * Remove a token file 
@@ -66,11 +66,11 @@ Bool_t CheckTokens(const TString& name,
  * @param merge  Merging stage or not 
  * @ingroup pwglf_forward_trains_helper
  */
-void RemoveTokens(const TString& name, 
+void RemoveCacheFile(const TString& name, 
                  const TString& ext, 
                  Bool_t merge=false)
 {
-  gSystem->Unlink(TokenName(name, ext, merge));
+  gSystem->Unlink(CacheFileName(name, ext, merge));
 }
 
 /** 
@@ -84,7 +84,7 @@ void RemoveTokens(const TString& name,
  *
  * @ingroup pwglf_forward_trains_helper
  */
-TObjArray* ReadTokens(const TString& name, 
+TObjArray* ReadCacheFile(const TString& name, 
                      const TString& ext, 
                      bool merge=false) 
 {
@@ -92,7 +92,7 @@ TObjArray* ReadTokens(const TString& name,
                               (merge ? "_merge" : ""), ext.Data());
   std::ifstream in(fn.Data());
   if (!in) { 
-    Error("ReadTokens", "Failed to open %s", fn.Data());
+    Error("ReadCacheFile", "Failed to open %s", fn.Data());
     return 0;
   }
   TString ln;
@@ -115,7 +115,7 @@ TObjArray* ReadTokens(const TString& name,
  */
 TObjArray* ReadJobIDs(const TString& name, bool merge=false)
 {
-  return ReadTokens(name, "jobid", merge);
+  return ReadCacheFile(name, "jobid", merge);
 }
 
 /** 
@@ -130,7 +130,7 @@ TObjArray* ReadJobIDs(const TString& name, bool merge=false)
  */
 TObjArray* ReadStages(const TString& name, bool merge=false)
 {
-  return ReadTokens(name, "stage", merge);
+  return ReadCacheFile(name, "stage", merge);
 }
 
 /** 
@@ -351,6 +351,21 @@ Bool_t GetJobStates(const TArrayI& jobs, TObjArray& states)
   return true;
 }
 
+/** 
+ * Check if the AliEn token is valid 
+ * 
+ * 
+ * @return true if it is 
+ */
+Bool_t CheckAlienToken()
+{
+  Int_t ret = gSystem->Exec("alien-token-info > /dev/null 2>&1");
+  if (ret != 0) {
+    Printf("=== AliEn token not valid");
+    return false;
+  }
+  return true;
+}
 
 /** 
  * Refersh the grid token every 6th hour
@@ -358,20 +373,53 @@ Bool_t GetJobStates(const TArrayI& jobs, TObjArray& states)
  * @param now 
  * @param force 
  */
-void RefreshToken(UInt_t now, Bool_t force=false)
+#if 0
+void RefreshAlienToken(UInt_t, Bool_t f=false)
+{}
+#else
+void RefreshAlienToken(UInt_t now, Bool_t force=false)
 {
-  static UInt_t start = 0;
-  if (start == 0) start = now;
-  
-  // Try to refresh token every 6th hour
-  if (!force || (now - start) / 60 / 60 < 6) return;
+  Bool_t renew = force;
+  if (!renew && !CheckAlienToken()) renew = true;
+
+  if (!renew) {
+    TString l = gSystem->GetFromPipe(Form("cat /tmp/gclient_token_%d",
+                                         gSystem->GetUid()));
+    TObjArray*  lines  = l.Tokenize("\n");
+    TObjString* sline  = 0;
+    UInt_t      expire = 0;
+    TIter       next(lines);
+    while ((sline = static_cast<TObjString*>(next()))) {
+      TString& line = sline->String();
+      if (!line.BeginsWith("Expiretime")) continue;
+
+      Size_t  eq      = line.Index("=");
+      TString sdatime = line(eq+2, line.Length()-eq-2);
+      expire          = sdatime.Atoi();
+      break;
+    }
+    lines->Delete();
+    // If the expiration date/time has passed or is less than 30 min
+    // away, we refresh
+    Int_t diff = (expire - now);
+    if (now > expire || diff < 30*60) renew = true;
+
+    Printf("=== Now: %d, Expires: %d, in %03d:%02d:%02d -> %s", 
+          now, expire, diff/60/60, (diff/60 % 60), (diff % 60), 
+           (renew ? "renew" : "nothing"));
+          
+  }
+
+  if (!renew) return;
 
   // Reset the start time 
-  start = now;
   Printf("=== Refreshing AliEn token");
   gSystem->Exec("alien-token-init");
   Printf("=== Done refreshing AliEn token");
 }
+#endif
+
+
 /** 
  * Wait of jobs to finish 
  * 
@@ -388,9 +436,10 @@ Bool_t WaitForJobs(TArrayI&   jobs,
                   Int_t      delay,
                   Bool_t     batch)
 {
+  if (!CheckAlienToken()) return false;
   // Bool_t stopped = false;
   TFileHandler h(0, 0x1);
-  RefreshToken(0, true);
+  // RefreshAlienToken(0, true);
   do { 
     Bool_t allDone = true;
     TDatime t;
@@ -424,7 +473,7 @@ Bool_t WaitForJobs(TArrayI&   jobs,
       Printf(" %d(%s)=%s", job, stages->At(i)->GetName(), state.Data());
       
     }
-    RefreshToken(now);
+    RefreshAlienToken(now);
 
     if (allDone) break;
     if (missing >= total) {
@@ -462,12 +511,16 @@ Bool_t WaitForJobs(TArrayI&   jobs,
  */
 void GridWatch(const TString& name, Bool_t batch=false, UShort_t delay=5*60)
 {
+#if 1
+  // We use command line tools instead of ROOT interface - which is
+  // broken so badly that it's hard to believe it ever worked.
   gEnv->SetValue("XSec.GSI.DelegProxy", "2");
   TGrid::Connect("alien:///");
   if (!gGrid) { 
     Error("GridWatch", "Failed to connect to the Grid");
     return;
   }
+#endif
 
   TObjArray* jobIDs = ReadJobIDs(name, false);
   TObjArray* stages = ReadStages(name, false);
@@ -478,33 +531,34 @@ void GridWatch(const TString& name, Bool_t batch=false, UShort_t delay=5*60)
   if (!ParseJobIDs(jobIDs, jobs)) return;
 
   gSystem->Sleep(10*1000);
-  if (!(CheckTokens(name, "jobid", true) && 
-       CheckTokens(name, "stage", true))) 
-    WaitForJobs(jobs, stages, delay, batch);
+  if (!(CheckCacheFile(name, "jobid", true) && 
+       CheckCacheFile(name, "stage", true))) 
+    if (!WaitForJobs(jobs, stages, delay, batch)) return;
 
   delete jobIDs;
   delete stages;
 
   // return;
   do {
-    if (!CheckTokens(name, "jobid", true) && 
-       !CheckTokens(name, "stage", true)) {
+    if (!CheckCacheFile(name, "jobid", true) && 
+       !CheckCacheFile(name, "stage", true)) {
+      if (!CheckAlienToken()) return;
       Printf("Now executing terminate");
       gSystem->Exec("aliroot -l -b -q Terminate.C");
       gSystem->Sleep(10*1000);
     }
-    Printf("Reading job ids");
 
+    Printf("Reading job ids");
     jobIDs = ReadJobIDs(name, true);
     stages = ReadStages(name, true);
     
     if (!ParseJobIDs(jobIDs, jobs)) {
       Error("GridWatch", "Failed to parse job ids %s", 
-           TokenName(name,"jobid",true).Data());
+           CacheFileName(name,"jobid",true).Data());
       return;
     }
 
-    WaitForJobs(jobs, stages, delay, batch);
+    if (!WaitForJobs(jobs, stages, delay, batch)) return;
     
     Bool_t allFinal = true;
     for (Int_t i = 0; i < jobs.GetSize(); i++) {
@@ -520,8 +574,8 @@ void GridWatch(const TString& name, Bool_t batch=false, UShort_t delay=5*60)
     Printf("All jobs in final stage");
     if (allFinal) break;
 
-    RemoveTokens(name, "jobid", true);
-    RemoveTokens(name, "stage", true);
+    RemoveCacheFile(name, "jobid", true);
+    RemoveCacheFile(name, "stage", true);
   } while (true);
 
   Printf("Finished");
index 53493dc74847005458fadf79d9a89cc934fd96c5..cec7c270f22a10b847b9d538c6d1a1724a208a2f 100644 (file)
@@ -776,6 +776,7 @@ protected:
       SaveSetupShell("rerun", ClassName(), fName, tmp, uopts);
     SaveSetupROOT("ReRun", ClassName(), fName, tmp, uopts);
     if (fHelper) fHelper->AuxSave(fEscapedName, asShellScript);
+    SavePostShellScript();
   }
   /** 
    * Save a setup as a shell script 
@@ -870,6 +871,85 @@ protected:
       << "//" << std::endl;
     o.close();
   }    
+  /** 
+   * Write shell code to do post processing after terminate.  This
+   * code should deal with a single run (or run range).  The following
+   * shell variables are available to the code:
+   *
+   * - @c $prefix  Relative path to job directory or empty 
+   * - @c $dest    Destination for output to be stored
+   * 
+   * Note, the code is injected into a shell function, and should
+   * therefor not define new functions or the like.
+   * 
+   * @param o The output stream.  
+   */
+  virtual void PostShellCode(std::ostream& o)
+  {
+    o << "  echo \"Nothing to do for " << ClassName() 
+      << " train\"" << std::endl;
+  }
+  /** 
+   * Save a script to do post processing after terminate on each run
+   * or run-range. 
+   * 
+   * The shell script will execute the train defined code (in
+   * PostShellCode) for each run or run-range.  The train defined code
+   * and call drawing and summarizing macros or the like.
+   *
+   * In case of Grid analysis, this script will download and extract
+   * the appropriate ZIP files to separate directories, and then
+   * change directory to these directories and execute the train
+   * defined shell code there.  In this case, the script defines the
+   * shell variable @c $prefix as the relative path to the job
+   * directory.
+   * 
+   */
+  void SavePostShellScript()
+  {
+    std::ofstream f("post.sh");
+    if (!f) { 
+      Error("SavePostAll", "Failed to open post.sh script");
+      return;
+    }
+    f << "#!/bin/bash\n"
+      << "# Generated by " << ClassName() << "\n"
+      << "set -e\n"
+      << "\n"
+      << "dest=$1\n"
+      << "prefix=\n"
+      << "\n"
+      << "doall() {"
+      << std::endl;
+    PostShellCode(f);
+    f << "}\n"
+      << "\n"
+      << "if test ! -f Download.C ;then\n"
+      << "  doall\n"
+      << "  exit\n"
+      << "fi\n"
+      << "\n"
+      << "if test ! -f .download ; then\n"
+      << "  aliroot -l -b -q Download.C\\(1\\)\n"
+      << "  touch .download\n"
+      << "fi\n"
+      << "prefix=../\n"
+      << "\n"
+      << "for i in root_archive_*.zip ; do\n"
+      << "  d=`basename $i .zip` \n"
+      << "  if test ! -d $d ; then\n"
+      << "    echo \"Directory $d missing\"\n"
+      << "    continue\n"
+      << "  fi\n"
+      << "  \n"
+      << "  (cd $d && doall)\n"
+      << "done\n"
+      << "# EOF"
+      << std::endl;
+    f.close();
+    gSystem->Exec("chmod a+x post.sh");
+  }
+    
   /* @} */
   TString      fName;
   TString      fEscapedName;