]>
Commit | Line | Data |
---|---|---|
56199f2b | 1 | /** |
bd6f5206 | 2 | * @defgroup pwglf_forward_trains Trains |
56199f2b | 3 | * |
bd6f5206 | 4 | * @ingroup pwglf_forward |
56199f2b | 5 | */ |
1d86b7ca | 6 | /** |
7 | * @file TrainSetup.C | |
8 | * @author Christian Holm Christensen <cholm@dalsgaard.hehi.nbi.dk> | |
9 | * @date Wed Mar 23 12:12:00 2011 | |
10 | * | |
11 | * @brief | |
12 | * | |
bd6f5206 | 13 | * @ingroup pwglf_forward_trains |
1d86b7ca | 14 | * |
15 | */ | |
16 | ||
17 | #ifndef __CINT__ | |
18 | #include <fstream> | |
19 | #include <iostream> | |
20 | ||
21 | #include <TAlienCollection.h> | |
22 | #include <TArrayI.h> | |
23 | #include <TChain.h> | |
24 | #include <TDatime.h> | |
25 | #include <TEnv.h> | |
26 | #include <TFile.h> | |
27 | #include <TGrid.h> | |
28 | #include <TList.h> | |
29 | #include <TObjString.h> | |
30 | #include <TProof.h> | |
31 | #include <TString.h> | |
32 | #include <TSystem.h> | |
33 | #include <TSystemDirectory.h> | |
34 | #include <TSystemFile.h> | |
35 | #include <TROOT.h> | |
36 | ||
37 | #include <AliAODHandler.h> | |
38 | #include <AliAODInputHandler.h> | |
39 | #include <AliAnalysisDataContainer.h> | |
40 | #include <AliAnalysisManager.h> | |
41 | #include <AliAnalysisAlien.h> | |
42 | #include <AliESDInputHandler.h> | |
43 | #include <AliMCEventHandler.h> | |
44 | #include <AliVEventHandler.h> | |
45 | #include <AliPhysicsSelection.h> | |
46 | #include <AliCentralitySelectionTask.h> | |
47 | #else | |
48 | class TArrayI; | |
49 | class TChain; | |
50 | class AliAnalysisManager; | |
51 | #endif | |
52 | ||
53 | //==================================================================== | |
54 | /** | |
55 | * Generic set-up of an analysis train using the grid-handler (AliEn plugin). | |
56 | * | |
57 | * Users should define a class that derives from this. The class | |
58 | * should implement the member function CreateTasks to add needed | |
59 | * tasks to the train | |
60 | * | |
61 | * @code | |
62 | * // MyTrain.C | |
63 | * class MyTrain : public TrainSetup | |
64 | * { | |
65 | * public: | |
66 | * MyTrain(Bool_t dateTime = false, | |
67 | * UShort_t year = 0, | |
68 | * UShort_t month = 0, | |
69 | * UShort_t day = 0, | |
70 | * UShort_t hour = 0, | |
71 | * UShort_t min = 0) | |
72 | * : TrainSetup("My train", dateTime, year, month, day, hour, min) | |
73 | * {} | |
74 | * void Run(const char* type, const char* mode, const char* oper, | |
75 | * Int_t nEvents=-1, Bool_t mc=false, | |
76 | * Bool_t usePar=false) | |
77 | * { | |
78 | * Exec(type, mode, oper, nEvents, mc, usePar); | |
79 | * } | |
80 | * protected: | |
81 | * void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr) | |
82 | * { | |
83 | * AliAnalysisManager::SetCommonFileName("my_analysis.root"); | |
84 | * LoadLibrary("MyAnalysis", mode, par, true); | |
85 | * Bool_t mc = mgr->GetMCtruthEventHandler() != 0; | |
86 | * gROOT->Macro("MyAnalysis.C"); | |
87 | * } | |
88 | * }; | |
89 | * @endcode | |
90 | * | |
91 | * This can then be run like | |
92 | * | |
93 | * @verbatim | |
94 | * > aliroot | |
95 | * Root> .L TrainSetup.C | |
96 | * Root> .L MyTrain.C | |
97 | * Root> MyTrain t; | |
98 | * Root> t.Run(); | |
99 | * @endverbatim | |
100 | * | |
101 | * or as a script | |
102 | * | |
103 | * @code | |
104 | * { | |
105 | * gROOT->LoadMacro("TrainSetup.C"); | |
106 | * gROOT->LoadMacro("MyTrain.C"); | |
107 | * MyTrain t; | |
108 | * t.Run(); | |
109 | * } | |
110 | * @endcode | |
111 | * | |
112 | * To byte compile this, you need to | |
113 | * - load the ROOT AliEn library | |
114 | * - load the analysis libraries | |
115 | * - add $ALICE_ROOT/include to header search | |
116 | * first | |
117 | * | |
118 | * @verbatim | |
119 | * > aliroot | |
bd6f5206 | 120 | * Root> gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2:" |
1d86b7ca | 121 | * Root> "$ALICE_ROOT/ANALYSIS/macros", |
122 | * Root> gROOT->GetMacroPath())); | |
123 | * Root> gSystem->AddIncludePath("-I${ALICE_ROOT}/include"); | |
124 | * Root> gSystem->Load("libRAliEn"); | |
125 | * Root> gSystem->Load("libANALYSIS"); | |
126 | * Root> gSystem->Load("libANALYSISalice"); | |
127 | * Root> gROOT->LoadMacro("TrainSetup.C+"); | |
128 | * @endverbatim | |
129 | * | |
56199f2b | 130 | * |
bd6f5206 | 131 | * @ingroup pwglf_forward_trains |
1d86b7ca | 132 | * |
133 | */ | |
134 | struct TrainSetup | |
135 | { | |
136 | /** | |
137 | * Data type to process | |
138 | */ | |
139 | enum EType { | |
140 | /** Event Summary Data */ | |
141 | kESD, | |
142 | /** Analysis Object Data */ | |
143 | kAOD | |
144 | }; | |
145 | /** | |
146 | * How to run the analysis | |
147 | * | |
148 | */ | |
149 | enum EMode { | |
150 | /** Locally */ | |
151 | kLocal = 1, | |
152 | /** In PROOF(-Lite) cluster */ | |
153 | kProof, | |
154 | /** On the Grid */ | |
155 | kGrid | |
156 | }; | |
157 | /** | |
158 | * What stage of the analysis to run | |
159 | * | |
160 | */ | |
161 | enum EOper { | |
162 | /** Testing. Local processing, a single copied from Grid */ | |
163 | kTest, | |
164 | /** Off-line */ | |
165 | kOffline, | |
166 | /** Submit to queue */ | |
167 | kSubmit, | |
168 | /** Merge and terminate */ | |
169 | kTerminate, | |
170 | /** Full run */ | |
171 | kFull | |
172 | }; | |
173 | ||
174 | //__________________________________________________________________ | |
175 | /** | |
176 | * Constructor | |
177 | * | |
178 | * @param name Name of analysis (free-form) | |
179 | * @param useDateTime Whether to append date and time to the name | |
180 | * @param year Year - if not specified, taken from current date | |
181 | * @param month Month - if not specified, taken from current date | |
182 | * @param day Day - if not specified, taken from current date | |
183 | * @param hour Hour - if not specified, taken from current time | |
184 | * @param min Minute - if not specified, taken from current time | |
185 | */ | |
186 | TrainSetup(const char* name, Bool_t useDateTime=true, | |
187 | UShort_t year=0, UShort_t month=0, | |
188 | UShort_t day=0, UShort_t hour=0, UShort_t min=0) | |
189 | : fName(name), | |
190 | fRootVersion("v5-28-00a"), | |
191 | fAliRootVersion("v4-21-18-AN"), | |
192 | fAliEnAPIVersion("V1.1x"), | |
193 | fProofServer("alicecaf.cern.ch"), | |
194 | fDataDir("/alice/data/2010/LHC10c"), | |
195 | fDataSet("/COMMON/COMMON/LHC09a4_run8100X#/esdTree"), | |
196 | fXML(""), | |
197 | fRunNumbers(0), | |
198 | fListOfPARs(), | |
199 | fListOfSources(), | |
200 | fListOfLibraries(), | |
201 | fListOfExtras(), | |
202 | fNReplica(4), | |
203 | fESDPass(3), | |
204 | fPassPostfix(""), | |
205 | fEscapedName(name), | |
871a9ac1 | 206 | fAllowOverwrite(kFALSE), |
207 | fUseGDB(kFALSE) | |
1d86b7ca | 208 | { |
209 | char c[] = { ' ', '/', '@', 0 }; | |
210 | char* p = c; | |
211 | while (*p) { | |
212 | fEscapedName.ReplaceAll(Form("%c", *p), "_"); | |
213 | p++; | |
214 | } | |
215 | ||
216 | if (useDateTime) { | |
217 | if (year == 0 || month == 0 || day == 0) { | |
218 | TDatime now; | |
219 | year = now.GetYear(); | |
220 | month = now.GetMonth(); | |
221 | day = now.GetDay(); | |
222 | hour = now.GetHour(); | |
223 | min = now.GetMinute(); | |
224 | } | |
225 | fEscapedName.Append(Form("_%04d%02d%02d_%02d%02d", | |
226 | year, month, day, hour, min)); | |
227 | } | |
228 | ||
229 | } | |
230 | ||
231 | //__________________________________________________________________ | |
232 | /** | |
233 | * Parse a string into a type enum | |
234 | * | |
235 | * @param type String to pass | |
236 | * | |
237 | * @return Enumaration value | |
238 | */ | |
239 | static EType ParseType(const char* type, Bool_t& /*mc*/) | |
240 | { | |
241 | // mc = false; | |
242 | TString sType(type); | |
243 | sType.ToUpper(); | |
244 | EType eType = kESD; | |
245 | // if (sType.Contains("MC")) mc = true; | |
246 | if (sType.Contains("ESD")) eType = kESD; | |
247 | else if (sType.Contains("AOD")) eType = kAOD; | |
248 | else | |
249 | Fatal("Run", "Unknown type '%s'", type); | |
250 | ||
251 | return eType; | |
252 | } | |
253 | //__________________________________________________________________ | |
254 | /** | |
255 | * Return a string that reflects the passed mode | |
256 | * | |
257 | * @param eMode Mode | |
258 | * | |
259 | * @return String representation of mode | |
260 | */ | |
261 | static const char* ModeString(EMode eMode) | |
262 | { | |
263 | switch (eMode) { | |
264 | case kLocal: return "LOCAL"; | |
265 | case kProof: return "PROOF"; | |
266 | case kGrid: return "GRID"; | |
267 | } | |
268 | return 0; | |
269 | } | |
270 | //__________________________________________________________________ | |
271 | /** | |
272 | * Parse a string for mode specifier | |
273 | * | |
274 | * @param mode Mode string | |
275 | * | |
276 | * @return EMode value | |
277 | */ | |
278 | static EMode ParseMode(const char* mode) | |
279 | { | |
280 | TString sMode(mode); | |
281 | sMode.ToUpper(); | |
282 | EMode eMode = kLocal; | |
283 | if (sMode == "LOCAL") eMode = kLocal; | |
284 | else if (sMode == "PROOF") eMode = kProof; | |
285 | else if (sMode == "GRID") eMode = kGrid; | |
286 | else | |
287 | Fatal("Run", "Unknown mode '%s'", mode); | |
288 | return eMode; | |
289 | } | |
290 | ||
291 | //__________________________________________________________________ | |
292 | /** | |
293 | * Return a string that reflects the passed operation | |
294 | * | |
295 | * @param eOper Operation | |
296 | * | |
297 | * @return String representation of operation | |
298 | */ | |
299 | static const char* OperString(EOper eOper) | |
300 | { | |
301 | switch (eOper) { | |
302 | case kTest: return "TEST"; | |
303 | case kOffline: return "OFFLINE"; | |
304 | case kSubmit: return "SUBMIT"; | |
305 | case kTerminate: return "TERMINATE"; | |
306 | case kFull: return "FULL"; | |
307 | } | |
308 | return 0; | |
309 | } | |
310 | //__________________________________________________________________ | |
311 | /** | |
312 | * Parse an operation string | |
313 | * | |
314 | * @param oper Operation | |
315 | * | |
316 | * @return An EOper value | |
317 | */ | |
318 | static EOper ParseOperation(const char* oper) | |
319 | { | |
320 | TString sOper(oper); | |
321 | sOper.ToUpper(); | |
322 | EOper eOper = kFull; | |
323 | if (sOper == "TEST") eOper = kTest; | |
324 | else if (sOper == "OFFLINE") eOper = kOffline; | |
325 | else if (sOper == "SUBMIT") eOper = kSubmit; | |
326 | else if (sOper == "TERMINATE") eOper = kTerminate; | |
327 | else if (sOper == "FULL") eOper = kFull; | |
328 | else | |
329 | Fatal("Run", "unknown operation '%s'", oper); | |
330 | return eOper; | |
331 | } | |
332 | ||
333 | //__________________________________________________________________ | |
334 | /** | |
335 | * Set ROOT version to use | |
336 | * | |
337 | * @param v Version string of ROOT | |
338 | */ | |
339 | void SetROOTVersion(const char* v) { fRootVersion = v; } | |
340 | //__________________________________________________________________ | |
341 | /** | |
342 | * Set AliROOT version to use | |
343 | * | |
344 | * @param v Version string of AliROOT | |
345 | */ | |
346 | void SetAliROOTVersion(const char* v) { fAliRootVersion = v; } | |
347 | //__________________________________________________________________ | |
348 | /** | |
349 | * Set the PROOF server URL | |
350 | * | |
351 | * @param s PROOF server URL | |
352 | */ | |
353 | void SetProofServer(const char* s) { fProofServer = s; } | |
354 | //__________________________________________________________________ | |
355 | /** | |
356 | * Set the GRID/Local data dir | |
357 | * | |
358 | * @param d Directory with data | |
359 | */ | |
360 | void SetDataDir(const char* d) { fDataDir = d; } | |
361 | //__________________________________________________________________ | |
362 | /** | |
363 | * Set the PROOF data set | |
364 | * | |
365 | * @param d PROOF registered data set | |
366 | */ | |
367 | void SetDataSet(const char* d) { fDataSet = d; } | |
368 | //__________________________________________________________________ | |
369 | /** | |
370 | * Set the XML file to use | |
371 | * | |
372 | * @param x XML file | |
373 | */ | |
374 | void SetXML(const char* x) { fXML = x; } | |
375 | //__________________________________________________________________ | |
376 | /** | |
377 | * Set how many replicas of the output we want | |
378 | * | |
379 | * @param n Number of replicas requested | |
380 | */ | |
381 | void SetNReplica(Int_t n) { fNReplica = n; } | |
382 | /** | |
383 | * Set the ESD pass to use | |
384 | * | |
385 | * @param pass Pass number | |
386 | */ | |
387 | void SetESDPass(Int_t pass) { fESDPass = pass; } | |
388 | /** | |
389 | * Set the ESD pass to use | |
390 | * | |
391 | * @param postfix Post fix to pass number | |
392 | */ | |
393 | void SetPassPostfix(const char* postfix) { fPassPostfix = postfix; } | |
394 | //__________________________________________________________________ | |
871a9ac1 | 395 | /** |
396 | * Use GDB to wrap PROOF slaves | |
397 | * | |
398 | * @param use Whether to use GDB or not | |
399 | */ | |
400 | void SetUseGDB(Bool_t use=kTRUE) { fUseGDB = use; } | |
401 | //__________________________________________________________________ | |
1d86b7ca | 402 | /** |
403 | * Add a source file to be copied and byte compiled on slaves | |
404 | * | |
405 | * @param src Sources | |
406 | * @param addToExtra If false, do not copy | |
407 | */ | |
408 | void AddSource(const char* src, bool addToExtra=true) | |
409 | { | |
410 | fListOfSources.Add(new TObjString(src)); | |
411 | if (addToExtra) AddExtraFile(src); // Source code isn't copied! | |
412 | } | |
413 | //__________________________________________________________________ | |
414 | /** | |
415 | * Add binary data to be uploaded to slaves | |
416 | * | |
417 | * @param lib Name of binary file | |
418 | */ | |
419 | void AddLibrary(const char* lib) { fListOfLibraries.Add(new TObjString(lib));} | |
420 | //__________________________________________________________________ | |
421 | /** | |
422 | * Add a run to be analysed | |
423 | * | |
424 | * @param run Run number | |
425 | */ | |
426 | void AddRun(Int_t run) | |
427 | { | |
428 | Int_t i = fRunNumbers.fN; fRunNumbers.Set(i+1); fRunNumbers[i] = run; | |
429 | } | |
430 | //__________________________________________________________________ | |
431 | /** | |
432 | * Read run numbers from a file | |
433 | * | |
434 | * @param filename File name | |
435 | */ | |
436 | void ReadRunNumbers(const char* filename) | |
437 | { | |
438 | std::ifstream file(filename); | |
439 | if (!file) | |
440 | Fatal("ReadRunNumbers", "Cannot read from %s", filename); | |
441 | ||
442 | while (!file.eof()) { | |
443 | Int_t run; | |
444 | file >> run; | |
445 | AddRun(run); | |
446 | Char_t c; | |
447 | file >> c; | |
448 | if (file.bad()) break; | |
449 | } | |
450 | file.close(); | |
451 | } | |
452 | //__________________________________________________________________ | |
453 | /** | |
454 | * Add an extra file to be uploaded to slave | |
455 | * | |
456 | * @param file Extra file to be uploaded | |
457 | */ | |
458 | void AddExtraFile(const char* file) | |
459 | { | |
460 | if (!file || file[0] == '\0') return; | |
461 | fListOfExtras.Add(new TObjString(file)); | |
462 | } | |
463 | //__________________________________________________________________ | |
464 | /** | |
465 | * Set whether to allow overwritting existing files/directories | |
466 | * | |
467 | * @param allow If true, allow overwritting files/directories | |
468 | */ | |
469 | void SetAllowOverwrite(Bool_t allow) { fAllowOverwrite = allow; } | |
470 | //__________________________________________________________________ | |
d23503ee | 471 | /** |
472 | * Service function to make a PAR out of a script. | |
473 | * | |
474 | * The script should contain can contain a sub-class of AliAnalysisTask. | |
475 | * The script will be compiled on the slaves before loading the | |
476 | * AliAnalysisManager. Parts to (not) be compiled can be protected like | |
477 | * | |
478 | * @code | |
479 | * #ifdef BUILD_PAR | |
480 | * // This will _only_ be compiled in the servers | |
481 | * #endif | |
482 | * #ifndef BUILD_PAR | |
483 | * // This will not be compiled in the servers | |
484 | * #endif | |
485 | * @endcode | |
486 | * | |
487 | * @param script Script to upload and compile in the PAR | |
488 | * @param deps Dependency pars | |
489 | * | |
490 | * @return true on success. | |
491 | */ | |
492 | static Bool_t MakeScriptPAR(const char* script, const char* deps) | |
493 | { | |
494 | // Get the base name | |
495 | TString base(gSystem->BaseName(script)); | |
496 | Int_t idx = base.Last('.'); | |
497 | if (idx != kNPOS) base.Remove(idx); | |
498 | Bool_t retval = true; | |
499 | Info("MakeScriptPAR", "script=%s, base=%s", script, base.Data()); | |
500 | ||
501 | try { | |
502 | // Check name of script file | |
503 | TString scr(script); | |
504 | TString ext; | |
505 | if (scr.EndsWith(".C")) ext = "C"; | |
506 | else if (scr.EndsWith(".cxx")) ext = "cxx"; | |
507 | else { ext = "C"; scr.Append(".C"); } | |
508 | ||
509 | // Check if we can access the file | |
510 | TString path = TString::Format(".:%s", TROOT::GetMacroPath()); | |
511 | char* loc = gSystem->Which(path, scr); | |
512 | if (!loc) throw TString::Format("Script %s not found in %s", | |
513 | scr.Data(), path.Data()); | |
514 | TString full(loc); | |
515 | ||
516 | ||
517 | // Set-up directories | |
518 | if (gSystem->MakeDirectory(base) < 0) { | |
519 | base = ""; | |
520 | throw TString::Format("Could not make directory '%s'", base.Data()); | |
521 | } | |
522 | ||
523 | if (gSystem->MakeDirectory(Form("%s/PROOF-INF", base.Data()))) | |
524 | throw TString::Format("Could not make directory %s/PROOF-INF", | |
525 | base.Data()); | |
526 | ||
527 | // Copy the script to the setup directory | |
528 | TString dest = TString::Format("%s/%s.%s", base.Data(), | |
529 | base.Data(), ext.Data()); | |
530 | Int_t ret = gSystem->CopyFile(full, dest, true); | |
531 | switch (ret) { | |
532 | case -1: throw TString::Format("Couldn't open %s for copy", scr.Data()); | |
533 | case -2: throw TString::Format("File %s exists", dest.Data()); | |
534 | case -3: throw TString::Format("Error while copying %s", scr.Data()); | |
535 | } | |
536 | ||
537 | // Make our build file | |
538 | std::ofstream build(Form("%s/PROOF-INF/BUILD.sh", base.Data())); | |
539 | if (!build) | |
540 | throw TString::Format("Failed to open build shell script"); | |
541 | build << "#!/bin/sh\n" | |
542 | << "echo BUILD.sh@`hostname`: Building " << base << "\n" | |
543 | << "root.exe -l -b -q PROOF-INF/BUILD.C 2>&1 | tee " << base << ".log\n" | |
544 | << "echo BUILD.sh@`hostname`: done: $?\n" | |
545 | << std::endl; | |
546 | build.close(); | |
547 | if (gSystem->Chmod(Form("%s/PROOF-INF/BUILD.sh", base.Data()), 0755) != 0) | |
548 | throw TString::Format("Failed to set exectuable flags on " | |
549 | "%s/PROOF-INF/BUILD.sh", base.Data()); | |
550 | ||
551 | std::ofstream util(Form("%s/PROOF-INF/UTIL.C", base.Data())); | |
552 | if (!util) | |
553 | throw TString::Format("Failed to open utility script"); | |
554 | util << "void LoadROOTLibs() {\n" | |
555 | << " gSystem->Load(\"libVMC\");\n" | |
556 | << " gSystem->Load(\"libNet\");\n" | |
557 | << " gSystem->Load(\"libTree\");\n" | |
558 | << " gSystem->Load(\"libPhysics\");\n" | |
559 | << " gSystem->Load(\"libMinuit\");\n" | |
560 | << "}\n\n" | |
561 | << "void AddDep(const char* env) {\n" | |
562 | << " TString val(gSystem->Getenv(Form(\"%s_INCLUDE\",env)));\n" | |
563 | << " if (val.IsNull())\n" | |
564 | << " Warning(\"Add\",\"%s_INCLUDE not defined\", env);\n" | |
565 | << " else {\n" | |
566 | << " gSystem->AddIncludePath(Form(\"-I../%s\",val.Data()));\n" | |
567 | << " }\n" | |
568 | << "}\n\n" | |
569 | << "void LoadDep(const char* name) {\n" | |
570 | << " gSystem->AddDynamicPath(Form(\"../%s\",name));\n" | |
571 | << " char* full = gSystem->DynamicPathName(name,true);\n" | |
572 | << " if (!full) \n" | |
573 | << " full = gSystem->DynamicPathName(Form(\"lib%s\",name),true);\n" | |
574 | << " if (!full) \n" | |
575 | << " full = gSystem->DynamicPathName(Form(\"lib%s.so\",name),true);\n" | |
576 | << " if (!full) {\n" | |
577 | << " Warning(\"LoadDep\",\"Module %s not found\", name);\n" | |
578 | << " return;\n" | |
579 | << " }\n" | |
580 | << " gSystem->Load(full);\n" | |
581 | << "}\n" | |
582 | << std::endl; | |
583 | ||
584 | std::ofstream cbuild(Form("%s/PROOF-INF/BUILD.C", base.Data())); | |
585 | if (!cbuild) | |
586 | throw TString::Format("Failed to open build script"); | |
587 | cbuild << "void BUILD() {\n" | |
588 | << " gSystem->AddIncludePath(\"-DBUILD_PAR=1\");\n" | |
589 | << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n" | |
590 | << " LoadROOTLibs();\n"; | |
591 | TObjArray* depList = TString(deps).Tokenize(","); | |
592 | TIter next(depList); | |
593 | TObject* dep = 0; | |
594 | while ((dep = next())) { | |
595 | cbuild << " AddDep(\"" << dep->GetName() << "\");\t" | |
596 | << " LoadDep(\"" << dep->GetName() << "\");\n"; | |
597 | } | |
598 | cbuild << " // gDebug = 5;\n" | |
599 | << " int ret = gROOT->LoadMacro(\"" | |
600 | << base << "." << ext << "++g\");\n" | |
601 | << " if (ret != 0) Fatal(\"BUILD\",\"Failed to build\");\n" | |
602 | << " else Info(\"BUILD\", \"Made " << base << "\");\n" | |
603 | << "}\n" | |
604 | << std::endl; | |
605 | cbuild.close(); | |
606 | ||
607 | // Make our set-up script | |
608 | std::ofstream setup(Form("%s/PROOF-INF/SETUP.C", base.Data())); | |
609 | if (!build) | |
610 | throw TString::Format("Failed to open setup script"); | |
611 | setup << "void SETUP() {\n" | |
612 | << " gROOT->LoadMacro(\"PROOF-INF/UTIL.C\");\n" | |
613 | << " LoadROOTLibs();\n" | |
614 | << " Info(\"SETUP\",\"Loading libraries\");\n"; | |
615 | next.Reset(); | |
616 | dep = 0; | |
617 | while ((dep = next())) | |
618 | setup << " LoadDep(\"" << dep->GetName() << "\");\n"; | |
619 | setup << " gDebug = 5;\n" | |
620 | << " gSystem->Load(\"" << base << "_" << ext << ".so\");\n" | |
621 | << " gDebug = 0;\n" | |
622 | << " gROOT->ProcessLine(\".include " << base << "\");\n" | |
623 | << " gSystem->Setenv(\"" << base << "_INCLUDE\",\"" | |
624 | << base << "\");\n" | |
625 | << " Info(\"SETUP\", \"Done\");\n" | |
626 | << "}\n" | |
627 | << std::endl; | |
628 | setup.close(); | |
629 | ||
630 | ret = gSystem->Exec(Form("tar -czvf %s.par %s", base.Data(),base.Data())); | |
631 | if (ret != 0) | |
632 | throw TString::Format("Failed to create PAR file %s.PAR", base.Data()); | |
633 | } | |
634 | catch (TString& e) { | |
635 | Error("MakeScriptPAR", e.Data()); | |
636 | retval = false; | |
637 | } | |
638 | if (!base.IsNull()) | |
639 | gSystem->Exec(Form("rm -vrf %s", base.Data())); | |
640 | return retval; | |
641 | } | |
642 | //__________________________________________________________________ | |
1d86b7ca | 643 | /** |
644 | * Print the setup | |
645 | * | |
646 | */ | |
647 | void Print() const | |
648 | { | |
649 | bool mc = AliAnalysisManager::GetAnalysisManager() | |
650 | ->GetMCtruthEventHandler(); | |
651 | std::cout << fName << " train setup\n" | |
652 | << std::boolalpha | |
653 | << " ROOT version: " << fRootVersion << "\n" | |
654 | << " AliROOT version: " << fAliRootVersion << "\n" | |
655 | << " Name of proof server: " << fProofServer << "\n" | |
656 | << " Grid Input directory: " << fDataDir << "\n" | |
657 | << " Proof data set name: " << fDataSet << "\n" | |
658 | << " XML collection: " << fXML << "\n" | |
659 | << " Monte-Carlo input: " << mc << "\n" | |
660 | << " Storage replication: " << fNReplica << "\n" | |
661 | << " Run numbers: " << std::flush; | |
662 | for (Int_t i = 0; i < fRunNumbers.GetSize(); i++) | |
663 | std::cout << (i == 0 ? "" : ", ") << fRunNumbers.At(i); | |
664 | ||
665 | std::cout << "\n" | |
666 | << " PAR files: " << std::flush; | |
667 | Bool_t first = true; | |
668 | TObject* obj = 0; | |
669 | TIter nextPar(&fListOfPARs); | |
670 | while ((obj = nextPar())) { | |
671 | std::cout << (first ? "" : ", ") << obj->GetName(); | |
672 | first = false; | |
673 | } | |
674 | ||
675 | std::cout << "\n" | |
676 | << " Script sources: " << std::flush; | |
677 | first = true; | |
678 | TIter nextSrc(&fListOfSources); | |
679 | while ((obj = nextSrc())) { | |
680 | std::cout << (first ? "" : ", ") << obj->GetName(); | |
681 | first = false; | |
682 | } | |
683 | ||
684 | std::cout << "\n" | |
685 | << " Libraries to load: " << std::flush; | |
686 | first = true; | |
687 | TIter nextLib(&fListOfLibraries); | |
688 | while ((obj = nextLib())) { | |
689 | std::cout << (first ? "" : ", ") << obj->GetName(); | |
690 | first = false; | |
691 | } | |
692 | std::cout << std::noboolalpha << std::endl; | |
693 | ||
694 | AliAnalysisGrid* plugin = | |
695 | AliAnalysisManager::GetAnalysisManager()->GetGridHandler(); | |
696 | if (!plugin) return; | |
697 | ||
698 | } | |
699 | ||
700 | protected: | |
701 | //__________________________________________________________________ | |
702 | /** | |
703 | * Copy constructor | |
704 | * | |
705 | * @param o Object to copy from | |
706 | */ | |
707 | TrainSetup(const TrainSetup& o) | |
708 | : fName(o.fName), | |
709 | fRootVersion(o.fRootVersion), | |
710 | fAliRootVersion(o.fAliRootVersion), | |
711 | fProofServer(o.fProofServer), | |
712 | fDataDir(o.fDataDir), | |
713 | fDataSet(o.fDataSet), | |
714 | fXML(o.fXML), | |
715 | fRunNumbers(o.fRunNumbers), | |
716 | fListOfPARs(), | |
717 | fListOfSources(), | |
718 | fListOfLibraries(), | |
719 | fListOfExtras(), | |
720 | fNReplica(o.fNReplica), | |
721 | fESDPass(o.fESDPass) | |
722 | { | |
723 | if (isdigit(fName[0])) { | |
724 | Warning("TrainSetup", "Name starts with a digit, prepending 'a' to name"); | |
725 | fName = Form("a%s", fName.Data()); | |
726 | } | |
727 | TObject* obj = 0; | |
728 | TIter nextPar(&o.fListOfPARs); | |
729 | while ((obj = nextPar())) fListOfPARs.Add(obj->Clone()); | |
730 | TIter nextSrc(&o.fListOfSources); | |
731 | while ((obj = nextSrc())) fListOfSources.Add(obj->Clone()); | |
732 | TIter nextLib(&o.fListOfLibraries); | |
733 | while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone()); | |
734 | TIter nextExa(&o.fListOfExtras); | |
735 | while ((obj = nextExa())) fListOfExtras.Add(obj->Clone()); | |
736 | } | |
737 | //__________________________________________________________________ | |
738 | /** | |
739 | * Assignment operator | |
740 | * | |
741 | * @param o Object to assign from | |
742 | * | |
743 | * @return Reference to this object. | |
744 | */ | |
745 | TrainSetup& operator=(const TrainSetup& o) | |
746 | { | |
747 | fName = o.fName; | |
748 | fRootVersion = o.fRootVersion; | |
749 | fAliRootVersion = o.fAliRootVersion; | |
750 | fProofServer = o.fProofServer; | |
751 | fDataDir = o.fDataDir; | |
752 | fDataSet = o.fDataSet; | |
753 | fXML = o.fXML; | |
754 | fNReplica = o.fNReplica; | |
755 | fESDPass = o.fESDPass; | |
756 | fRunNumbers = o.fRunNumbers; | |
757 | TObject* obj = 0; | |
758 | TIter nextPar(&o.fListOfPARs); | |
759 | while ((obj = nextPar())) fListOfPARs.Add(obj->Clone()); | |
760 | TIter nextSrc(&o.fListOfSources); | |
761 | while ((obj = nextSrc())) fListOfSources.Add(obj->Clone()); | |
762 | TIter nextLib(&o.fListOfLibraries); | |
763 | while ((obj = nextLib())) fListOfLibraries.Add(obj->Clone()); | |
764 | TIter nextExa(&o.fListOfExtras); | |
765 | while ((obj = nextExa())) fListOfExtras.Add(obj->Clone()); | |
766 | ||
767 | return *this; | |
768 | } | |
769 | ||
770 | //__________________________________________________________________ | |
771 | /** | |
772 | * Run this analysis | |
773 | * | |
774 | * @param type Type of input for analysis (kESD, kAOD) | |
775 | * @param mode Mode of job (kLocal, kProof, kGrid) | |
776 | * @param oper Operation | |
777 | * @param nEvents Number of events to analyse (<0 means all) | |
778 | * @param mc Whether to connect MC data | |
779 | * @param usePar Whether to use PARs | |
780 | * @param dbg Debug level | |
781 | */ | |
782 | void Exec(const char* type, | |
783 | const char* mode="GRID", | |
784 | const char* oper="FULL", | |
785 | Int_t nEvents=-1, | |
786 | Bool_t mc=false, | |
787 | Bool_t usePar=false, | |
788 | Int_t dbg=0) | |
789 | { | |
790 | Info("Exec", "Doing exec with type=%s, mode=%s, oper=%s, events=%d " | |
791 | "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar); | |
792 | EType eType = ParseType(type, mc); | |
793 | EMode eMode = ParseMode(mode); | |
794 | EOper eOper = ParseOperation(oper); | |
795 | ||
796 | Exec(eType, eMode, eOper, nEvents, mc, usePar, dbg); | |
797 | } | |
798 | ||
799 | //__________________________________________________________________ | |
800 | /** | |
801 | * Run this analysis | |
802 | * | |
803 | * @param type Type of input for analysis (kESD, kAOD) | |
804 | * @param mode Mode of job (kLocal, kProof, kGrid) | |
805 | * @param oper Operation | |
806 | * @param nEvents Number of events to analyse (<0 means all) | |
807 | * @param mc Whether to connect MC data | |
808 | * @param usePar Whether to use PARs | |
809 | * @param dbg Debug level | |
810 | */ | |
811 | void Exec(EType type, | |
812 | EMode mode, | |
813 | EOper oper, | |
814 | Int_t nEvents, | |
815 | Bool_t mc, | |
816 | Bool_t usePar, | |
817 | Int_t dbg=0) | |
818 | { | |
819 | Info("Exec", "Doing exec with type=%d, mode=%d, oper=%d, events=%d " | |
820 | "mc=%d, usePar=%d", type, mode, oper, nEvents, mc, usePar); | |
821 | ||
822 | if (mode == kProof) usePar = true; | |
823 | ||
d23503ee | 824 | Info("Exec", "Connecting in mode=%d", mode); |
1d86b7ca | 825 | if (!Connect(mode)) return; |
826 | ||
827 | TString cwd = gSystem->WorkingDirectory(); | |
828 | TString nam = EscapedName(); | |
d23503ee | 829 | Info("Exec", "Current directory=%s, escaped name=%s", |
830 | cwd.Data(), nam.Data()); | |
1d86b7ca | 831 | if (oper != kTerminate) { |
832 | if (!fAllowOverwrite && !gSystem->AccessPathName(nam.Data())) { | |
833 | Error("Exec", "File/directory %s already exists", nam.Data()); | |
834 | return; | |
835 | } | |
836 | if (gSystem->AccessPathName(nam.Data())) { | |
837 | if (gSystem->MakeDirectory(nam.Data())) { | |
d23503ee | 838 | Error("Exec", "Failed to make directory '%s'", nam.Data()); |
1d86b7ca | 839 | return; |
840 | } | |
841 | } | |
842 | } | |
843 | else { | |
844 | if (gSystem->AccessPathName(nam.Data())) { | |
845 | Error("Exec", "File/directory %s does not exists", nam.Data()); | |
846 | return; | |
847 | } | |
848 | } | |
849 | ||
850 | if (!gSystem->ChangeDirectory(nam.Data())) { | |
851 | Error("Exec", "Failed to change directory to %s", nam.Data()); | |
852 | return; | |
853 | } | |
854 | Info("Exec", "Made subdirectory %s, and cd'ed there", nam.Data()); | |
855 | ||
856 | if (!LoadCommonLibraries(mode, usePar)) return; | |
857 | ||
858 | // --- Create analysis manager ----------------------------------- | |
859 | AliAnalysisManager *mgr = new AliAnalysisManager(fName,"Analysis Train"); | |
860 | ||
861 | // In test mode, collect system information on every event | |
862 | // if (oper == kTest) mgr->SetNSysInfo(1); | |
863 | if (dbg > 0) mgr->SetDebugLevel(dbg); | |
864 | if (mode == kLocal) mgr->SetUseProgressBar(kTRUE, 100); | |
865 | ||
866 | // --- ESD input handler ------------------------------------------ | |
867 | AliVEventHandler* inputHandler = CreateInputHandler(type); | |
868 | if (inputHandler) mgr->SetInputEventHandler(inputHandler); | |
869 | ||
870 | // --- Monte-Carlo ------------------------------------------------ | |
871 | AliVEventHandler* mcHandler = CreateMCHandler(type,mc); | |
872 | if (mcHandler) mgr->SetMCtruthEventHandler(mcHandler); | |
873 | ||
874 | // --- AOD output handler ----------------------------------------- | |
875 | AliVEventHandler* outputHandler = CreateOutputHandler(type); | |
876 | if (outputHandler) mgr->SetOutputEventHandler(outputHandler); | |
877 | ||
878 | // --- Include analysis macro path in search path ---------------- | |
879 | gROOT->SetMacroPath(Form("%s:%s:$ALICE_ROOT/ANALYSIS/macros", | |
880 | cwd.Data(), gROOT->GetMacroPath())); | |
881 | ||
882 | // --- Physics selction - only for ESD --------------------------- | |
883 | if (type == kESD) CreatePhysicsSelection(mc, mgr); | |
884 | ||
885 | // --- Create centrality task ------------------------------------ | |
886 | CreateCentralitySelection(mc, mgr); | |
887 | ||
888 | // --- Create tasks ---------------------------------------------- | |
889 | CreateTasks(mode, usePar, mgr); | |
890 | ||
891 | // --- Create Grid handler ---------------------------------------- | |
892 | // _must_ be done after all tasks has been added | |
893 | AliAnalysisAlien* gridHandler = CreateGridHandler(type, mode, oper); | |
894 | if (gridHandler) mgr->SetGridHandler(gridHandler); | |
895 | ||
896 | // --- Create the chain ------------------------------------------ | |
897 | TChain* chain = CreateChain(type, mode, oper, mc); | |
898 | if (mode == kLocal && !chain) { | |
899 | Error("Exec", "No chain defined in local mode!"); | |
900 | return; | |
901 | } | |
902 | ||
903 | // --- Print setup ----------------------------------------------- | |
904 | Print(); | |
36619b75 | 905 | // if (mode == kProof) { |
906 | // Info("Run", "Exported environment variables to PROOF slaves:"); | |
907 | // TProof::GetEnvVars()->ls(); | |
908 | // Info("Run", "Environment variables for this session:"); | |
909 | // gSystem->Exec("printenv"); | |
910 | // } | |
1d86b7ca | 911 | |
912 | // --- Initialise the train -------------------------------------- | |
913 | if (!mgr->InitAnalysis()) { | |
914 | gSystem->ChangeDirectory(cwd.Data()); | |
915 | Error("Run","Failed to initialise train"); | |
916 | return; | |
917 | } | |
918 | ||
919 | // --- Show status ----------------------------------------------- | |
920 | mgr->PrintStatus(); | |
921 | ||
922 | Long64_t ret = StartAnalysis(mgr, mode, chain, nEvents); | |
923 | ||
924 | // Make sure we go back | |
925 | gSystem->ChangeDirectory(cwd.Data()); | |
926 | ||
927 | if (ret < 0) Error("Exec", "Analysis failed"); | |
928 | } | |
929 | //__________________________________________________________________ | |
930 | /** | |
931 | * Start the analysis | |
932 | * | |
933 | * @param mgr Analysis manager | |
934 | * @param mode Run mode | |
935 | * @param chain Input data (local and proof only) | |
936 | * @param nEvents Number of events to analyse | |
937 | */ | |
938 | Long64_t StartAnalysis(AliAnalysisManager* mgr, | |
939 | EMode mode, | |
940 | TChain* chain, | |
941 | Int_t nEvents) | |
942 | { | |
943 | // --- Run the analysis ------------------------------------------ | |
944 | switch (mode) { | |
945 | case kLocal: | |
946 | if (!chain) { | |
947 | Error("StartAnalysis", "No chain defined"); | |
948 | return -1; | |
949 | } | |
950 | if (nEvents < 0) nEvents = chain->GetEntries(); | |
951 | return mgr->StartAnalysis(ModeString(mode), chain, nEvents); | |
952 | case kProof: | |
953 | if (fDataSet.IsNull()) { | |
954 | if (!chain) { | |
955 | Error("StartAnalysis", "No chain defined"); | |
956 | return -1; | |
957 | } | |
958 | if (nEvents < 0) nEvents = chain->GetEntries(); | |
959 | return mgr->StartAnalysis(ModeString(mode), chain, nEvents); | |
960 | } | |
961 | return mgr->StartAnalysis(ModeString(mode), fDataSet); | |
962 | case kGrid: | |
963 | if (nEvents < 0) | |
964 | return mgr->StartAnalysis(ModeString(mode)); | |
965 | return mgr->StartAnalysis(ModeString(mode), nEvents); | |
966 | } | |
967 | // We should never get here | |
968 | return -1; | |
969 | } | |
970 | //__________________________________________________________________ | |
971 | /** | |
972 | * Return the escaped name | |
973 | * | |
974 | * | |
975 | * @return Escaped name | |
976 | */ | |
977 | const TString& EscapedName() const | |
978 | { | |
979 | return fEscapedName; | |
980 | } | |
981 | //__________________________________________________________________ | |
982 | /** | |
983 | * Create a grid handler | |
984 | * | |
985 | * @param type Data type | |
986 | * @param mode Run mode | |
987 | * @param oper Operation | |
988 | * | |
989 | * @return Grid handler | |
990 | */ | |
991 | virtual AliAnalysisAlien* | |
992 | CreateGridHandler(EType type, EMode mode, EOper oper) | |
993 | { | |
994 | if (mode != kGrid) return 0; | |
995 | ||
996 | TString name = EscapedName(); | |
997 | ||
998 | // Create the plug-in object, and set run mode | |
999 | AliAnalysisAlien* plugin = new AliAnalysisAlien(); | |
1000 | plugin->SetRunMode(OperString(oper)); | |
1001 | ||
1002 | // Production mode - not used here | |
1003 | // plugin->SetProductionMode(); | |
1004 | ||
1005 | // Set output to be per run | |
1006 | plugin->SetOutputToRunNo(); | |
1007 | ||
1008 | // Set the job tag | |
1009 | plugin->SetJobTag(fName); | |
1010 | ||
1011 | // Set number of test files - used in test mode only | |
1012 | plugin->SetNtestFiles(1); | |
1013 | ||
1014 | // Set required version of software | |
1015 | plugin->SetAPIVersion(fAliEnAPIVersion); | |
1016 | plugin->SetROOTVersion(fRootVersion); | |
1017 | plugin->SetAliROOTVersion(fAliRootVersion); | |
1018 | ||
1019 | // Keep log files | |
1020 | plugin->SetKeepLogs(); | |
1021 | ||
1022 | // Declare root of input data directory | |
1023 | plugin->SetGridDataDir(fDataDir); | |
1024 | ||
1025 | // Data search patterns | |
1026 | TString pat; | |
1027 | if (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()) { | |
1028 | pat = "*/"; | |
1029 | plugin->SetRunPrefix(""); | |
1030 | } | |
1031 | else { | |
1032 | pat = Form("*ESDs/pass%d%s/*/", fESDPass, fPassPostfix.Data()); | |
1033 | plugin->SetRunPrefix("000"); | |
1034 | } | |
1035 | pat.Append(Form("*%s.root", type == kESD ? "ESDs" : "AOD")); | |
1036 | plugin->SetDataPattern(pat); | |
1037 | ||
1038 | // Add the run numbers | |
1039 | for (Int_t i = 0; i < fRunNumbers.fN; i++) { | |
1040 | if (fRunNumbers[i] < 0) continue; | |
1041 | plugin->AddRunNumber(fRunNumbers[i]); | |
1042 | } | |
1043 | ||
1044 | // Set the working directory to be the trains name (with special | |
1045 | // characters replaced by '_' and the date appended), and also set | |
1046 | // the output directory (relative to working directory) | |
1047 | plugin->SetGridWorkingDir(name.Data()); | |
1048 | plugin->SetGridOutputDir("output"); | |
1049 | ||
1050 | // Enable configured PARs | |
1051 | TIter nextPar(&fListOfPARs); | |
1052 | TObject* parName; | |
1053 | while ((parName = nextPar())) | |
1054 | plugin->EnablePackage(parName->GetName()); | |
1055 | ||
1056 | // Add sources that need to be compiled on the workers using | |
1057 | // AcLIC. | |
1058 | TString addSources = SetupSources(); | |
1059 | if (!addSources.IsNull()) plugin->SetAnalysisSource(addSources.Data()); | |
1060 | ||
1061 | // Add binary libraries that should be uploaded to the workers | |
1062 | TString addLibs = SetupLibraries(); | |
1063 | if (!addLibs.IsNull()) plugin->SetAdditionalLibs(addLibs.Data()); | |
1064 | ||
1065 | // Disable default outputs | |
1066 | plugin->SetDefaultOutputs(true); | |
1067 | ||
1068 | // Merge parameters | |
1069 | plugin->SetMaxMergeFiles(20); | |
1070 | plugin->SetMergeExcludes("AliAOD.root " | |
1071 | "*EventStat*.root " | |
1072 | "*event_stat*.root"); | |
1073 | ||
1074 | // Set number of runs per master - set to one to per run | |
1075 | plugin->SetNrunsPerMaster(1); | |
1076 | ||
1077 | // Loop over defined containers in the analysis manager, | |
1078 | // and declare these as outputs | |
1079 | TString listOfAODs = ""; | |
1080 | TString listOfHists = ""; | |
1081 | AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager(); | |
1082 | AliAnalysisDataContainer* cont = 0; | |
1083 | TIter nextCont(mgr->GetOutputs()); | |
1084 | while ((cont = static_cast<AliAnalysisDataContainer*>(nextCont()))) { | |
1085 | TString outName(cont->GetFileName()); | |
1086 | TString& list = (outName == "default" ? listOfAODs : listOfHists); | |
1087 | if (outName == "default") { | |
1088 | if (!mgr->GetOutputEventHandler()) continue; | |
1089 | ||
1090 | outName = mgr->GetOutputEventHandler()->GetOutputFileName(); | |
1091 | } | |
1092 | if (list.Contains(outName)) continue; | |
1093 | if (!list.IsNull()) list.Append(","); | |
1094 | list.Append(outName); | |
1095 | } | |
1096 | if (!mgr->GetExtraFiles().IsNull()) { | |
1097 | if (!listOfAODs.IsNull()) listOfAODs.Append("+"); | |
1098 | TString extra = mgr->GetExtraFiles(); | |
1099 | extra.ReplaceAll(" ", ","); | |
1100 | listOfAODs.Append(extra); | |
1101 | } | |
1102 | TString outArchive = Form("stderr, stdout@disk=%d", fNReplica); | |
1103 | if (!listOfHists.IsNull()) | |
1104 | outArchive.Append(Form(" hist_archive.zip:%s@disk=%d", | |
1105 | listOfHists.Data(), fNReplica)); | |
1106 | if (!listOfAODs.IsNull()) | |
1107 | outArchive.Append(Form(" aod_archive.zip:%s@disk=%d", | |
1108 | listOfAODs.Data(), fNReplica)); | |
1109 | if (listOfAODs.IsNull() && listOfHists.IsNull()) | |
1110 | Fatal("CreateGridHandler", "No outputs defined"); | |
1111 | // Disabled for now | |
1112 | // plugin->SetOutputArchive(outArchive); | |
1113 | ||
1114 | // Set name of generated analysis macro | |
1115 | plugin->SetAnalysisMacro(Form("%s.C", name.Data())); | |
1116 | ||
1117 | // Maximum number of sub-jobs | |
1118 | // plugin->SetSplitMaxInputFileNumber(25); | |
1119 | ||
1120 | // Set the Time-To-Live | |
1121 | plugin->SetTTL(70000); | |
1122 | ||
1123 | // Re-submit failed jobs as long as the ratio of failed jobs is | |
1124 | // below this percentage. | |
1125 | plugin->SetMasterResubmitThreshold(95); | |
1126 | ||
1127 | // Set the input format | |
1128 | plugin->SetInputFormat("xml-single"); | |
1129 | ||
1130 | // Set the name of the generated jdl | |
1131 | plugin->SetJDLName(Form("%s.jdl", name.Data())); | |
1132 | ||
1133 | // Set the name of the generated executable | |
1134 | plugin->SetExecutable(Form("%s.sh", name.Data())); | |
1135 | ||
1136 | // Set the job price !? | |
1137 | plugin->SetPrice(1); | |
1138 | ||
1139 | // Set whether to merge via JDL | |
1140 | plugin->SetMergeViaJDL(true); | |
1141 | ||
1142 | // Fast read otion | |
1143 | plugin->SetFastReadOption(false); | |
1144 | ||
1145 | // Whether to overwrite existing output | |
1146 | plugin->SetOverwriteMode(true); | |
1147 | ||
1148 | // Set the executable binary name and options | |
1149 | plugin->SetExecutableCommand("aliroot -b -q -x"); | |
1150 | ||
1151 | // Split by storage element - must be lower case! | |
1152 | plugin->SetSplitMode("se"); | |
1153 | ||
1154 | return plugin; | |
1155 | } | |
1156 | //__________________________________________________________________ | |
1157 | /** | |
1158 | * Create input handler | |
1159 | * | |
1160 | * @param type | |
1161 | * | |
1162 | * @return | |
1163 | */ | |
1164 | virtual AliVEventHandler* CreateInputHandler(EType type) | |
1165 | { | |
1166 | switch (type) { | |
1167 | case kESD: return new AliESDInputHandler(); | |
1168 | case kAOD: return new AliAODInputHandler(); | |
1169 | } | |
1170 | return 0; | |
1171 | } | |
1172 | //__________________________________________________________________ | |
1173 | /** | |
1174 | * Create input handler | |
1175 | * | |
1176 | * @param type Run type (ESD or AOD) | |
1177 | * @param mc Assume monte-carlo input | |
1178 | * | |
1179 | * @return | |
1180 | */ | |
1181 | virtual AliVEventHandler* CreateMCHandler(EType type, bool mc) | |
1182 | { | |
1183 | if (!mc) return 0; | |
1184 | if (type != kESD) return 0; | |
1185 | Info("CreateMCHandler", "Making MC handler"); | |
1186 | AliMCEventHandler* mcHandler = new AliMCEventHandler(); | |
1187 | mcHandler->SetReadTR(true); | |
1188 | return mcHandler; | |
1189 | } | |
1190 | //__________________________________________________________________ | |
1191 | /** | |
1192 | * Create output event handler | |
1193 | * | |
1194 | * @param type | |
1195 | * | |
1196 | * @return | |
1197 | */ | |
1198 | virtual AliVEventHandler* CreateOutputHandler(EType type) | |
1199 | { | |
1200 | AliAODHandler* ret = new AliAODHandler(); | |
1201 | switch (type) { | |
1202 | case kESD: | |
1203 | ret->SetOutputFileName("AliAOD.root"); | |
1204 | break; | |
1205 | case kAOD: | |
1206 | ret->SetOutputFileName("AliAOD.pass2.root"); | |
1207 | break; | |
1208 | } | |
1209 | return ret; | |
1210 | } | |
1211 | //__________________________________________________________________ | |
1212 | /** | |
1213 | * Create physics selection , and add to manager | |
1214 | * | |
1215 | * @param mc Whether this is for MC | |
1216 | * @param mgr Manager | |
1217 | */ | |
1218 | virtual void CreatePhysicsSelection(Bool_t mc, | |
1219 | AliAnalysisManager* mgr) | |
1220 | { | |
1221 | gROOT->Macro(Form("AddTaskPhysicsSelection.C(%d)", mc)); | |
1222 | mgr->RegisterExtraFile("event_stat.root"); | |
1223 | } | |
1224 | //__________________________________________________________________ | |
1225 | /** | |
1226 | * Create physics selection , and add to manager | |
1227 | * | |
1228 | * @param mc Whether this is for MC | |
1229 | * @param mgr Manager | |
1230 | */ | |
1231 | virtual void CreateCentralitySelection(Bool_t mc, AliAnalysisManager* mgr) | |
1232 | { | |
1233 | gROOT->Macro("AddTaskCentrality.C"); | |
1234 | AliCentralitySelectionTask* ctask = | |
1235 | dynamic_cast<AliCentralitySelectionTask*>(mgr->GetTask("CentralitySelection")); | |
1236 | if (!ctask) return; | |
d23503ee | 1237 | // ctask->SetPass(fESDPass); |
1d86b7ca | 1238 | if (mc) ctask->SetMCInput(); |
1239 | } | |
1240 | //__________________________________________________________________ | |
1241 | /** | |
1242 | * Create analysis tasks | |
1243 | * | |
1244 | * @param mode Run mode | |
1245 | * @param mgr Manager | |
1246 | * @param par Whether to use pars | |
1247 | */ | |
1248 | virtual void CreateTasks(EMode mode, Bool_t par, AliAnalysisManager* mgr)=0; | |
1249 | //__________________________________________________________________ | |
1250 | /** | |
1251 | * Connect to external services (Proof and/or grid) | |
1252 | * | |
1253 | * @param mode Running mode | |
1254 | * | |
1255 | * @return true on success | |
1256 | */ | |
1257 | virtual Bool_t Connect(EMode mode) | |
1258 | { | |
1259 | if (mode == kLocal) return true; | |
1260 | ||
1261 | // --- Set-up connections to Proof cluster and alien ------------- | |
1262 | if (mode == kProof) { | |
d23503ee | 1263 | Info("Connect", "Opening connection to proof server"); |
1d86b7ca | 1264 | // --- Find user name ------------------------------------------ |
1265 | TString userName(gSystem->Getenv("alien_API_USER")); | |
1266 | if (userName.IsNull()) { | |
1267 | userName = gSystem->GetUserInfo()->fUser; | |
1268 | Warning("Connect", | |
1269 | "environment variable 'alien_API_USER' not set, using %s", | |
1270 | userName.Data()); | |
1271 | } | |
1272 | ||
1273 | // --- Set prefered GSI method --------------------------------- | |
1274 | gEnv->SetValue("XSec.GSI.DelegProxy", "2"); | |
36619b75 | 1275 | |
1276 | // --- Figure out some server settings ------------------------- | |
1d86b7ca | 1277 | TString serv = ""; |
1278 | Bool_t lite = false; | |
1279 | if (fProofServer.BeginsWith("workers=") || fProofServer.IsNull()) { | |
1280 | lite = true; | |
1281 | serv = fProofServer; | |
1282 | } | |
1283 | else | |
1284 | serv = Form("%s@%s", userName.Data(), fProofServer.Data()); | |
36619b75 | 1285 | |
1286 | // --- Possibly debug slave sessions with GDB ------------------ | |
1287 | if (fUseGDB) { | |
1288 | TString gdbCmd("\"gdb --batch -ex run -ex bt --args\""); | |
1289 | Info("Connect", "Using GDB to wrap slaves: %s", gdbCmd.Data()); | |
1290 | TProof::AddEnvVar("PROOF_WRAPPERCMD", gdbCmd); | |
1291 | } | |
1292 | ||
1293 | // --- Add ALICE_ROOT directory to search path for packages ---- | |
d23503ee | 1294 | Info("Connect", "Set location of packages"); |
36619b75 | 1295 | gEnv->SetValue("Proof.GlobalPackageDirs", |
1296 | Form("%s:%s", | |
1297 | gEnv->GetValue("Proof.GlobalPackageDirs", "."), | |
1298 | gSystem->Getenv("ALICE_ROOT"))); | |
1299 | ||
1300 | // --- Set OADB path on workers -------------------------------- | |
1301 | const char* oadbPath = AliAnalysisManager::GetOADBPath(); | |
1302 | TProof::AddEnvVar("OADB_PATH", oadbPath); | |
1303 | // if (lite) gSystem->Setenv("OADB_PATH", oadbPath); | |
1304 | // Info("Connect", "OADB_PATH=%s", gSystem->Getenv("OADB_PATH")); | |
1305 | ||
1306 | // --- Now open connection to PROOF cluster -------------------- | |
1d86b7ca | 1307 | TProof::Open(serv); |
1308 | if (!gProof) { | |
1309 | Error("Connect", "Failed to connect to Proof cluster %s as %s", | |
1310 | fProofServer.Data(), userName.Data()); | |
1311 | return false; | |
1312 | } | |
d23503ee | 1313 | Info("Connect", "Now connected to Proof"); |
1314 | // gProof->SetParameter("PROOF_LookupOpt", "all"); | |
1d86b7ca | 1315 | if (lite) return true; |
1316 | } | |
1317 | ||
1318 | // --- Open a connection to the grid ----------------------------- | |
d23503ee | 1319 | #if 0 |
1d86b7ca | 1320 | TGrid::Connect("alien://"); |
1321 | if (!gGrid || !gGrid->IsConnected()) { | |
1322 | // This is only fatal in grid mode | |
1323 | Error("Connect", "Failed to connect to AliEN"); | |
1324 | if (mode == kGrid) return false; | |
1325 | return true; | |
1326 | } | |
1327 | if (mode == kGrid) return true; | |
1328 | ||
1329 | ||
1330 | // --- Set and make output directory ----------------------------- | |
1331 | TString name = EscapedName(); | |
1332 | TString homeDir(gGrid->GetHomeDirectory()); | |
1333 | TString workDir(homeDir); | |
1334 | workDir.Append("/"); | |
1335 | workDir.Append(name); | |
1336 | ||
1337 | // Make working directory | |
1338 | if (!gGrid->Cd(workDir)) { | |
1339 | gGrid->Cd(homeDir); | |
1340 | if (gGrid->Mkdir(workDir)) { | |
1341 | gGrid->Cd(name); | |
1342 | Info("Connect", "Directory %s created", workDir.Data()); | |
1343 | } | |
1344 | } | |
1345 | // Make output directory | |
1346 | gGrid->Mkdir("proof_output"); | |
1347 | gGrid->Cd("proof_output"); | |
d23503ee | 1348 | #endif |
1d86b7ca | 1349 | return true; |
1350 | } | |
1351 | //__________________________________________________________________ | |
1352 | /** | |
1353 | * Load common libraries | |
1354 | * | |
1355 | * @param mode Running mode | |
1356 | * @param par If true, load as PARs | |
1357 | * | |
1358 | * @return true on success | |
1359 | */ | |
1360 | Bool_t LoadCommonLibraries(EMode mode, Bool_t par) | |
1361 | { | |
1362 | if (!gSystem->Getenv("ALICE_ROOT")) { | |
1363 | Error("LoadCommonLibraries", "Local AliROOT not available"); | |
1364 | return false; | |
1365 | } | |
1366 | gSystem->Load("libTree.so"); | |
1367 | gSystem->Load("libGeom.so"); | |
1368 | gSystem->Load("libVMC.so"); | |
1369 | gSystem->Load("libPhysics.so"); | |
1370 | gSystem->Load("libMinuit.so"); | |
36619b75 | 1371 | if (mode == kProof) { |
1372 | gProof->Exec("gSystem->Load(\"libTree.so\");"); | |
1373 | gProof->Exec("gSystem->Load(\"libGeom.so\");"); | |
1374 | gProof->Exec("gSystem->Load(\"libMinuit.so\");"); | |
1375 | gProof->Exec("gSystem->Load(\"libVMC.so\");"); | |
1376 | ||
1377 | ||
1378 | } | |
1d86b7ca | 1379 | |
d23503ee | 1380 | #if 0 |
1381 | // We need to activate the workers here in case | |
1382 | // we have dynamic slaves - otherwise they won't get | |
1383 | // the packages | |
1384 | if (mode == kProof) { | |
1385 | Info("LoadCommonLibraries", "Starting slaves"); | |
1386 | if (!gProof->StartSlaves()) { | |
1387 | Error("LoadCommonLibraries", "Failed to start slaves"); | |
1388 | return false; | |
1389 | } | |
1390 | Info("LoadCommonLibraries", "Slaves started"); | |
1391 | } | |
1392 | #endif | |
1393 | ||
1d86b7ca | 1394 | Bool_t ret = true; |
1395 | Bool_t basic = mode == kGrid ? false : par; | |
1396 | ||
1397 | ret &= LoadLibrary("STEERBase", mode, basic, false); | |
1398 | ret &= LoadLibrary("ESD", mode, basic, false); | |
1399 | ret &= LoadLibrary("AOD", mode, basic, false); | |
1400 | ret &= LoadLibrary("ANALYSIS", mode, basic, true); | |
36619b75 | 1401 | ret &= LoadLibrary("OADB", mode, basic, true); |
1d86b7ca | 1402 | ret &= LoadLibrary("ANALYSISalice", mode, basic, true); |
1403 | ||
1404 | return ret; | |
1405 | } | |
1406 | //__________________________________________________________________ | |
1407 | /** | |
1408 | * Load a library | |
1409 | * | |
1410 | * @param what What library to load | |
1411 | * @param mode Mode (local, proof, grid) | |
1412 | * @param par If true, load as PAR | |
1413 | * @param rec If true, also load on slaves | |
1414 | * | |
1415 | * @return true on success | |
1416 | */ | |
1417 | Bool_t LoadLibrary(const char* what, EMode mode, Bool_t par, Bool_t rec=false) | |
1418 | { | |
1419 | if (!what || what[0] == '\0') return true; | |
1420 | ||
1421 | TString module(what); | |
1422 | TString libName(what); | |
1423 | if (!libName.BeginsWith("lib")) libName = Form("lib%s", libName.Data()); | |
1424 | if (!libName.EndsWith(".so")) libName.Append(".so"); | |
1425 | ||
1426 | Int_t ret = 0; | |
1427 | ||
1428 | switch (mode) { | |
1429 | case kLocal: // Just load and exit | |
1430 | gSystem->Load(libName.Data()); | |
1431 | break; | |
1432 | case kGrid: | |
1433 | if (par) { | |
1434 | ret = SetupPAR(what) ? 0 : -1; | |
1435 | if (rec) fListOfPARs.Add(new TObjString(what)); | |
1436 | } else { | |
1437 | ret = gSystem->Load(libName.Data()); | |
1438 | if (rec) fListOfLibraries.Add(new TObjString(libName)); | |
1439 | } | |
1440 | break; | |
1441 | case kProof: | |
d23503ee | 1442 | Info("LoadLibrary", "Uploading %s", what); |
1443 | ret = gProof->UploadPackage(what, TProof::kRemoveOld); | |
1d86b7ca | 1444 | if (ret < 0) { |
1445 | ret = gProof->UploadPackage(gSystem->ExpandPathName(Form("../%s.par", | |
1446 | what))); | |
1447 | if (ret < 0) { | |
1448 | ret = | |
1449 | gProof->UploadPackage(gSystem | |
1450 | ->ExpandPathName(Form("$ALICE_ROOT/%s.par", | |
1451 | what))); | |
1452 | if (ret < 0) { | |
1453 | Error("LoadLibrary", | |
1454 | "Could not find module %s.par in current directory nor " | |
1455 | "in $ALICE_ROOT", module.Data()); | |
1456 | return false; | |
1457 | } | |
1458 | } | |
1459 | } | |
d23503ee | 1460 | Info("LoadLibrary", "Enabling package %s", what); |
1d86b7ca | 1461 | ret = gProof->EnablePackage(what); |
1462 | break; | |
1463 | } | |
1464 | if (ret < 0) { | |
1465 | Error("LoadLibrary", "Couldn't load %s", what); | |
1466 | return false; | |
1467 | } | |
1468 | return true; | |
1469 | } | |
1470 | ||
1471 | //__________________________________________________________________ | |
1472 | Bool_t SetupPAR(const char* what) | |
1473 | { | |
1474 | if (!what || what[0] == '\0') return -1; | |
1475 | ||
1476 | TString parFile(Form("%s.par", what)); | |
1477 | if (gSystem->AccessPathName(parFile.Data())) { | |
1478 | if (gSystem->AccessPathName(Form("../%s.par", what))) { | |
1479 | // If not found | |
1480 | TString aliParFile = | |
1481 | gSystem->ExpandPathName(Form("$(ALICE_ROOT)/%s.par", what)); | |
1482 | if (gSystem->AccessPathName(aliParFile.Data())) { | |
1483 | Error("SetupPAR", "PAR file %s not found in current directory or " | |
1484 | "$(ALICE_ROOT)", what); | |
1485 | return false; | |
1486 | } | |
1487 | // Copy to current directory | |
1488 | TFile::Cp(aliParFile, parFile); | |
1489 | } | |
1490 | else | |
1491 | gSystem->Exec(Form("ln -s ../%s.par .", what)); | |
1492 | } | |
1493 | ||
1494 | // Extract archive | |
1495 | gSystem->Exec(Form("tar xvzf %s", parFile.Data())); | |
1496 | ||
1497 | // Change directory into par archive | |
1498 | TString cwd = gSystem->WorkingDirectory(); | |
1499 | ||
1500 | if (!gSystem->ChangeDirectory(what)) { | |
1501 | Error("SetupPAR", "Failed to change directory to %s", what); | |
1502 | return false; | |
1503 | } | |
1504 | ||
1505 | // Test the build | |
1506 | if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) { | |
1507 | Info("SetupPar", "Building in PAR archive %s", what); | |
1508 | if (gSystem->Exec("PROOF-INF/BUILD.sh")) { | |
1509 | Error("SetupPar", "Failed to build in PAR directory %s", what); | |
1510 | gSystem->ChangeDirectory(cwd.Data()); | |
1511 | return false; | |
1512 | } | |
1513 | } | |
1514 | ||
1515 | // Check for setup script | |
1516 | if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) { | |
1517 | Info("SetupPAR", "Setting up for PAR %s", what); | |
1518 | gROOT->Macro("PROOF-INF/SETUP.C"); | |
1519 | } | |
1520 | if (!gSystem->ChangeDirectory(cwd.Data())) return false; | |
1521 | ||
1522 | return true; | |
1523 | } | |
1524 | //__________________________________________________________________ | |
1525 | TString SetupExtras() | |
1526 | { | |
1527 | TString ret; | |
1528 | TIter next(&fListOfExtras); | |
1529 | TObjString* obj = 0; | |
1530 | while ((obj = static_cast<TObjString*>(next()))) { | |
1531 | TString path = gSystem->ExpandPathName(obj->GetName()); | |
1532 | if (!path.BeginsWith("/")) | |
1533 | // If not an absolute path, prepend to up-one | |
1534 | path = Form("../%s", path.Data()); | |
1535 | if (gSystem->AccessPathName(path.Data())) { | |
1536 | // File not accessible | |
1537 | Warning("SetupExtras", "File %s not accessible", path.Data()); | |
1538 | continue; | |
1539 | } | |
1540 | ret.Append(Form("%s ", gSystem->BaseName(obj->GetName()))); | |
1541 | gSystem->Exec(Form("ln -s %s .", path.Data())); | |
1542 | } | |
1543 | ret = ret.Strip(); | |
1544 | return ret; | |
1545 | } | |
1546 | //__________________________________________________________________ | |
1547 | TString SetupSources() | |
1548 | { | |
1549 | TString nam = EscapedName(); | |
1550 | TString ret; | |
1551 | TIter next(&fListOfSources); | |
1552 | TObject* src; | |
1553 | while ((src = next())) { | |
1554 | TString path = gSystem->ExpandPathName(src->GetName()); | |
1555 | if (!path.BeginsWith("/")) | |
1556 | // If not an absolute path, prepend to up-one | |
1557 | path = Form("../%s", path.Data()); | |
1558 | if (gSystem->AccessPathName(path.Data())) { | |
1559 | // File not accessible | |
1560 | Warning("SetupSources", "File %s not accessible", path.Data()); | |
1561 | continue; | |
1562 | } | |
1563 | ret.Append(Form("%s ", gSystem->BaseName(src->GetName()))); | |
1564 | gSystem->Exec(Form("ln -s %s .", path.Data())); | |
1565 | } | |
1566 | ret = ret.Strip(); | |
1567 | return ret; | |
1568 | } | |
1569 | //__________________________________________________________________ | |
1570 | TString SetupLibraries() | |
1571 | { | |
1572 | TString ret; | |
1573 | TIter next(&fListOfLibraries); | |
1574 | TObject* lib; | |
1575 | while ((lib = next())) { | |
1576 | ret.Append(lib->GetName()); | |
1577 | ret.Append(" "); | |
1578 | } | |
1579 | // Also add extra files to this variable | |
1580 | ret.Append(SetupExtras()); | |
1581 | ret = ret.Strip(); | |
1582 | return ret; | |
1583 | } | |
1584 | //__________________________________________________________________ | |
1585 | /** | |
1586 | * Scan directory @a dir (possibly recursive) for tree files to add | |
1587 | * to the chain. This does not follow sym-links | |
1588 | * | |
1589 | * @param dir Directory to scan | |
1590 | * @param chain Chain to add to | |
1591 | * @param type Type of tree (ESD or AOD) | |
1592 | * @param recursive Whether to scan recursively | |
1593 | * @param mc Look also for MC files if true | |
1594 | * | |
1595 | * @return true if any files where added | |
1596 | */ | |
1597 | Bool_t ScanDirectory(TSystemDirectory* dir, TChain* chain, | |
1598 | EType type, bool recursive, bool mc) | |
1599 | { | |
1600 | TString fnPattern; | |
1601 | switch (type) { | |
1602 | case kESD: fnPattern = "AliESD"; break; | |
1603 | case kAOD: fnPattern = "AliAOD"; break; | |
1604 | } | |
1605 | ||
1606 | // Assume failure | |
1607 | Bool_t ret = false; | |
1608 | ||
1609 | // Get list of files, and go back to old working directory | |
1610 | TString oldDir(gSystem->WorkingDirectory()); | |
1611 | TList* files = dir->GetListOfFiles(); | |
1612 | if (!gSystem->ChangeDirectory(oldDir)) { | |
1613 | Error("ScanDirectory", "Failed to go back to %s", oldDir.Data()); | |
1614 | return false; | |
1615 | } | |
1616 | if (!files) return false; | |
1617 | ||
1618 | TList toAdd; | |
1619 | toAdd.SetOwner(); | |
1620 | Bool_t hasGAlice = (!mc ? true : false); | |
1621 | Bool_t hasKine = (!mc ? true : false); | |
1622 | Bool_t hasTrRef = (!mc ? true : false); | |
1623 | ||
1624 | // Sort list of files and check if we should add it | |
1625 | files->Sort(); | |
1626 | TIter next(files); | |
1627 | TSystemFile* file = 0; | |
1628 | while ((file = static_cast<TSystemFile*>(next()))) { | |
1629 | TString name(file->GetName()); | |
1630 | TString title(file->GetTitle()); | |
1631 | TString full(gSystem->ConcatFileName(file->GetTitle(), name.Data())); | |
1632 | if (dynamic_cast<TSystemDirectory*>(file)) full = title; | |
1633 | // Ignore special links | |
1634 | if (name == "." || name == "..") { | |
1635 | // Info("ScanDirectory", "Ignoring %s", name.Data()); | |
1636 | continue; | |
1637 | } | |
1638 | ||
1639 | FileStat_t fs; | |
1640 | if (gSystem->GetPathInfo(full.Data(), fs)) { | |
1641 | Warning("ScanDirectory", "Cannot stat %s (%s)", full.Data(), | |
1642 | gSystem->WorkingDirectory()); | |
1643 | continue; | |
1644 | } | |
1645 | // Check if this is a directory | |
1646 | if (file->IsDirectory(full)) { | |
1647 | if (recursive) { | |
1648 | // if (title[0] == '/') | |
1649 | TSystemDirectory* d = new TSystemDirectory(file->GetName(), | |
1650 | full.Data()); | |
1651 | if (ScanDirectory(d,chain,type,recursive,mc)) | |
1652 | ret = true; | |
1653 | delete d; | |
1654 | } | |
1655 | continue; | |
1656 | } | |
1657 | ||
1658 | // If this is not a root file, ignore | |
1659 | if (!name.EndsWith(".root")) continue; | |
1660 | ||
1661 | // If this file does not contain AliESDs, ignore | |
1662 | if (!name.Contains(fnPattern)) { | |
1663 | // Info("ScanDirectory", "%s does not match pattern %s", | |
1664 | // name.Data(), fnPattern.Data()); | |
1665 | if (mc) { | |
1666 | if (name.CompareTo("galice.root") == 0) hasGAlice = true; | |
1667 | if (name.CompareTo("Kinematics.root") == 0) hasKine = true; | |
1668 | if (name.CompareTo("TrackRefs.root") == 0) hasTrRef = true; | |
1669 | } | |
1670 | continue; | |
1671 | } | |
1672 | ||
1673 | // Add | |
1674 | // Info("ScanDirectory", "Adding %s", full.Data()); | |
1675 | toAdd.Add(new TObjString(full)); | |
1676 | } | |
1677 | ||
1678 | if (mc && toAdd.GetEntries() > 0 && | |
1679 | (!hasGAlice || !hasKine || !hasTrRef)) { | |
1680 | Warning("ScanDirectory", | |
1681 | "one or more of {galice,Kinematics,TrackRefs}.root missing from " | |
1682 | "%s, not adding anything from this directory", | |
1683 | dir->GetTitle()); | |
1684 | toAdd.Delete(); | |
1685 | } | |
1686 | ||
1687 | TIter nextAdd(&toAdd); | |
1688 | TObjString* s = 0; | |
1689 | while ((s = static_cast<TObjString*>(nextAdd()))) { | |
1690 | // Info("ScanDirectory", "Adding %s", s->GetString().Data()); | |
1691 | chain->Add(s->GetString()); | |
1692 | } | |
1693 | if (toAdd.GetEntries() > 0) ret = true; | |
1694 | ||
1695 | gSystem->ChangeDirectory(oldDir); | |
1696 | return ret; | |
1697 | } | |
1698 | //__________________________________________________________________ | |
1699 | /** | |
1700 | * Create a chain from an XML containing an collection | |
1701 | * | |
1702 | * @param treeName Name of tree's | |
1703 | * @param xmlFile XML collection | |
1704 | * | |
1705 | * @return Newly allocated chain or null | |
1706 | */ | |
1707 | TChain* CreateChainFromXML(const char* treeName, | |
1708 | const char* xmlFile) | |
1709 | { | |
1710 | TGridCollection* collection = TAlienCollection::Open(xmlFile); | |
1711 | if (!collection) { | |
1712 | Error("CreateChainFromXML", "Cannot create AliEn collection from " | |
1713 | "XML file %s", xmlFile); | |
1714 | return 0; | |
1715 | } | |
1716 | ||
1717 | TChain* chain = new TChain(treeName); | |
1718 | collection->Reset(); | |
1719 | while (collection->Next()) chain->Add(collection->GetTURL("")); | |
1720 | ||
1721 | return chain; | |
1722 | } | |
1723 | //__________________________________________________________________ | |
1724 | /** | |
1725 | * Create a chain of data | |
1726 | * | |
1727 | * @param type Type of data | |
1728 | * @param mode Operation mode | |
1729 | * @param mc Assume MC input if true | |
1730 | * | |
1731 | * @return TChain of data | |
1732 | */ | |
1733 | TChain* CreateChain(EType type, EMode mode, EOper /* oper */, Bool_t mc) | |
1734 | { | |
1735 | TString treeName; | |
1736 | switch (type) { | |
1737 | case kESD: treeName = "esdTree"; break; | |
1738 | case kAOD: treeName = "aodTree"; break; | |
1739 | } | |
1740 | ||
1741 | TChain* chain = 0; | |
1742 | switch (mode) { | |
1743 | case kProof: | |
1744 | if (!fDataSet.IsNull()) break; | |
1745 | // Otherwise fall through | |
1746 | case kLocal: | |
1747 | if (fXML.IsNull()) { | |
1748 | chain = new TChain(treeName.Data()); | |
1749 | TString dir(fDataDir); | |
1750 | if (dir == ".") dir = ""; | |
1751 | if (!dir.BeginsWith("/")) dir = Form("../%s", dir.Data()); | |
1752 | TString savdir(gSystem->WorkingDirectory()); | |
1753 | TSystemDirectory d(gSystem->BaseName(dir.Data()), dir.Data()); | |
1754 | if (!ScanDirectory(&d, chain, type, true, mc)) { | |
1755 | delete chain; | |
1756 | chain = 0; | |
1757 | } | |
1758 | gSystem->ChangeDirectory(savdir); | |
1759 | } | |
1760 | else | |
1761 | chain = CreateChainFromXML(treeName.Data(), fXML.Data()); | |
1762 | break; | |
1763 | case kGrid: break; // Do nothing - we use plugin | |
1764 | } | |
1765 | ||
1766 | if (chain && chain->GetNtrees() <= 0) { | |
1767 | delete chain; | |
1768 | return 0; | |
1769 | } | |
1770 | return chain; | |
1771 | } | |
1772 | //__________________________________________________________________ | |
1773 | TString fName; // Name of analysis | |
1774 | TString fRootVersion; // ROOT version to use | |
1775 | TString fAliRootVersion; // AliROOT version to use | |
1776 | TString fAliEnAPIVersion; // AliEn API version to use | |
1777 | TString fProofServer; // Name of proof server | |
1778 | TString fDataDir; // Grid Input directory | |
1779 | TString fDataSet; // Proof data set name | |
1780 | TString fXML; // XML collection for local/proof mode | |
1781 | TArrayI fRunNumbers; // List of run number | |
1782 | TList fListOfPARs; // List of PAR files to use | |
1783 | TList fListOfSources; // List of sources to upload and AcLIC | |
1784 | TList fListOfLibraries; // List of libraries to load | |
1785 | TList fListOfExtras; // List of extra files to upload | |
1786 | Int_t fNReplica; // Storage replication | |
871a9ac1 | 1787 | Int_t fESDPass; // ESD pass number |
1d86b7ca | 1788 | TString fPassPostfix; // Possible pass postfix |
871a9ac1 | 1789 | TString fEscapedName; // Name escaped for special chars |
1790 | Bool_t fAllowOverwrite; // Allow overwriting output dir | |
1791 | Bool_t fUseGDB; // Wrap PROOF slaves in GDB | |
1d86b7ca | 1792 | }; |
1793 | ||
1794 | ||
1795 | void | |
1796 | BuildTrainSetup() | |
1797 | { | |
bd6f5206 | 1798 | gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2:" |
1d86b7ca | 1799 | "$ALICE_ROOT/ANALYSIS/macros", |
1800 | gROOT->GetMacroPath())); | |
1801 | gSystem->AddIncludePath("-I${ALICE_ROOT}/include"); | |
1802 | gSystem->Load("libRAliEn"); | |
1803 | gSystem->Load("libANALYSIS"); | |
1804 | gSystem->Load("libANALYSISalice"); | |
1805 | TString path = gSystem->Which(gROOT->GetMacroPath(), "TrainSetup.C"); | |
1806 | Info("BuildTrainSetup", "Path=%s", path.Data()); | |
1807 | TString tmp("TrainSetup"); | |
1808 | FILE* fp = gSystem->TempFileName(tmp, "."); | |
1809 | fclose(fp); | |
1810 | gSystem->Unlink(tmp); | |
1811 | tmp.Append(".C"); | |
1812 | Info("BuildTrainSetup", "Copy %s -> %s", path.Data(), tmp.Data()); | |
1813 | gSystem->CopyFile(path, tmp); | |
1814 | gROOT->LoadMacro(Form("%s+g", tmp.Data())); | |
1815 | gSystem->Unlink(tmp); | |
1816 | tmp.ReplaceAll(".C", "_C.so"); | |
1817 | gSystem->Unlink(tmp); | |
1818 | tmp.ReplaceAll("_C.so", "_C.d"); | |
1819 | gSystem->Unlink(tmp); | |
1820 | } | |
1821 | ||
1822 | ||
1823 | //____________________________________________________________________ | |
1824 | // | |
1825 | // EOF | |
1826 | // |