2 // Calculate flow in the forward and central regions using the Q cumulants method.
8 // - AnalysisResults.root
12 #include <TInterpreter.h>
19 #include "TProfile2D.h"
21 #include "AliForwardFlowTaskQC.h"
22 #include "AliAnalysisManager.h"
23 #include "AliAODHandler.h"
24 #include "AliAODInputHandler.h"
25 #include "AliAODForwardMult.h"
26 #include "AliAODCentralMult.h"
27 #include "AliAODEvent.h"
29 ClassImp(AliForwardFlowTaskQC)
34 AliForwardFlowTaskQC::AliForwardFlowTaskQC()
35 : AliAnalysisTaskSE(),
36 fBinsFMD(), // List with FMD flow histos
37 fBinsSPD(), // List with SPD flow histos
38 fSumList(0), // Event sum list
39 fOutputList(0), // Result output list
40 fAOD(0), // AOD input event
41 fZvertex(1111), // Z vertex coordinate
42 fCent(-1), // Centrality
43 fHistCent(), // Histo for centrality
44 fHistVertexSel(), // Histo for selected vertices
45 fHistVertexAll() // Histo for all vertices
48 // Default constructor
50 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
52 //_____________________________________________________________________
53 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const char* name)
54 : AliAnalysisTaskSE(name),
55 fBinsFMD(), // List with FMD flow histos
56 fBinsSPD(), // List with SPD flow histos
57 fSumList(0), // Event sum list
58 fOutputList(0), // Result output list
59 fAOD(0), // AOD input event
60 fZvertex(1111), // Z vertex coordinate
61 fCent(-1), // Centrality
62 fHistCent(), // Histo for centrality
63 fHistVertexSel(), // Histo for selected vertices
64 fHistVertexAll() // Histo for all vertices
72 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
74 fHistCent = new TH1D("hCent", "Centralities", 100, 0, 100);
75 fHistVertexSel = new TH1D("hVertexSel", "Selected vertices", 40, -20, 20);
76 fHistVertexAll = new TH1D("hVertexAll", "All vertices", 40, -20, 20);
78 DefineOutput(1, TList::Class());
79 DefineOutput(2, TList::Class());
81 //_____________________________________________________________________
82 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const AliForwardFlowTaskQC& o)
83 : AliAnalysisTaskSE(o),
84 fBinsFMD(), // List with FMD flow histos
85 fBinsSPD(), // List with SPD flow histos
86 fSumList(o.fSumList), // Event sum list
87 fOutputList(o.fOutputList), // Result output list
88 fAOD(o.fAOD), // AOD input event
89 fZvertex(o.fZvertex), // Z vertex coordinate
90 fCent(o.fCent), // Centrality
91 fHistCent(o.fHistCent), // Histo for centrality
92 fHistVertexSel(o.fHistVertexSel), // Histo for selected vertices
93 fHistVertexAll(o.fHistVertexAll) // Histo for all vertices
99 // o Object to copy from
101 for (Int_t n = 0; n <= 6; n++) fv[n] = o.fv[n];
103 //_____________________________________________________________________
104 AliForwardFlowTaskQC&
105 AliForwardFlowTaskQC::operator=(const AliForwardFlowTaskQC& o)
108 // Assignment operator
110 if (&o == this) return *this;
111 fSumList = o.fSumList;
112 fOutputList = o.fOutputList;
114 fZvertex = o.fZvertex;
116 fHistCent = o.fHistCent;
117 fHistVertexSel = o.fHistVertexSel;
118 fHistVertexAll = o.fHistVertexAll;
119 fHistVertexAll = o.fHistVertexAll;
121 for (Int_t n = 0; n <= 6; n++) fv[n] = o.fv[n];
124 //_____________________________________________________________________
125 void AliForwardFlowTaskQC::UserCreateOutputObjects()
128 // Create output objects
133 PostData(1, fSumList);
134 PostData(2, fOutputList);
137 //_____________________________________________________________________
138 void AliForwardFlowTaskQC::InitVertexBins()
141 // Init vertexbin objects for FMD and SPD, and add them to the lists
143 for(Int_t n = 1; n <= 6; n++) {
144 if (!fv[n]) continue;
145 for (Int_t v = -10; v < 10; v++) {
146 fBinsFMD.Add(new VertexBin(v, v+1, n, "FMD"));
147 fBinsSPD.Add(new VertexBin(v, v+1, n, "SPD"));
152 //_____________________________________________________________________
153 void AliForwardFlowTaskQC::InitHists()
156 // Init histograms and add vertex bin histograms to the sum list
159 fSumList = new TList();
160 fSumList->SetName("Sums");
161 fSumList->SetOwner();
163 TList* dList = new TList();
164 dList->SetName("Diagnostics");
165 dList->Add(fHistCent);
166 dList->Add(fHistVertexSel);
167 dList->Add(fHistVertexAll);
168 fSumList->Add(dList);
170 TIter nextFMD(&fBinsFMD);
172 while ((bin = static_cast<VertexBin*>(nextFMD()))) {
173 bin->AddOutput(fSumList);
175 TIter nextSPD(&fBinsSPD);
176 while ((bin = static_cast<VertexBin*>(nextSPD()))) {
177 bin->AddOutput(fSumList);
180 //_____________________________________________________________________
181 void AliForwardFlowTaskQC::UserExec(Option_t */*option*/)
184 // Calls the analyze function - called every event
192 PostData(1, fSumList);
195 //_____________________________________________________________________
196 Bool_t AliForwardFlowTaskQC::Analyze()
199 // Load FMD and SPD objects from aod tree and call the cumulants
200 // calculation for the correct vertexbin
203 // Reset data members
208 fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
209 if (!fAOD) return kFALSE;
211 AliAODForwardMult* aodfmult = static_cast<AliAODForwardMult*>(fAOD->FindListObject("Forward"));
212 if (!aodfmult) return kFALSE;
213 if (!AODCheck(aodfmult)) return kFALSE;
214 TH2D fmddNdetadphi = aodfmult->GetHistogram();
216 AliAODCentralMult* aodcmult = static_cast<AliAODCentralMult*>(fAOD->FindListObject("CentralClusters"));
217 if (!aodcmult) return kFALSE;
218 TH2D spddNdetadphi = aodcmult->GetHistogram();
223 // Run analysis on FMD and SPD
224 TIter nextFMD(&fBinsFMD);
226 while ((bin = static_cast<VertexBin*>(nextFMD()))) {
227 if (bin->CheckVertex(fZvertex)) {
228 if (!bin->FillHists(&fmddNdetadphi)) return kFALSE;
229 bin->CumulantsAccumulate(fCent);
233 TIter nextSPD(&fBinsSPD);
234 while ((bin = static_cast<VertexBin*>(nextSPD()))) {
235 if (bin->CheckVertex(fZvertex)) {
236 if (!bin->FillHists(&spddNdetadphi)) return kFALSE;
237 bin->CumulantsAccumulate(fCent);
243 //_____________________________________________________________________
244 void AliForwardFlowTaskQC::Terminate(Option_t */*option*/)
247 // Calls the finalize function, done at the end of the analysis
253 // Make sure pointers are set to the correct lists
254 fSumList = dynamic_cast<TList*> (GetOutputData(1));
256 AliError("Could not retrieve TList fSumList");
261 fOutputList = new TList();
262 fOutputList->SetName("Results");
263 fOutputList->SetOwner();
265 // Run finalize on VertexBins
268 // Collect centralities
269 TProfile2D* hist2D = 0;
272 TIter nextProfile(fOutputList);
273 while ((hist2D = dynamic_cast<TProfile2D*>(nextProfile()))) {
274 for (Int_t cBin = 1; cBin <= hist2D->GetNbinsY(); ) {
275 Int_t cRat = 100/hist2D->GetNbinsY();
276 Int_t cMin = cBin - 1;
277 Int_t cMax = (cMin < 80/cRat ? (cMin < 20/cRat ? cMin + 5/cRat : cMin + 10/cRat) : cMin + 20/cRat);
278 TString name = Form("cent_%d-%d", cMin*cRat, cMax*cRat);
279 centList = (TList*)fOutputList->FindObject(name.Data());
281 centList = new TList();
282 centList->SetName(name.Data());
283 fOutputList->Add(centList);
285 hist1D = hist2D->ProjectionX(Form("%s_%s", hist2D->GetName(), name.Data()),
287 hist1D->SetTitle(hist1D->GetName());
288 hist1D->Scale(1./(cMax-cMin));
289 centList->Add(hist1D);
295 PostData(2, fOutputList);
298 //_____________________________________________________________________
299 void AliForwardFlowTaskQC::Finalize()
302 // Finalize command, called by Terminate()
306 // Reinitiate vertex bins if Terminate is called separately!
307 if (fBinsFMD.GetEntries() == 0) InitVertexBins();
309 // Iterate over all vertex bins objects and finalize cumulants
311 TIter nextFMD(&fBinsFMD);
313 while ((bin = static_cast<VertexBin*>(nextFMD()))) {
314 bin->CumulantsTerminate(fSumList, fOutputList);
316 TIter nextSPD(&fBinsSPD);
317 while ((bin = static_cast<VertexBin*>(nextSPD()))) {
318 bin->CumulantsTerminate(fSumList, fOutputList);
322 // _____________________________________________________________________
323 Bool_t AliForwardFlowTaskQC::AODCheck(const AliAODForwardMult* aodfm)
326 // Function to check that and AOD event meets the cuts
329 // AliAODForwardMult: forward mult object with trigger and vertex info
331 // Returns false if there is no trigger or if the centrality or vertex
332 // is out of range. Otherwise true.
335 // First check for trigger
336 if (!aodfm->IsTriggerBits(AliAODForwardMult::kOffline)) return kFALSE;
338 // Then check for centrality
339 fCent = (Double_t)aodfm->GetCentrality();
340 if (0. >= fCent || fCent >= 100.) return kFALSE;
341 fHistCent->Fill(fCent);
343 // And finally check for vertex
344 fZvertex = aodfm->GetIpZ();
345 fHistVertexAll->Fill(fZvertex);
346 if (TMath::Abs(fZvertex) >= 10.) return kFALSE;
347 fHistVertexSel->Fill(fZvertex);
352 //_____________________________________________________________________
353 AliForwardFlowTaskQC::VertexBin::VertexBin()
355 fMoment(0), // Flow moment for this vertexbin
356 fVzMin(0), // Vertex z-coordinate min
357 fVzMax(0), // Vertex z-coordinate max
358 fType(), // Data type (FMD/SPD/FMDTR/SPDTR/MC)
359 fCumuRef(), // Histogram for reference flow
360 fCumuDiff(), // Histogram for differential flow
361 fCumuHist(), // Sum histogram for cumulants
362 fdNdedpAcc() // Diagnostics histogram to make acc. maps
365 // Default constructor
368 //_____________________________________________________________________
369 AliForwardFlowTaskQC::VertexBin::VertexBin(const Int_t vLow, const Int_t vHigh,
370 const Int_t moment, const Char_t* name)
372 fMoment(moment), // Flow moment for this vertexbin
373 fVzMin(vLow), // Vertex z-coordinate min
374 fVzMax(vHigh), // Vertex z-coordinate max
375 fType(name), // Data type (FMD/SPD/FMDTR/SPDTR/MC)
376 fCumuRef(), // Histogram for reference flow
377 fCumuDiff(), // Histogram for differential flow
378 fCumuHist(), // Sum histogram for cumulants
379 fdNdedpAcc() // Diagnostics histogram to make acc. maps
385 // vLow: min z-coordinate
386 // vHigh: max z-coordinate
387 // moment: flow moment
388 // name: data type name (FMD/SPD/FMDTR/SPDTR/MC)
390 SetName(Form("%svertexBin%d_%d_%d", name, moment, vLow, vHigh));
391 SetTitle(Form("%svertexBin%d_%d_%d", name, moment, vLow, vHigh));
394 //_____________________________________________________________________
395 AliForwardFlowTaskQC::VertexBin&
396 AliForwardFlowTaskQC::VertexBin::operator=(const AliForwardFlowTaskQC::VertexBin& o)
399 // Assignment operator
402 // o: AliForwardFlowTaskQC::VertexBin
404 if (&o == this) return *this;
406 fCumuRef = o.fCumuRef;
407 fCumuDiff = o.fCumuDiff;
408 fCumuHist = o.fCumuHist;
409 fdNdedpAcc = o.fdNdedpAcc;
413 //_____________________________________________________________________
414 void AliForwardFlowTaskQC::VertexBin::AddOutput(TList* outputlist)
417 // Add histograms to outputlist
420 // outputlist: list of histograms
423 // First we try to find an outputlist for this vertexbin
424 TList* list = (TList*)outputlist->FindObject(Form("%svertex_%d_%d", fType, fVzMin, fVzMax));
426 // If it doesn't exist we make one
429 list->SetName(Form("%svertex_%d_%d", fType, fVzMin, fVzMax));
430 outputlist->Add(list);
433 // We initiate the reference histogram according to an acceptance correction map,
434 // so we don't shift the SPD coverage within a reference bin
435 fCumuRef = new TH2D(Form("%s_v%d_%d_%d_ref", fType, fMoment, fVzMin, fVzMax),
436 Form("%s_v%d_%d_%d_ref", fType, fMoment, fVzMin, fVzMax),
437 24, -6., 6., 5, 0.5, 5.5);
438 TFile acc("$ALICE_ROOT/PWGLF/FORWARD/corrections/FlowCorrections/FlowAccMap.root", "READ");
439 TH1D* accMap = (TH1D*)acc.Get(Form("%saccVertex_%d_%d", fType, fVzMin, fVzMax));
441 Int_t nBins = accMap->GetNbinsX();
442 Double_t eta[48] = { 0. };
444 Double_t newOcc[48] = { 0. };
446 for (Int_t i = 0; i < nBins; i++) {
447 Double_t occ = accMap->GetBinContent(i+1);
448 if (prev != occ && (occ > 0.6 || occ == 0)) {
452 // printf("eta: %f \t occ: %f \t Vertex: %d \n", eta[n-1], occ, fVzMin);
457 fCumuRef->GetXaxis()->Set(n, eta);
462 //list->Add(fCumuRef);
464 // We initiate the differential histogram
465 fCumuDiff = new TH2D(Form("%s_v%d_%d_%d_diff", fType, fMoment, fVzMin, fVzMax),
466 Form("%s_v%d_%d_%d_diff", fType, fMoment, fVzMin, fVzMax),
467 48, -6., 6., 5, 0.5, 5.5);
469 //list->Add(fCumuDiff);
471 // Initiate the cumulant sum histogram
472 fCumuHist = new TH3D(Form("%sv%d_vertex_%d_%d", fType, fMoment, fVzMin, fVzMax),
473 Form("%sv%d_vertex_%d_%d", fType, fMoment, fVzMin, fVzMax),
474 48, -6., 6., 20, 0., 100., 26, 0.5, 26.5);
477 list->Add(fCumuHist);
479 // We check for diagnostics histograms (only done per type and moment, not vertexbin)
480 // If they are not found we create them.
481 TList* dList = (TList*)outputlist->FindObject("Diagnostics");
482 if (!dList) AliFatal("No diagnostics list found, what kind of game are you running here?!?!");
484 // Acceptance hists are shared over all moments
485 fdNdedpAcc = (TH2D*)dList->FindObject(Form("h%sdNdedpAcc_%d_%d", fType, fVzMin, fVzMax));
487 fdNdedpAcc = new TH2D(Form("h%sdNdedpAcc_%d_%d", fType, fVzMin, fVzMax),
488 Form("%s acceptance map for %d cm < v_{z} < %d cm", fType, fVzMin, fVzMax),
489 48, -6, 6, 20, 0, TMath::TwoPi());
491 dList->Add(fdNdedpAcc);
496 //_____________________________________________________________________
497 Bool_t AliForwardFlowTaskQC::VertexBin::CheckVertex(Double_t vz)
500 // We check if this is the correct bin for the current event's vertex
503 // vZ: Current event vertex
505 // Returns false if out of range, true otherwise
507 if ((Double_t)fVzMin > vz) return kFALSE;
508 if ((Double_t)fVzMax <= vz) return kFALSE;
512 //_____________________________________________________________________
513 Bool_t AliForwardFlowTaskQC::VertexBin::FillHists(TH2D* dNdetadphi)
516 // Fill reference and differential eta-histograms
519 // dNdetadphi: 2D histogram with input data
522 if (!fCumuRef) AliFatal("You have not called AddOutput() - Terminating!");
524 // Fist we reset histograms
528 // Numbers to cut away bad events and acceptance.
533 Int_t nBins = (dNdetadphi->GetNbinsX() * 6) / (fCumuDiff->GetNbinsX() * 5);
535 Int_t nCurBin = 0, nPrevBin = 1;
537 // Then we loop over the input and calculate sum cos(k*n*phi)
538 // and fill it in the reference and differential histograms
539 Double_t eta, phi, weight;
540 Double_t dQnRe = 0, dQ2nRe = 0, dQnIm = 0, dQ2nIm = 0;
541 for (Int_t etaBin = 1; etaBin <= dNdetadphi->GetNbinsX(); etaBin++) {
542 eta = dNdetadphi->GetXaxis()->GetBinCenter(etaBin);
543 nCurBin = fCumuDiff->GetXaxis()->FindBin(eta);
544 // If we have moved to a new bin in the flow hist, and less than half the eta
545 // region has been covered by it we cut it away.
546 if (nCurBin != nPrevBin) {
547 if (nInBin <= nBins/2) {
548 for (Int_t pBin = 1; pBin <= fCumuDiff->GetNbinsY(); pBin++) {
549 fCumuDiff->SetBinContent(nPrevBin, pBin, 0);
550 fCumuDiff->SetBinError(nPrevBin, pBin, 0);
559 Bool_t data = kFALSE;
560 for (Int_t phiBin = 1; phiBin <= dNdetadphi->GetNbinsY(); phiBin++) {
561 phi = dNdetadphi->GetYaxis()->GetBinCenter(phiBin);
562 weight = dNdetadphi->GetBinContent(etaBin, phiBin);
563 if (!weight) continue;
564 if (!data) data = kTRUE;
565 // We calculate the running average Nch per. bin
570 // if the current bin has more than write the avg we count a bad bin
571 if (weight > max) max = weight;
573 dQnRe = weight*TMath::Cos(fMoment*phi);
574 dQnIm = weight*TMath::Sin(fMoment*phi);
575 dQ2nRe = weight*TMath::Cos(2.*fMoment*phi);
576 dQ2nIm = weight*TMath::Sin(2.*fMoment*phi);
578 fCumuRef->Fill(eta, kHmult, weight);
579 fCumuRef->Fill(eta, kHQnRe, dQnRe);
580 fCumuRef->Fill(eta, kHQnIm, dQnIm);
581 fCumuRef->Fill(eta, kHQ2nRe, dQ2nRe);
582 fCumuRef->Fill(eta, kHQ2nIm, dQ2nIm);
584 fCumuDiff->Fill(eta, kHmult, weight);
585 fCumuDiff->Fill(eta, kHQnRe, dQnRe);
586 fCumuDiff->Fill(eta, kHQnIm, dQnIm);
587 fCumuDiff->Fill(eta, kHQ2nRe, dQ2nRe);
588 fCumuDiff->Fill(eta, kHQ2nIm, dQ2nIm);
591 fdNdedpAcc->Fill(eta, phi, weight);
595 if (max > 2*runAvg) nBadBins++;
597 // If there are too many bad bins we throw the event away!
598 if (nBadBins > 3) return kFALSE;
602 //_____________________________________________________________________
603 void AliForwardFlowTaskQC::VertexBin::CumulantsAccumulate(Double_t cent)
606 // Calculate the Q cumulant of order fMoment
609 // cent: Centrality of event
612 if (!fCumuRef) AliFatal("You have not called AddOutput() - Terminating!");
614 // We create the objects needed for the analysis
615 Double_t dQnRe = 0, dQ2nRe = 0, dQnIm = 0, dQ2nIm = 0, mult = 0;
616 Double_t pnRe = 0, p2nRe = 0, qnRe = 0, q2nRe = 0, pnIm = 0, p2nIm = 0, qnIm = 0, q2nIm = 0;
617 Double_t two = 0, four = 0, twoPrime = 0, fourPrime = 0;
618 Double_t cosPhi1Phi2 = 0, cosPhi1Phi2Phi3m = 0;
619 Double_t sinPhi1Phi2 = 0, sinPhi1Phi2Phi3m = 0;
620 Double_t cosPsi1Phi2 = 0, cosPsi1Phi2Phi3m = 0, cosPsi1Phi2Phi3p = 0;
621 Double_t sinPsi1Phi2 = 0, sinPsi1Phi2Phi3m = 0, sinPsi1Phi2Phi3p = 0;
623 Double_t multi = 0, multp = 0, mp = 0, mq = 0;
624 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
627 // We loop over the data 1 time!
628 for (Int_t etaBin = 1; etaBin <= fCumuDiff->GetNbinsX(); etaBin++) {
629 eta = fCumuDiff->GetXaxis()->GetBinCenter(etaBin);
630 refEtaBin = fCumuRef->GetXaxis()->FindBin(eta);
631 // The values for each individual etaBin bins are reset
645 multi = fCumuRef->GetBinContent(refEtaBin, kHmult);
646 dQnRe = fCumuRef->GetBinContent(refEtaBin, kHQnRe);
647 dQnIm = fCumuRef->GetBinContent(refEtaBin, kHQnIm);
648 dQ2nRe = fCumuRef->GetBinContent(refEtaBin, kHQ2nRe);
649 dQ2nIm = fCumuRef->GetBinContent(refEtaBin, kHQ2nIm);
652 // For each etaBin bin the necessary values for differential flow
653 // is calculated. Here is the loop over the phi's.
654 multp = fCumuDiff->GetBinContent(etaBin, kHmult);
655 pnRe = fCumuDiff->GetBinContent(etaBin, kHQnRe);
656 pnIm = fCumuDiff->GetBinContent(etaBin, kHQnIm);
657 p2nRe = fCumuDiff->GetBinContent(etaBin, kHQ2nRe);
658 p2nIm = fCumuDiff->GetBinContent(etaBin, kHQ2nIm);
661 if (mult <= 3) continue;
663 if (mp == 0) continue;
664 // The reference flow is calculated
667 w2 = mult * (mult - 1.);
668 two = dQnRe*dQnRe + dQnIm*dQnIm - mult;
670 fCumuHist->Fill(eta, cent, kW2Two, two);
671 fCumuHist->Fill(eta, cent, kW2, w2);
673 fCumuHist->Fill(eta, cent, kQnRe, dQnRe);
674 fCumuHist->Fill(eta, cent, kQnIm, dQnIm);
675 fCumuHist->Fill(eta, cent, kM, mult);
678 w4 = mult * (mult - 1.) * (mult - 2.) * (mult - 3.);
680 four = 2.*mult*(mult-3.) + TMath::Power((TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.)),2.)
681 -4.*(mult-2.)*(TMath::Power(dQnRe,2.) + TMath::Power(dQnIm,2.))
682 -2.*(TMath::Power(dQnRe,2.)*dQ2nRe+2.*dQnRe*dQnIm*dQ2nIm-TMath::Power(dQnIm,2.)*dQ2nRe)
683 +(TMath::Power(dQ2nRe,2.)+TMath::Power(dQ2nIm,2.));
685 fCumuHist->Fill(eta, cent, kW4Four, four);
686 fCumuHist->Fill(eta, cent, kW4, w4);
688 cosPhi1Phi2 = dQnRe*dQnRe - dQnIm*dQnIm - dQ2nRe;
689 sinPhi1Phi2 = 2.*dQnRe*dQnIm - dQ2nIm;
691 cosPhi1Phi2Phi3m = dQnRe*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))-dQnRe*dQ2nRe-dQnIm*dQ2nIm-2.*(mult-1)*dQnRe;
693 sinPhi1Phi2Phi3m = -dQnIm*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))+dQnRe*dQ2nIm-dQnIm*dQ2nRe+2.*(mult-1)*dQnIm;
695 fCumuHist->Fill(eta, cent, kCosphi1phi2, cosPhi1Phi2);
696 fCumuHist->Fill(eta, cent, kSinphi1phi2, sinPhi1Phi2);
697 fCumuHist->Fill(eta, cent, kCosphi1phi2phi3m, cosPhi1Phi2Phi3m);
698 fCumuHist->Fill(eta, cent, kSinphi1phi2phi3m, sinPhi1Phi2Phi3m);
699 fCumuHist->Fill(eta, cent, kMm1m2, mult*(mult-1.)*(mult-2.));
701 // Differential flow calculations for each eta bin bin is done:
708 // 2-particle differential flow
709 w2p = mp * mult - mq;
710 twoPrime = pnRe*dQnRe + pnIm*dQnIm - mq;
712 fCumuHist->Fill(eta, cent, kw2two, twoPrime);
713 fCumuHist->Fill(eta, cent, kw2, w2p);
715 fCumuHist->Fill(eta, cent, kpnRe, pnRe);
716 fCumuHist->Fill(eta, cent, kpnIm, pnIm);
717 fCumuHist->Fill(eta, cent, kmp, mp);
719 // 4-particle differential flow
720 w4p = (mp * mult - 3.*mq)*(mult - 1.)*(mult - 2.);
722 fourPrime = (TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*(pnRe*dQnRe+pnIm*dQnIm)
723 - q2nRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))
724 - 2.*q2nIm*dQnRe*dQnIm
725 - pnRe*(dQnRe*dQ2nRe+dQnIm*dQ2nIm)
726 + pnIm*(dQnIm*dQ2nRe-dQnRe*dQ2nIm)
727 - 2.*mult*(pnRe*dQnRe+pnIm*dQnIm)
728 - 2.*(TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*mq
729 + 6.*(qnRe*dQnRe+qnIm*dQnIm)
730 + 1.*(q2nRe*dQ2nRe+q2nIm*dQ2nIm)
731 + 2.*(pnRe*dQnRe+pnIm*dQnIm)
735 fCumuHist->Fill(eta, cent, kw4four, fourPrime);
736 fCumuHist->Fill(eta, cent, kw4, w4p);
738 cosPsi1Phi2 = pnRe*dQnRe - pnIm*dQnIm - q2nRe;
739 sinPsi1Phi2 = pnRe*dQnIm + pnIm*dQnRe - q2nIm;
741 cosPsi1Phi2Phi3p = pnRe*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
742 - 1.*(q2nRe*dQnRe+q2nIm*dQnIm)
745 sinPsi1Phi2Phi3p = pnIm*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
746 - 1.*(q2nIm*dQnRe-q2nRe*dQnIm)
749 cosPsi1Phi2Phi3m = pnRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))+2.*pnIm*dQnRe*dQnIm
750 - 1.*(pnRe*dQ2nRe+pnIm*dQ2nIm)
751 - 2.*mq*dQnRe+2.*qnRe;
753 sinPsi1Phi2Phi3m = pnIm*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))-2.*pnRe*dQnRe*dQnIm
754 - 1.*(pnIm*dQ2nRe-pnRe*dQ2nIm)
755 + 2.*mq*dQnIm-2.*qnIm;
757 fCumuHist->Fill(eta, cent, kCospsi1phi2, cosPsi1Phi2);
758 fCumuHist->Fill(eta, cent, kSinpsi1phi2, sinPsi1Phi2);
759 fCumuHist->Fill(eta, cent, kCospsi1phi2phi3m, cosPsi1Phi2Phi3m);
760 fCumuHist->Fill(eta, cent, kSinpsi1phi2phi3m, sinPsi1Phi2Phi3m);
761 fCumuHist->Fill(eta, cent, kmpmq, (mp*mult-2.*mq)*(mult-1.));
762 fCumuHist->Fill(eta, cent, kCospsi1phi2phi3p, cosPsi1Phi2Phi3p);
763 fCumuHist->Fill(eta, cent, kSinpsi1phi2phi3p, sinPsi1Phi2Phi3p);
766 fCumuHist->Fill(-7., cent, -0.5, 1.);
769 //_____________________________________________________________________
770 void AliForwardFlowTaskQC::VertexBin::CumulantsTerminate(TList* inlist, TList* outlist)
773 // Finalizes the Q cumulant calculations
776 // inlist: input sumlist
777 // outlist: output result list
780 // Re-find cumulants hist if Terminate is called separately
782 TList* list = (TList*)inlist->FindObject(Form("%svertex_%d_%d", fType, fVzMin, fVzMax));
783 fCumuHist = (TH3D*)list->FindObject(Form("%sv%d_vertex_%d_%d", fType, fMoment, fVzMin, fVzMax));
786 // Create result profiles
787 TProfile2D* cumu2 = (TProfile2D*)outlist->FindObject(Form("%sQC2_v%d_unCorr", fType, fMoment));
788 TProfile2D* cumu4 = (TProfile2D*)outlist->FindObject(Form("%sQC4_v%d_unCorr", fType, fMoment));
790 cumu2 = new TProfile2D(Form("%sQC2_v%d_unCorr", fType, fMoment),
791 Form("%sQC2_v%d_unCorr", fType, fMoment),
792 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
793 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
797 cumu4 = new TProfile2D(Form("%sQC4_v%d_unCorr", fType, fMoment),
798 Form("%sQC4_v%d_unCorr", fType, fMoment),
799 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
800 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
804 // For flow calculations
805 Double_t two = 0, qc2 = 0, vnTwo = 0, four = 0, qc4 = 0, vnFour = 0;
806 Double_t twoPrime = 0, qc2Prime = 0, vnTwoDiff = 0, fourPrime = 0, qc4Prime = 0, vnFourDiff = 0;
807 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
808 Double_t w2Two = 0, w2pTwoPrime = 0, w4Four = 0, w4pFourPrime = 0;
809 Double_t cosP1nPhi = 0, sinP1nPhi = 0, mult = 0, cosP1nPhi1P1nPhi2 = 0, sinP1nPhi1P1nPhi2 = 0;
810 Double_t cosP1nPhi1M1nPhi2M1nPhi3 = 0, sinP1nPhi1M1nPhi2M1nPhi3 = 0, multm1m2 = 0;
811 Double_t cosP1nPsi = 0, sinP1nPsi = 0, mp = 0, cosP1nPsi1P1nPhi2 = 0, sinP1nPsi1P1nPhi2 = 0;
812 Double_t cosP1nPsi1M1nPhi2M1nPhi3 = 0, sinP1nPsi1M1nPhi2M1nPhi3 = 0, mpqMult = 0;
813 Double_t cosP1nPsi1P1nPhi2M1nPhi3 = 0, sinP1nPsi1P1nPhi2M1nPhi3 = 0;
815 // Loop over cumulant histogram for final calculations
817 for (Int_t cBin = 1; cBin <= fCumuHist->GetNbinsY(); cBin++) {
818 Double_t cent = fCumuHist->GetYaxis()->GetBinCenter(cBin);
821 for (Int_t etaBin = 1; etaBin <= fCumuHist->GetNbinsX(); etaBin++) {
822 Double_t eta = fCumuHist->GetXaxis()->GetBinCenter(etaBin);
823 // 2-particle reference flow
824 w2Two = fCumuHist->GetBinContent(etaBin, cBin, kW2Two);
825 w2 = fCumuHist->GetBinContent(etaBin, cBin, kW2);
826 mult = fCumuHist->GetBinContent(etaBin, cBin, kM);
827 if (!w2 || !mult) continue;
828 cosP1nPhi = fCumuHist->GetBinContent(etaBin, cBin, kQnRe);
829 sinP1nPhi = fCumuHist->GetBinContent(etaBin, cBin, kQnIm);
834 qc2 = two - TMath::Power(cosP1nPhi, 2) - TMath::Power(sinP1nPhi, 2);
835 if (qc2 <= 0) continue;
836 vnTwo = TMath::Sqrt(qc2);
837 // if (!TMath::IsNaN(vnTwo*mult))
838 // cumu2->Fill(eta, cent, vnTwo, fCumuHist->GetBinContent(0,cBin,0));
840 // 4-particle reference flow
841 w4Four = fCumuHist->GetBinContent(etaBin, cBin, kW4Four);
842 w4 = fCumuHist->GetBinContent(etaBin, cBin, kW4);
843 multm1m2 = fCumuHist->GetBinContent(etaBin, cBin, kMm1m2);
844 if (!w4 || !multm1m2) continue;
845 cosP1nPhi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kCosphi1phi2);
846 sinP1nPhi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kSinphi1phi2);
847 cosP1nPhi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCosphi1phi2phi3m);
848 sinP1nPhi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinphi1phi2phi3m);
850 cosP1nPhi1P1nPhi2 /= w2;
851 sinP1nPhi1P1nPhi2 /= w2;
852 cosP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
853 sinP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
855 qc4 = four-2.*TMath::Power(two,2.)
856 - 4.*cosP1nPhi*cosP1nPhi1M1nPhi2M1nPhi3
857 + 4.*sinP1nPhi*sinP1nPhi1M1nPhi2M1nPhi3-TMath::Power(cosP1nPhi1P1nPhi2,2.)-TMath::Power(sinP1nPhi1P1nPhi2,2.)
858 + 4.*cosP1nPhi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
859 + 8.*sinP1nPhi1P1nPhi2*sinP1nPhi*cosP1nPhi
860 + 8.*two*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
861 - 6.*TMath::Power((TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.)),2.);
863 if (qc4 >= 0) continue;
864 vnFour = TMath::Power(-qc4, 0.25);
865 // if (!TMath::IsNaN(vnFour*mult))
866 // cumu4->Fill(eta, cent, vnFour, fCumuHist->GetBinContent(0,cBin,0));
868 // 2-particle differential flow
869 w2pTwoPrime = fCumuHist->GetBinContent(etaBin, cBin, kw2two);
870 w2p = fCumuHist->GetBinContent(etaBin, cBin, kw2);
871 mp = fCumuHist->GetBinContent(etaBin, cBin, kmp);
872 if (!w2p || !mp) continue;
873 cosP1nPsi = fCumuHist->GetBinContent(etaBin, cBin, kpnRe);
874 sinP1nPsi = fCumuHist->GetBinContent(etaBin, cBin, kpnIm);
878 twoPrime = w2pTwoPrime / w2p;
879 qc2Prime = twoPrime - sinP1nPsi*sinP1nPhi - cosP1nPsi*cosP1nPhi;
881 vnTwoDiff = qc2Prime / TMath::Sqrt(qc2);
882 if (!TMath::IsNaN(vnTwoDiff*mp)) cumu2->Fill(eta, cent, vnTwoDiff, fCumuHist->GetBinContent(0,cBin,0));
884 // 4-particle differential flow
885 w4pFourPrime = fCumuHist->GetBinContent(etaBin, cBin, kw4four);
886 w4p = fCumuHist->GetBinContent(etaBin, cBin, kw4);
887 mpqMult = fCumuHist->GetBinContent(etaBin, cBin, kmpmq);
888 if (!w4p || !mpqMult) continue;
889 cosP1nPsi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2);
890 sinP1nPsi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2);
891 cosP1nPsi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2phi3m);
892 sinP1nPsi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2phi3m);
893 cosP1nPsi1P1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2phi3p);
894 sinP1nPsi1P1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2phi3p);
896 cosP1nPsi1P1nPhi2 /= w2p;
897 sinP1nPsi1P1nPhi2 /= w2p;
898 cosP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
899 sinP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
900 cosP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
901 sinP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
903 fourPrime = w4pFourPrime / w4p;
905 qc4Prime = fourPrime-2.*twoPrime*two
906 - cosP1nPsi*cosP1nPhi1M1nPhi2M1nPhi3
907 + sinP1nPsi*sinP1nPhi1M1nPhi2M1nPhi3
908 - cosP1nPhi*cosP1nPsi1M1nPhi2M1nPhi3
909 + sinP1nPhi*sinP1nPsi1M1nPhi2M1nPhi3
910 - 2.*cosP1nPhi*cosP1nPsi1P1nPhi2M1nPhi3
911 - 2.*sinP1nPhi*sinP1nPsi1P1nPhi2M1nPhi3
912 - cosP1nPsi1P1nPhi2*cosP1nPhi1P1nPhi2
913 - sinP1nPsi1P1nPhi2*sinP1nPhi1P1nPhi2
914 + 2.*cosP1nPhi1P1nPhi2*(cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
915 + 2.*sinP1nPhi1P1nPhi2*(cosP1nPsi*sinP1nPhi+sinP1nPsi*cosP1nPhi)
916 + 4.*two*(cosP1nPsi*cosP1nPhi+sinP1nPsi*sinP1nPhi)
917 + 2.*cosP1nPsi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
918 + 4.*sinP1nPsi1P1nPhi2*cosP1nPhi*sinP1nPhi
919 + 4.*twoPrime*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
920 - 6.*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
921 * (cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
922 - 12.*cosP1nPhi*sinP1nPhi
923 * (sinP1nPsi*cosP1nPhi+cosP1nPsi*sinP1nPhi);
925 vnFourDiff = - qc4Prime / TMath::Power(-qc4, 0.75);
926 if (!TMath::IsNaN(vnFourDiff*mp)) cumu4->Fill(eta, cent, vnFourDiff, fCumuHist->GetBinContent(0,cBin,0));
929 nEv += fCumuHist->GetBinContent(0,cBin,0);
930 cumu2->Fill(7., cent, nEv);
931 cumu4->Fill(7., cent, nEv);
932 } // End of centrality loop
936 //_____________________________________________________________________