TENDER becomes Tender
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / sim / QA.C
1 /**
2  * @file   QA.C
3  * @author Christian Holm Christensen <cholm@nbi.dk>
4  * @date   Wed Sep 24 15:04:38 2014
5  * 
6  * @brief  Master script for QA train 
7  * 
8  * @note Do not modify this script. 
9  *
10  *
11  * This script reads in 4 other scripts 
12  *
13  * - GRP.C to load the global run parameters for the selected run,
14  *   such as collision system, energy, etc.
15  * 
16  * - AODConfig.C which defines a number of functions that return
17  *   either true or false.  The tasks added depends on these functions
18  *
19  * - BaseConfig.C which defines some base classes 
20  * 
21  * - DetConfig.C which defines which detectors are active and on. 
22  * 
23  * Users can customize QAConfig.C and DetConfig.C according to their
24  * needs
25  */
26 // Trigger mask.
27 UInt_t kTriggerInt        = AliVEvent::kAnyINT;
28 UInt_t kTriggerMuonAll    = (AliVEvent::kMUL7       | 
29                              AliVEvent::kMUSH7      | 
30                              AliVEvent::kMUU7       |
31                              AliVEvent::kMUS7       |
32                              AliVEvent::kMUSPB      |
33                              AliVEvent::kMUSHPB     |
34                              AliVEvent::kMuonLikePB | 
35                              AliVEvent::kMuonUnlikePB);
36 UInt_t kTriggerMuonBarell = AliVEvent::kMUU7;
37 UInt_t kTriggerEMC        = (AliVEvent::kEMC7   | 
38                              AliVEvent::kEMC8   | 
39                              AliVEvent::kEMCEJE | 
40                              AliVEvent::kEMCEGA);
41 UInt_t kTriggerHM         = AliVEvent::kHighMult;
42 UInt_t kTriggerMask       = kTriggerInt;
43
44 /**
45  * Interface (pure virtual) that all configuration classes must
46  * implement.
47  */
48 struct VirtualQACfg
49 {
50   /** @return  */
51   virtual Bool_t DoCDBconnect()  const = 0;
52   /** @return  */
53   virtual Bool_t DoEventStat()   const = 0;
54   /** @return  */
55   virtual Bool_t DoCentrality()  const = 0;
56   /** @return  */
57   virtual Bool_t DoQAsym()       const = 0;
58   /** @return  there is a 2nd file */
59   virtual Bool_t DoVZERO()       const = 0;
60   /** @return  */
61   virtual Bool_t DoVZEROPbPb()   const = 0;
62   /** @return  */
63   virtual Bool_t DoVertex()      const = 0;
64   /** @return  needs RP    */
65   virtual Bool_t DoSPD()         const = 0;
66   /** @return  */
67   virtual Bool_t DoTPC()         const = 0;
68   /** @return  */
69   virtual Bool_t DoHLT()         const = 0;
70   /** @return  needs RP */
71   virtual Bool_t DoSDD()         const = 0;
72   /** @return  */
73   virtual Bool_t DoSSDdEdx()     const = 0;
74   /** @return  */
75   virtual Bool_t DoTRD()         const = 0;
76   /** @return  */
77   virtual Bool_t DoITS()         const = 0;
78   /** @return  */
79   virtual Bool_t DoITSsaTracks() const = 0;
80   /** @return  */
81   virtual Bool_t DoITSalign()    const = 0;
82   /** @return  */
83   virtual Bool_t DoCALO()        const = 0;
84   /** @return  */
85   virtual Bool_t DoMUONTrig()    const = 0;
86   /** @return  */
87   virtual Bool_t DoImpParRes()   const = 0;
88   /** @return  */
89   virtual Bool_t DoMUON()        const = 0;
90   /** @return  */
91   virtual Bool_t DoTOF()         const = 0;
92   /** @return  */
93   virtual Bool_t DoHMPID()       const = 0;
94   /** @return  */
95   virtual Bool_t DoT0()          const = 0;
96   /** @return  */
97   virtual Bool_t DoZDC()         const = 0;
98   /** @return  */
99   virtual Bool_t DoPIDResponse() const = 0;
100   /** @return  */
101   virtual Bool_t DoPIDqa()       const = 0;
102   /** @return  */
103   virtual Bool_t DoFWD()         const = 0;
104   /** @return  */
105   virtual Bool_t DoPHOS()        const = 0;
106   /** @return  */
107   virtual Bool_t DoPHOSTrig()    const = 0;
108   /** @return  */
109   virtual Bool_t DoEMCAL()       const = 0;
110   /** @return  */
111   virtual Bool_t DoFBFqa()       const = 0;
112   /** @return  NEEDS geometry */
113   virtual Bool_t DoMUONEff()     const = 0;
114   /** @return  NEEDS MCtruth  */
115   virtual Bool_t DoV0()          const = 0;
116   /** @return Get Debug level */
117   virtual Int_t DebugLevel() const = 0;
118
119   virtual void PrintOne(const char* title, Bool_t use) const 
120   {
121     Printf("%-30s : %3s", title, use ? "yes" : "no");
122   }
123   virtual void Print() const 
124   {
125     PrintOne("CDBconnect ",             DoCDBconnect());
126     PrintOne("EventStat ",              DoEventStat());
127     PrintOne("Centrality ",             DoCentrality());
128     PrintOne("QAsym ",                  DoQAsym());
129     PrintOne("VZERO",                   DoVZERO());
130     PrintOne("VZEROPbPb ",              DoVZEROPbPb());
131     PrintOne("Vertex ",                 DoVertex());
132     PrintOne("SPD  needs RP   ",        DoSPD());
133     PrintOne("TPC ",                    DoTPC());
134     PrintOne("HLT ",                    DoHLT());
135     PrintOne("SDD  needs RP",           DoSDD());
136     PrintOne("SSDdEdx ",                DoSSDdEdx());
137     PrintOne("TRD ",                    DoTRD());
138     PrintOne("ITS ",                    DoITS());
139     PrintOne("ITSsaTracks ",            DoITSsaTracks());
140     PrintOne("ITSalign ",               DoITSalign());
141     PrintOne("CALO ",                   DoCALO());
142     PrintOne("MUONTrig ",               DoMUONTrig());
143     PrintOne("ImpParRes ",              DoImpParRes());
144     PrintOne("MUON ",                   DoMUON());
145     PrintOne("TOF ",                    DoTOF());
146     PrintOne("HMPID ",                  DoHMPID());
147     PrintOne("T0 ",                     DoT0());
148     PrintOne("ZDC ",                    DoZDC());
149     PrintOne("PIDResponse ",            DoPIDResponse());
150     PrintOne("PIDqa ",                  DoPIDqa());
151     PrintOne("FWD ",                    DoFWD());
152     PrintOne("PHOS ",                   DoPHOS());
153     PrintOne("PHOSTrig ",               DoPHOSTrig());
154     PrintOne("EMCAL ",                  DoEMCAL());
155     PrintOne("FBFqa ",                  DoFBFqa());
156     PrintOne("MUONEff NEEDS geometry",  DoMUONEff());
157     PrintOne("V0  NEEDS MCtruth ",      DoV0());
158   }
159 };
160 VirtualQACfg* qaCfg = 0;
161
162 //====================================================================
163 /** 
164  * Load the needed libraries 
165  * 
166  */
167 void LoadLibraries()
168 {
169   Bool_t is10h = grp->period.EqualTo("LHC10h",TString::kIgnoreCase);
170   gSystem->SetIncludePath("-I. " 
171                         "-I$ROOTSYS/include " 
172                         "-I$ALICE_ROOT/include " 
173                         "-I$ALICE_ROOT " 
174                         "-I$ALICE_ROOT/ITS " 
175                         "-I$ALICE_ROOT/TRD " 
176                         "-I$ALICE_ROOT/PWGPP " 
177                         "-I$ALICE_ROOT/PWGPP/TRD");
178   gSystem->Load("libANALYSIS");
179   gSystem->Load("libANALYSISalice");
180   gSystem->Load("libOADB");
181   gSystem->Load("libESDfilter.so");
182   gSystem->Load("libCORRFW");
183   gSystem->Load("libTender");
184   gSystem->Load("libPWGPP.so");
185   gSystem->Load("libAliHLTTrigger.so");
186
187   if ((qaCfg->DoEMCAL() && detCfg->UseEMCAL()) || 
188       ((qaCfg->DoPHOS() || qaCfg->DoPHOSTrig())  && detCfg->UsePHOS()) || 
189       (qaCfg->DoCALO() && !is10h)) {
190     gSystem->Load("libEMCALUtils");
191     gSystem->Load("libPHOSUtils");
192     gSystem->Load("libPWGCaloTrackCorrBase");
193     gSystem->Load("libPWGGACaloTrackCorrelations");
194     gSystem->Load("libPWGGACaloTasks");
195     gSystem->Load("libPWGGAPHOSTasks");
196     gSystem->Load("libPWGTools");
197     gSystem->Load("libPWGEMCAL");
198     gSystem->Load("libPWGGAEMCALTasks");
199   }  
200   if((qaCfg->DoMUON() || qaCfg->DoMUONTrig()) && detCfg->UseMUON()) {
201     gSystem->Load("libPWGmuon");
202     gSystem->Load("libPWGPPMUONlite");
203     gSystem->Load("libPWGmuondep");
204   }
205   if (qaCfg->DoFWD() && detCfg->UseFMD()) {
206     gSystem->Load("libPWGLFforward2");
207   }      
208 }
209  
210 //====================================================================
211 /** 
212  * Add the analysis tasks 
213  * 
214  * @param cdb_location 
215  */
216 void AddAnalysisTasks(const char *cdb_location)
217 {
218   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
219   mgr->SetCommonFileName("QAresults.root");
220
221   Bool_t is10h = grp->period.EqualTo("LHC10h",TString::kIgnoreCase);
222   // --- Some short-hands --------------------------------------------
223   TString ali   = "$ALICE_ROOT";
224   TString ana   = ali + "/ANALYSIS";
225   TString pwghf = ali + "/PWGHF";
226   TString pwglf = ali + "/PWGLF";
227   TString pwgje = ali + "/PWGJE";
228   TString pwgdq = ali + "/PWGDQ";
229   TString pwgpp = ali + "/PWGPP";
230   TString pwgga = ali + "/PWGGA";
231   
232   // --- Statistics task ---------------------------------------------
233   mgr->AddStatisticsTask(kTriggerMask);
234
235   // --- CDB connection ----------------------------------------------
236   if (qaCfg->DoCDBconnect()) {
237     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskCDBconnect.C");
238     AliTaskCDBconnect *taskCDB = AddTaskCDBconnect(cdb_location, grp->run);
239     if (!taskCDB) return;
240   }    
241   
242   // --- Event Statistics (Jan Fiete) --------------------------------
243   if (qaCfg->DoEventStat()) {
244     gROOT->LoadMacro(ana+"/macros/AddTaskPhysicsSelection.C");
245     AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection(kTRUE/*MC*/);
246     // Hack by Alexander for LHC10h
247     // gROOT->LoadMacro("LHC10hPS.C");
248     // AliOADBPhysicsSelection* ops = LHC10hPS(grp->period, grp->run);
249     // if (ops) 
250     //   physSelTask->GetPhysicsSelection()->SetCustomOADBObjects(ops,0);
251   }
252   // --- PIDResponse(JENS) -------------------------------------------
253   if (qaCfg->DoPIDResponse() && !is10h) {
254     gROOT->LoadMacro(ana+"/macros/AddTaskPIDResponse.C"); 
255     AliAnalysisTaskPIDResponse *PIDResponse = AddTaskPIDResponse(kTRUE);
256     PIDResponse->SelectCollisionCandidates(kTriggerMask);
257   }    
258   // --- Centrality (A. Toia) ----------------------------------------
259   if (qaCfg->DoCentrality()) {
260     gROOT->LoadMacro(ana+"/macros/AddTaskCentrality.C");
261     AliCentralitySelectionTask *taskCentrality = AddTaskCentrality();
262     taskCentrality->SetMCInput();        
263   }   
264   
265   // --- Vertexing (A. Dainese) --------------------------------------
266   if (qaCfg->DoVertex()) {
267     gROOT->LoadMacro(pwgpp+"/macros/AddTaskVertexESD.C");
268     // Specific setting for MC
269     AliAnalysisTaskVertexESD* taskvertexesd =  
270       AddTaskVertexESD(kTRUE, kTriggerMask);
271     taskvertexesd->SelectCollisionCandidates(kTriggerMask);
272   }  
273
274   // --- TPC QA (E. Sicking) -----------------------------------------
275   if (qaCfg->DoQAsym()) {
276   // offline trigger in AddTask
277     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskQAsym.C");
278     AliAnalysisTaskSE * taskqasim = AddTaskQAsym(0, 
279                                                  kTriggerMask, 
280                                                  kTriggerHM, 
281                                                  kTriggerEMC, 
282                                                  kTriggerMuonBarell);
283   }  
284   // --- VZERO QA  (C. Cheshkov) -------------------------------------
285   if (qaCfg->DoVZERO() && detCfg->UseVZERO()) {
286     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskVZEROQA.C");
287     AliAnalysisTaskSE * taskv0qa = AddTaskVZEROQA(0);
288   }
289   if (qaCfg->DoVZEROPbPb() && detCfg->UseVZERO() && grp->IsAA()) {
290     gROOT->LoadMacro(pwgpp+"/VZERO/AddTaskVZEROPbPb.C");
291     AliAnaVZEROPbPb* taskV0PbPb = 
292       (AliAnaVZEROPbPb*)AddTaskVZEROPbPb(Int_t(grp->run));
293   }
294   // --- TPC (Jacek Otwinowski & Michael Knichel) --------------------
295   //
296   //
297   // - Optionally MC information can be used by setting the 1st
298   //   argument to true
299   // - Optionally friends information can be switched off by setting
300   //   the 2st argument to false
301   // - Optionally highMult axis can be used by setting the 3st
302   //   argument to true (for PbPb)
303   if (qaCfg->DoTPC() && detCfg->UseTPC()) {
304     gROOT->LoadMacro(pwgpp+"/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
305     AliPerformanceTask *tpcQA = 0;
306     if (grp->IsAA()) {
307        // High multiplicity Pb-Pb
308        tpcQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, kTRUE);
309     } else {
310       // Low multiplicity (pp)
311        tpcQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, kFALSE);
312     }
313     tpcQA->SelectCollisionCandidates(kTriggerMask);
314     AliPerformanceRes::SetMergeEntriesCut(5000000); 
315   }  
316
317   // --- HLT (Alberica Toia) -----------------------------------------
318   if (qaCfg->DoHLT() && detCfg->UseTPC()) {
319     gROOT->LoadMacro(pwgpp+"/TPC/macros/AddTaskPerformanceTPCdEdxQA.C");
320     AliPerformanceTask *hltQA = AddTaskPerformanceTPCdEdxQA(kTRUE, kTRUE, 
321                                                             kFALSE,0,kTRUE);
322     hltQA->SelectCollisionCandidates(kTriggerMask);
323   }  
324   // --- SPD (A. Mastroserio) ----------------------------------------
325   if (qaCfg->DoSPD() && detCfg->UseITS()) {
326     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskSPDQA.C");
327     AliAnalysisTaskSPD* taskspdqa = (AliAnalysisTaskSPD*)AddTaskSPDQA();
328     // Request from Annalisa
329     if (grp->IsAA()) taskspdqa->SetHeavyIonMode();
330     taskspdqa->SelectCollisionCandidates(kTriggerMask);
331     taskspdqa->SetOCDBInfo(grp->run, "raw://");
332   }  
333   // --- SDD (F. Prino) ----------------------------------------------
334   if (qaCfg->DoSDD() && detCfg->UseITS()) {
335     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddSDDPoints.C");
336     AliAnalysisTaskSE* tasksdd = AddSDDPoints();
337     tasksdd->SelectCollisionCandidates(kTriggerMask);
338   }
339   // --- SSD dEdx (Marek Chojnacki) ----------------------------------
340   if (qaCfg->DoSSDdEdx() && detCfg->UseITS()) {
341     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskdEdxSSDQA.C");
342     AliAnalysisTaskSE* taskssddedx = AddTaskdEdxSSDQA();
343     taskssddedx->SelectCollisionCandidates(kTriggerMask);
344   }
345
346   // --- ITS ---------------------------------------------------------
347   if (qaCfg->DoITS() && detCfg->UseITS()) {
348     // hardcoded non-zero trigger mask
349     gROOT->LoadMacro(pwgpp+"/macros/AddTaskPerformanceITS.C");
350     AliAnalysisTaskITSTrackingCheck *itsQA = 0;
351     AliAnalysisTaskITSTrackingCheck *itsQACent0010 = 0;
352     AliAnalysisTaskITSTrackingCheck *itsQACent3050 = 0;
353     AliAnalysisTaskITSTrackingCheck *itsQACent6080 = 0;
354     if(grp->IsPP()) {
355       itsQA = AddTaskPerformanceITS(kTRUE);
356     } else {
357       itsQA = AddTaskPerformanceITS(kTRUE);
358       itsQACent0010 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,3500,10000);
359       itsQACent3050 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,590,1570);
360       itsQACent6080 = AddTaskPerformanceITS(kTRUE,kFALSE,kFALSE,70,310);
361     }
362   }
363   // --- ITS saTracks, align (F.Prino) -------------------------------
364   if (qaCfg->DoITSsaTracks() && detCfg->UseITS()) {
365     // offline trigger in AddTask
366     gROOT->LoadMacro(pwgpp+"/macros/AddTaskITSsaTracks.C");
367     AliAnalysisTaskITSsaTracks *itssaTracks = AddTaskITSsaTracks(kTRUE,kFALSE);
368     itssaTracks->SelectCollisionCandidates(kTriggerMask);
369   }   
370   if (qaCfg->DoITSalign() && detCfg->UseITS()) {
371     // no offline trigger selection
372      gROOT->LoadMacro(pwgpp+"/macros/AddTaskITSAlign.C");
373      AliAnalysisTaskITSAlignQA *itsAlign = AddTaskITSAlign(0,2011);
374   }   
375
376   // --- TRD (Alex Bercuci, M. Fasel) --------------------------------
377   if(qaCfg->DoTRD() && detCfg->UseTRD()) {
378     // no offline trigger selection
379     gROOT->LoadMacro(pwgpp+"/macros/AddTrainPerformanceTRD.C");
380     // steer individual TRD tasks
381     Bool_t 
382       doCheckESD(kTRUE),  // AliTRDcheckESD
383       doCheckDET(kTRUE),  // AliTRDcheckDET
384       doEffic(kTRUE),     // AliTRDefficiency
385       doResolution(kTRUE),// AliTRDresolution
386       doCheckPID(kTRUE),  // AliTRDcheckPID
387       doV0Monitor(kFALSE);// AliTRDv0Monitor
388     AddTrainPerformanceTRD(Translate(doCheckESD, doCheckDET, doEffic, 
389                                      doResolution, doCheckPID, doV0Monitor));
390   }
391
392   // --- ZDC (Chiara Oppedisano) -------------------------------------
393   if(qaCfg->DoZDC() && detCfg->UseZDC()) {
394     // hardcoded kMB trigger mask
395      gROOT->LoadMacro(pwgpp+"/ZDC/AddTaskZDCQA.C");
396      AliAnalysisTaskSE *taskZDC = AddTaskZDCQA();
397      taskZDC->SelectCollisionCandidates(kTriggerMask);
398   }   
399
400   // --- Calorimetry (Gustavo Conesa) --------------------------------
401   if(qaCfg->DoCALO() && !is10h) {
402     gROOT->LoadMacro(pwgga+
403                      "/CaloTrackCorrelations/macros/QA/AddTaskCalorimeterQA.C");
404     AliAnalysisTaskCaloTrackCorrelation *taskCaloQA = 
405       AddTaskCalorimeterQA("default");
406     taskCaloQA->SetDebugLevel(0);
407     // offline mask set in AddTask to kMB
408     taskCaloQA->SelectCollisionCandidates(kTriggerMask);
409     // Add a new calo task with EMC1 trigger only
410     if (!is10h) {
411       taskCaloQA = AddTaskCalorimeterQA("trigEMC");
412       taskCaloQA->SetDebugLevel(0);
413       taskCaloQA->SelectCollisionCandidates(kTriggerEMC);
414     }
415   }
416
417   // --- Muon Trigger ------------------------------------------------
418   if(qaCfg->DoMUONTrig() && detCfg->UseMUON()) {
419     // no offline trigger selection
420     gROOT->LoadMacro(pwgpp+"/macros/AddTaskMTRchamberEfficiency.C");
421     AliAnalysisTaskTrigChEff *taskMuonTrig = AddTaskMTRchamberEfficiency();
422   }
423
424   // --- Muon Efficiency (not used) ----------------------------------
425   if(qaCfg->DoMUONEff() && detCfg->UseMUON()) {
426       gROOT->LoadMacro(ali+"/PWG3/muondep/AddTaskMUONTrackingEfficiency.C");
427       AliAnalysisTaskMuonTrackingEff *taskMuonTrackEff = 
428         AddTaskMUONTrackingEfficiency();
429   }
430   
431   // --- V0-Decay Reconstruction (Ana Marin) (not used) --------------
432   if (qaCfg->DoV0()) {
433     gROOT->LoadMacro(pwgpp+"/macros/AddTaskV0QA.C");
434     AliAnalysisTaskV0QA *taskv0QA = AddTaskV0QA(kTRUE);
435   }
436   
437   // -- Impact parameter resolution ----------------------------------
438   // (xianbao.yuan@pd.infn.it, andrea.dainese@pd.infn.it)
439   if (qaCfg->DoImpParRes()) {
440     gROOT->LoadMacro(pwgpp+"/macros/AddTaskImpParRes.C");
441     AliAnalysisTaskSE* taskimpparres=0;
442     // Specific setting for MC
443     if(grp->IsPP()) {
444       taskimpparres= AddTaskImpParRes(kTRUE);
445     } else {
446       taskimpparres= AddTaskImpParRes(kTRUE,-1,kTRUE,kFALSE);
447     }
448     taskimpparres->SelectCollisionCandidates(kTriggerMask);
449   }  
450
451   // --- MUON QA (Philippe Pillot) -----------------------------------
452   if (qaCfg->DoMUON() && detCfg->UseMUON()) {
453     // trigger analysis internal
454     gROOT->LoadMacro(pwgpp+"/PilotTrain/AddTaskMuonQA.C");
455     AliAnalysisTaskSE* taskmuonqa= AddTaskMuonQA();
456   }  
457
458   // --- TOF (Francesca Bellini) -------------------------------------
459   if (qaCfg->DoTOF() && detCfg->UseTOF()) {
460     gROOT->LoadMacro(pwgpp+"/TOF/AddTaskTOFQA.C");
461     AliAnalysisTaskTOFqa *tofQA = AddTaskTOFQA(kFALSE);
462     tofQA->SelectCollisionCandidates(kTriggerMask);
463   } 
464
465   // --- PIDqa(JENS) -------------------------------------------------
466   if (qaCfg->DoPIDqa() && !is10h) {
467     gROOT->LoadMacro(ana+"/macros/AddTaskPIDqa.C");
468     AliAnalysisTaskPIDqa *PIDQA = AddTaskPIDqa();
469     PIDQA->SelectCollisionCandidates(kTriggerMask);
470   }  
471  
472   // --- HMPID QA (Giacomo Volpe) ------------------------------------
473   //
474   if (qaCfg->DoHMPID() && detCfg->UseHMPID()) {
475     gROOT->LoadMacro(pwgpp+"/HMPID/AddTaskHmpidQA.C");
476     AliAnalysisTaskSE* taskhmpidqa= AddTaskHmpidQA(kTRUE);
477     // offline mask set in AddTask to kMB
478     taskhmpidqa->SelectCollisionCandidates(kTriggerMask);
479   }      
480
481   // --- T0 QA (Alla Mayevskaya) -------------------------------------
482   if (qaCfg->DoT0() && detCfg->UseT0()) {
483     // no offline trigger selection
484     gROOT->LoadMacro(pwgpp+"/T0/AddTaskT0QA.C");
485     AliT0AnalysisTaskQA* taskt0qa= AddTaskT0QA();
486     taskt0qa->SelectCollisionCandidates(kTriggerMask);
487   }      
488
489   // ---- FMD QA (Christian Holm Christiansen) -----------------------
490   if (qaCfg->DoFWD() && detCfg->UseFMD()) {
491     gROOT->LoadMacro(pwglf+"/FORWARD/analysis2/AddTaskForwardQA.C");
492     // Parameters: usemc, usecentrality
493     // AliAnalysisTaskSE *forwardQA = (AliAnalysisTaskSE *)
494     AddTaskForwardQA(kTRUE, qaCfg->DoCentrality());
495     // HACK: to read corrections from current directory
496     const char* hack="AliForwardCorrectionManager::Instance().SetPrefix(\".\")";
497     gROOT->ProcessLine(hack);
498     const char* hack2="AliForwardCorrectionManager::Instance().Print(\"R\")";
499     gROOT->ProcessLine(hack2);
500     // No offline trigger config. needed (see #84077)
501   }
502   
503   // --- PHOS QA (Boris Polishchuk) ----------------------------------
504   if (qaCfg->DoPHOS()&& detCfg->UsePHOS()) {
505     gROOT->LoadMacro(pwgga+"/PHOSTasks/CaloCellQA/macros/AddTaskCaloCellsQA.C");
506     AliAnalysisTaskCaloCellsQA *taskPHOSCellQA1 = 
507       AddTaskCaloCellsQA(4, 1, NULL,"PHOSCellsQA_AnyInt"); 
508     taskPHOSCellQA1->SelectCollisionCandidates(kTriggerMask);
509     taskPHOSCellQA1->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);
510
511     AliAnalysisTaskCaloCellsQA *taskPHOSCellQA2 = 
512       AddTaskCaloCellsQA(4, 1, NULL,"PHOSCellsQA_PHI7"); 
513     taskPHOSCellQA2->SelectCollisionCandidates(AliVEvent::kPHI7);
514     taskPHOSCellQA2->GetCaloCellsQA()->SetClusterEnergyCuts(0.3,0.3,1.0);
515
516     // Pi0 QA fo PbPb
517     if (grp->IsAA()) {
518       gROOT->LoadMacro(pwgga+"/PHOSTasks/PHOS_PbPbQA/macros/AddTaskPHOSPbPb.C");
519       AliAnalysisTaskPHOSPbPbQA* phosPbPb = AddTaskPHOSPbPbQA(0);
520     }
521   }
522   if (qaCfg->DoPHOSTrig() && detCfg->UsePHOS()) {
523     gROOT->LoadMacro(pwgga+
524                      "/PHOSTasks/PHOS_TriggerQA/macros/AddTaskPHOSTriggerQA.C");
525     AliAnalysisTaskPHOSTriggerQA *taskPHOSTrig = AddTaskPHOSTriggerQA(0,0);
526   }   
527
528   // --- EMCAL QA (Gustavo Conesa) -----------------------------------
529   if (qaCfg->DoEMCAL() && detCfg->UseEMCAL()) {
530      gROOT->LoadMacro(pwgga+"/EMCALTasks/macros/AddTaskEMCALTriggerQA.C");
531      AliAnalysisTaskEMCALTriggerQA *emctrig = AddTaskEMCALTriggerQA();
532   }   
533
534   // --- FLOW and BF QA (C.Perez && A.Rodriguez) ---------------------
535   if (qaCfg->DoFBFqa()) {
536     gROOT->LoadMacro(pwgpp+"/macros/AddTaskFBFqa.C");
537     AliAnalysisTaskSE *qaFBFMB = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFmb",
538                                                                   kFALSE);
539     qaFBFMB->SelectCollisionCandidates(AliVEvent::kMB);
540     AliAnalysisTaskSE *qaFBFSC = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFsc",
541                                                                   kFALSE);
542     qaFBFSC->SelectCollisionCandidates(AliVEvent::kSemiCentral);
543     AliAnalysisTaskSE *qaFBFCE = (AliAnalysisTaskSE*)AddTaskFBFqa("qaFBFce",
544                                                                   kFALSE);
545     qaFBFCE->SelectCollisionCandidates(AliVEvent::kCentral);
546   }
547 }
548 /** 
549  * Helper function to make @c outputs_valid file 
550  * 
551  */
552 void ValidateOutput()
553 {
554   std::ofstream out;
555   out.open("outputs_valid", ios::out);
556   out.close();    
557 }  
558
559 //====================================================================
560 /** 
561  * Run QA merging 
562  * 
563  * @param dir      directory 
564  * @param stage    stage 
565  */
566 void QAMerge(const char *dir, Int_t stage)
567 {
568 // Merging method
569   TStopwatch  timer;     timer.Start();
570   TString     outputDir     = dir;
571   TObjArray   outputFiles;
572   outputFiles.Add(new TObjString("QAresults.root"));
573   outputFiles.Add(new TObjString("EventStat_temp.root"));
574
575   TString     mergeExcludes = "";
576   TIter       iter(&outputFiles);
577   TObjString* str           = 0;
578   Bool_t      merged        = kTRUE;
579   while((str = static_cast<TObjString*>(iter()))) {
580     TString& outputFile = str->GetString();
581     // Skip already merged outputs
582     if (!gSystem->AccessPathName(outputFile)) {
583       ::Warning("Merge","Output file <%s> found. Not merging again.",
584                 outputFile.Data());
585       continue;
586     }
587     if (mergeExcludes.Contains(outputFile.Data())) continue;
588     merged = AliAnalysisAlien::MergeOutput(outputFile, 
589                                            outputDir, 
590                                            10, 
591                                            stage);
592     if (!merged) {
593       ::Error("Merge", "Cannot merge %s\n", outputFile.Data());
594       continue;
595     }
596   }
597   TString infolog = "fileinfo.log";
598   AliAnalysisAlien::MergeInfo(infolog, dir); 
599
600   if (!outputDir.Contains("Stage")) {
601     ValidateOutput();
602     timer.Print();
603     return;
604   }
605   // --- Set up to run terminate -------------------------------------
606   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
607   mgr->SetSkipTerminate(kFALSE);
608   if (!mgr->InitAnalysis()) return;
609
610   mgr->PrintStatus();
611   mgr->StartAnalysis("gridterminate", (TTree*)0);
612   ValidateOutput();
613   timer.Print();
614 }
615
616 //====================================================================
617 /** 
618  * Run QA trains 
619  * 
620  * @param run         Run number 
621  * @param xmlfile     Collection file 
622  * @param stage       Stage 
623  * @param cdb         CDB location 
624  */
625 void QA(UInt_t      run, 
626         const char* xmlfile   = "wn.xml",
627         Int_t       stage     = 0, /*0 = QA train, 1...n - merging stage*/
628         const char* cdb       = "raw://")
629 {
630   // -----------------------------------------------------------------
631   // 
632   // Get GRP parameters.  Defines global "grp" as a pointer to GRPData
633   //
634   gROOT->Macro(Form("GRP.C(%d)", run));
635   gROOT->Macro("BaseConfig.C");
636   gROOT->Macro("QAConfig.C");
637   gROOT->Macro("DetConfig.C");
638   qaCfg->Print();
639   Int_t   debug_level = qaCfg->DebugLevel();   // Debugging
640   TString cdbString(cdb);
641   if (cdbString.Contains("raw://")) {
642     TGrid::Connect("alien://");
643     if (!gGrid || !gGrid->IsConnected()) {
644       ::Error("QAtrain", "No grid connection");
645       return;
646     }  
647   }  
648
649   // --- Some settings -----------------------------------------------
650   // Set temporary merging directory to current one
651   gSystem->Setenv("TMPDIR", gSystem->pwd());
652   // Set temporary compilation directory to current one
653   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
654   // Load common libraries and set include path
655   LoadLibraries();
656   printf("Include path: %s\n", gSystem->GetIncludePath());
657
658   // === Make the analysis manager and connect event handlers ========
659   // 
660   // --- Analysis manager and load libraries -------------------------
661   AliAnalysisManager *mgr  = new AliAnalysisManager("QA", "Production train");
662   mgr->SetRunFromPath(grp->run);
663
664   // --- Create ESD input handler ------------------------------------
665   AliESDInputHandlerRP *esdHandler = new AliESDInputHandlerRP();
666   esdHandler->SetReadFriends(kTRUE);
667   esdHandler->SetActiveBranches("ESDfriend");
668   mgr->SetInputEventHandler(esdHandler);
669   
670   // --- Monte Carlo handler -----------------------------------------
671   if (true) {
672     AliMCEventHandler* mcHandler = new AliMCEventHandler();
673     mgr->SetMCtruthEventHandler(mcHandler);
674     mcHandler->SetPreReadMode(1);
675     mcHandler->SetReadTR(true);
676   }
677
678   // === Set up tasks ================================================
679   //
680   // --- Create tasks ------------------------------------------------
681   AddAnalysisTasks(cdb);
682
683   // --- Debugging if needed -----------------------------------------
684   if (debug_level > 0) mgr->SetDebugLevel(debug_level);
685
686   // --- If merging, do so here and exit -----------------------------
687   if (stage>0) {
688     QAMerge(xmlfile, stage);
689     return;
690   }   
691
692   // === Run the analysis ============================================
693   //
694   // --- Make our chain ----------------------------------------------
695   TChain *chain = new TChain("esdTree");
696   chain->Add("AliESDs.root");
697
698   // --- Run the thing -----------------------------------------------
699   TStopwatch timer;
700   timer.Start();
701   if (!mgr->InitAnalysis()) return;
702
703   mgr->PrintStatus(); 
704   mgr->SetSkipTerminate(kTRUE);
705   mgr->SetNSysInfo(1);
706   mgr->StartAnalysis("local", chain);
707   timer.Print();
708 }
709
710 // 
711 // EOF
712 // 
713