Coverity fixes
[u/mrichter/AliRoot.git] / PWG2 / centraltrain / AnalysisTrainPWG2.C
1 //===================== ANALYSIS TRAIN ==============================
2 // To use: copy this macro to your work directory, modify the global
3 // part to match your needs, then run root.
4 // 
5 //    root[0] .L AnalysisTrain.C
6 // Grid full mode as below (other modes: test, offline, submit, terminate)
7 //    root[1] AnalysisTrainNew("grid", "full")
8 // CAF mode (requires root v5-23-02 + aliroot v4-16-Rev08)
9 //    root[2] AnalysisTrainNew("proof")
10 // Local mode requires AliESds.root or AliAOD.root in ./data directory
11 //    root[3] AnalysisTrainNew("local")
12 // 
13 // In proof and grid modes, a token is needed and sourcing the
14 // produced environment file.
15 //
16 // If 'saveTrain' flag is set, the train will generate a directory
17 // name and run in this directory. A configuration file
18 // 'ConfigTrain.C' will be generated.  One can replay at any time the
19 // train via:
20 // 
21 //    root[1] AnalysisTrainNew(ana_mode, plugin_mode, "train_default_<date>/ConfigTrain.C")
22
23 //==================   TRAIN NAME   ==================================
24 TString     train_name         = "PWG2";    // local folder name
25 TString     train_tag          = "_Pb-Pb_"; // Train special tag
26                                             // appended to visible
27                                             // name. ("data", "sim",
28                                             // "pp", "highmult", ...) 
29 // Name in train page (DON'T CHANGE)
30 TString     visible_name       = Form("PWG2%s$2_$3", train_tag.Data()); //# FIXED #
31 // Add train composition and other comments
32 TString     job_comment        = "PWG2 tasks on ESDs";
33 TString     job_tag            = Form("%s: %s", visible_name.Data(), 
34                                       job_comment.Data());
35 //====================================================================
36
37 // ### Settings that make sense in PROOF only
38 //====================================================================
39 TString     proof_cluster      = "alice-caf.cern.ch";
40 Bool_t      useAFPAR           = kFALSE;  // use AF special par file
41 TString     AFversion          = "AF-v4-17";
42 // Change CAF dataset here
43 TString     proof_dataset      = "/COMMON/COMMON/LHC09a4_run8100X#/esdTree";
44 TString     proof_outdir       = "";
45
46 // ### Settings that make sense when using the Alien plugin
47 //====================================================================
48 Int_t       runOnData          = 1;       // Set to 1 if processing real data
49 Int_t       iCollision         = 1;       // 0=pp, 1=Pb-Pb
50 Bool_t      usePLUGIN          = kTRUE;   // do not change
51 Bool_t      useProductionMode  = kTRUE;   // use the plugin in production mode
52
53 // Usage of par files ONLY in grid mode and ONLY if the code is not
54 // available in the deployed AliRoot versions. Par file search path:
55 // local dir, if not there $ALICE_ROOT.  To refresh par files, remove
56 // the ones in the workdir, then do "make <target.par>" in AliRoot.
57 Bool_t      usePAR             = kFALSE;  // use par files for extra libs
58 Bool_t      useCPAR            = kFALSE;  // use par files for common libs
59 TString     root_version       = "v5-27-06c";  // *CHANGE ME IF MORE
60                                                // *RECENT IN GRID* 
61 TString     aliroot_version    = "v4-21-15-AN";  // *CHANGE ME IF MORE
62                                                  // *RECENT IN GRID* 
63 // Change production base directory here (test mode)
64 TString     alien_datadir      = "/alice/data/2010/LHC10h";
65 // Work directory in GRID (DON'T CHANGE)
66 TString     grid_workdir       = "/alice/cern.ch/user/a/alidaq/PWG2/PWG2_$2";
67 // Data pattern - change as needed for test mode
68 // TString     data_pattern       = "*ESDs/pass1/AOD033/*AOD.root";
69 TString     data_pattern       = "*ESDs/pass1/*ESDs.root";
70 // Set the run range
71 Int_t run_numbers[10] = {137844}; // **********************!!!!!!!
72 // AliEn output directory. If blank will become output_<train_name>
73 // Output directory (DON'T CHANGE)
74 TString     alien_outdir       = "$1/PWG2OUT$2";
75 // Input collection (production mode)
76 TString     data_collection    = "$1/input.xml";
77 // Output folder to write delta AOD's. Considered if not null.
78 TString     outputSingleFolder = "";
79 //TString     outputSingleFolder = "deltas";
80 // Number of files merged in a chunk
81 Int_t       maxMergeFiles      = 20;
82 // Files that should not be merged
83 TString     mergeExclude       = ("AliAOD.root "
84                                   "AliAOD.VertexingHF.root "
85                                   "AliAOD.Jets.root "
86                                   "deltaAODPartCorr.root "
87                                   "AliAOD.Muons.root "
88                                   "AliAOD.Dimuons.root "
89                                   "AliAOD.Dielectron.root "
90                                   "AliAODCentrality.root");
91 TString     mergeDirName       = "PWG2OUT$2";
92 // Make replicas on the storages below
93 TString     outputStorages      = "disk=4";
94 // Number of runs per master job
95 Int_t       nRunsPerMaster     = 10;
96 // Maximum number of files per job (gives size of AOD)
97 Int_t       nFilesPerJob       = 5;
98 // Int_t       nFilesPerJob       = 1; (AOD->delta AOD production case)
99 // ### Settings that make sense only for local analysis
100 //==============================================================================
101 // Change local xml dataset for local interactive analysis
102 TString     local_xmldataset   = "";
103
104 // ### Other flags to steer the analysis
105 //==============================================================================
106 Bool_t      usePhysicsSelection = kTRUE;  // use physics selection
107 Bool_t      useBKrejection      = kFALSE; // use BK rejection
108 Bool_t      useCentrality       = kTRUE;  // centrality delta AOD
109 Bool_t      useTender           = kFALSE; // use tender wagon
110 Bool_t      useV0tender         = kFALSE; // use V0 correction in tender
111 Bool_t      useMergeViaJDL      = kTRUE;  // merge via JDL
112 Bool_t      useFastReadOption   = kFALSE; // use xrootd tweaks
113 Bool_t      useOverwriteMode    = kTRUE;  // overwrite existing collections
114 Bool_t      useDATE             = kFALSE; // use date in train name
115 Bool_t      useDBG              = kTRUE;  // activate debugging
116 Bool_t      useMC               = kFALSE; // use MC info
117 Bool_t      useTAGS             = kFALSE; // use ESD tags for selection
118 Bool_t      useKFILTER          = kFALSE; // use Kinematics filter
119 Bool_t      useTR               = kFALSE; // use track references
120 Bool_t      useCORRFW           = kTRUE;  // do not change
121 Bool_t      useAODTAGS          = kFALSE; // use AOD tags
122 Bool_t      saveTrain           = kTRUE;  // save train configuration as:
123 Bool_t      saveCanvases        = kFALSE; // save canvases created in Terminate
124 Bool_t      saveProofToAlien    = kFALSE; // save proof outputs in AliEn
125
126 // ### Analysis modules to be included. Some may not be yet fully implemented.
127 //==============================================================================
128 Int_t       iAODanalysis       = 0;      // Analysis on input AOD's
129 Int_t       iAODhandler        = 1;      // Analysis produces an AOD or dAOD's
130
131 Int_t       iPWG2fmd           = 1;      // FMD forward analysis (PWG2)
132 Int_t       iPWG2femto         = 1;      // Femtoscopy two-track analysis (PWG2)
133 Int_t       iPWG2spectra       = 1;      // Charge hadron spectra (PWG2)
134
135 // Temporaries.
136 TString anaPars = "";
137 TString anaLibs = "";
138 // Function signatures
139 class AliAnalysisAlien;
140
141 //______________________________________________________________________________
142 void AnalysisTrainPWG2(const char *analysis_mode="local",
143                        const char *plugin_mode="full",
144                        const char *config_file="")
145 {
146   // Main analysis train macro. If a configuration file is provided,
147   // all parameters are taken from there but may be altered by
148   // CheckModuleFlags.
149   if (strlen(config_file) && !LoadConfig(config_file)) return;
150   TString smode(analysis_mode);
151   smode.ToUpper();
152   TString spmode(plugin_mode);
153   spmode.ToLower();
154   if (spmode == "test") useProductionMode = kFALSE;
155   // Check compatibility of selected modules
156   CheckModuleFlags(smode);
157   if (saveTrain)              WriteConfig();
158
159   printf("=================================================================\n");
160   printf("===========    RUNNING ANALYSIS TRAIN %s IN %s MODE   ==========\n", 
161          train_name.Data(),smode.Data());
162   printf("=================================================================\n");
163   printf("=  Configuring analysis train for:                              =\n");
164   if (iAODanalysis)        printf("=  %-60s  =\n", "AOD analysis");
165   else                     printf("=  %-60s  =\n", "ESD analysis");
166   if (usePhysicsSelection) printf("=  %-60s  =\n", "Physics selection");
167   if (useTender)           printf("=  %-60s  =\n", "TENDER");
168   if (iPWG2fmd)            printf("=  %-60s  =\n", "PWG2 FMD");
169   if (iPWG2femto)          printf("=  %-60s  =\n", "PWG2 Femtoscopy");
170   if (iPWG2spectra)        printf("=  %-60s  =\n", "PWG2 Charged Spectra");
171   printf("=================================================================\n");
172   printf(":: use physics selection: %d\n", (UInt_t)usePhysicsSelection);
173   printf(":: use xrootd tweaks:     %d\n", (UInt_t)useFastReadOption);
174   printf(":: use overwrite xml    : %d\n", (UInt_t)useOverwriteMode);
175   printf(":: use merge via JDL:     %d\n", (UInt_t)useMergeViaJDL);
176   printf(":: use MC truth:          %d\n", (UInt_t)useMC);
177   printf(":: use KINE filter:       %d\n", (UInt_t)useKFILTER);
178   printf(":: use track references:  %d\n", (UInt_t)useTR);
179   printf(":: use tags:              %d\n", (UInt_t)useTAGS);
180   printf(":: use AOD tags:          %d\n", (UInt_t)useAODTAGS);
181   printf(":: use debugging:         %d\n", (UInt_t)useDBG);
182   printf(":: use PAR files:         %d\n", (UInt_t)usePAR);
183   printf(":: use AliEn plugin:      %d\n", (UInt_t)usePLUGIN);
184
185   //==================================================================
186   // Connect to back-end system
187   // if (!Connect(smode)) {
188   //   ::Error("AnalysisTrain", "Could not connect to %s back-end", 
189   //           analysis_mode);
190   //   return;
191   // }
192
193   // Load common libraries and set include path
194   if (!LoadCommonLibraries(smode)) {
195     ::Error("AnalysisTrain", "Could not load common libraries");
196     return;
197   }
198
199   // Make the analysis manager and connect event handlers
200   AliAnalysisManager *mgr  = 
201     new AliAnalysisManager("Analysis Train", "Production train");
202   if (saveProofToAlien) mgr->SetSpecialOutputLocation(proof_outdir);
203   if (!strcmp(plugin_mode, "test")) mgr->SetNSysInfo(1);
204   // Load analysis specific libraries
205   if (!LoadAnalysisLibraries(smode)) {
206     ::Error("AnalysisTrain", "Could not load analysis libraries");
207     return;
208   }
209
210   // Create input handler (input container created automatically)
211   if (iAODanalysis) {
212     // AOD input handler
213     AliAODInputHandler *aodH = new AliAODInputHandler();
214     mgr->SetInputEventHandler(aodH);
215   } else {
216     // ESD input handler
217     AliESDInputHandler *esdHandler = new AliESDInputHandler();
218     if (useTAGS) esdHandler->SetReadTags();
219     mgr->SetInputEventHandler(esdHandler);
220   }
221   // Monte Carlo handler
222   if (useMC && !iAODanalysis) {
223     AliMCEventHandler* mcHandler = new AliMCEventHandler();
224     mgr->SetMCtruthEventHandler(mcHandler);
225     mcHandler->SetReadTR(useTR);
226   }
227   // AOD output container, created automatically when setting an AOD handler
228   if (iAODhandler) {
229     // AOD output handler
230     AliAODHandler* aodHandler   = new AliAODHandler();
231     aodHandler->SetOutputFileName("AliAOD.root");
232     mgr->SetOutputEventHandler(aodHandler);
233     if (iAODanalysis) {
234       aodHandler->SetFillAOD(kFALSE);
235       aodHandler->SetCreateNonStandardAOD();
236       // if (iPWG3vertexing) 
237       //   aodHandler->SetOutputFileName("AliAOD.VertexingHF.root");
238     }
239   }
240   // Debugging if needed
241   if (useDBG) mgr->SetDebugLevel(3);
242   if (saveCanvases) mgr->SetSaveCanvases(kTRUE);
243
244   //==========================================================================
245   // Create the chain. In this example it is created only from ALIEN
246   // files but can be done to work in batch or grid mode as well.
247   TChain *chain = CreateChain(smode, plugin_mode);
248
249   //==========================================================================
250   // Load the tasks configuration macros for all wagons. These files
251   // are supposed now to be in the current workdir, but in AliEn they
252   // will be in the file catalog, mapped from AliRoot and pecified in
253   // the jdl input list.
254   // 
255   // For now connection to top input container and common AOD output
256   // container is done in this macro, but in future these containers
257   // will be connected from each task configuration macro.
258   AddAnalysisTasks();
259
260   // Run the analysis
261   //
262   if (usePLUGIN) {
263     AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
264     AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
265   }
266
267   if (mgr->InitAnalysis()) {
268     mgr->PrintStatus();
269     if (saveTrain || strlen(config_file)) gSystem->ChangeDirectory(train_name);
270     StartAnalysis(smode, chain);
271   }
272 }
273
274 //____________________________________________________________________
275 void AddToMacroPath(const char* path)
276 {
277   TString macroPath(gROOT->GetMacroPath());
278   TString tgt(gSystem->ExpandPathName(path));
279   if (macroPath.Contains(tgt)) return;
280   macroPath.Append(":");
281   macroPath.Append(tgt);
282   gROOT->SetMacroPath(macroPath.Data());
283 }
284
285 //____________________________________________________________________
286 void AddAnalysisTasks()
287 {
288   // Add all analysis task wagons to the train
289   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
290   //
291   // Tender and supplies. Needs to be called for every event.
292   //
293   if (useTender) {
294     AddToMacroPath("$ALICE_ROOT/ANALYSIS/TenderSupplies/");
295     gROOT->LoadMacro("AddTaskTender.C");
296     // IF V0 tender needed, put kTRUE below
297     AliAnalysisTaskSE *tender = AddTaskTender(useV0tender);
298     // tender->SetDebugLevel(2);
299   }
300   
301   if (usePhysicsSelection) {
302     // Physics selection task
303     AddToMacroPath("$ALICE_ROOT/ANALYSIS/macros/");
304     gROOT->LoadMacro("AddTaskPhysicsSelection.C");
305     mgr->RegisterExtraFile("event_stat.root");
306     AliPhysicsSelectionTask *physSelTask =
307       AddTaskPhysicsSelection(useMC,useBKrejection);
308     mgr->AddStatisticsTask(AliVEvent::kMB);
309   }
310   
311   if (useCentrality) {
312     // Common Centrality task
313     AddToMacroPath("$ALICE_ROOT/ANALYSIS/macros/");
314     gROOT->LoadMacro("AddTaskCentrality.C");
315     AliCentralitySelectionTask* ctask = AddTaskCentrality();
316     if (ctask) {
317       Int_t pass = 0;
318       if      (data_pattern.Contains("pass1")) pass = 1;
319       else if (data_pattern.Contains("pass2")) pass = 2;
320       else if (data_pattern.Contains("pass3")) pass = 3;
321       ctask->SetPass(pass);
322       if (useMC) ctask->SetMCInput();
323     }
324     else
325       ::Warning("AnalysisTrainNew", "AliCentralitySelectionTask cannot "
326                 "run for this train conditions - EXCLUDED");
327   }
328   
329   // AOD tags
330   if (useAODTAGS) {
331     AliAnalysisTaskTagCreator* tagTask =
332       new AliAnalysisTaskTagCreator("AOD Tag Creator");
333     mgr->AddTask(tagTask);
334     AliAnalysisDataContainer *coutTags =
335       mgr->CreateContainer("cTag",  TTree::Class(),
336                            AliAnalysisManager::kOutputContainer,
337                            "AOD.tag.root");
338     mgr->ConnectInput (tagTask, 0, mgr->GetCommonInputContainer());
339     mgr->ConnectOutput(tagTask, 1, coutTags);
340   }
341
342
343   // ********** PWG2 wagons *****************************************
344   AliAnalysisManager::SetCommonFileName("PWG2histograms.root");
345   
346   // PWG2 FMD
347   if (iPWG2fmd) {
348     AddToMacroPath("$ALICE_ROOT/PWG2/FORWARD/analysis2/");
349     
350     gROOT->LoadMacro("AddTaskForwardMult.C");
351     gROOT->LoadMacro("AddTaskCentralMult.C");
352     /* Input parameters for the analysis task.
353      *
354      * - sys, collision system 0: get from data, 1: pp, 2: AA
355      * - sNN, Center of mass energy (per nucleon pair) 0: get from
356      *        data, otherwise sqrt(sNN) in GeV
357      * - fld, L3 magnetic field. if sNN=0: get from data, otherwise
358      *        magnetic field in kG
359      */
360     UShort_t sys = iCollision+1;
361     UShort_t sNN = 0;
362     Short_t  fld = 0.5;
363     AliAnalysisTask *taskForward = AddTaskForwardMult(useMC, sys, sNN, fld);
364     if (!taskForward)
365       ::Warning("AnalysisTrainNew", "AliForwardMultiplicityTask cannot "
366                 "run for this train conditions - EXCLUDED");
367     AliAnalysisTask *taskCentral = AddTaskCentralMult(useMC, sys, sNN, fld);
368     if (!taskCentral)
369       ::Warning("AnalysisTrainNew", "AliCentralMultiplicityTask cannot "
370                 "run for this train conditions - EXCLUDED");
371   }
372   
373   // PWG2 Femtoscopy
374   if (iPWG2femto) {
375     AddToMacroPath("$ALICE_ROOT/PWG2/FEMTOSCOPY/macros");
376     // AddToMacroPath("$ALICE_ROOT/PWG2/FEMTOSCOPY/macros/Train/TwoTrackQA");
377     gROOT->LoadMacro("AddTaskFemto.C");
378     AliAnalysisTask *taskFemto = 
379       AddTaskFemto("$ALICE_ROOT/PWG2/FEMTOSCOPY/macros/Train/TwoTrackQA/ConfigFemtoAnalysisCentral.C",
380                    Form("%i, %i, %i", iAODanalysis?0:1, iCollision, 0));
381     if (!taskFemto) 
382       ::Warning("AnalysisTrainNew", "AliAnalysisTaskFemto cannot run for "
383                 "this train conditions - EXCLUDED");
384   }
385
386   // PWG2 Spectra
387   if (iPWG2spectra) {
388     AddToMacroPath("$ALICE_ROOT/PWG2/SPECTRA/macros");
389     gROOT->LoadMacro("AddTaskITSsaSpectra.C");
390     AliAnalysisTask *taskSpectraITSsa = 
391       AddTaskITSsaSpectra(0,useMC,-1,-1,iCollision);
392     if (!taskSpectraITSsa) 
393       ::Warning("AnalysisTrainNew", "AliAnalysisTaskSpectraITSsa cannot "
394                 "run for this train conditions - EXCLUDED");
395
396     gROOT->LoadMacro("AddTaskChargedHadronSpectraITSTruncatedMean.C");
397     AliAnalysisTask *taskSpectraITSTPC = 
398       AddTaskChargedHadronSpectraITSTruncatedMean(-1,-1,useMC,iCollision,
399                                                   "configChargedHadronSpectraITSTruncatedMeanTask.C");
400     if (!taskSpectraITSTPC) 
401       ::Warning("AnalysisTrainNew", "AliAnalysisTaskSpectraITSTPC "
402                 "cannot run for this train conditions - EXCLUDED");
403   }
404 }
405
406 //______________________________________________________________________________
407 void StartAnalysis(const char *mode, TChain *chain) {
408   // Start analysis.
409   Int_t imode = -1;
410   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
411   if (!strcmp(mode, "LOCAL")) imode = 0;
412   if (!strcmp(mode, "PROOF")) imode = 1;
413   if (!strcmp(mode, "GRID"))  imode = 2;
414   switch (imode) {
415   case 0:
416     if (!chain) {
417       ::Error("AnalysisTrainNew.C::StartAnalysis", "Cannot create the chain");
418       return;
419     }
420     mgr->StartAnalysis(mode, chain);
421     return;
422   case 1:
423     if (!proof_dataset.Length()) {
424       ::Error("AnalysisTrainNew.C::StartAnalysis", "proof_dataset is empty");
425       return;
426     }
427     mgr->StartAnalysis(mode, proof_dataset, 1000);
428     return;
429   case 2:
430     if (usePLUGIN) {
431       if (!mgr->GetGridHandler()) {
432         ::Error("AnalysisTrainNew.C::StartAnalysis", 
433                 "Grid plugin not initialized");
434         return;
435       }
436       mgr->StartAnalysis("grid");
437     } else {
438       if (!chain) {
439         ::Error("AnalysisTrainNew.C::StartAnalysis", "Cannot create the chain");
440         return;
441       }
442       mgr->StartAnalysis(mode, chain);
443     }
444     return;
445   }
446 }
447
448 //______________________________________________________________________________
449 void CheckModuleFlags(const char *mode) 
450 {
451   // Checks selected modules and insure compatibility
452   Int_t imode = -1;
453   if (!strcmp(mode, "LOCAL")) imode = 0;
454   if (!strcmp(mode, "PROOF")) imode = 1;
455   if (!strcmp(mode, "GRID"))  imode = 2;
456   if (imode==1) {
457     if (!usePAR) {
458       ::Info("AnalysisTrainNew.C::CheckModuleFlags", 
459              "PAR files enabled due to PROOF analysis");
460       usePAR = kTRUE;
461     }
462   }
463   if (imode != 2) {
464     ::Info("AnalysisTrainNew.C::CheckModuleFlags", 
465            "AliEn plugin disabled since not in GRID mode");
466     usePLUGIN = kFALSE;
467   }
468   if (iAODanalysis) {
469     // AOD analysis
470     if (useMC)
471       ::Info("AnalysisTrainNew.C::CheckModuleFlags", 
472              "MC usage disabled in analysis on AOD's");
473     if (useAODTAGS)
474       ::Info("AnalysisTrainNew.C::CheckModuleFlags", 
475              "AOD tags usage disabled in analysis on AOD's");
476     useMC = kFALSE;
477     useTR = kFALSE;
478     useAODTAGS = kFALSE;
479   } else {
480     // ESD analysis
481     if (!useMC) useTR = kFALSE;
482     if (!useTR) {
483       ::Info("AnalysisTrainNew.C::CheckModuleFlags", 
484              "iPWG2evchar disabled if not reading track references");
485       iPWG2evchar = 0;
486     }
487   }
488   if (useKFILTER && !useMC) useKFILTER = kFALSE;
489   if (useAODTAGS && !iAODhandler) useAODTAGS = kFALSE;
490 }
491
492 //______________________________________________________________________________
493 Bool_t Connect(const char *mode) 
494 {
495   // Connect <username> to the back-end system.
496   Int_t imode = -1;
497   if (!strcmp(mode, "LOCAL")) imode = 0;
498   if (!strcmp(mode, "PROOF")) imode = 1;
499   if (!strcmp(mode, "GRID"))  imode = 2;
500   TString username = gSystem->Getenv("alien_API_USER");
501   switch (imode) {
502   case 0:
503     break;
504   case 1:
505     if  (!username.Length()) {
506       ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), 
507               "Make sure you:\n "
508               "\t1. Have called: alien-token-init <username>\n"
509               "\t2. Have called: >source /tmp/gclient_env_$UID");
510       return kFALSE;
511     }
512     ::Info("AnalysisTrainNew.C::Connect", 
513            "Connecting user <%s> to PROOF cluster <%s>",
514            username.Data(), proof_cluster.Data());
515     gEnv->SetValue("XSec.GSI.DelegProxy", "2");
516     //  TProof::Open(Form("%s@%s:31093", username.Data(), 
517     //               proof_cluster.Data()));
518     TProof::Open(Form("%s@%s", username.Data(), proof_cluster.Data()));
519     if (!gProof) {
520       if (strcmp(gSystem->Getenv("XrdSecGSISRVNAMES"), "lxfsrd0506.cern.ch"))
521         ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode), 
522                 "Environment XrdSecGSISRVNAMES different from "
523                 "lxfsrd0506.cern.ch");
524       return kFALSE;
525     }
526     TGrid::Connect("alien://");
527     if (gGrid) {
528       TString homedir = gGrid->GetHomeDirectory();
529       TString workdir = homedir + train_name;
530       if (!gGrid->Cd(workdir)) {
531         gGrid->Cd(homedir);
532         if (gGrid->Mkdir(workdir)) {
533           gGrid->Cd(train_name);
534           ::Info("AnalysisTrainNew::Connect()", "Directory %s created", 
535                  gGrid->Pwd());
536         }
537       }
538       gGrid->Mkdir("proof_output");
539       gGrid->Cd("proof_output");
540       proof_outdir = Form("alien://%s", gGrid->Pwd());
541     }
542     break;
543   case 2:
544     if (usePLUGIN && !gSystem->Getenv("alien_CLOSE_SE")) {
545       ::Error(Form("AnalysisTrainNew.C::Connect <%s>", mode),
546               "When using the AliEn plugin it is preferable to define the "
547               "variable alien_CLOSE_SE in your environment.");
548       return kFALSE;
549     }
550     ::Info("AnalysisTrainNew.C::Connect", "Connecting user <%s> to AliEn ...",
551            username.Data());
552     TGrid::Connect("alien://");
553     if (!gGrid || !gGrid->IsConnected()) return kFALSE;
554     break;
555   default:
556     ::Error("AnalysisTrainNew.C::Connect", "Unknown run mode: %s", mode);
557     return kFALSE;
558   }
559   ::Info("AnalysisTrainNew.C::Connect","Connected in %s mode", mode);
560   return kTRUE;
561 }
562
563 //______________________________________________________________________________
564 Bool_t LoadCommonLibraries(const char *mode)
565 {
566   // Load common analysis libraries.
567   Int_t imode = -1;
568   if (!strcmp(mode, "LOCAL")) imode = 0;
569   if (!strcmp(mode, "PROOF")) imode = 1;
570   if (!strcmp(mode, "GRID"))  imode = 2;
571   if (!gSystem->Getenv("ALICE_ROOT")) {
572     ::Error("AnalysisTrainNew.C::LoadCommonLibraries", 
573             "Analysis train requires that analysis libraries are "
574             "compiled with a local AliRoot");
575     return kFALSE;
576   }
577   Bool_t success = kTRUE;
578   // ROOT libraries
579   gSystem->Load("libTree.so");
580   gSystem->Load("libGeom.so");
581   gSystem->Load("libVMC.so");
582   gSystem->Load("libPhysics.so");
583   gSystem->Load("libMinuit.so");
584
585   // Load framework classes. Par option ignored here.
586   switch (imode) {
587   case 0:
588   case 2:
589     if (useCPAR) {
590       success &= LoadLibrary("STEERBase", mode, kTRUE);
591       success &= LoadLibrary("ESD", mode, kTRUE);
592       success &= LoadLibrary("AOD", mode, kTRUE);
593       success &= LoadLibrary("ANALYSIS", mode, kTRUE);
594       success &= LoadLibrary("ANALYSISalice", mode, kTRUE);
595       if (useCORRFW) success &= LoadLibrary("CORRFW", mode, kTRUE);
596     } else {
597       success &= LoadLibrary("libSTEERBase.so", mode);
598       success &= LoadLibrary("libESD.so", mode);
599       success &= LoadLibrary("libAOD.so", mode);
600       success &= LoadLibrary("libANALYSIS.so", mode);
601       success &= LoadLibrary("libANALYSISalice.so", mode);
602       if (useCORRFW) success &= LoadLibrary("libCORRFW.so", mode);
603       gROOT->ProcessLine(".include $ALICE_ROOT/include");
604     }
605     break;
606   case 1:
607     Int_t ires = -1;
608     if (useAFPAR && !gSystem->AccessPathName(AFversion)) 
609       ires = gProof->UploadPackage(AFversion);
610     if (ires < 0) {
611       success &= LoadLibrary("STEERBase", mode);
612       success &= LoadLibrary("ESD", mode);
613       success &= LoadLibrary("AOD", mode);
614       success &= LoadLibrary("ANALYSIS", mode);
615       success &= LoadLibrary("ANALYSISalice", mode);
616       if (useCORRFW) success &= LoadLibrary("CORRFW", mode);
617     } else {
618       ires = gProof->EnablePackage(AFversion);
619       if (ires<0) success = kFALSE;
620       if (useCORRFW) success &= LoadLibrary("CORRFW", mode);
621     }
622     break;
623   default:
624     ::Error("AnalysisTrainNew.C::LoadCommonLibraries", 
625             "Unknown run mode: %s", mode);
626     return kFALSE;
627   }
628   if (success) {
629     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
630            "Load common libraries:    SUCCESS");
631     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
632            "Include path for Aclic compilation:\n%s",
633            gSystem->GetIncludePath());
634   } else {
635     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
636            "Load common libraries:    FAILED");
637   }
638
639   return success;
640 }
641
642 //______________________________________________________________________________
643 Bool_t LoadAnalysisLibraries(const char *mode)
644 {
645   // Load common analysis libraries.
646   Bool_t success = kTRUE;
647   if (useTender) {
648     if (!LoadLibrary("TENDER", mode, kTRUE) ||
649         !LoadLibrary("TENDERSupplies", mode, kTRUE)) return kFALSE;
650   }
651   // PWG2 fmd
652   if (iPWG2fmd) {
653     if (!LoadLibrary("PWG2forward2", mode, kTRUE)) return kFALSE;
654   }
655   // PWG2 femtoscopy
656   if (iPWG2femto) {
657     if (!LoadLibrary("PWG2AOD", mode, kTRUE) ||
658         !LoadLibrary("PWG2femtoscopy", mode, kTRUE) ||
659         !LoadLibrary("PWG2femtoscopyUser", mode, kTRUE)) return kFALSE;
660   }
661   // PWG2 spectra
662   if (iPWG2spectra) {
663     if (!LoadLibrary("PWG2spectra", mode, kTRUE)) return kFALSE;
664   }
665   ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", 
666          "Load other libraries:   SUCCESS");
667   return kTRUE;
668 }
669
670 //______________________________________________________________________________
671 Bool_t LoadLibrary(const char *module, const char *mode, Bool_t rec=kFALSE)
672 {
673   // Load a module library in a given mode. Reports success.
674   Int_t imode = -1;
675   Int_t result;
676   TString smodule(module);
677   if (!strcmp(mode, "LOCAL")) imode = 0;
678   if (!strcmp(mode, "PROOF")) imode = 1;
679   if (!strcmp(mode, "GRID"))  imode = 2;
680   TString mod(module);
681   if (!mod.Length()) {
682     ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
683     return kFALSE;
684   }
685   // If a library is specified, just load it
686   if (smodule.EndsWith(".so")) {
687     mod.Remove(mod.Index(".so"));
688     result = gSystem->Load(mod);
689     if (result < 0) {
690       ::Error("AnalysisTrainNew.C::LoadLibrary", 
691               "Could not load library %s", module);
692       return kFALSE;
693     }
694     if (rec) anaLibs += Form("%s.so ",mod.Data());
695     return kTRUE;
696   }
697   // Check if the library is already loaded
698   if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0)
699     return kTRUE;
700   switch (imode) {
701   case 0:
702   case 2:
703     if (usePAR) {
704       result = SetupPar(module);
705       if (rec) anaPars += Form("%s.par ", module);
706     } else {
707       result = gSystem->Load(Form("lib%s.so", module));
708       if (rec) anaLibs += Form("lib%s.so ", module);
709     }
710     break;
711   case 1:
712     result = gProof->UploadPackage(module);
713     if (result<0) {
714       result = 
715         gProof->UploadPackage(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par",
716                                                            module)));
717       if (result<0) {
718         ::Error("AnalysisTrainNew.C::LoadLibrary", 
719                 "Could not find module %s.par in current directory "
720                 "nor in $ALICE_ROOT", module);
721         return kFALSE;
722       }
723     }
724     result = gProof->EnablePackage(module);
725     break;
726   default:
727     return kFALSE;
728   }
729   if (result < 0) {
730     ::Error("AnalysisTrainNew.C::LoadLibrary", 
731             "Could not load module %s", module);
732     return kFALSE;
733   }
734   return kTRUE;
735 }
736
737
738 //______________________________________________________________________________
739 TChain *CreateChain(const char *mode, const char *plugin_mode)
740 {
741   // Create the input chain
742   Int_t imode = -1;
743   if (!strcmp(mode, "LOCAL")) imode = 0;
744   if (!strcmp(mode, "PROOF")) imode = 1;
745   if (!strcmp(mode, "GRID"))  imode = 2;
746   TChain *chain = NULL;
747   // Local chain
748   switch (imode) {
749   case 0:
750     if (iAODanalysis) {
751       if (!local_xmldataset.Length()) {
752         // Local AOD
753         chain = new TChain("aodTree");
754         if (gSystem->AccessPathName("data/AliAOD.root"))
755           ::Error("AnalysisTrainNew.C::CreateChain", 
756                   "File: AliAOD.root not in ./data dir");
757         else {
758           if (!saveTrain) chain->Add("data/AliAOD.root");
759           else            chain->Add("../data/AliAOD.root");
760         }
761       } else {
762         // Interactive AOD
763         chain = CreateChainSingle(local_xmldataset, "aodTree");
764       }
765     } else {
766       if (!local_xmldataset.Length()) {
767         // Local ESD
768         chain = new TChain("esdTree");
769         if (gSystem->AccessPathName("data/AliESDs.root"))
770           ::Error("AnalysisTrainNew.C::CreateChain", 
771                   "File: AliESDs.root not in ./data dir");
772         else {
773           if (!saveTrain) chain->Add("data/AliESDs.root");
774           else            chain->Add("../data/AliESDs.root");
775         }
776       } else {
777         // Interactive ESD
778         chain = CreateChainSingle(local_xmldataset, "esdTree");
779       }
780     }
781     break;
782   case 1:
783     break;
784   case 2:
785     if (usePLUGIN) {
786       // AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
787       // AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
788     } else {
789       TString           treeName = "esdTree";
790       if (iAODanalysis) treeName = "aodTree";
791       chain = CreateChainSingle("wn.xml", treeName);
792     }
793     break;
794   default:
795   }
796   if (chain && chain->GetNtrees()) return chain;
797   return NULL;
798 }
799
800 //______________________________________________________________________________
801 TChain* CreateChainSingle(const char* xmlfile, const char *treeName)
802 {
803   printf("*******************************\n");
804   printf("*** Getting the ESD Chain   ***\n");
805   printf("*******************************\n");
806   TAlienCollection * myCollection  = TAlienCollection::Open(xmlfile);
807
808   if (!myCollection) {
809     ::Error("AnalysisTrainNew.C::CreateChainSingle", 
810             "Cannot create an AliEn collection from %s", xmlfile) ;
811     return NULL ;
812   }
813
814   TChain* chain = new TChain(treeName);
815   myCollection->Reset() ;
816   while ( myCollection->Next() ) chain->Add(myCollection->GetTURL("")) ;
817   chain->ls();
818   return chain;
819 }
820
821 //______________________________________________________________________________
822 Int_t SetupPar(char* pararchivename)
823 {
824   if (!pararchivename || !strlen(pararchivename)) return -1;
825   char processline[1024];
826   if (gSystem->AccessPathName(Form("%s.par", pararchivename))) {
827     if (!gSystem->AccessPathName(Form("%s/%s.par", 
828                                       gSystem->Getenv("ALICE_ROOT"),
829                                       pararchivename))) {
830       ::Info("AnalysisTrainNew.C::SetupPar", 
831              "Getting %s.par from $ALICE_ROOT", pararchivename);
832       TFile::Cp(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", 
833                                              pararchivename)),
834                 Form("%s.par",pararchivename));
835     } else {
836       ::Error("AnalysisTrainNew.C::SetupPar", "Cannot find %s.par", 
837               pararchivename);
838       return -1;
839     }
840   }
841   if (usePLUGIN && saveTrain) 
842     gSystem->Exec(Form("ln -s ../%s.par %s",pararchivename, train_name.Data()));
843   gSystem->Exec(Form("tar xvzf %s.par", pararchivename));
844
845   TString ocwd = gSystem->WorkingDirectory();
846   if (!gSystem->ChangeDirectory(pararchivename)) return -1;
847
848   // check for BUILD.sh and execute
849   if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
850     printf("*******************************\n");
851     printf("*** Building PAR archive    ***\n");
852     printf("*******************************\n");
853     if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
854       Error("runProcess","Cannot Build the PAR Archive! - Abort!");
855       return -1;
856     }
857   }
858
859   // check for SETUP.C and execute
860   if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
861     printf("*******************************\n");
862     printf("*** Setup PAR archive       ***\n");
863     printf("*******************************\n");
864     gROOT->Macro("PROOF-INF/SETUP.C");
865   }
866   if (!gSystem->ChangeDirectory(ocwd.Data())) return -1;
867   return 0;
868 }
869
870 //______________________________________________________________________________
871 AliAnalysisAlien* CreateAlienHandler(const char *plugin_mode)
872 {
873   // Check if user has a valid token, otherwise make one. This has
874   // limitations.  One can always follow the standard procedure of
875   // calling alien-token-init then
876   AliAnalysisAlien *plugin = new AliAnalysisAlien();
877   // Set the run mode (can be "full", "test", "offline", "submit" or
878   // "terminate")
879   plugin->SetRunMode(plugin_mode);
880   if (useProductionMode) {
881     plugin->SetProductionMode();
882     plugin->AddDataFile(data_collection);
883   }
884
885   if (!outputSingleFolder.IsNull()) {
886     plugin->SetOutputSingleFolder(outputSingleFolder);
887     plugin->SetOutputToRunNo();
888   }
889   plugin->SetJobTag(job_tag);
890   plugin->SetNtestFiles(5);
891   plugin->SetCheckCopy(kFALSE);
892   plugin->SetMergeDirName(mergeDirName);
893   // Set versions of used packages
894   plugin->SetAPIVersion("V1.1x");
895   plugin->SetROOTVersion(root_version);
896   plugin->SetAliROOTVersion(aliroot_version);
897   // Declare input data to be processed.
898   // Method 1: Create automatically XML collections using alien 'find' command.
899   // Define production directory LFN
900   plugin->SetGridDataDir(alien_datadir);
901   // Set data search pattern
902   plugin->SetDataPattern(data_pattern);
903   if (!useProductionMode) {
904     if (runOnData) {
905       plugin->SetRunPrefix("%09d");
906     }
907     //   if (!iAODanalysis) plugin->SetRunRange(run_range[0], run_range[1]);
908     for (Int_t i=0; i<10; i++) {
909       if (run_numbers[i]==0) break;
910       plugin->AddRunNumber(run_numbers[i]);
911     }
912   }
913   // Define alien work directory where all files will be
914   // copied. Relative to alien $HOME.
915   plugin->SetGridWorkingDir(grid_workdir);
916   // Declare alien output directory. Relative to working directory.
917   if (alien_outdir.IsNull()) alien_outdir = Form("output_%s",train_name.Data());
918   plugin->SetGridOutputDir(alien_outdir);
919
920   TString ana_sources = "";
921   TString ana_add = "";
922   if (usePAR && anaPars.Length()) {
923     printf("%s\n", anaPars.Data());
924     TObjArray *arr;
925     TObjString *objstr;
926     arr = anaPars.Tokenize(" ");
927     TIter next(arr);
928     while ((objstr=(TObjString*)next())) plugin->EnablePackage(objstr->GetString());
929     delete arr;
930   }
931
932   // Declare the analysis source files names separated by blancs. To
933   // be compiled runtime using ACLiC on the worker nodes.
934   ana_sources = ana_sources.Strip();
935   // Declare all libraries (other than the default ones for the
936   // framework. These will be loaded by the generated analysis
937   // macro. Add all extra files (task .cxx/.h) here.
938   anaLibs     = anaLibs.Strip();
939   if (ana_sources.Length()) plugin->SetAnalysisSource(ana_sources);
940   if (anaLibs.Length())     plugin->SetAdditionalLibs(anaLibs);
941
942   // Declare the output file names separated by blancs.  (can be like:
943   // file.root or file.root@ALICE::Niham::File)
944   plugin->SetDefaultOutputs();
945   plugin->SetMergeExcludes(mergeExclude);
946   plugin->SetMaxMergeFiles(maxMergeFiles);
947   plugin->SetNrunsPerMaster(nRunsPerMaster);
948   // Optionally define the files to be archived.
949   //   plugin->SetOutputArchive("log_archive.zip:stdout,stderr@ALICE::NIHAM::File root_archive.zip:AliAOD.root,AOD.tag.root@ALICE::NIHAM::File");
950
951
952   // Put default output files to archive
953   TString listhists = "";
954   TString listaods  = "";
955   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
956   TIter next(mgr->GetOutputs());
957   AliAnalysisDataContainer *output;
958   while ((output=(AliAnalysisDataContainer*)next())) {
959     const char *filename = output->GetFileName();
960     if (!(strcmp(filename, "default"))) {
961       if (!mgr->GetOutputEventHandler()) continue;
962       filename = mgr->GetOutputEventHandler()->GetOutputFileName();
963       if (listaods.Length()) listaods += ",";
964       listaods += filename;
965       listaods += ",";
966       listaods += "pyxsec_hists.root";
967     } else {
968       if (!strcmp(filename, "pyxsec_hists.root")) continue;
969       if (listhists.Contains(filename)) continue;
970       if (listhists.Length()) listhists += ",";
971       listhists += filename;
972     }
973   }
974   if (mgr->GetExtraFiles().Length()) {
975     if (listaods.Length()) listaods += ",";
976     listaods += mgr->GetExtraFiles();
977     listaods.ReplaceAll(" ", ",");
978   }
979   if (listhists.Length()) listhists = Form("hist_archive.zip:%s@%s", 
980                                            listhists.Data(), 
981                                            outputStorages.Data());
982   if (listaods.Length())  listaods  = Form("aod_archive.zip:%s@%s", 
983                                            listaods.Data(), 
984                                            outputStorages.Data());
985   if (!listhists.Length() && !listaods.Length()) {
986     ::Fatal("AnalysisTrainNew", "No task output !");
987   }
988   TString outputArchive = Form("log_archive.zip:stderr@%s", 
989                                outputStorages.Data());
990   if (listaods.Length()) {
991     outputArchive += " ";
992     outputArchive += listaods;
993   }
994   if (listhists.Length()) {
995     outputArchive += " ";
996     outputArchive += listhists;
997   }
998   // Set friends
999   //   if (iAODanalysis && iPWG3d2h)
1000   //      plugin->SetFriendChainName("AliAOD.VertexingHF.root");
1001   //   plugin->SetOutputArchive(outputArchive);
1002   
1003   // Optionally set a name for the generated analysis macro (default
1004   // MyAnalysis.C)
1005   plugin->SetAnalysisMacro(Form("%s.C", train_name.Data()));
1006   // Optionally set a name for the generated validation script
1007   plugin->SetValidationScript("PWG2validation.sh");
1008   // Optionally set maximum number of input files/subjob (default 100,
1009   // put 0 to ignore)
1010   plugin->SetSplitMaxInputFileNumber(nFilesPerJob);
1011   // Optionally set number of failed jobs that will trigger killing
1012   // waiting sub-jobs.
1013   //   plugin->SetMaxInitFailed(5);
1014   // Optionally modify the number of replicas
1015   plugin->SetNumberOfReplicas(4);
1016   // Optionally resubmit threshold.
1017   //   plugin->SetMasterResubmitThreshold(90);
1018   // Optionally set time to live (default 30000 sec)
1019   plugin->SetTTL(70000);
1020   // Optionally set input format (default xml-single)
1021   plugin->SetInputFormat("xml-single");
1022   // Optionally modify the name of the generated JDL (default analysis.jdl)
1023   plugin->SetJDLName(Form("%s.jdl", train_name.Data()));
1024   // Optionally modify the executable name (default analysis.sh)
1025   plugin->SetExecutable(Form("%s.sh", train_name.Data()));
1026   // Optionally modify job price (default 1)
1027   plugin->SetPrice(1);
1028   // Merge via JDL
1029   plugin->SetMergeViaJDL(useMergeViaJDL);
1030   // Use fastread option
1031   plugin->SetFastReadOption(useFastReadOption);
1032   // UseOverwrite mode
1033   plugin->SetOverwriteMode(useOverwriteMode);
1034   plugin->SetExecutableCommand("aliroot -b -q");
1035   // Optionally modify split mode (default 'se')
1036   plugin->SetSplitMode("se");
1037   return plugin;
1038 }
1039
1040 //______________________________________________________________________________
1041 void WriteConfig()
1042 {
1043   // Write train configuration in a file. The file name has the
1044   // format: train_[trainName]_ddMonthyyyy_time.C
1045   if (useDATE) {
1046     gSystem->Exec("date +%d%b%Y_%Hh%M > date.tmp");
1047     ifstream fdate("date.tmp");
1048     if (!fdate.is_open()) {
1049       ::Error("AnalysisTrainNew.C::Export","Could not generate file name");
1050       return;
1051     }
1052     const char date[64];
1053     fdate.getline(date,64);
1054     fdate.close();
1055     gSystem->Exec("rm date.tmp");
1056     train_name = Form("%s_%s", train_name.Data(), date);
1057   }
1058   TString cdir = gSystem->WorkingDirectory();
1059   gSystem->MakeDirectory(train_name);
1060   gSystem->ChangeDirectory(train_name);
1061   ofstream out;
1062   TString outName(Form("%sConfig.C",train_name.Data()));
1063   out.open(outName.Data(), ios::out);
1064   if (out.bad()) {
1065     ::Error("AnalysisTrainNew.C::Export", 
1066             "Cannot open %s for writing", outName.Data());
1067     return;
1068   }
1069   out << "{" << endl;
1070   out << "   train_name      = " << "\"" << train_name.Data() << "\";" << endl;
1071   out << "   proof_cluster   = " << "\"" << proof_cluster.Data() << "\";" << endl;
1072   out << "   useAFPAR        = " << useAFPAR << ";" << endl;
1073   if (useAFPAR)
1074     out << "   AFversion       = " << AFversion.Data() << ";" << endl;
1075   out << "   proof_dataset   = " << "\"" << proof_dataset.Data() << "\";" << endl;
1076   out << "   usePLUGIN       = " << usePLUGIN << ";" << endl;
1077   out << "   usePAR          = " << usePAR << ";" << endl;
1078   out << "   useCPAR         = " << useCPAR << ";" << endl;
1079   out << "   root_version    = " << "\"" << root_version.Data() << "\";" << endl;
1080   out << "   aliroot_version = " << "\"" << aliroot_version.Data() << "\";" << endl;
1081   out << "   alien_datadir   = " << "\"" << alien_datadir.Data() << "\";" << endl;
1082   if (!alien_outdir.Length()) alien_outdir = Form("output_%s",train_name.Data());
1083   out << "   alien_outdir    = " << "\"" << alien_outdir.Data() << "\";" << endl;
1084   out << "   maxMergeFiles   = " << maxMergeFiles << ";" << endl;
1085   out << "   mergeExclude    = " << "\"" << mergeExclude.Data() << "\";" << endl;
1086   out << "   nRunsPerMaster  = " << nRunsPerMaster << ";" << endl;
1087   out << "   nFilesPerJob    = " << nFilesPerJob << ";" << endl;
1088   //   for (Int_t i=0; i<10; i++) {
1089   //      if (run_numbers[i])
1090   //         out << "   run_numbers[" << i << "]  = " << run_numbers[i] << ";" << endl;
1091   //   }
1092   //   out << "   run_range[0]    = " << run_range[0] << ";" << endl;
1093   //   out << "   run_range[1]    = " << run_range[1] << ";" << endl;
1094   out << "   usePhysicsSelection = " << usePhysicsSelection << ";" << endl;
1095   out << "   useTender       = " << useTender << ";" << endl;
1096   out << "   useMergeViaJDL  = " << useMergeViaJDL << ";" << endl;
1097   out << "   useOverwriteMode  = " << useOverwriteMode << ";" << endl;
1098   out << "   useFastReadOption = " << useFastReadOption << ";" << endl;
1099   out << "   useDBG          = " << useDBG << ";" << endl;
1100   out << "   useMC           = " << useMC << ";" << endl;
1101   out << "   useTAGS         = " << useTAGS << ";" << endl;
1102   out << "   useKFILTER      = " << useKFILTER << ";" << endl;
1103   out << "   useTR           = " << useTR << ";" << endl;
1104   out << "   useCORRFW       = " << useCORRFW << ";" << endl;
1105   out << "   useAODTAGS      = " << useAODTAGS << ";" << endl;
1106   out << "   saveTrain       = " << "kFALSE;" << endl << endl;
1107   out << "   // Analysis modules" << endl;
1108   out << "   iAODanalysis    = " << iAODanalysis << ";" << endl;
1109   out << "   iAODhandler     = " << iAODhandler << ";" << endl;
1110   out << "   iPWG2fmd        = " << iPWG2fmd << ";" << endl;
1111   out << "   iPWG2femto      = " << iPWG2femto << ";" << endl;
1112   out << "   iPWG2spectra    = " << iPWG2spectra << ";" << endl;
1113   out << "}" << endl;
1114   ::Info("AnalysisTrainNew.C::WriteConfig", 
1115          "Train configuration wrote to file %s", outName.Data());
1116   gSystem->ChangeDirectory(cdir);
1117 }
1118
1119 //____________________________________________________________________
1120 Bool_t LoadConfig(const char *filename)
1121 {
1122   // Read train configuration from file
1123   if (gSystem->AccessPathName(filename)) {
1124     ::Error("AnalysisTrainNew.C::LoadConfig", "Config file name not found");
1125     return kFALSE;
1126   }
1127   gROOT->ProcessLine(Form(".x %s", filename));
1128   ::Info("AnalysisTrainNew.C::LoadConfig", 
1129          "Train configuration loaded from file %s", filename);
1130   return kTRUE;
1131 }
1132 //____________________________________________________________________
1133 //
1134 // EOF
1135 //