2 // Calculate flow in the forward and central regions using the Q cumulants method.
8 // - AnalysisResults.root
12 #include <TInterpreter.h>
18 #include "THnSparse.h"
20 #include "TProfile2D.h"
22 #include "AliForwardFlowTaskQC.h"
23 #include "AliAnalysisManager.h"
24 #include "AliAODHandler.h"
25 #include "AliAODInputHandler.h"
26 #include "AliAODMCParticle.h"
27 #include "AliAODForwardMult.h"
28 #include "AliAODEvent.h"
31 // Enumeration for adding and retrieving stuff from the histogram
33 enum { kW2Two = 1, kW2, kW4Four, kW4, kQnRe, kQnIm, kM,
34 kCosphi1phi2, kSinphi1phi2, kCosphi1phi2phi3m, kSinphi1phi2phi3m, kMm1m2,
35 kw2two, kw2, kw4four, kw4, kpnRe, kpnIm, kmp,
36 kCospsi1phi2, kSinpsi1phi2, kCospsi1phi2phi3m, kSinpsi1phi2phi3m,
37 kmpmq, kCospsi1phi2phi3p, kSinpsi1phi2phi3p };
39 ClassImp(AliForwardFlowTaskQC)
44 AliForwardFlowTaskQC::AliForwardFlowTaskQC()
45 : fOutputList(0), // Output list
46 fFlowUtil(0), // AliForwardFlowUtil
47 fAOD(0), // AOD input event
48 fMC(kFALSE), // MC flag
49 fEtaBins(48), // # of etaBin bins in histograms
50 fEtaRef(12), // # of Eta bins for reference flow
51 fAddFlow(0), // Add flow string
52 fAddType(0), // Add flow type #
53 fAddOrder(0), // Add flow order
54 fZvertex(1111), // Z vertex range
55 fCent(-1) // Centrality
58 // Default constructor
60 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
62 //_____________________________________________________________________
63 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const char* name) :
64 AliAnalysisTaskSE(name),
65 fOutputList(0), // Output list
66 fFlowUtil(0), // AliForwardFlowUtil
67 fAOD(0), // AOD input event
68 fMC(kFALSE), // MC flag
69 fEtaBins(48), // # of Eta bins
70 fEtaRef(12), // # of Eta bins for reference flow
71 fAddFlow(0), // Add flow string
72 fAddType(0), // Add flow type #
73 fAddOrder(0), // Add flow order
74 fZvertex(1111), // Z vertex range
75 fCent(-1) // Centrality
83 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
84 DefineOutput(1, TList::Class());
86 //_____________________________________________________________________
87 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const AliForwardFlowTaskQC& o) :
89 fOutputList(o.fOutputList), // Output list
90 fFlowUtil(o.fFlowUtil), // AliForwardFlowUtil
91 fAOD(o.fAOD), // AOD input event
92 fMC(o.fMC), // MC flag
93 fEtaBins(o.fEtaBins), // # of Eta bins
94 fEtaRef(o.fEtaRef), // # of Eta bins for reference flow
95 fAddFlow(o.fAddFlow), // Add flow string
96 fAddType(o.fAddType), // Add flow type #
97 fAddOrder(o.fAddOrder), // Add flow order
98 fZvertex(o.fZvertex), // Z vertex range
99 fCent(o.fCent) // Centrality
105 // o Object to copy from
107 for (Int_t n = 0; n <= 6; n++) fv[n] = o.fv[n];
108 DefineOutput(1, TList::Class());
110 //_____________________________________________________________________
111 void AliForwardFlowTaskQC::UserCreateOutputObjects()
114 // Create output objects
117 fOutputList = new TList();
118 fOutputList->SetName("QCumulants");
119 fOutputList->SetOwner();
120 fFlowUtil = new AliForwardFlowUtil(fOutputList);
122 Double_t x[101] = { 0. };
123 // Double_t etaMin = -6;
124 // Double_t etaMax = 6;
126 // First we have a number of options for eta binning, also if it is
127 // not really eta, but centrality or pt we want to do flow as a
128 // function of, then this is possible:
140 else if (fEtaBins == 100) {
141 for (Int_t e = 0; e<= 100; e++) {
149 if (fEtaBins % 6) fEtaBins = 48;
150 for (Int_t e = 0; e <=fEtaBins; e++) {
151 x[e] = -6. + e*(12./(Double_t)fEtaBins);
155 // Reference flow binning
156 Double_t xR[101] = { 0. };
157 for (Int_t r = 0; r <= fEtaRef; r++) {
158 xR[r] = -6 + r*(12./(Double_t)fEtaRef);
162 Double_t phi[21] = { 0. };
163 for (Int_t p = 0; p <= 20; p++) {
164 phi[p] = p*2.*TMath::Pi() / 20.;
166 Double_t phiMC[201] = { 0. };
167 for (Int_t p = 0; p <= 200; p++) {
168 phiMC[p] = p*2.*TMath::Pi() / 200.;
171 // Histograms for cumulants analysis
173 // We loop over flow histograms here to add different orders of harmonics
175 for (Int_t loop = 1; loop <= 5; loop++) {
177 if (loop == 1) type = "FMD";
178 if (loop == 2) type = "SPD";
179 if (loop == 3) type = "MC";
180 if (loop == 4) type = "FMDTR";
181 if (loop == 5) type = "SPDTR";
183 TList* tList = new TList();
184 tList->SetName(type.Data());
185 fOutputList->Add(tList);
187 for (Int_t n = 1; n <= 6; n++) {
188 if (!fv[n]) continue;
190 TList* vList = new TList();
191 vList->SetName(Form("v%d", n));
194 TString tag = TString();
195 for (Int_t c = 0; c < 100; c++) {
197 tag = Form("%d_%d", c, c+1);
199 TH3D* hFlowHist = new TH3D(Form("hQ%dCumuHist%s_%s", n, type.Data(), tag.Data()),
200 Form("hQ%dCumuHist%s_%s", n, type.Data(), tag.Data()), fEtaBins, -6, 6, 10, -5, 5, 26, 0.5, 26.5);
201 TAxis* xAxis = hFlowHist->GetXaxis();
202 xAxis->Set(fEtaBins, x);
204 vList->Add(hFlowHist);
206 TProfile* hCumulant2DiffFlow = new TProfile(Form("hQ%dCumulant2DiffFlow%s_%s", n, type.Data(), tag.Data()),
207 Form("hQ%dCumulant2DiffFlow%s_%s", n, type.Data(), tag.Data()), fEtaBins, x);
208 hCumulant2DiffFlow->Sumw2();
209 vList->Add(hCumulant2DiffFlow);
211 TProfile* hCumulant4DiffFlow = new TProfile(Form("hQ%dCumulant4DiffFlow%s_%s", n, type.Data(), tag.Data()),
212 Form("hQ%dCumulant4DiffFlow%s_%s", n, type.Data(), tag.Data()), fEtaBins, x);
213 hCumulant4DiffFlow->Sumw2();
214 vList->Add(hCumulant4DiffFlow);
215 } // end of centrality loop
217 } // end of v_{n} loop
219 // Single Event histograms
220 TH2D* hdNdphiSE = new TH2D(Form("hdNdphiSE%s", type.Data()),
221 Form("hdNdphiSE%s", type.Data()), fEtaRef, xR, (type.Contains("MC") ? 200 : 20), (type.Contains("MC") ? phiMC : phi));
223 fOutputList->Add(hdNdphiSE);
225 TH2D* hdNdetadphiSE = new TH2D(Form("hdNdetadphiSE%s", type.Data()),
226 Form("hdNdetadphiSE%s", type.Data()), fEtaBins, x, (type.Contains("MC") ? 200 : 20), (type.Contains("MC") ? phiMC : phi));
227 hdNdetadphiSE->Sumw2();
228 fOutputList->Add(hdNdetadphiSE);
229 } // end of type loop
231 TProfile2D* pMCTruth = new TProfile2D("pMCTruth", "pMCTruth", 48, -6, 6, 100, 0, 100);
232 TAxis* xAxis = pMCTruth->GetXaxis();
233 xAxis->Set(fEtaBins, x);
235 fOutputList->Add(pMCTruth);
238 TH1D* cent = new TH1D("Centralities", "Centralities", 100, 0, 100);
239 fOutputList->Add(cent);
241 TH1D* vertexSel = new TH1D("VertexSelected", "VertexSelected", 50, -10, 10);
242 fOutputList->Add(vertexSel);
243 TH1D* vertexAll = new TH1D("VertexAll", "VertexAll", 50, -10, 10);
244 fOutputList->Add(vertexAll);
246 TH2D* vertex2D = new TH2D("CoverageVsVertex", "CoverageVsVertex", fEtaBins, -6, 6, 20, -10, 10);
247 fOutputList->Add(vertex2D);
249 PostData(1, fOutputList);
251 //_____________________________________________________________________
252 void AliForwardFlowTaskQC::UserExec(Option_t */*option*/)
255 // Process each event
261 // Reset data members
266 fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
270 if (!fFlowUtil->LoopAODFMD(fAOD)) return;
271 if (!fFlowUtil->LoopAODSPD(fAOD)) return;
273 // Get centrality and vertex from flow utility and fill monitoring histograms
274 fCent = fFlowUtil->GetCentrality();
275 fZvertex = fFlowUtil->GetVertex();
277 TH1D* cent = (TH1D*)fOutputList->FindObject("Centralities");
280 TH1D* vertex = (TH1D*)fOutputList->FindObject("VertexSelected");
281 vertex->Fill(fZvertex);
283 // Run analysis on FMD and SPD
284 for (Int_t n = 1; n <= 6; n++) {
286 CumulantsMethod("FMD", n);
287 CumulantsMethod("SPD", n);
291 // And do analysis if there is.
296 PostData(1, fOutputList);
298 //_____________________________________________________________________
299 void AliForwardFlowTaskQC::CumulantsMethod(TString type = "",
303 // Calculate the Q cumulant of order n
306 // type: Determines which histograms should be used
307 // - "FMD" or "SPD" = data histograms
308 // - "FMDTR" or "SPDTR" = track reference histograms
309 // - "MC" = MC truth histograms
310 // harmonic: Which harmonic to calculate
312 Double_t n = harmonic;
314 TList* tList = (TList*)fOutputList->FindObject(type.Data());
315 TList* vList = (TList*)tList->FindObject(Form("v%d", harmonic));
316 // We get the histograms
317 TH3D* flowHist = (TH3D*)vList->FindObject(Form("hQ%dCumuHist%s_%d_%d", harmonic, type.Data(), (Int_t)fCent, (Int_t)fCent+1));
318 TH2D* dNdetadphi = (TH2D*)fOutputList->FindObject(Form("hdNdetadphiSE%s", type.Data()));
319 TH2D* dNdphi = (TH2D*)fOutputList->FindObject(Form("hdNdphiSE%s", /*"FMD"*/type.Data()));
321 // We create the coordinate array used to fill the THnSparse, centrality and vertex is set from the beginning.
322 Double_t coord[4] = { 0., fCent, fZvertex, 0. };
323 // We create the objects needed for the analysis
324 Double_t dQnRe = 0, dQ2nRe = 0, dQnIm = 0, dQ2nIm = 0, mult = 0;
325 Double_t pnRe = 0, p2nRe = 0, qnRe = 0, q2nRe = 0, pnIm = 0, p2nIm = 0, qnIm = 0, q2nIm = 0;
326 Double_t two = 0, four = 0, twoPrime = 0, fourPrime = 0;
327 Double_t cosPhi1Phi2 = 0, cosPhi1Phi2Phi3m = 0;
328 Double_t sinPhi1Phi2 = 0, sinPhi1Phi2Phi3m = 0;
329 Double_t cosPsi1Phi2 = 0, cosPsi1Phi2Phi3m = 0, cosPsi1Phi2Phi3p = 0;
330 Double_t sinPsi1Phi2 = 0, sinPsi1Phi2Phi3m = 0, sinPsi1Phi2Phi3p = 0;
331 Double_t phi = 0, eta = 0;
332 Double_t multi = 0, multp = 0, mp = 0, mq = 0;
333 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
335 Bool_t kEventCount = kFALSE;
337 // We loop over the data 1 time!
338 for (Int_t etaBin = 1; etaBin <= dNdetadphi->GetNbinsX(); etaBin++) {
339 eta = dNdetadphi->GetXaxis()->GetBinCenter(etaBin);
340 refEtaBin = dNdphi->GetXaxis()->FindBin(eta);
341 // The values for each individual etaBin bins are reset
354 for (Int_t phiBin = 1; phiBin <= dNdphi->GetNbinsY(); phiBin++) {
355 phi = dNdphi->GetYaxis()->GetBinCenter(phiBin);
358 multi = dNdphi->GetBinContent(refEtaBin, phiBin);
359 dQnRe += multi*TMath::Cos(n*phi);
360 dQnIm += multi*TMath::Sin(n*phi);
361 dQ2nRe += multi*TMath::Cos(2.*n*phi);
362 dQ2nIm += multi*TMath::Sin(2.*n*phi);
365 // For each etaBin bin the necessary values for differential flow
366 // is calculated. Here is the loop over the phi's.
367 multp = dNdetadphi->GetBinContent(etaBin, phiBin);
369 pnRe += multp*TMath::Cos(n*phi);
370 pnIm += multp*TMath::Sin(n*phi);
371 p2nRe += multp*TMath::Cos(2.*n*phi);
372 p2nIm += multp*TMath::Sin(2.*n*phi);
374 if (mult == 0) continue;
377 // Count number of events
380 flowHist->Fill(coord[0], coord[2], coord[3], 1.);
384 // The reference flow is calculated
388 w2 = mult * (mult - 1.);
389 two = dQnRe*dQnRe + dQnIm*dQnIm - mult;
391 flowHist->Fill(coord[0], coord[2], coord[3], two);
393 flowHist->Fill(coord[0], coord[2], coord[3], w2);
396 flowHist->Fill(coord[0], coord[2], coord[3], dQnRe);
398 flowHist->Fill(coord[0], coord[2], coord[3], dQnIm);
400 flowHist->Fill(coord[0], coord[2], coord[3], mult);
403 w4 = mult * (mult - 1.) * (mult - 2.) * (mult - 3.);
405 four = 2.*mult*(mult-3.) + TMath::Power((TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.)),2.)
406 -4.*(mult-2.)*(TMath::Power(dQnRe,2.) + TMath::Power(dQnIm,2.))
407 -2.*(TMath::Power(dQnRe,2.)*dQ2nRe+2.*dQnRe*dQnIm*dQ2nIm-TMath::Power(dQnIm,2.)*dQ2nRe)
408 +(TMath::Power(dQ2nRe,2.)+TMath::Power(dQ2nIm,2.));
411 flowHist->Fill(coord[0], coord[2], coord[3], four);
413 flowHist->Fill(coord[0], coord[2], coord[3], w4);
415 cosPhi1Phi2 = dQnRe*dQnRe - dQnIm*dQnIm - dQ2nRe;
416 sinPhi1Phi2 = 2.*dQnRe*dQnIm - dQ2nIm;
418 cosPhi1Phi2Phi3m = dQnRe*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))-dQnRe*dQ2nRe-dQnIm*dQ2nIm-2.*(mult-1)*dQnRe;
420 sinPhi1Phi2Phi3m = -dQnIm*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))+dQnRe*dQ2nIm-dQnIm*dQ2nRe+2.*(mult-1)*dQnIm;
422 coord[3] = kCosphi1phi2;
423 flowHist->Fill(coord[0], coord[2], coord[3], cosPhi1Phi2);
424 coord[3] = kSinphi1phi2;
425 flowHist->Fill(coord[0], coord[2], coord[3], sinPhi1Phi2);
426 coord[3] = kCosphi1phi2phi3m;
427 flowHist->Fill(coord[0], coord[2], coord[3], cosPhi1Phi2Phi3m);
428 coord[3] = kSinphi1phi2phi3m;
429 flowHist->Fill(coord[0], coord[2], coord[3], sinPhi1Phi2Phi3m);
431 flowHist->Fill(coord[0], coord[2], coord[3], mult*(mult-1.)*(mult-2.));
433 // Differential flow calculations for each etaBin bin is done:
440 // 2-particle differential flow
441 w2p = mp * mult - mq;
442 twoPrime = pnRe*dQnRe + pnIm*dQnIm - mq;
445 flowHist->Fill(coord[0], coord[2], coord[3], twoPrime);
447 flowHist->Fill(coord[0], coord[2], coord[3], w2p);
450 flowHist->Fill(coord[0], coord[2], coord[3], pnRe);
452 flowHist->Fill(coord[0], coord[2], coord[3], pnIm);
454 flowHist->Fill(coord[0], coord[2], coord[3], mp);
456 // 4-particle differential flow
457 w4p = (mp * mult - 3.*mq)*(mult - 1.)*(mult - 2.);
459 fourPrime = (TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*(pnRe*dQnRe+pnIm*dQnIm)
460 - q2nRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))
461 - 2.*q2nIm*dQnRe*dQnIm
462 - pnRe*(dQnRe*dQ2nRe+dQnIm*dQ2nIm)
463 + pnIm*(dQnIm*dQ2nRe-dQnRe*dQ2nIm)
464 - 2.*mult*(pnRe*dQnRe+pnIm*dQnIm)
465 - 2.*(TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*mq
466 + 6.*(qnRe*dQnRe+qnIm*dQnIm)
467 + 1.*(q2nRe*dQ2nRe+q2nIm*dQ2nIm)
468 + 2.*(pnRe*dQnRe+pnIm*dQnIm)
473 flowHist->Fill(coord[0], coord[2], coord[3], fourPrime);
475 flowHist->Fill(coord[0], coord[2], coord[3], w4p);
477 cosPsi1Phi2 = pnRe*dQnRe - pnIm*dQnIm - q2nRe;
478 sinPsi1Phi2 = pnRe*dQnIm + pnIm*dQnRe - q2nIm;
480 cosPsi1Phi2Phi3p = pnRe*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
481 - 1.*(q2nRe*dQnRe+q2nIm*dQnIm)
484 sinPsi1Phi2Phi3p = pnIm*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
485 - 1.*(q2nIm*dQnRe-q2nRe*dQnIm)
488 cosPsi1Phi2Phi3m = pnRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))+2.*pnIm*dQnRe*dQnIm
489 - 1.*(pnRe*dQ2nRe+pnIm*dQ2nIm)
490 - 2.*mq*dQnRe+2.*qnRe;
492 sinPsi1Phi2Phi3m = pnIm*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))-2.*pnRe*dQnRe*dQnIm
493 - 1.*(pnIm*dQ2nRe-pnRe*dQ2nIm)
494 + 2.*mq*dQnIm-2.*qnIm;
496 coord[3] = kCospsi1phi2;
497 flowHist->Fill(coord[0], coord[2], coord[3], cosPsi1Phi2);
498 coord[3] = kSinpsi1phi2;
499 flowHist->Fill(coord[0], coord[2], coord[3], sinPsi1Phi2);
500 coord[3] = kCospsi1phi2phi3m;
501 flowHist->Fill(coord[0], coord[2], coord[3], cosPsi1Phi2Phi3m);
502 coord[3] = kSinpsi1phi2phi3m;
503 flowHist->Fill(coord[0], coord[2], coord[3], sinPsi1Phi2Phi3m);
505 flowHist->Fill(coord[0], coord[2], coord[3], (mp*mult-2.*mq)*(mult-1.));
506 coord[3] = kCospsi1phi2phi3p;
507 flowHist->Fill(coord[0], coord[2], coord[3], cosPsi1Phi2Phi3p);
508 coord[3] = kSinpsi1phi2phi3p;
509 flowHist->Fill(coord[0], coord[2], coord[3], sinPsi1Phi2Phi3p);
514 //_____________________________________________________________________
515 void AliForwardFlowTaskQC::Terminate(Option_t */*option*/)
519 // Finalizes the Q cumulant calculations
525 TH3D* cumulantsHist = 0;
526 TProfile* cumulant2diffHist = 0;
527 TProfile* cumulant4diffHist = 0;
531 // For flow calculations
532 Double_t two = 0, qc2 = 0, /* vnTwo = 0, */ four = 0, qc4 = 0 /*, vnFour = 0*/;
533 Double_t twoPrime = 0, qc2Prime = 0, vnTwoDiff = 0, fourPrime = 0, qc4Prime = 0, vnFourDiff = 0;
534 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
535 Double_t w2Two = 0, w2pTwoPrime = 0, w4Four = 0, w4pFourPrime = 0;
536 Double_t cosP1nPhi = 0, sinP1nPhi = 0, mult = 0, cosP1nPhi1P1nPhi2 = 0, sinP1nPhi1P1nPhi2 = 0;
537 Double_t cosP1nPhi1M1nPhi2M1nPhi3 = 0, sinP1nPhi1M1nPhi2M1nPhi3 = 0, multm1m2 = 0;
538 Double_t cosP1nPsi = 0, sinP1nPsi = 0, mp = 0, cosP1nPsi1P1nPhi2 = 0, sinP1nPsi1P1nPhi2 = 0;
539 Double_t cosP1nPsi1M1nPhi2M1nPhi3 = 0, sinP1nPsi1M1nPhi2M1nPhi3 = 0, mpqMult = 0;
540 Double_t cosP1nPsi1P1nPhi2M1nPhi3 = 0, sinP1nPsi1P1nPhi2M1nPhi3 = 0;
542 Int_t nLoops = (fMC ? 5 : 2);
545 // Do a loop over the difference analysis types, calculating flow
546 // 2 loops for real data, 3 for MC data
547 // inside each is a nested loop over each harmonic (1, 2, 3 and 4 at the moment)
548 for (Int_t loop = 1; loop <= nLoops; loop++) {
550 if (loop == 1) type = "FMD";
551 if (loop == 2) type = "SPD";
552 if (loop == 3) type = "MC";
553 if (loop == 4) type = "FMDTR";
554 if (loop == 5) type = "SPDTR";
556 for (Int_t n = 1; n <= 6; n++) {
557 if (!fv[n]) continue;
559 tList = (TList*)fOutputList->FindObject(type.Data());
560 vList = (TList*)tList->FindObject(Form("v%d", n));
564 for (Int_t c = 0; c < 100; c++) {
567 tag = Form("%d_%d", c, c+1);
568 cumulantsHist = (TH3D*)vList->FindObject(Form("hQ%dCumuHist%s_%s", n, type.Data(), tag.Data()));
570 cumulant2diffHist = (TProfile*)vList->FindObject(Form("hQ%dCumulant2DiffFlow%s_%s", n, type.Data(), tag.Data()));
571 cumulant4diffHist = (TProfile*)vList->FindObject(Form("hQ%dCumulant4DiffFlow%s_%s", n, type.Data(), tag.Data()));
573 for (Int_t vertexBin = 1; vertexBin <= cumulantsHist->GetNbinsY(); vertexBin++) {
575 for (Int_t etaBin = 1; etaBin <= cumulantsHist->GetNbinsX(); etaBin++) {
576 Double_t eta = cumulantsHist->GetXaxis()->GetBinCenter(etaBin);
577 // 2-particle reference flow
578 w2Two = cumulantsHist->GetBinContent(etaBin, vertexBin, kW2Two);
579 if (!w2Two) continue;
580 w2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kW2);
581 cosP1nPhi = cumulantsHist->GetBinContent(etaBin, vertexBin, kQnRe);
582 sinP1nPhi = cumulantsHist->GetBinContent(etaBin, vertexBin, kQnIm);
583 mult = cumulantsHist->GetBinContent(etaBin, vertexBin, kM);
588 qc2 = two - TMath::Power(cosP1nPhi, 2) - TMath::Power(sinP1nPhi, 2);
589 if (qc2 <= 0) continue;
590 // vnTwo = TMath::Sqrt(qc2);
591 // if (!TMath::IsNaN(vnTwo*mult))
592 // cumulant2diffHist->Fill(eta, vnTwo, cumulantsHist->GetBinContent(0,vertexBin,0));
594 // 4-particle reference flow
595 w4Four = cumulantsHist->GetBinContent(etaBin, vertexBin, kW4Four);
596 w4 = cumulantsHist->GetBinContent(etaBin, vertexBin, kW4);
597 cosP1nPhi1P1nPhi2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kCosphi1phi2);
598 sinP1nPhi1P1nPhi2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kSinphi1phi2);
599 cosP1nPhi1M1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kCosphi1phi2phi3m);
600 sinP1nPhi1M1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kSinphi1phi2phi3m);
601 multm1m2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kMm1m2);
603 cosP1nPhi1P1nPhi2 /= w2;
604 sinP1nPhi1P1nPhi2 /= w2;
605 cosP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
606 sinP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
608 qc4 = four-2.*TMath::Power(two,2.)
609 - 4.*cosP1nPhi*cosP1nPhi1M1nPhi2M1nPhi3
610 + 4.*sinP1nPhi*sinP1nPhi1M1nPhi2M1nPhi3-TMath::Power(cosP1nPhi1P1nPhi2,2.)-TMath::Power(sinP1nPhi1P1nPhi2,2.)
611 + 4.*cosP1nPhi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
612 + 8.*sinP1nPhi1P1nPhi2*sinP1nPhi*cosP1nPhi
613 + 8.*two*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
614 - 6.*TMath::Power((TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.)),2.);
616 if (qc4 >= 0) continue;
617 // vnFour = TMath::Power(-qc4, 0.25);
618 // if (!TMath::IsNaN(vnFour*mult))
619 // cumulant4diffHist->Fill(eta, vnFour, cumulantsHist->GetBinContent(0,vertexBin,0));
621 // 2-particle differential flow
622 w2pTwoPrime = cumulantsHist->GetBinContent(etaBin, vertexBin, kw2two);
623 if (!w2pTwoPrime) continue;
624 w2p = cumulantsHist->GetBinContent(etaBin, vertexBin, kw2);
625 cosP1nPsi = cumulantsHist->GetBinContent(etaBin, vertexBin, kpnRe);
626 sinP1nPsi = cumulantsHist->GetBinContent(etaBin, vertexBin, kpnIm);
627 mp = cumulantsHist->GetBinContent(etaBin, vertexBin, kmp);
631 twoPrime = w2pTwoPrime / w2p;
632 qc2Prime = twoPrime - sinP1nPsi*sinP1nPhi - cosP1nPsi*cosP1nPhi;
634 vnTwoDiff = qc2Prime / TMath::Sqrt(qc2);
635 if (!TMath::IsNaN(vnTwoDiff*mp) && vnTwoDiff > 0) cumulant2diffHist->Fill(eta, vnTwoDiff, cumulantsHist->GetBinContent(0,vertexBin,0));
637 // 4-particle differential flow
638 w4pFourPrime = cumulantsHist->GetBinContent(etaBin, vertexBin, kw4four);
639 w4p = cumulantsHist->GetBinContent(etaBin, vertexBin, kw4);
640 cosP1nPsi1P1nPhi2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kCospsi1phi2);
641 sinP1nPsi1P1nPhi2 = cumulantsHist->GetBinContent(etaBin, vertexBin, kSinpsi1phi2);
642 cosP1nPsi1M1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kCospsi1phi2phi3m);
643 sinP1nPsi1M1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kSinpsi1phi2phi3m);
644 cosP1nPsi1P1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kCospsi1phi2phi3p);
645 sinP1nPsi1P1nPhi2M1nPhi3 = cumulantsHist->GetBinContent(etaBin, vertexBin, kSinpsi1phi2phi3p);
646 mpqMult = cumulantsHist->GetBinContent(etaBin, vertexBin, kmpmq);
648 cosP1nPsi1P1nPhi2 /= w2p;
649 sinP1nPsi1P1nPhi2 /= w2p;
650 cosP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
651 sinP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
652 cosP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
653 sinP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
654 fourPrime = w4pFourPrime / w4p;
656 qc4Prime = fourPrime-2.*twoPrime*two
657 - cosP1nPsi*cosP1nPhi1M1nPhi2M1nPhi3
658 + sinP1nPsi*sinP1nPhi1M1nPhi2M1nPhi3
659 - cosP1nPhi*cosP1nPsi1M1nPhi2M1nPhi3
660 + sinP1nPhi*sinP1nPsi1M1nPhi2M1nPhi3
661 - 2.*cosP1nPhi*cosP1nPsi1P1nPhi2M1nPhi3
662 - 2.*sinP1nPhi*sinP1nPsi1P1nPhi2M1nPhi3
663 - cosP1nPsi1P1nPhi2*cosP1nPhi1P1nPhi2
664 - sinP1nPsi1P1nPhi2*sinP1nPhi1P1nPhi2
665 + 2.*cosP1nPhi1P1nPhi2*(cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
666 + 2.*sinP1nPhi1P1nPhi2*(cosP1nPsi*sinP1nPhi+sinP1nPsi*cosP1nPhi)
667 + 4.*two*(cosP1nPsi*cosP1nPhi+sinP1nPsi*sinP1nPhi)
668 + 2.*cosP1nPsi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
669 + 4.*sinP1nPsi1P1nPhi2*cosP1nPhi*sinP1nPhi
670 + 4.*twoPrime*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
671 - 6.*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
672 * (cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
673 - 12.*cosP1nPhi*sinP1nPhi
674 * (sinP1nPsi*cosP1nPhi+cosP1nPsi*sinP1nPhi);
676 vnFourDiff = - qc4Prime / TMath::Power(-qc4, 0.75);
677 if (!TMath::IsNaN(vnFourDiff*mp) && vnFourDiff > 0) cumulant4diffHist->Fill(eta, vnFourDiff, cumulantsHist->GetBinContent(0,vertexBin,0));
678 } // End of etaBin loop
679 nEv += cumulantsHist->GetBinContent(0,vertexBin,0);
680 } // End of vertexBin loop
682 cumulant2diffHist->Fill(7., nEv);
683 cumulant4diffHist->Fill(7., nEv);
685 } // End of centrality loop
686 } // End of harmonics loop
687 } // End of type loop
689 PostData(1, fOutputList);
693 // _____________________________________________________________________
694 void AliForwardFlowTaskQC::ProcessPrimary()
697 // If fMC == kTRUE this function takes care of organizing the input
698 // Monte Carlo data and histograms so AliForwardFlowTaskQC::QCumulants
702 if (fFlowUtil->LoopAODFMDtrrefHits(fAOD)) {
703 // Run analysis on TrackRefs
704 for (Int_t n = 1; n <= 6; n++) {
706 CumulantsMethod("FMDTR", n);
710 if (fFlowUtil->LoopAODSPDtrrefHits(fAOD)) {
711 // Run analysis on SPD TrackRefs
712 for (Int_t n = 1; n <= 6; n++) {
714 CumulantsMethod("SPDTR", n);
718 if (fFlowUtil->LoopAODmc(fAOD, fAddFlow, fAddType, fAddOrder)) {
719 // Run analysis on MC truth
720 for (Int_t n = 1; n <= 6; n++) {
722 CumulantsMethod("MC", n);
727 //_____________________________________________________________________