1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 // AliMuonGridSubmitter : a class to help submit jobs for several runs
19 // This class is dealing with 3 different directories :
21 // - template directory ($ALICE_ROOT/PWG/muondep/XXXTemplates) containing the
22 // basic template files to be used for a particular job type (XXX). A template can contain
23 // some variables that will be replaced during during the copy from template
26 // - local directory, where the files from the template directory, are copied
27 // once the class has been configured properly (i.e. using the various Set, Use,
28 // etc... methods). Some other files (e.g. JDL ones) are generated from
29 // scratch and also copied into this directory.
30 // At this point one could(should) check the files, as they are the ones
31 // to be copied to the remote directory for the production
33 // - remote directory, the alien directory where the files will be copied
34 // (from the local directory) before the actual submission
36 // author: Laurent Aphecetche (Subatech
39 #include "AliMuonGridSubmitter.h"
44 #include "TGridResult.h"
47 #include "TObjString.h"
52 #include "AliAnalysisTriggerScalers.h"
53 #include "Riostream.h"
55 //______________________________________________________________________________
56 AliMuonGridSubmitter::AliMuonGridSubmitter(AliMuonGridSubmitter::EJobType jobType)
61 fShouldOverwriteFiles(kFALSE),
62 fTemplateFileList(0x0),
69 TGrid::Connect("alien://");
72 AliError("cannot connect to grid");
76 SetPackages("VO_ALICE@AliRoot::v5-04-46-AN","VO_ALICE@GEANT3::v1-15","VO_ALICE@ROOT::v5-34-05");
78 TString basedir = gSystem->ExpandPathName("$ALICE_ROOT/PWG/muondep");
81 dir.Form("%s/%sTemplates",basedir.Data(),JobTypeName(jobType).Data());
83 if (!SetTemplateDir(dir.Data()))
85 AliError(Form("Could not find %s directory. Please check.",dir.Data()));
88 SetLocalDir(gSystem->pwd());
91 //______________________________________________________________________________
92 AliMuonGridSubmitter::~AliMuonGridSubmitter()
95 delete fTemplateFileList;
96 delete fLocalFileList;
101 //______________________________________________________________________________
102 void AliMuonGridSubmitter::AddToTemplateFileList(const char* filename)
104 // add a file to the list of templates
105 // and update the local file list if needed
107 TObjArray* a = TemplateFileList();
109 if ( !a->FindObject(filename) )
111 a->Add(new TObjString(filename));
112 UpdateLocalFileList();
116 //______________________________________________________________________________
117 Bool_t AliMuonGridSubmitter::CheckCompilation(const char* file) const
119 /// Check whether file can be compiled or not
120 /// FIXME: use gSystem->TempFileName for tmpfile !
124 TString sfile(gSystem->BaseName(file));
125 TString tmpfile(Form("tmpfile_%s",sfile.Data()));
127 gSystem->Exec(Form("cp %s %s",file,tmpfile.Data()));
129 ReplaceVars(tmpfile.Data());
131 gSystem->AddIncludePath("-I$ALICE_ROOT/include");
132 gSystem->AddIncludePath("-I$ALICE_ROOT/EVGEN");
134 if (gROOT->LoadMacro(Form("%s++",tmpfile.Data())))
136 AliError(Form("macro %s can not be compiled. Please check.",file));
140 gSystem->Exec(Form("rm %s",tmpfile.Data()));
146 //______________________________________________________________________________
147 Bool_t AliMuonGridSubmitter::CheckLocal() const
149 /// Check whether all required local files are there
150 TIter next(LocalFileList());
153 while ( ( file = static_cast<TObjString*>(next())) )
155 if ( gSystem->AccessPathName(file->String().Data()) )
164 //______________________________________________________________________________
165 Bool_t AliMuonGridSubmitter::CheckRemote() const
167 /// Check whether all required remote files are there
168 AliWarning("implement me");
172 //______________________________________________________________________________
173 void AliMuonGridSubmitter::CleanLocal(const char* excludeList) const
175 /// Clean (remove) local generated files
176 /// exclude contains a list of comma separated pattern of files
179 TIter next(LocalFileList());
181 TObjArray* excludeArray = TString(excludeList).Tokenize(",");
183 while ( ( file = static_cast<TObjString*>(next())) )
185 Bool_t shouldExclude(kFALSE);
187 TIter nextExclude(excludeArray);
190 while ( ( s = static_cast<TObjString*>(nextExclude())) && !shouldExclude )
192 if ( file->String().Contains(s->String()) ) shouldExclude=kTRUE;
197 gSystem->Unlink(file->String().Data());
204 //______________________________________________________________________________
205 Bool_t AliMuonGridSubmitter::CopyFile(const char* localFile)
207 /// copy a local file to remote destination
210 if ( gSystem->IsAbsoluteFileName(localFile) )
216 local = Form("%s/%s",LocalDir().Data(),gSystem->ExpandPathName(localFile));
219 if (gSystem->AccessPathName(local.Data()))
221 AliErrorClass(Form("Local file %s does not exist",local.Data()));
227 remote += RemoteDir().Data();
230 if ( gSystem->IsAbsoluteFileName(localFile) )
232 TString tmp(localFile);
233 tmp.ReplaceAll(GetMapValue("Snapshot"),"");
234 tmp.ReplaceAll(GetMapValue("Local"),"");
242 TString dirName = gSystem->DirName(remote.Data());
246 if (!RemoteDirectoryExists(dirName.Data()))
248 ok = gGrid->Mkdir(dirName.Data(),"-p");
253 AliDebugClass(1,Form("cp %s alien://%s",local.Data(),remote.Data()));
254 return TFile::Cp(local.Data(),Form("alien://%s",remote.Data()));
262 //______________________________________________________________________________
263 Bool_t AliMuonGridSubmitter::CheckRemoteDir() const
265 /// Check we have a grid connection and that the remote dir exists
267 if (RemoteDir().IsNull())
269 AliError("you must provide the grid location where to copy the files");
273 if (!RemoteDirectoryExists(RemoteDir()))
275 AliError(Form("directory %s does not exist", RemoteDir().Data()));
282 //______________________________________________________________________________
283 Bool_t AliMuonGridSubmitter::CopyLocalFilesToRemote()
285 /// copy all files necessary to run the simulation into remote directory
287 TIter next(LocalFileList());
292 while ( ( ftc = static_cast<TObjString*>(next())) )
294 allok = allok && CopyFile(ftc->String());
299 //______________________________________________________________________________
300 Bool_t AliMuonGridSubmitter::CopyTemplateFilesToLocal()
302 // copy (or generate) local files from the template ones
304 if (!IsValid()) return kFALSE;
308 TIter next(TemplateFileList());
312 Bool_t potentialProblem(kFALSE);
314 while ( ( file = static_cast<TObjString*>(next())) )
316 if ( file->String().Contains("OCDB") )
318 /// OCDB snapshots are not in template
322 if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(file->String().Data()) )
324 AliError(Form("Local file %s already exists. Remove it first if you want to update overwrite it",file->String().Data()));
325 potentialProblem = kTRUE;
329 TString stemplate(Form("%s/%s",TemplateDir().Data(),file->String().Data()));
330 TString slocal(Form("%s/%s",LocalDir().Data(),file->String().Data()));
332 Int_t c = gSystem->CopyFile(stemplate.Data(),slocal.Data(),ShouldOverwriteFiles());
336 if ( stemplate.Contains(".jdl",TString::kIgnoreCase) )
338 ok = Generate(file->String().Data());
342 AliError(Form("Error %d copying file %s",c,stemplate.Data()));
351 if ( HasVars(slocal.Data()) )
353 if (!ReplaceVars(slocal.Data()))
355 AliError("pb in ReplaceVars");
364 if ( potentialProblem )
366 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 !");
372 //______________________________________________________________________________
373 std::ostream* AliMuonGridSubmitter::CreateJDLFile(const char* name) const
375 /// Create a (local and empty) JDL file
379 TString jdl(Form("%s/%s",LocalDir().Data(),name));
381 if ( !ShouldOverwriteFiles() && !gSystem->AccessPathName(jdl.Data()) )
383 AliErrorClass(Form("File %s already exists. Remove it if you want to overwrite it",jdl.Data()));
387 std::ofstream* os = new std::ofstream(gSystem->ExpandPathName(jdl.Data()));
391 AliErrorClass(Form("Cannot create file %s",jdl.Data()));
399 //______________________________________________________________________________
400 Int_t AliMuonGridSubmitter::GetLastStage(const char* remoteDir)
402 /// Get the last staging phase already performed
404 TGridResult* r = gGrid->Ls(remoteDir);
407 Int_t offset = TString("Stage_").Length();
409 while ( r->GetFileName(i) )
411 TString file(r->GetFileName(i));
412 if (file.BeginsWith("Stage_") && !file.Contains("xml") )
414 Int_t n = TString(file(offset,file.Length()-offset)).Atoi();
415 lastStage = TMath::Max(lastStage,n);
423 //______________________________________________________________________________
424 TString AliMuonGridSubmitter::GetMapValue(const char* key) const
426 // convenience method to access internal map of TObjStrings
427 if (!fInternalMap) return "";
429 TObject* o = fInternalMap->GetValue(key);
433 return static_cast<TObjString*>(o)->String();
439 //______________________________________________________________________________
440 TObjArray* AliMuonGridSubmitter::GetVariables(const char* file) const
442 /// Find the variables in the file
444 std::ifstream in(file);
446 TObjArray* variables(0x0);
448 while ( in.getline(line,1023,'\n') )
451 while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
453 Int_t i1 = sline.Index("VAR_");
456 while ( ( i2 < sline.Length() ) && ( isalnum(sline[i2]) || sline[i2]=='_' ) ) ++i2;
460 variables = new TObjArray;
461 variables->SetOwner(kTRUE);
464 TString var = sline(i1,i2-i1);
465 if ( !variables->FindObject(var) )
467 variables->Add(new TObjString(var));
469 sline.ReplaceAll(var,"");
478 //______________________________________________________________________________
479 Bool_t AliMuonGridSubmitter::HasVars(const char* file) const
481 /// Whether or not the file contains variables that have to
484 std::ifstream in(file);
486 while ( in.getline(line,1023,'\n') )
489 if (sline.Contains("VAR_") && !sline.BeginsWith("//") )
497 //______________________________________________________________________________
498 TMap* AliMuonGridSubmitter::InternalMap() const
502 fInternalMap = new TMap;
503 fInternalMap->SetOwnerKeyValue(kTRUE,kTRUE);
508 //______________________________________________________________________________
509 TString AliMuonGridSubmitter::JobTypeName(AliMuonGridSubmitter::EJobType jobType) const
511 if ( jobType == kAccEff )
515 else if ( jobType == kQAMerge)
522 //______________________________________________________________________________
523 TObjArray* AliMuonGridSubmitter::LocalFileList() const
525 /// Return (after createing and filling it if needed)
526 /// the internal file list with paths from the local directory
530 fLocalFileList = static_cast<TObjArray*>(TemplateFileList()->Clone());
533 return fLocalFileList;
536 //______________________________________________________________________________
537 UInt_t AliMuonGridSubmitter::NofRuns() const
539 // number of runs we're dealing with
540 return fRunList.size();
543 //______________________________________________________________________________
544 void AliMuonGridSubmitter::OutputToJDL(std::ostream& out, const char* key,
545 const TObjArray& values) const
547 /// output to ostream of key,{values} pair
551 Int_t n = values.GetEntries();
555 out << "{" << std::endl;
559 while ( ( v = static_cast<TObjString*>(next())) )
562 out << "\t\"" << v->String().Data() << "\"";
570 TString& v1 = static_cast<TObjString*>(values.At(0))->String();
572 if ( v1.IsDigit() && !(TString(key).Contains("SplitMax")) && !(TString(key).Contains("TTL")) )
578 out << "\"" << v1.Data() << "\"";
581 out << ";" << std::endl;
584 //______________________________________________________________________________
585 void AliMuonGridSubmitter::OutputToJDL(std::ostream& out, const char* key, const char* v1,
586 const char* v2, const char* v3, const char* v4,
587 const char* v5, const char* v6, const char* v7,
588 const char* v8, const char* v9) const
590 /// output to ostream
593 values.SetOwner(kTRUE);
595 values.Add(new TObjString(v1));
596 if ( strlen(v2) > 0 ) values.Add(new TObjString(v2));
597 if ( strlen(v3) > 0 ) values.Add(new TObjString(v3));
598 if ( strlen(v4) > 0 ) values.Add(new TObjString(v4));
599 if ( strlen(v5) > 0 ) values.Add(new TObjString(v5));
600 if ( strlen(v6) > 0 ) values.Add(new TObjString(v6));
601 if ( strlen(v7) > 0 ) values.Add(new TObjString(v7));
602 if ( strlen(v8) > 0 ) values.Add(new TObjString(v8));
603 if ( strlen(v9) > 0 ) values.Add(new TObjString(v9));
605 OutputToJDL(out,key,values);
609 //______________________________________________________________________________
610 void AliMuonGridSubmitter::Print(Option_t* /*opt*/) const
616 std::cout << std::string(80,'*') << std::endl;
617 std::cout << "INVALID OBJECT. CHECK BELOW THE CONFIGURATION." << std::endl;
618 std::cout << std::string(80,'*') << std::endl;
621 TIter next(fInternalMap);
624 while ( ( key = static_cast<TObjString*>(next()) ) )
626 TString value = static_cast<TObjString*>(fInternalMap->GetValue(key->String()))->String();
628 std::cout << key->String() << " : " << value.Data() << std::endl;
633 std::cout << NofRuns() << " run";
634 if ( NofRuns() > 1 ) std::cout << "s";
636 for ( std::vector<int>::size_type i = 0; i < fRunList.size(); ++i )
638 std::cout << fRunList[i] << " ";
642 TIter nextVar(fVars);
643 while ( ( key = static_cast<TObjString*>(nextVar())) )
645 TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
646 std::cout << "Variable " << key->String() << " will be replaced by " << value->String() << std::endl;
649 std::cout << "Files to be uploaded:" << std::endl;
650 TIter nextFile(LocalFileList());
652 while ( ( sfile = static_cast<TObjString*>(nextFile())) )
654 std::cout << sfile->String().Data() << std::endl;
659 //______________________________________________________________________________
660 Bool_t AliMuonGridSubmitter::RemoteDirectoryExists(const char *dirname) const
662 // Returns true if directory exists. Can be also a path.
663 if (!gGrid) return kFALSE;
664 // Check if dirname is a path
665 TString dirstripped = dirname;
666 dirstripped = dirstripped.Strip();
667 dirstripped = dirstripped.Strip(TString::kTrailing, '/');
668 TString dir = gSystem->BaseName(dirstripped);
670 TString path = gSystem->DirName(dirstripped);
671 TGridResult *res = gGrid->Ls(path, "-F");
672 if (!res) return kFALSE;
676 while ((map=dynamic_cast<TMap*>(next()))) {
677 obj = map->GetValue("name");
679 if (dir == obj->GetName()) {
688 //______________________________________________________________________________
689 Bool_t AliMuonGridSubmitter::RemoteFileExists(const char *lfn)
691 // Returns true if file exists.
692 if (!gGrid) return kFALSE;
693 TGridResult *res = gGrid->Ls(lfn);
694 if (!res) return kFALSE;
695 TMap *map = dynamic_cast<TMap*>(res->At(0));
700 TObjString *objs = dynamic_cast<TObjString*>(map->GetValue("name"));
701 if (!objs || !objs->GetString().Length()) {
709 //______________________________________________________________________________
710 Bool_t AliMuonGridSubmitter::ReplaceVars(const char* file) const
712 /// Replace the variables (i.e. things starting by VAR_) found in file
714 std::ifstream in(file);
717 lines.SetOwner(kTRUE);
723 while ( in.getline(line,1023,'\n') )
726 while (sline.Contains("VAR_") && !sline.BeginsWith("//") )
731 while ( ( key = static_cast<TObjString*>(next())) )
733 if ( sline.Contains(key->String()) )
736 TObjString* value = static_cast<TObjString*>(fVars->GetValue(key->String()));
737 sline.ReplaceAll(key->String(),value->String());
743 lines.Add(new TObjString(sline));
750 if ( nreplaced != nvars )
752 AliError(Form("nvars=%d nreplaced=%d",nvars,nreplaced));
755 std::ofstream out(file);
756 TIter nextLine(&lines);
758 while ( ( s = static_cast<TObjString*>(nextLine()) ) )
760 out << s->String().Data() << std::endl;
768 //______________________________________________________________________________
769 const std::vector<int>& AliMuonGridSubmitter::RunList() const
771 /// Return a reference to our runlist
775 //______________________________________________________________________________
776 void AliMuonGridSubmitter::SetPackages(const char* aliroot,
781 /// Set the packages to be used by the jobs
782 /// Must be a valid combination, see http://alimonitor.cern.ch/packages/
785 SetMapKeyValue("AliRoot",aliroot);
786 SetMapKeyValue("Root",root);
787 SetMapKeyValue("Geant3",geant3);
788 SetMapKeyValue("API",api);
791 //______________________________________________________________________________
792 TString AliMuonGridSubmitter::GetRemoteDir(const char* dir, Bool_t create)
794 /// Set the target remote directory (on the grid)
796 if (!RemoteDirectoryExists(dir))
800 AliErrorClass(Form("Remote directory %s does not exist", dir));
805 AliInfoClass(Form("Remote directory %s does not exist. Trying to create it...",dir));
808 AliErrorClass("cannot connect to grid");
811 if ( !gGrid->Mkdir(dir,"-p") )
813 AliErrorClass(Form("Could not create remote dir. Sorry."));
821 //______________________________________________________________________________
822 Bool_t AliMuonGridSubmitter::SetLocalDirectory(const char* type, const char* path)
824 if (gSystem->AccessPathName(path)==kFALSE)
826 SetMapKeyValue(type,path);
832 //______________________________________________________________________________
833 void AliMuonGridSubmitter::SetMapKeyValue(const char* key, const char* value)
835 TObjString skey(key);
836 InternalMap()->Remove(&skey);
837 InternalMap()->Add(new TObjString(key),new TObjString(value));
840 //______________________________________________________________________________
841 Bool_t AliMuonGridSubmitter::SetRemoteDirectory(const char* type, const char* path)
843 // Set the merged directory to be used
844 TString v = GetRemoteDir(path,kTRUE);
845 SetMapKeyValue(type,v);
846 return (v.Length()>0);
849 //______________________________________________________________________________
850 void AliMuonGridSubmitter::SetRunList(const char* runlist)
852 // set the runlist from a text file
853 AliAnalysisTriggerScalers ts(runlist);
854 fRunList = ts.GetRunList();
857 //______________________________________________________________________________
858 void AliMuonGridSubmitter::SetRunList(int runNumber)
860 // set the runlist from a text file
862 fRunList.push_back(runNumber);
865 //______________________________________________________________________________
866 Bool_t AliMuonGridSubmitter::SetVar(const char* varname, const char* value)
872 if (!s.BeginsWith("VAR_"))
874 AliError("Variable name should start with VAR_");
880 fVars->SetOwnerKeyValue(kTRUE,kTRUE);
883 TObject* o = new TObjString(s);
886 fVars->Add(o,new TObjString(value));
891 //______________________________________________________________________________
892 TObjArray* AliMuonGridSubmitter::TemplateFileList() const
894 /// Return (after createing if needed)
896 if (!fTemplateFileList)
898 fTemplateFileList = new TObjArray;
899 fTemplateFileList->SetOwner(kTRUE);
901 return fTemplateFileList;
904 //______________________________________________________________________________
905 void AliMuonGridSubmitter::UpdateLocalFileList()
907 // insure that local file list contains at least all of the template files
908 TIter next(TemplateFileList());
911 while ( ( s = static_cast<TObjString*>(next())) )
913 TObjArray* local = LocalFileList();
914 if ( !local->FindObject(s->String()))
916 local->Add(new TObjString(*s));
921 //______________________________________________________________________________
922 TMap* AliMuonGridSubmitter::Vars() const
927 fVars->SetOwnerKeyValue(kTRUE,kTRUE);