1ff87a785cc8db14b4b3c91dfa279af416038b45
[u/mrichter/AliRoot.git] / ANALYSIS / macros / AODtrain.C
1 // ### Settings that make sense when using the Alien plugin
2 //==============================================================================
3 Int_t       runOnData          = 1;       // Set to 1 if processing real data
4 Int_t       iCollision         = 0;       // 0=pp, 1=Pb-Pb
5 Int_t       run_flag           = 1000;    // year (2010 pp)
6 //==============================================================================
7 Bool_t      doCDBconnect        =1;
8 Bool_t      usePhysicsSelection = kTRUE; // use physics selection
9 Bool_t      useTender           = kFALSE; // use tender wagon
10 Bool_t      useCentrality       = kFALSE; // centrality
11 Bool_t      useV0tender         = kFALSE;  // use V0 correction in tender
12 Bool_t      useDBG              = kTRUE;  // activate debugging
13 Bool_t      useMC               = kFALSE;  // use MC info
14 Bool_t      useKFILTER          = kFALSE;  // use Kinematics filter
15 Bool_t      useTR               = kFALSE;  // use track references
16 Bool_t      useCORRFW           = kFALSE; // do not change
17 Bool_t      useAODTAGS          = kFALSE; // use AOD tags
18 Bool_t      useSysInfo          = kTRUE; // use sys info
19
20 // ### Analysis modules to be included. Some may not be yet fully implemented.
21 //==============================================================================
22 Int_t       iAODhandler        = 1;      // Analysis produces an AOD or dAOD's
23 Int_t       iESDfilter         = 1;      // ESD to AOD filter (barrel + muon tracks)
24 Int_t       iMUONcopyAOD       = 1;      // Task that copies only muon events in a separate AOD (PWG3)
25 Int_t       iJETAN             = 0;      // Jet analysis (PWG4)
26 Int_t       iJETANdelta        = 0;      // Jet delta AODs
27 Int_t       iPWGHFvertexing     = 1;      // Vertexing HF task (PWG3)
28 Int_t       iPWGDQJPSIfilter    = 0;      // JPSI filtering (PWG3)
29 Int_t       iPWGHFd2h           = 1;      // D0->2 hadrons (PWG3)
30 Int_t       iPWGPP               =1;      // high pt filter task
31 Int_t       iPWGLFForward       = 1;      // Forward mult task (PWGLF)
32 Bool_t doPIDResponse  = 1;
33 Bool_t doPIDqa        = 1; //new
34
35 // ### Configuration macros used for each module
36 //==============================================================================
37  TString configPWGHFd2h = (iCollision==0)?"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF.C"
38                           :"$ALICE_ROOT/PWGHF/vertexingHF/ConfigVertexingHF_highmult.C";
39                                                  
40 // Temporaries.
41 void AODmerge();
42 void AddAnalysisTasks();
43 Bool_t LoadCommonLibraries();
44 Bool_t LoadAnalysisLibraries();
45 Bool_t LoadLibrary(const char *);
46 TChain *CreateChain();
47 const char *cdbPath = "raw://";
48 Int_t run_number = 0;
49
50 //______________________________________________________________________________
51 void AODtrain(Int_t merge=0)
52 {
53 // Main analysis train macro.
54
55   if (merge || doCDBconnect) {
56     TGrid::Connect("alien://");
57     if (!gGrid || !gGrid->IsConnected()) {
58       ::Error("QAtrain", "No grid connection");
59       return;
60     }
61   }
62   // Set temporary merging directory to current one
63   gSystem->Setenv("TMPDIR", gSystem->pwd());
64   // Set temporary compilation directory to current one
65   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
66    printf("==================================================================\n");
67    printf("===========    RUNNING FILTERING TRAIN   ==========\n");
68    printf("==================================================================\n");
69    printf("=  Configuring analysis train for:                               =\n");
70    if (usePhysicsSelection)   printf("=  Physics selection                                                =\n");
71    if (useTender)    printf("=  TENDER                                                        =\n");
72    if (iESDfilter)   printf("=  ESD filter                                                    =\n");
73    if (iMUONcopyAOD) printf("=  MUON copy AOD                                                 =\n");
74    if (iJETAN)       printf("=  Jet analysis                                                  =\n");
75    if (iJETANdelta)  printf("=     Jet delta AODs                                             =\n");
76    if (iPWGHFvertexing) printf("=  PWGHF vertexing                                                =\n");
77    if (iPWGDQJPSIfilter) printf("=  PWGDQ j/psi filter                                             =\n");
78    if (iPWGHFd2h) printf("=  PWGHF D0->2 hadrons QA                                     =\n");
79
80    // Load common libraries and set include path
81    if (!LoadCommonLibraries()) {
82       ::Error("AnalysisTrain", "Could not load common libraries");
83       return;
84    }
85     
86    // Make the analysis manager and connect event handlers
87    AliAnalysisManager *mgr  = new AliAnalysisManager("Analysis Train", "Production train");
88     mgr->SetCacheSize(0);
89    if (useSysInfo) {
90  //     mgr->SetNSysInfo(100);
91       AliSysInfo::SetVerbose(kTRUE);
92    }   
93    // Load analysis specific libraries
94    if (!LoadAnalysisLibraries()) {
95       ::Error("AnalysisTrain", "Could not load analysis libraries");
96       return;
97    }   
98
99    // Create input handler (input container created automatically)
100    // ESD input handler
101    AliESDInputHandler *esdHandler = new AliESDInputHandler();
102    mgr->SetInputEventHandler(esdHandler);       
103    // Monte Carlo handler
104    if (useMC) {
105       AliMCEventHandler* mcHandler = new AliMCEventHandler();
106       mgr->SetMCtruthEventHandler(mcHandler);
107       mcHandler->SetReadTR(useTR); 
108    }   
109    // AOD output container, created automatically when setting an AOD handler
110    if (iAODhandler) {
111       // AOD output handler
112       AliAODHandler* aodHandler   = new AliAODHandler();
113       aodHandler->SetOutputFileName("AliAOD.root");
114       mgr->SetOutputEventHandler(aodHandler);
115    }
116    // Debugging if needed
117    if (useDBG) mgr->SetDebugLevel(3);
118
119    AddAnalysisTasks(cdbPath);
120    if (merge) {
121       AODmerge();
122       mgr->InitAnalysis();
123       mgr->SetGridHandler(new AliAnalysisAlien);
124       mgr->StartAnalysis("gridterminate",0);
125       return;
126    }   
127    // Run the analysis                                                                                                                     
128    //
129    TChain *chain = CreateChain();
130    if (!chain) return;
131                                                                                                                                                    
132    TStopwatch timer;
133    timer.Start();
134    mgr->SetSkipTerminate(kTRUE);
135    if (mgr->InitAnalysis()) {
136       mgr->PrintStatus();
137       mgr->StartAnalysis("local", chain);
138    }
139    timer.Print();
140 }                                                                                                                                          
141                                                                                                                                             
142 //______________________________________________________________________________                                                           
143 void AddAnalysisTasks(const char *cdb_location){                                                                                                                                          
144   // Add all analysis task wagons to the train                                                                                               
145    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();                                                                     
146
147   //
148   // Tender and supplies. Needs to be called for every event.
149   //
150    AliAnalysisManager::SetCommonFileName("AODQA.root");
151    if (useTender) {
152       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/TenderSupplies/AddTaskTender.C");
153       // IF V0 tender needed, put kTRUE below
154       AliAnalysisTaskSE *tender = AddTaskTender(useV0tender);
155 //      tender->SetDebugLevel(2);
156    }
157    
158    // Clean Geometry: Ruben
159   gROOT->LoadMacro("$ALICE_ROOT/PWGPP/CalibMacros/commonMacros/CleanGeom.C++");
160   CleanGeom* clgmTask = new CleanGeom("cleanGeom");
161   mgr->AddTask(clgmTask);
162   AliAnalysisDataContainer *dummyInp = mgr->GetCommonInputContainer();
163   if (dummyInp) mgr->ConnectInput(clgmTask,0,dummyInp);  
164  
165    
166    //
167   // PIDResponse(JENS)
168   //
169   if (doPIDResponse) {
170     gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C"); 
171     AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse();
172      PIDResponse->SetUserDataRecoPass(1);
173 //    PIDResponse->SelectCollisionCandidates(AliVEvent::kAny);
174   }  
175  
176   //
177   // PIDqa(JENS)
178   //
179   if (doPIDqa) {
180     gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDqa.C");
181     AliAnalysisTaskPIDqa *PIDQA = AddTaskPIDqa();
182     PIDQA->SelectCollisionCandidates(AliVEvent::kAny);
183   }  
184   // CDB connection
185   //
186   if (doCDBconnect && !useTender) {
187     gROOT->LoadMacro("$ALICE_ROOT/PWGPP/PilotTrain/AddTaskCDBconnect.C");
188     AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, run_number);
189     if (!taskCDB) return;
190     AliCDBManager *cdb = AliCDBManager::Instance();
191     cdb->SetDefaultStorage(cdb_location);
192 //    taskCDB->SetRunNumber(run_number);
193   }    
194  
195    if (usePhysicsSelection) {
196    // Physics selection task
197       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
198       mgr->RegisterExtraFile("event_stat.root");
199       AliPhysicsSelectionTask *physSelTask = AddTaskPhysicsSelection(useMC);
200 //      AliOADBPhysicsSelection * oadbDefaultPbPb = CreateOADBphysicsSelection();      
201 //      physSelTask->GetPhysicsSelection()->SetCustomOADBObjects(oadbDefaultPbPb,0,0);
202       mgr->AddStatisticsTask(AliVEvent::kAny);
203    }
204    
205
206 //Jacek
207    if (iPWGPP) {
208       gROOT->LoadMacro("$ALICE_ROOT/PWGPP/macros/AddTaskFilteredTree.C");
209       AddTaskFilteredTree("FilterEvents_Trees.root");
210    }   
211    
212    // Centrality (only Pb-Pb)
213    if (useCentrality) {
214       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
215       AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
216       //taskCentrality->SelectCollisionCandidates(AliVEvent::kAny);
217    }
218    
219 // --- PWGLF - Forward (cholm@nbi.dk) -----------------------------
220    if (iPWGLFForward && usePhysicsSelection) { 
221         gROOT->LoadMacro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/AddTaskForwardMult.C");
222      UShort_t pwglfForwardSys = 0; // iCollision+1; // pp:1, PbPb:2, pPb:3
223      UShort_t pwglfSNN        = 0;            // GeV, 0==unknown
224      Short_t  pwglfField      = 0;
225      AddTaskForwardMult(useMC && useTR,        // Need track-refs 
226                         pwglfForwardSys,       // Collision system
227                         pwglfSNN, 
228                         pwglfField);
229         gROOT->LoadMacro("$ALICE_ROOT/PWGLF/FORWARD/analysis2/AddTaskCentralMult.C");
230         AddTaskCentralMult(useMC, pwglfForwardSys, pwglfSNN, pwglfField);
231    }
232  
233     
234
235    if (iESDfilter) {
236       //  ESD filter task configuration.
237       gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/ESDfilter/macros/AddTaskESDFilter.C");
238       if (iMUONcopyAOD) {
239          printf("Registering delta AOD file\n");
240          mgr->RegisterExtraFile("AliAOD.Muons.root");
241           mgr->RegisterExtraFile("AliAOD.Dimuons.root");
242       }
243       AliAnalysisTaskESDfilter *taskesdfilter = 
244                  AddTaskESDFilter(useKFILTER, 
245                                   iMUONcopyAOD,         // write Muon AOD
246                                   kFALSE,               // write dimuon AOD 
247                                   kFALSE,               // usePhysicsSelection 
248                                   kFALSE,               // centrality OBSOLETE
249                                   kTRUE,                // enable TPS only tracks
250                                   kFALSE,               // disable cascades
251                                   kFALSE,               // disable kinks
252                                   run_flag);            // run flag (YY00)
253         mgr->RegisterExtraFile("AliAOD.Dimuons.root");
254    }   
255
256 // ********** PWG3 wagons ******************************************************           
257    // PWGHF vertexing
258    if (iPWGHFvertexing) {
259       gROOT->LoadMacro("$ALICE_ROOT/PWGHF/vertexingHF/macros/AddTaskVertexingHF.C");
260       if (!iPWGHFd2h) TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()), "file:ConfigVertexingHF.C");
261       AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
262       if (!taskvertexingHF) ::Warning("AnalysisTrainNew", "AliAnalysisTaskSEVertexingHF cannot run for this train conditions - EXCLUDED");
263       else mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
264       taskvertexingHF->SelectCollisionCandidates(0);
265    }   
266       
267    // PWGDQ JPSI filtering (only pp)
268    if (iPWGDQJPSIfilter && (iCollision==0)) {
269       gROOT->LoadMacro("$ALICE_ROOT/PWGDQ/dielectron/macros/AddTaskJPSIFilter.C");
270       AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
271       if (!taskJPSIfilter) ::Warning("AnalysisTrainNew", "AliAnalysisTaskDielectronFilter cannot run for this train conditions - EXCLUDED");
272       else mgr->RegisterExtraFile("AliAOD.Dielectron.root");
273       taskJPSIfilter->SelectCollisionCandidates(0);
274    }   
275
276    // PWGHF D2h
277    if (iPWGHFd2h) {   
278      gROOT->LoadMacro("$ALICE_ROOT/PWGHF/vertexingHF/AddD2HTrain.C");
279      TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()), "file:ConfigVertexingHF.C");
280      AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);                                 
281    }
282    
283    // ********** PWG4 wagons ******************************************************
284    // Jet analysis
285
286    // Configurations flags, move up?
287    TString kDeltaAODJetName = "AliAOD.Jets.root"; //
288    Bool_t  kIsPbPb = (iCollision==0)?false:true; // can be more intlligent checking the name of the data set
289    TString kDefaultJetBackgroundBranch = "";
290    TString kJetSubtractBranches = "";
291    UInt_t kHighPtFilterMask = 272;// from esd filter
292    UInt_t iPhysicsSelectionFlag = 0;
293    if (iJETAN) {
294      gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJets.C");
295      // Default jet reconstructor running on ESD's
296      AliAnalysisTaskJets *taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,0); // no background subtraction     
297      if (!taskjets) ::Fatal("AnalysisTrainNew", "AliAnalysisTaskJets cannot run for this train conditions - EXCLUDED");
298      if(kDeltaAODJetName.Length()>0) taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
299      if (iJETANdelta) {
300         //            AddTaskJetsDelta("AliAOD.Jets.root"); // need to modify this accordingly in the add task jets
301         mgr->RegisterExtraFile(kDeltaAODJetName.Data());
302         TString cTmp("");
303         if(kIsPbPb){
304           // UA1 intrinsic background subtraction
305           taskjets = AddTaskJets("AOD","UA1",0.4,kHighPtFilterMask,1.,2); // background subtraction
306           if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
307        }
308        // SICONE 
309        taskjets = AddTaskJets("AOD","SISCONE",0.4,kHighPtFilterMask,0.15,0); //no background subtration to be done later....                                                                                  
310        if(kDeltaAODJetName.Length()>0)taskjets->SetNonStdOutputFile(kDeltaAODJetName.Data());
311        cTmp = taskjets->GetNonStdBranch();
312        if(cTmp.Length()>0)kJetSubtractBranches += Form("%s ",cTmp.Data());
313          
314        // Add the clusters..
315        gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJetCluster.C");
316        AliAnalysisTaskJetCluster *taskCl = 0;
317        Float_t fCenUp = 0;
318        Float_t fCenLo = 0;
319        Float_t fTrackEtaWindow = 0.9;
320        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"KT",0.4,0,1, kDeltaAODJetName.Data(),0.15,fTrackEtaWindow,0); // this one is for the background and random jets, random cones with no skip                                                                                 
321        taskCl->SetBackgroundCalc(kTRUE);
322        taskCl->SetNRandomCones(10);
323        taskCl->SetCentralityCut(fCenLo,fCenUp);
324        taskCl->SetGhostEtamax(fTrackEtaWindow);
325        kDefaultJetBackgroundBranch = Form("%s_%s",AliAODJetEventBackground::StdBranchName(),taskCl->GetJetOutputBranch());
326
327        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.4,2,1,kDeltaAODJetName.Data(),0.15);
328        taskCl->SetCentralityCut(fCenLo,fCenUp);
329        if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
330        taskCl->SetNRandomCones(10);
331        kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
332
333        taskCl = AddTaskJetCluster("AOD","",kHighPtFilterMask,iPhysicsSelectionFlag,"ANTIKT",0.2,0,1,kDeltaAODJetName.Data(),0.15);
334        taskCl->SetCentralityCut(fCenLo,fCenUp);
335        if(kIsPbPb)taskCl->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
336        kJetSubtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
337          
338        // DO THE BACKGROUND SUBTRACTION
339        if(kIsPbPb&&kJetSubtractBranches.Length()){
340          gROOT->LoadMacro("$ALICE_ROOT/PWGJE/macros/AddTaskJetBackgroundSubtract.C");
341          AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
342          taskSubtract = AddTaskJetBackgroundSubtract(kJetSubtractBranches,1,"B0","B%d");
343          taskSubtract->SetBackgroundBranch(kDefaultJetBackgroundBranch.Data());
344          if(kDeltaAODJetName.Length()>0)taskSubtract->SetNonStdOutputFile(kDeltaAODJetName.Data());
345        }
346      } 
347    }
348 }
349 //______________________________________________________________________________
350 Bool_t LoadCommonLibraries()
351 {
352 // Load common analysis libraries.
353    if (!gSystem->Getenv("ALICE_ROOT")) {
354       ::Error("AnalysisTrainNew.C::LoadCommonLibraries", "Analysis train requires that analysis libraries are compiled with a local AliRoot"); 
355       return kFALSE;
356    }   
357    Bool_t success = kTRUE;
358    // Load framework classes. Par option ignored here.
359    success &= LoadLibrary("libSTEERBase.so");
360    success &= LoadLibrary("libESD.so");
361    success &= LoadLibrary("libAOD.so");
362    success &= LoadLibrary("libANALYSIS.so");
363    success &= LoadLibrary("libOADB.so");
364    success &= LoadLibrary("libANALYSISalice.so");
365      success &= LoadLibrary("libESDfilter.so");
366    success &= LoadLibrary("libCORRFW.so");
367    gROOT->ProcessLine(".include $ALICE_ROOT/include");
368    if (success) {
369       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    SUCCESS");
370       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Include path for Aclic compilation:\n%s",
371               gSystem->GetIncludePath());
372    } else {           
373       ::Info("AnalysisTrainNew.C::LoadCommodLibraries", "Load common libraries:    FAILED");
374    }   
375    return success;
376 }
377
378 //______________________________________________________________________________
379 Bool_t LoadAnalysisLibraries()
380 {
381 // Load common analysis libraries.
382    if (useTender || doCDBconnect) {
383       if (!LoadLibrary("TENDER") ||
384           !LoadLibrary("TENDERSupplies")) return kFALSE;
385    }       
386    // CDBconnect
387    if (doCDBconnect && !useTender) {
388       if (!LoadLibrary("PWGPP")) return kFALSE;
389    }
390           
391    if (iESDfilter || iPWGMuonTrain) {
392       if (!LoadLibrary("PWGmuon")) return kFALSE;
393    }   
394    // JETAN
395    if (iJETAN) {
396       if (!LoadLibrary("JETAN")) return kFALSE;
397    }
398    if (iJETANdelta) {
399       if (!LoadLibrary("JETAN") ||
400           !LoadLibrary("CGAL") ||
401           !LoadLibrary("fastjet") ||
402           !LoadLibrary("siscone") ||
403           !LoadLibrary("SISConePlugin") ||
404           !LoadLibrary("FASTJETAN")) return kFALSE;
405    }  
406    // PWG2 FORWARD
407    if (iPWGLFForward) {
408       //if (!LoadLibrary("PWGLFforward", mode, kTRUE)) return kFALSE;
409      if (!LoadLibrary("PWGLFforward2")) return kFALSE;
410   }   
411    
412    // PWG3 Vertexing HF
413    if (iPWGHFvertexing || iPWGHFd2h) {
414       if (!LoadLibrary("PWGflowBase") ||
415           !LoadLibrary("PWGflowTasks") ||
416           !LoadLibrary("PWGTRD") ||
417           !LoadLibrary("PWGHFvertexingHF")) return kFALSE;
418    }    
419  //    if (iPWGHFvertexing || iPWG3d2h) {
420  //     if (!LoadLibrary("PWG3base") ||
421  //         !LoadLibrary("PWGHFvertexingHF")) return kFALSE;
422  //  }   
423    // PWG3 dielectron
424    if (iPWGDQJPSIfilter) {
425       if (!LoadLibrary("PWGDQdielectron")) return kFALSE;
426    }   
427    
428    ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", "Load other libraries:   SUCCESS");
429    return kTRUE;
430 }
431
432 //______________________________________________________________________________
433 Bool_t LoadLibrary(const char *module)
434 {
435 // Load a module library in a given mode. Reports success.
436    Int_t result;
437    TString mod(module);
438    if (!mod.Length()) {
439       ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
440       return kFALSE;
441    }   
442    // If a library is specified, just load it
443    if (mod.EndsWith(".so")) {
444       mod.Remove(mod.Index(".so"));
445       result = gSystem->Load(mod);
446       if (result < 0) {
447          ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load library %s", module);
448          return kFALSE;
449       }
450       return kTRUE;
451    } 
452    // Check if the library is already loaded
453    if (strlen(gSystem->GetLibraries(Form("%s.so", module), "", kFALSE)) > 0) return kTRUE;    
454    result = gSystem->Load(Form("lib%s.so", module));
455    if (result < 0) {
456       ::Error("AnalysisTrainNew.C::LoadLibrary", "Could not load module %s", module);
457       return kFALSE;
458    }
459    return kTRUE;
460 }           
461
462
463 //______________________________________________________________________________
464 TChain *CreateChain()
465 {
466 // Create the input chain
467    chain = new TChain("esdTree");
468    if (gSystem->AccessPathName("AliESDs.root")) 
469       ::Error("AnalysisTrainNew.C::CreateChain", "File: AliESDs.root not in ./data dir");
470    else 
471        chain->Add("AliESDs.root");
472    if (chain->GetNtrees()) return chain;
473    return NULL;
474 }   
475
476 //______________________________________________________________________________
477 void AODmerge()
478 {
479 // Merging method. No staging and no terminate phase.
480   TStopwatch timer;
481   timer.Start();
482   TString outputDir = "wn.xml";
483   TString outputFiles = "EventStat_temp.root,AODQA.root,AliAOD.root,AliAOD.VertexingHF.root,FilterEvents_Trees.root,AliAOD.Muons.root,AliAOD.Jets.root";
484   TString mergeExcludes = "";
485   TObjArray *list = outputFiles.Tokenize(",");
486   TIter *iter = new TIter(list);
487   TObjString *str;
488   TString outputFile;
489   Bool_t merged = kTRUE;
490   while((str=(TObjString*)iter->Next())) {
491     outputFile = str->GetString();
492     // Skip already merged outputs
493     if (!gSystem->AccessPathName(outputFile)) {
494        printf("Output file <%s> found. Not merging again.",outputFile.Data());
495        continue;
496     }
497     if (mergeExcludes.Contains(outputFile.Data())) continue;
498     merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 10, 0);
499     if (!merged) {
500        printf("ERROR: Cannot merge %s\n", outputFile.Data());
501        continue;
502     }
503   }
504   // all outputs merged, validate
505   ofstream out;
506   out.open("outputs_valid", ios::out);
507   out.close();
508   timer.Print();
509 }