a76500a983a05eb037b2a4bf166a117137452217
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / sim / AOD.C
1 /**
2  * @file   AOD.C
3  * @author Christian Holm Christensen <cholm@nbi.dk>
4  * @date   Wed Sep 24 15:02:00 2014
5  * 
6  * @brief  Master script for AOD production.
7  * 
8  * @note Do not modify this script. 
9  *
10  * This script reads in 4 other scripts 
11  *
12  * - GRP.C to load the global run parameters for the selected run,
13  *   such as collision system, energy, etc.
14  * 
15  * - AODConfig.C which defines a number of functions that return
16  *   either true or false.  The tasks added depends on these functions
17  *
18  * - BaseConfig.C which defines some base classes 
19  * 
20  * - DetConfig.C which defines which detectors are active and on. 
21  *
22  * Users can customize QAConfig.C and DetConfig.C according to their
23  * needs
24  */
25 /** Path to CDB */
26 const char *cdbPath = "raw://";
27 Bool_t cholm = false;
28 /**
29  * Interface (pure virtual) that all configuration classes must
30  * implement.
31  */
32 struct VirtualAODCfg
33 {
34   /** 
35    * @{ 
36    * @name Plug-in settings 
37    * Settings that make sense when using the Alien plugin
38    */
39   /** @return Connect to CDB */
40   virtual Bool_t UseCDBconnect() const = 0;
41   /** @return use physics selection */
42   virtual Bool_t UsePhysicsSelection() const = 0;
43   /** @return use tender wagon */
44   virtual Bool_t UseTender() const = 0;
45   /** @return centrality */
46   virtual Bool_t UseCentrality() const = 0;
47   /** @return use V0 correction in tender */
48   virtual Bool_t UseV0tender() const = 0;
49   /** @return activate debugging */
50   virtual Bool_t UseDBG() const = 0;
51   /** @return use MC info */
52   virtual Bool_t UseMC() const = 0;
53   /** @return use Kinematics filter */
54   virtual Bool_t UseKFILTER() const = 0;
55   /** @return use track references */
56   virtual Bool_t UseTR() const = 0;
57   /** @return do not change */
58   virtual Bool_t UseCORRFW() const = 0;
59   /** @return use AOD tags */
60   virtual Bool_t UseAODTAGS() const = 0;
61   /** @return use sys info */
62   virtual Bool_t UseSysInfo() const = 0;
63   /* @} */
64   
65   /** 
66    * @{ 
67    * @name Modules 
68    *  Analysis modules to be included. Some may not be yet fully implemented.
69    */
70   /** @return Analysis produces an AOD or dAOD's */
71   virtual Bool_t UseAODhandler() const = 0;
72   /** @return ESD to AOD filter (barrel + muon tracks) */
73   virtual Bool_t UseESDfilter() const = 0;
74   /** @return Use Muon train  */
75   virtual Bool_t UsePWGMuonTrain() const = 0;
76   /** @return Task that copies only muon events */
77   virtual Bool_t UseMUONcopyAOD() const = 0;
78   /** @return Jet analysis (PWG4) */
79   virtual Bool_t UseJETAN() const = 0;
80   /** @return Jet delta AODs */
81   virtual Bool_t UseJETANdelta() const = 0;
82   /** @return Vertexing HF task (PWG3) */
83   virtual Bool_t UsePWGHFvertexing() const = 0;
84   /** @return JPSI filtering (PWG3) */
85   virtual Bool_t UsePWGDQJPSIfilter() const = 0;
86   /** @return D0->2 hadrons (PWG3) */
87   virtual Bool_t UsePWGHFd2h() const = 0;
88   /** @return PID response */
89   virtual Bool_t UsePIDResponse() const = 0;
90   /** @return Forward mult task (PWGLF) */
91   virtual Bool_t UsePWGLFForward() const = 0;
92   /* @} */
93   /** 
94    * Print one flag
95    * 
96    * @param title Title
97    * @param use   Use or not 
98    */
99   virtual void PrintOne(const char* title, Bool_t use) const
100   {
101     Printf("%-30s : %3s", title, use ? "yes" : "no");
102   }
103   /** 
104    * Print settings
105    * 
106    */
107   virtual void Print() const { 
108     PrintOne("Connect to CDB",                  UseCDBconnect());
109     PrintOne("Use physics selection",           UsePhysicsSelection());
110     PrintOne("Use tender wagon",                UseTender());
111     PrintOne("Use centrality",                  UseCentrality());
112     PrintOne("Use V0 correction in tender",     UseV0tender());
113     PrintOne("Activate debugging",              UseDBG());
114     PrintOne("Use MC info",                     UseMC());
115     PrintOne("Use Kinematics filter",           UseKFILTER());
116     PrintOne("Use track references",            UseTR());
117     PrintOne("Use correction framework",        UseCORRFW());
118     PrintOne("Use AOD tags",                    UseAODTAGS());
119     PrintOne("Use sys info",                    UseSysInfo());
120     PrintOne("Produces an AOD or dAOD's",       UseAODhandler());
121     PrintOne("ESD to AOD filter",               UseESDfilter());
122     PrintOne("Use Muon train ",                 UsePWGMuonTrain());
123     PrintOne("Copy muon events",                UseMUONcopyAOD());
124     PrintOne("Jet analysis (PWG4)",             UseJETAN());
125     PrintOne("Jet delta AODs",                  UseJETANdelta());
126     PrintOne("Vertexing HF task (PWG3)",        UsePWGHFvertexing());
127     PrintOne("JPSI filtering (PWG3)",           UsePWGDQJPSIfilter());
128     PrintOne("D0->2 hadrons (PWG3)",            UsePWGHFd2h());
129     PrintOne("PID response",                    UsePIDResponse());
130     PrintOne("Forward mult task (PWGLF)",       UsePWGLFForward());
131   }
132 };
133
134 VirtualAODCfg* aodCfg = 0;
135
136 //====================================================================
137 /** 
138  * Load a library/module 
139  * 
140  * @param module Library/module name 
141  * 
142  * @return true on success
143  */
144 Bool_t LoadLibrary(const char *module)
145 {
146   // Load a module library in a given mode. Reports success.
147   Int_t result = 0;
148   TString mod(module);
149   ::Info("LoadLibrary", "Loading %s", module);
150   gROOT->IncreaseDirLevel();
151
152   if (mod.IsNull()) {
153     ::Error("AnalysisTrainNew.C::LoadLibrary", "Empty module name");
154     gROOT->DecreaseDirLevel();
155     return kFALSE;
156   }
157
158   // If a library is specified, just load it
159   if (mod.EndsWith(".so")) {
160     mod.Remove(mod.Index(".so"));
161     ::Info("LoadLibrary", "Loading library: %s", mod.Data()); 
162     result = gSystem->Load(mod);
163     if (result < 0) {
164       ::Error("AnalysisTrainNew.C::LoadLibrary", 
165               "Could not load library %s", module);
166     }
167     gROOT->DecreaseDirLevel();      
168     return (result >= 0);
169   }
170   // Check if the library is already loaded
171   if (strlen(gSystem->GetLibraries(module, "", kFALSE)) > 0) {
172     ::Info("LoadLibrary", "Module %s already loaded", module);
173     gROOT->DecreaseDirLevel();      
174     return kTRUE;
175   }
176
177   ::Info("LoadLibrary", "Trying to load lib%s", module);
178   result = gSystem->Load(Form("lib%s", module));
179   if (result < 0)
180     ::Error("AnalysisTrainNew.C::LoadLibrary", 
181             "Could not load module %s", module);
182   ::Info("LoadLibrary", "Module %s, successfully loaded", module);
183   gROOT->DecreaseDirLevel();      
184   return (result >= 0);
185 }
186
187 //====================================================================
188 /** 
189  * Load common libraries 
190  * 
191  * @return true on sucess 
192  */
193 Bool_t LoadCommonLibraries()
194 {
195   // Load common analysis libraries.
196   if (!gSystem->Getenv("ALICE_ROOT")) {
197     ::Error("AnalysisTrainNew.C::LoadCommonLibraries", 
198             "Analysis train requires that analysis libraries are "
199             "compiled with a local AliRoot");
200     return kFALSE;
201   }
202
203   Bool_t success = kTRUE;
204   // Load framework classes. Par option ignored here.
205   success &= LoadLibrary("libSTEERBase.so");
206   success &= LoadLibrary("libESD.so");
207   success &= LoadLibrary("libAOD.so");
208   success &= LoadLibrary("libANALYSIS.so");
209   success &= LoadLibrary("libOADB.so");
210   success &= LoadLibrary("libANALYSISalice.so");
211   success &= LoadLibrary("libESDfilter.so");
212   success &= LoadLibrary("libCORRFW.so");
213   gROOT->ProcessLine(".include $ALICE_ROOT/include");
214   if (success) {
215     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
216            "Load common libraries:    SUCCESS");
217     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
218            "Include path for Aclic compilation:\n%s",
219            gSystem->GetIncludePath());
220   } else {
221     ::Info("AnalysisTrainNew.C::LoadCommodLibraries", 
222            "Load common libraries:    FAILED");
223   }
224   return success;
225 }
226
227 //====================================================================
228 /** 
229  * Load libraries needed by the train 
230  * 
231  * @param useTender 
232  * @param doCDBconnect 
233  * @param iESDfilter 
234  * @param iPWGMuonTrain 
235  * @param iJETAN 
236  * @param iJETANdelta 
237  * @param iPWGHFvertexing 
238  * @param iPWGHFd2h 
239  * @param iPWGDQJPSIfilter 
240  * 
241  * @return true on success 
242  */
243 Bool_t LoadAnalysisLibraries()
244 {
245   // Load common analysis libraries.
246   if (aodCfg->UseTender() || aodCfg->UseCDBconnect()) {
247     if (!LoadLibrary("TENDER") ||!LoadLibrary("TENDERSupplies")) return kFALSE;
248   }
249   // CDBconnect
250   if ((aodCfg->UseCDBconnect() && !aodCfg->UseTender()) 
251       && !LoadLibrary("PWGPP")) return false;
252   if ((aodCfg->UseESDfilter() || 
253        (aodCfg->UsePWGMuonTrain() && detCfg->UseMUON())))
254     if (!LoadLibrary("PWGmuon")) return kFALSE;
255   // JETAN
256   if ((aodCfg->UseJETAN() || aodCfg->UseJETANdelta()))
257     if (!LoadLibrary("JETAN")) return kFALSE;
258   if (aodCfg->UseJETANdelta()) { // CINT doesn't like long '||' chains
259     if (!LoadLibrary("CGAL"))           return false;
260     if (!LoadLibrary("fastjet"))        return false;
261     if (!LoadLibrary("siscone"))        return false;
262     if (!LoadLibrary("SISConePlugin"))  return false;
263     if (!LoadLibrary("FASTJETAN"))      return false;
264   }
265
266   // PWG3 Vertexing HF
267   if (aodCfg->UsePWGHFvertexing() || aodCfg->UsePWGHFd2h())) { 
268     // CINT doesn't like long '||' chains
269     if (!LoadLibrary("PWGflowBase"))      return false;
270     if (!LoadLibrary("PWGflowTasks"))     return false;
271     if (cholm) if (!LoadLibrary("PWGTRD"))           return false;
272     if (!LoadLibrary("PWGHFvertexingHF")) return false;
273   }
274
275   // PWG3 dielectron
276   if (aodCfg->UsePWGDQJPSIfilter() && 
277       !LoadLibrary("PWGDQdielectron")) return kFALSE;
278   
279   ::Info("AnalysisTrainNew.C::LoadAnalysisLibraries", 
280          "Load other libraries:   SUCCESS");
281   return kTRUE;
282 }
283
284 //====================================================================
285 /** 
286  * Add tasks to the train 
287  * 
288  * @param cdb_location 
289  */
290 void AddAnalysisTasks(const char *cdb_location)
291 {
292   // === Add all analysis task wagons to the train ===================
293   // 
294   // --- Some constants ----------------------------------------------
295   TString ali   = "$(ALICE_ROOT)";
296   TString ana   = ali + "/ANALYSIS";
297   TString pwghf = ali + "/PWGHF";
298   TString pwglf = ali + "/PWGLF";
299   TString pwgje = ali + "/PWGJE";
300   TString pwgdq = ali + "/PWGDQ";
301   TString pwgpp = ali + "/PWGPP";
302
303   // --- Get the analysis manager ------------------------------------
304   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
305   AliAnalysisManager::SetCommonFileName("AODQA.root");
306
307   // --- PIDResponse(JENS) -------------------------------------------
308   if (aodCfg->UsePIDResponse()) {
309     gROOT->LoadMacro(ana+"/macros/AddTaskPIDResponse.C");
310     AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
311   }
312
313   // --- CDB connection ----------------------------------------------
314   if (aodCfg->UseCDBconnect() && !aodCfg->UseTender()) {
315     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskCDBconnect.C");
316     AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, grp->run);
317     if (!taskCDB) return;
318
319     AliCDBManager *cdb = AliCDBManager::Instance();
320     // cdb->SetDefaultStorage(cdb_location);
321     cdb->SetDefaultStorageFromRun(grp->run);
322   }
323   if (aodCfg->UseTender()) {
324     gROOT->LoadMacro(ana+"/TenderSupplies/AddTaskTender.C");
325     AliAnalysisTaskSE *tender = AddTaskTender(aodCfg->UseV0tender());
326   }
327
328   // --- Physics selection -------------------------------------------
329   if (aodCfg->UsePhysicsSelection()) {
330     // Physics selection task
331     gROOT->LoadMacro(ana+"/macros/AddTaskPhysicsSelection.C");
332     mgr->RegisterExtraFile("event_stat.root");
333     AliPhysicsSelectionTask *physSelTask = 
334       AddTaskPhysicsSelection(aodCfg->UseMC());
335   }
336
337   // --- Centrality (only Pb-Pb) -------------------------------------
338   if (aodCfg->UseCentrality()) {
339     gROOT->LoadMacro(ana+"/macros/AddTaskCentrality.C");
340     AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
341     taskCentrality->SetMCInput();
342   }
343
344   // --- PWGLF - Forward (cholm@nbi.dk) -----------------------------
345   if (aodCfg->UsePWGLFForward() && 
346       aodCfg->UsePhysicsSelection() &&
347       detCfg->UseFMD()) {
348     gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskForwardMult.C");
349     // Arguments are 
350     //   mc         Assume MC input
351     //   runNo      Run number to do local initialization - not used
352     //   sys        Collision system (1:pp,2:PbPb,3:pPb/Pbp) - not used
353     //   sNN        Collision energy in GeV - not used
354     //   field      L3 magnetic field strength  - not used
355     //   config     Configuration script 
356     //   corrdir    Possible directory containing custom OADB corrections
357     // HACK load custom corrections 
358     Info("", "Adding forward AOD task with mc=%d",
359          aodCfg->UseMC() && aodCfg->UseTR());
360     AddTaskForwardMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
361                        "ForwardAODConfig.C",".");
362     gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskCentralMult.C");
363     AddTaskCentralMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
364                        "CentralAODConfig.C");
365     const char* hack2="AliForwardCorrectionManager::Instance().Print(\"R\")";
366     gROOT->ProcessLine(hack2);
367   }
368
369
370   // --- ESD filter --------------------------------------------------
371   if (aodCfg->UseESDfilter()) {
372     //  ESD filter task configuration.
373     gROOT->LoadMacro(ana+"/ESDfilter/macros/AddTaskESDFilter.C");
374     if (aodCfg->UseMUONcopyAOD() && detCfg->UseMUON()) {
375       printf("Registering delta AOD file\n");
376       mgr->RegisterExtraFile("AliAOD.Muons.root");
377       mgr->RegisterExtraFile("AliAOD.Dimuons.root");
378     }
379     UInt_t runFlag = (grp->Year()%100)*100;
380     AliAnalysisTaskESDfilter *taskesdfilter =
381       AddTaskESDFilter(aodCfg->UseKFILTER(),
382                        aodCfg->UseMUONcopyAOD(),         // write Muon AOD
383                        kFALSE,               // write dimuon AOD
384                        kFALSE,               // usePhysicsSelection
385                        kFALSE,               // centrality OBSOLETE
386                        kTRUE,                // enable TPS only tracks
387                        kFALSE,               // disable cascades
388                        kFALSE,               // disable kinks
389                        runFlag);             // run flag (YY00)
390   }
391
392   TString configPWGHFd2h = 
393     (grp->IsPP() ?
394      pwghf+"/vertexingHF/ConfigVertexingHF.C" :
395      pwghf+"/vertexingHF/ConfigVertexingHF_Pb_AllCent.C");
396
397   // --- PWG3 vertexing ----------------------------------------------
398   if (aodCfg->UsePWGHFvertexing()) {
399     gROOT->LoadMacro(pwghf+"/vertexingHF/macros/AddTaskVertexingHF.C");
400
401     if (!aodCfg->UsePWGHFd2h()) 
402       TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()), 
403                 "file:ConfigVertexingHF.C");
404
405     AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
406     if (!taskvertexingHF) 
407       ::Warning("AnalysisTrainNew", 
408                 "AliAnalysisTaskSEVertexingHF cannot run for this train "
409                 "conditions - EXCLUDED");
410     else 
411       mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
412
413     taskvertexingHF->SelectCollisionCandidates(0);
414   }
415
416   // ---- PWG3 JPSI filtering (only pp) ------------------------------
417   if (aodCfg->UsePWGDQJPSIfilter()) {
418     gROOT->LoadMacro(pwgdq+"/dielectron/macros/AddTaskJPSIFilter.C");
419     AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
420
421     if (!taskJPSIfilter) 
422       ::Warning("AnalysisTrainNew", 
423                 "AliAnalysisTaskDielectronFilter cannot run for this train "
424                 "conditions - EXCLUDED");
425     else 
426       mgr->RegisterExtraFile("AliAOD.Dielectron.root");
427
428     taskJPSIfilter->SelectCollisionCandidates(0);
429   }
430
431   // --- PWG3 D2h ----------------------------------------------------
432   if (aodCfg->UsePWGHFd2h() && aodCfg->UsePWGHFvertexing()) {
433     gROOT->LoadMacro(pwghf+"/vertexingHF/AddD2HTrain.C");
434     TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()), 
435               "file:ConfigVertexingHF.C");
436     AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);
437   }
438
439   // --- Jet analysis ------------------------------------------------
440
441   // Configurations flags, move up?
442   if (aodCfg->UseJETAN()) {
443 #if 0
444     Warning("", "JET analysis disabled - major restructuring ofg JETAN");
445 #else
446     TString jetAOD             = "AliAOD.Jets.root";
447     UInt_t  highPtMask         = 768;// from esd filter
448     TString subtractBranches   = "";
449     UInt_t  psFlag             = 0;
450
451     Info("", "Loading macro %s/macros/AddTaskJets.C", pwgje.Data());
452     gROOT->LoadMacro(pwgje+"/macros/AddTaskJets.C");
453     // Default jet reconstructor running on ESD's
454     // no background subtraction
455     AliAnalysisTask* task = AddTaskJets("AOD","UA1",0.4F,highPtMask,1.F,0); 
456     if (!task) 
457       ::Fatal("AnalysisTrainNew", 
458               "AliAnalysisTaskJets cannot run for this train "
459               "conditions - EXCLUDED");
460     
461     AliAnalysisTaskJets* taskjets = static_cast<AliAnalysisTaskJets*>(task);
462     if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
463
464     if (aodCfg->UseJETANdelta()) {
465       // need to modify this accordingly in the add task jets
466       // AddTaskJetsDelta("AliAOD.Jets.root"); 
467       mgr->RegisterExtraFile(jetAOD);
468       TString cTmp("");
469
470       if(grp->IsAA()){
471         // UA1 intrinsic background subtraction
472         // background subtraction
473         taskjets = AddTaskJets("AOD","UA1",0.4,highPtMask,1.,2); 
474         if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
475       }
476       // SICONE
477       //no background subtration to be done later....
478       taskjets = AddTaskJets("AOD","SISCONE",0.4,highPtMask,0.15,0); 
479       if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD.Data());
480       cTmp = taskjets->GetNonStdBranch();
481       if(!cTmp.IsNull()) subtractBranches += Form("%s ",cTmp.Data());
482
483       // Add the clusters..
484       gROOT->LoadMacro(pwgje+"/macros/AddTaskJetCluster.C");
485       AliAnalysisTaskJetCluster *taskCl = 0;
486       Float_t fCenUp = 0;
487       Float_t fCenLo = 0;
488       Float_t fTrackEtaWindow = 0.9;
489       // this one is for the background and random jets, random cones
490       // with no skip
491       taskCl = AddTaskJetCluster("AOD","",highPtMask,
492                                  psFlag,"KT",0.4,0,1, 
493                                  jetAOD,0.15,
494                                  fTrackEtaWindow,0); 
495       taskCl->SetBackgroundCalc(kTRUE);
496       taskCl->SetNRandomCones(10);
497       taskCl->SetCentralityCut(fCenLo,fCenUp);
498       taskCl->SetGhostEtamax(fTrackEtaWindow);
499       TString bkgBranch = Form("%s_%s",
500                                AliAODJetEventBackground::StdBranchName(),
501                                taskCl->GetJetOutputBranch());
502
503       taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
504                                  0.4, 2, 1, jetAOD, 0.15);
505       taskCl->SetCentralityCut(fCenLo,fCenUp);
506       if(grp->IsAA()) taskCl->SetBackgroundBranch(bkgBranch.Data());
507
508       taskCl->SetNRandomCones(10);
509       subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
510
511       taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
512                                  0.2, 0 , 1, jetAOD, 0.15);
513       taskCl->SetCentralityCut(fCenLo,fCenUp);
514       if(grp->IsAA())taskCl->SetBackgroundBranch(bkgBranch);
515       
516       subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
517
518       // DO THE BACKGROUND SUBTRACTION
519       if(grp->IsAA() && !subtractBranches.IsNull()) {
520         gROOT->LoadMacro(pwgje+"/macros/AddTaskJetBackgroundSubtract.C");
521         AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
522         taskSubtract = AddTaskJetBackgroundSubtract(subtractBranches,1,
523                                                     "B0","B%d");
524         taskSubtract->SetBackgroundBranch(bkgBranch);
525         if(!jetAOD.IsNull()) taskSubtract->SetNonStdOutputFile(jetAOD.Data());
526       }
527     }
528 #endif
529   }
530 }
531
532
533
534 //====================================================================
535 /** 
536  * Create the input chain
537  * 
538  * 
539  * @return Pointer to newly allocated train 
540  */
541 TChain *CreateChain()
542 {
543   // Create the input chain
544   chain = new TChain("esdTree");
545   if (gSystem->AccessPathName("AliESDs.root"))
546     ::Error("AnalysisTrainNew.C::CreateChain", 
547             "File: AliESDs.root not in ./data dir");
548   else
549     chain->Add("AliESDs.root");
550   if (chain->GetNtrees()) return chain;
551   return NULL;
552 }
553
554 /** 
555  * Helper function to make @c outputs_valid file 
556  * 
557  */
558 void ValidateOutput()
559 {
560   std::ofstream out;
561   out.open("outputs_valid", ios::out);
562   out.close();    
563 }  
564 //====================================================================
565 /** 
566  * Merge AOD output 
567  * 
568  * @param dir   Directory 
569  * @param stage The merging stage 
570  */
571 void AODMerge(const char* dir, Int_t stage)
572 {
573   // Merging method. No staging and no terminate phase.
574   TStopwatch  timer; timer.Start();
575   TString     outputDir     = dir;
576   TObjArray   outputFiles;
577   // outputFiles.Add(new TObjString("EventStat_temp.root"));
578   outputFiles.Add(new TObjString("AODQA.root"));
579   outputFiles.Add(new TObjString("pyxsec_hists.root"));
580
581   Bool_t mergeTrees = stage <= 1;
582   if (mergeTrees) {
583     outputFiles.Add(new TObjString("AliAOD.root"));
584     if (aodCfg->UsePWGHFvertexing()) 
585       outputFiles.Add(new TObjString("AliAOD.VertexingHF.root"));
586     if (aodCfg->UseESDfilter() && 
587         aodCfg->UseMUONcopyAOD() && 
588         detCfg->UseMUON())
589       outputFiles.Add(new TObjString("AliAOD.Muons.root"));
590     if (aodCfg->UseJETAN()) 
591       outputFiles.Add(new TObjString("AliAOD.Jets.root"));
592     if (aodCfg->UsePWGDQJPSIfilter()) 
593       outputFiles.Add(new TObjString("AliAOD.Dielectron.root"));
594   }
595
596   TString     mergeExcludes = "";
597   TIter       iter(&outputFiles);
598   TObjString* str           = 0;
599   Bool_t      merged        = kTRUE;
600   while ((str = static_cast<TObjString*>(iter()))) {
601     TString& outputFile = str->GetString();
602     // Skip already merged outputs
603     if (!gSystem->AccessPathName(outputFile)) {
604       ::Warning("Merge","Output file <%s> found. Not merging again.",
605                 outputFile.Data());
606       continue;
607     }
608     if (mergeExcludes.Contains(outputFile.Data())) continue;
609     merged = AliAnalysisAlien::MergeOutput(outputFile, 
610                                            outputDir, 
611                                            10, 
612                                            stage);
613     if (!merged) {
614       ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
615       continue;
616     }
617   }
618
619   // all outputs merged, validate
620   if (!outputDir.Contains("stage")) {
621     ValidateOutput();
622     timer.Print();
623     return;
624   }
625
626   // --- set up to run terminate -------------------------------------
627   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
628   mgr->SetSkipTerminate(kFALSE);
629   if (!mgr->InitAnalysis()) return;
630
631   mgr->PrintStatus();
632   mgr->SetGridHandler(new AliAnalysisAlien);
633   mgr->StartAnalysis("gridterminate",0);
634   ValidateOutput();
635   timer.Print();
636
637 }
638
639 //====================================================================
640 /** 
641  * Set-up and run AOD train 
642  * 
643  * @param run      Run number 
644  * @param xmlfile  Collection 
645  * @param stage    Stage 
646  */
647 void AOD(UInt_t run, const char* xmlfile=0, Int_t stage=0)
648 {
649   TString host(gSystem->HostName());
650   cholm = host.BeginsWith("hehi");
651   if (cholm) TGrid::Connect("alien:");
652
653   // -----------------------------------------------------------------
654   // 
655   // Get GRP parameters.  Defines global "grp" as a pointer to GRPData
656   //
657   gROOT->Macro(Form("GRP.C(%d)", run));
658   gROOT->Macro("AODConfig.C");
659   gROOT->Macro("BaseConfig.C");
660   gROOT->Macro("DetConfig.C");
661
662   // --- Some settings -----------------------------------------------
663   // Set temporary merging directory to current one
664   gSystem->Setenv("TMPDIR", gSystem->pwd());
665   // Set temporary compilation directory to current one
666   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
667
668   // --- Friendly message --------------------------------------------
669   printf("===================================================\n");
670   printf("===========    RUNNING FILTERING TRAIN   ==========\n");
671   printf("===================================================\n");
672   printf("=  Configuring analysis train for:\n");
673   aodCfg->Print();
674
675   // Load common libraries and set include path
676   if (!LoadCommonLibraries()) {
677     ::Error("AnalysisTrain", "Could not load common libraries");
678     return;
679   }
680
681   // === Make the analysis manager and connect event handlers ========
682   // 
683   // --- Analysis manager and load libraries -------------------------
684   AliAnalysisManager *mgr = new AliAnalysisManager("Filter","Production train");
685   mgr->SetRunFromPath(grp->run);
686   if (aodCfg->UseSysInfo()) mgr->SetNSysInfo(100);
687   if (!LoadAnalysisLibraries()) {
688     ::Error("AnalysisTrain", "Could not load analysis libraries");
689     return;
690   }
691
692   // --- Create ESD input handler ------------------------------------
693   AliESDInputHandler *esdHandler = new AliESDInputHandler();
694   mgr->SetInputEventHandler(esdHandler);
695
696   // --- Monte Carlo handler -----------------------------------------
697   if (aodCfg->UseMC()) {
698     AliMCEventHandler* mcHandler = new AliMCEventHandler();
699     mgr->SetMCtruthEventHandler(mcHandler);
700     mcHandler->SetPreReadMode(1);
701     mcHandler->SetReadTR(aodCfg->UseTR());
702   }
703
704   // --- AOD output handler ------------------------------------------
705   if (aodCfg->UseAODhandler()) {
706     AliAODHandler* aodHandler   = new AliAODHandler();
707     aodHandler->SetOutputFileName("AliAOD.root");
708     mgr->SetOutputEventHandler(aodHandler);
709   }
710
711   // === Set up tasks ================================================
712   //
713   // --- Create tasks ------------------------------------------------
714   AddAnalysisTasks(cdbPath);
715
716   // --- Debugging if needed -----------------------------------------
717   if (aodCfg->UseDBG()) mgr->SetDebugLevel(3);
718
719
720   // --- If merging, do so here and exit -----------------------------
721   if (stage > 0) {
722     AODMerge(xmlfile, stage);
723     return;
724   }
725   // === Run the analysis ============================================
726   //
727   // --- Make our chain ----------------------------------------------
728   TChain *chain = CreateChain();
729   if (!chain) return;
730
731   // --- Run the thing -----------------------------------------------
732   TStopwatch timer;
733   timer.Start();
734   if (!mgr->InitAnalysis()) return;
735
736   
737   mgr->PrintStatus();
738   mgr->SetSkipTerminate(kTRUE);
739   mgr->StartAnalysis("local", chain);
740   timer.Print();
741 }
742
743 // 
744 // EOF
745 // 
746