2 // Calculate flow on MC data in the forward and central regions using the Q cumulants method.
8 // - AnalysisResults.root
10 #include "AliForwardMCFlowTaskQC.h"
11 #include "AliAODMCParticle.h"
12 #include "AliAODMCHeader.h"
15 #include "AliAODEvent.h"
16 #include "AliAODForwardMult.h"
17 #include "AliAODCentralMult.h"
18 #include "AliGenEventHeader.h"
19 #include "AliAnalysisManager.h"
20 #include "AliInputEventHandler.h"
21 #include "AliGenEventHeaderTunedPbPb.h"
22 #include "AliCollisionGeometry.h"
24 ClassImp(AliForwardMCFlowTaskQC)
28 //_____________________________________________________________________
29 AliForwardMCFlowTaskQC::AliForwardMCFlowTaskQC()
30 : AliForwardFlowTaskQC(),
31 fBinsForwardTR(), // List of FMDTR analysis objects
32 fBinsCentralTR(), // List of SPDTR analysis objects
33 fBinsMC(), // List of MC particle analysis objects
34 fAODMCHeader(), // MC Header
35 fHistdNdedpMC(), // MC particle d^2N/detadphi histogram
36 fHistFMDMCCorr(), // FMD MC correlation
37 fHistSPDMCCorr(), // SPD MC correlation
38 fWeights(0), // Flow weights
39 fImpactParToCent(), // Impact parameter to centrality graph
40 fUseImpactPar(0), // Use impact par for centrality
41 fUseMCVertex(0), // Get vertex from MC header?
42 fUseFlowWeights(0) // Add flow to MC particles
45 // Default Constructor
47 //_____________________________________________________________________
48 AliForwardMCFlowTaskQC::AliForwardMCFlowTaskQC(const char* name)
49 : AliForwardFlowTaskQC(name),
50 fBinsForwardTR(), // List of FMDTR analysis objects
51 fBinsCentralTR(), // List of SPDTR analysis objects
52 fBinsMC(), // List of MC particles analysis objects
53 fAODMCHeader(0), // MC Header
54 fHistdNdedpMC(), // MC particles d^2N/detadphi histogram
55 fHistFMDMCCorr(), // FMD MC correlation
56 fHistSPDMCCorr(), // SPD MC correlation
57 fWeights(0), // Flow weights
58 fImpactParToCent(), // Impact parameter to centrality graph
59 fUseImpactPar(0), // Use impact par for centrality
60 fUseMCVertex(0), // Get vertex from MC header?
61 fUseFlowWeights(0) // Add flow to MC particles
69 // Double_t impactParam[] = {0.,1.75,4.225,5.965,7.765,9.215,10.46,
70 // 11.565,12.575,13.515,16.679};
71 // Double_t centrality[] = {0.,2.5,7.5,15,25,35,45,55,65,75,90};
72 Double_t impactParam[] = { 0.00, 3.72, 5.23, 7.31, 8.88, 10.20,
73 11.38, 12.47, 13.50, 14.51, 16.679};
74 Double_t centrality[] = { 0., 5., 10., 20., 30., 40.,
75 50., 60., 70., 80., 100.};
77 Int_t nPoints = sizeof(impactParam)/sizeof(Double_t);
78 fImpactParToCent = new TGraph(nPoints, impactParam, centrality);
81 //_____________________________________________________________________
82 AliForwardMCFlowTaskQC::AliForwardMCFlowTaskQC(const AliForwardMCFlowTaskQC& o)
83 : AliForwardFlowTaskQC(o),
84 fBinsForwardTR(), // List of FMDTR analysis objects
85 fBinsCentralTR(), // List of SPDTR analysis objects
86 fBinsMC(), // List of MC particles analysis objects
87 fAODMCHeader(o.fAODMCHeader), // MC Header
88 fHistdNdedpMC(o.fHistdNdedpMC), // MC particles d^2N/detadphi histogram
89 fHistFMDMCCorr(o.fHistFMDMCCorr), // FMD MC correlation
90 fHistSPDMCCorr(o.fHistSPDMCCorr), // SPD MC correlation
91 fWeights(o.fWeights), // Flow weights
92 fImpactParToCent(o.fImpactParToCent), // Impact parameter to centrality
93 fUseImpactPar(o.fUseImpactPar), // Use impact par for centrality
94 fUseMCVertex(o.fUseMCVertex), // Get vertex from MC header?
95 fUseFlowWeights(o.fUseFlowWeights) // Add flow to MC particles
101 //_____________________________________________________________________
102 AliForwardMCFlowTaskQC&
103 AliForwardMCFlowTaskQC::operator=(const AliForwardMCFlowTaskQC& o)
106 // Assignment operator
108 // o Object to copy from
110 if (&o == this) return *this;
111 fAODMCHeader = o.fAODMCHeader;
112 fHistdNdedpMC = o.fHistdNdedpMC;
113 fHistFMDMCCorr = o.fHistFMDMCCorr;
114 fHistSPDMCCorr = o.fHistSPDMCCorr;
115 fWeights = o.fWeights;
116 fImpactParToCent = o.fImpactParToCent;
117 fUseImpactPar = o.fUseImpactPar;
118 fUseMCVertex = o.fUseMCVertex;
119 fUseFlowWeights = o.fUseFlowWeights;
122 //_____________________________________________________________________
123 void AliForwardMCFlowTaskQC::InitVertexBins()
126 // Initiate VertexBin lists
128 AliForwardFlowTaskQC::InitVertexBins();
130 Bool_t isNUA = (fFlowFlags & kNUAcorr);
131 for (Int_t v = 1; v <= fVtxAxis->GetNbins(); v++) {
132 Int_t vL = Int_t(fVtxAxis->GetBinLowEdge(v));
133 Int_t vH = Int_t(fVtxAxis->GetBinUpEdge(v));
135 if ((fFlowFlags & kFMD)) {
136 fBinsForwardTR.Add(new VertexBin(vL, vH, fMaxMoment, "FMDTR", fFlowFlags, fFMDCut, fEtaGap));
137 if (!(fFlowFlags & k3Cor))
138 fBinsCentralTR.Add(new VertexBin(vL, vH, fMaxMoment, "SPDTR", fFlowFlags|kSPD, fSPDCut, fEtaGap));
139 if (isNUA) fFlowFlags ^= kNUAcorr;
140 fBinsMC.Add(new VertexBin(vL, vH, fMaxMoment, "MC-FMD", fFlowFlags|kMC, -1, fEtaGap));
141 if ((fFlowFlags & kStdQC))
142 fBinsMC.Add(new VertexBin(vL, vH, fMaxMoment, "MC-SPD", fFlowFlags|kMC|kSPD, -1, fEtaGap));
143 if (isNUA) fFlowFlags ^= kNUAcorr;
146 else if ((fFlowFlags & kVZERO)) {
147 fBinsMC.Add(new VertexBin(vL, vH, fMaxMoment, "MC-VZERO", fFlowFlags|kMC, -1, fEtaGap));
151 //_____________________________________________________________________
152 void AliForwardMCFlowTaskQC::InitHists()
155 // Initiate diagnostics hists and add to outputlist
157 AliForwardFlowTaskQC::InitHists();
159 TString subDetName = ((fFlowFlags & kFMD) ? "FMD" : ((fFlowFlags & kVZERO) ? "VZERO" : "none"));
160 fHistdNdedpMC = TH2D(Form("fdNdedpMC%s%s", subDetName.Data(), GetQCType(fFlowFlags)),
161 Form("fdNdedpMC%s%s", subDetName.Data(), GetQCType(fFlowFlags)),
162 240, -6., 6., 200, 0., TMath::TwoPi());
164 fHistFMDMCCorr = new TH2D("hFMDMCCorr", "hFMDMCCorr", 200, 0., 15000., 200, 0, 20000);
165 fHistSPDMCCorr = new TH2D("hSPDMCCorr", "hSPDMCCorr", 200, 0., 7500., 200, 0, 20000);
166 TList* dList = (TList*)fSumList->FindObject("Diagnostics");
169 dList->SetName("Diagnostics");
170 fSumList->Add(dList);
172 dList->Add(fHistFMDMCCorr);
173 dList->Add(fHistSPDMCCorr);
175 TIter nextForwardTR(&fBinsForwardTR);
177 while ((bin = static_cast<VertexBin*>(nextForwardTR()))) {
178 bin->AddOutput(fSumList, fCentAxis);
180 TIter nextCentralTR(&fBinsCentralTR);
181 while ((bin = static_cast<VertexBin*>(nextCentralTR()))) {
182 bin->AddOutput(fSumList, fCentAxis);
184 TIter nextMC(&fBinsMC);
185 while ((bin = static_cast<VertexBin*>(nextMC()))) {
186 bin->AddOutput(fSumList, fCentAxis);
189 TList* wList = new TList();
190 wList->SetName("FlowWeights");
191 fWeights->Init(wList);
192 fSumList->Add(wList);
196 //_____________________________________________________________________
197 Bool_t AliForwardMCFlowTaskQC::Analyze()
200 // Load FMD and SPD MC objects from aod tree and call the cumulants
201 // calculation for the correct vertexbin
203 if (!AliForwardFlowTaskQC::Analyze()) return kFALSE;
205 // Run analysis on trackrefs from FMD and SPD
206 AliAODForwardMult* aodfmult = static_cast<AliAODForwardMult*>(fAOD->FindListObject("ForwardMC"));
207 AliAODCentralMult* aodcmult = static_cast<AliAODCentralMult*>(fAOD->FindListObject("CentralClustersMC"));
208 Int_t vtx = fVtxAxis->FindBin(fVtx)-1;
210 // if objects are present, get histograms
212 TH2D& fmdTRdNdetadphi = aodfmult->GetHistogram();
213 if ((fFlowFlags & kStdQC)) {
214 FillVtxBinList(fBinsForwardTR, fmdTRdNdetadphi, vtx);
215 } else if ((fFlowFlags & kEtaGap)) {
216 FillVtxBinListEtaGap(fBinsForwardTR, fmdTRdNdetadphi, fmdTRdNdetadphi, vtx/*, kDoVtxCut*/);
219 TH2D& spdTRdNdetadphi = aodcmult->GetHistogram();
220 if ((fFlowFlags & kStdQC)) {
221 FillVtxBinList(fBinsCentralTR, spdTRdNdetadphi, vtx);
222 } else if ((fFlowFlags & kEtaGap)) {
223 FillVtxBinListEtaGap(fBinsCentralTR, fmdTRdNdetadphi, spdTRdNdetadphi, vtx/*, kDoVtxCut*/);
224 } else if ((fFlowFlags & k3Cor)) {
225 FillVtxBinList3Cor(fBinsForwardTR, spdTRdNdetadphi, fmdTRdNdetadphi, vtx);
229 // Run analysis on MC branch
230 if (!FillMCHist()) return kFALSE;
232 if ((fFlowFlags & kStdQC)) {
233 FillVtxBinList(fBinsMC, fHistdNdedpMC, vtx, kMC);
234 } else if ((fFlowFlags & kEtaGap)) {
235 FillVtxBinListEtaGap(fBinsMC, fHistdNdedpMC, fHistdNdedpMC, vtx, kMC);
236 } else if ((fFlowFlags & k3Cor)) {
237 FillVtxBinList3Cor(fBinsMC, fHistdNdedpMC, fHistdNdedpMC, vtx);
240 // Mult correlation diagnostics
241 if (aodfmult && aodcmult) {
242 AliAODForwardMult* fmult = static_cast<AliAODForwardMult*>(fAOD->FindListObject("Forward"));
243 AliAODCentralMult* cmult = static_cast<AliAODCentralMult*>(fAOD->FindListObject("CentralClusters"));
244 const TH2D& fhist = fmult->GetHistogram();
245 const TH2D& chist = cmult->GetHistogram();
247 Double_t totForward = fhist.Integral(1, fhist.GetNbinsX(), 1, fhist.GetNbinsY());
248 Double_t totSPD = chist.Integral(1, chist.GetNbinsX(), 1, chist.GetNbinsY());
249 Double_t totMC = fHistdNdedpMC.Integral(1, fHistdNdedpMC.GetNbinsX(), 1, fHistdNdedpMC.GetNbinsY());
250 fHistFMDMCCorr->Fill(totForward, totMC);
251 fHistSPDMCCorr->Fill(totSPD, totMC);
256 //_____________________________________________________________________
257 void AliForwardMCFlowTaskQC::Finalize()
260 // Finalize command, called by Terminate()
262 AliForwardFlowTaskQC::Finalize();
264 EndVtxBinList(fBinsForwardTR);
265 EndVtxBinList(fBinsCentralTR);
266 EndVtxBinList(fBinsMC);
270 //_____________________________________________________________________
271 Bool_t AliForwardMCFlowTaskQC::CheckEvent(const AliAODForwardMult* aodfm)
274 // Function to check that an AOD event meets the cuts
277 // AliAODForwardMult: forward mult object with trigger and vertex info
279 // Return: false if there is no trigger or if the centrality or vertex
280 // is out of range. Otherwise true.
282 fAODMCHeader = static_cast<AliAODMCHeader*>(fAOD->FindListObject(AliAODMCHeader::StdBranchName()));
283 return AliForwardFlowTaskQC::CheckEvent(aodfm);
285 //_____________________________________________________________________
286 Bool_t AliForwardMCFlowTaskQC::CheckTrigger(const AliAODForwardMult* aodfm) const
289 // Function to look for a trigger string in the event.
292 // AliAODForwardMult: forward mult object with trigger and vertex info
294 // Returns true if B trigger is present - for some reason this is the one we use in MC
296 if (aodfm) return aodfm->IsTriggerBits(AliAODForwardMult::kB);
297 else return (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))
298 ->IsEventSelected() & AliVEvent::kMB);
301 // _____________________________________________________________________
302 Bool_t AliForwardMCFlowTaskQC::GetCentrality(const AliAODForwardMult* aodfm)
305 // Function to use centrality parametrization from impact parameter
306 // if flag is not set call AliForwardFlowTaskQC::GetCentrality
309 // AliAODForwardMult: forward mult object with trigger and vertex info
311 // Returns true when centrality is set.
313 AliGenEventHeaderTunedPbPb* header =
314 dynamic_cast<AliGenEventHeaderTunedPbPb*>(fAODMCHeader->GetCocktailHeader(0));
315 if (header) fCent = header->GetCentrality();
316 else if (fUseImpactPar) fCent = GetCentFromB();
317 else return AliForwardFlowTaskQC::GetCentrality(aodfm);
319 if (fCentAxis->GetXmin() > fCent || fCent >= fCentAxis->GetXmax()) {
320 fHistEventSel->Fill(kInvCent);
323 if (fCent != 0) return kTRUE;
325 fHistEventSel->Fill(kNoCent);
329 //_____________________________________________________________________
330 Bool_t AliForwardMCFlowTaskQC::GetVertex(const AliAODForwardMult* aodfm)
333 // Function to look for vertex determination in the event using the MC header.
336 // AliAODForwardMult: Not used
338 // Returns true if vertex is determined
342 fVtx = fAODMCHeader->GetVtxZ();
343 if (fVtx < fVtxAxis->GetXmin() || fVtx > fVtxAxis->GetXmax()) {
344 fHistEventSel->Fill(kInvVtx);
349 fHistEventSel->Fill(kNoVtx);
353 return AliForwardFlowTaskQC::GetVertex(aodfm);
355 //_____________________________________________________________________
356 Bool_t AliForwardMCFlowTaskQC::FillMCHist()
359 // Loop over AliAODParticle branch and fill d^2N/detadphi-histograms.
360 // Add flow if set to do so in AddTask function
362 fHistdNdedpMC.Reset();
363 Double_t minEta = -3.75;
364 Double_t maxEta = 5.;
366 //retreive MC particles from event
367 TClonesArray* mcArray =
368 static_cast<TClonesArray*>(fAOD->FindListObject(AliAODMCParticle::StdBranchName()));
370 AliWarning("No MC array found in AOD. Try making it again.");
374 if (!fAODMCHeader) AliWarning("No MC header found.");
376 Int_t ntracks = mcArray->GetEntriesFast();
377 Double_t rp = -1, b = -1;
379 rp = fAODMCHeader->GetReactionPlaneAngle();
380 b = fAODMCHeader->GetImpactParameter();
381 if (fAODMCHeader->GetNCocktailHeaders() > 1) {
382 ntracks = fAODMCHeader->GetCocktailHeader(0)->NProduced();
386 for (Int_t it = 0; it < ntracks; it++) { // Track loop
388 AliAODMCParticle* particle = (AliAODMCParticle*)mcArray->At(it);
390 AliError(Form("Could not receive track %d", it));
393 if (!particle->IsPrimary()) continue;
394 if (particle->Charge() == 0) continue;
395 Double_t pT = particle->Pt();
396 Double_t eta = particle->Eta();
397 Double_t phi = particle->Phi();
398 if (eta >= minEta && eta < maxEta) {
399 // Add flow if it is in the argument
400 if (fUseFlowWeights && fWeights) {
401 weight = fWeights->CalcWeight(eta, pT, phi, particle->PdgCode(), rp, b);
402 // Printf("%f", weight);
404 fHistdNdedpMC.Fill(eta, phi, weight);
407 // Set underflow bins for acceptance checks
408 Int_t sBin = fHistdNdedpMC.GetXaxis()->FindBin(minEta);
409 Int_t eBin = fHistdNdedpMC.GetXaxis()->FindBin(maxEta);
410 for ( ; sBin <= eBin; sBin++) {
411 fHistdNdedpMC.SetBinContent(sBin, 0, 1);
412 } // End of eta bin loop
416 //_____________________________________________________________________
417 Double_t AliForwardMCFlowTaskQC::GetCentFromB() const
420 // Get centrality from MC impact parameter.
423 if (!fAODMCHeader) return cent;
424 Double_t b = fAODMCHeader->GetImpactParameter();
425 cent = fImpactParToCent->Eval(b);
429 //_____________________________________________________________________