]>
Commit | Line | Data |
---|---|---|
a58729a5 | 1 | #include "AliMuonAccEffSubmitter.h" |
2 | ||
3 | #include "AliAnalysisTriggerScalers.h" | |
4 | #include "AliLog.h" | |
5 | #include "TFile.h" | |
6 | #include "TGrid.h" | |
7 | #include "TGridResult.h" | |
8 | #include "TMap.h" | |
9 | #include "TMath.h" | |
10 | #include "TObjString.h" | |
11 | #include "TString.h" | |
12 | #include "TSystem.h" | |
13 | #include <vector> | |
14 | ||
15 | namespace | |
16 | { | |
17 | Int_t splitLevel=10; | |
18 | } | |
19 | ||
20 | //______________________________________________________________________________ | |
21 | AliMuonAccEffSubmitter::AliMuonAccEffSubmitter() | |
22 | : TObject(), | |
23 | fScalers(0x0), | |
24 | fRemoteDir(""), | |
25 | fReferenceTrigger(""), | |
26 | fRatio(1.0), | |
27 | fMaxEventsPerChunk(5000), | |
28 | fLocalDir(gSystem->pwd()), | |
29 | fOCDBPath("raw://"), | |
30 | fTemplateDir(gSystem->ExpandPathName("$ALICE_ROOT/PWG/muondep/AccEffTemplates")), | |
31 | fPackageAliroot(), | |
32 | fPackageGeant3(), | |
33 | fPackageRoot(), | |
34 | fPackageApi(), | |
35 | fMergedDir(Form("%s/AODs",fRemoteDir.Data())), | |
36 | fSplitMaxInputFileNumber(20), | |
37 | fCompactMode(1), | |
38 | fShouldOverwriteFiles(kFALSE), | |
39 | fVars(0x0), | |
40 | fExternalConfig(""), | |
41 | fUseOCDBSnapshots(kTRUE), | |
42 | fIsValid(kFALSE), | |
43 | fTemplateFileList(0x0), | |
44 | fLocalFileList(0x0), | |
45 | fSnapshotDir(fLocalDir) | |
46 | { | |
47 | // ctor | |
48 | ||
49 | if (!TGrid::Connect("alien://")) | |
50 | { | |
51 | AliError("cannot connect to grid"); | |
52 | fIsValid = kFALSE; | |
53 | } | |
54 | ||
55 | SetPackages("VO_ALICE@AliRoot::v5-03-Rev-09","VO_ALICE@GEANT3::v1-14-6","VO_ALICE@ROOT::v5-34-02-1"); | |
56 | ||
57 | // SetVar("VAR_ENERGY","5.03"); | |
58 | SetVar("VAR_GENLIB_TYPE","AliGenMUONlib::kJpsi"); | |
59 | SetVar("VAR_GENLIB_PARNAME","\"pPb 5.03\""); | |
60 | SetVar("VAR_OCDB_PATH","\"raw://\""); | |
61 | UseOCDBSnapshots(kTRUE); | |
62 | } | |
63 | ||
64 | //______________________________________________________________________________ | |
65 | AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter() | |
66 | { | |
67 | // dtor | |
68 | delete fScalers; | |
69 | delete fTemplateFileList; | |
70 | delete fLocalFileList; | |
71 | delete fVars; | |
72 | } | |
73 | ||
74 | //______________________________________________________________________________ | |
75 | Bool_t AliMuonAccEffSubmitter::CheckLocal() const | |
76 | { | |
77 | /// Check whether all required local files are there | |
78 | TIter next(LocalFileList()); | |
79 | TObjString* file; | |
80 | ||
81 | while ( ( file = static_cast<TObjString*>(next())) ) | |
82 | { | |
83 | if ( gSystem->AccessPathName(file->String().Data()) ) | |
84 | { | |
85 | return kFALSE; | |
86 | } | |
87 | } | |
88 | ||
89 | return kTRUE; | |
90 | } | |
91 | ||
92 | //______________________________________________________________________________ | |
93 | Bool_t AliMuonAccEffSubmitter::CheckRemote() const | |
94 | { | |
95 | /// Check whether all required remote files are there | |
96 | AliWarning("implement me"); | |
97 | return kFALSE; | |
98 | } | |
99 | ||
100 | //______________________________________________________________________________ | |
101 | void AliMuonAccEffSubmitter::CleanLocal(Bool_t cleanSnapshots) const | |
102 | { | |
103 | /// Clean (remove) local generated files | |
104 | /// As OCDB snapshot creation is a long process, cleanSnapshots | |
105 | /// is kFALSE by default in order not to delete those. | |
106 | ||
107 | TIter next(LocalFileList()); | |
108 | TObjString* file; | |
109 | ||
110 | while ( ( file = static_cast<TObjString*>(next())) ) | |
111 | { | |
112 | if ( !cleanSnapshots && file->String().Contains("OCDB_") ) continue; | |
113 | gSystem->Unlink(file->String().Data()); | |
114 | } | |
115 | } | |
116 | ||
117 | //______________________________________________________________________________ | |
118 | void AliMuonAccEffSubmitter::CleanRemote() const | |
119 | { | |
120 | /// Clean (remove) remote files | |
121 | AliWarning("implement me"); | |
122 | } | |
123 | ||
124 | //______________________________________________________________________________ | |
125 | Bool_t AliMuonAccEffSubmitter::CopyFile(const char* localFile) | |
126 | { | |
127 | TString local; | |
128 | ||
129 | if ( gSystem->IsAbsoluteFileName(localFile) ) | |
130 | { | |
131 | local = localFile; | |
132 | } | |
133 | else | |
134 | { | |
135 | local = Form("%s/%s",fLocalDir.Data(),gSystem->ExpandPathName(localFile)); | |
136 | } | |
137 | ||
138 | if (gSystem->AccessPathName(local.Data())) | |
139 | { | |
140 | AliError(Form("Local file %s does not exist",local.Data())); | |
141 | return kFALSE; | |
142 | } | |
143 | ||
144 | TString remote; | |
145 | ||
146 | remote += fRemoteDir; | |
147 | remote += "/"; | |
148 | ||
149 | if ( gSystem->IsAbsoluteFileName(localFile) ) | |
150 | { | |
151 | TString tmp(localFile); | |
152 | tmp.ReplaceAll(fSnapshotDir.Data(),""); | |
153 | remote += tmp; | |
154 | } | |
155 | else | |
156 | { | |
157 | remote += localFile; | |
158 | } | |
159 | ||
160 | TString dirName = gSystem->DirName(remote.Data()); | |
161 | ||
162 | Bool_t ok(kTRUE); | |
163 | ||
164 | if (!RemoteDirectoryExists(dirName.Data())) | |
165 | { | |
166 | ok = gGrid->Mkdir(dirName.Data(),"-p"); | |
167 | } | |
168 | ||
169 | if ( ok ) | |
170 | { | |
171 | return TFile::Cp(local.Data(),Form("alien://%s",remote.Data())); | |
172 | } | |
173 | else | |
174 | { | |
175 | return kFALSE; | |
176 | } | |
177 | } | |
178 | ||
179 | //______________________________________________________________________________ | |
180 | Bool_t AliMuonAccEffSubmitter::CheckRemoteDir() const | |
181 | { | |
182 | /// Check we have a grid connection and that the remote dir exists | |
183 | ||
184 | if (fRemoteDir.IsNull()) | |
185 | { | |
186 | AliError("you must provide the grid location where to copy the files"); | |
187 | return kFALSE; | |
188 | } | |
189 | ||
190 | // connect to alien | |
191 | if (!gGrid) | |
192 | { | |
193 | if (!TGrid::Connect("alien://")) | |
194 | { | |
195 | AliError("Cannot connect to grid"); | |
196 | return kFALSE; | |
197 | } | |
198 | } | |
199 | ||
200 | if (!RemoteDirectoryExists(fRemoteDir)) | |
201 | { | |
202 | AliError(Form("directory %s does not exist", fRemoteDir.Data())); | |
203 | return kFALSE; | |
204 | } | |
205 | ||
206 | return kTRUE; | |
207 | } | |
208 | ||
209 | //______________________________________________________________________________ | |
210 | Bool_t AliMuonAccEffSubmitter::CopyLocalFilesToRemote() | |
211 | { | |
212 | /// copy all files necessary to run the simulation into remote directory | |
213 | ||
214 | if (!IsValid()) return kFALSE; | |
215 | ||
216 | if ( CheckRemoteDir() ) | |
217 | { | |
218 | TString sdir(gSystem->ExpandPathName(LocalDir())); | |
219 | ||
220 | TIter next(LocalFileList()); | |
221 | TObjString* ftc; | |
222 | ||
223 | Bool_t allok(kTRUE); | |
224 | ||
225 | while ( ( ftc = static_cast<TObjString*>(next())) ) | |
226 | { | |
227 | allok = allok && CopyFile(ftc->String()); | |
228 | } | |
229 | return allok; | |
230 | } | |
231 | ||
232 | return kFALSE; | |
233 | } | |
234 | ||
235 | //______________________________________________________________________________ | |
236 | Bool_t AliMuonAccEffSubmitter::CopyTemplateFilesToLocal() | |
237 | { | |
238 | // copy (or generate) local files from the template ones | |
239 | ||
240 | if (!IsValid()) return kFALSE; | |
241 | ||
242 | TIter next(TemplateFileList()); | |
243 | TObjString* file; | |
244 | ||
245 | Int_t err(0); | |
246 | Bool_t potentialProblem(kFALSE); | |
247 | ||
248 | while ( ( file = static_cast<TObjString*>(next())) ) | |
249 | { | |
250 | if ( file->String().Contains("OCDB") ) | |
251 | { | |
252 | /// OCDB snapshots are not in template | |
253 | continue; | |
254 | } | |
255 | ||
256 | if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(file->String().Data()) ) | |
257 | { | |
258 | AliError(Form("Local file %s already exists. Remove it first if you want to update overwrite it",file->String().Data())); | |
259 | potentialProblem = kTRUE; | |
260 | } | |
261 | else | |
262 | { | |
263 | TString stemplate(Form("%s/%s",fTemplateDir.Data(),file->String().Data())); | |
264 | TString slocal(Form("%s/%s",fLocalDir.Data(),file->String().Data())); | |
265 | ||
266 | Int_t c = gSystem->CopyFile(stemplate.Data(),slocal.Data(),ShouldOverwriteFiles()); | |
267 | if ( c ) | |
268 | { | |
269 | Bool_t ok(kFALSE); | |
270 | if ( stemplate.Contains(".jdl",TString::kIgnoreCase) ) | |
271 | { | |
272 | if ( stemplate.Contains("merge",TString::kIgnoreCase) ) | |
273 | { | |
274 | ok = GenerateMergeJDL(file->String().Data()); | |
275 | } | |
276 | else | |
277 | { | |
278 | ok = GenerateRunJDL(file->String().Data()); | |
279 | } | |
280 | } | |
281 | if (!ok) | |
282 | { | |
283 | AliError(Form("Error %d copying file %s",c,stemplate.Data())); | |
284 | } | |
285 | else | |
286 | { | |
287 | c=0; | |
288 | } | |
289 | } | |
290 | else | |
291 | { | |
292 | if ( HasVars(slocal.Data()) ) | |
293 | { | |
294 | if (!ReplaceVars(slocal.Data())) | |
295 | { | |
296 | AliError("pb in ReplaceVars"); | |
297 | c=1; | |
298 | } | |
299 | } | |
300 | } | |
301 | err += c; | |
302 | } | |
303 | } | |
304 | ||
305 | if ( potentialProblem ) | |
306 | { | |
307 | AliWarning("At least one local file could not be overwritten. Cross-check that the local files are OK before we try to upload them to the Grid !"); | |
308 | return kFALSE; | |
309 | } | |
310 | return (err==0); | |
311 | } | |
312 | ||
313 | //______________________________________________________________________________ | |
314 | std::ostream* AliMuonAccEffSubmitter::CreateJDLFile(const char* name) const | |
315 | { | |
316 | TString jdl(Form("%s/%s",fLocalDir.Data(),name)); | |
317 | ||
318 | if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(jdl.Data()) ) | |
319 | { | |
320 | AliError(Form("File %s already exists. Remove it if you want to overwrite it",jdl.Data())); | |
321 | return 0x0; | |
322 | } | |
323 | ||
324 | std::ofstream* os = new std::ofstream(gSystem->ExpandPathName(jdl.Data())); | |
325 | ||
326 | if (os->bad()) | |
327 | { | |
328 | AliError(Form("Cannot create file %s",jdl.Data())); | |
329 | delete os; | |
330 | os=0x0; | |
331 | } | |
332 | ||
333 | return os; | |
334 | } | |
335 | ||
336 | ///______________________________________________________________________________ | |
337 | Bool_t AliMuonAccEffSubmitter::GenerateMergeJDL(const char* name) | |
338 | { | |
339 | std::ostream* os = CreateJDLFile(name); | |
340 | ||
341 | if (!os) | |
342 | { | |
343 | return kFALSE; | |
344 | } | |
345 | ||
346 | Bool_t final = TString(name).Contains("merge",TString::kIgnoreCase); | |
347 | ||
348 | (*os) << "# Generated merging jdl (production mode)" << std::endl | |
349 | << "# $1 = run number" << std::endl | |
350 | << "# $2 = merging stage" << std::endl | |
351 | << "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*root_archive.zip" << std::endl; | |
352 | ||
353 | Output(*os,"Packages",fPackageAliroot.Data(),fPackageGeant3.Data(), | |
354 | fPackageRoot.Data(),fPackageApi.Data()); | |
355 | ||
356 | Output(*os,"Executable","AOD_merge.sh"); | |
357 | ||
358 | Output(*os,"Price","1"); | |
359 | ||
360 | if ( final ) | |
361 | { | |
362 | Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter final merging"); | |
363 | } | |
364 | else | |
365 | { | |
366 | Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter merging stage $2"); | |
367 | } | |
368 | ||
369 | Output(*os,"Workdirectorysize","5000MB"); | |
370 | ||
371 | Output(*os,"Validationcommand",Form("%s/validation_merge.sh",fRemoteDir.Data())); | |
372 | ||
373 | Output(*os,"TTL","7200"); | |
374 | ||
375 | Output(*os,"OutputArchive", | |
376 | "log_archive.zip:stderr,stdout@disk=1", | |
377 | "root_archive.zip:AliAOD.root,AliAOD.Muons.root,AnalysisResults.root@disk=3" | |
378 | ); | |
379 | ||
380 | Output(*os,"Arguments",(final ? "2":"1")); // for AOD_merge.sh, 1 means intermediate merging stage, 2 means final merging | |
381 | ||
382 | if ( !final ) | |
383 | { | |
384 | Output(*os,"InputFile",Form("LF:%s/AODtrain.C",fRemoteDir.Data())); | |
385 | Output(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",fRemoteDir.Data())); | |
386 | Output(*os,"InputDataCollection",Form("%s/$1/Stage_$2.xml,nodownload",fRemoteDir.Data())); | |
387 | Output(*os,"split","se"); | |
388 | Output(*os,"SplitMaxInputFileNumber",GetSplitMaxInputFileNumber()); | |
389 | Output(*os,"InputDataListFormat","xml-single"); | |
390 | Output(*os,"InputDataList","wn.xml"); | |
391 | } | |
392 | else | |
393 | { | |
394 | Output(*os,"InputFile",Form("LF:%s/AODtrain.C",fRemoteDir.Data()), | |
395 | Form("LF:%s/$1/wn.xml",fRemoteDir.Data())); | |
396 | Output(*os,"OutputDir",Form("%s/$1",fRemoteDir.Data())); | |
397 | } | |
398 | ||
399 | return kTRUE; | |
400 | } | |
401 | ||
402 | //______________________________________________________________________________ | |
403 | Bool_t AliMuonAccEffSubmitter::GenerateRunJDL(const char* name) | |
404 | { | |
405 | /// Generate (locally) the JDL to perform the simulation+reco+aod filtering | |
406 | /// (to be then copied to the grid and finally submitted) | |
407 | ||
408 | std::ostream* os = CreateJDLFile(name); | |
409 | ||
410 | if (!os) | |
411 | { | |
412 | return kFALSE; | |
413 | } | |
414 | ||
415 | Output(*os,"Packages",fPackageAliroot.Data(),fPackageGeant3.Data(), | |
416 | fPackageRoot.Data(),fPackageApi.Data()); | |
417 | ||
418 | Output(*os,"Jobtag","comment: AliMuonAccEffSubmitter RUN $1"); | |
419 | ||
420 | Output(*os,"split","production:1-$2"); | |
421 | ||
422 | Output(*os,"Price","1"); | |
423 | ||
424 | Output(*os,"OutputDir",Form("%s/$1/#alien_counter_03i#",fRemoteDir.Data())); | |
425 | ||
426 | Output(*os,"Executable","/alice/bin/aliroot_new"); | |
427 | ||
428 | TObjArray files; | |
429 | files.SetOwner(kTRUE); | |
430 | TIter next(TemplateFileList()); | |
431 | TObjString* file; | |
432 | ||
433 | while ( ( file = static_cast<TObjString*>(next())) ) | |
434 | { | |
435 | if ( !file->String().Contains(".jdl",TString::kIgnoreCase) || | |
436 | !file->String().Contains("OCDB_") ) | |
437 | { | |
438 | files.Add(new TObjString(Form("LF:%s/%s",fRemoteDir.Data(),file->String().Data()))); | |
439 | } | |
440 | } | |
441 | ||
442 | if ( fUseOCDBSnapshots ) | |
443 | { | |
444 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_sim.root",fRemoteDir.Data()))); | |
445 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_rec.root",fRemoteDir.Data()))); | |
446 | } | |
447 | ||
448 | Output(*os,"InputFile",files); | |
449 | ||
450 | if ( CompactMode() == 0 ) | |
451 | { | |
452 | // store everything | |
453 | Output(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,recwatch.log,sim.log,simwatch.log@disk=1", | |
454 | "root_archive.zip:galice*.root,Kinematics*.root,TrackRefs*.root,AliESDs.root,AliAOD.root,AliAOD.Muons.root,Merged.QA.Data.root,Run*.root@disk=2"); | |
455 | } | |
456 | else if ( CompactMode() == 1 ) | |
457 | { | |
458 | // keep only muon AODs | |
459 | Output(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1", | |
460 | "root_archive.zip:galice*.root,AliAOD.Muons.root@disk=2"); | |
461 | } | |
462 | else | |
463 | { | |
464 | AliError(Form("Unknown CompactMode %d",CompactMode())); | |
465 | delete os; | |
466 | return kFALSE; | |
467 | } | |
468 | ||
469 | Output(*os,"splitarguments","simrun.C --run $1 --chunk #alien_counter# --event $3"); | |
470 | ||
471 | Output(*os,"Workdirectorysize","5000MB"); | |
472 | ||
473 | Output(*os,"JDLVariables","Packages","OutputDir"); | |
474 | ||
475 | Output(*os,"Validationcommand",Form("%s/validation.sh",fRemoteDir.Data())); | |
476 | ||
477 | Output(*os,"TTL","72000"); | |
478 | ||
479 | return kTRUE; | |
480 | } | |
481 | ||
482 | //______________________________________________________________________________ | |
483 | Bool_t AliMuonAccEffSubmitter::GetLastStage(const char* remoteDir) const | |
484 | { | |
485 | Int_t n = 0, lastStage = 0; | |
486 | gSystem->Exec(Form("alien_ls -F %s | grep Stage_.*/ > __stage__", remoteDir)); | |
487 | ifstream f("__stage__"); | |
488 | std::string dummy; | |
489 | while (std::getline(f, dummy)) n++; | |
490 | f.close(); | |
491 | while (n > 0) if (gSystem->Exec(Form("grep Stage_%d/ __stage__ 2>&1 >/dev/null", ++lastStage)) == 0) n--; | |
492 | gSystem->Exec("rm -f __stage__"); | |
493 | return lastStage; | |
494 | } | |
495 | ||
496 | //______________________________________________________________________________ | |
497 | Bool_t AliMuonAccEffSubmitter::HasVars(const char* file) const | |
498 | { | |
499 | /// Whether or not the file contains variables that have to | |
500 | /// be substituted | |
501 | ||
502 | std::ifstream in(file); | |
503 | char line[1024]; | |
504 | while ( in.getline(line,1023,'\n') ) | |
505 | { | |
506 | TString sline(line); | |
507 | if (sline.Contains("VAR_") && !sline.BeginsWith("//") ) | |
508 | { | |
509 | return kTRUE; | |
510 | } | |
511 | } | |
512 | return kFALSE; | |
513 | } | |
514 | ||
515 | //______________________________________________________________________________ | |
516 | TObjArray* AliMuonAccEffSubmitter::LocalFileList() const | |
517 | { | |
518 | /// Return (after createing and filling it if needed) | |
519 | /// the internal file list with paths from the local directory | |
520 | ||
521 | if (!fLocalFileList) | |
522 | { | |
523 | fLocalFileList = static_cast<TObjArray*>(TemplateFileList()->Clone()); | |
524 | } | |
525 | ||
526 | return fLocalFileList; | |
527 | } | |
528 | ||
529 | //______________________________________________________________________________ | |
530 | Bool_t AliMuonAccEffSubmitter::MakeOCDBSnapshots() | |
531 | { | |
532 | /// Run sim.C and rec.C in a special mode to generate OCDB snapshots | |
533 | /// Can only be done after the templates have been copied locally | |
534 | ||
535 | if (!IsValid()) return kFALSE; | |
536 | ||
537 | if (!fUseOCDBSnapshots) return kTRUE; | |
538 | ||
539 | if (!fScalers) return kFALSE; | |
540 | ||
541 | const std::vector<int>& runs = fScalers->GetRunList(); | |
542 | ||
543 | Bool_t ok(kTRUE); | |
544 | ||
545 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
546 | { | |
547 | Int_t runNumber = runs[i]; | |
548 | ||
549 | TString ocdbSim(Form("%s/OCDB/%d/OCDB_sim.root",SnapshotDir().Data(),runNumber)); | |
550 | TString ocdbRec(Form("%s/OCDB/%d/OCDB_rec.root",SnapshotDir().Data(),runNumber)); | |
551 | ||
552 | if ( !gSystem->AccessPathName(ocdbSim.Data()) && | |
553 | !gSystem->AccessPathName(ocdbRec.Data()) ) | |
554 | { | |
555 | AliWarning(Form("Local OCDB snapshots already there for run %d. Will not redo them. If you want to force them, delete them by hand !",runNumber)); | |
556 | } | |
557 | else | |
558 | { | |
559 | gSystem->Exec(Form("aliroot -b -q -x simrun.C --run %d --snapshot",runNumber)); | |
560 | ||
561 | if ( gSystem->AccessPathName(ocdbSim.Data()) ) | |
562 | { | |
563 | AliError(Form("Could not create OCDB snapshot for simulation")); | |
564 | ok = kFALSE; | |
565 | } | |
566 | ||
567 | if ( gSystem->AccessPathName(ocdbRec.Data()) ) | |
568 | { | |
569 | AliError(Form("Could not create OCDB snapshot for reconstruction")); | |
570 | ok = kFALSE; | |
571 | } | |
572 | } | |
573 | ||
574 | LocalFileList()->Add(new TObjString(ocdbSim)); | |
575 | LocalFileList()->Add(new TObjString(ocdbRec)); | |
576 | } | |
577 | ||
578 | return ok; | |
579 | } | |
580 | ||
581 | //______________________________________________________________________________ | |
582 | Bool_t AliMuonAccEffSubmitter::Merge(Int_t stage, Bool_t dryRun) | |
583 | { | |
584 | /// Submit multiple merging jobs with the format "submit AOD_merge(_final).jdl run# (stage#)". | |
585 | /// Also produce the xml collection before sending jobs | |
586 | /// Initial AODs will be taken from fRemoteDir/[RUNNUMBER] while the merged | |
587 | /// ones will be put into fMergedDir/AODs/[RUNNUMBER] | |
588 | /// | |
589 | /// Example: | |
590 | /// - inDir = "/alice/sim/2012/LHC12a10_bis" (where to find the data to merge) | |
591 | /// = 0x0 --> inDir = homeDir/outDir/resDir | |
592 | /// - outDir = "Sim/LHC11h/embedding/AODs" (where to store merged results) | |
593 | /// - runList.txt must contains the list of run number | |
594 | /// - stage=0 --> final merging / stage>0 --> intermediate merging i | |
595 | /// | |
596 | ||
597 | if (!RemoteDirectoryExists(fMergedDir.Data())) { | |
598 | AliError(Form("directory %s does not exist", fMergedDir.Data())); | |
599 | return kFALSE; | |
600 | } | |
601 | ||
602 | gGrid->Cd(fMergedDir.Data()); | |
603 | ||
604 | TString jdl = MergeJDLName(stage==0); | |
605 | ||
606 | if (!RemoteFileExists(jdl.Data())) | |
607 | { | |
608 | AliError(Form("file %s does not exist in %s\n", jdl.Data(), fRemoteDir.Data())); | |
609 | return kFALSE; | |
610 | } | |
611 | ||
612 | const std::vector<int>& runs = fScalers->GetRunList(); | |
613 | ||
614 | if (runs.empty()) | |
615 | { | |
616 | AliError("No run to work with"); | |
617 | return kFALSE; | |
618 | } | |
619 | ||
620 | TString currRun; | |
621 | TString reply = ""; | |
622 | gSystem->Exec("rm -f __failed__"); | |
623 | Bool_t failedRun = kFALSE; | |
624 | ||
625 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
626 | { | |
627 | Int_t run = runs[i]; | |
628 | AliInfo(Form("\n --- processing run %d ---\n", run)); | |
629 | ||
630 | TString runDir = Form("%s/%d", fMergedDir.Data(), run); | |
631 | ||
632 | if (!RemoteDirectoryExists(runDir.Data())) | |
633 | { | |
634 | AliInfo(Form(" - creating output directory %s\n", runDir.Data())); | |
635 | gSystem->Exec(Form("alien_mkdir -p %s", runDir.Data())); | |
636 | } | |
637 | ||
638 | if (RemoteFileExists(Form("%s/root_archive.zip", runDir.Data()))) | |
639 | { | |
640 | AliWarning(" ! final merging already done"); | |
641 | continue; | |
642 | } | |
643 | ||
644 | Int_t lastStage = GetLastStage(runDir.Data()); | |
645 | ||
646 | if (stage > 0 && stage != lastStage+1) | |
647 | { | |
648 | AliError(Form(" ! lastest merging stage = %d. Next must be stage %d or final stage\n", lastStage, lastStage+1)); | |
649 | continue; | |
650 | } | |
651 | ||
652 | TString wn = (stage > 0) ? Form("Stage_%d.xml", stage) : "wn.xml"; | |
653 | TString find = (lastStage == 0) ? | |
654 | Form("alien_find -x %s %s/%d *root_archive.zip", wn.Data(), fRemoteDir.Data(), run) : | |
655 | Form("alien_find -x %s %s/%d/Stage_%d *root_archive.zip", wn.Data(), fRemoteDir.Data(), run, lastStage); | |
656 | gSystem->Exec(Form("%s 1> %s 2>/dev/null", find.Data(), wn.Data())); | |
657 | gSystem->Exec(Form("grep -c /event %s > __nfiles__", wn.Data())); | |
658 | ifstream f2("__nfiles__"); | |
659 | TString nFiles; | |
660 | nFiles.ReadLine(f2,kTRUE); | |
661 | f2.close(); | |
662 | gSystem->Exec("rm -f __nfiles__"); | |
663 | printf(" - number of files to merge = %d\n", nFiles.Atoi()); | |
664 | if (nFiles.Atoi() == 0) { | |
665 | printf(" ! collection of files to merge is empty\n"); | |
666 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
667 | continue; | |
668 | } else if (stage > 0 && nFiles.Atoi() <= splitLevel && !reply.BeginsWith("y")) { | |
669 | if (!reply.BeginsWith("n")) { | |
670 | printf(" ! number of files to merge <= split level (%d). Continue? [Y/n] ", splitLevel); | |
671 | fflush(stdout); | |
672 | reply.Gets(stdin,kTRUE); | |
673 | reply.ToLower(); | |
674 | } | |
675 | if (reply.BeginsWith("n")) { | |
676 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
677 | continue; | |
678 | } else reply = "y"; | |
679 | } | |
680 | ||
681 | if (!dryRun) | |
682 | { | |
683 | TString dirwn = Form("%s/%s", runDir.Data(), wn.Data()); | |
684 | if (RemoteFileExists(dirwn.Data())) gGrid->Rm(dirwn.Data()); | |
685 | gSystem->Exec(Form("alien_cp file:%s alien://%s", wn.Data(), dirwn.Data())); | |
686 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
687 | } | |
688 | ||
689 | TString query; | |
690 | if (stage > 0) query = Form("submit %s %d %d", jdl.Data(), run, stage); | |
691 | else query = Form("submit %s %d", jdl.Data(), run); | |
692 | printf(" - %s ...", query.Data()); | |
693 | fflush(stdout); | |
694 | ||
695 | if (dryRun) | |
696 | { | |
697 | AliInfo(" dry run"); | |
698 | continue; | |
699 | } | |
700 | ||
701 | Bool_t done = kFALSE; | |
702 | TGridResult *res = gGrid->Command(query); | |
703 | if (res) | |
704 | { | |
705 | TString cjobId1 = res->GetKey(0,"jobId"); | |
706 | if (!cjobId1.IsDec()) | |
707 | { | |
708 | AliError(" FAILED"); | |
709 | gGrid->Stdout(); | |
710 | gGrid->Stderr(); | |
711 | } | |
712 | else | |
713 | { | |
714 | AliInfo(Form(" DONE\n --> the job Id is: %s \n", cjobId1.Data())); | |
715 | done = kTRUE; | |
716 | } | |
717 | delete res; | |
718 | } | |
719 | else | |
720 | { | |
721 | AliError(" FAILED"); | |
722 | } | |
723 | ||
724 | if (!done) | |
725 | { | |
726 | gSystem->Exec(Form("echo %d >> __failed__", run)); | |
727 | failedRun = kTRUE; | |
728 | } | |
729 | ||
730 | } | |
731 | ||
732 | if (failedRun) | |
733 | { | |
734 | AliInfo("\n--------------------\n"); | |
735 | AliInfo("list of failed runs:\n"); | |
736 | gSystem->Exec("cat __failed__"); | |
737 | gSystem->Exec("rm -f __failed__"); | |
738 | return kFALSE; | |
739 | } | |
740 | ||
741 | return kTRUE; | |
742 | } | |
743 | ||
744 | //______________________________________________________________________________ | |
745 | UInt_t AliMuonAccEffSubmitter::NofRuns() const | |
746 | { | |
747 | // number of runs we're dealing with | |
748 | if (!fScalers) return 0; | |
749 | ||
750 | return fScalers->GetRunList().size(); | |
751 | } | |
752 | ||
753 | //______________________________________________________________________________ | |
754 | void AliMuonAccEffSubmitter::Output(std::ostream& out, const char* key, | |
755 | const TObjArray& values) const | |
756 | { | |
757 | out << key << " = "; | |
758 | ||
759 | Int_t n = values.GetEntries(); | |
760 | ||
761 | if ( n > 1 ) | |
762 | { | |
763 | out << "{" << std::endl; | |
764 | TIter next(&values); | |
765 | TObjString* v; | |
766 | ||
767 | while ( ( v = static_cast<TObjString*>(next())) ) | |
768 | { | |
769 | --n; | |
770 | out << "\t\"" << v->String().Data() << "\""; | |
771 | if ( n ) out << ","; | |
772 | out << std::endl; | |
773 | } | |
774 | out << "}"; | |
775 | } | |
776 | else | |
777 | { | |
778 | TString& v1 = static_cast<TObjString*>(values.At(0))->String(); | |
779 | ||
780 | if ( v1.IsDigit() ) | |
781 | { | |
782 | out << v1.Atoi(); | |
783 | } | |
784 | else | |
785 | { | |
786 | out << "\"" << v1.Data() << "\""; | |
787 | } | |
788 | } | |
789 | out << ";" << std::endl; | |
790 | } | |
791 | ||
792 | //______________________________________________________________________________ | |
793 | void AliMuonAccEffSubmitter::Output(std::ostream& out, const char* key, const char* v1, | |
794 | const char* v2, const char* v3, const char* v4, | |
795 | const char* v5, const char* v6, const char* v7, | |
796 | const char* v8, const char* v9) const | |
797 | { | |
798 | TObjArray values; | |
799 | values.SetOwner(kTRUE); | |
800 | ||
801 | values.Add(new TObjString(v1)); | |
802 | if ( strlen(v2) > 0 ) values.Add(new TObjString(v2)); | |
803 | if ( strlen(v3) > 0 ) values.Add(new TObjString(v3)); | |
804 | if ( strlen(v4) > 0 ) values.Add(new TObjString(v4)); | |
805 | if ( strlen(v5) > 0 ) values.Add(new TObjString(v5)); | |
806 | if ( strlen(v6) > 0 ) values.Add(new TObjString(v6)); | |
807 | if ( strlen(v7) > 0 ) values.Add(new TObjString(v7)); | |
808 | if ( strlen(v8) > 0 ) values.Add(new TObjString(v8)); | |
809 | if ( strlen(v9) > 0 ) values.Add(new TObjString(v9)); | |
810 | ||
811 | Output(out,key,values); | |
812 | } | |
813 | ||
814 | ||
815 | //______________________________________________________________________________ | |
816 | void AliMuonAccEffSubmitter::Print(Option_t* /*opt*/) const | |
817 | { | |
818 | if (!IsValid()) | |
819 | { | |
820 | std::cout << std::string(80,'*') << std::endl; | |
821 | std::cout << "INVALID OBJECT. CHECK BELOW THE CONFIGURATION." << std::endl; | |
822 | std::cout << std::string(80,'*') << std::endl; | |
823 | } | |
824 | ||
825 | std::cout << "Template directory = " << fTemplateDir.Data() << std::endl; | |
826 | std::cout << "Local directory = " << fLocalDir.Data() << std::endl; | |
827 | std::cout << "Remote directory = " << fRemoteDir.Data() << std::endl; | |
828 | ||
829 | std::cout << "OCDB path = " << fOCDBPath.Data() << std::endl; | |
830 | ||
831 | if ( fRatio > 0 ) | |
832 | { | |
833 | std::cout << Form("For each run, will generate %5.2f times the number of real events for trigger %s", | |
834 | fRatio,fReferenceTrigger.Data()) << std::endl; | |
835 | } | |
836 | else | |
837 | { | |
838 | std::cout << Form("For each run, will generate %10d events",fFixedNofEvents) << std::endl; | |
839 | } | |
840 | ||
841 | std::cout << "MaxEventsPerChunk = " << fMaxEventsPerChunk << std::endl; | |
842 | ||
843 | if ( NofRuns() ) | |
844 | { | |
845 | std::cout << NofRuns() << " run"; | |
846 | if ( NofRuns() > 1 ) std::cout << "s"; | |
847 | std::cout << " = "; | |
848 | fScalers->Print(); | |
849 | } | |
850 | ||
851 | if ( fVars ) | |
852 | { | |
853 | TIter next(fVars); | |
854 | TObjString* key; | |
855 | while ( ( key = static_cast<TObjString*>(next())) ) | |
856 | { | |
857 | TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String())); | |
858 | std::cout << "Variable " << key->String() << " will be replaced by " << value->String() << std::endl; | |
859 | } | |
860 | } | |
861 | ||
862 | std::cout << "Files to be uploaded:" << std::endl; | |
863 | TIter nextFile(LocalFileList()); | |
864 | TObjString* sfile; | |
865 | while ( ( sfile = static_cast<TObjString*>(nextFile())) ) | |
866 | { | |
867 | std::cout << sfile->String().Data() << std::endl; | |
868 | } | |
869 | } | |
870 | ||
871 | ||
872 | //______________________________________________________________________________ | |
873 | Bool_t AliMuonAccEffSubmitter::RemoteDirectoryExists(const char *dirname) const | |
874 | { | |
875 | // Returns true if directory exists. Can be also a path. | |
876 | if (!gGrid) return kFALSE; | |
877 | // Check if dirname is a path | |
878 | TString dirstripped = dirname; | |
879 | dirstripped = dirstripped.Strip(); | |
880 | dirstripped = dirstripped.Strip(TString::kTrailing, '/'); | |
881 | TString dir = gSystem->BaseName(dirstripped); | |
882 | dir += "/"; | |
883 | TString path = gSystem->DirName(dirstripped); | |
884 | TGridResult *res = gGrid->Ls(path, "-F"); | |
885 | if (!res) return kFALSE; | |
886 | TIter next(res); | |
887 | TMap *map; | |
888 | TObject *obj; | |
889 | while ((map=dynamic_cast<TMap*>(next()))) { | |
890 | obj = map->GetValue("name"); | |
891 | if (!obj) break; | |
892 | if (dir == obj->GetName()) { | |
893 | delete res; | |
894 | return kTRUE; | |
895 | } | |
896 | } | |
897 | delete res; | |
898 | return kFALSE; | |
899 | } | |
900 | ||
901 | //______________________________________________________________________________ | |
902 | Bool_t AliMuonAccEffSubmitter::RemoteFileExists(const char *lfn) const | |
903 | { | |
904 | // Returns true if file exists. | |
905 | if (!gGrid) return kFALSE; | |
906 | TGridResult *res = gGrid->Ls(lfn); | |
907 | if (!res) return kFALSE; | |
908 | TMap *map = dynamic_cast<TMap*>(res->At(0)); | |
909 | if (!map) { | |
910 | delete res; | |
911 | return kFALSE; | |
912 | } | |
913 | TObjString *objs = dynamic_cast<TObjString*>(map->GetValue("name")); | |
914 | if (!objs || !objs->GetString().Length()) { | |
915 | delete res; | |
916 | return kFALSE; | |
917 | } | |
918 | delete res; | |
919 | return kTRUE; | |
920 | } | |
921 | ||
922 | //______________________________________________________________________________ | |
923 | Bool_t AliMuonAccEffSubmitter::ReplaceVars(const char* file) | |
924 | { | |
925 | std::ifstream in(file); | |
926 | char line[1024]; | |
927 | TObjArray lines; | |
928 | lines.SetOwner(kTRUE); | |
929 | Int_t nvars(0); | |
930 | Int_t nreplaced(0); | |
931 | ||
932 | TIter next(fVars); | |
933 | ||
934 | while ( in.getline(line,1023,'\n') ) | |
935 | { | |
936 | TString sline(line); | |
937 | while (sline.Contains("VAR_") && !sline.BeginsWith("//") ) | |
938 | { | |
939 | ++nvars; | |
940 | TObjString* key; | |
941 | next.Reset(); | |
942 | while ( ( key = static_cast<TObjString*>(next())) ) | |
943 | { | |
944 | if ( sline.Contains(key->String()) ) | |
945 | { | |
946 | ++nreplaced; | |
947 | TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String())); | |
948 | sline.ReplaceAll(key->String(),value->String()); | |
949 | break; | |
950 | } | |
951 | } | |
952 | } | |
953 | ||
954 | lines.Add(new TObjString(sline)); | |
955 | } | |
956 | ||
957 | in.close(); | |
958 | ||
959 | if ( nvars > 0 ) | |
960 | { | |
961 | if ( nreplaced != nvars ) | |
962 | { | |
963 | AliError(Form("nvars=%d nreplaced=%d",nvars,nreplaced)); | |
964 | return kFALSE; | |
965 | } | |
966 | std::ofstream out(file); | |
967 | TIter nextLine(&lines); | |
968 | TObjString* s; | |
969 | while ( ( s = static_cast<TObjString*>(nextLine()) ) ) | |
970 | { | |
971 | out << s->String().Data() << std::endl; | |
972 | } | |
973 | out.close(); | |
974 | } | |
975 | ||
976 | return kTRUE; | |
977 | } | |
978 | ||
979 | //______________________________________________________________________________ | |
980 | Bool_t AliMuonAccEffSubmitter::Run(const char* mode) | |
981 | { | |
982 | /// mode can be one of (case insensitive) | |
983 | /// | |
984 | /// LOCAL : copy the template files from the template directory to the local one | |
985 | /// UPLOAD : copy the local files to the grid (requires LOCAL) | |
986 | /// OCDB : make ocdb snapshots (requires LOCAL) | |
987 | /// SUBMIT : submit the jobs (requires LOCAL + UPLOAD) | |
988 | /// FULL : all of the above (requires all of the above) | |
989 | /// | |
990 | /// TEST : as SUBMIT, but in dry mode (does not actually submit the jobs) | |
991 | ||
992 | if (!IsValid()) return kFALSE; | |
993 | ||
994 | TString smode(mode); | |
995 | smode.ToUpper(); | |
996 | ||
997 | if ( smode == "FULL") | |
998 | { | |
999 | return ( Run("LOCAL") && Run("OCDB") && Run("UPLOAD") && Run("SUBMIT") ); | |
1000 | } | |
1001 | ||
1002 | if ( smode == "LOCAL") | |
1003 | { | |
1004 | return CopyTemplateFilesToLocal(); | |
1005 | } | |
1006 | ||
1007 | if ( smode == "UPLOAD" ) | |
1008 | { | |
1009 | return (CopyLocalFilesToRemote()); | |
1010 | } | |
1011 | ||
1012 | if ( smode == "OCDB" ) | |
1013 | { | |
1014 | Bool_t ok = Run("LOCAL"); | |
1015 | if (ok) | |
1016 | { | |
1017 | ok = MakeOCDBSnapshots(); | |
1018 | } | |
1019 | return ok; | |
1020 | } | |
1021 | ||
1022 | if ( smode == "TEST" ) | |
1023 | { | |
1024 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
1025 | if ( ok ) | |
1026 | { | |
1027 | ok = (Submit(kTRUE)>0); | |
1028 | } | |
1029 | return ok; | |
1030 | } | |
1031 | ||
1032 | if ( smode == "FULL" ) | |
1033 | { | |
1034 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
1035 | if ( ok ) | |
1036 | { | |
1037 | ok = (Submit(kFALSE)>0); | |
1038 | } | |
1039 | return ok; | |
1040 | } | |
1041 | ||
1042 | if( smode == "SUBMIT" ) | |
1043 | { | |
1044 | return (Submit(kFALSE)>0); | |
1045 | } | |
1046 | ||
1047 | return kFALSE; | |
1048 | } | |
1049 | ||
1050 | //______________________________________________________________________________ | |
1051 | void AliMuonAccEffSubmitter::SetPackages(const char* aliroot, | |
1052 | const char* root, | |
1053 | const char* geant3, | |
1054 | const char* api) | |
1055 | { | |
1056 | fPackageAliroot = aliroot; | |
1057 | fPackageRoot = root; | |
1058 | fPackageGeant3 = geant3; | |
1059 | fPackageApi = api; | |
1060 | } | |
1061 | ||
1062 | //______________________________________________________________________________ | |
1063 | TString AliMuonAccEffSubmitter::GetRemoteDir(const char* dir, Bool_t create) | |
1064 | { | |
1065 | /// Set the target remote directory (on the grid) | |
1066 | ||
1067 | if (!RemoteDirectoryExists(dir)) | |
1068 | { | |
1069 | if (!create) | |
1070 | { | |
1071 | AliError(Form("Remote directory %s does not exist", dir)); | |
1072 | return ""; | |
1073 | } | |
1074 | else | |
1075 | { | |
1076 | AliInfo(Form("Remote directory %s does not exist. Trying to create it...",dir)); | |
1077 | if ( !gGrid->Mkdir(dir,"-p") ) | |
1078 | { | |
1079 | AliError(Form("Could not create remote dir. Sorry.")); | |
1080 | return ""; | |
1081 | } | |
1082 | } | |
1083 | } | |
1084 | return dir; | |
1085 | } | |
1086 | ||
1087 | //______________________________________________________________________________ | |
1088 | Bool_t AliMuonAccEffSubmitter::SetMergedDir(const char* dir, Bool_t create) | |
1089 | { | |
1090 | fMergedDir = GetRemoteDir(dir,create); | |
1091 | return (fMergedDir.Length()>0); | |
1092 | } | |
1093 | ||
1094 | //______________________________________________________________________________ | |
1095 | Bool_t AliMuonAccEffSubmitter::SetRemoteDir(const char* dir, Bool_t create) | |
1096 | { | |
1097 | fRemoteDir = GetRemoteDir(dir,create); | |
1098 | return (fIsValid = (fRemoteDir.Length()>0)); | |
1099 | } | |
1100 | ||
1101 | ||
1102 | //______________________________________________________________________________ | |
1103 | void AliMuonAccEffSubmitter::SetRunList(const char* runList) | |
1104 | { | |
1105 | // set the runlist from a text file | |
1106 | if (!fScalers) | |
1107 | { | |
1108 | fScalers = new AliAnalysisTriggerScalers(runList,fOCDBPath.Data()); | |
1109 | } | |
1110 | else | |
1111 | { | |
1112 | fScalers->SetRunList(runList); | |
1113 | } | |
1114 | UpdateLocalFileList(kTRUE); | |
1115 | } | |
1116 | ||
1117 | //______________________________________________________________________________ | |
1118 | void AliMuonAccEffSubmitter::SetRunList(int runNumber) | |
1119 | { | |
1120 | // set the runlist from a text file | |
1121 | if (!fScalers) | |
1122 | { | |
1123 | fScalers = new AliAnalysisTriggerScalers(runNumber,fOCDBPath.Data()); | |
1124 | } | |
1125 | else | |
1126 | { | |
1127 | fScalers->SetRunList(runNumber); | |
1128 | } | |
1129 | UpdateLocalFileList(kTRUE); | |
1130 | } | |
1131 | ||
1132 | //______________________________________________________________________________ | |
1133 | Bool_t AliMuonAccEffSubmitter::SetVar(const char* varname, const char* value) | |
1134 | { | |
1135 | TString s(varname); | |
1136 | s.ToUpper(); | |
1137 | if (!s.BeginsWith("VAR_")) | |
1138 | { | |
1139 | AliError("Variable name should start with VAR_"); | |
1140 | return kFALSE; | |
1141 | } | |
1142 | if (!fVars) | |
1143 | { | |
1144 | fVars = new TMap; | |
1145 | fVars->SetOwnerKeyValue(kTRUE,kTRUE); | |
1146 | } | |
1147 | ||
1148 | TObject* o = new TObjString(s); | |
1149 | fVars->Remove(o); | |
1150 | ||
1151 | fVars->Add(o,new TObjString(value)); | |
1152 | ||
1153 | return kTRUE; | |
1154 | } | |
1155 | ||
1156 | //______________________________________________________________________________ | |
1157 | Int_t AliMuonAccEffSubmitter::Submit(Bool_t dryRun) | |
1158 | { | |
1159 | /// Submit multiple production jobs with the format "submit jdl 000run#.xml 000run#". | |
1160 | /// | |
1161 | /// Return the number of submitted (master) jobs | |
1162 | /// | |
1163 | /// Example: | |
1164 | /// - outputDir = "/alice/cern.ch/user/p/ppillot/Sim/LHC10h/JPsiPbPb276/AlignRawVtxRaw/ESDs" | |
1165 | /// - runList must contains the list of run number | |
1166 | /// - trigger is the (fully qualified) trigger name used to compute the base number of events | |
1167 | /// - mult is the factor to apply to the number of trigger to get the number of events to be generated | |
1168 | /// (# generated events = # triggers x mult | |
1169 | ||
1170 | if (!IsValid()) return 0; | |
1171 | ||
1172 | gGrid->Cd(RemoteDir()); | |
1173 | ||
1174 | if (!RemoteFileExists(RunJDLName())) | |
1175 | { | |
1176 | AliError(Form("file %s does not exist in %s", RunJDLName().Data(), RemoteDir().Data())); | |
1177 | return 0; | |
1178 | } | |
1179 | ||
1180 | if ( !fScalers ) | |
1181 | { | |
1182 | AliError("No run list set. Use SetRunList"); | |
1183 | return 0; | |
1184 | } | |
1185 | const std::vector<int>& runs = fScalers->GetRunList(); | |
1186 | ||
1187 | if (runs.empty()) | |
1188 | { | |
1189 | AliError("No run to work with"); | |
1190 | return 0; | |
1191 | } | |
1192 | ||
1193 | // cout << "total number of selected MB events = " << totEvt << endl; | |
1194 | // cout << "required number of generated events = " << nGenEvents << endl; | |
1195 | // cout << "number of generated events per MB event = " << ratio << endl; | |
1196 | // cout << endl; | |
1197 | ||
1198 | std::cout << "run\tchunks\tevents" << std::endl; | |
1199 | std::cout << "----------------------" << std::endl; | |
1200 | ||
1201 | Int_t nJobs(0); | |
1202 | Int_t nEvts(0); | |
1203 | ||
1204 | for (std::vector<int>::size_type i=0; i < runs.size(); ++i) | |
1205 | { | |
1206 | Int_t runNumber = runs[i]; | |
1207 | ||
1208 | Int_t nEvtRun(fFixedNofEvents); | |
1209 | ||
1210 | if ( fRatio > 0 ) | |
1211 | { | |
1212 | AliAnalysisTriggerScalerItem* trigger = fScalers->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data()); | |
1213 | ||
1214 | if (!trigger) | |
1215 | { | |
1216 | AliError(Form("Could not get trigger %s for run %09d",ReferenceTrigger().Data(),runNumber)); | |
1217 | continue; | |
1218 | } | |
1219 | nEvtRun = TMath::Nint(fRatio * trigger->Value()); | |
1220 | } | |
1221 | ||
1222 | Int_t nChunk = 1; | |
1223 | ||
1224 | while (nEvtRun/nChunk+0.5 > MaxEventsPerChunk()) | |
1225 | { | |
1226 | ++nChunk; | |
1227 | } | |
1228 | ||
1229 | Int_t nEvtChunk = TMath::Nint(nEvtRun/nChunk + 0.5); | |
1230 | ||
1231 | nJobs += nChunk; | |
1232 | ||
1233 | nEvts += nChunk*nEvtChunk; | |
1234 | ||
1235 | std::cout << runNumber << "\t" << nChunk << "\t" << nEvtChunk << std::endl; | |
1236 | ||
1237 | TString query(Form("submit %s %d %d %d", RunJDLName().Data(), runNumber, nChunk, nEvtChunk)); | |
1238 | ||
1239 | std::cout << query.Data() << " ..." << std::flush; | |
1240 | ||
1241 | TGridResult* res = 0x0; | |
1242 | ||
1243 | if (!dryRun) | |
1244 | { | |
1245 | res = gGrid->Command(query); | |
1246 | } | |
1247 | ||
1248 | if (res) | |
1249 | { | |
1250 | TString cjobId1 = res->GetKey(0,"jobId"); | |
1251 | ||
1252 | if (!cjobId1.Length()) | |
1253 | { | |
1254 | std::cout << " FAILED" << std::endl << std::endl; | |
1255 | gGrid->Stdout(); | |
1256 | gGrid->Stderr(); | |
1257 | } | |
1258 | else | |
1259 | { | |
1260 | std::cout << "DONE" << std::endl; | |
1261 | std::cout << Form(" --> the job Id is: %s",cjobId1.Data()) << std::endl << std::endl; | |
1262 | } | |
1263 | } | |
1264 | else | |
1265 | { | |
1266 | std::cout << " FAILED" << std::endl << std::endl; | |
1267 | } | |
1268 | ||
1269 | delete res; | |
1270 | } | |
1271 | ||
1272 | std::cout << std::endl | |
1273 | << "total number of jobs = " << nJobs << std::endl | |
1274 | << "total number of generated events = " << nEvts << std::endl | |
1275 | << std::endl; | |
1276 | ||
1277 | return nJobs; | |
1278 | } | |
1279 | ||
1280 | //______________________________________________________________________________ | |
1281 | TObjArray* AliMuonAccEffSubmitter::TemplateFileList() const | |
1282 | { | |
1283 | /// Return (after createing and filling it if needed) | |
1284 | /// the internal file list with paths from the template directory | |
1285 | ||
1286 | if (!fTemplateFileList) | |
1287 | { | |
1288 | fTemplateFileList = new TObjArray; | |
1289 | fTemplateFileList->SetOwner(kTRUE); | |
1290 | ||
1291 | fTemplateFileList->Add(new TObjString("CheckESD.C")); | |
1292 | fTemplateFileList->Add(new TObjString("CheckAOD.C")); | |
1293 | fTemplateFileList->Add(new TObjString("AODtrain.C")); | |
1294 | fTemplateFileList->Add(new TObjString("validation.sh")); | |
1295 | if ( fExternalConfig.Length() > 0 ) | |
1296 | { | |
1297 | fTemplateFileList->Add(new TObjString(fExternalConfig)); | |
1298 | } | |
1299 | else | |
1300 | { | |
1301 | fTemplateFileList->Add(new TObjString("Config.C")); | |
1302 | } | |
1303 | fTemplateFileList->Add(new TObjString("rec.C")); | |
1304 | fTemplateFileList->Add(new TObjString("sim.C")); | |
1305 | fTemplateFileList->Add(new TObjString("simrun.C")); | |
1306 | fTemplateFileList->Add(new TObjString(RunJDLName().Data())); | |
1307 | fTemplateFileList->Add(new TObjString(MergeJDLName(kFALSE).Data())); | |
1308 | fTemplateFileList->Add(new TObjString(MergeJDLName(kTRUE).Data())); | |
1309 | fTemplateFileList->Add(new TObjString("AOD_merge.sh")); | |
1310 | fTemplateFileList->Add(new TObjString("validation_merge.sh")); | |
1311 | } | |
1312 | ||
1313 | return fTemplateFileList; | |
1314 | } | |
1315 | ||
1316 | //______________________________________________________________________________ | |
1317 | void AliMuonAccEffSubmitter::UpdateLocalFileList(Bool_t clearSnapshots) | |
1318 | { | |
1319 | if (!fScalers) return; | |
1320 | ||
1321 | if ( clearSnapshots ) | |
1322 | { | |
1323 | TIter next(LocalFileList()); | |
1324 | TObjString* file; | |
1325 | ||
1326 | while ( ( file = static_cast<TObjString*>(next())) ) | |
1327 | { | |
1328 | if ( file->String().Contains("OCDB_") ) | |
1329 | { | |
1330 | LocalFileList()->Remove(file); | |
1331 | } | |
1332 | } | |
1333 | LocalFileList()->Compress(); | |
1334 | } | |
1335 | ||
1336 | const std::vector<int>& runs = fScalers->GetRunList(); | |
1337 | ||
1338 | const char* type[] = { "sim","rec" }; | |
1339 | ||
1340 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
1341 | { | |
1342 | Int_t runNumber = runs[i]; | |
1343 | ||
1344 | for ( Int_t t = 0; t < 2; ++t ) | |
1345 | { | |
1346 | TString snapshot(Form("%s/OCDB/%d/OCDB_%s.root",SnapshotDir().Data(),runNumber,type[t])); | |
1347 | ||
1348 | if ( !gSystem->AccessPathName(snapshot.Data()) ) | |
1349 | { | |
1350 | if ( !LocalFileList()->FindObject(snapshot.Data()) ) | |
1351 | { | |
1352 | LocalFileList()->Add(new TObjString(snapshot)); | |
1353 | } | |
1354 | } | |
1355 | } | |
1356 | } | |
1357 | ||
1358 | } | |
1359 | ||
1360 | //______________________________________________________________________________ | |
1361 | void AliMuonAccEffSubmitter::UseOCDBSnapshots(Bool_t flag) | |
1362 | { | |
1363 | fUseOCDBSnapshots = flag; | |
1364 | if ( flag ) | |
1365 | { | |
1366 | SetVar("VAR_OCDB_SNAPSHOT","kTRUE"); | |
1367 | } | |
1368 | else | |
1369 | { | |
1370 | SetVar("VAR_OCDB_SNAPSHOT","kFALSE"); | |
1371 | } | |
1372 | ||
1373 | UpdateLocalFileList(); | |
1374 | } | |
1375 |