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