]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ANALYSIS/macros/AnalysisTrainNew.C
4df6d837b4f336032e19fba4e7c996e3438b9f15
[u/mrichter/AliRoot.git] / ANALYSIS / macros / AnalysisTrainNew.C
1 //===================== ANALYSIS TRAIN =========================================
2 // To use: copy this macro to your work directory, modify the global part to match
3 // your needs, then run root.
4 //    root[0] .L AnalysisTrain.C
5 // Grid full mode as below (other modes: test, offline, submit, terminate)
6 //    root[1] AnalysisTrainNew("grid", "full")
7 // CAF mode (requires root v5-23-02 + aliroot v4-16-Rev08)
8 //    root[2] AnalysisTrainNew("proof")
9 // Local mode requires AliESds.root or AliAOD.root in ./data directory
10 //    root[3] AnalysisTrainNew("local")
11 // In proof and grid modes, a token is needed and sourcing the produced environment file.
12 //
13 // If 'saveTrain' flag is set, the train will generate a directory name and run
14 // in this directory. A configuration file 'ConfigTrain.C' will be generated. 
15 // One can replay at any time the train via:
16 //    root[1] AnalysisTrainNew(ana_mode, plugin_mode, "train_default_<date>/ConfigTrain.C")
17
18 //==================   TRAIN NAME   ============================================
19 TString     train_name         = "default"; // enters file names, so no blancs or special characters
20 //==============================================================================
21
22 // ### Settings that make sense in PROOF only
23 //==============================================================================
24 TString     proof_cluster      = "alicecaf.cern.ch";
25 Bool_t      useAFPAR           = kFALSE;  // use AF special par file
26 TString     AFversion          = "AF-v4-16";
27 // Change CAF dataset here
28 TString     proof_dataset      = "/COMMON/COMMON/LHC09a4_run8100X#/esdTree";
29
30 // ### Settings that make sense when using the Alien plugin
31 //==============================================================================
32 Bool_t      usePLUGIN          = kTRUE;   // do not change
33 // Usage of par files ONLY in grid mode and ONLY if the code is not available
34 // in the deployed AliRoot versions. Par file search path: local dir, if not there $ALICE_ROOT.
35 // To refresh par files, remove the ones in the workdir, then do "make <target.par>" in 
36 // AliRoot.
37 Bool_t      usePAR             = kFALSE;  // use par files for extra libs
38 Bool_t      useCPAR            = kFALSE;  // use par files for common libs
39 TString     root_version       = "v5-23-02";
40 TString     aliroot_version    = "v4-17-00";
41 // Change production base directory here
42 TString     alien_datadir      = "/alice/sim/PDC_09/LHC09a4/";
43 // Use up to 10 non-zero run numbers
44 Int_t       run_numbers[10]    = {81272,    81273 ,     81274,     0,     0,
45                                       0,     0,     0,     0,     0};
46 // ### Settings that make sense only for local analysis
47 //==============================================================================
48 // Change local xml dataset for local interactive analysis
49 TString     local_xmldataset   = "";
50
51 // ### Other flags to steer the analysis
52 //==============================================================================
53 Bool_t      useDBG             = kTRUE;  // activate debugging
54 Bool_t      useMC              = kTRUE;  // use MC info
55 Bool_t      useTAGS            = kFALSE; // use ESD tags for selection
56 Bool_t      useKFILTER         = kTRUE;  // use Kinematics filter
57 Bool_t      useTR              = kFALSE; // use track references
58 Bool_t      useCORRFW          = kFALSE; // do not change
59 Bool_t      useAODTAGS         = kFALSE; // use AOD tags
60 Bool_t      saveTrain          = kTRUE;  // save train configuration as: 
61                                          // train_[trainName]_ddMonthyyyy_time.C
62 // ### Analysis modules to be included. Some may not be yet fully implemented.
63 //==============================================================================
64 Int_t       iAODanalysis       = 0;      // Analysis on input AOD's
65 Int_t       iAODhandler        = 1;      // Analysis produces an AOD or dAOD's
66 Int_t       iESDfilter         = 1;      // ESD to AOD filter (barrel + muon tracks)
67 Int_t       iMUONcopyAOD       = 0;      // Task that copies only muon events in a separate AOD (PWG3)
68 Int_t       iJETAN             = 1;      // Jet analysis (PWG4) - needs ESD filter
69 Int_t       iPWG4partcorr      = 1;      // Gamma-hadron correlations task (PWG4)
70 Int_t       iPWG3vertexing     = 1;      // Vertexing HF task (PWG2)
71 Int_t       iPWG2femto         = 1;      // Femtoscopy task (PWG2)
72 Int_t       iPWG2spectra       = 1;      // Spectra PWG2 tasks (protons, cascades, V0 check, strange)
73 Int_t       iPWG2flow          = 0;      // Flow analysis task (PWG2)
74 Int_t       iPWG2res           = 1;      // Resonances task (PWG2)
75 Int_t       iPWG2kink          = 1;      // Kink analysis task (PWG2)
76
77 // Temporaries.
78 TString anaPars = "";
79 TString anaLibs = "";
80 // Function signatures
81 class AliAnalysisGrid;
82
83 //______________________________________________________________________________
84 void AnalysisTrainNew(const char *analysis_mode="grid", 
85                       const char *plugin_mode="full",
86                       const char *config_file="")
87 {
88 // Main analysis train macro. If a configuration file is provided, all parameters
89 // are taken from there but may be altered by CheckModuleFlags.
90    if (strlen(config_file) && !LoadConfig(config_file)) return;
91    TString smode(analysis_mode);
92    smode.ToUpper();
93    if (saveTrain)              WriteConfig();
94    // Check compatibility of selected modules
95    CheckModuleFlags(smode);
96
97    printf("==================================================================\n");
98    printf("===========    RUNNING ANALYSIS TRAIN %s IN %s MODE   ==========\n", train_name.Data(),smode.Data());
99    printf("==================================================================\n");
100    printf("=  Configuring analysis train for:                               =\n");
101    if (iAODanalysis) printf("=  AOD analysis                                                  =\n");
102    else              printf("=  ESD analysis                                                  =\n");
103    if (iESDfilter)   printf("=  ESD filter                                                    =\n");
104    if (iMUONcopyAOD) printf("=  MUON copy AOD                                                 =\n");
105    if (iJETAN)       printf("=  Jet analysis                                                  =\n");
106    if (iPWG2spectra) printf("=  PWG2 proton, checkCascade, checkV0, strange                   =\n");
107    if (iPWG2femto)   printf("=  PWG2 femtoscopy                                               =\n");
108    if (iPWG2flow)    printf("=  PWG2 flow                                                     =\n");
109    if (iPWG2res)     printf("=  PWG2 resonances                                               =\n");
110    if (iPWG2kink)    printf("=  PWG2 kink analysis                                            =\n");
111    if (iPWG3vertexing) printf("=  PWG3 vertexing                                            =\n");
112    if (iPWG4partcorr)  printf("=  PWG4 gamma-hadron, pi0 and gamma-jet correlations         =\n");
113    printf("==================================================================\n");
114    printf(":: use MC truth      %d\n", (UInt_t)useMC);
115    printf(":: use KINE filter   %d\n", (UInt_t)useKFILTER);
116    printf(":: use track refs    %d\n", (UInt_t)useTR);
117    printf(":: use tags          %d\n", (UInt_t)useTAGS);
118    printf(":: use AOD tags      %d\n", (UInt_t)useAODTAGS);
119    printf(":: use debugging     %d\n", (UInt_t)useDBG);
120    printf(":: use PAR files     %d\n", (UInt_t)usePAR);
121    printf(":: use AliEn plugin  %d\n", (UInt_t)usePLUGIN);
122
123    // Connect to back-end system
124    if (!Connect(smode)) {
125       ::Error("AnalysisTrain", "Could not connect to %s back-end", analysis_mode);
126       return;
127    }   
128
129    // Load common libraries and set include path
130    if (!LoadCommonLibraries(smode)) {
131       ::Error("AnalysisTrain", "Could not load common libraries");
132       return;
133    }   Int_t iPWG2res       = 0;      // Resonances task (PWG2)
134
135     
136    // Load analysis specific libraries
137    if (!LoadAnalysisLibraries(smode)) {
138       ::Error("AnalysisTrain", "Could not load analysis libraries");
139       return;
140    }   
141
142     
143    //==========================================================================
144    // Make the analysis manager and connect event handlers
145    AliAnalysisManager *mgr  = new AliAnalysisManager("Analysis Train", "Production train");
146
147    // Create input handler (input container created automatically)
148    if (iAODanalysis) {
149    // AOD input handler
150       AliAODInputHandler *aodH = new AliAODInputHandler();
151       mgr->SetInputEventHandler(aodH);
152    } else {   
153    // ESD input handler
154       AliESDInputHandler *esdHandler = new AliESDInputHandler();
155       if (useTAGS) esdHandler->SetReadTags();
156       mgr->SetInputEventHandler(esdHandler);       
157    }
158    // Monte Carlo handler
159    if (useMC && !iAODanalysis) {
160       AliMCEventHandler* mcHandler = new AliMCEventHandler();
161       mgr->SetMCtruthEventHandler(mcHandler);
162       mcHandler->SetReadTR(useTR); 
163    }   
164    // AOD output container, created automatically when setting an AOD handler
165    if (iAODhandler) {
166       // AOD output handler
167       AliAODHandler* aodHandler   = new AliAODHandler();
168       mgr->SetOutputEventHandler(aodHandler);
169       if (iAODanalysis) aodHandler->SetCreateNonStandardAOD();
170       if (iPWG3vertexing) aodHandler->SetOutputFileName("AliAOD.VertexingHF.root");
171       else aodHandler->SetOutputFileName("AliAOD.root");
172    }
173    // Debugging if needed
174    if (useDBG) mgr->SetDebugLevel(3);
175
176    //==========================================================================
177    // Create the chain. In this example it is created only from ALIEN files but
178    // can be done to work in batch or grid mode as well.
179    TChain *chain = CreateChain(smode, plugin_mode);
180         
181    //==========================================================================
182    // Load the tasks configuration macros for all wagons. These files are supposed now to be
183    // in the current workdir, but in AliEn they will be in the file catalog, 
184    // mapped from AliRoot and pecified in the jdl input list.
185     
186    // For now connection to top input container and common AOD output container
187    // is done in this macro, but in future these containers will be connected
188    // from each task configuration macro.
189
190    if (iESDfilter && !iAODanalysis) {
191       //  ESD filter task configuration.
192       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C");
193       AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilter(useKFILTER);
194    }   
195
196    // AOD tags
197    if (useAODTAGS) {
198       AliAnalysisTaskTagCreator* tagTask = new AliAnalysisTaskTagCreator("AOD Tag Creator");
199       mgr->AddTask(tagTask);
200       AliAnalysisDataContainer *coutTags = mgr->CreateContainer("cTag",  TTree::Class(), 
201                                            AliAnalysisManager::kOutputContainer, "AOD.tag.root");
202       mgr->ConnectInput (tagTask, 0, mgr->GetCommonInputContainer());
203       mgr->ConnectOutput(tagTask, 1, coutTags);
204    }   
205     
206     // Jet analysis
207    if (iJETAN) {
208       gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskJets.C");
209       AliAnalysisTaskJets *taskjets = AddTaskJets("AOD", "UA1");
210       if (!taskjets) ::Warning("AnalysisTrainNew", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
211    }
212        
213    // Proton analysis
214    if (iPWG2spectra) {
215       // protons
216       gROOT->LoadMacro("$ALICE_ROOT/PWG2/SPECTRA/macros/AddTaskProtons.C");
217       AliAnalysisTaskProtons *taskprotons = AddTaskProtons();
218       if (!taskprotons) ::Warning("AnalysisTrainNew", "AliAnalysisTaskProtons cannot run for this train conditions - EXCLUDED");
219       // cascades
220       gROOT->LoadMacro("$ALICE_ROOT/PWG2/SPECTRA/macros/AddTaskCheckCascade.C");
221       AliAnalysisTaskCheckCascade *taskcheckcascade = AddTaskCheckCascade();      
222       if (!taskcheckcascade) ::Warning("AnalysisTrainNew", "AliAnalysisTaskCheckCascade cannot run for this train conditions - EXCLUDED");
223       // v0's
224       gROOT->LoadMacro("$ALICE_ROOT/PWG2/SPECTRA/macros/AddTaskCheckV0.C");
225       AliAnalysisTaskCheckV0 *taskcheckV0 = AddTaskCheckV0();
226       if (!taskcheckV0) ::Warning("AnalysisTrainNew", "AliAnalysisTaskCheckV0 cannot run for this train conditions - EXCLUDED");
227       // strangeness
228       gROOT->LoadMacro("$ALICE_ROOT/PWG2/SPECTRA/macros/AddTaskStrange.C");
229       AliAnalysisTaskStrange *taskstrange = AddTaskStrange();
230       if (!taskstrange) ::Warning("AnalysisTrainNew", "AliAnalysisTaskStrange cannot run for this train conditions - EXCLUDED");
231    }   
232    
233    // Femtoscopy analysis modules
234    if (iPWG2femto) {
235       gROOT->LoadMacro("$ALICE_ROOT/PWG2/FEMTOSCOPY/macros/AddTaskFemto.C");
236       AliAnalysisTaskFemto *taskfemto = AddTaskFemto();
237       if (!taskfemto) ::Warning("AnalysisTrainNew", "AliAnalysisTaskFemto cannot run for this train conditions - EXCLUDED");
238    }   
239
240    // Kink analysis
241    if (iPWG2kink) {
242       gROOT->LoadMacro("$ALICE_ROOT/PWG2/KINK/macros/AddTaskKink.C");
243       AliAnalysisKinkESDMC *taskkink = AddTaskKink();
244       if (!taskkink) ::Warning("AnalysisTrainNew", "AliAnalysisKinkESDMC cannot run for this train conditions - EXCLUDED");
245       gROOT->LoadMacro("$ALICE_ROOT/PWG2/KINK/macros/AddTaskKinkResonance.C");
246       AliResonanceKinkPID *taskkinkres = AddTaskKinkResonance();
247       if (!taskkinkres) ::Warning("AnalysisTrainNew", "AliResonanceKinkPID cannot run for this train conditions - EXCLUDED");
248       gROOT->LoadMacro("$ALICE_ROOT/PWG2/KINK/macros/AddTaskKinkResonanceLikeSign.C");
249       AliResonanceKinkLikeSign *taskkinklikesign = AddTaskKinkResonanceLikeSign();
250       if (!taskkinklikesign) ::Warning("AnalysisTrainNew", "AliResonanceKinkLikeSign cannot run for this train conditions - EXCLUDED");
251    }   
252       
253   // PWG3 vertexing
254    if (iPWG3vertexing) {
255       gROOT->LoadMacro("$ALICE_ROOT/PWG3/vertexingHF/AddTaskVertexingHF.C");
256       AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
257       if (!taskvertexingHF) ::Warning("AnalysisTrainNew", "AliAnalysisTaskSEVertexingHF cannot run for this train conditions - EXCLUDED");
258    }   
259       
260    // PWG4 hadron correlations
261    if (iPWG4partcorr) {
262       gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskPartCorr.C");
263       AliAnalysisTaskParticleCorrelation *taskpartcorrPHOS = AddTaskPartCorr("AOD", "PHOS");
264       if (!taskpartcorrPHOS) ::Warning("AnalysisTrainNew", "AliAnalysisTaskParticleCorrelation PHOS cannot run for this train conditions - EXCLUDED");
265       AliAnalysisTaskParticleCorrelation *taskpartcorrEMCAL = AddTaskPartCorr("AOD", "EMCAL");
266       if (!taskpartcorrEMCAL) ::Warning("AnalysisTrainNew", "AliAnalysisTaskParticleCorrelation EMCAL cannot run for this train conditions - EXCLUDED");
267    }   
268    //==========================================================================
269    // FOR THE REST OF THE TASKS THE MACRO AddTaskXXX() is not yet implemented/
270    // Run the analysis
271    //    
272    if (mgr->InitAnalysis()) {
273       mgr->PrintStatus();
274       if (saveTrain) gSystem->ChangeDirectory(train_name);
275       StartAnalysis(smode, chain);
276    }   
277 }
278
279 //______________________________________________________________________________
280 void StartAnalysis(const char *mode, TChain *chain) {
281 // Start analysis.
282    Int_t imode = -1;
283    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
284    if (!strcmp(mode, "LOCAL")) imode = 0;
285    if (!strcmp(mode, "PROOF")) imode = 1;
286    if (!strcmp(mode, "GRID"))  imode = 2;
287    switch (imode) {
288       case 0:
289          if (!chain) {
290             ::Error("AnalysisTrainNew.C::StartAnalysis", "Cannot create the chain");
291             return;
292          }   
293          mgr->StartAnalysis(mode, chain);
294          return;
295       case 1:
296          if (!proof_dataset.Length()) {
297             ::Error("AnalysisTrainNew.C::StartAnalysis", "proof_dataset is empty");
298             return;
299          }   
300          mgr->StartAnalysis(mode, proof_dataset, 100000);
301          return;
302       case 2:
303          if (usePLUGIN) {
304             if (!mgr->GetGridHandler()) {
305                ::Error("AnalysisTrainNew.C::StartAnalysis", "Grid plugin not initialized");
306                return;
307             }   
308             mgr->StartAnalysis("grid");
309          } else {
310             if (!chain) {
311                ::Error("AnalysisTrainNew.C::StartAnalysis", "Cannot create the chain");
312                return;
313             }   
314             mgr->StartAnalysis(mode, chain);
315          }   
316          return;
317    }      
318 }          
319     
320 //______________________________________________________________________________
321 void CheckModuleFlags(const char *mode) {
322 // Checks selected modules and insure compatibility
323    Int_t imode = -1;
324    if (!strcmp(mode, "LOCAL")) imode = 0;
325    if (!strcmp(mode, "PROOF")) imode = 1;
326    if (!strcmp(mode, "GRID"))  imode = 2;
327    if (imode==1) {
328       if (!usePAR) {
329          ::Info("AnalysisTrainNew.C::CheckModuleFlags", "PAR files enabled due to PROOF analysis");
330          usePAR = kTRUE;
331       }   
332    }  
333    if (imode != 2) {
334       ::Info("AnalysisTrainNew.C::CheckModuleFlags", "AliEn plugin disabled since not in GRID mode");
335       usePLUGIN = kFALSE; 
336    }   
337    if (iAODanalysis) {
338    // AOD analysis
339       if (useMC)
340          ::Info("AnalysisTrainNew.C::CheckModuleFlags", "MC usage disabled in analysis on AOD's");
341       useMC = kFALSE;
342       useTR = kFALSE;
343       if (iESDfilter)
344          ::Info("AnalysisTrainNew.C::CheckModuleFlags", "ESD filter disabled in analysis on AOD's");
345       iESDfilter   = 0;
346       if (!iAODhandler) {
347          if (iJETAN) 
348             ::Info("AnalysisTrainNew.C::CheckModuleFlags", "JETAN disabled in analysis on AOD's without AOD handler");
349          iJETAN = 0;
350       }
351       // Disable tasks that do not work yet on AOD data
352       if (iPWG2kink)         
353          ::Info("AnalysisTrainNew.C::CheckModuleFlags", "PWG2kink disabled in analysis on AOD's");
354       iPWG2kink = 0;
355    } else {   
356    // ESD analysis
357       iMUONcopyAOD = 0;
358    }       
359    if (iJETAN) iESDfilter=1;
360    if (iESDfilter) iAODhandler=1;
361    if (iPWG2spectra || iPWG2flow || iPWG3vertexing) useCORRFW = kTRUE;
362    if (useKFILTER && !useMC) useKFILTER = kFALSE;
363    if (useAODTAGS && !iAODhandler) useAODTAGS = kFALSE;
364 }
365
366 //______________________________________________________________________________
367 Bool_t Connect(const char *mode) {
368 // Connect <username> to the back-end system.
369    Int_t imode = -1;
370    if (!strcmp(mode, "LOCAL")) imode = 0;
371    if (!strcmp(mode, "PROOF")) imode = 1;
372    if (!strcmp(mode, "GRID"))  imode = 2;
373    TString username = gSystem->Getenv("alien_API_USER");
374    switch (imode) {
375       case 0:
376          break;
377       case 1:
378          if  (!username.Length()) {
379             ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), "Make sure you:\n \
380                            1. Have called: alien-token-init <username>\n \
381                            2. Have called: >source /tmp/gclient_env_$UID");
382             return kFALSE;
383          }
384          ::Info("AnalysisTrainNew.C::Connect", "Connecting user <%s> to PROOF cluster <%s>", 
385                 username.Data(), proof_cluster.Data());
386          TProof::Open(Form("%s@%s", username.Data(), proof_cluster.Data()));       
387          if (!gProof) {
388             if (strcmp(gSystem->Getenv("XrdSecGSISRVNAMES"), "lxfsrd0506.cern.ch"))
389                ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), "Environment XrdSecGSISRVNAMES different from lxfsrd0506.cern.ch");
390             return kFALSE;
391          }
392          break;
393       case 2:      
394          if  (!username.Length()) {
395             ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), "Make sure you:\n \
396                            1. Have called: alien-token-init <username>\n \
397                            2. Have called: >source /tmp/gclient_env_$UID");
398             return kFALSE;
399          }
400          if (usePLUGIN && !gSystem->Getenv("alien_CLOSE_SE")) {
401             ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), 
402                            "When using the AliEn plugin it is preferable to define the \
403                            variable alien_CLOSE_SE in your environment.");
404             return kFALSE;
405          }
406          ::Info("AnalysisTrainNew.C::Connect", "Connecting user <%s> to AliEn ...", 
407                 username.Data());
408          TGrid::Connect("alien://");
409          if (!gGrid || !gGrid->IsConnected()) return kFALSE;
410          break;
411       default:
412          ::Error("AnalysisTrainNew.C::Connect", "Unknown run mode: %s", mode);
413          return kFALSE;
414    }
415    ::Info("AnalysisTrainNew.C::Connect","Connected in %s mode", mode);
416    return kTRUE;
417 }
418
419 //______________________________________________________________________________
420 Bool_t LoadCommonLibraries(const char *mode)
421 {
422 // Load common analysis libraries.
423    Int_t imode = -1;
424    if (!strcmp(mode, "LOCAL")) imode = 0;
425    if (!strcmp(mode, "PROOF")) imode = 1;
426    if (!strcmp(mode, "GRID"))  imode = 2;
427    if (!gSystem->Getenv("ALICE_ROOT")) {
428       ::Error("AnalysisTrainNew.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot"); 
429       return kFALSE;
430    }   
431    Bool_t success = kTRUE;
432    // ROOT libraries
433    gSystem->Load("libTree.so");
434    gSystem->Load("libGeom.so");
435    gSystem->Load("libVMC.so");
436    gSystem->Load("libPhysics.so");
437    
438    // Load framework classes. Par option ignored here.
439    switch (imode) {
440       case 0:
441       case 2:
442          if (useCPAR) {
443             success &= LoadLibrary("STEERBase", mode, kTRUE);
444             success &= LoadLibrary("ESD", mode, kTRUE);
445             success &= LoadLibrary("AOD", mode, kTRUE);
446             success &= LoadLibrary("ANALYSIS", mode, kTRUE);
447             success &= LoadLibrary("ANALYSISalice", mode, kTRUE);
448             if (useCORRFW) success &= LoadLibrary("CORRFW", mode, kTRUE);
449          } else {   
450             success &= LoadLibrary("libSTEERBase.so", mode);
451             success &= LoadLibrary("libESD.so", mode);
452             success &= LoadLibrary("libAOD.so", mode);
453             success &= LoadLibrary("libANALYSIS.so", mode);
454             success &= LoadLibrary("libANALYSISalice.so", mode);
455             if (useCORRFW) success &= LoadLibrary("libCORRFW.so", mode);
456             gROOT->ProcessLine(".include $ALICE_ROOT/include");
457          }   
458          break;
459       case 1:
460          Int_t ires = -1;
461          if (useAFPAR && !gSystem->AccessPathName(AFversion)) ires = gProof->UploadPackage(AFversion);
462          if (ires < 0) {
463             success &= LoadLibrary("STEERBase", mode);
464             success &= LoadLibrary("ESD", mode);
465             success &= LoadLibrary("AOD", mode);
466             success &= LoadLibrary("ANALYSIS", mode);
467             success &= LoadLibrary("ANALYSISalice", mode);
468             if (useCORRFW) success &= LoadLibrary("CORRFW", mode);
469          } else { 
470             ires = gProof->EnablePackage(AFversion);
471             if (ires<0) success = kFALSE;
472             if (useCORRFW) success &= LoadLibrary("CORRFW", mode);
473          }
474          break;         
475       default:
476          ::Error("AnalysisTrainNew.C::LoadCommonLibraries", "Unknown run mode: %s", mode);
477          return kFALSE;
478    }
479    if (success) {
480       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    SUCCESS");
481       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
482               gSystem->GetIncludePath());
483    } else {           
484       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    FAILED");
485    }   
486       
487    return success;
488 }
489
490 //______________________________________________________________________________
491 Bool_t LoadAnalysisLibraries(const char *mode)
492 {
493 // Load common analysis libraries.
494    Bool_t success = kTRUE;
495    if (iESDfilter) {
496       if (!LoadLibrary("PWG3base", mode, kTRUE) ||
497           !LoadLibrary("PWG3muon", mode, kTRUE)) return kFALSE;
498    }   
499    // JETAN
500    if (iJETAN) {
501       if (!LoadLibrary("JETAN", mode, kTRUE)) return kFALSE;
502    }   
503             
504    // PWG4 particle correlations
505    if (iPWG4partcorr) {   
506       if (!LoadLibrary("PWG4PartCorrBase", mode, kTRUE) ||
507           !LoadLibrary("PWG4PartCorrDep", mode, kTRUE)) return kFALSE;
508    }
509    // PWG2 task protons 
510    if (iPWG2spectra) {
511       if (!LoadLibrary("PWG2spectra", mode, kTRUE)) return kFALSE;
512    }
513    // PWG2 flow
514    if (iPWG2flow) {
515       if (!LoadLibrary("PWG2AOD", mode, kTRUE) ||
516           !LoadLibrary("PWG2flow", mode, kTRUE)) return kFALSE;
517    }
518    // PWG2 resonances
519    if (iPWG2res) {
520       if (!LoadLibrary("PWG2resonances", mode, kTRUE)) return kFALSE;
521    }   
522    // PWG2 kink
523    if (iPWG2kink) {
524       if (!LoadLibrary("PWG2kink", mode, kTRUE)) return kFALSE;
525    }   
526    // PWG2 femtoscopy
527    if (iPWG2femto) {
528       if (!LoadLibrary("PWG2AOD", mode, kTRUE) ||
529           !LoadLibrary("PWG2femtoscopy", mode, kTRUE) ||
530           !LoadLibrary("PWG2femtoscopyUser", mode, kTRUE)) return kFALSE;
531       TFile::Cp(gSystem->ExpandPathName("$(ALICE_ROOT)/PWG2/FEMTOSCOPY/macros/ConfigFemtoAnalysis.C"), Form("%s/ConfigFemtoAnalysis.C", train_name.Data()));
532       anaLibs += "ConfigFemtoAnalysis.C ";
533    }   
534    // Vertexing HF
535    if (iPWG3vertexing) {
536       if (!LoadLibrary("PWG3base", mode, kTRUE) ||
537           !LoadLibrary("PWG3vertexingHF", mode, kTRUE)) return kFALSE;
538    }   
539    ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", "Load other libraries:   SUCCESS");
540    return kTRUE;
541 }
542
543 //______________________________________________________________________________
544 Bool_t LoadLibrary(const char *module, const char *mode, Bool_t rec=kFALSE)
545 {
546 // Load a module library in a given mode. Reports success.
547    Int_t imode = -1;
548    Int_t result;
549    TString smodule(module);
550    if (!strcmp(mode, "LOCAL")) imode = 0;
551    if (!strcmp(mode, "PROOF")) imode = 1;
552    if (!strcmp(mode, "GRID"))  imode = 2;
553    TString mod(module);
554    if (!mod.Length()) {
555       ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
556       return kFALSE;
557    }   
558    // If a library is specified, just load it
559    if (smodule.EndsWith(".so")) {
560       mod.Remove(mod.Index(".so"));
561       result = gSystem->Load(mod);
562       if (result < 0) {
563          ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load library %s", module);
564          return kFALSE;
565       }
566       if (rec) anaLibs += Form("%s.so ",mod.Data()); 
567       return kTRUE;
568    } 
569    // Check if the library is already loaded
570    if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0)
571       return kTRUE;    
572    switch (imode) {
573       case 0:
574       case 2:
575          if (usePAR) {
576             result = SetupPar(module);
577             if (rec) anaPars += Form("%s.par ", module);
578          } else {
579             result = gSystem->Load(Form("lib%s.so", module));
580             if (rec) anaLibs += Form("lib%s.so ", module);
581          }   
582          break;
583       case 1:
584          result = gProof->UploadPackage(module);
585          if (result<0) {
586             result = gProof->UploadPackage(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", module)));
587             if (result<0) {
588                ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not find module %s.par in current directory nor in $ALICE_ROOT", module);
589                return kFALSE;
590             }
591          }   
592          result = gProof->EnablePackage(module);
593          break;
594       default:
595          return kFALSE;
596    }         
597    if (result < 0) {
598       ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load module %s", module);
599       return kFALSE;
600    }
601    return kTRUE;
602 }           
603
604
605 //______________________________________________________________________________
606 TChain *CreateChain(const char *mode, const char *plugin_mode)
607 {
608 // Create the input chain
609    Int_t imode = -1;
610    if (!strcmp(mode, "LOCAL")) imode = 0;
611    if (!strcmp(mode, "PROOF")) imode = 1;
612    if (!strcmp(mode, "GRID"))  imode = 2;
613    TChain *chain = NULL;
614    // Local chain
615    switch (imode) {
616       case 0:
617          if (iAODanalysis) {
618             if (!local_xmldataset.Length()) {
619                // Local AOD
620                chain = new TChain("aodTree");
621                if (gSystem->AccessPathName("data/AliAOD.root")) 
622                   ::Error("AnalysisTrainNew.C::CreateChain", "File: AliAOD.root not in ./data dir");
623                else chain->Add("data/AliAOD.root");
624             } else {
625                // Interactive AOD
626                chain = CreateChainSingle(local_xmldataset, "aodTree");
627             }
628          } else {      
629             if (!local_xmldataset.Length()) {
630                // Local ESD
631                chain = new TChain("esdTree");
632                if (gSystem->AccessPathName("data/AliESDs.root")) 
633                   ::Error("AnalysisTrainNew.C::CreateChain", "File: AliESDs.root not in ./data dir");
634                else chain->Add("data/AliESDs.root");
635             } else {
636                // Interactive ESD
637                chain = CreateChainSingle(local_xmldataset, "esdTree");
638             }   
639          }
640          break;
641       case 1:
642          break;
643       case 2:
644          if (usePLUGIN) {
645             AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
646             AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
647          } else {
648             TString           treeName = "esdTree";
649             if (iAODanalysis) treeName = "aodTree";
650             chain = CreateChainSingle("wn.xml", treeName);
651          }
652          break;      
653       default:   
654    }
655    if (chain && chain->GetNtrees()) return chain;
656    return NULL;
657 }   
658
659 //______________________________________________________________________________
660 TChain* CreateChainSingle(const char* xmlfile, const char *treeName)
661 {
662    printf("*******************************\n");
663    printf("*** Getting the ESD Chain   ***\n");
664    printf("*******************************\n");
665    TAlienCollection * myCollection  = TAlienCollection::Open(xmlfile);
666
667    if (!myCollection) {
668       ::Error("AnalysisTrainNew.C::CreateChainSingle", "Cannot create an AliEn collection from %s", xmlfile) ;
669       return NULL ;
670    }
671
672    TChain* chain = new TChain(treeName);
673    myCollection->Reset() ;
674    while ( myCollection->Next() ) chain->Add(myCollection->GetTURL("")) ;
675    chain->ls();
676    return chain;
677 }
678
679 //______________________________________________________________________________
680 Int_t SetupPar(char* pararchivename)
681 {
682    if (!pararchivename || !strlen(pararchivename)) return -1;
683    char processline[1024];
684    if (gSystem->AccessPathName(Form("%s.par", pararchivename))) {
685       if (!gSystem->AccessPathName(Form("%s/%s.par", gSystem->Getenv("ALICE_ROOT"),pararchivename))) {
686          ::Info("AnalysisTrainNew.C::SetupPar", "Getting %s.par from $ALICE_ROOT", pararchivename);
687          TFile::Cp(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", pararchivename)), 
688                    Form("%s.par",pararchivename));
689       } else {
690          ::Error("AnalysisTrainNew.C::SetupPar", "Cannot find %s.par", pararchivename);
691          return -1;
692       }   
693    }
694    if (usePLUGIN && saveTrain) gSystem->Exec(Form("ln -s ../%s.par %s",pararchivename, train_name.Data()));
695    gSystem->Exec(Form("tar xvzf %s.par", pararchivename));
696
697    TString ocwd = gSystem->WorkingDirectory();
698    if (!gSystem->ChangeDirectory(pararchivename)) return -1;
699         
700    // check for BUILD.sh and execute
701    if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
702       printf("*******************************\n");
703       printf("*** Building PAR archive    ***\n");
704       printf("*******************************\n");          
705       if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
706          Error("runProcess","Cannot Build the PAR Archive! - Abort!");
707          return -1;
708       }
709    }
710
711         // check for SETUP.C and execute
712         if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
713             printf("*******************************\n");
714             printf("*** Setup PAR archive       ***\n");
715             printf("*******************************\n");
716             gROOT->Macro("PROOF-INF/SETUP.C");
717         }       
718         if (!gSystem->ChangeDirectory(ocwd.Data())) return -1;
719    return 0;
720 }
721
722 //______________________________________________________________________________
723 AliAnalysisGrid* CreateAlienHandler(const char *plugin_mode)
724 {
725 // Check if user has a valid token, otherwise make one. This has limitations.
726 // One can always follow the standard procedure of calling alien-token-init then
727 //   source /tmp/gclient_env_$UID in the current shell.
728    if (!AliAnalysisGrid::CreateToken()) return NULL;
729    AliAnalysisAlien *plugin = new AliAnalysisAlien();
730 // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
731    plugin->SetRunMode(plugin_mode);
732    plugin->SetNtestFiles(1);
733    plugin->SetPreferedSE("ALICE::NIHAM::FILE");
734 // Set versions of used packages
735    plugin->SetAPIVersion("V2.4");
736    plugin->SetROOTVersion(root_version);
737    plugin->SetAliROOTVersion(aliroot_version);
738 // Declare input data to be processed.
739 // Method 1: Create automatically XML collections using alien 'find' command.
740 // Define production directory LFN
741    plugin->SetGridDataDir(alien_datadir);
742 // Set data search pattern
743    if (iAODanalysis) plugin->SetDataPattern("*AliAOD.root");
744    else              plugin->SetDataPattern("*AliESDs.root");
745 // ...then add run numbers to be considered
746    for (Int_t i=0; i<10; i++) {
747       if (run_numbers[i]==0) break;
748       plugin->AddRunNumber(run_numbers[i]);
749    }   
750 // Method 2: Declare existing data files (raw collections, xml collections, root file)
751 // If no path mentioned data is supposed to be in the work directory (see SetGridWorkingDir())
752 // XML collections added via this method can be combined with the first method if
753 // the content is compatible (using or not tags)
754 //   plugin->AddDataFile("tag.xml");
755 //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");
756 // Define alien work directory where all files will be copied. Relative to alien $HOME.
757    if (iAODanalysis) plugin->SetGridWorkingDir("analysisAOD");
758    else              plugin->SetGridWorkingDir("analysisESD");
759 // Declare alien output directory. Relative to working directory.
760    plugin->SetGridOutputDir(Form("output_%s",train_name.Data())); // In this case will be $HOME/work/output
761
762    TString ana_sources = "";
763    TString ana_add = "";
764    if (usePAR && anaPars.Length()) {
765       printf("%s\n", anaPars.Data());
766       TObjArray *arr;
767       TObjString *objstr;
768       arr = anaPars.Tokenize(" ");
769       TIter next(arr);
770       while ((objstr=(TObjString*)next())) plugin->EnablePackage(objstr->GetString());
771       delete arr;
772    } 
773    
774 // Declare the analysis source files names separated by blancs. To be compiled runtime
775 // using ACLiC on the worker nodes.
776    ana_sources = ana_sources.Strip();
777 // Declare all libraries (other than the default ones for the framework. These will be
778 // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
779    anaLibs     = anaLibs.Strip();   
780    if (ana_sources.Length()) plugin->SetAnalysisSource(ana_sources);
781    if (anaLibs.Length())     plugin->SetAdditionalLibs(anaLibs);
782      
783 // Declare the output file names separated by blancs.
784 // (can be like: file.root or file.root@ALICE::Niham::File)
785    plugin->SetDefaultOutputs();
786    plugin->SetMergeExcludes("AliAOD.root");
787 // Optionally define the files to be archived.
788 //   plugin->SetOutputArchive("log_archive.zip:stdout,stderr@ALICE::NIHAM::File root_archive.zip:*.root@ALICE::NIHAM::File");
789    plugin->SetOutputArchive("log_archive.zip:stdout,stderr");
790 // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
791    plugin->SetAnalysisMacro(Form("%s.C", train_name.Data()));
792 // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
793    plugin->SetSplitMaxInputFileNumber(100);
794 // Optionally set number of failed jobs that will trigger killing waiting sub-jobs.
795 //   plugin->SetMaxInitFailed(5);
796 // Optionally resubmit threshold.
797 //   plugin->SetMasterResubmitThreshold(90);
798 // Optionally set time to live (default 30000 sec)
799    plugin->SetTTL(30000);
800 // Optionally set input format (default xml-single)
801    plugin->SetInputFormat("xml-single");
802 // Optionally modify the name of the generated JDL (default analysis.jdl)
803    plugin->SetJDLName(Form("%s.jdl", train_name.Data()));
804 // Optionally modify the executable name (default analysis.sh)
805    plugin->SetExecutable(Form("%s.sh", train_name.Data()));
806 // Optionally modify job price (default 1)
807    plugin->SetPrice(1);      
808 // Optionally modify split mode (default 'se')    
809    plugin->SetSplitMode("se");
810    return plugin;
811 }
812
813 //______________________________________________________________________________
814 void WriteConfig()
815 {
816 // Write train configuration in a file. The file name has the format:
817 // train_[trainName]_ddMonthyyyy_time.C
818    gSystem->Exec("date +%d%b%Y_%Hh%M > date.tmp");
819    ifstream fdate("date.tmp");
820    if (!fdate.is_open()) {
821       ::Error("AnalysisTrainNew.C::Export","Could not generate file name");
822       return;
823    }
824    const char date[64];
825    fdate.getline(date,64);
826    fdate.close();
827    gSystem->Exec("rm date.tmp");
828    train_name = Form("train_%s_%s", train_name.Data(), date);
829    TString cdir = gSystem->WorkingDirectory();
830    gSystem->MakeDirectory(train_name);
831    gSystem->ChangeDirectory(train_name);
832    ofstream out;
833    out.open("ConfigTrain.C", ios::out); 
834    if (out.bad()) {
835       ::Error("AnalysisTrainNew.C::Export", "Cannot open ConfigTrain.C for writing");
836       return;
837    }
838    out << "{" << endl;
839    out << "   train_name      = " << "\"" << train_name.Data() << "\";" << endl;
840    out << "   proof_cluster   = " << "\"" << proof_cluster.Data() << "\";" << endl;
841    out << "   useAFPAR        = " << useAFPAR << ";" << endl;
842    if (useAFPAR) 
843       out << "   AFversion       = " << AFversion.Data() << ";" << endl;
844    out << "   proof_dataset   = " << "\"" << proof_dataset.Data() << "\";" << endl;
845    out << "   usePLUGIN       = " << usePLUGIN << ";" << endl;
846    out << "   usePAR          = " << usePAR << ";" << endl;
847    out << "   useCPAR         = " << useCPAR << ";" << endl;
848    out << "   root_version    = " << "\"" << root_version.Data() << "\";" << endl;
849    out << "   aliroot_version = " << "\"" << aliroot_version.Data() << "\";" << endl;
850    out << "   alien_datadir   = " << "\"" << alien_datadir.Data() << "\";" << endl;
851    for (Int_t i=0; i<10; i++) {
852       if (run_numbers[i]) 
853          out << "   run_numbers[" << i << "]  = " << run_numbers[i] << ";" << endl;
854    }
855    out << "   useDBG          = " << useDBG << ";" << endl;
856    out << "   useMC           = " << useMC << ";" << endl;
857    out << "   useTAGS         = " << useTAGS << ";" << endl;
858    out << "   useKFILTER      = " << useKFILTER << ";" << endl;
859    out << "   useTR           = " << useTR << ";" << endl;
860    out << "   useCORRFW       = " << useCORRFW << ";" << endl;
861    out << "   useAODTAGS      = " << useAODTAGS << ";" << endl;
862    out << "   saveTrain       = " << "kFALSE;" << endl << endl;
863    out << "   // Analysis modules" << endl;
864    out << "   iAODanalysis    = " << iAODanalysis << ";" << endl;
865    out << "   iAODhandler     = " << iAODhandler << ";" << endl;
866    out << "   iESDfilter      = " << iESDfilter << ";" << endl;
867    out << "   iMUONcopyAOD    = " << iMUONcopyAOD << ";" << endl;
868    out << "   iJETAN          = " << iJETAN << ";" << endl;
869    out << "   iPWG4partcorr   = " << iPWG4partcorr << ";" << endl;
870    out << "   iPWG2femto      = " << iPWG2femto << ";" << endl;
871    out << "   iPWG2spectra    = " << iPWG2spectra << ";" << endl;
872    out << "   iPWG2flow       = " << iPWG2flow << ";" << endl;
873    out << "   iPWG2res        = " << iPWG2res << ";" << endl;
874    out << "   iPWG2kink       = " << iPWG2kink << ";" << endl;
875    out << "}" << endl;
876    ::Info("AnalysisTrainNew.C::WriteConfig", "Train configuration wrote to file %s", Form("config_%s.C", train_name.Data()));
877    gSystem->ChangeDirectory(cdir);
878 }   
879
880 //______________________________________________________________________________
881 Bool_t LoadConfig(const char *filename)
882 {
883 // Read train configuration from file
884    if (gSystem->AccessPathName(filename)) {
885       ::Error("AnalysisTrainNew.C::LoadConfig", "Config file name not found");
886       return kFALSE;
887    }   
888    gROOT->ProcessLine(Form(".x %s", filename));
889    ::Info("AnalysisTrainNew.C::LoadConfig", "Train configuration loaded from file %s", filename);
890    return kTRUE;
891 }