a84a8f2419ee6cec58c64c8ad0664782069ee4a6
[u/mrichter/AliRoot.git] / PWGLF / SPECTRA / PiKaPr / HMPID / AnalysisTrainHMPID.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 AnalysisTrainHMPID.C
5 // Grid full mode as below (other modes: test, offline, submit, terminate)
6 //    root[1] AnalysisTrainHMPID("grid", "full")
7 // CAF mode (requires root v5-23-02 + aliroot v4-16-Rev08)
8 //    root[2] AnalysisTrainHMPID("proof")
9 // Local mode requires AliESds.root or AliAOD.root in ./data directory
10 //    root[3] AnalysisTrainHMPID("local")
11 // In proof and grid modes, a token is needed and sourcing the produced environment file.
12 //
13
14 // =============================================================================
15 // ### General Steering variables
16 // =============================================================================
17 //== general setup variables
18 TString     kTrainName         = "hmpidAnalysis"; // (no blancs or special characters)
19 TString     kJobTag            = "HMPID Tasks analysis train configured"; //
20 Bool_t      kUsePAR            = kFALSE;  // use par files for extra libs
21 Bool_t      kUseCPAR           = kFALSE;  // use par files for common libs
22 Bool_t      kFillAOD           = kFALSE;  // switch of AOD filling for on the fly analysis
23
24 Int_t       iAODhandler        = 1;      // Analysis produces an AOD or dAOD's
25 Int_t       iESDfilter         = 0;      // ESD to AOD filter (barrel + muon tracks)
26 Int_t       iPhysicsSelection  = 1;      // Physics selection task
27 Bool_t      kUseKinefilter     = kFALSE; // use Kinematics filter
28 Bool_t      kUseMuonfilter     = kFALSE; // use muon filter
29 TString     kCommonOutputFileName = "HmpidOutput.root";
30
31
32 //== general process variables
33
34 // ### Other flags to steer the analysis
35 //==============================================================================
36 Bool_t      kSkipTerminate      = kFALSE; // Do not call Teminate
37 Bool_t      kDebugLevel         = kTRUE; // activate debugging
38 Int_t       kUseSysInfo         = 0; // activate debugging
39 Bool_t      kUseMC              = kTRUE;  // use MC info
40 Bool_t      kIsMC               = kFALSE;  // is MC info, if false it overwrites Use(AOD)MC
41 Bool_t      kUseESDTags         = kFALSE; // use ESD tags for selection
42 Bool_t      kUseTR              = kFALSE;  // use track references
43
44 // ### Analysis modules to be included. Some may not be yet fully implemented.
45 //==============================================================================
46 Int_t       iHMPID             = 1;      // Basic HMPID analysis task
47 Int_t       iJETAN             = 0;      // Jet analysis (PWG4) // 1 write standard 2 write non-standard jets
48 Int_t       iJETANLib          = 0;
49 Int_t       kHighPtFilterMask  = 16;     // change depending on the used AOD Filter
50
51
52 //==============================================================================
53 // ### PROOF Steering varibales
54 //==============================================================================
55 //== proof setup variables
56 TString     kProofCluster      = "alice-caf.cern.ch";
57 Bool_t      kProofUseAFPAR     = kTRUE;  // use AF special par file
58 TString     kProofAFversion    = "VO_ALICE@AliRoot::v4-20-08-AN";
59 //== proof input and output variables
60 TString     kProofDataSet      = "/alice/sim/LHC10d2_117220";
61 //== proof process variables
62 Bool_t      kProofClearPackages = kFALSE;
63 Int_t       kProofEvents = 10000;
64 Int_t       kProofOffset = 0;
65
66 //==============================================================================
67 // ### Grid plugin Steering varibiables
68 //==============================================================================
69 //== grid plugin setup variables
70 Bool_t      kPluginUse         = kTRUE;   // do not change
71 Bool_t      kPluginUseProductionMode  = kFALSE;   // use the plugin in production mode
72 TString     kPluginRootVersion       = "v5-30-03";  // *CHANGE ME IF MORE RECENT IN GRID*
73 TString     kPluginAliRootVersion    = "v5-02-06-AN";  // *CHANGE ME IF MORE RECENT IN GRID*                                          
74 Bool_t      kPluginMergeViaJDL       = kTRUE;  // merge via JDL
75 Bool_t      kPluginFastReadOption    = kFALSE;  // use xrootd flags to reduce timeouts
76 Bool_t      kPluginOverwriteMode     = kTRUE;  // overwrite existing collections
77 Int_t       kPluginOutputToRunNumber = 1;     // write the output to subdirs named after run number
78 TString kPluginExecutableCommand = "root -b -q";
79
80 // == grid plugin input and output variables
81 TString     kGridDatadir      = "/alice/data/2010/LHC10b";
82 TString     kGridLocalRunList = "";
83 TString     kGridWorkDir      = "LHC10b/pass3";   // Alien working directory
84 TString     kGridOutdir       = ""; // AliEn output directory. If blank will become output_<kTrainName>
85 TString     kGridDataSet      = ""; // sub working directory not to confuse different run xmls 
86 Int_t       kGridRunRange[2]       = {114783, 114783}; // Set the run range
87 TString     kGridRunPattern        = "%03d"; // important for leading zeroes!!
88 TString     kGridPassPattern       = "/ESDs/pass3";
89 //TString     kGridPassPattern       = "ESDs/pass1"; to work with plugin->AddRunNumber
90 TString     kGridExtraFiles        = ""; // files that will be added to the input list in the JDL...
91 Int_t       kGridMaxMergeFiles      = 12; // Number of files merged in a chunk grid run range
92 TString     kGridMergeExclude       = "AliAOD.root"; // Files that should not be merged
93 TString     kGridOutputStorages      = "disk=2"; // Make replicas on the storages
94 // == grid process variables
95 Int_t       kGridRunsPerMaster     = 1; // Number of runs per master job
96 Int_t       kGridFilesPerJob       = 100; // Maximum number of files per job (gives size of AOD)
97
98 //==============================================================================
99 // ### Local Steering variables
100 //==============================================================================
101 //== local setup variables
102 //== local input and output variables
103 TString     kLocalXMLDataset   = ""; // Change local xml dataset for local interactive analysis
104 TString     kLocalDataList   = "list.txt"; // Change local xml dataset for local interactive analysis
105 // == local process variables
106
107
108
109 // Temporaries.
110 TString anaPars = "";
111 TString anaLibs = "";
112 TString anaLibsExtra = "";
113 TString anaSources = "";
114 // Function signatures
115 class AliAnalysisAlien;
116
117 //______________________________________________________________________________
118 void AnalysisTrainHMPID(const char *analysis_mode="local", const char *plugin_mode="",
119                         const char *config_file="",Int_t iOffset = 0)
120 {
121 // Main analysis train macro. If a configuration file is provided, all parameters
122 // are taken from there but may be altered by CheckModuleFlags.
123
124    if (strlen(config_file) && !LoadConfig(config_file)) return;
125
126    if(iOffset)kProofOffset = iOffset;
127    TString smode(analysis_mode);
128    smode.ToUpper();
129    // Check compatibility of selected modules
130    CheckModuleFlags(smode);
131
132    printf("==================================================================\n");
133    printf("===========    RUNNING ANALYSIS TRAIN %s IN %s MODE   ==========\n", kTrainName.Data(),smode.Data());
134    printf("==================================================================\n");
135    printf("=  Configuring analysis train for:                               =\n");
136    printf("=  ESD analysis                                                  =\n");
137    if (iPhysicsSelection)   printf("=  Physics selection                                                    =\n");
138    if (iESDfilter)   printf("=  ESD filter                                                    =\n");
139    if (iJETAN)       printf("=  Jet analysis                                                  =\n");
140    printf("==================================================================\n");
141    printf(":: use MC truth      %d\n", (UInt_t)kUseMC);
142    printf(":: use KINE filter   %d\n", (UInt_t)kUseKinefilter);
143    printf(":: use track refs    %d\n", (UInt_t)kUseTR);
144    printf(":: use tags          %d\n", (UInt_t)kUseESDTags);
145    printf(":: use debugging     %d\n", (UInt_t)kDebugLevel);
146    printf(":: use PAR files     %d\n", (UInt_t)kUsePAR);
147    printf(":: use AliEn plugin  %d\n", (UInt_t)kPluginUse);
148    
149    //==========================================================================
150    // Connect to back-end system
151    if (!Connect(smode)) {
152       ::Error("AnalysisTrain", "Could not connect to %s back-end", analysis_mode);
153       return;
154    }   
155
156    // Load common libraries and set include path
157    if (!LoadCommonLibraries(smode)) {
158       ::Error("AnalysisTrain", "Could not load common libraries");
159       return;
160    }
161
162
163     
164    // Make the analysis manager and connect event handlers
165    AliAnalysisManager *mgr  = new AliAnalysisManager("HMPIDTrain", "HMPID train");
166    if (kCommonOutputFileName.Length()>0)mgr->SetCommonFileName(kCommonOutputFileName.Data());
167    mgr->SetNSysInfo(0);
168    if (!strcmp(plugin_mode, "test")) mgr->SetNSysInfo(1);
169    if (kUseSysInfo)mgr->SetNSysInfo(kUseSysInfo);
170    mgr->SetSkipTerminate(kSkipTerminate);
171
172    // Load analysis specific libraries
173    if (!LoadAnalysisLibraries(smode)) {
174       ::Error("AnalysisTrain", "Could not load analysis libraries");
175      return;
176    }   
177
178    // Create input handler (input container created automatically)
179    // ESD input handler
180    AliESDInputHandler *esdHandler = new AliESDInputHandler();
181    if (kUseESDTags) esdHandler->SetReadTags();
182    esdHandler->SetReadFriends(kFALSE);
183    mgr->SetInputEventHandler(esdHandler);       
184
185    // Monte Carlo handler
186    if (kUseMC) {
187       AliMCEventHandler* mcHandler = new AliMCEventHandler();
188       mgr->SetMCtruthEventHandler(mcHandler);
189       mcHandler->SetReadTR(kUseTR); 
190    }   
191
192    // AOD output container, created automatically when setting an AOD handler
193    if (iAODhandler) {
194       // AOD output handler
195       AliAODHandler* aodHandler   = new AliAODHandler();
196       aodHandler->SetOutputFileName("AliAOD.root");
197       aodHandler->SetFillAODforRun(kFillAOD);
198       
199       mgr->SetOutputEventHandler(aodHandler);
200       AliAnalysisDataContainer *cout_aod = mgr->GetCommonOutputContainer();
201       cout_aod->SetSpecialOutput();
202    }
203
204    // Debugging if needed
205    if (kDebugLevel){
206       mgr->SetDebugLevel(3);
207    }
208    if(kUseSysInfo>0){
209       mgr->RegisterExtraFile("syswatch.root");
210       if(kGridMergeExclude.Length())kGridMergeExclude += " ";
211       kGridMergeExclude += "syswatch.root";
212    } else {
213       AliLog::SetGlobalLogLevel(AliLog::kError);
214    }
215
216    //==========================================================================
217    // Create the chain. In this example it is created only from ALIEN files but
218    // can be done to work in batch or grid mode as well.
219    TChain *chain = CreateChain(smode, plugin_mode);
220         
221    //==========================================================================
222    // Load the tasks configuration macros for all wagons. These files are supposed now to be
223    // in the current workdir, but in AliEn they will be in the file catalog, 
224    // mapped from AliRoot and pecified in the jdl input list.
225    if(iPhysicsSelection){
226      gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
227      AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection(); // last flag also adds information on  
228    }
229
230    if (iESDfilter) {
231       //  ESD filter task configuration.
232       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskESDFilter.C");
233       AliAnalysisTaskESDfilter *taskesdfilter = AddTaskESDFilter(kUseKinefilter,kUseMuonfilter);
234       if(kIsMC){
235          mgr->RegisterExtraFile("pyxsec_hists.root");
236          if(kGridMergeExclude.Length())kGridMergeExclude += " ";
237          kGridMergeExclude += "pyxsec_hists.root";
238       }
239    }   
240
241     // Jet analysis
242    if (iJETAN) {
243       gROOT->LoadMacro("$ALICE_ROOT/PWG4/macros/AddTaskJets.C");
244       AliAnalysisTaskJets *taskjets = 0;
245       if (iJETAN&1) taskjets = AddTaskJets(kHighPtFilterMask); 
246       if (!taskjets) ::Warning("AnalysisTrainHMPID", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
247    }
248    
249     gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C");
250     AliAnalysisTaskPIDResponse  *taskPIDResponse = AddTaskPIDResponse();
251       
252
253    if(iHMPID){
254      gROOT->LoadMacro("$ALICE_ROOT/HMPID/AddTaskHMPID.C");
255      AliHMPIDAnalysisTask *taskHmpid = AddTaskHMPID(kUseMC);
256      taskHmpid->SelectCollisionCandidates();
257      if (!taskHmpid) ::Warning("AnalysisTrainHMPID", "AliAnalysisTaskHMPID cannot run for this train conditions - EXCLUDED");
258    }
259
260    if (kPluginUse) {
261       AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
262       AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
263    }
264
265    if (mgr->InitAnalysis()) {
266      mgr->PrintStatus();
267      if (!strcmp(plugin_mode,"submit") && smode=="GRID"){
268        TString alien_workdir = gGrid->GetHomeDirectory();
269        alien_workdir += kGridWorkDir.Data();
270        if(kGridDataSet.Length()>0)alien_workdir += Form("/%s",kGridDataSet.Data());
271        AliAnalysisAlien *gridhandler = (AliAnalysisAlien*)mgr->GetGridHandler();
272        printf("=== AnalysisTrainHMPID:: Registering jdl in the work directory alien://%s/%s, should be done by the manager! ===\n",
273               alien_workdir.Data(),gridhandler->GetGridOutputDir());
274
275        TString dest;
276        dest = Form("%s/%s/%s.jdl",alien_workdir.Data(),gridhandler->GetGridOutputDir(),kTrainName.Data());
277        if(AliAnalysisAlien::FileExists(dest.Data())){
278      //  Printf("%s exist on grid removing...",dest.Data());
279      //  gGrid->Rm(dest.Data());
280        }
281        TFile::Cp(Form("file:%s.jdl",kTrainName.Data()),Form("alien://%s",dest.Data()));
282
283
284        TString dest;
285        dest = Form("%s/%s/%s_merge.jdl",alien_workdir.Data(),gridhandler->GetGridOutputDir(),kTrainName.Data());
286        if(AliAnalysisAlien::FileExists(dest.Data())){
287          //      Printf("%s exist on grid removing...",dest.Data());
288          //      gGrid->Rm(dest.Data());
289        }
290        TFile::Cp(Form("file:%s_merge.jdl",kTrainName.Data()),Form("alien://%s",dest.Data()));
291      }
292
293      AliLog::SetGlobalLogLevel(AliLog::kError);
294      if((kUseSysInfo>0 && smode=="LOCAL") || !strcmp(plugin_mode, "test")){
295        TFile *fM = TFile::Open("manager_local.root","RECREATE");
296        mgr->Write();
297        fM->Close();
298      }
299
300      StartAnalysis(smode, chain);
301        
302      if((kUseSysInfo>0 && smode=="LOCAL") || !strcmp(plugin_mode, "test")){
303        for(int i = 0;i < mgr->GetTopTasks()->GetEntries();i++){
304          mgr->ProfileTask(i);
305        }
306      }
307      if (!strcmp(plugin_mode, "offline") && smode=="GRID"){
308        // Offline mode path files
309        //       PatchJDL();
310        PatchAnalysisMacro();
311      }
312    }
313 }
314
315
316 //______________________________________________________________________________
317 void StartAnalysis(const char *mode, TChain *chain) {
318
319    Int_t imode = -1;
320    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
321    if (!strcmp(mode, "LOCAL")) imode = 0;
322    if (!strcmp(mode, "PROOF")) imode = 1;
323    if (!strcmp(mode, "GRID"))  imode = 2;
324    switch (imode) {
325       case 0:
326          if (!chain) {
327             ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Cannot create the chain");
328             return;
329          }
330          mgr->StartAnalysis(mode, chain);
331          return;
332       case 1:
333          if (!kProofDataSet.Length()) {
334             ::Error("AnalysisTrainHMPID.C::StartAnalysis", "kProofDataSet is empty");
335             return;
336          }
337          mgr->StartAnalysis(mode, kProofDataSet, kProofEvents,kProofOffset);
338          return;
339       case 2:
340          if (kPluginUse) {
341             if (!mgr->GetGridHandler()) {
342                ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Grid plugin not initialized");
343                return;
344             }
345             mgr->StartAnalysis("grid");
346          } else {
347             if (!chain) {
348                ::Error("AnalysisTrainHMPID.C::StartAnalysis", "Cannot create the chain");
349                return;
350             }
351             mgr->StartAnalysis(mode, chain);
352          }
353       return;
354    }
355 }
356
357 //______________________________________________________________________________
358 void CheckModuleFlags(const char *mode) {
359 // Checks selected modules and insure compatibility
360    Int_t imode = -1;
361    if (!strcmp(mode, "LOCAL")) imode = 0;
362    if (!strcmp(mode, "PROOF")) imode = 1;
363    if (!strcmp(mode, "GRID"))  imode = 2;
364
365
366    if (kUseCPAR) {
367      kPluginAliRootVersion    = ""; // NO aliroot if we use CPAR
368    }
369
370    if (imode==1) {
371       if (!kUsePAR) {
372          ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "PAR files enabled due to PROOF analysis");
373          kUsePAR = kTRUE;
374       }   
375    }  
376    if (imode != 2) {
377       ::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "AliEn plugin disabled since not in GRID mode");
378       kPluginUse = kFALSE; 
379    }
380
381    if(!kIsMC){
382      // switch off anthin related to MC
383      kUseMC = 0;
384      kUseTR = kFALSE;
385    }
386
387  // ESD analysis
388    if (!kUseMC){
389      kUseTR = kFALSE;
390      if(kUseKinefilter)::Info("AnalysisTrainHMPID.C::CheckModuleFlags", "Kine Filter disabled in analysis without MC");
391      kUseKinefilter = kFALSE;
392    }
393    if (iJETAN){
394      iESDfilter=1;
395    }
396    if (!iESDfilter){
397      kUseKinefilter = kFALSE;
398      kUseMuonfilter = kFALSE;
399    }
400
401    iJETANLib = iJETAN && 1;
402    if (iESDfilter) {iAODhandler=1;}
403    if (kUseKinefilter && !kUseMC) kUseKinefilter = kFALSE;
404    
405 }
406
407
408 //______________________________________________________________________________
409 Bool_t Connect(const char *mode) {
410 // Connect <username> to the back-end system.
411    Int_t imode = -1;
412    if (!strcmp(mode, "LOCAL")) imode = 0;
413    if (!strcmp(mode, "PROOF")) imode = 1;
414    if (!strcmp(mode, "GRID"))  imode = 2;
415    TString username = gSystem->Getenv("alien_API_USER");
416    switch (imode) {
417      case 0:
418        break;
419      case 1:
420        if  (!username.Length()) {
421          ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Make sure you:\n \
422                         1. Have called: alien-token-init <username>\n \
423                         2. Have called: >source /tmp/gclient_env_$UID");
424          return kFALSE;
425        }
426        ::Info("AnalysisTrainHMPID.C::Connect", "Connecting user <%s> to PROOF cluster <%s>", 
427                 username.Data(), kProofCluster.Data());
428        gEnv->SetValue("XSec.GSI.DelegProxy", "2");
429        TProof::Open(Form("%s@%s", username.Data(), kProofCluster.Data()));       
430        if (!gProof) {
431          if (strcmp(gSystem->Getenv("XrdSecGSISRVNAMES"), "lxfsrd0506.cern.ch"))
432            ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Environment XrdSecGSISRVNAMES different from lxfsrd0506.cern.ch");
433            return kFALSE;
434          }
435        if(kProofClearPackages)gProof->ClearPackages();
436        break;
437      case 2:      
438        if  (!username.Length()) {
439          ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), "Make sure you:\n \
440                         1. Have called: alien-token-init <username>\n \
441                         2. Have called: >source /tmp/gclient_env_$UID");
442          return kFALSE;
443        }
444        if (kPluginUse && !gSystem->Getenv("alien_CLOSE_SE")) {
445          ::Error(Form("AnalysisTrainHMPID.C::Connect <%s>", mode), 
446                         "When using the AliEn plugin it is preferable to define the \
447                         variable alien_CLOSE_SE in your environment.");
448          return kFALSE;
449        }
450        ::Info("AnalysisTrainHMPID.C::Connect", "Connecting user <%s> to AliEn ...", 
451                 username.Data());
452        TGrid::Connect("alien://");
453        if (!gGrid || !gGrid->IsConnected()) return kFALSE;
454        break;
455      default:
456        ::Error("AnalysisTrainHMPID.C::Connect", "Unknown run mode: %s", mode);
457        return kFALSE;
458    }
459    ::Info("AnalysisTrainHMPID.C::Connect","Connected in %s mode", mode);
460    return kTRUE;
461 }
462
463
464 //______________________________________________________________________________
465 Bool_t LoadCommonLibraries(const char *mode)
466 {
467 // Load common analysis libraries.
468    Int_t imode = -1;
469    if (!strcmp(mode, "LOCAL")) imode = 0;
470    if (!strcmp(mode, "PROOF")) imode = 1;
471    if (!strcmp(mode, "GRID"))  imode = 2;
472    if (!gSystem->Getenv("ALICE_ROOT")) {
473       ::Error("AnalysisTrainHMPID.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot"); 
474       return kFALSE;
475    }   
476    Bool_t success = kTRUE;
477    // ROOT libraries
478    gSystem->Load("libTree");
479    gSystem->Load("libGeom");
480    gSystem->Load("libVMC");
481    gSystem->Load("libPhysics");
482    
483    // Load framework classes. Par option ignored here.
484    switch (imode) {
485       case 0:
486       case 2:
487          if (kUseCPAR) {
488             success &= LoadLibrary("STEERBase", mode, kTRUE);
489             success &= LoadLibrary("ESD", mode, kTRUE);
490             success &= LoadLibrary("AOD", mode, kTRUE);
491             success &= LoadLibrary("ANALYSIS", mode, kTRUE);
492             success &= LoadLibrary("ANALYSISalice", mode, kTRUE);
493             success &= LoadLibrary("CORRFW", mode, kTRUE);
494          } else {   
495             success &= LoadLibrary("libSTEERBase.so", mode);
496             success &= LoadLibrary("libESD.so", mode);
497             success &= LoadLibrary("libAOD.so", mode);
498             success &= LoadLibrary("libANALYSIS.so", mode);
499             success &= LoadLibrary("libANALYSISalice.so", mode);
500             success &= LoadLibrary("libCORRFW.so", mode);
501             gROOT->ProcessLine(".include $ALICE_ROOT/include");
502          }   
503          break;
504       case 1:
505          if (!kProofUseAFPAR) {
506             success &= LoadLibrary("STEERBase", mode);
507             success &= LoadLibrary("ESD", mode);
508             success &= LoadLibrary("AOD", mode);
509             success &= LoadLibrary("ANALYSIS", mode);
510             success &= LoadLibrary("ANALYSISalice", mode);
511             success &= LoadLibrary("CORRFW", mode);
512          } else { 
513             success &= !gProof->EnablePackage(kProofAFversion);
514             success &= LoadLibrary("CORRFW", mode);
515          }
516          break;         
517       default:
518          ::Error("AnalysisTrainHMPID.C::LoadCommonLibraries", "Unknown run mode: %s", mode);
519          return kFALSE;
520    }
521    if (success) {
522       ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Load common libraries:    SUCCESS");
523       ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
524               gSystem->GetIncludePath());
525    } else {           
526       ::Info("AnalysisTrainHMPID.C::LoadCommodLibraries", "Load common libraries:    FAILED");
527    }   
528       
529    return success;
530 }
531
532
533 //______________________________________________________________________________
534 Bool_t LoadAnalysisLibraries(const char *mode)
535 {
536 // Load common analysis libraries.
537    Bool_t success = kTRUE;
538    if (iESDfilter) {
539       if (!LoadLibrary("PWG3base", mode, kTRUE) ||
540           !LoadLibrary("PWG3muon", mode, kTRUE)) return kFALSE;
541    }   
542
543    if(iHMPID){
544      if (!LoadSource(Form("%s/AliHMPIDAnalysisTask.cxx",gSystem->ExpandPathName(".")), mode, kTRUE))return kFALSE;
545    }
546
547    if (iJETANLib) {
548      if (!LoadLibrary("JETAN", mode, kTRUE)) return kFALSE;
549    }
550
551    ::Info("AnalysisTrainHMPID.C::LoadAnalysisLibraries", "Load other libraries:   SUCCESS");
552    return kTRUE;
553 }
554
555
556 //______________________________________________________________________________
557 Bool_t LoadLibrary(const char *module, const char *mode, Bool_t rec=kFALSE)
558 {
559 // Load a module library in a given mode. Reports success.
560    Int_t imode = -1;
561    Int_t result;
562    TString smodule(module);
563    if (!strcmp(mode, "LOCAL")) imode = 0;
564    if (!strcmp(mode, "PROOF")) imode = 1;
565    if (!strcmp(mode, "GRID"))  imode = 2;
566    TString mod(module);
567    if (!mod.Length()) {
568       ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Empty module name");
569       return kFALSE;
570    }   
571    // If a library is specified, just load it
572    if (smodule.EndsWith(".so")) {
573       mod.Remove(mod.Index(".so"));
574       result = gSystem->Load(mod);
575       if (result < 0) {
576          ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not load library %s", module);
577          return kFALSE;
578       }
579       if (rec) anaLibs += Form("%s.so ",mod.Data()); 
580       if (rec) anaLibsExtra += Form("%s.so ",mod.Data()); 
581       return kTRUE;
582    } 
583    // Check if the library is already loaded
584    if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0)
585       return kTRUE;    
586    switch (imode) {
587       case 0:
588       case 2:
589          if (kUsePAR) {
590             result = SetupPar(module);
591             if (rec) anaPars += Form("%s.par ", module);
592          } else {
593             result = gSystem->Load(Form("lib%s", module));
594             if (rec) anaLibs += Form("lib%s.so ", module);
595          }   
596          break;
597       case 1:
598              if(!gSystem->AccessPathName(module)){
599                ::Info("AnalysisTrainHMPID.C::LoadLibrary", "Removing directory %s",module);
600                gSystem->Exec(Form("rm -rf %s",module));
601          }
602          result = gProof->UploadPackage(module);
603          if (result<0) {
604             result = gProof->UploadPackage(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", module)));
605             if (result<0) {
606                ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not find module %s.par in current directory nor in $ALICE_ROOT", module);
607                return kFALSE;
608             }
609          }   
610          result = gProof->EnablePackage(module);
611          break;
612       default:
613          return kFALSE;
614    }         
615    if (result < 0) {
616       ::Error("AnalysisTrainHMPID.C::LoadLibrary", "Could not load module %s", module);
617       return kFALSE;
618    }
619    return kTRUE;
620 }           
621
622 //______________________________________________________________________________
623 Bool_t LoadSource(const char *source, const char *mode, Bool_t rec=kFALSE)
624 {
625 // Load a module library in a given mode. Reports success.
626    Int_t imode = -1;
627    Int_t result = -1;
628    if (!strcmp(mode, "LOCAL")) imode = 0;
629    if (!strcmp(mode, "PROOF")) imode = 1;
630    if (!strcmp(mode, "GRID"))  imode = 2;
631    TString ssource(source);
632    TString basename = gSystem->BaseName(ssource.Data());
633    if (!ssource.Length()) {
634       ::Error("AnalysisTrainHMPID.C::LoadSource", "Empty task name");
635       return kFALSE;
636    }
637    // we have a source code so compile it
638    if (ssource.EndsWith(".cxx")) {
639      // need to copy it here other wise the path is also used on grid...
640      ssource.Remove(ssource.Index(".cxx"));
641      basename.Remove(basename.Index(".cxx"));
642      Printf("LoadSources:: Copying...  path %s{cxx,h}",ssource.Data());
643      gSystem->Exec(Form("cp %s.cxx . ",ssource.Data()));
644      gSystem->Exec(Form("cp %s.h . ",ssource.Data()));
645      // Path to code
646      // only needed for local compilation, in grid and proof mode 
647      // the task headers are uploaded 
648      //     path.Remove(path.Index(gSystem->BaseName(path.Data())));
649      // Printf("LoadSources:: Including path %s",path.Data());
650      //  if(path.Length()>0)gROOT->ProcessLine(Form(".include %s",path.Data()));
651      Printf("LoadSources:: Loading...  path %s",basename.Data());
652      switch (imode) {
653      case 0:
654        result = gROOT->LoadMacro(Form("%s.cxx++g",basename.Data()));
655        break;
656      case 1:
657        result = gProof->Load(Form("%s.cxx++g",basename.Data()));
658        break;
659      case 2:
660        result = gROOT->LoadMacro(Form("%s.cxx++g",basename.Data()));
661        if (rec){
662        // what we want to compile
663          anaSources += Form("%s.cxx ",basename.Data());
664        // what we need as input...
665          anaLibs += Form("%s.cxx %s.h ",basename.Data(),basename.Data());
666        }
667        break;
668      default:
669        return kFALSE;
670      }
671    }
672    if (result < 0) {
673       ::Error("AnalysisTrainHMPID.C::LoadSources", "Could not load source %s", source);
674       return kFALSE;
675    }
676    return kTRUE;
677 }
678
679 //______________________________________________________________________________
680 TChain *CreateChain(const char *mode, const char *plugin_mode)
681 {
682 // Create the input chain
683    Int_t imode = -1;
684    if (!strcmp(mode, "LOCAL")) imode = 0;
685    if (!strcmp(mode, "PROOF")) imode = 1;
686    if (!strcmp(mode, "GRID"))  imode = 2;
687    TChain *chain = NULL;
688    // Local chain
689    switch (imode) {
690       case 0:
691              if (!kLocalXMLDataset.Length()) {
692                // Local ESD
693                chain = new TChain("esdTree");
694                TString line;
695                ifstream in;
696                in.open(kLocalDataList.Data());
697                while (in.good()) {
698                  in >> line;
699                  if (line.Length() == 0) continue;
700                  cout << " line = " << line << endl;
701                  chain->Add(line.Data());
702                }       
703              } else {
704                // Interactive ESD
705            chain = CreateChainSingle(kLocalXMLDataset, "esdTree");
706              }   
707          break;
708       case 1:
709          break;
710       case 2:
711          if (kPluginUse) {
712             AliAnalysisGrid *alienHandler = CreateAlienHandler(plugin_mode);
713             AliAnalysisManager::GetAnalysisManager()->SetGridHandler(alienHandler);
714          } else {
715             TString treeName = "esdTree";
716             chain = CreateChainSingle("wn.xml", treeName);
717          }
718          break;      
719       default:   
720    }
721    if (chain && chain->GetNtrees()) return chain;
722    return NULL;
723 }   
724
725 //______________________________________________________________________________
726 TChain* CreateChainSingle(const char* xmlfile, const char *treeName)
727 {
728    printf("*******************************\n");
729    printf("*** Getting the ESD Chain   ***\n");
730    printf("*******************************\n");
731    TAlienCollection * myCollection  = TAlienCollection::Open(xmlfile);
732
733    if (!myCollection) {
734       ::Error("AnalysisTrainHMPID.C::CreateChainSingle", "Cannot create an AliEn collection from %s", xmlfile) ;
735       return NULL ;
736    }
737
738    TChain* chain = new TChain(treeName);
739    myCollection->Reset() ;
740    while ( myCollection->Next() ) chain->Add(myCollection->GetTURL("")) ;
741    chain->ls();
742    return chain;
743 }
744
745 //______________________________________________________________________________
746 Int_t SetupPar(char* pararchivename)
747 {
748    if (!pararchivename || !strlen(pararchivename)) return -1;
749    char processline[1024];
750    if (gSystem->AccessPathName(Form("%s.par", pararchivename))) {
751       if (!gSystem->AccessPathName(Form("%s/%s.par", gSystem->Getenv("ALICE_ROOT"),pararchivename))) {
752          ::Info("AnalysisTrainHMPID.C::SetupPar", "Getting %s.par from $ALICE_ROOT", pararchivename);
753          TFile::Cp(gSystem->ExpandPathName(Form("$ALICE_ROOT/%s.par", pararchivename)), 
754                    Form("%s.par",pararchivename));
755       } else {
756          ::Error("AnalysisTrainHMPID.C::SetupPar", "Cannot find %s.par", pararchivename);
757          return -1;
758       }   
759    }
760    gSystem->Exec(Form("tar xvzf %s.par", pararchivename));
761
762    TString ocwd = gSystem->WorkingDirectory();
763    if (!gSystem->ChangeDirectory(pararchivename)) return -1;
764         
765    // check for BUILD.sh and execute
766    if (!gSystem->AccessPathName("PROOF-INF/BUILD.sh")) {
767       printf("*******************************\n");
768       printf("*** Building PAR archive    ***\n");
769       printf("*******************************\n");          
770       if (gSystem->Exec("PROOF-INF/BUILD.sh")) {
771          Error("runProcess","Cannot Build the PAR Archive! - Abort!");
772          return -1;
773       }
774    }
775
776         // check for SETUP.C and execute
777         if (!gSystem->AccessPathName("PROOF-INF/SETUP.C")) {
778             printf("*******************************\n");
779             printf("*** Setup PAR archive       ***\n");
780             printf("*******************************\n");
781             gROOT->Macro("PROOF-INF/SETUP.C");
782         }       
783         if (!gSystem->ChangeDirectory(ocwd.Data())) return -1;
784    return 0;
785 }
786
787 //______________________________________________________________________________
788 AliAnalysisAlien* CreateAlienHandler(const char *plugin_mode)
789 {
790 // Check if user has a valid token, otherwise make one. This has limitations.
791 // One can always follow the standard procedure of calling alien-token-init then
792 //   source /tmp/gclient_env_$UID in the current shell.
793    if (!AliAnalysisGrid::CreateToken()) return NULL;
794    AliAnalysisAlien *plugin = new AliAnalysisAlien();
795 // Set the run mode (can be "full", "test", "offline", "submit" or "terminate")
796    plugin->SetRunMode(plugin_mode);
797    if (kPluginUseProductionMode) plugin->SetProductionMode();
798    plugin->SetJobTag(kJobTag);
799    plugin->SetNtestFiles(1);
800 //   plugin->SetPreferedSE("ALICE::NIHAM::File");
801 // Set versions of used packages
802    plugin->SetAPIVersion("V1.1x");
803    plugin->SetROOTVersion(kPluginRootVersion);
804    plugin->SetAliROOTVersion(kPluginAliRootVersion);
805
806 // Declare input data to be processed.
807 // Method 1: Create automatically XML collections using alien 'find' command.
808 // Define production directory LFN
809    plugin->SetGridDataDir(kGridDatadir.Data());
810 // Set data search pattern
811    plugin->SetDataPattern(Form(" %s/*/*ESDs.root",kGridPassPattern.Data()));
812 // ...then add run numbers to be considered
813    plugin->SetRunPrefix("000");
814    plugin->SetRunRange(kGridRunRange[0], kGridRunRange[1]);
815
816    if(kGridLocalRunList.Length()>0){
817      ifstream in1;
818      in1.open(kGridLocalRunList.Data());
819      int iRun;
820      // just use run numbers, negatives will be excluded
821      while(in1>>iRun){
822        if(iRun>0){
823        Printf("AnalysisTrainHMPID Adding run number from File %s", Form(kGridRunPattern.Data(),iRun));
824        plugin->AddRunNumber(Form(kGridRunPattern.Data(),iRun));
825        } else{
826          Printf("AnalysisTrainHMPID Skipping run number from File %d", iRun);
827        }
828      }
829    }
830
831 // Method 2: Declare existing data files (raw collections, xml collections, root file)
832 // If no path mentioned data is supposed to be in the work directory (see SetGridWorkingDir())
833 // XML collections added via this method can be combined with the first method if
834 // the content is compatible (using or not tags)
835 //   plugin->AddDataFile("137431.xml");
836 //   plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");
837 // Define alien work directory where all files will be copied. Relative to alien $HOME.
838    TString alien_workdir = "";
839
840    alien_workdir += kGridWorkDir.Data();
841    if(kGridDataSet.Length()>0)alien_workdir += Form("/%s",kGridDataSet.Data());
842    plugin->SetGridWorkingDir(alien_workdir.Data());
843
844    // Declare alien output directory. Relative to working directory.
845    if (!kGridOutdir.Length()) kGridOutdir = Form("output_%s",kTrainName.Data());
846    plugin->SetGridOutputDir(kGridOutdir);
847
848    // set extra libs before par file compilation
849    anaLibs += kGridExtraFiles;
850    anaLibs  = anaLibs.Strip();   
851    Printf("anaLibs %s",anaLibs.Data());
852    Printf("anaLibsExtra %s",anaLibsExtra.Data());
853
854    if (anaLibs.Length())          plugin->SetAdditionalLibs(anaLibs.Data());
855    if (anaLibsExtra.Length())     plugin->SetAdditionalRootLibs(anaLibsExtra.Data());
856
857    TString ana_sources = "";
858    TString ana_add = "";
859    if (kUsePAR && anaPars.Length()) {
860       printf("%s\n", anaPars.Data());
861       TObjArray *arr;
862       TObjString *objstr;
863       arr = anaPars.Tokenize(" ");
864       TIter next(arr);
865       while ((objstr=(TObjString*)next())) plugin->EnablePackage(objstr->GetString());
866       delete arr;
867    } 
868    
869 // Declare the analysis source files names separated by blancs. To be compiled runtime
870 // using ACLiC on the worker nodes.
871    ana_sources = anaSources.Strip();
872 // Declare all libraries (other than the default ones for the framework. These will be
873 // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
874
875    if (ana_sources.Length()) plugin->SetAnalysisSource(ana_sources);
876    plugin->SetExecutableCommand(kPluginExecutableCommand.Data());
877    // Declare the output file names separated by blancs.
878    // (can be like: file.root or file.root@ALICE::Niham::File)
879    plugin->SetUseSubmitPolicy(kFALSE);
880    plugin->SetMergeExcludes(kGridMergeExclude);
881    plugin->SetMaxMergeFiles(kGridMaxMergeFiles);
882    plugin->SetNrunsPerMaster(kGridRunsPerMaster);
883    plugin->SetMergeViaJDL(kPluginMergeViaJDL);
884    // Use fastread option
885    plugin->SetFastReadOption(kPluginFastReadOption);
886    // UseOverwrite mode
887    plugin->SetOverwriteMode(kPluginOverwriteMode);
888    // Optionally define the files to be archived.
889    //   plugin->SetOutputArchive("log_archive.zip:stdout,stderr@ALICE::NIHAM::File root_archive.zip:AliAOD.root,AOD.tag.root@ALICE::NIHAM::File");
890    plugin->SetOutputToRunNo(kPluginOutputToRunNumber);     // write the output to subdirs named after run number
891 //   plugin->SetDefaultOutputs(kFALSE);
892
893    // Put default output files to archive
894    TString listhists = "";
895    TString listaods  = "";
896    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
897    TIter next(mgr->GetOutputs());
898    AliAnalysisDataContainer *output;
899    while ((output=(AliAnalysisDataContainer*)next())) {
900       const char *filename = output->GetFileName();
901       if (!(strcmp(filename, "default"))) {
902          if (!mgr->GetOutputEventHandler()) continue;
903          filename = mgr->GetOutputEventHandler()->GetOutputFileName();
904          if (listaods.Length()) listaods += " ";
905          listaods += filename;
906       } else {
907          if(!listhists.Contains(filename)){
908             if (listhists.Length()) listhists += " ";
909             listhists += filename;
910          }
911       }
912    }
913
914    if (mgr->GetExtraFiles().Length()) {
915      if (listaods.Length()) listaods += " ";
916      listaods += mgr->GetExtraFiles();
917    }
918
919    TString outputArchive;
920    outputArchive = Form("log_archive.zip:std*r@%s",kGridOutputStorages.Data());
921    listaods.ReplaceAll(" ", ",");
922    listhists.ReplaceAll(" ", ",");
923    if (listhists.Length()) listhists = Form("hist_archive.zip:%s@%s", listhists.Data(), kGridOutputStorages.Data());
924    if (listaods.Length())  listaods  = Form("aod_archive.zip:%s@%s", listaods.Data(), kGridOutputStorages.Data());
925
926    if (!listhists.Length() && !listaods.Length()) {
927       ::Fatal("AnalysisTrainHMPID", "No task output !");
928    }
929
930    if (listaods.Length()) {
931       outputArchive += " ";
932       outputArchive += listaods;
933    }
934    if (listhists.Length()) {
935       outputArchive += " ";
936       outputArchive += listhists;
937    }
938 //   plugin->SetOutputArchive(outputArchive);
939
940 // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
941    plugin->SetAnalysisMacro(Form("%s.C", kTrainName.Data()));
942 // Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
943    plugin->SetSplitMaxInputFileNumber(kGridFilesPerJob);
944 // Optionally set number of failed jobs that will trigger killing waiting sub-jobs.
945 //   plugin->SetMaxInitFailed(5);
946 // Optionally resubmit threshold.
947 //   plugin->SetMasterResubmitThreshold(90);
948 // Optionally set time to live (default 30000 sec)
949    plugin->SetTTL(30000);
950 // Optionally set input format (default xml-single)
951    plugin->SetInputFormat("xml-single");
952 // Optionally modify the name of the generated JDL (default analysis.jdl)
953    plugin->SetJDLName(Form("%s.jdl", kTrainName.Data()));
954 // Optionally modify the executable name (default analysis.sh)
955    plugin->SetExecutable(Form("%s.sh", kTrainName.Data()));
956 // Optionally modify job price (default 1)
957    plugin->SetPrice(1);      
958 // Optionally modify split mode (default 'se')    
959    plugin->SetSplitMode("se");
960    plugin->SetCheckCopy(kFALSE);
961    return plugin;
962 }
963
964 //______________________________________________________________________________
965 Bool_t LoadConfig(const char *filename)
966 {
967 // Read train configuration from file
968    if (gSystem->AccessPathName(filename)) {
969       ::Error("AnalysisTrainHMPID.C::LoadConfig", "Config file name not found");
970       return kFALSE;
971    }   
972    gROOT->ProcessLine(Form(".x %s", filename));
973    ::Info("AnalysisTrainHMPID.C::LoadConfig", "Train configuration loaded from file %s", filename);
974    return kTRUE;
975 }
976
977 //______________________________________________________________________________
978 Bool_t PatchJDL(){
979   Printf(">>> Patching JDL");
980   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
981   AliAnalysisAlien*    gridHandler = (AliAnalysisAlien*)mgr->GetGridHandler();
982   TGridJDL *jdl = gridHandler->GetGridJDL();
983   if(iJETAN)jdl->AddToPackages("fastjet","v2.4.0");
984   gridHandler->WriteJDL(kFALSE);
985   Printf("<<<  Patching JDL");
986   return kTRUE;
987 }
988
989 //______________________________________________________________________________
990 Bool_t PatchAnalysisMacro(){
991   Printf(">>> Patching AnalysisMacro");
992   gSystem->Exec(Form("mv %s.C %s.C_tmp",kTrainName.Data(),kTrainName.Data()));
993
994   ifstream in1; 
995   in1.open(Form("%s.C_tmp", kTrainName.Data()));
996   char cLine[250];
997   TString st;
998   while(in1.getline(cLine,250)){
999     st += cLine;
1000     st += "\n";
1001   }
1002   Int_t index= -1;
1003   index = st.Index("gSystem->Load(\"libPhysics\");");
1004   index += strlen("gSystem->Load(\"libPhysics\");");
1005   /*
1006     TObjArray *arr;
1007     TObjString *objstr;
1008     arr = anaLibs.Tokenize(" ");
1009     TIter next(arr);
1010
1011     add += "\n\n // added by CKB \n";
1012     while ((objstr=(TObjString*)next())){
1013       if(objstr->GetString().Contains("PWG3"))continue;
1014       if(objstr->GetString().EndsWith(".so"))add += Form("gSystem->Load(\"%s\");\n",objstr->GetString().Data());
1015     }
1016     delete arr; 
1017     */
1018     //    add += Form("AliLog::SetGlobalLogLevel(%d);\n",AliLog::GetGlobalLogLevel());
1019   TString add = "";
1020
1021   if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1022   add += "\n\n // added by CKB \n";
1023   add += "\n gSystem->AddIncludePath(\"./\"); \n";
1024   if(gGrid && kPluginAliRootVersion.Length()==0){
1025     add += "\n // Dirty hack for TRD reference data \n";
1026     add += "\n gSystem->Setenv(\"ALICE_ROOT\",\"";
1027     add += Form("alien://%s/rootfiles/",gGrid->GetHomeDirectory());
1028     add += "\"); \n";
1029   }
1030   add += "// BKC \n\n";
1031   st.Insert(index,add.Data());
1032
1033   if(kUseCPAR && kPluginAliRootVersion.Length()==0){
1034     index = st.Index("gSystem->AddIncludePath(\"-I$"); // uncommen $ALICE_ROOT include for par files
1035     if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1036     st.Insert(index,"// CKB comment out whehn no aliroot is provided \n //");
1037   }
1038
1039   ofstream out;
1040   out.open(Form("%s.C", kTrainName.Data()));
1041   if (out.bad()) {
1042     return kFALSE;
1043   }
1044   out << st << endl;
1045   Printf("<<< Patching AnalysisMacro");
1046
1047   Printf(">>> Patching Merge Macro");
1048   gSystem->Exec(Form("mv %s_merge.C %s_merge.C_tmp",kTrainName.Data(),kTrainName.Data()));
1049
1050   ifstream in2; 
1051   in2.open(Form("%s_merge.C_tmp", kTrainName.Data()));
1052   TString st2;
1053   while(in2.getline(cLine,250)){
1054     st2 += cLine;
1055     st2 += "\n";
1056   }
1057   index = st2.Index("gSystem->Load(\"libPhysics\");");
1058   index += strlen("gSystem->Load(\"libPhysics\");");
1059   TString add2 = "";
1060   add2 += "\n gSystem->AddIncludePath(\"./\"); \n";
1061   if(gGrid&&kPluginAliRootVersion.Length()==0){
1062     add2 += "\n // Dirty hack for TRD reference data \n";
1063     add2 += "\n gSystem->Setenv(\"ALICE_ROOT\",\"";
1064     add2 += Form("alien://%s/rootfiles/",gGrid->GetHomeDirectory());
1065     add2 += "\"); \n";
1066   }
1067   add2 += "// BKC \n\n";
1068   if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1069   st2.Insert(index,add.Data());
1070
1071   if(kUseCPAR&&kPluginAliRootVersion.Length()==0){
1072     index = st2.Index("gSystem->AddIncludePath(\"-I$"); // uncommen $ALICE_ROOT include for par files
1073     if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1074     st2.Insert(index,"// CKB comment out whehn no aliroot is provided \n //");
1075   }
1076
1077   // do not exclude the extra files from merign, this is done explicitly in this train script
1078   index = st2.Index("mergeExcludes +="); // uncommen $ALICE_ROOT include for par files
1079   if(index<0)Printf("%s:%d index out of bounds",(char*)__FILE__,__LINE__);
1080   st2.Insert(index,"// CKB comment out, handled explicitly by the train macro \n //");
1081
1082
1083   ofstream out2;
1084   out2.open(Form("%s_merge.C", kTrainName.Data()));
1085   if (out2.bad()) {
1086     return kFALSE;
1087   }
1088   out2 << st2 << endl;
1089   Printf("<<< Patching Merging Macro");
1090
1091
1092   return kTRUE;
1093
1094 }