3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Tue Oct 16 17:51:10 2012
6 * @brief PAR file utilities
8 * @ingroup pwglf_forward_trains_util
27 // ===================================================================
29 * Helper to set-up and load PARs
31 * @ingroup pwglf_forward_trains_util
36 * Find PAR file (either in current or parent directory or directly
37 * in $ALICE_ROOT), and link it here
39 * @param what PAR file name (sans .par)
41 * @return true on success
43 static Bool_t Find(const TString& what)
45 if (what.IsNull()) return false;
47 TString parFile(what);
48 if (!parFile.EndsWith(".par")) parFile.Append(".par");
49 if (gSystem->AccessPathName(parFile.Data())) {
52 if (gSystem->AccessPathName(Form("../%s.par", parFile.Data())) == 0)
53 src.Form("../%s", parFile.Data());
57 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
58 if (gSystem->AccessPathName(aliParFile.Data()) == 0)
62 Error("ParUtilities::Find",
63 "PAR file %s not found in current or parent "
64 "directory nor in $(ALICE_ROOT)", parFile.Data());
67 // Copy to current directory
68 // TFile::Copy(aliParFile, parFile);
69 if (gSystem->Exec(Form("ln -s %s %s", src.Data(), parFile.Data())) != 0){
70 Error("ParUtilities::Find", "Failed to symlink %s to %s",
71 src.Data(), parFile.Data());
78 * Unpack and load a PAR file previously found with Find.
80 * @param name PAR file name
81 * @deprecated Use Find and Build instead
82 * @return true on success
84 static Bool_t Load(const TString& name)
86 if (name.IsNull()) return true;
88 Error("ParUtilities::Load", "No connection to a Proof cluster");
94 Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data());
96 // First check in current directory
97 Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld);
100 // IF not found there, then check parent directory
102 gSystem->ExpandPathName(fn);
103 ret = gProof->UploadPackage(fn);
107 // If not found in current or parent directory, try the
108 // the ALICE_ROOT directory
109 fn = Form("$ALICE_ROOT/%s.par", name.Data());
110 gSystem->ExpandPathName(fn);
111 ret = gProof->UploadPackage(fn);
115 // IF not found, bark
116 Error("ParUtilities::Load",
117 "Could not find module %s.par in current or parent directory "
118 "nor in $ALICE_ROOT", name.Data());
122 ret = gProof->EnablePackage(name);
123 Info("ParUtilities::Load", "Enabled package %s (from %s)",
124 name.Data(), fn.Data());
129 * Unpack, build, and load a PAR file.
131 * @param what Which PAR file
135 static Bool_t Build(const TString& what)
137 if (what.IsNull()) return false;
139 TString parFile(what);
140 if (!parFile.EndsWith(".par")) parFile.Append(".par");
143 gSystem->Exec(Form("tar xzf %s", parFile.Data()));
145 // Change directory into par archive
146 TString cwd = gSystem->WorkingDirectory();
149 if (dir.EndsWith(".par")) dir.ReplaceAll(".par", "");
150 if (!gSystem->ChangeDirectory(dir)) {
151 Error("ParUtilities::Setup", "Failed to change directory to %s",
157 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
158 Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data());
159 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
160 Error("ParUtilities::Setup", "Failed to build in PAR directory %s",
162 gSystem->ChangeDirectory(cwd.Data());
167 // Check for setup script
168 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
169 // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what);
170 gROOT->Macro("PROOF-INF/SETUP.C");
172 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
176 //__________________________________________________________________
179 * @name PAR generation from script
182 * Service function to make a PAR out of a script.
184 * The script should contain can contain a sub-class of AliAnalysisTask.
185 * The script will be compiled on the slaves before loading the
186 * AliAnalysisManager. Parts to (not) be compiled can be protected like
190 * // This will _only_ be compiled in the servers
193 * // This will not be compiled in the servers
197 * @param mode Execution mode (Grid, PROOF, Local)
198 * @param script Script to upload and compile in the PAR
199 * @param deps Dependency pars
201 * @return true on success.
203 static Bool_t MakeScriptPAR(Bool_t isLocal,
204 const TString& script,
207 // --- In local mode, just AcLic and load ------------------------
209 if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0)
214 // --- Get the base name -----------------------------------------
215 Info("ParUtilities::MakeScriptPAR", "Making par file for %s",
217 TString base(gSystem->BaseName(script));
218 Int_t idx = base.Last('.');
219 if (idx != kNPOS) base.Remove(idx);
221 // --- Check name of script file ---------------------------------
224 if (script.EndsWith(".C")) ext = "C";
225 else if (script.EndsWith(".cxx")) ext = "cxx";
226 else { ext = "C"; scr.Append(".C"); }
228 // --- Check if we can access the file ---------------------------
229 TString path = TString::Format(".:%s", TROOT::GetMacroPath());
230 char* loc = gSystem->Which(path, scr);
232 Error("ParUtilities::MakeScriptPAR",
233 "Script %s not found in %s", scr.Data(), path.Data());
238 // --- Create our temporary directory ----------------------------
239 TString tmpdir(gSystem->TempDirectory());
240 int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
241 char* templ = new char[ltempl];
242 snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
243 if (!mkdtemp(templ)) {
244 Error("ParUtilities::MakeScriptPAR",
245 "Failed to generate temporary directory from template %s",
250 Bool_t retVal = false;
252 // --- Make directories for package ------------------------------
253 TString dir = TString::Format("%s/%s", templ, base.Data());
254 // Set-up directories
255 if (gSystem->MakeDirectory(dir) < 0)
256 throw TString::Format("Could not make directory '%s'", base.Data());
257 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data())))
258 throw TString::Format("Could not make directory %s/PROOF-INF",
261 // --- Copy the script to the setup directory --------------------
262 TString dest = TString::Format("%s/%s.%s", dir.Data(),
263 base.Data(), ext.Data());
264 Int_t ret = gSystem->CopyFile(full, dest, true);
266 case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
267 case -2: throw TString::Format("File %s exists", dest.Data());
268 case -3: throw TString::Format("Error while copying %s", scr.Data());
271 // --- Make scripts, etc. ----------------------------------------
272 TObjArray* depList = deps.Tokenize(", ");
273 if (!MakeBuildScript(dir, base))
274 throw TString::Format("Failed to make build script");
275 if (!MakeUtilityScript(dir))
276 throw TString::Format("Failed to make utility script");
277 if (!MakeBuildMacro(dir, base, ext, depList))
278 throw TString::Format("Failed to make build macro");
279 if (!MakeSetupMacro(dir, base, ext, depList))
280 throw TString::Format("Failed to setup macro");
282 // --- Pack up the archive ---------------------------------------
283 ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)",
284 templ, base.Data(),base.Data()));
286 throw TString::Format("Failed to create PAR file %s.PAR from %s",
287 base.Data(), dir.Data());
289 // --- Move PAR file to here -------------------------------------
290 ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(),
293 throw TString::Format("Failed to rename %s/%s.par to %s.par: %s",
294 templ, base.Data(), base.Data(),
295 gSystem->GetError());
299 Error("ParUtilities::MakeScriptPAR", e.Data());
303 // --- Remove temporary directory --------------------------------
304 gSystem->Exec(Form("rm -rf %s", templ));
309 * Write a build script
311 * @param dir Directory to put it in
313 * @return true on success
315 static Bool_t MakeBuildScript(const TString& dir,
318 // Make our build file
319 std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
321 Error("ParUtilities::MakeBuildScript", "Failed to open out shell script");
325 << "if test x$ALICE_ROOT != x ; then\n"
326 << " if test x$ALICE_TARGET = x ; then\n"
327 << " export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n"
329 << " export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"
330 << "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n"
332 << "echo BUILD.sh@`hostname`: Building " << base << "\n"
333 << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee "
335 << "echo BUILD.sh@`hostname`: done: $?\n"
338 if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
339 Error("ParUtilities::MakeBuildScript",
340 "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh",
347 * Write a build macro
349 * @param dir Directory to put macro in
350 * @param deps Dependencies
351 * @param base Base name of script to compile
353 * @return true on success
355 static Bool_t MakeBuildMacro(const TString& dir,
358 const TCollection* deps) {
359 std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
361 Error("ParUtilities::MakeBuildMacro", "Failed to open build script");
364 out << "void BUILD() {\n"
365 << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
366 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
367 << " LoadROOTLibs();\n"
368 << " AddAliROOT();\n";
372 while ((dep = next())) {
373 out << " AddDep(\"" << dep->GetName() << "\");\t"
374 << " LoadDep(\"" << dep->GetName() << "\");\n";
377 out << " // gDebug = 5;\n"
378 << " int ret = gROOT->LoadMacro(\""
379 << base << "." << ext << "++g\");\n"
380 << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
381 << " // else Info(\"BUILD\", \"Made " << base << "\");\n"
389 * Make a utility macro
391 * @param dir Directory to put the macro in
393 * @return true on success
395 static Bool_t MakeUtilityScript(const TString& dir)
397 std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
399 Error("ParUtilities::MakeUtilityScript", "Failed to open utility script");
402 out << "void LoadROOTLibs() {\n"
403 << " gSystem->Load(\"libVMC\");\n"
404 << " gSystem->Load(\"libNet\");\n"
405 << " gSystem->Load(\"libTree\");\n"
406 << " gSystem->Load(\"libPhysics\");\n"
407 << " gSystem->Load(\"libMinuit\");\n"
409 << "void AddAliROOT() {\n"
410 << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
411 << " if (val.IsNull())\n"
412 << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
414 << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
416 << "void AddDep(const char* env) {\n"
417 << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
418 << " if (val.IsNull())\n"
419 << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
421 << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
424 << "void LoadDep(const char* name) {\n"
425 << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
426 << " char* full = gSystem->DynamicPathName(name,true);\n"
428 << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
430 << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
432 << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
435 << " gSystem->Load(full);\n"
442 * Make a setup script
444 * @param dir Directory to put it in
445 * @param base Base name of target script
446 * @param ext Extension of target script
447 * @param deps Dependencies
449 * @return true on success
451 static Bool_t MakeSetupMacro(const TString& dir,
454 const TCollection* deps)
456 // Make our set-up script
457 std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
459 Error("ParUtilities::MakeSetupMacro", "Failed to open setup script");
462 out << "void SETUP() {\n"
463 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
464 << " LoadROOTLibs();\n"
465 << " // Info(\"SETUP\",\"Loading libraries\");\n";
469 while ((dep = next()))
470 out << " LoadDep(\"" << dep->GetName() << "\");\n";
472 out << " // gDebug = 5;\n"
473 << " // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
474 << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
475 << " // gDebug = 0;\n"
476 << " gROOT->ProcessLine(\".include " << base << "\");\n"
477 << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
479 << " // Info(\"SETUP\", \"Done\");\n"