]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGJE/EMCALJetTasks/UserTasks/AliAnalysisTaskQualityAssurancePA.cxx
update from Ruediger
[u/mrichter/AliRoot.git] / PWGJE / EMCALJetTasks / UserTasks / AliAnalysisTaskQualityAssurancePA.cxx
1 #ifndef ALIANALYSISTASKSE_H
2 #include <Riostream.h>
3 #include <TROOT.h>
4 #include <TString.h>
5 #include <TFile.h>
6 #include <TCint.h>
7 #include <TChain.h>
8 #include <TTree.h>
9 #include <TKey.h>
10 #include <TProfile.h>
11 #include <TH1F.h>
12 #include <TH2F.h>
13 #include <TCanvas.h>
14 #include <TList.h>
15 #include <TClonesArray.h>
16 #include <TObject.h>
17 #include <TMath.h>
18 #include <TSystem.h>
19 #include <TInterpreter.h>
20 #include <TH1.h>
21 #include "AliAnalysisTask.h"
22 #include "AliCentrality.h"
23 #include "AliStack.h"
24 #include "AliESDEvent.h"
25 #include "AliESDInputHandler.h"
26 #include "AliAODEvent.h"
27 #include "AliAODHandler.h"
28 #include "AliAnalysisManager.h"
29 #include "AliAnalysisTaskSE.h"
30 #endif
31
32 #include <TRandom3.h>
33 #include "AliGenPythiaEventHeader.h"
34 #include "AliMCEvent.h"
35 #include "AliLog.h"
36 #include <AliEmcalJet.h>
37 #include <AliRhoParameter.h>
38 #include "AliVEventHandler.h"
39 #include "AliVParticle.h"
40 #include "AliAnalysisUtils.h"
41
42 #include "AliAnalysisTaskQualityAssurancePA.h"
43
44
45 //TODO: FillHistogram can be done better with virtual TH1(?)
46 ClassImp(AliAnalysisTaskQualityAssurancePA)
47
48 // ######################################################################################## DEFINE HISTOGRAMS
49 void AliAnalysisTaskQualityAssurancePA::Init()
50 {
51   #ifdef DEBUGMODE
52     AliInfo("Creating histograms.");
53   #endif
54   *fRunNumbers = *fRunNumbers + " ALL";
55    
56   TObjArray* runNumberArr = fRunNumbers->Tokenize(" ");
57
58   for(Int_t i=0; i<runNumberArr->GetEntries();i++)
59   {
60     const char* tmpRunNum = (static_cast<TObjString*>(runNumberArr->At(i)))->String().Data();
61     
62     // NOTE: Track & Cluster & QA histograms
63     if (fAnalyzeQA)
64     {
65       AddHistogram1D<TH1D>(tmpRunNum, "hNumberEvents", "Number of events (0 = before, 1 = after vertex cuts)", "", 2, 0, 2, "#Delta z(cm)","N^{Events}/cut");
66       AddHistogram1D<TH1D>(tmpRunNum, "hVertexX", "X distribution of the vertex", "", 10000, -1., 1., "#Delta x(cm)","dN^{Events}/dx");
67       AddHistogram1D<TH1D>(tmpRunNum, "hVertexY", "Y distribution of the vertex", "", 10000, -1., 1., "#Delta y(cm)","dN^{Events}/dy");
68       AddHistogram2D<TH2D>(tmpRunNum, "hVertexXY", "XY distribution of the vertex", "COLZ", 1000, -1., 1., 1000, -1., 1.,"#Delta x(cm)", "#Delta y(cm)","dN^{Events}/dxdy");
69       AddHistogram1D<TH1D>(tmpRunNum, "hVertexZ", "Z distribution of the vertex", "", 400, -40., 40., "#Delta z(cm)","dN^{Events}/dz");
70       AddHistogram1D<TH1D>(tmpRunNum, "hVertexR", "R distribution of the vertex", "", 100, 0., 1., "#Delta r(cm)","dN^{Events}/dr");
71       AddHistogram1D<TH1D>(tmpRunNum, "hCentralityV0M", "Centrality distribution V0M", "", 100, 0., 100., "Centrality","dN^{Events}");
72       AddHistogram1D<TH1D>(tmpRunNum, "hCentralityV0A", "Centrality distribution V0A", "", 100, 0., 100., "Centrality","dN^{Events}");
73       AddHistogram1D<TH1D>(tmpRunNum, "hCentralityV0C", "Centrality distribution V0C", "", 100, 0., 100., "Centrality","dN^{Events}");
74
75       AddHistogram2D<TH2D>(tmpRunNum, "hTrackCountAcc", "Number of tracks in acceptance vs. centrality", "LEGO2", 750, 0., 750., 100, 0, 100, "N tracks","Centrality", "dN^{Events}/dN^{Tracks}");
76       AddHistogram1D<TH1D>(tmpRunNum, "hTrackPt", "Tracks p_{T} distribution", "", 20000, 0., 400., "p_{T} (GeV/c)","dN^{Tracks}/dp_{T}");
77       AddHistogram1D<TH1D>(tmpRunNum, "hTrackPtNegEta", "Tracks p_{T} distribution (negative #eta)", "", 2000, 0., 400., "p_{T} (GeV/c)","dN^{Tracks}/dp_{T}");
78       AddHistogram1D<TH1D>(tmpRunNum, "hTrackPtPosEta", "Tracks p_{T} distribution (positive #eta)", "", 2000, 0., 400., "p_{T} (GeV/c)","dN^{Tracks}/dp_{T}");      
79       AddHistogram1D<TH1D>(tmpRunNum, "hTrackCharge", "Charge", "", 11, -5, 5, "Charge (e)","dN^{Tracks}/dq");
80       AddHistogram1D<TH1D>(tmpRunNum, "hTrackPhi", "Track #phi distribution", "", 360, 0, TMath::TwoPi(), "#phi","dN^{Tracks}/d#phi");
81       AddHistogram2D<TH2D>(tmpRunNum, "hTrackPhiEta", "Track angular distribution", "LEGO2", 100, 0., 2*TMath::Pi(),100, -2.5, 2.5, "#phi","#eta","dN^{Tracks}/(d#phi d#eta)");
82
83       AddHistogram2D<TH2D>(tmpRunNum, "hTrackPhiPtCut", "Track #phi distribution for different pT cuts", "LEGO2", 360, 0, TMath::TwoPi(), 20, 0, 20, "#phi", "p_{T} lower cut", "dN^{Tracks}/d#phi dp_{T}");      
84       AddHistogram2D<TH2D>(tmpRunNum, "hTrackPhiLabel", "Track #phi distribution in different labels", "LEGO2", 360, 0, TMath::TwoPi(), 3, 0, 3, "#phi", "Label", "dN^{Tracks}/d#phi");
85       AddHistogram1D<TH1D>(tmpRunNum, "hTrackEta", "Track #eta distribution", "", 180, -fTrackEtaWindow, +fTrackEtaWindow, "#eta","dN^{Tracks}/d#eta");
86     }
87
88     // NOTE: Pythia histograms
89     if (fAnalyzePythia)
90     {
91       AddHistogram1D<TH1D>(tmpRunNum, "hPythiaPtHard", "Pythia p_{T} hard distribution", "", 2000, 0, 400, "p_{T} hard","dN^{Events}/dp_{T,hard}");
92       AddHistogram1D<TProfile>(tmpRunNum, "hPythiaXSection", "Pythia cross section distribution", "", fNumPtHardBins, 0, fNumPtHardBins, "p_{T} hard bin","dN^{Events}/dp_{T,hard}");
93       AddHistogram1D<TH1D>(tmpRunNum, "hPythiaNTrials", "Pythia trials (no correction for manual cuts)", "", fNumPtHardBins, 0, fNumPtHardBins, "p_{T} hard bin", "Trials");
94     }
95
96     // NOTE: Jet histograms
97     if (fAnalyzeJets)
98     {
99       // ######## Jet spectra
100       AddHistogram1D<TH1D>(tmpRunNum, "hJetPt", "Jets p_{T} distribution", "", 1000, 0., 200., "p_{T} (GeV/c)","dN^{Jets}/dp_{T}");
101       AddHistogram1D<TH1D>(tmpRunNum, "hJetArea", "Jets area distribution", "", 200, 0., 2., "Area","dN^{Jets}/dA");
102       AddHistogram2D<TH2D>(tmpRunNum, "hJetAreaVsPt", "Jets area vs. p_{T} distribution", "COLZ", 200, 0., 2., 400, 0., 200., "Area", "p_{T}", "dN^{Jets}/dA dp_{T}");
103
104       AddHistogram2D<TH2D>(tmpRunNum, "hJetPhiEta", "Jets angular distribution", "LEGO2", 360, 0., 2*TMath::Pi(),100, -0.6, 0.6, "#phi","#eta","dN^{Jets}/(d#phi d#eta)");
105       AddHistogram2D<TH2D>(tmpRunNum, "hJetPtVsConstituentCount", "Jets number of constituents vs. jet p_{T}", "COLZ", 800, 0., 400., 100, 0., 100., "p_{T}","N^{Tracks}","dN^{Jets}/(dp_{T} dN^{tracks})");
106       AddHistogram1D<TH1D>(tmpRunNum, "hJetCountAll", "Number of Jets", "", 200, 0., 200., "N jets","dN^{Events}/dN^{Jets}");
107       AddHistogram1D<TH1D>(tmpRunNum, "hJetCountAccepted", "Number of accepted Jets", "", 200, 0., 200., "N jets","dN^{Events}/dN^{Jets}");
108
109     }
110   }
111   // register Histograms
112   for (Int_t i = 0; i < fHistCount; i++)
113   {
114     fOutputList->Add(fHistList->At(i));
115   }
116   
117   PostData(1,fOutputList); // important for merging
118
119 }
120
121
122 //________________________________________________________________________
123 AliAnalysisTaskQualityAssurancePA::AliAnalysisTaskQualityAssurancePA() : AliAnalysisTaskSE("AliAnalysisTaskQualityAssurancePA"), fOutputList(0), fAnalyzeQA(1), fAnalyzeJets(1), fAnalyzePythia(0), fHasTracks(0), fHasClusters(0), fHasJets(0), fIsMC(0), fJetArray(0), fTrackArray(0), fClusterArray(0), fJetArrayName(0), fTrackArrayName(0), fClusterArrayName(0), fRunNumbers(0), fNumPtHardBins(11), fSignalJetRadius(0.4), fNumberExcludedJets(2), fSignalJetEtaWindow(0.5), fTrackEtaWindow(0.9), fClusterEtaWindow(0.7), fVertexWindow(10.0), fVertexMaxR(1.0), fMinTrackPt(0.150), fMinClusterPt(0.300), fMinJetPt(1.0), fMinJetArea(0.4), fFirstLeadingJet(0), fSecondLeadingJet(0), fNumberSignalJets(0), fCrossSection(0.0), fTrials(0.0), fRandom(0), fHelperClass(0), fInitialized(0), fTaskInstanceCounter(0), fHistList(0), fHistCount(0)
124 {
125   // default constructor
126 }
127
128
129 //________________________________________________________________________
130 AliAnalysisTaskQualityAssurancePA::AliAnalysisTaskQualityAssurancePA(const char *name, const char* trackArrayName, const char* clusterArrayName, const char* jetArrayName) : AliAnalysisTaskSE(name), fOutputList(0), fAnalyzeQA(1), fAnalyzeJets(1), fAnalyzePythia(0), fHasTracks(0), fHasClusters(0), fHasJets(0), fIsMC(0), fJetArray(0), fTrackArray(0), fClusterArray(0), fJetArrayName(0), fTrackArrayName(0), fClusterArrayName(0), fRunNumbers(0), fNumPtHardBins(11), fSignalJetRadius(0.4), fNumberExcludedJets(2), fSignalJetEtaWindow(0.5), fTrackEtaWindow(0.9), fClusterEtaWindow(0.7), fVertexWindow(10.0), fVertexMaxR(1.0), fMinTrackPt(0.150), fMinClusterPt(0.300), fMinJetPt(1.0), fMinJetArea(0.4), fFirstLeadingJet(0), fSecondLeadingJet(0), fNumberSignalJets(0), fCrossSection(0.0), fTrials(0.0), fRandom(0), fHelperClass(0), fInitialized(0), fTaskInstanceCounter(0), fHistList(0), fHistCount(0)
131 {
132   #ifdef DEBUGMODE
133     AliInfo("Calling constructor.");
134   #endif
135
136   // Constructor
137   // Define input and output slots here (never in the dummy constructor)
138   // Input slot #0 works with a TChain - it is connected to the default input container
139   // Output slot #1 writes into a TH1 container
140   // Constructor
141
142   // Every instance of this task gets his own number
143   static Int_t instance = 0;
144   fTaskInstanceCounter = instance;
145   instance++;
146
147   fTrackArrayName = new TString(trackArrayName);
148   fClusterArrayName = new TString(clusterArrayName);
149   fRunNumbers = new TString("");
150   if (strcmp(fTrackArrayName->Data(),"") == 0)
151     fAnalyzeQA = kFALSE;
152   else
153   {
154     fAnalyzeQA = kTRUE;
155     if (fTrackArrayName->Contains("MCParticles")) //TODO: Hardcoded for now
156       fIsMC = kTRUE;
157   }
158
159   fJetArrayName = new TString(jetArrayName);
160   if (strcmp(fJetArrayName->Data(),"") == 0)
161     fAnalyzeJets = kFALSE;
162   else
163     fAnalyzeJets = kTRUE;
164
165   DefineOutput(1, TList::Class());
166  
167   fHistList = new TList();
168
169   #ifdef DEBUGMODE
170     AliInfo("Constructor done.");
171   #endif
172   
173 }
174
175 //________________________________________________________________________
176 inline Double_t AliAnalysisTaskQualityAssurancePA::GetPtHard()
177 {
178   Double_t tmpPtHard = -1.0;
179
180   if (!MCEvent())
181     AliError("MCEvent not accessible although demanded!");
182   else
183   {
184     AliGenPythiaEventHeader* pythiaHeader = dynamic_cast<AliGenPythiaEventHeader*>(MCEvent()->GenEventHeader());
185     if (!pythiaHeader)
186       AliError("Pythia Header not accessible!");
187     else
188       tmpPtHard = pythiaHeader->GetPtHard();
189   }
190   return tmpPtHard;
191 }
192
193 //________________________________________________________________________
194 inline Int_t AliAnalysisTaskQualityAssurancePA::GetPtHardBin()
195 {
196   // ########## PT HARD BIN EDGES
197   const Int_t localkPtHardLowerEdges[] = { 0, 5,11,21,36,57, 84,117,152,191,234};
198   const Int_t localkPtHardHigherEdges[] = { 5,11,21,36,57,84,117,152,191,234,1000000};
199
200   Int_t tmpPtHardBin = 0;
201   Double_t tmpPtHard = GetPtHard();
202  
203   for (tmpPtHardBin = 0; tmpPtHardBin <= fNumPtHardBins; tmpPtHardBin++)
204     if (tmpPtHard >= localkPtHardLowerEdges[tmpPtHardBin] && tmpPtHard < localkPtHardHigherEdges[tmpPtHardBin])
205       break;
206
207   return tmpPtHardBin;
208 }
209
210 //________________________________________________________________________
211 inline Bool_t AliAnalysisTaskQualityAssurancePA::IsTrackInAcceptance(AliVParticle* track)
212 {
213   if (track != 0)
214     if (TMath::Abs(track->Eta()) <= fTrackEtaWindow)
215       if (track->Pt() >= fMinTrackPt)
216         return kTRUE;
217
218   return kFALSE;
219 }
220
221 //________________________________________________________________________
222 inline Bool_t AliAnalysisTaskQualityAssurancePA::IsClusterInAcceptance(AliVCluster* cluster)
223 {
224   if (cluster != 0)
225  //   if (TMath::Abs(cluster->Eta()) <= fClusterEtaWindow)
226 //      if (cluster->Phi() <= 187.0/360.0 * TMath::TwoPi());
227 //        if (cluster->Phi() >= 80.0/360.0 * TMath::TwoPi());
228           if (cluster->E() >= fMinClusterPt)
229             return kTRUE;
230
231   return kFALSE;
232 }
233
234 //________________________________________________________________________
235 inline Bool_t AliAnalysisTaskQualityAssurancePA::IsSignalJetInAcceptance(AliEmcalJet *jet)
236 {   
237   if (jet != 0)
238     if (TMath::Abs(jet->Eta()) <= fSignalJetEtaWindow)
239       if (jet->Pt() >= fMinJetPt)
240         if (jet->Area() >= fMinJetArea)
241           return kTRUE;
242
243   return kFALSE;
244 }
245
246 //________________________________________________________________________
247 void AliAnalysisTaskQualityAssurancePA::ExecOnce()
248 {
249   #ifdef DEBUGMODE
250     AliInfo("Starting ExecOnce.");
251   #endif
252   fInitialized = kTRUE;
253
254   // Check for track array
255   if (strcmp(fTrackArrayName->Data(), "") != 0)
256   {
257     fTrackArray = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fTrackArrayName->Data()));
258     fHasTracks = kTRUE;
259     if (!fTrackArray) 
260     {
261       AliInfo(Form("%s: Could not retrieve tracks %s! This is OK, if tracks are not demanded.", GetName(), fTrackArrayName->Data())); 
262       fHasTracks = kFALSE;
263     } 
264     else
265     {
266       TClass *cl = fTrackArray->GetClass();
267       if (!cl->GetBaseClass("AliVParticle"))
268       {
269         AliError(Form("%s: Collection %s does not contain AliVParticle objects!", GetName(), fTrackArrayName->Data())); 
270         fTrackArray = 0;
271         fHasTracks = kFALSE;
272       }
273     }
274   }
275   // Check for cluster array
276   if (strcmp(fClusterArrayName->Data(), "") != 0)
277   {
278     fClusterArray = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fClusterArrayName->Data()));
279     fHasClusters = kTRUE;
280     if (!fClusterArray) 
281     {
282       AliInfo(Form("%s: Could not retrieve clusters %s! This is OK, if clusters are not demanded.", GetName(), fClusterArrayName->Data())); 
283       fHasClusters = kFALSE;
284     } 
285     else
286     {
287       TClass *cl = fClusterArray->GetClass();
288       if (!cl->GetBaseClass("AliVCluster"))
289       {
290         AliError(Form("%s: Collection %s does not contain AliVCluster objects!", GetName(), fClusterArrayName->Data())); 
291         fClusterArray = 0;
292         fHasClusters = kFALSE;
293       }
294     }
295   }
296
297   // Check for jet array
298   if (strcmp(fJetArrayName->Data(), "") != 0)
299   {
300     fJetArray = dynamic_cast<TClonesArray*>(InputEvent()->FindListObject(fJetArrayName->Data()));
301     fHasJets = kTRUE;
302
303     if (!fJetArray) 
304     {
305       AliInfo(Form("%s: Could not retrieve jets %s! This is OK, if jets are not demanded.", GetName(), fJetArrayName->Data())); 
306       fHasJets = kFALSE;
307     } 
308     else
309     {
310       if (!fJetArray->GetClass()->GetBaseClass("AliEmcalJet")) 
311       {
312         AliError(Form("%s: Collection %s does not contain AliEmcalJet objects!", GetName(), fJetArrayName->Data())); 
313         fJetArray = 0;
314         fHasJets = kFALSE;
315       }
316     }
317   }
318
319   // Look, if initialization is OK
320   if (!fHasTracks && fAnalyzeQA)
321   {
322     AliError(Form("%s: Tracks NOT successfully casted although demanded! Deactivating QA",GetName()));
323     fAnalyzeQA = kFALSE;
324   }
325   if (!fHasJets && fAnalyzeJets)
326   {
327     AliError(Form("%s: Jets NOT successfully casted although demanded!  Deactivating jet",GetName()));
328     fAnalyzeJets = kFALSE;
329   }
330
331   // Initialize helper class (for vertex selection)
332   fHelperClass = new AliAnalysisUtils();
333
334   // Histogram init
335   Init();
336
337   #ifdef DEBUGMODE
338     AliInfo("ExecOnce done.");
339   #endif
340
341 }
342
343 //________________________________________________________________________
344 void AliAnalysisTaskQualityAssurancePA::GetSignalJets()
345 {
346   // Reset vars
347   fFirstLeadingJet = NULL;
348   fSecondLeadingJet = NULL;
349   fNumberSignalJets = 0;
350
351   Float_t maxJetPts[] = {0, 0};
352   Int_t jetIDArray[]   = {-1, -1};
353   Int_t jetCount = fJetArray->GetEntries();
354
355   // Go through all jets and save signal jets and the two leading ones
356   for (Int_t i = 0; i < jetCount; i++)
357   {
358     AliEmcalJet* jet = static_cast<AliEmcalJet*>(fJetArray->At(i));
359     if (!jet)
360     {
361       AliError(Form("%s: Could not receive jet %d", GetName(), i));
362       continue;
363     }
364
365     if (!IsSignalJetInAcceptance(jet)) continue;
366     
367     if (jet->Pt() > maxJetPts[0]) 
368     {
369       maxJetPts[1] = maxJetPts[0];
370       jetIDArray[1] = jetIDArray[0];
371       maxJetPts[0] = jet->Pt();
372       jetIDArray[0] = i;
373     }
374     else if (jet->Pt() > maxJetPts[1]) 
375     {
376       maxJetPts[1] = jet->Pt();
377       jetIDArray[1] = i;
378     }
379     fSignalJets[fNumberSignalJets] = jet;
380     fNumberSignalJets++;
381   }
382   
383   if (fNumberSignalJets > 0)
384     fFirstLeadingJet  = static_cast<AliEmcalJet*>(fJetArray->At(jetIDArray[0]));
385   if (fNumberSignalJets > 1)
386     fSecondLeadingJet = static_cast<AliEmcalJet*>(fJetArray->At(jetIDArray[1]));
387
388 }
389
390 //________________________________________________________________________
391 Int_t AliAnalysisTaskQualityAssurancePA::GetLeadingJets(TClonesArray* jetArray, Int_t* jetIDArray)
392 {
393 // Writes first two leading jets into already registered array jetIDArray
394
395   if (!jetArray)
396   {
397     AliError("Could not get the jet array to get leading jets from it!");
398     return 0;
399   }
400
401   Float_t maxJetPts[] = {0, 0};
402   jetIDArray[0] = -1;
403   jetIDArray[1] = -1;
404
405   Int_t jetCount = jetArray->GetEntries();
406   Int_t jetCountAccepted = 0;
407
408   for (Int_t i = 0; i < jetCount; i++)
409   {
410     AliEmcalJet* jet = static_cast<AliEmcalJet*>(jetArray->At(i));
411     if (!jet) 
412     {
413       AliError(Form("%s: Could not receive jet %d", GetName(), i));
414       continue;
415     }
416
417     if (!IsSignalJetInAcceptance(jet)) continue;
418
419     if (jet->Pt() > maxJetPts[0]) 
420     {
421       maxJetPts[1] = maxJetPts[0];
422       jetIDArray[1] = jetIDArray[0];
423       maxJetPts[0] = jet->Pt();
424       jetIDArray[0] = i;
425     }
426     else if (jet->Pt() > maxJetPts[1]) 
427     {
428       maxJetPts[1] = jet->Pt();
429       jetIDArray[1] = i;
430     }
431     jetCountAccepted++;
432   }
433   return jetCountAccepted;
434 }
435
436
437 //________________________________________________________________________
438 void AliAnalysisTaskQualityAssurancePA::Calculate(AliVEvent* event)
439 {
440   #ifdef DEBUGMODE
441     AliInfo("Starting Calculate().");
442   #endif
443   ////////////////////// NOTE: initialization & casting
444
445   if (!event) {
446     AliError("??? Event pointer == 0 ???");
447     return;
448   }
449  
450   if (!fInitialized)
451     ExecOnce(); // Get tracks, jets from arrays if not already given + Init Histos
452   
453   // Get run number
454   TString tmpRunNum("");
455   tmpRunNum += event->GetRunNumber();
456   // Additional cuts
457   FillHistogram(tmpRunNum.Data(), "hNumberEvents", 0.5); // number of events before manual cuts
458   
459   if(!fHelperClass->IsVertexSelected2013pA(event))
460     return;
461
462   FillHistogram(tmpRunNum.Data(), "hNumberEvents", 1.5); // number of events after manual cuts
463
464   #ifdef DEBUGMODE
465     AliInfo("Calculate()::Init done.");
466   #endif
467
468   ////////////////////// NOTE: Get Centrality, (Leading)Signal jets
469
470   // Get centrality (V0A)
471   AliCentrality* tmpCentrality = NULL;
472   tmpCentrality = event->GetCentrality();
473   Double_t centralityPercentileV0A = 0.0;
474   Double_t centralityPercentileV0C = 0.0;
475   Double_t centralityPercentileV0M = 0.0;
476   if (tmpCentrality != NULL)
477   {
478     centralityPercentileV0A = tmpCentrality->GetCentralityPercentile("V0A");
479     centralityPercentileV0C = tmpCentrality->GetCentralityPercentile("V0C");
480     centralityPercentileV0M = tmpCentrality->GetCentralityPercentile("V0M");
481   }
482   // Get jets
483   if (fAnalyzeJets)
484     GetSignalJets();
485
486   #ifdef DEBUGMODE
487     AliInfo("Calculate()::Centrality&SignalJets done.");
488   #endif
489   ////////////////////// NOTE: Pythia histograms
490   if(fAnalyzePythia)
491   {
492     FillHistogram(tmpRunNum.Data(), "hPythiaPtHard", GetPtHard());
493     FillHistogram(tmpRunNum.Data(), "hPythiaNTrials", GetPtHardBin()+0.1, fTrials);
494     FillHistogram(tmpRunNum.Data(), "hPythiaXSection", GetPtHardBin()+0.1, fCrossSection);
495
496     #ifdef DEBUGMODE
497       AliInfo("Calculate()::Pythia done.");
498     #endif
499   }
500
501   ////////////////////// NOTE: Track & QA histograms
502
503   if (fAnalyzeQA)
504   {
505     FillHistogram(tmpRunNum.Data(), "hVertexX",event->GetPrimaryVertex()->GetX());
506     FillHistogram(tmpRunNum.Data(), "hVertexY",event->GetPrimaryVertex()->GetY());
507     FillHistogram(tmpRunNum.Data(), "hVertexXY",event->GetPrimaryVertex()->GetX(), event->GetPrimaryVertex()->GetY());
508     FillHistogram(tmpRunNum.Data(), "hVertexZ",event->GetPrimaryVertex()->GetZ());
509     FillHistogram(tmpRunNum.Data(), "hVertexR",TMath::Sqrt(event->GetPrimaryVertex()->GetX()*event->GetPrimaryVertex()->GetX() + event->GetPrimaryVertex()->GetY()*event->GetPrimaryVertex()->GetY()));
510     FillHistogram(tmpRunNum.Data(), "hCentralityV0M",centralityPercentileV0M);
511     FillHistogram(tmpRunNum.Data(), "hCentralityV0A",centralityPercentileV0A);
512     FillHistogram(tmpRunNum.Data(), "hCentralityV0C",centralityPercentileV0C);
513
514     Int_t trackCountAcc = 0;
515     Int_t nTracks = fTrackArray->GetEntries();
516     for (Int_t i = 0; i < nTracks; i++)
517     {
518       AliVTrack* track = static_cast<AliVTrack*>(fTrackArray->At(i));
519       if (IsTrackInAcceptance(track))
520       {
521         FillHistogram(tmpRunNum.Data(), "hTrackPhiEta", track->Phi(),track->Eta(), 1);
522         FillHistogram(tmpRunNum.Data(), "hTrackPt", track->Pt());
523         if(track->Eta() >= 0)
524           FillHistogram(tmpRunNum.Data(), "hTrackPtPosEta", track->Pt());
525         else
526           FillHistogram(tmpRunNum.Data(), "hTrackPtNegEta", track->Pt());        
527                 
528         FillHistogram(tmpRunNum.Data(), "hTrackEta", track->Eta());
529         FillHistogram(tmpRunNum.Data(), "hTrackPhi", track->Phi());
530         FillHistogram(tmpRunNum.Data(), "hTrackPhiLabel", track->Phi(), track->GetLabel());
531         for(Int_t j=0;j<20;j++)
532           if(track->Pt() > j)
533             FillHistogram(tmpRunNum.Data(), "hTrackPhiPtCut", track->Phi(), track->Pt());
534
535         FillHistogram(tmpRunNum.Data(), "hTrackCharge", track->Charge());
536         trackCountAcc++;
537       }
538     }
539     FillHistogram(tmpRunNum.Data(), "hTrackCountAcc", trackCountAcc, centralityPercentileV0M);
540
541   }
542   #ifdef DEBUGMODE
543     AliInfo("Calculate()::QA done.");
544   #endif
545
546   ////////////////////// NOTE: Jet analysis and calculations
547
548   if (fAnalyzeJets)
549   {
550     FillHistogram(tmpRunNum.Data(), "hJetCountAll", fJetArray->GetEntries());
551     FillHistogram(tmpRunNum.Data(), "hJetCountAccepted", fNumberSignalJets);
552     // SIGNAL JET ANALYSIS
553     for (Int_t i = 0; i<fNumberSignalJets; i++)
554     {
555       AliEmcalJet* tmpJet = fSignalJets[i];
556
557       FillHistogram(tmpRunNum.Data(), "hJetArea", tmpJet->Area());
558       FillHistogram(tmpRunNum.Data(), "hJetAreaVsPt", tmpJet->Area(), tmpJet->Pt());
559       FillHistogram(tmpRunNum.Data(), "hJetPt", tmpJet->Pt());
560       FillHistogram(tmpRunNum.Data(), "hJetPtVsConstituentCount", tmpJet->Pt(),tmpJet->GetNumberOfTracks());
561       FillHistogram(tmpRunNum.Data(), "hJetPhiEta", tmpJet->Phi(),tmpJet->Eta());
562
563
564     }
565   } //endif AnalyzeJets
566
567   #ifdef DEBUGMODE
568     AliInfo("Calculate()::Jets done.");
569   #endif
570
571
572 //________________________________________________________________________
573 Bool_t AliAnalysisTaskQualityAssurancePA::Notify()
574 {
575   // Implemented Notify() to read the cross sections
576   // and number of trials from pyxsec.root
577   // 
578   #ifdef DEBUGMODE
579     AliInfo("Notify started.");
580   #endif
581
582   if(fAnalyzePythia)
583   {
584     TTree *tree = AliAnalysisManager::GetAnalysisManager()->GetTree();
585     TFile *currFile = tree->GetCurrentFile();
586
587     TString file(currFile->GetName());
588
589     if(file.Contains("root_archive.zip#")){
590       Ssiz_t pos1 = file.Index("root_archive",12,TString::kExact);
591       Ssiz_t pos = file.Index("#",1,pos1,TString::kExact);
592       file.Replace(pos+1,20,"");
593     }
594     else {
595       // not an archive take the basename....
596       file.ReplaceAll(gSystem->BaseName(file.Data()),"");
597     }
598    
599     TFile *fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec.root")); // problem that we cannot really test the existance of a file in a archive so we have to lvie with open error message from root
600     if(!fxsec){
601       // next trial fetch the histgram file
602       fxsec = TFile::Open(Form("%s%s",file.Data(),"pyxsec_hists.root"));
603       if(!fxsec){
604           // not a severe condition but inciate that we have no information
605         return kFALSE;
606       }
607       else{
608         // find the tlist we want to be independtent of the name so use the Tkey
609         TKey* key = (TKey*)fxsec->GetListOfKeys()->At(0); 
610         if(!key){
611           fxsec->Close();
612           return kFALSE;
613         }
614         TList *list = dynamic_cast<TList*>(key->ReadObj());
615         if(!list){
616           fxsec->Close();
617           return kFALSE;
618         }
619         fCrossSection = ((TProfile*)list->FindObject("h1Xsec"))->GetBinContent(1);
620         fTrials  = ((TH1F*)list->FindObject("h1Trials"))->GetBinContent(1);
621         fxsec->Close();
622       }
623     } // no tree pyxsec.root
624     else {
625       TTree *xtree = (TTree*)fxsec->Get("Xsection");
626       if(!xtree){
627         fxsec->Close();
628         return kFALSE;
629       }
630       UInt_t   ntrials  = 0;
631       Double_t  xsection  = 0;
632       xtree->SetBranchAddress("xsection",&xsection);
633       xtree->SetBranchAddress("ntrials",&ntrials);
634       xtree->GetEntry(0);
635       fTrials = ntrials;
636       fCrossSection = xsection;
637       fxsec->Close();
638     }
639     #ifdef DEBUGMODE
640       AliInfo("Notify ended.");
641     #endif
642   }
643   return kTRUE;
644 }
645
646 //________________________________________________________________________
647 inline void AliAnalysisTaskQualityAssurancePA::FillHistogram(const char* runNumber, const char * key, Double_t x)
648 {
649   if(strcmp(runNumber,"ALL") != 0)
650     FillHistogram("ALL", key, x);
651
652   TH1* tmpHist = static_cast<TH1*>(fOutputList->FindObject(GetHistoName(runNumber, key)));
653   if(!tmpHist)
654   {
655     AliError(Form("Cannot find histogram <%s> ",GetHistoName(runNumber, key))) ;
656     return;
657   }
658
659   tmpHist->Fill(x);
660 }
661
662 //________________________________________________________________________
663 inline void AliAnalysisTaskQualityAssurancePA::FillHistogram(const char* runNumber, const char * key, Double_t x, Double_t y)
664 {
665   if(strcmp(runNumber,"ALL") != 0)
666     FillHistogram("ALL", key, x, y);
667
668   TH1* tmpHist = static_cast<TH1*>(fOutputList->FindObject(GetHistoName(runNumber, key)));
669   if(!tmpHist)
670   {
671     AliError(Form("Cannot find histogram <%s> ",GetHistoName(runNumber, key)));
672     return;
673   }
674
675   if (tmpHist->IsA()->GetBaseClass("TH1"))
676     static_cast<TH1*>(tmpHist)->Fill(x,y); // Fill x with y
677   else if (tmpHist->IsA()->GetBaseClass("TH2"))
678     static_cast<TH2*>(tmpHist)->Fill(x,y); // Fill x,y with 1
679 }
680
681 //________________________________________________________________________
682 inline void AliAnalysisTaskQualityAssurancePA::FillHistogram(const char* runNumber, const char * key, Double_t x, Double_t y, Double_t add)
683 {
684   if(strcmp(runNumber,"ALL") != 0)
685     FillHistogram("ALL", key, x, y, add);
686
687
688   TH2* tmpHist = static_cast<TH2*>(fOutputList->FindObject(GetHistoName(runNumber, key)));
689   if(!tmpHist)
690   {
691     AliError(Form("Cannot find histogram <%s> ",GetHistoName(runNumber, key)));
692     return;
693   }
694   
695   tmpHist->Fill(x,y,add);
696 }
697 //________________________________________________________________________
698 template <class T> T* AliAnalysisTaskQualityAssurancePA::AddHistogram1D(const char* runNumber, const char* name, const char* title, const char* options, Int_t xBins, Double_t xMin, Double_t xMax, const char* xTitle, const char* yTitle)
699 {
700   T* tmpHist = new T(GetHistoName(runNumber, name), GetHistoName(runNumber, title), xBins, xMin, xMax);
701
702   tmpHist->GetXaxis()->SetTitle(xTitle);
703   tmpHist->GetYaxis()->SetTitle(yTitle);
704   tmpHist->SetOption(options);
705   tmpHist->SetMarkerStyle(kFullCircle);
706   tmpHist->Sumw2();
707
708   fHistList->Add(tmpHist);
709   fHistCount++;
710   
711   return tmpHist;
712 }
713
714 //________________________________________________________________________
715 template <class T> T* AliAnalysisTaskQualityAssurancePA::AddHistogram2D(const char* runNumber, const char* name, const char* title, const char* options, Int_t xBins, Double_t xMin, Double_t xMax, Int_t yBins, Double_t yMin, Double_t yMax, const char* xTitle, const char* yTitle, const char* zTitle)
716 {
717   T* tmpHist = new T(GetHistoName(runNumber, name), GetHistoName(runNumber, title), xBins, xMin, xMax, yBins, yMin, yMax);
718   tmpHist->GetXaxis()->SetTitle(xTitle);
719   tmpHist->GetYaxis()->SetTitle(yTitle);
720   tmpHist->GetZaxis()->SetTitle(zTitle);
721   tmpHist->SetOption(options);
722   tmpHist->SetMarkerStyle(kFullCircle);
723   tmpHist->Sumw2();
724
725   fHistList->Add(tmpHist);
726   fHistCount++;
727
728   return tmpHist;
729 }
730
731 //________________________________________________________________________
732 void AliAnalysisTaskQualityAssurancePA::Terminate(Option_t *)
733 {
734   PostData(1, fOutputList);
735
736   // Mandatory
737   fOutputList = dynamic_cast<TList*> (GetOutputData(1)); // '1' refers to the output slot
738   if (!fOutputList) {
739     printf("ERROR: Output list not available\n");
740     return;
741   }
742 }
743
744 //________________________________________________________________________
745 AliAnalysisTaskQualityAssurancePA::~AliAnalysisTaskQualityAssurancePA()
746 {
747   // Destructor. Clean-up the output list, but not the histograms that are put inside
748   // (the list is owner and will clean-up these histograms). Protect in PROOF case.
749   if (fOutputList && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
750     delete fOutputList;
751   }
752 }
753
754 //________________________________________________________________________
755 void AliAnalysisTaskQualityAssurancePA::UserCreateOutputObjects()
756 {
757   // called once to create user defined output objects like histograms, plots etc. 
758   // and to put it on the output list.
759   // Note: Saving to file with e.g. OpenFile(0) is must be before creating other objects.
760
761   fRandom = new TRandom3(0);
762   
763   fOutputList = new TList();
764   fOutputList->SetOwner(); // otherwise it produces leaks in merging
765
766   PostData(1, fOutputList);
767 }
768
769 //________________________________________________________________________
770 void AliAnalysisTaskQualityAssurancePA::UserExec(Option_t *) 
771 {
772   #ifdef DEBUGMODE
773     AliInfo("UserExec() started.");
774   #endif
775
776   Calculate(InputEvent());
777         
778   PostData(1, fOutputList);
779 }