]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG/muondep/AliMuonAccEffSubmitter.cxx
Merge branch 'Diego_3'
[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//______________________________________________________________________________
1afce1ce 80AliMuonAccEffSubmitter::AliMuonAccEffSubmitter(const char* generator)
81190958 81: AliMuonGridSubmitter(AliMuonGridSubmitter::kAccEff),
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
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 153AliMuonAccEffSubmitter::~AliMuonAccEffSubmitter()
a58729a5 154{
81190958 155 // dtor
a58729a5 156}
157
81190958 158///______________________________________________________________________________
159Bool_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 172Bool_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 246Bool_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//______________________________________________________________________________
331Bool_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//______________________________________________________________________________
386Bool_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 549void 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//______________________________________________________________________________
571Bool_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//______________________________________________________________________________
642Bool_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//______________________________________________________________________________
696void 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//______________________________________________________________________________
705void 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 720void AliMuonAccEffSubmitter::MakeNofEventsPropToTriggerCount(const char* trigger, Float_t ratio)
a58729a5 721{
81190958 722 SetMapKeyValue("ReferenceTrigger",trigger);
723 fRatio = ratio;
724}
725
726//______________________________________________________________________________
727void AliMuonAccEffSubmitter::MakeNofEventsFixed(Int_t nevents)
728{
729 fFixedNofEvents = nevents;
730 fRatio=0.0;
731 SetMapKeyValue("ReferenceTrigger","");
a58729a5 732}
733
81190958 734
a58729a5 735//______________________________________________________________________________
736Int_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//______________________________________________________________________________
872void 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//______________________________________________________________________________
919void 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//______________________________________________________________________________
940void 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//______________________________________________________________________________
953void 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}