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 copy/link 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())) {
51 if (gSystem->AccessPathName(Form("../%s.par", parFile.Data()))) {
54 gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s", parFile.Data()));
55 if (gSystem->AccessPathName(aliParFile.Data())) {
56 Error("ParUtilities::Find",
57 "PAR file %s not found in current or parent "
58 "directory nor in $(ALICE_ROOT)", parFile.Data());
61 // Copy to current directory
62 TFile::Cp(aliParFile, parFile);
65 gSystem->Exec(Form("ln -s %s .", parFile.Data()));
69 static Bool_t Load(const TString& name)
71 if (name.IsNull()) return true;
73 Error("ParUtilities::Load", "No connection to a Proof cluster");
79 Info("ParUtilities::LoadLibrary", "Uploading %s", name.Data());
81 // First check in current directory
82 Int_t ret = gProof->UploadPackage(fn, TProof::kRemoveOld);
85 // IF not found there, then check parent directory
87 gSystem->ExpandPathName(fn);
88 ret = gProof->UploadPackage(fn);
92 // If not found in current or parent directory, try the
93 // the ALICE_ROOT directory
94 fn = Form("$ALICE_ROOT/%s.par", name.Data());
95 gSystem->ExpandPathName(fn);
96 ret = gProof->UploadPackage(fn);
100 // IF not found, bark
101 Error("ParUtilities::Load",
102 "Could not find module %s.par in current or parent directory "
103 "nor in $ALICE_ROOT", name.Data());
107 ret = gProof->EnablePackage(name);
108 Info("ParUtilities::Load", "Enabled package %s (from %s)",
109 name.Data(), fn.Data());
114 * Unpack, build, and load a PAR file.
116 * @param what Which PAR file
120 static Bool_t Build(const TString& what)
122 if (what.IsNull()) return false;
124 TString parFile(what);
125 if (!parFile.EndsWith(".par")) parFile.Append(".par");
128 gSystem->Exec(Form("tar xzf %s", parFile.Data()));
130 // Change directory into par archive
131 TString cwd = gSystem->WorkingDirectory();
134 if (dir.EndsWith(".par")) dir.ReplaceAll(".par", "");
135 if (!gSystem->ChangeDirectory(dir)) {
136 Error("ParUtilities::Setup", "Failed to change directory to %s",
142 if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
143 Info("ParUtilities::Setup", "Building in PAR archive %s", parFile.Data());
144 if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
145 Error("ParUtilities::Setup", "Failed to build in PAR directory %s",
147 gSystem->ChangeDirectory(cwd.Data());
152 // Check for setup script
153 if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
154 // Info("ParUtilities::SetupPAR", "Setting up for PAR %s", what);
155 gROOT->Macro("PROOF-INF/SETUP.C");
157 if (!gSystem->ChangeDirectory(cwd.Data())) return false;
161 //__________________________________________________________________
164 * @name PAR generation from script
167 * Service function to make a PAR out of a script.
169 * The script should contain can contain a sub-class of AliAnalysisTask.
170 * The script will be compiled on the slaves before loading the
171 * AliAnalysisManager. Parts to (not) be compiled can be protected like
175 * // This will _only_ be compiled in the servers
178 * // This will not be compiled in the servers
182 * @param mode Execution mode (Grid, PROOF, Local)
183 * @param script Script to upload and compile in the PAR
184 * @param deps Dependency pars
186 * @return true on success.
188 static Bool_t MakeScriptPAR(Bool_t isLocal,
189 const TString& script,
192 // --- In local mode, just AcLic and load ------------------------
194 if (gROOT->LoadMacro(Form("%s++g", script.Data())) < 0)
199 // --- Get the base name -----------------------------------------
200 Info("ParUtilities::MakeScriptPAR", "Making par file for %s",
202 TString base(gSystem->BaseName(script));
203 Int_t idx = base.Last('.');
204 if (idx != kNPOS) base.Remove(idx);
206 // --- Check name of script file ---------------------------------
209 if (script.EndsWith(".C")) ext = "C";
210 else if (script.EndsWith(".cxx")) ext = "cxx";
211 else { ext = "C"; scr.Append(".C"); }
213 // --- Check if we can access the file ---------------------------
214 TString path = TString::Format(".:%s", TROOT::GetMacroPath());
215 char* loc = gSystem->Which(path, scr);
217 Error("ParUtilities::MakeScriptPAR",
218 "Script %s not found in %s", scr.Data(), path.Data());
223 // --- Create our temporary directory ----------------------------
224 TString tmpdir(gSystem->TempDirectory());
225 int ltempl = tmpdir.Length() + 1 + 5 + 6 + 1;
226 char* templ = new char[ltempl];
227 snprintf(templ, ltempl, "%s/trainXXXXXX", tmpdir.Data());
228 if (!mkdtemp(templ)) {
229 Error("ParUtilities::MakeScriptPAR",
230 "Failed to generate temporary directory from template %s",
235 Bool_t retVal = false;
237 // --- Make directories for package ------------------------------
238 TString dir = TString::Format("%s/%s", templ, base.Data());
239 // Set-up directories
240 if (gSystem->MakeDirectory(dir) < 0)
241 throw TString::Format("Could not make directory '%s'", base.Data());
242 if (gSystem->MakeDirectory(Form("%s/PROOF-INF", dir.Data())))
243 throw TString::Format("Could not make directory %s/PROOF-INF",
246 // --- Copy the script to the setup directory --------------------
247 TString dest = TString::Format("%s/%s.%s", dir.Data(),
248 base.Data(), ext.Data());
249 Int_t ret = gSystem->CopyFile(full, dest, true);
251 case -1: throw TString::Format("Couldn't open %s for copy", scr.Data());
252 case -2: throw TString::Format("File %s exists", dest.Data());
253 case -3: throw TString::Format("Error while copying %s", scr.Data());
256 // --- Make scripts, etc. ----------------------------------------
257 TObjArray* depList = deps.Tokenize(", ");
258 if (!MakeBuildScript(dir, base))
259 throw TString::Format("Failed to make build script");
260 if (!MakeUtilityScript(dir))
261 throw TString::Format("Failed to make utility script");
262 if (!MakeBuildMacro(dir, base, ext, depList))
263 throw TString::Format("Failed to make build macro");
264 if (!MakeSetupMacro(dir, base, ext, depList))
265 throw TString::Format("Failed to setup macro");
267 // --- Pack up the archive ---------------------------------------
268 ret = gSystem->Exec(Form("(cd %s && tar -czf %s.par %s)",
269 templ, base.Data(),base.Data()));
271 throw TString::Format("Failed to create PAR file %s.PAR from %s",
272 base.Data(), dir.Data());
274 // --- Move PAR file to here -------------------------------------
275 ret = gSystem->Exec(Form("mv -f %s/%s.par %s.par", templ, base.Data(),
278 throw TString::Format("Failed to rename %s/%s.par to %s.par: %s",
279 templ, base.Data(), base.Data(),
280 gSystem->GetError());
284 Error("ParUtilities::MakeScriptPAR", e.Data());
288 // --- Remove temporary directory --------------------------------
289 gSystem->Exec(Form("rm -rf %s", templ));
294 * Write a build script
296 * @param dir Directory to put it in
298 * @return true on success
300 static Bool_t MakeBuildScript(const TString& dir,
303 // Make our build file
304 std::ofstream out(Form("%s/PROOF-INF/BUILD.sh", dir.Data()));
306 Error("ParUtilities::MakeBuildScript", "Failed to open out shell script");
310 << "if test x$ALICE_ROOT != x ; then\n"
311 << " if test x$ALICE_TARGET = x ; then\n"
312 << " export ALICE_TARGET=`$ROOTSYS/bin/root-config --arch`\n"
314 << " export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:"
315 << "${ALICE_ROOT}/lib/tgt_${ALICE_TARGET}\n"
317 << "echo BUILD.sh@`hostname`: Building " << base << "\n"
318 << "root.exe -l -out -q PROOF-INF/BUILD.C 2>&1 | tee "
320 << "echo BUILD.sh@`hostname`: done: $?\n"
323 if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", dir.Data()), 0755) != 0) {
324 Error("ParUtilities::MakeBuildScript",
325 "Failed to set exectuable flags on %s/PROOF-INF/BUILD.sh",
332 * Write a build macro
334 * @param dir Directory to put macro in
335 * @param deps Dependencies
336 * @param base Base name of script to compile
338 * @return true on success
340 static Bool_t MakeBuildMacro(const TString& dir,
343 const TCollection* deps) {
344 std::ofstream out(Form("%s/PROOF-INF/BUILD.C", dir.Data()));
346 Error("ParUtilities::MakeBuildMacro", "Failed to open build script");
349 out << "void BUILD() {\n"
350 << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n"
351 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
352 << " LoadROOTLibs();\n"
353 << " AddAliROOT();\n";
357 while ((dep = next())) {
358 out << " AddDep(\"" << dep->GetName() << "\");\t"
359 << " LoadDep(\"" << dep->GetName() << "\");\n";
362 out << " // gDebug = 5;\n"
363 << " int ret = gROOT->LoadMacro(\""
364 << base << "." << ext << "++g\");\n"
365 << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n"
366 << " // else Info(\"BUILD\", \"Made " << base << "\");\n"
374 * Make a utility macro
376 * @param dir Directory to put the macro in
378 * @return true on success
380 static Bool_t MakeUtilityScript(const TString& dir)
382 std::ofstream out(Form("%s/PROOF-INF/UTIL.C", dir.Data()));
384 Error("ParUtilities::MakeUtilityScript", "Failed to open utility script");
387 out << "void LoadROOTLibs() {\n"
388 << " gSystem->Load(\"libVMC\");\n"
389 << " gSystem->Load(\"libNet\");\n"
390 << " gSystem->Load(\"libTree\");\n"
391 << " gSystem->Load(\"libPhysics\");\n"
392 << " gSystem->Load(\"libMinuit\");\n"
394 << "void AddAliROOT() {\n"
395 << " TString val(gSystem->Getenv(\"ALICE_ROOT\"));\n"
396 << " if (val.IsNull())\n"
397 << " Warning(\"Add\",\"ALICE_ROOT not defined\");\n"
399 << " gSystem->AddIncludePath(Form(\"-I%s/include\",val.Data()));\n"
401 << "void AddDep(const char* env) {\n"
402 << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n"
403 << " if (val.IsNull())\n"
404 << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n"
406 << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n"
409 << "void LoadDep(const char* name) {\n"
410 << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n"
411 << " char* full = gSystem->DynamicPathName(name,true);\n"
413 << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n"
415 << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n"
417 << " Warning(\"LoadDep\",\"Module %s not found\", name);\n"
420 << " gSystem->Load(full);\n"
427 * Make a setup script
429 * @param dir Directory to put it in
430 * @param base Base name of target script
431 * @param ext Extension of target script
432 * @param deps Dependencies
434 * @return true on success
436 static Bool_t MakeSetupMacro(const TString& dir,
439 const TCollection* deps)
441 // Make our set-up script
442 std::ofstream out(Form("%s/PROOF-INF/SETUP.C", dir.Data()));
444 Error("ParUtilities::MakeSetupMacro", "Failed to open setup script");
447 out << "void SETUP() {\n"
448 << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n"
449 << " LoadROOTLibs();\n"
450 << " // Info(\"SETUP\",\"Loading libraries\");\n";
454 while ((dep = next()))
455 out << " LoadDep(\"" << dep->GetName() << "\");\n";
457 out << " // gDebug = 5;\n"
458 << " // Info(\"SETUP\",\"Loading " << base <<"_"<< ext << ".so\");\n"
459 << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n"
460 << " // gDebug = 0;\n"
461 << " gROOT->ProcessLine(\".include " << base << "\");\n"
462 << " gSystem->Setenv(\"" << base << "_INCLUDE\",\""
464 << " // Info(\"SETUP\", \"Done\");\n"