]>
Commit | Line | Data |
---|---|---|
1afce1ce | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | // | |
17 | // AliMuonAccEffSubmitter : a class to help submit Acc x Eff simulations | |
18 | // anchored to real runs for J/psi, upsilon, single muons, etc... | |
19 | // | |
20 | // This class is dealing with 3 different directories : | |
21 | // | |
22 | // - template directory ($ALICE_ROOT/PWG/muondep/AccEffTemplates) containing the | |
23 | // basic template files to be used for a simuation. A template can contain | |
24 | // some variables that will be replaced during during the copy from template | |
25 | // to local dir | |
26 | // | |
27 | // - local directory, where the files from the template directory, are copied | |
28 | // once the class has been configured properly (i.e. using the various Set, Use, | |
29 | // etc... methods). Some other files (e.g. JDL ones) are generated from | |
30 | // scratch and also copied into this directory. | |
31 | // At this point one could(should) check the files, as they are the ones | |
32 | // to be copied to the remote directory for the production | |
33 | // | |
34 | // - remote directory, the alien directory where the files will be copied | |
35 | // (from the local directory) before the actual submission | |
36 | // | |
37 | // ========================================================== | |
38 | // | |
39 | // Basic usage | |
40 | // | |
41 | // AliMuonAccEffSubmitter a; | |
42 | // a.UseOCDBSnapshots(kFALSE); | |
43 | // a.SetRemoteDir("/alice/cern.ch/user/l/laphecet/Analysis/LHC13d/simjpsi/pp503z0"); | |
44 | // a.ShouldOverwriteFiles(true); | |
45 | // a.MakeNofEventsPropToTriggerCount("CMUL7-B-NOPF-MUON"); | |
46 | // a.SetVar("VAR_GENLIB_PARNAME","\"pp 5.03\""); | |
47 | // a.SetRunList(195682); | |
48 | // a.Print(); | |
49 | // a.Run("test"); // will do everything but the submit | |
50 | // a.Submit(false); // actual submission | |
51 | // | |
52 | // | |
53 | // author: Laurent Aphecetche (Subatech | |
54 | // | |
55 | ||
a58729a5 | 56 | #include "AliMuonAccEffSubmitter.h" |
57 | ||
58 | #include "AliAnalysisTriggerScalers.h" | |
59 | #include "AliLog.h" | |
60 | #include "TFile.h" | |
61 | #include "TGrid.h" | |
62 | #include "TGridResult.h" | |
63 | #include "TMap.h" | |
64 | #include "TMath.h" | |
65 | #include "TObjString.h" | |
1afce1ce | 66 | #include "TROOT.h" |
a58729a5 | 67 | #include "TString.h" |
68 | #include "TSystem.h" | |
69 | #include <vector> | |
c2aad3ae | 70 | #include <fstream> |
71 | using std::ifstream; | |
a58729a5 | 72 | namespace |
73 | { | |
74 | Int_t splitLevel=10; | |
75 | } | |
76 | ||
81190958 | 77 | ClassImp(AliMuonAccEffSubmitter) |
78 | ||
a58729a5 | 79 | //______________________________________________________________________________ |
1afce1ce | 80 | AliMuonAccEffSubmitter::AliMuonAccEffSubmitter(const char* generator) |
81190958 | 81 | : AliMuonGridSubmitter(AliMuonGridSubmitter::kAccEff), |
82 | fRatio(-1.0), | |
1afce1ce | 83 | fFixedNofEvents(10000), |
a58729a5 | 84 | fMaxEventsPerChunk(5000), |
d484adc1 | 85 | fOCDBPath(""), |
a58729a5 | 86 | fSplitMaxInputFileNumber(20), |
87 | fCompactMode(1), | |
a58729a5 | 88 | fExternalConfig(""), |
81190958 | 89 | fUseOCDBSnapshots(kFALSE), |
d484adc1 | 90 | fSnapshotDir(""), |
a3c2a88b | 91 | fUseAODMerging(kFALSE) |
a58729a5 | 92 | { |
93 | // ctor | |
94 | ||
81190958 | 95 | SetOCDBPath("raw://"); |
96 | ||
97 | SetLocalDirectory("Snapshot",LocalDir()); | |
a58729a5 | 98 | |
a58729a5 | 99 | SetVar("VAR_OCDB_PATH","\"raw://\""); |
1afce1ce | 100 | |
101 | SetVar("VAR_GENPARAM_GENLIB_TYPE","AliGenMUONlib::kJpsi"); | |
102 | SetVar("VAR_GENPARAM_GENLIB_PARNAME","\"pPb 5.03\""); | |
103 | ||
104 | SetVar("VAR_GENCORRHF_QUARK","5"); | |
105 | SetVar("VAR_GENCORRHF_ENERGY","5"); | |
106 | ||
a3c2a88b | 107 | // some default values for J/psi |
1afce1ce | 108 | SetVar("VAR_GENPARAMCUSTOM_PDGPARTICLECODE","443"); |
109 | ||
110 | // default values below are from J/psi p+Pb (from muon_calo pass) | |
111 | SetVar("VAR_GENPARAMCUSTOM_Y_P0","4.08E5"); | |
112 | SetVar("VAR_GENPARAMCUSTOM_Y_P1","7.1E4"); | |
113 | ||
114 | SetVar("VAR_GENPARAMCUSTOM_PT_P0","1.13E9"); | |
115 | SetVar("VAR_GENPARAMCUSTOM_PT_P1","18.05"); | |
116 | SetVar("VAR_GENPARAMCUSTOM_PT_P2","2.05"); | |
117 | SetVar("VAR_GENPARAMCUSTOM_PT_P3","3.34"); | |
118 | ||
a3c2a88b | 119 | // some default values for single muons |
120 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PTMIN","0.35"); | |
121 | ||
122 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P0","4.05962"); | |
123 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P1","1.0"); | |
124 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P2","2.46187"); | |
125 | SetVar("VAR_GENPARAMCUSTOMSINGLE_PT_P3","2.08644"); | |
126 | ||
127 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P0","0.729545"); | |
128 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P1","0.53837"); | |
129 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P2","0.141776"); | |
130 | SetVar("VAR_GENPARAMCUSTOMSINGLE_Y_P3","0.0130173"); | |
131 | ||
81190958 | 132 | UseOCDBSnapshots(fUseOCDBSnapshots); |
1afce1ce | 133 | |
134 | SetGenerator(generator); | |
1afce1ce | 135 | |
81190958 | 136 | MakeNofEventsPropToTriggerCount(); |
1afce1ce | 137 | |
81190958 | 138 | AddToTemplateFileList("CheckESD.C"); |
139 | AddToTemplateFileList("CheckAOD.C"); | |
140 | AddToTemplateFileList("AODtrain.C"); | |
141 | AddToTemplateFileList("validation.sh"); | |
1afce1ce | 142 | |
81190958 | 143 | AddToTemplateFileList("Config.C"); |
144 | AddToTemplateFileList("rec.C"); | |
145 | AddToTemplateFileList("sim.C"); | |
146 | AddToTemplateFileList("simrun.C"); | |
147 | AddToTemplateFileList(RunJDLName().Data()); | |
1afce1ce | 148 | |
81190958 | 149 | UseExternalConfig(fExternalConfig); |
1afce1ce | 150 | } |
151 | ||
a58729a5 | 152 | //______________________________________________________________________________ |
81190958 | 153 | AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter() |
a58729a5 | 154 | { |
81190958 | 155 | // dtor |
a58729a5 | 156 | } |
157 | ||
81190958 | 158 | ///______________________________________________________________________________ |
159 | Bool_t AliMuonAccEffSubmitter::Generate(const char* jdlname) const | |
a58729a5 | 160 | { |
81190958 | 161 | if ( TString(jdlname).Contains("merge",TString::kIgnoreCase) ) |
a58729a5 | 162 | { |
81190958 | 163 | return GenerateMergeJDL(jdlname); |
a58729a5 | 164 | } |
165 | else | |
166 | { | |
81190958 | 167 | return GenerateRunJDL(jdlname); |
a58729a5 | 168 | } |
a58729a5 | 169 | } |
170 | ||
171 | ///______________________________________________________________________________ | |
81190958 | 172 | Bool_t AliMuonAccEffSubmitter::GenerateMergeJDL(const char* name) const |
a58729a5 | 173 | { |
1afce1ce | 174 | /// Create the JDL for merging jobs |
175 | /// FIXME: not checked ! | |
176 | ||
177 | AliDebug(1,""); | |
178 | ||
a58729a5 | 179 | std::ostream* os = CreateJDLFile(name); |
180 | ||
181 | if (!os) | |
182 | { | |
183 | return kFALSE; | |
184 | } | |
185 | ||
186 | Bool_t final = TString(name).Contains("merge",TString::kIgnoreCase); | |
187 | ||
188 | (*os) << "# Generated merging jdl (production mode)" << std::endl | |
189 | << "# $1 = run number" << std::endl | |
190 | << "# $2 = merging stage" << std::endl | |
191 | << "# Stage_<n>.xml made via: find <OutputDir> *Stage<n-1>/*root_archive.zip" << std::endl; | |
192 | ||
81190958 | 193 | OutputToJDL(*os,"Packages", |
194 | GetMapValue("AliRoot"), | |
195 | GetMapValue("Geant3"), | |
196 | GetMapValue("Root"), | |
197 | GetMapValue("API")); | |
a58729a5 | 198 | |
81190958 | 199 | OutputToJDL(*os,"Executable","AOD_merge.sh"); |
a58729a5 | 200 | |
81190958 | 201 | OutputToJDL(*os,"Price","1"); |
a58729a5 | 202 | |
203 | if ( final ) | |
204 | { | |
81190958 | 205 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter final merging"); |
a58729a5 | 206 | } |
207 | else | |
208 | { | |
81190958 | 209 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter merging stage $2"); |
a58729a5 | 210 | } |
211 | ||
81190958 | 212 | OutputToJDL(*os,"Workdirectorysize","5000MB"); |
a58729a5 | 213 | |
81190958 | 214 | OutputToJDL(*os,"Validationcommand",Form("%s/validation_merge.sh",RemoteDir().Data())); |
a58729a5 | 215 | |
81190958 | 216 | OutputToJDL(*os,"TTL","7200"); |
a58729a5 | 217 | |
81190958 | 218 | OutputToJDL(*os,"OutputArchive", |
a58729a5 | 219 | "log_archive.zip:stderr,stdout@disk=1", |
220 | "root_archive.zip:AliAOD.root,AliAOD.Muons.root,AnalysisResults.root@disk=3" | |
221 | ); | |
222 | ||
81190958 | 223 | OutputToJDL(*os,"Arguments",(final ? "2":"1")); // for AOD_merge.sh, 1 means intermediate merging stage, 2 means final merging |
a58729a5 | 224 | |
225 | if ( !final ) | |
226 | { | |
81190958 | 227 | OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrain.C",RemoteDir().Data())); |
228 | OutputToJDL(*os,"OutputDir",Form("%s/$1/Stage_$2/#alien_counter_03i#",RemoteDir().Data())); | |
229 | OutputToJDL(*os,"InputDataCollection",Form("%s/$1/Stage_$2.xml,nodownload",RemoteDir().Data())); | |
230 | OutputToJDL(*os,"split","se"); | |
231 | OutputToJDL(*os,"SplitMaxInputFileNumber",GetSplitMaxInputFileNumber()); | |
232 | OutputToJDL(*os,"InputDataListFormat","xml-single"); | |
233 | OutputToJDL(*os,"InputDataList","wn.xml"); | |
a58729a5 | 234 | } |
235 | else | |
236 | { | |
81190958 | 237 | OutputToJDL(*os,"InputFile",Form("LF:%s/AODtrain.C",RemoteDir().Data()), |
238 | Form("LF:%s/$1/wn.xml",RemoteDir().Data())); | |
239 | OutputToJDL(*os,"OutputDir",Form("%s/$1",RemoteDir().Data())); | |
a58729a5 | 240 | } |
241 | ||
242 | return kTRUE; | |
243 | } | |
244 | ||
245 | //______________________________________________________________________________ | |
81190958 | 246 | Bool_t AliMuonAccEffSubmitter::GenerateRunJDL(const char* name) const |
a58729a5 | 247 | { |
248 | /// Generate (locally) the JDL to perform the simulation+reco+aod filtering | |
249 | /// (to be then copied to the grid and finally submitted) | |
250 | ||
1afce1ce | 251 | AliDebug(1,""); |
252 | ||
a58729a5 | 253 | std::ostream* os = CreateJDLFile(name); |
254 | ||
255 | if (!os) | |
256 | { | |
257 | return kFALSE; | |
258 | } | |
259 | ||
81190958 | 260 | OutputToJDL(*os,"Packages", |
261 | GetMapValue("AliRoot"), | |
262 | GetMapValue("Geant3"), | |
263 | GetMapValue("Root"), | |
264 | GetMapValue("API")); | |
265 | ||
266 | OutputToJDL(*os,"Jobtag","comment: AliMuonAccEffSubmitter RUN $1"); | |
a58729a5 | 267 | |
81190958 | 268 | OutputToJDL(*os,"split","production:1-$2"); |
a58729a5 | 269 | |
81190958 | 270 | OutputToJDL(*os,"Price","1"); |
a58729a5 | 271 | |
81190958 | 272 | OutputToJDL(*os,"OutputDir",Form("%s/$1/#alien_counter_03i#",RemoteDir().Data())); |
a58729a5 | 273 | |
81190958 | 274 | OutputToJDL(*os,"Executable","/alice/bin/aliroot_new"); |
a58729a5 | 275 | |
276 | TObjArray files; | |
277 | files.SetOwner(kTRUE); | |
278 | TIter next(TemplateFileList()); | |
279 | TObjString* file; | |
280 | ||
281 | while ( ( file = static_cast<TObjString*>(next())) ) | |
282 | { | |
283 | if ( !file->String().Contains(".jdl",TString::kIgnoreCase) || | |
284 | !file->String().Contains("OCDB_") ) | |
285 | { | |
81190958 | 286 | files.Add(new TObjString(Form("LF:%s/%s",RemoteDir().Data(),file->String().Data()))); |
a58729a5 | 287 | } |
288 | } | |
289 | ||
290 | if ( fUseOCDBSnapshots ) | |
291 | { | |
81190958 | 292 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_sim.root",RemoteDir().Data()))); |
293 | files.Add(new TObjString(Form("LF:%s/OCDB/$1/OCDB_rec.root",RemoteDir().Data()))); | |
a58729a5 | 294 | } |
295 | ||
81190958 | 296 | OutputToJDL(*os,"InputFile",files); |
a58729a5 | 297 | |
298 | if ( CompactMode() == 0 ) | |
299 | { | |
300 | // store everything | |
81190958 | 301 | OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1", |
a58729a5 | 302 | "root_archive.zip:galice*.root,Kinematics*.root,TrackRefs*.root,AliESDs.root,AliAOD.root,AliAOD.Muons.root,Merged.QA.Data.root,Run*.root@disk=2"); |
303 | } | |
304 | else if ( CompactMode() == 1 ) | |
305 | { | |
81190958 | 306 | // keep only muon AODs and QA |
307 | OutputToJDL(*os,"OutputArchive", "log_archive.zip:stderr,stdout,aod.log,checkaod.log,checkesd.log,rec.log,sim.log@disk=1", | |
308 | "root_archive.zip:galice*.root,AliAOD.Muons.root,Merged.QA.Data.root@disk=2"); | |
a58729a5 | 309 | } |
310 | else | |
311 | { | |
312 | AliError(Form("Unknown CompactMode %d",CompactMode())); | |
313 | delete os; | |
314 | return kFALSE; | |
315 | } | |
316 | ||
81190958 | 317 | OutputToJDL(*os,"splitarguments","simrun.C --run $1 --chunk #alien_counter# --event $3"); |
a58729a5 | 318 | |
81190958 | 319 | OutputToJDL(*os,"Workdirectorysize","5000MB"); |
a58729a5 | 320 | |
81190958 | 321 | OutputToJDL(*os,"JDLVariables","Packages","OutputDir"); |
a58729a5 | 322 | |
81190958 | 323 | OutputToJDL(*os,"Validationcommand",Form("%s/validation.sh",RemoteDir().Data())); |
a58729a5 | 324 | |
81190958 | 325 | OutputToJDL(*os,"TTL","72000"); |
a58729a5 | 326 | |
327 | return kTRUE; | |
328 | } | |
329 | ||
a58729a5 | 330 | //______________________________________________________________________________ |
331 | Bool_t AliMuonAccEffSubmitter::MakeOCDBSnapshots() | |
332 | { | |
333 | /// Run sim.C and rec.C in a special mode to generate OCDB snapshots | |
334 | /// Can only be done after the templates have been copied locally | |
335 | ||
336 | if (!IsValid()) return kFALSE; | |
337 | ||
338 | if (!fUseOCDBSnapshots) return kTRUE; | |
339 | ||
81190958 | 340 | if (!NofRuns()) return kFALSE; |
a58729a5 | 341 | |
1afce1ce | 342 | AliDebug(1,""); |
343 | ||
a58729a5 | 344 | Bool_t ok(kTRUE); |
345 | ||
81190958 | 346 | const std::vector<int>& runs = RunList(); |
347 | ||
a58729a5 | 348 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) |
349 | { | |
350 | Int_t runNumber = runs[i]; | |
351 | ||
352 | TString ocdbSim(Form("%s/OCDB/%d/OCDB_sim.root",SnapshotDir().Data(),runNumber)); | |
353 | TString ocdbRec(Form("%s/OCDB/%d/OCDB_rec.root",SnapshotDir().Data(),runNumber)); | |
354 | ||
1afce1ce | 355 | if ( !gSystem->AccessPathName(ocdbSim.Data()) && |
a58729a5 | 356 | !gSystem->AccessPathName(ocdbRec.Data()) ) |
357 | { | |
358 | 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)); | |
1afce1ce | 359 | continue; |
a58729a5 | 360 | } |
361 | else | |
362 | { | |
363 | gSystem->Exec(Form("aliroot -b -q -x simrun.C --run %d --snapshot",runNumber)); | |
364 | ||
365 | if ( gSystem->AccessPathName(ocdbSim.Data()) ) | |
366 | { | |
367 | AliError(Form("Could not create OCDB snapshot for simulation")); | |
368 | ok = kFALSE; | |
369 | } | |
370 | ||
371 | if ( gSystem->AccessPathName(ocdbRec.Data()) ) | |
372 | { | |
373 | AliError(Form("Could not create OCDB snapshot for reconstruction")); | |
374 | ok = kFALSE; | |
375 | } | |
376 | } | |
377 | ||
378 | LocalFileList()->Add(new TObjString(ocdbSim)); | |
379 | LocalFileList()->Add(new TObjString(ocdbRec)); | |
380 | } | |
381 | ||
382 | return ok; | |
383 | } | |
384 | ||
385 | //______________________________________________________________________________ | |
386 | Bool_t AliMuonAccEffSubmitter::Merge(Int_t stage, Bool_t dryRun) | |
387 | { | |
388 | /// Submit multiple merging jobs with the format "submit AOD_merge(_final).jdl run# (stage#)". | |
389 | /// Also produce the xml collection before sending jobs | |
390 | /// Initial AODs will be taken from fRemoteDir/[RUNNUMBER] while the merged | |
391 | /// ones will be put into fMergedDir/AODs/[RUNNUMBER] | |
392 | /// | |
393 | /// Example: | |
394 | /// - inDir = "/alice/sim/2012/LHC12a10_bis" (where to find the data to merge) | |
395 | /// = 0x0 --> inDir = homeDir/outDir/resDir | |
396 | /// - outDir = "Sim/LHC11h/embedding/AODs" (where to store merged results) | |
397 | /// - runList.txt must contains the list of run number | |
398 | /// - stage=0 --> final merging / stage>0 --> intermediate merging i | |
399 | /// | |
400 | ||
81190958 | 401 | if (!RemoteDirectoryExists(MergedDir().Data())) { |
402 | AliError(Form("directory %s does not exist", MergedDir().Data())); | |
a58729a5 | 403 | return kFALSE; |
404 | } | |
405 | ||
81190958 | 406 | gGrid->Cd(MergedDir().Data()); |
a58729a5 | 407 | |
408 | TString jdl = MergeJDLName(stage==0); | |
409 | ||
410 | if (!RemoteFileExists(jdl.Data())) | |
411 | { | |
81190958 | 412 | AliError(Form("file %s does not exist in %s\n", jdl.Data(), RemoteDir().Data())); |
a58729a5 | 413 | return kFALSE; |
414 | } | |
415 | ||
81190958 | 416 | const std::vector<int>& runs = RunList(); |
a58729a5 | 417 | |
418 | if (runs.empty()) | |
419 | { | |
420 | AliError("No run to work with"); | |
421 | return kFALSE; | |
422 | } | |
423 | ||
424 | TString currRun; | |
425 | TString reply = ""; | |
426 | gSystem->Exec("rm -f __failed__"); | |
427 | Bool_t failedRun = kFALSE; | |
428 | ||
429 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) | |
430 | { | |
431 | Int_t run = runs[i]; | |
432 | AliInfo(Form("\n --- processing run %d ---\n", run)); | |
433 | ||
81190958 | 434 | TString runDir = Form("%s/%d", MergedDir().Data(), run); |
a58729a5 | 435 | |
436 | if (!RemoteDirectoryExists(runDir.Data())) | |
437 | { | |
438 | AliInfo(Form(" - creating output directory %s\n", runDir.Data())); | |
439 | gSystem->Exec(Form("alien_mkdir -p %s", runDir.Data())); | |
440 | } | |
441 | ||
442 | if (RemoteFileExists(Form("%s/root_archive.zip", runDir.Data()))) | |
443 | { | |
444 | AliWarning(" ! final merging already done"); | |
445 | continue; | |
446 | } | |
447 | ||
448 | Int_t lastStage = GetLastStage(runDir.Data()); | |
449 | ||
450 | if (stage > 0 && stage != lastStage+1) | |
451 | { | |
452 | AliError(Form(" ! lastest merging stage = %d. Next must be stage %d or final stage\n", lastStage, lastStage+1)); | |
453 | continue; | |
454 | } | |
455 | ||
456 | TString wn = (stage > 0) ? Form("Stage_%d.xml", stage) : "wn.xml"; | |
457 | TString find = (lastStage == 0) ? | |
81190958 | 458 | Form("alien_find -x %s %s/%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run) : |
459 | Form("alien_find -x %s %s/%d/Stage_%d *root_archive.zip", wn.Data(), RemoteDir().Data(), run, lastStage); | |
a58729a5 | 460 | gSystem->Exec(Form("%s 1> %s 2>/dev/null", find.Data(), wn.Data())); |
461 | gSystem->Exec(Form("grep -c /event %s > __nfiles__", wn.Data())); | |
462 | ifstream f2("__nfiles__"); | |
463 | TString nFiles; | |
464 | nFiles.ReadLine(f2,kTRUE); | |
465 | f2.close(); | |
466 | gSystem->Exec("rm -f __nfiles__"); | |
467 | printf(" - number of files to merge = %d\n", nFiles.Atoi()); | |
468 | if (nFiles.Atoi() == 0) { | |
469 | printf(" ! collection of files to merge is empty\n"); | |
470 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
471 | continue; | |
472 | } else if (stage > 0 && nFiles.Atoi() <= splitLevel && !reply.BeginsWith("y")) { | |
473 | if (!reply.BeginsWith("n")) { | |
474 | printf(" ! number of files to merge <= split level (%d). Continue? [Y/n] ", splitLevel); | |
475 | fflush(stdout); | |
476 | reply.Gets(stdin,kTRUE); | |
477 | reply.ToLower(); | |
478 | } | |
479 | if (reply.BeginsWith("n")) { | |
480 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
481 | continue; | |
482 | } else reply = "y"; | |
483 | } | |
484 | ||
485 | if (!dryRun) | |
486 | { | |
487 | TString dirwn = Form("%s/%s", runDir.Data(), wn.Data()); | |
488 | if (RemoteFileExists(dirwn.Data())) gGrid->Rm(dirwn.Data()); | |
489 | gSystem->Exec(Form("alien_cp file:%s alien://%s", wn.Data(), dirwn.Data())); | |
490 | gSystem->Exec(Form("rm -f %s", wn.Data())); | |
491 | } | |
492 | ||
493 | TString query; | |
494 | if (stage > 0) query = Form("submit %s %d %d", jdl.Data(), run, stage); | |
495 | else query = Form("submit %s %d", jdl.Data(), run); | |
496 | printf(" - %s ...", query.Data()); | |
497 | fflush(stdout); | |
498 | ||
499 | if (dryRun) | |
500 | { | |
501 | AliInfo(" dry run"); | |
502 | continue; | |
503 | } | |
504 | ||
505 | Bool_t done = kFALSE; | |
506 | TGridResult *res = gGrid->Command(query); | |
507 | if (res) | |
508 | { | |
509 | TString cjobId1 = res->GetKey(0,"jobId"); | |
510 | if (!cjobId1.IsDec()) | |
511 | { | |
512 | AliError(" FAILED"); | |
513 | gGrid->Stdout(); | |
514 | gGrid->Stderr(); | |
515 | } | |
516 | else | |
517 | { | |
518 | AliInfo(Form(" DONE\n --> the job Id is: %s \n", cjobId1.Data())); | |
519 | done = kTRUE; | |
520 | } | |
521 | delete res; | |
522 | } | |
523 | else | |
524 | { | |
525 | AliError(" FAILED"); | |
526 | } | |
527 | ||
528 | if (!done) | |
529 | { | |
530 | gSystem->Exec(Form("echo %d >> __failed__", run)); | |
531 | failedRun = kTRUE; | |
532 | } | |
533 | ||
534 | } | |
535 | ||
536 | if (failedRun) | |
537 | { | |
538 | AliInfo("\n--------------------\n"); | |
539 | AliInfo("list of failed runs:\n"); | |
540 | gSystem->Exec("cat __failed__"); | |
541 | gSystem->Exec("rm -f __failed__"); | |
542 | return kFALSE; | |
543 | } | |
544 | ||
545 | return kTRUE; | |
546 | } | |
547 | ||
548 | //______________________________________________________________________________ | |
81190958 | 549 | void AliMuonAccEffSubmitter::Print(Option_t* opt) const |
a58729a5 | 550 | { |
1afce1ce | 551 | /// Printout |
552 | ||
81190958 | 553 | AliMuonGridSubmitter::Print(opt); |
554 | ||
a58729a5 | 555 | if ( fRatio > 0 ) |
556 | { | |
557 | std::cout << Form("For each run, will generate %5.2f times the number of real events for trigger %s", | |
81190958 | 558 | fRatio,ReferenceTrigger().Data()) << std::endl; |
a58729a5 | 559 | } |
560 | else | |
561 | { | |
562 | std::cout << Form("For each run, will generate %10d events",fFixedNofEvents) << std::endl; | |
563 | } | |
564 | ||
565 | std::cout << "MaxEventsPerChunk = " << fMaxEventsPerChunk << std::endl; | |
566 | ||
81190958 | 567 | std::cout << "Will" << (fUseOCDBSnapshots ? "" : " NOT") << " use OCDB snaphosts" << std::endl; |
a58729a5 | 568 | } |
569 | ||
570 | //______________________________________________________________________________ | |
571 | Bool_t AliMuonAccEffSubmitter::Run(const char* mode) | |
572 | { | |
573 | /// mode can be one of (case insensitive) | |
574 | /// | |
575 | /// LOCAL : copy the template files from the template directory to the local one | |
576 | /// UPLOAD : copy the local files to the grid (requires LOCAL) | |
577 | /// OCDB : make ocdb snapshots (requires LOCAL) | |
578 | /// SUBMIT : submit the jobs (requires LOCAL + UPLOAD) | |
579 | /// FULL : all of the above (requires all of the above) | |
580 | /// | |
581 | /// TEST : as SUBMIT, but in dry mode (does not actually submit the jobs) | |
582 | ||
583 | if (!IsValid()) return kFALSE; | |
584 | ||
585 | TString smode(mode); | |
586 | smode.ToUpper(); | |
587 | ||
588 | if ( smode == "FULL") | |
589 | { | |
590 | return ( Run("LOCAL") && Run("OCDB") && Run("UPLOAD") && Run("SUBMIT") ); | |
591 | } | |
592 | ||
593 | if ( smode == "LOCAL") | |
594 | { | |
595 | return CopyTemplateFilesToLocal(); | |
596 | } | |
597 | ||
598 | if ( smode == "UPLOAD" ) | |
599 | { | |
600 | return (CopyLocalFilesToRemote()); | |
601 | } | |
602 | ||
603 | if ( smode == "OCDB" ) | |
604 | { | |
605 | Bool_t ok = Run("LOCAL"); | |
606 | if (ok) | |
607 | { | |
608 | ok = MakeOCDBSnapshots(); | |
609 | } | |
610 | return ok; | |
611 | } | |
612 | ||
613 | if ( smode == "TEST" ) | |
614 | { | |
615 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
616 | if ( ok ) | |
617 | { | |
618 | ok = (Submit(kTRUE)>0); | |
619 | } | |
620 | return ok; | |
621 | } | |
622 | ||
623 | if ( smode == "FULL" ) | |
624 | { | |
625 | Bool_t ok = Run("LOCAL") && Run("OCDB") && Run("UPLOAD"); | |
626 | if ( ok ) | |
627 | { | |
628 | ok = (Submit(kFALSE)>0); | |
629 | } | |
630 | return ok; | |
631 | } | |
632 | ||
633 | if( smode == "SUBMIT" ) | |
634 | { | |
635 | return (Submit(kFALSE)>0); | |
636 | } | |
637 | ||
638 | return kFALSE; | |
639 | } | |
640 | ||
1afce1ce | 641 | //______________________________________________________________________________ |
642 | Bool_t AliMuonAccEffSubmitter::SetGenerator(const char* generator) | |
643 | { | |
644 | // set the variable to select the generator macro in Config.C | |
645 | ||
646 | gSystem->Load("libEVGEN"); | |
1afce1ce | 647 | |
81190958 | 648 | Invalidate(); |
649 | ||
650 | TString generatorFile(Form("%s/%s.C",TemplateDir().Data(),generator)); | |
1afce1ce | 651 | |
652 | Int_t nofMissingVariables(0); | |
653 | ||
654 | // first check we indeed have such a macro | |
655 | if (!gSystem->AccessPathName(generatorFile.Data())) | |
656 | { | |
657 | TObjArray* variables = GetVariables(generatorFile.Data()); | |
658 | ||
659 | TIter next(variables); | |
660 | TObjString* var; | |
661 | ||
662 | while ( ( var = static_cast<TObjString*>(next())) ) | |
663 | { | |
81190958 | 664 | if ( !Vars()->GetValue(var->String()) ) |
1afce1ce | 665 | { |
666 | ++nofMissingVariables; | |
667 | AliError(Form("file %s expect the variable %s to be defined, but we've not defined it !",generatorFile.Data(),var->String().Data())); | |
668 | } | |
669 | } | |
670 | ||
671 | delete variables; | |
672 | ||
673 | if ( !nofMissingVariables ) | |
674 | { | |
675 | if (CheckCompilation(generatorFile.Data())) | |
676 | { | |
81190958 | 677 | Validate(); |
1afce1ce | 678 | SetVar("VAR_GENERATOR",Form("%s",generator)); |
81190958 | 679 | AddToTemplateFileList(Form("%s.C",generator)); |
1afce1ce | 680 | return kTRUE; |
681 | } | |
682 | } | |
683 | else | |
684 | { | |
685 | return kFALSE; | |
686 | } | |
687 | } | |
688 | else | |
689 | { | |
690 | AliError(Form("Can not work with the macro %s",generatorFile.Data())); | |
691 | } | |
692 | return kFALSE; | |
693 | } | |
694 | ||
1afce1ce | 695 | //______________________________________________________________________________ |
696 | void AliMuonAccEffSubmitter::SetOCDBPath(const char* ocdbPath) | |
697 | { | |
698 | /// Sets the OCDB path to be used | |
699 | ||
81190958 | 700 | SetMapKeyValue("OCDBPath",ocdbPath); |
1afce1ce | 701 | } |
702 | ||
703 | ||
704 | //______________________________________________________________________________ | |
705 | void AliMuonAccEffSubmitter::SetOCDBSnapshotDir(const char* dir) | |
706 | { | |
707 | // change the directory used for snapshot | |
708 | ||
709 | if (gSystem->AccessPathName(Form("%s/OCDB",dir))) | |
710 | { | |
711 | AliError(Form("Snapshot top directory (%s) should contain an OCDB subdir with runnumbers in there",dir)); | |
712 | } | |
713 | else | |
714 | { | |
81190958 | 715 | SetMapKeyValue("OCDBSnapshot",dir); |
1afce1ce | 716 | } |
717 | } | |
718 | ||
a58729a5 | 719 | //______________________________________________________________________________ |
81190958 | 720 | void AliMuonAccEffSubmitter::MakeNofEventsPropToTriggerCount(const char* trigger, Float_t ratio) |
a58729a5 | 721 | { |
81190958 | 722 | SetMapKeyValue("ReferenceTrigger",trigger); |
723 | fRatio = ratio; | |
724 | } | |
725 | ||
726 | //______________________________________________________________________________ | |
727 | void AliMuonAccEffSubmitter::MakeNofEventsFixed(Int_t nevents) | |
728 | { | |
729 | fFixedNofEvents = nevents; | |
730 | fRatio=0.0; | |
731 | SetMapKeyValue("ReferenceTrigger",""); | |
a58729a5 | 732 | } |
733 | ||
81190958 | 734 | |
a58729a5 | 735 | //______________________________________________________________________________ |
736 | Int_t AliMuonAccEffSubmitter::Submit(Bool_t dryRun) | |
737 | { | |
738 | /// Submit multiple production jobs with the format "submit jdl 000run#.xml 000run#". | |
739 | /// | |
740 | /// Return the number of submitted (master) jobs | |
741 | /// | |
742 | /// Example: | |
743 | /// - outputDir = "/alice/cern.ch/user/p/ppillot/Sim/LHC10h/JPsiPbPb276/AlignRawVtxRaw/ESDs" | |
744 | /// - runList must contains the list of run number | |
745 | /// - trigger is the (fully qualified) trigger name used to compute the base number of events | |
746 | /// - mult is the factor to apply to the number of trigger to get the number of events to be generated | |
747 | /// (# generated events = # triggers x mult | |
748 | ||
749 | if (!IsValid()) return 0; | |
750 | ||
1afce1ce | 751 | AliDebug(1,""); |
752 | ||
a58729a5 | 753 | gGrid->Cd(RemoteDir()); |
754 | ||
755 | if (!RemoteFileExists(RunJDLName())) | |
756 | { | |
757 | AliError(Form("file %s does not exist in %s", RunJDLName().Data(), RemoteDir().Data())); | |
758 | return 0; | |
759 | } | |
760 | ||
81190958 | 761 | if ( !NofRuns() ) |
a58729a5 | 762 | { |
763 | AliError("No run list set. Use SetRunList"); | |
764 | return 0; | |
765 | } | |
81190958 | 766 | const std::vector<int>& runs = RunList(); |
a58729a5 | 767 | |
768 | if (runs.empty()) | |
769 | { | |
770 | AliError("No run to work with"); | |
771 | return 0; | |
772 | } | |
773 | ||
774 | // cout << "total number of selected MB events = " << totEvt << endl; | |
775 | // cout << "required number of generated events = " << nGenEvents << endl; | |
776 | // cout << "number of generated events per MB event = " << ratio << endl; | |
777 | // cout << endl; | |
778 | ||
779 | std::cout << "run\tchunks\tevents" << std::endl; | |
780 | std::cout << "----------------------" << std::endl; | |
781 | ||
782 | Int_t nJobs(0); | |
783 | Int_t nEvts(0); | |
784 | ||
81190958 | 785 | AliAnalysisTriggerScalers* ts(0x0); |
786 | ||
a58729a5 | 787 | for (std::vector<int>::size_type i=0; i < runs.size(); ++i) |
788 | { | |
789 | Int_t runNumber = runs[i]; | |
790 | ||
791 | Int_t nEvtRun(fFixedNofEvents); | |
792 | ||
793 | if ( fRatio > 0 ) | |
794 | { | |
81190958 | 795 | if (!ts) |
796 | { | |
797 | AliInfo(Form("Creating AliAnalysisTriggerScalers from OCDB=%s",OCDBPath().Data())); | |
798 | ts = new AliAnalysisTriggerScalers(runs,OCDBPath().Data()); | |
799 | } | |
800 | ||
801 | AliAnalysisTriggerScalerItem* trigger = ts->GetTriggerScaler(runNumber, "L2A", ReferenceTrigger().Data()); | |
a58729a5 | 802 | |
803 | if (!trigger) | |
804 | { | |
805 | AliError(Form("Could not get trigger %s for run %09d",ReferenceTrigger().Data(),runNumber)); | |
806 | continue; | |
807 | } | |
808 | nEvtRun = TMath::Nint(fRatio * trigger->Value()); | |
809 | } | |
810 | ||
811 | Int_t nChunk = 1; | |
812 | ||
813 | while (nEvtRun/nChunk+0.5 > MaxEventsPerChunk()) | |
814 | { | |
815 | ++nChunk; | |
816 | } | |
817 | ||
818 | Int_t nEvtChunk = TMath::Nint(nEvtRun/nChunk + 0.5); | |
819 | ||
820 | nJobs += nChunk; | |
821 | ||
822 | nEvts += nChunk*nEvtChunk; | |
823 | ||
824 | std::cout << runNumber << "\t" << nChunk << "\t" << nEvtChunk << std::endl; | |
825 | ||
826 | TString query(Form("submit %s %d %d %d", RunJDLName().Data(), runNumber, nChunk, nEvtChunk)); | |
827 | ||
828 | std::cout << query.Data() << " ..." << std::flush; | |
829 | ||
830 | TGridResult* res = 0x0; | |
831 | ||
832 | if (!dryRun) | |
833 | { | |
834 | res = gGrid->Command(query); | |
835 | } | |
836 | ||
837 | if (res) | |
838 | { | |
839 | TString cjobId1 = res->GetKey(0,"jobId"); | |
840 | ||
841 | if (!cjobId1.Length()) | |
842 | { | |
843 | std::cout << " FAILED" << std::endl << std::endl; | |
844 | gGrid->Stdout(); | |
845 | gGrid->Stderr(); | |
846 | } | |
847 | else | |
848 | { | |
849 | std::cout << "DONE" << std::endl; | |
850 | std::cout << Form(" --> the job Id is: %s",cjobId1.Data()) << std::endl << std::endl; | |
851 | } | |
852 | } | |
853 | else | |
854 | { | |
855 | std::cout << " FAILED" << std::endl << std::endl; | |
856 | } | |
857 | ||
858 | delete res; | |
859 | } | |
860 | ||
861 | std::cout << std::endl | |
862 | << "total number of jobs = " << nJobs << std::endl | |
863 | << "total number of generated events = " << nEvts << std::endl | |
864 | << std::endl; | |
865 | ||
81190958 | 866 | delete ts; |
a58729a5 | 867 | |
81190958 | 868 | return nJobs; |
a58729a5 | 869 | } |
870 | ||
871 | //______________________________________________________________________________ | |
872 | void AliMuonAccEffSubmitter::UpdateLocalFileList(Bool_t clearSnapshots) | |
873 | { | |
1afce1ce | 874 | /// Update the list of local files |
875 | ||
81190958 | 876 | AliMuonGridSubmitter::UpdateLocalFileList(); |
877 | ||
878 | if (!NofRuns()) return; | |
a58729a5 | 879 | |
880 | if ( clearSnapshots ) | |
881 | { | |
882 | TIter next(LocalFileList()); | |
883 | TObjString* file; | |
884 | ||
885 | while ( ( file = static_cast<TObjString*>(next())) ) | |
886 | { | |
887 | if ( file->String().Contains("OCDB_") ) | |
888 | { | |
889 | LocalFileList()->Remove(file); | |
890 | } | |
891 | } | |
892 | LocalFileList()->Compress(); | |
893 | } | |
894 | ||
a58729a5 | 895 | const char* type[] = { "sim","rec" }; |
896 | ||
81190958 | 897 | const std::vector<int>& runs = RunList(); |
898 | ||
a58729a5 | 899 | for ( std::vector<int>::size_type i = 0; i < runs.size(); ++i ) |
900 | { | |
901 | Int_t runNumber = runs[i]; | |
902 | ||
903 | for ( Int_t t = 0; t < 2; ++t ) | |
904 | { | |
905 | TString snapshot(Form("%s/OCDB/%d/OCDB_%s.root",SnapshotDir().Data(),runNumber,type[t])); | |
906 | ||
907 | if ( !gSystem->AccessPathName(snapshot.Data()) ) | |
908 | { | |
909 | if ( !LocalFileList()->FindObject(snapshot.Data()) ) | |
910 | { | |
911 | LocalFileList()->Add(new TObjString(snapshot)); | |
912 | } | |
913 | } | |
914 | } | |
915 | } | |
a58729a5 | 916 | } |
917 | ||
918 | //______________________________________________________________________________ | |
919 | void AliMuonAccEffSubmitter::UseOCDBSnapshots(Bool_t flag) | |
920 | { | |
1afce1ce | 921 | /// Whether or not to use OCDB snapshots |
922 | /// Using OCDB snapshots will speed-up both the sim and reco initialization | |
923 | /// phases on each worker node, but takes time to produce... | |
924 | /// So using them is not always a win-win... | |
925 | ||
a58729a5 | 926 | fUseOCDBSnapshots = flag; |
927 | if ( flag ) | |
928 | { | |
929 | SetVar("VAR_OCDB_SNAPSHOT","kTRUE"); | |
930 | } | |
931 | else | |
932 | { | |
933 | SetVar("VAR_OCDB_SNAPSHOT","kFALSE"); | |
934 | } | |
935 | ||
936 | UpdateLocalFileList(); | |
937 | } | |
938 | ||
a3c2a88b | 939 | //______________________________________________________________________________ |
940 | void AliMuonAccEffSubmitter::UseAODMerging(Bool_t flag) | |
941 | { | |
942 | /// whether or not we should generate JDL for merging AODs | |
943 | ||
944 | fUseAODMerging = flag; | |
81190958 | 945 | |
946 | AddToTemplateFileList(MergeJDLName(kFALSE).Data()); | |
947 | AddToTemplateFileList(MergeJDLName(kTRUE).Data()); | |
948 | AddToTemplateFileList("AOD_merge.sh"); | |
949 | AddToTemplateFileList("validation_merge.sh"); | |
950 | } | |
951 | ||
952 | //______________________________________________________________________________ | |
953 | void AliMuonAccEffSubmitter::UseExternalConfig(const char* externalConfigFullFilePath) | |
954 | { | |
955 | // use an external config (or the default Config.C if externalConfigFullFilePath="") | |
956 | ||
957 | fExternalConfig = externalConfigFullFilePath; | |
958 | if ( fExternalConfig.Length() > 0 ) | |
959 | { | |
960 | AddToTemplateFileList(fExternalConfig); | |
961 | } | |
962 | else | |
963 | { | |
964 | AddToTemplateFileList("Config.C"); | |
965 | } | |
a3c2a88b | 966 | } |