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