4 /// @file run-single-task.C
5 /// @author Matthias.Richter@ift.uib.no
7 /// @brief Run a single task
9 /// Helper macro to run a single task either locally or on Grid
11 /// aliroot -b -q -l run-single-task.C'("mode", "input", "tasks", "name", "options", events, "path", "pattern", "friendPattern", "outputDir", "user")'
13 /// mode: local, full, test
14 /// input: In grid mode a list of run numbers.
16 /// - ESD file AliESDs.root
17 /// - a list of ESD files in a text file <choose-file-name>.txt
18 /// - AOD file AliAOD.root
19 /// - AODs with predefined list/AODs in same folder, specifiy as "AOD"
21 /// tasks: list of class names/source or header files of task, or AddTask-Macro
23 /// optional arguments
24 /// name: analysis name (default 'myanalysis')
25 /// options: optional arguments passed onto the task, e.g. 'mc', 'event-mixing'
26 /// options of run-single-task:
27 /// 'mcData' -> the run numbers indicate MC Data, no '000' prepended
28 /// events: number of events to be processed (default -1 -> all)
29 /// path: data search path for grid analysis (default from configuration file)
30 /// pattern: data search pattern (default from configuration file)
31 /// friend pattern: friend file search pattern (default from configuration file)
32 /// output dir: output directory in Grid home (default gridwork/yyyy-mm-dd_hh-mm)
33 /// user: default NULL, using user of active token
36 /// aliroot -b -q -l run-single-task.C'("full", "146860", "AliAnalysisTaskSample", "myanalysis_LHC11a")'
38 /// aliroot -b -q -l run-single-task.C'("local", "$ALICE_ROOT/test/ppbench/AliESDs.root", "AliAnalysisTaskSample")'
40 /// aliroot -b -q -l run-single-task.C'("local", "AOD", "AddTaskSample.C")'
42 /// aliroot -b -q -l run-single-task.C'("full", "146860", "AliAnalysisTaskSample", "correlation3p_LHC11a", 0, -1, "/alice/data/2011/LHC11a", "*/pass2_without_SDD/AOD*/*/AliAOD.root")'
45 /// depending on the format of the search pattern either the ESD or AOD input handler is used.
48 /// If the task and classes used by the task are not in an AliRoot library available, e.g.
49 /// for the purpose of development, all header and source files need to be in the local
50 /// directory. The macro searches automatically for dependencies, compiles those and
51 /// copies files to the Grid working directory. In order to make the files accessible in
52 /// the local directory, the files can be just linked.
54 /// for f in <search path>; do ln -s $f; done
56 /// If there are dependencies (include headers) which are not available in the working
57 /// directory, the macro searches for the aliroot libraries implementing them, and adds
58 /// the libraries if found to the setup.
61 /// requires only the path to the input file and the task class name. If the specified file is
62 /// a text file (.txt) each line can contain an input ESD file path, all files are chained.
63 /// Analysis on local AOD files needs to be setup prior to this macro. gDirectory must contain
64 /// a TChain object of name 'aodTree'. This is for example created by macros like
65 /// $ALICE_ROOT/PWGHF/vertexingHF/MakeAODInputChain.C
66 /// Set $ALICE_ROOT/PWGHF/correlationHF/macros/setupDxHFE.C for an example.
69 /// All modes provided by the AliAnalysisAlien plugin can be used, e.g. full, test, offline
70 /// A couple of settings need to be defined in a configuration file 'grid-config.C' which can be
71 /// either in the local directory or home directory. The file can look like
73 /// const char* alienAPIVersion="V1.1x";
74 /// const char* alienROOTVersion="v5-34-01";
75 /// const char* alienAliROOTVersion="v5-03-61-AN";
76 /// const char* defaultGridDataDir="/alice/data/2011/LHC11a";
77 /// const char* defaultDataPattern="*/pass2_without_SDD/*/AliESDs.root";
78 /// const char* defaultFriendDataPattern="";
79 /// {} // note this empty body
81 /// Data path and pattern can also be specified as command line arguments.
82 /// The working directory in the grid home directory of the user is set to
83 /// gridwork/<date>_<time> (gridwork/yyyy-mm-dd_hh-mm), can be overridden by command line
88 /// Feedback appreciated: Matthias.Richter@cern.ch
89 /// If you find this macro useful but not applicable without patching it, let me know
90 /// your changes and use cases.
93 ///////////////////////////////////////////////////////////////////////////////////////////////////
98 const char* defaultAnalysisName="myanalysis";
99 const char* includePath="-I. -I$ROOTSYS/include -I$ALICE_ROOT/include";
100 const char* libraryDependencies=
105 "libANALYSISalice.so "
108 TString GetIncludeHeaders(const char* filename, TString& headers, TString& libs, bool loadClass=true);
109 void ErrorConfigurationFile(const char* fileName);
111 void run_single_task(const char* mode,
113 const char* tasknames,
114 const char* analysisName=defaultAnalysisName,
115 const char* arguments="",
117 const char* gridDataDir=NULL,
118 const char* dataPattern=NULL,
119 const char* friendDataPattern=NULL,
121 const char* user=NULL
124 ///////////////////////////////////////////////////////////////////////////////////////////////////
125 ///////////////////////////////////////////////////////////////////////////////////////////////////
126 ///////////////////////////////////////////////////////////////////////////////////////////////////
130 if (analysisName==defaultAnalysisName && gDirectory!=NULL) {
131 // NOTE: the direct pointer comparison is on purpose
132 // string comparison not necessary in this special case
134 // fetch the analysis name from the setup file
135 const char* confObjectName="analysis_name";
136 TObject* confObject=gDirectory->FindObject(confObjectName);
138 analysisName=confObject->GetTitle();
142 bool bRunLocal=strcmp(mode, "local")==0;
143 const char* gridConfigFile="grid-config.C";
144 TString strGridConfigFile=gridConfigFile;
145 if (gSystem->AccessPathName(strGridConfigFile)!=0) {
146 strGridConfigFile.Prepend("/");
147 strGridConfigFile.Prepend(gSystem->Getenv("HOME"));
148 if (gSystem->AccessPathName(strGridConfigFile)!=0) {
150 ErrorConfigurationFile(gridConfigFile);
153 strGridConfigFile="";
157 if (strGridConfigFile.IsNull()==0 && !bRunLocal) {
158 cout << "loading grid configuration from file '" << strGridConfigFile << "':" << endl;
159 gROOT->LoadMacro(strGridConfigFile);
160 cout << " alienAPIVersion =" << alienAPIVersion << endl;
161 cout << " alienROOTVersion =" << alienROOTVersion << endl;
162 cout << " alienAliROOTVersion =" << alienAliROOTVersion << endl;
163 cout << " defaultGridDataDir =" << defaultGridDataDir << endl;
164 cout << " defaultDataPattern =" << defaultDataPattern << endl;
165 cout << " defaultFriendDataPattern =" << defaultFriendDataPattern << endl;
167 if (gridDataDir==NULL) gridDataDir=defaultGridDataDir;
168 if (dataPattern==NULL) dataPattern=defaultDataPattern;
169 if (friendDataPattern==NULL) friendDataPattern=defaultFriendDataPattern;
170 } else if (bRunLocal) {
171 if (dataPattern==NULL) {
172 // thats a very crude logic, I guess it can fail in some special cases
174 if (strin.Contains("AOD"))
176 else if (strin.Contains("ESD"))
183 TGrid::Connect("alien://");
185 ///////////////////////////////////////////////////////////////////////////////////////////////////
186 ///////////////////////////////////////////////////////////////////////////////////////////////////
187 ///////////////////////////////////////////////////////////////////////////////////////////////////
192 TString strArguments(arguments);
193 TObjArray* tokens=strArguments.Tokenize(" ");
195 for (int iToken=0; iToken<tokens->GetEntriesFast(); iToken++) {
196 TObject* token=tokens->At(iToken);
197 if (!token) continue;
198 TString arg=token->GetName();
199 const char* key=NULL;
202 if (arg.CompareTo(key)==0) {
203 strArguments.ReplaceAll(key, "");
210 ///////////////////////////////////////////////////////////////////////////////////////////////////
211 ///////////////////////////////////////////////////////////////////////////////////////////////////
212 ///////////////////////////////////////////////////////////////////////////////////////////////////
214 // make the analysis manager
216 AliAnalysisManager *pManager = new AliAnalysisManager("AnalysisManager");
218 cerr << "failed to created AnalysisManager" << endl;
221 AliInputEventHandler *pInputHandler = NULL;
222 TString strDataPattern(dataPattern);
223 if (strDataPattern.Contains("AOD")) pInputHandler=new AliAODInputHandler;
224 else if (strDataPattern.Contains("ESD")) pInputHandler=new AliESDInputHandler;
226 cerr << "can not determine input type from data pattern '" << dataPattern << "'" << endl;
229 if (!pInputHandler) {
230 cerr << "failed to created input handler" << endl;
233 //pInputHandler->SetReadFriends(kFALSE);
234 pManager->SetInputEventHandler(pInputHandler);
235 pManager->SetNSysInfo(1000);
237 TString ofile=Form("%s.root", analysisName);
239 ///////////////////////////////////////////////////////////////////////////////////////////////////
240 ///////////////////////////////////////////////////////////////////////////////////////////////////
241 ///////////////////////////////////////////////////////////////////////////////////////////////////
243 // load task classes and find and load all dependencies
245 gSystem->AddIncludePath(includePath);
246 TString libraries=libraryDependencies;
247 if (gDirectory!=NULL) {
248 // fetch the analysis libraries from the setup file
249 const char* confObjectName="analysis_libraries";
250 TObject* confObject=gDirectory->FindObject(confObjectName);
252 TString analysisLibraries(confObject->GetTitle());
253 TObjArray* pTokens=analysisLibraries.Tokenize(" ");
255 for (int i=0; i<pTokens->GetEntriesFast(); i++) {
256 if (libraries.Contains(pTokens->At(i)->GetName())==0) {
258 libraries+=pTokens->At(i)->GetName();
259 TString library=pTokens->At(i)->GetName();
260 if (!library.EndsWith(".so")) libraries+=".so";
267 TObjArray* pTokens=libraries.Tokenize(" ");
269 for (int i=0; i<pTokens->GetEntriesFast(); i++) {
270 TString library=pTokens->At(i)->GetName();
271 if (!library.EndsWith(".so")) {
272 cerr << "libraries need to have ending '.so' in order to be correctly processed by alien plugin, please correct library name '" << library << "'" << endl;
274 if (gSystem->Load(pTokens->At(i)->GetName())==0) {
275 cout << "loading " << pTokens->At(i)->GetName() << endl;
281 TString taskNames=tasknames;
282 TString taskClasses="";
283 TString taskSources="";
284 TString taskHeaders="";
285 TString addTaskMacros="";
286 TString parPackages="";
287 TObjArray* pTaskNames=taskNames.Tokenize(" ");
289 for (int iTaskName=0; iTaskName<pTaskNames->GetEntriesFast(); iTaskName++) {
290 TString taskSource=pTaskNames->At(iTaskName)->GetName();
291 TString taskHeader=pTaskNames->At(iTaskName)->GetName();
292 bool bIsAddTask=false;
293 if (taskSource.EndsWith(".C")) {
294 // suppose that's an 'AddTask' macro
297 } else if (taskSource.EndsWith(".par")) {
299 if (gSystem->AccessPathName(taskSource)!=0) {
300 ::Error("run_single_task", Form("par file '%s' not found in current directory, you might want to set a symbolic link", taskSource.Data()));
304 parPackages+=taskSource;
306 } else if (taskSource.EndsWith(".h")) {
307 taskSource.ReplaceAll(".h", "");
309 taskClasses+=taskSource;
311 } else if (taskSource.EndsWith(".cxx")) {
312 taskHeader.ReplaceAll(".cxx", "");
314 taskClasses+=taskHeader;
318 taskClasses+=taskSource;
322 TString dependencyHeader;
323 TString dependencySource;
324 if (gSystem->AccessPathName(taskHeader)==0) {
325 GetIncludeHeaders(taskHeader, dependencyHeader, libraries);
326 taskHeaders+=" "; taskHeaders+=taskHeader;
328 if (gSystem->AccessPathName(taskSource)==0) {
329 GetIncludeHeaders(taskSource, dependencyHeader, libraries);
330 if (!bIsAddTask) {taskSources+=" "; taskSources+=taskSource;}
331 else {addTaskMacros+=" "; addTaskMacros+=taskSource;}
333 TObjArray* pTokens=dependencyHeader.Tokenize(" ");
335 for (int i=0; i<pTokens->GetEntriesFast(); i++) {
336 TString sourceFile=pTokens->At(i)->GetName();
337 sourceFile.ReplaceAll(".h", ".cxx");
338 if (gSystem->AccessPathName(sourceFile)!=0) continue;
339 if (!dependencySource.IsNull()) dependencySource+=" ";
340 dependencySource+=sourceFile;
341 if (!libraries.IsNull()) libraries+=" ";
342 libraries+=sourceFile;
346 dependencySource.ReplaceAll(taskSource, "");
347 dependencyHeader.ReplaceAll(taskHeader, "");
351 cout << "Tasks: " << taskClasses << endl;
352 cout << "Task files: " << taskSources << addTaskMacros << taskHeaders << endl;
353 cout << "Dependency classes: " << dependencySource << endl;
354 cout << "Dependency headers: " << dependencyHeader << endl;
355 cout << "Dependency libraries: " << libraries << endl;
356 cout << "Packages: " << parPackages << endl;
358 ///////////////////////////////////////////////////////////////////////////////////////////////////
359 ///////////////////////////////////////////////////////////////////////////////////////////////////
360 ///////////////////////////////////////////////////////////////////////////////////////////////////
362 // init for local or GRID analysis
364 AliAnalysisAlien *alienHandler = NULL; // for grid analysis
365 TChain *chain=NULL; // for local analysis
366 TString strInput=input;
368 ///////////////////////////////////////////////////////////////////////////////////////////////////
372 if (strInput.BeginsWith("alien://")) {
373 // file on Grid -> connect to AliEn
374 TGrid::Connect("alien://");
376 if(strInput.EndsWith("AliESDs.root")){
377 // suppose it's a single ESD file
378 chain = new TChain("esdTree");
379 chain->Add(strInput);
380 } else if(strInput.EndsWith(".txt")) {
381 // Constructs chain from filenames in *.txt
382 // in the form $DIR/AliESDs.root
383 gROOT->LoadMacro("$ALICE_ROOT/PWG0/CreateESDChain.C");
384 // chain can contain up to 200 files, value can be modified to
385 // include a subset of what the *txt file contains
386 chain = CreateESDChain(strInput.Data(),200);
388 // check if the files are on grid
389 TIter next(chain->GetListOfFiles());
390 TChainElement *chEl = 0;
391 while(( chEl = (TChainElement*)next() )){
392 TString tmp = chEl->GetTitle();
393 if(tmp.BeginsWith("alien://")) {
394 TGrid::Connect("alien://");
398 } else if(strInput.EndsWith("ESD")){
399 // fetch esd tree from the setup macro
400 if (gDirectory!=NULL) {
401 const char* esdTreeName="esdTree";
402 TObject* chainObject=gDirectory->FindObject(esdTreeName);
404 chain=dynamic_cast<TChain*>(chainObject);
408 ::Error("run_single_task", Form("failed to fetch esd tree object from setup; the chain with name '%s' has to be created before calling this macro", esdTreeName));
411 } else if(strInput.EndsWith("AliAOD.root")){
412 // single local AOD file
413 chain = new TChain("aodTree");
414 chain->Add(strInput);
415 } else if(strInput.EndsWith("AOD")){
416 // fetch aod tree from the setup macro
417 if (gDirectory!=NULL) {
418 const char* aodTreeName="aodTree";
419 TObject* chainObject=gDirectory->FindObject(aodTreeName);
421 chain=dynamic_cast<TChain*>(chainObject);
425 ::Error("run_single_task", Form("failed to fetch aod tree object from setup; the chain with name '%s' has to be created before calling this macro", aodTreeName));
429 ::Error("run_single_task", Form("invalid input"));
433 ///////////////////////////////////////////////////////////////////////////////////////////////////
438 TString strInput(input);
439 if (!strInput.IsDigit()) {
440 // support for external macros specifying the the runs to be
442 // the input is expected to be an external plugin with name 'input'
443 // and all run numbers being set
444 TObject* pObj=gDirectory->FindObject(input);
445 if (pObj) alienHandler=dynamic_cast<AliAnalysisAlien*>(pObj);
447 ::Error("run_single_task", Form("can not find plugin of name '%s', please setup alien handler with name and run numbers before calling this macro", input));
452 alienHandler=new AliAnalysisAlien();
455 ::Error("run_single_task", Form("failed to create alien handler"));
459 // do not check for copying to grid (CLOSE_SE)
460 alienHandler->SetCheckCopy(kFALSE);
462 // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
463 alienHandler->SetRunMode(mode);
465 // check the versions available on alien with the command 'packages'
466 alienHandler->SetAPIVersion(alienAPIVersion);
467 alienHandler->SetROOTVersion(alienROOTVersion);
468 alienHandler->SetAliROOTVersion(alienAliROOTVersion);
470 //Allow non-default outputs
471 //This is required to set non-default output files with the SetOutputFiles
473 alienHandler->SetDefaultOutputs(kFALSE);
474 if (user && user[0]!=0) alienHandler->SetUser(user);
476 // data alien directory
477 alienHandler->SetGridDataDir(gridDataDir);
479 // Set data search pattern
480 alienHandler->SetDataPattern(dataPattern);
481 alienHandler->SetFriendChainName(friendDataPattern);
483 TObjArray* packageTokens=parPackages.Tokenize(" " );
485 for (int iPackageToken=0; iPackageToken<packageTokens->GetEntriesFast(); iPackageToken++) {
486 alienHandler->EnablePackage(packageTokens->At(iPackageToken)->GetName());
488 delete packageTokens;
492 // only set if input is a run number
493 if (!mcData && !strInput.BeginsWith("000"))
494 alienHandler->SetRunPrefix("000"); // real data
496 alienHandler->AddRunNumber(input);
499 // define working and output directories
502 odir=(Form("gridwork/%04d-%02d-%02d_%02d-%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay(), dt.GetHour(), dt.GetMinute()));
503 cout << odir << endl;
504 alienHandler->SetGridWorkingDir(odir); // relative to $HOME
505 alienHandler->SetGridOutputDir("output"); // relative to working dir
506 //alienHandler->SetOverwriteMode(); // overwrites the contents of the working and output directory
508 // workaround for a Root feature: GetIncludePath() appends always
509 // the current Root include path including escaped quotes. Those
510 // quotes make it difficult to pass the output directly. Search for the
511 // last appended include path and truncate
512 TString strIncludePath(gSystem->GetIncludePath());
513 Int_t pos=strIncludePath.Index(includePath);
517 cut=pos+strlen(includePath);
518 } while ((pos=strIncludePath.Index(includePath, cut))>cut);
519 strIncludePath.Resize(cut);
521 alienHandler->AddIncludePath(strIncludePath);
523 // Note: there is no extra source or header file to be transferred if 'AddTask' macros are used
524 alienHandler->SetAnalysisSource(Form("%s %s %s %s", dependencySource.Data(), dependencyHeader.Data(), taskSources.Data(), taskHeaders.Data()));
525 alienHandler->SetAdditionalLibs(Form("%s %s %s", libraries.Data(), taskHeaders.Data(), dependencyHeader.Data()));
527 alienHandler->SetOutputFiles(ofile);
529 // Optionally define the files to be archived.
530 alienHandler->SetOutputArchive("log_archive.zip:stdout,stderr");
532 // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
533 TString macroName; macroName.Form("run_%s.C",analysisName); macroName.ReplaceAll("-","_");
534 alienHandler->SetAnalysisMacro(macroName);
536 //alienHandler->SetExecutable("comparison.sh");
537 alienHandler->SetExecutable(Form("run_%s.sh",analysisName));
539 alienHandler->SetSplitMaxInputFileNumber(100);
541 // Optionally set number of failed jobs that will trigger killing waiting sub-jobs.
542 alienHandler->SetMaxInitFailed(10);
544 // Optionally resubmit threshold.
545 alienHandler->SetMasterResubmitThreshold(90); // in %
547 alienHandler->SetTTL(86400);// in sec
549 // Optionally set input format (default xml-single)
550 alienHandler->SetInputFormat("xml-single");
552 // Optionally modify the name of the generated JDL (default analysis.jdl)
553 alienHandler->SetJDLName(Form("run_%s.jdl",analysisName));
555 // Optionally modify job price (default 1)
556 alienHandler->SetPrice(1);
558 // Optionally modify split mode (default 'se')
559 alienHandler->SetSplitMode("se");
561 // comment out the next line when using the "terminate" option, unless
562 // you want separate merged files for each run
563 if (strcmp(mode, "terminate")==0) {
564 alienHandler->SetMergeViaJDL(kFALSE);
567 alienHandler->SetOneStageMerging(kFALSE);
568 alienHandler->SetMaxMergeStages(2);
571 // Connect plugin to the analysis manager
573 pManager->SetGridHandler(alienHandler);
576 ///////////////////////////////////////////////////////////////////////////////////////////////////
577 ///////////////////////////////////////////////////////////////////////////////////////////////////
578 ///////////////////////////////////////////////////////////////////////////////////////////////////
580 // create task from the name, create output container, connect slots
582 TObjArray* taskClassTokens=taskClasses.Tokenize(" ");
583 if (taskClassTokens) {
584 for (int iTaskClassToken=0; iTaskClassToken<taskClassTokens->GetEntriesFast(); iTaskClassToken++) {
585 AliAnalysisTaskSE *pTask=NULL;
586 TString taskName=taskClassTokens->At(iTaskClassToken)->GetName();
587 taskName.ReplaceAll(".cxx", "");
588 TClass* pCl=TClass::GetClass(taskName);
590 cerr << "can not load class " << taskName << endl;
593 TObject* p=pCl->New();
595 cerr << "failed to instantiate class " << taskName << endl;
598 pTask=reinterpret_cast<AliAnalysisTaskSE*>(p);
599 pManager->AddTask(pTask);
600 AliAnalysisDataContainer *pContainer=pManager->CreateContainer(analysisName ,TObject::Class(), AliAnalysisManager::kOutputContainer, ofile);
601 pManager->ConnectInput(pTask,0,pManager->GetCommonInputContainer());
602 pManager->ConnectOutput(pTask,1,pContainer);
604 delete taskClassTokens;
606 TObjArray* taskMacroTokens=addTaskMacros.Tokenize(" ");
607 if (taskMacroTokens) {
608 for (int iTaskMacroToken=0; iTaskMacroToken<taskMacroTokens->GetEntriesFast(); iTaskMacroToken++) {
610 TString configuration;
611 configuration.Form("name=%s file=%s %s", analysisName, ofile.Data(), strArguments.Data());
612 if (gDirectory) gDirectory->Add(new TNamed("run_single_task_configuration", configuration.Data()));
613 gROOT->Macro(taskMacroTokens->At(iTaskMacroToken)->GetName());
615 delete taskMacroTokens;
618 ///////////////////////////////////////////////////////////////////////////////////////////////////
619 ///////////////////////////////////////////////////////////////////////////////////////////////////
620 ///////////////////////////////////////////////////////////////////////////////////////////////////
625 if (!pManager->InitAnalysis()) {
626 cerr << "failed to initialize analysis" << endl;
629 if (nevents<0) nevents=1000000000;
630 pManager->PrintStatus();
632 pManager->StartAnalysis("local", chain, nevents);
634 pManager->StartAnalysis("grid", nevents);
638 // method for backward compatibility
639 void run_single_task(const char* mode,
641 const char* tasknames,
642 const char* analysisName,
645 const char* gridDataDir=NULL,
646 const char* dataPattern=NULL,
647 const char* friendDataPattern=NULL,
649 const char* user=NULL
652 run_single_task(mode,
666 TString GetIncludeHeaders(const char* filename, TString& headers, TString& libs, bool loadClass)
668 // scan the file and add all include headers found by path
669 // to the parameter headers
670 ifstream input(filename);
672 cerr << "failed to open file " << filename << endl;
676 while (!line.ReadLine(input).eof()) {
677 if (!line.Contains("#include") || !line.Contains(".h")) continue;
678 line=line(0, line.Index(".h"));line+=".h";
679 line.Replace(0, line.Index("#include"), "");
680 line.ReplaceAll("#include", "");
681 line.ReplaceAll(" ", "");
682 line.ReplaceAll("\"", "");
683 if (!line.BeginsWith("Ali") && !line.BeginsWith("T")) continue;
684 if (gSystem->AccessPathName(line)!=0) {
685 // not an include file in the current directory, check if class
686 // is available or find library
687 line.ReplaceAll(".h","");
688 //cout << "checking class " << line << endl;
689 if (TClass::GetClass(line)==NULL) {
691 TString resfilename(gSystem->TempDirectory()); resfilename+="/findlib.txt";
692 command.Form("for lib in $ALICE_ROOT/lib/*/lib*.so; do (nm $lib | grep %s | grep ' T ' | grep Class_Name > /dev/null) && echo $lib > %s; done", line.Data(), resfilename.Data());
693 gSystem->Exec(command);
694 ifstream resfile(resfilename.Data());
695 if (resfile.good()) {
697 if (!result.ReadLine(resfile).eof()) {
699 while ((haveSlash=result.First('/'))>=0) result.Replace(0, haveSlash+1, "");
700 if (!libs.Contains(result)) {
701 cout << "loading dependency library '" << result << "' for class '" << line << "'" << endl;
702 gSystem->Load(result);
703 if (!libs.IsNull()) libs+=" ";
707 command="rm "; command+=resfilename;
708 gSystem->Exec(command);
712 if (headers.Contains(line)) {
713 if (!headers.BeginsWith(line)) {
714 headers.ReplaceAll(line, "");
715 if (!headers.IsNull()) headers.Insert(0, " ");
716 if (macroVerbosity>0) cout << "moving " << line << endl;
717 headers.Insert(0, line);
721 if (!headers.IsNull()) headers.Insert(0, " ");
722 if (macroVerbosity>0) cout << "inserting " << line << endl;
723 headers.Insert(0, line);
724 TString source=line; source.ReplaceAll(".h", ".cxx");
725 if (gSystem->AccessPathName(source)==0) {
726 GetIncludeHeaders(source, headers, libs);
728 GetIncludeHeaders(line, headers, libs);
729 if (loadClass && gSystem->AccessPathName(source)==0) {
730 line.ReplaceAll(".h", "");
731 if (TClass::GetClass(line)==NULL) {
733 gROOT->LoadMacro(source);
742 void ErrorConfigurationFile(const char* fileName) {
744 cout << "/// -------------------------------------------------------------------" << endl;
745 cout << "/// Warning: can not find configuration file '" << fileName << "'" << endl;
746 cout << "/// please create a configuration file in either local or HOME directory, or in" << endl;
747 cout << "/// specified location. Below is an example, fill in your preferred defaults." << endl;
748 cout << "/// -------------------------------------------------------------------" << endl;
750 cout << "const char* alienAPIVersion=\"V1.1x\";" << endl;
751 cout << "const char* alienROOTVersion=\"v5-33-02a\";" << endl;
752 cout << "const char* alienAliROOTVersion=\"v5-01-Rev-29\";" << endl;
753 cout << "const char* defaultGridDataDir=\"/alice/data/2011/LHC11f\";" << endl;
754 cout << "const char* defaultDataPattern=\"*ESDs.root\";" << endl;
755 cout << "const char* defaultFriendDataPattern=\"\";" << endl;
756 cout << "{} // note this empty body";