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