]>
Commit | Line | Data |
---|---|---|
81190958 | 1 | #include "AliMuonQAMergeSubmitter.h" |
2 | ||
3 | #include "AliMuonAccEffSubmitter.h" | |
4 | #include "AliAnalysisTriggerScalers.h" | |
5 | #include "AliLog.h" | |
6 | #include "TSystem.h" | |
7 | #include "Riostream.h" | |
8 | #include "TGrid.h" | |
9 | #include "TGridResult.h" | |
10 | ||
11 | namespace { | |
12 | const Int_t kFinal(999); | |
13 | } | |
14 | ||
15 | ClassImp(AliMuonQAMergeSubmitter) | |
16 | ||
17 | //_____________________________________________________________________________ | |
18 | AliMuonQAMergeSubmitter::AliMuonQAMergeSubmitter(const char* period, const char* pass) : | |
19 | AliMuonGridSubmitter(AliMuonGridSubmitter::kQAMerge), | |
20 | fPeriod(period), | |
21 | fPass(pass), | |
22 | fWhatToMerge("Merged.QA.Data.root"), | |
23 | fSplitMaxInputFileNumber(50) | |
24 | { | |
25 | if (!fPeriod.BeginsWith("LHC")) | |
26 | { | |
27 | AliError("Period not starting with LHC !"); | |
28 | } | |
29 | ||
30 | AddToTemplateFileList("QAMerge.C"); | |
31 | AddToTemplateFileList("QAMerge.sh"); | |
32 | AddToTemplateFileList("validation.sh"); | |
33 | AddToTemplateFileList(MergeJDLName(kFALSE).Data()); | |
34 | AddToTemplateFileList(MergeJDLName(kTRUE).Data()); | |
35 | ||
36 | SetVar("VAR_MERGED_OUTPUT_NAME",Form("%s",fWhatToMerge.Data())); | |
37 | ||
38 | ShouldOverwriteFiles(kTRUE); | |
39 | ||
40 | TString speriod(period); | |
41 | ||
42 | Int_t year = 2000 + TString(speriod(3,3)).Atoi(); | |
43 | ||
44 | SetMapKeyValue("DataDirFormat",Form("/alice/data/%d/%s/%%09d/ESDs/%s",year,period,pass)); | |
45 | } | |
46 | ||
47 | //_____________________________________________________________________________ | |
48 | AliMuonQAMergeSubmitter::~AliMuonQAMergeSubmitter() | |
49 | { | |
50 | } | |
51 | ||
52 | //______________________________________________________________________________ | |
53 | Bool_t AliMuonQAMergeSubmitter::Generate(const char* jdlname) const | |
54 | { | |
55 | /// Create the JDL for merging jobs | |
56 | ||
57 | AliDebug(1,""); | |
58 | ||
59 | std::ostream* os = CreateJDLFile(jdlname); | |
60 | ||
61 | if (!os) | |
62 | { | |
63 | return kFALSE; | |
64 | } | |
65 | ||
66 | Bool_t final = TString(jdlname).Contains("final",TString::kIgnoreCase); | |
67 | ||
68 | (*os) << "# Generated merging jdl (production mode)" << std::endl | |
69 | << "# $1 = run number" << std::endl | |
70 | << "# $2 = merging stage" << std::endl | |
71 | << "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*" << fWhatToMerge.Data() << std::endl; | |
72 | ||
73 | OutputToJDL(*os,"Packages", | |
74 | GetMapValue("AliRoot").Data(), | |
75 | GetMapValue("Geant3").Data(), | |
76 | GetMapValue("Root").Data(), | |
77 | GetMapValue("API").Data()); | |
78 | ||
79 | OutputToJDL(*os,"Executable","QAMerge.sh"); | |
80 | ||
81 | OutputToJDL(*os,"Price","1"); | |
82 | ||
83 | if ( final ) | |
84 | { | |
85 | OutputToJDL(*os,"Jobtag","comment: AliMuonQAMergeSubmitter final merging RUN $1"); | |
86 | } | |
87 | else | |
88 | { | |
89 | OutputToJDL(*os,"Jobtag","comment: AliMuonQAMergeSubmitter merging RUN $1 stage $2"); | |
90 | } | |
91 | ||
92 | OutputToJDL(*os,"Workdirectorysize","5000MB"); | |
93 | ||
94 | OutputToJDL(*os,"Validationcommand",Form("%s/validation.sh",RemoteDir().Data())); | |
95 | ||
96 | OutputToJDL(*os,"TTL","14400"); | |
97 | ||
98 | OutputToJDL(*os,"OutputArchive", | |
99 | "log_archive.zip:stderr,stdout@disk=1", | |
100 | Form("root_archive.zip:%s@disk=3",fWhatToMerge.Data()) | |
101 | ); | |
102 | ||
103 | // OutputToJDL(*os,"Arguments",(final ? "2":"1")); // for QAmerge.sh, 1 means intermediate merging stage, 2 means final merging | |
104 | ||
105 | if ( !final ) | |
106 | { | |
107 | OutputToJDL(*os,"Arguments","wn.xml"); | |
108 | OutputToJDL(*os,"InputFile",Form("LF:%s/QAMerge.C",RemoteDir().Data())); | |
109 | OutputToJDL(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",RemoteDir().Data())); | |
110 | OutputToJDL(*os,"Split","se"); | |
111 | OutputToJDL(*os,"InputDataCollection",Form("LF:%s/$1/Stage_$2.xml,nodownload",RemoteDir().Data())); | |
112 | OutputToJDL(*os,"SplitMaxInputFileNumber",Form("%d",GetSplitMaxInputFileNumber())); | |
113 | OutputToJDL(*os,"InputDataListFormat","xml-single"); | |
114 | OutputToJDL(*os,"InputDataList","wn.xml"); | |
115 | } | |
116 | else | |
117 | { | |
118 | OutputToJDL(*os,"InputFile",Form("LF:%s/QAMerge.C",RemoteDir().Data()), | |
119 | Form("LF:%s/$1/Stage_$2.xml",RemoteDir().Data())); | |
120 | OutputToJDL(*os,"Arguments","Stage_$2.xml $1"); | |
121 | OutputToJDL(*os,"OutputDir",Form("%s/$1",RemoteDir().Data())); | |
122 | } | |
123 | ||
124 | return kTRUE; | |
125 | } | |
126 | ||
127 | //_____________________________________________________________________________ | |
128 | UInt_t AliMuonQAMergeSubmitter::MakeXMLCollectionForRun(Int_t runNumber, Int_t stage) | |
129 | { | |
130 | /// Create a collection named Stage_[stage].xml | |
131 | /// with the files from stage-1 (or all the files if stage=0) | |
132 | /// Return the total number of files to be merged | |
133 | ||
134 | if ( stage < 0 ) | |
135 | { | |
136 | AliError(Form("Stage (%d) should be >=0",stage)); | |
137 | return 0; | |
138 | } | |
139 | ||
140 | TString filename; | |
141 | TString sourcedir; | |
142 | ||
143 | if ( stage > 1 ) | |
144 | { | |
145 | filename.Form("%s/%d/Stage_%d.xml",LocalDir().Data(),runNumber,stage); | |
146 | sourcedir.Form("%s/%d/Stage_%d",RemoteDir().Data(),runNumber,stage-1); | |
147 | } | |
148 | else if ( stage == 1 ) | |
149 | { | |
150 | sourcedir = GetMapValue("DataDirFormat"); | |
151 | ||
152 | if ( sourcedir.Length() == 0 ) | |
153 | { | |
154 | AliError("Cannot make collections from an empty data dir !"); | |
155 | return 0; | |
156 | } | |
157 | filename.Form("%s/%d/Stage_%d.xml",LocalDir().Data(),runNumber,stage); | |
158 | } | |
159 | else | |
160 | { | |
161 | AliError("oups"); | |
162 | return 0; | |
163 | } | |
164 | ||
165 | UInt_t count(0); | |
166 | ||
167 | TGridResult* res = gGrid->Query(Form(sourcedir.Data(),runNumber),fWhatToMerge.Data()); | |
168 | ||
169 | Int_t nFiles = res->GetEntries(); | |
170 | ||
171 | if (!nFiles) | |
172 | { | |
173 | AliError(Form("Got no file for run %d",runNumber)); | |
174 | return 0; | |
175 | } | |
176 | ||
177 | gSystem->mkdir(Form("%s/",gSystem->DirName(filename.Data())),kTRUE); | |
178 | ||
179 | AliDebug(1,Form("Creating %s",filename.Data())); | |
180 | ||
181 | std::ofstream out(filename.Data()); | |
182 | ||
183 | out << Form("<?xml version=\"1.0\"?>\n<alien>\n <collection name=\"%d-stage-%d\">",runNumber,stage) << std::endl; | |
184 | ||
185 | Long64_t size(0); | |
186 | const Double_t byte2GB(1024*1024*1024); | |
187 | ||
188 | for (Int_t i = 0; i < nFiles; ++i) | |
189 | { | |
190 | ++count; | |
191 | ||
192 | size += TString(res->GetKey(i,"size")).Atoll(); | |
193 | ||
1a37b253 | 194 | out << Form(" <event name=\"%d\">",count) << std::endl; |
81190958 | 195 | out << Form(" <file name=\"%s\" aclId=\"%s\" broken=\"%s\" ctime=\"%s\" " |
196 | "dir=\"%s\" entryId=\"%s\" expiretime=\"%s\" gowner=\"%s\" " | |
197 | "guid=\"%s\" guidtime=\"%s\" lfn=\"%s\" md5=\"%s\" owner=\"%s\" " | |
198 | " perm=\"%s\" replicated=\"%s\" size=\"%s\" turl=\"%s\" type=\"%s\" />", | |
199 | gSystem->BaseName(res->GetKey(i,"lfn")), | |
200 | res->GetKey(i,"aclId"), | |
201 | res->GetKey(i,"broken"), | |
202 | res->GetKey(i,"ctime"), | |
203 | res->GetKey(i,"dir"), | |
204 | res->GetKey(i,"entryId"), | |
205 | res->GetKey(i,"expiretime"), | |
206 | res->GetKey(i,"gowner"), | |
207 | res->GetKey(i,"guid"), | |
208 | res->GetKey(i,"guidtime"), | |
209 | res->GetKey(i,"lfn"), | |
210 | res->GetKey(i,"md5"), | |
211 | res->GetKey(i,"owner"), | |
212 | res->GetKey(i,"perm"), | |
213 | res->GetKey(i,"replicated"), | |
214 | res->GetKey(i,"size"), | |
215 | res->GetKey(i,"turl"), | |
1a37b253 | 216 | res->GetKey(i,"type")) << std::endl; |
217 | out << " </event>" << std::endl; | |
81190958 | 218 | } |
219 | ||
220 | TString summary(Form("numberoffiles=\"%d\" size=\"%7.2f GB\" ",count,size/byte2GB)); | |
221 | ||
1a37b253 | 222 | out << Form(" <summary %s />",summary.Data()) << std::endl; |
223 | out << " </collection>" << std::endl; | |
224 | out << "</alien>" << std::endl; | |
81190958 | 225 | |
226 | out.close(); | |
227 | ||
228 | delete res; | |
229 | ||
230 | Bool_t ok = CopyFile(filename.Data()); | |
231 | ||
232 | if (!ok) return 0; | |
233 | ||
234 | return count; | |
235 | } | |
236 | ||
237 | //_____________________________________________________________________________ | |
238 | void AliMuonQAMergeSubmitter::Print(Option_t*) const | |
239 | { | |
240 | std::cout << "SplitMaxInputFileNumber : " << GetSplitMaxInputFileNumber() << std::endl; | |
241 | AliMuonGridSubmitter::Print(); | |
242 | } | |
243 | ||
244 | //_____________________________________________________________________________ | |
245 | Bool_t AliMuonQAMergeSubmitter::Run(const char* mode) | |
246 | { | |
247 | if (!IsValid()) return kFALSE; | |
248 | ||
249 | TString smode(mode); | |
250 | smode.ToUpper(); | |
251 | ||
252 | if ( smode == "FULL") | |
253 | { | |
254 | return ( Run("LOCAL") && Run("UPLOAD") && Run("SUBMIT") ); | |
255 | } | |
256 | ||
257 | if ( smode == "LOCAL") | |
258 | { | |
259 | return CopyTemplateFilesToLocal(); | |
260 | } | |
261 | ||
262 | if ( smode == "UPLOAD" ) | |
263 | { | |
264 | return CopyLocalFilesToRemote(); | |
265 | } | |
266 | ||
267 | if ( smode == "TEST" ) | |
268 | { | |
269 | Bool_t ok = Run("LOCAL") && Run("UPLOAD"); | |
270 | if ( ok ) | |
271 | { | |
272 | ok = (Submit(kTRUE)>0); | |
273 | } | |
274 | return ok; | |
275 | } | |
276 | ||
277 | if ( smode == "SUBMIT" ) | |
278 | { | |
279 | return (Submit(kFALSE)>0); | |
280 | } | |
281 | ||
282 | return kFALSE; | |
283 | ||
284 | } | |
285 | ||
286 | //_____________________________________________________________________________ | |
287 | Bool_t AliMuonQAMergeSubmitter::SetRemoteDir(const char* dir) | |
288 | { | |
289 | if ( AliMuonGridSubmitter::SetRemoteDir(dir) ) | |
290 | { | |
291 | Validate(); | |
292 | return kTRUE; | |
293 | } | |
294 | else | |
295 | { | |
296 | Invalidate(); | |
297 | return kFALSE; | |
298 | } | |
299 | } | |
300 | ||
301 | //______________________________________________________________________________ | |
302 | void AliMuonQAMergeSubmitter::ShowStage(Int_t runNumber) | |
303 | { | |
304 | /// Show stage for a given run number | |
305 | ||
306 | Int_t stage(0); | |
307 | ||
308 | if ( RemoteFileExists(Form("%s/%d/%s",RemoteDir().Data(),runNumber,fWhatToMerge.Data())) ) | |
309 | { | |
310 | stage = kFinal; | |
311 | } | |
312 | else | |
313 | { | |
314 | stage = GetLastStage(Form("%s/%d",RemoteDir().Data(),runNumber)); | |
315 | } | |
316 | ||
317 | std::cout << "RUN " << runNumber << " "; | |
318 | ||
319 | if ( stage == kFinal ) | |
320 | { | |
321 | std::cout << "FINAL"; | |
322 | } | |
323 | else | |
324 | { | |
325 | std::cout << "Stage " << stage; | |
326 | } | |
327 | std::cout << std::endl; | |
328 | } | |
329 | ||
330 | //______________________________________________________________________________ | |
331 | void AliMuonQAMergeSubmitter::ShowStages() | |
332 | { | |
333 | /// Show in remote dir the list of stages we're in for each run | |
334 | ||
335 | TGridResult* r = gGrid->Ls(RemoteDir()); | |
336 | Int_t i(0); | |
337 | std::map<int,std::vector<int> > stages; | |
338 | ||
339 | while ( r->GetFileName(i) ) | |
340 | { | |
341 | TString s(r->GetFileName(i)); | |
342 | if (s.IsDec()) | |
343 | { | |
344 | Int_t runNumber = s.Atoi(); | |
345 | Int_t stage(0); | |
346 | ||
347 | if ( RemoteFileExists(Form("%s/%d/%s",RemoteDir().Data(),runNumber,fWhatToMerge.Data())) ) | |
348 | { | |
349 | stage = kFinal; | |
350 | } | |
351 | else | |
352 | { | |
353 | stage = GetLastStage(Form("%s/%d",RemoteDir().Data(),runNumber)); | |
354 | } | |
355 | ||
356 | stages[stage].push_back(runNumber); | |
357 | } | |
358 | ++i; | |
359 | } | |
360 | delete r; | |
361 | ||
362 | std::map<int,std::vector<int> >::const_iterator it; | |
363 | ||
364 | for ( it = stages.begin(); it != stages.end(); ++it ) | |
365 | { | |
366 | const std::vector<int>& runs = it->second; | |
367 | Int_t stage = it->first; | |
368 | if ( stage == kFinal ) | |
369 | { | |
370 | std::cout << "FINAL"; | |
371 | } | |
372 | else | |
373 | { | |
374 | std::cout << "Stage " << stage; | |
375 | } | |
376 | std::cout << std::endl; | |
377 | for ( std::vector<int>::size_type irun = 0; irun < runs.size(); ++irun ) | |
378 | { | |
379 | std::cout << runs[irun] << " "; | |
380 | } | |
381 | std::cout << std::endl; | |
382 | } | |
383 | } | |
384 | ||
385 | ||
386 | //_____________________________________________________________________________ | |
387 | Bool_t AliMuonQAMergeSubmitter::Submit(Int_t runNumber, Bool_t dryRun) | |
388 | { | |
389 | /// Submit merging job for one run | |
390 | ||
391 | TString runDir = GetRemoteDir(Form("%s/%d", RemoteDir().Data(), runNumber),kTRUE); | |
392 | ||
393 | if (RemoteFileExists(Form("%s/%s", runDir.Data(),fWhatToMerge.Data()))) | |
394 | { | |
395 | AliWarning(" ! final merging already done"); | |
396 | return kTRUE; | |
397 | } | |
398 | ||
399 | Int_t lastStage = GetLastStage(runDir.Data()); | |
400 | ||
401 | AliDebug(1,Form("lastStage=%d",lastStage)); | |
402 | ||
403 | ++lastStage; | |
404 | ||
405 | UInt_t n = MakeXMLCollectionForRun(runNumber,lastStage); | |
406 | ||
407 | Bool_t final = ( n < GetSplitMaxInputFileNumber() ); | |
408 | ||
409 | TString query; | |
410 | TString jdl(MergeJDLName(final)); | |
411 | ||
412 | gGrid->Cd(RemoteDir().Data()); | |
413 | ||
414 | query.Form("submit %s %d %d", jdl.Data(), runNumber, lastStage); | |
415 | ||
416 | AliInfo(Form("query=%s",query.Data())); | |
417 | ||
418 | if (dryRun) | |
419 | { | |
420 | return kTRUE; | |
421 | } | |
422 | ||
423 | Bool_t done = kFALSE; | |
424 | TGridResult *res = gGrid->Command(query); | |
425 | if (res) | |
426 | { | |
427 | TString cjobId1 = res->GetKey(0,"jobId"); | |
428 | if (!cjobId1.IsDec()) | |
429 | { | |
430 | AliError(" FAILED"); | |
431 | gGrid->Stdout(); | |
432 | gGrid->Stderr(); | |
433 | } | |
434 | else | |
435 | { | |
436 | AliInfo(Form(" DONE\n --> the job Id is: %s \n", cjobId1.Data())); | |
437 | done = kTRUE; | |
438 | } | |
439 | delete res; | |
440 | } | |
441 | else | |
442 | { | |
443 | AliError(" FAILED"); | |
444 | } | |
445 | ||
446 | return done; | |
447 | } | |
448 | ||
449 | //_____________________________________________________________________________ | |
450 | Int_t AliMuonQAMergeSubmitter::Submit(Bool_t dryRun) | |
451 | { | |
452 | /// Submit merging jobs | |
453 | ||
454 | if (!NofRuns()) | |
455 | { | |
456 | AliError("No run to work with"); | |
457 | return 0; | |
458 | } | |
459 | ||
460 | const std::vector<int>& runs = RunList(); | |
461 | ||
462 | TString failed; | |
463 | ||
464 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
465 | { | |
466 | Int_t run = runs[i]; | |
467 | Bool_t ok = Submit(run,dryRun); | |
468 | ||
469 | if (!ok) | |
470 | { | |
471 | failed += TString::Format("%d",run); | |
472 | failed += " "; | |
473 | } | |
474 | } | |
475 | ||
476 | if (failed.Length()>0) | |
477 | { | |
478 | AliInfo(Form("List of failed runs : %s",failed.Data())); | |
479 | return 0; | |
480 | } | |
481 | ||
482 | return 1; | |
483 | } | |
484 |