]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/sim/AOD.C
Merge branch 'feature-movesplit'
[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 oadb  = ali + "/OADB";
298   TString pwghf = ali + "/PWGHF";
299   TString pwglf = ali + "/PWGLF";
300   TString pwgje = ali + "/PWGJE";
301   TString pwgdq = ali + "/PWGDQ";
302   TString pwgpp = ali + "/PWGPP";
303
304   // --- Get the analysis manager ------------------------------------
305   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
306   AliAnalysisManager::SetCommonFileName("AODQA.root");
307
308   // --- PIDResponse(JENS) -------------------------------------------
309   if (aodCfg->UsePIDResponse()) {
310     gROOT->LoadMacro(ana+"/macros/AddTaskPIDResponse.C");
311     AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
312   }
313
314   // --- CDB connection ----------------------------------------------
315   if (aodCfg->UseCDBconnect() && !aodCfg->UseTender()) {
316     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskCDBconnect.C");
317     AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, grp->run);
318     if (!taskCDB) return;
319
320     AliCDBManager *cdb = AliCDBManager::Instance();
321     // cdb->SetDefaultStorage(cdb_location);
322     cdb->SetDefaultStorageFromRun(grp->run);
323   }
324   if (aodCfg->UseTender()) {
325     gROOT->LoadMacro(ana+"/TenderSupplies/AddTaskTender.C");
326     AliAnalysisTaskSE *tender = AddTaskTender(aodCfg->UseV0tender());
327   }
328
329   // --- Physics selection -------------------------------------------
330   if (aodCfg->UsePhysicsSelection()) {
331     // Physics selection task
332     gROOT->LoadMacro(oadb+"/macros/AddTaskPhysicsSelection.C");
333     mgr->RegisterExtraFile("event_stat.root");
334     AliPhysicsSelectionTask *physSelTask = 
335       AddTaskPhysicsSelection(aodCfg->UseMC());
336   }
337
338   // --- Centrality (only Pb-Pb) -------------------------------------
339   if (aodCfg->UseCentrality()) {
340     gROOT->LoadMacro(oadb+"/macros/AddTaskCentrality.C");
341     AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
342     taskCentrality->SetMCInput();
343   }
344
345   // --- PWGLF - Forward (cholm@nbi.dk) -----------------------------
346   if (aodCfg->UsePWGLFForward() && 
347       aodCfg->UsePhysicsSelection() &&
348       detCfg->UseFMD()) {
349     gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskForwardMult.C");
350     // Arguments are 
351     //   mc         Assume MC input
352     //   runNo      Run number to do local initialization - not used
353     //   sys        Collision system (1:pp,2:PbPb,3:pPb/Pbp) - not used
354     //   sNN        Collision energy in GeV - not used
355     //   field      L3 magnetic field strength  - not used
356     //   config     Configuration script 
357     //   corrdir    Possible directory containing custom OADB corrections
358     // HACK load custom corrections 
359     Info("", "Adding forward AOD task with mc=%d",
360          aodCfg->UseMC() && aodCfg->UseTR());
361     AddTaskForwardMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
362                        "ForwardAODConfig.C",".");
363     gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskCentralMult.C");
364     AddTaskCentralMult(aodCfg->UseMC() && aodCfg->UseTR(),0,0,0,0,
365                        "CentralAODConfig.C");
366     const char* hack2="AliForwardCorrectionManager::Instance().Print(\"R\")";
367     gROOT->ProcessLine(hack2);
368   }
369
370
371   // --- ESD filter --------------------------------------------------
372   if (aodCfg->UseESDfilter()) {
373     //  ESD filter task configuration.
374     gROOT->LoadMacro(ana+"/ESDfilter/macros/AddTaskESDFilter.C");
375     if (aodCfg->UseMUONcopyAOD() && detCfg->UseMUON()) {
376       printf("Registering delta AOD file\n");
377       mgr->RegisterExtraFile("AliAOD.Muons.root");
378       mgr->RegisterExtraFile("AliAOD.Dimuons.root");
379     }
380     UInt_t runFlag = (grp->Year()%100)*100;
381     AliAnalysisTaskESDfilter *taskesdfilter =
382       AddTaskESDFilter(aodCfg->UseKFILTER(),
383                        aodCfg->UseMUONcopyAOD(),         // write Muon AOD
384                        kFALSE,               // write dimuon AOD
385                        kFALSE,               // usePhysicsSelection
386                        kFALSE,               // centrality OBSOLETE
387                        kTRUE,                // enable TPS only tracks
388                        kFALSE,               // disable cascades
389                        kFALSE,               // disable kinks
390                        runFlag);             // run flag (YY00)
391   }
392
393   TString configPWGHFd2h = 
394     (grp->IsPP() ?
395      pwghf+"/vertexingHF/ConfigVertexingHF.C" :
396      pwghf+"/vertexingHF/ConfigVertexingHF_Pb_AllCent.C");
397
398   // --- PWG3 vertexing ----------------------------------------------
399   if (aodCfg->UsePWGHFvertexing()) {
400     gROOT->LoadMacro(pwghf+"/vertexingHF/macros/AddTaskVertexingHF.C");
401
402     if (!aodCfg->UsePWGHFd2h()) 
403       TFile::Cp(gSystem->ExpandPathName(configPWG3d2h.Data()), 
404                 "file:ConfigVertexingHF.C");
405
406     AliAnalysisTaskSEVertexingHF *taskvertexingHF = AddTaskVertexingHF();
407     if (!taskvertexingHF) 
408       ::Warning("AnalysisTrainNew", 
409                 "AliAnalysisTaskSEVertexingHF cannot run for this train "
410                 "conditions - EXCLUDED");
411     else 
412       mgr->RegisterExtraFile("AliAOD.VertexingHF.root");
413
414     taskvertexingHF->SelectCollisionCandidates(0);
415   }
416
417   // ---- PWG3 JPSI filtering (only pp) ------------------------------
418   if (aodCfg->UsePWGDQJPSIfilter()) {
419     gROOT->LoadMacro(pwgdq+"/dielectron/macros/AddTaskJPSIFilter.C");
420     AliAnalysisTaskSE *taskJPSIfilter = AddTaskJPSIFilter();
421
422     if (!taskJPSIfilter) 
423       ::Warning("AnalysisTrainNew", 
424                 "AliAnalysisTaskDielectronFilter cannot run for this train "
425                 "conditions - EXCLUDED");
426     else 
427       mgr->RegisterExtraFile("AliAOD.Dielectron.root");
428
429     taskJPSIfilter->SelectCollisionCandidates(0);
430   }
431
432   // --- PWG3 D2h ----------------------------------------------------
433   if (aodCfg->UsePWGHFd2h() && aodCfg->UsePWGHFvertexing()) {
434     gROOT->LoadMacro(pwghf+"/vertexingHF/AddD2HTrain.C");
435     TFile::Cp(gSystem->ExpandPathName(configPWGHFd2h.Data()), 
436               "file:ConfigVertexingHF.C");
437     AddD2HTrain(kFALSE, 1,0,0,0,0,0,0,0,0,0,0);
438   }
439
440   // --- Jet analysis ------------------------------------------------
441
442   // Configurations flags, move up?
443   if (aodCfg->UseJETAN()) {
444 #if 0
445     Warning("", "JET analysis disabled - major restructuring ofg JETAN");
446 #else
447     TString jetAOD             = "AliAOD.Jets.root";
448     UInt_t  highPtMask         = 768;// from esd filter
449     TString subtractBranches   = "";
450     UInt_t  psFlag             = 0;
451
452     Info("", "Loading macro %s/macros/AddTaskJets.C", pwgje.Data());
453     gROOT->LoadMacro(pwgje+"/macros/AddTaskJets.C");
454     // Default jet reconstructor running on ESD's
455     // no background subtraction
456     AliAnalysisTask* task = AddTaskJets("AOD","UA1",0.4F,highPtMask,1.F,0); 
457     if (!task) 
458       ::Fatal("AnalysisTrainNew", 
459               "AliAnalysisTaskJets cannot run for this train "
460               "conditions - EXCLUDED");
461     
462     AliAnalysisTaskJets* taskjets = static_cast<AliAnalysisTaskJets*>(task);
463     if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
464
465     if (aodCfg->UseJETANdelta()) {
466       // need to modify this accordingly in the add task jets
467       // AddTaskJetsDelta("AliAOD.Jets.root"); 
468       mgr->RegisterExtraFile(jetAOD);
469       TString cTmp("");
470
471       if(grp->IsAA()){
472         // UA1 intrinsic background subtraction
473         // background subtraction
474         taskjets = AddTaskJets("AOD","UA1",0.4,highPtMask,1.,2); 
475         if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD);
476       }
477       // SICONE
478       //no background subtration to be done later....
479       taskjets = AddTaskJets("AOD","SISCONE",0.4,highPtMask,0.15,0); 
480       if(!jetAOD.IsNull()) taskjets->SetNonStdOutputFile(jetAOD.Data());
481       cTmp = taskjets->GetNonStdBranch();
482       if(!cTmp.IsNull()) subtractBranches += Form("%s ",cTmp.Data());
483
484       // Add the clusters..
485       gROOT->LoadMacro(pwgje+"/macros/AddTaskJetCluster.C");
486       AliAnalysisTaskJetCluster *taskCl = 0;
487       Float_t fCenUp = 0;
488       Float_t fCenLo = 0;
489       Float_t fTrackEtaWindow = 0.9;
490       // this one is for the background and random jets, random cones
491       // with no skip
492       taskCl = AddTaskJetCluster("AOD","",highPtMask,
493                                  psFlag,"KT",0.4,0,1, 
494                                  jetAOD,0.15,
495                                  fTrackEtaWindow,0); 
496       taskCl->SetBackgroundCalc(kTRUE);
497       taskCl->SetNRandomCones(10);
498       taskCl->SetCentralityCut(fCenLo,fCenUp);
499       taskCl->SetGhostEtamax(fTrackEtaWindow);
500       TString bkgBranch = Form("%s_%s",
501                                AliAODJetEventBackground::StdBranchName(),
502                                taskCl->GetJetOutputBranch());
503
504       taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
505                                  0.4, 2, 1, jetAOD, 0.15);
506       taskCl->SetCentralityCut(fCenLo,fCenUp);
507       if(grp->IsAA()) taskCl->SetBackgroundBranch(bkgBranch.Data());
508
509       taskCl->SetNRandomCones(10);
510       subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
511
512       taskCl = AddTaskJetCluster("AOD", "", highPtMask, psFlag, "ANTIKT",
513                                  0.2, 0 , 1, jetAOD, 0.15);
514       taskCl->SetCentralityCut(fCenLo,fCenUp);
515       if(grp->IsAA())taskCl->SetBackgroundBranch(bkgBranch);
516       
517       subtractBranches += Form("%s ",taskCl->GetJetOutputBranch());
518
519       // DO THE BACKGROUND SUBTRACTION
520       if(grp->IsAA() && !subtractBranches.IsNull()) {
521         gROOT->LoadMacro(pwgje+"/macros/AddTaskJetBackgroundSubtract.C");
522         AliAnalysisTaskJetBackgroundSubtract *taskSubtract = 0;
523         taskSubtract = AddTaskJetBackgroundSubtract(subtractBranches,1,
524                                                     "B0","B%d");
525         taskSubtract->SetBackgroundBranch(bkgBranch);
526         if(!jetAOD.IsNull()) taskSubtract->SetNonStdOutputFile(jetAOD.Data());
527       }
528     }
529 #endif
530   }
531 }
532
533
534
535 //====================================================================
536 /** 
537  * Create the input chain
538  * 
539  * 
540  * @return Pointer to newly allocated train 
541  */
542 TChain *CreateChain()
543 {
544   // Create the input chain
545   chain = new TChain("esdTree");
546   if (gSystem->AccessPathName("AliESDs.root"))
547     ::Error("AnalysisTrainNew.C::CreateChain", 
548             "File: AliESDs.root not in ./data dir");
549   else
550     chain->Add("AliESDs.root");
551   if (chain->GetNtrees()) return chain;
552   return NULL;
553 }
554
555 /** 
556  * Helper function to make @c outputs_valid file 
557  * 
558  */
559 void ValidateOutput()
560 {
561   std::ofstream out;
562   out.open("outputs_valid", ios::out);
563   out.close();    
564 }  
565 //====================================================================
566 /** 
567  * Merge AOD output 
568  * 
569  * @param dir   Directory 
570  * @param stage The merging stage 
571  */
572 void AODMerge(const char* dir, Int_t stage)
573 {
574   // Merging method. No staging and no terminate phase.
575   TStopwatch  timer; timer.Start();
576   TString     outputDir     = dir;
577   TObjArray   outputFiles;
578   // outputFiles.Add(new TObjString("EventStat_temp.root"));
579   outputFiles.Add(new TObjString("AODQA.root"));
580   outputFiles.Add(new TObjString("pyxsec_hists.root"));
581
582   Bool_t mergeTrees = stage <= 1;
583   if (mergeTrees) {
584     outputFiles.Add(new TObjString("AliAOD.root"));
585     if (aodCfg->UsePWGHFvertexing()) 
586       outputFiles.Add(new TObjString("AliAOD.VertexingHF.root"));
587     if (aodCfg->UseESDfilter() && 
588         aodCfg->UseMUONcopyAOD() && 
589         detCfg->UseMUON())
590       outputFiles.Add(new TObjString("AliAOD.Muons.root"));
591     if (aodCfg->UseJETAN()) 
592       outputFiles.Add(new TObjString("AliAOD.Jets.root"));
593     if (aodCfg->UsePWGDQJPSIfilter()) 
594       outputFiles.Add(new TObjString("AliAOD.Dielectron.root"));
595   }
596
597   TString     mergeExcludes = "";
598   TIter       iter(&outputFiles);
599   TObjString* str           = 0;
600   Bool_t      merged        = kTRUE;
601   while ((str = static_cast<TObjString*>(iter()))) {
602     TString& outputFile = str->GetString();
603     // Skip already merged outputs
604     if (!gSystem->AccessPathName(outputFile)) {
605       ::Warning("Merge","Output file <%s> found. Not merging again.",
606                 outputFile.Data());
607       continue;
608     }
609     if (mergeExcludes.Contains(outputFile.Data())) continue;
610     merged = AliAnalysisAlien::MergeOutput(outputFile, 
611                                            outputDir, 
612                                            10, 
613                                            stage);
614     if (!merged) {
615       ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
616       continue;
617     }
618   }
619
620   // all outputs merged, validate
621   if (!outputDir.Contains("stage")) {
622     ValidateOutput();
623     timer.Print();
624     return;
625   }
626
627   // --- set up to run terminate -------------------------------------
628   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
629   mgr->SetSkipTerminate(kFALSE);
630   if (!mgr->InitAnalysis()) return;
631
632   mgr->PrintStatus();
633   mgr->SetGridHandler(new AliAnalysisAlien);
634   mgr->StartAnalysis("gridterminate",0);
635   ValidateOutput();
636   timer.Print();
637
638 }
639
640 //====================================================================
641 /** 
642  * Set-up and run AOD train 
643  * 
644  * @param run      Run number 
645  * @param xmlfile  Collection 
646  * @param stage    Stage 
647  */
648 void AOD(UInt_t run, const char* xmlfile=0, Int_t stage=0)
649 {
650   TString host(gSystem->HostName());
651   cholm = host.BeginsWith("hehi");
652   if (cholm) TGrid::Connect("alien:");
653
654   // -----------------------------------------------------------------
655   // 
656   // Get GRP parameters.  Defines global "grp" as a pointer to GRPData
657   //
658   gROOT->Macro(Form("GRP.C(%d)", run));
659   gROOT->Macro("AODConfig.C");
660   gROOT->Macro("BaseConfig.C");
661   gROOT->Macro("DetConfig.C");
662
663   // --- Some settings -----------------------------------------------
664   // Set temporary merging directory to current one
665   gSystem->Setenv("TMPDIR", gSystem->pwd());
666   // Set temporary compilation directory to current one
667   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
668
669   // --- Friendly message --------------------------------------------
670   printf("===================================================\n");
671   printf("===========    RUNNING FILTERING TRAIN   ==========\n");
672   printf("===================================================\n");
673   printf("=  Configuring analysis train for:\n");
674   aodCfg->Print();
675
676   // Load common libraries and set include path
677   if (!LoadCommonLibraries()) {
678     ::Error("AnalysisTrain", "Could not load common libraries");
679     return;
680   }
681
682   // === Make the analysis manager and connect event handlers ========
683   // 
684   // --- Analysis manager and load libraries -------------------------
685   AliAnalysisManager *mgr = new AliAnalysisManager("Filter","Production train");
686   mgr->SetRunFromPath(grp->run);
687   if (aodCfg->UseSysInfo()) mgr->SetNSysInfo(100);
688   if (!LoadAnalysisLibraries()) {
689     ::Error("AnalysisTrain", "Could not load analysis libraries");
690     return;
691   }
692
693   // --- Create ESD input handler ------------------------------------
694   AliESDInputHandler *esdHandler = new AliESDInputHandler();
695   mgr->SetInputEventHandler(esdHandler);
696
697   // --- Monte Carlo handler -----------------------------------------
698   if (aodCfg->UseMC()) {
699     AliMCEventHandler* mcHandler = new AliMCEventHandler();
700     mgr->SetMCtruthEventHandler(mcHandler);
701     mcHandler->SetPreReadMode(1);
702     mcHandler->SetReadTR(aodCfg->UseTR());
703   }
704
705   // --- AOD output handler ------------------------------------------
706   if (aodCfg->UseAODhandler()) {
707     AliAODHandler* aodHandler   = new AliAODHandler();
708     aodHandler->SetOutputFileName("AliAOD.root");
709     mgr->SetOutputEventHandler(aodHandler);
710   }
711
712   // === Set up tasks ================================================
713   //
714   // --- Create tasks ------------------------------------------------
715   AddAnalysisTasks(cdbPath);
716
717   // --- Debugging if needed -----------------------------------------
718   if (aodCfg->UseDBG()) mgr->SetDebugLevel(3);
719
720
721   // --- If merging, do so here and exit -----------------------------
722   if (stage > 0) {
723     AODMerge(xmlfile, stage);
724     return;
725   }
726   // === Run the analysis ============================================
727   //
728   // --- Make our chain ----------------------------------------------
729   TChain *chain = CreateChain();
730   if (!chain) return;
731
732   // --- Run the thing -----------------------------------------------
733   TStopwatch timer;
734   timer.Start();
735   if (!mgr->InitAnalysis()) return;
736
737   
738   mgr->PrintStatus();
739   mgr->SetSkipTerminate(kTRUE);
740   mgr->StartAnalysis("local", chain);
741   timer.Print();
742 }
743
744 // 
745 // EOF
746 // 
747