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"
22 #include "AliForwardFlowTaskQC.h"
23 #include "AliAnalysisManager.h"
24 #include "AliAODHandler.h"
25 #include "AliAODInputHandler.h"
26 #include "AliAODForwardMult.h"
27 #include "AliAODCentralMult.h"
28 #include "AliAODEvent.h"
30 ClassImp(AliForwardFlowTaskQC)
35 AliForwardFlowTaskQC::AliForwardFlowTaskQC()
36 : AliAnalysisTaskSE(),
37 fVtxAxis(), // Axis to contorl vertex binning
38 fFMDCut(-1), // FMD sigma cut
39 fSPDCut(-1), // SPD sigma cut
40 fBinsFMD(), // List with FMD flow histos
41 fBinsSPD(), // List with SPD flow histos
42 fSumList(0), // Event sum list
43 fOutputList(0), // Result output list
44 fAOD(0), // AOD input event
45 fVtx(1111), // Z vertex coordinate
46 fCent(-1), // Centrality
47 fHistCent(), // Histo for centrality
48 fHistVertexSel() // Histo for selected vertices
51 // Default constructor
53 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
55 //_____________________________________________________________________
56 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const char* name)
57 : AliAnalysisTaskSE(name),
58 fVtxAxis(), // Axis to contorl vertex binning
59 fFMDCut(-1), // FMD sigma cut
60 fSPDCut(-1), // SPD sigma cut
61 fBinsFMD(), // List with FMD flow histos
62 fBinsSPD(), // List with SPD flow histos
63 fSumList(0), // Event sum list
64 fOutputList(0), // Result output list
65 fAOD(0), // AOD input event
66 fVtx(1111), // Z vertex coordinate
67 fCent(-1), // Centrality
68 fHistCent(), // Histo for centrality
69 fHistVertexSel() // Histo for selected vertices
77 for (Int_t n = 0; n <= 6; n++) fv[n] = kTRUE;
79 DefineOutput(1, TList::Class());
80 DefineOutput(2, TList::Class());
82 //_____________________________________________________________________
83 Bool_t AliForwardFlowTaskQC::fgDispVtx = kFALSE;
84 //_____________________________________________________________________
85 AliForwardFlowTaskQC::AliForwardFlowTaskQC(const AliForwardFlowTaskQC& o)
86 : AliAnalysisTaskSE(o),
87 fVtxAxis(o.fVtxAxis), // Axis to contorl vertex binning
88 fFMDCut(o.fFMDCut), // FMD sigma cut
89 fSPDCut(o.fSPDCut), // SPD sigma cut
90 fBinsFMD(), // List with FMD flow histos
91 fBinsSPD(), // List with SPD flow histos
92 fSumList(o.fSumList), // Event sum list
93 fOutputList(o.fOutputList), // Result output list
94 fAOD(o.fAOD), // AOD input event
95 fVtx(o.fVtx), // Z vertex coordinate
96 fCent(o.fCent), // Centrality
97 fHistCent(o.fHistCent), // Histo for centrality
98 fHistVertexSel(o.fHistVertexSel) // Histo for selected vertices
104 // o Object to copy from
106 for (Int_t n = 0; n <= 6; n++) fv[n] = o.fv[n];
108 //_____________________________________________________________________
109 AliForwardFlowTaskQC&
110 AliForwardFlowTaskQC::operator=(const AliForwardFlowTaskQC& o)
113 // Assignment operator
115 if (&o == this) return *this;
116 fVtxAxis = o.fVtxAxis;
119 fSumList = o.fSumList;
120 fOutputList = o.fOutputList;
124 fHistCent = o.fHistCent;
125 fHistVertexSel = o.fHistVertexSel;
127 for (Int_t n = 0; n <= 6; n++) fv[n] = o.fv[n];
130 //_____________________________________________________________________
131 void AliForwardFlowTaskQC::UserCreateOutputObjects()
134 // Create output objects
140 PostData(1, fSumList);
141 PostData(2, fOutputList);
144 //_____________________________________________________________________
145 void AliForwardFlowTaskQC::InitVertexBins()
148 // Init vertexbin objects for FMD and SPD, and add them to the lists
150 for(UShort_t n = 2; n <= 6; n++) {
151 if (!fv[n]) continue;
152 for (Int_t v = 1; v <= fVtxAxis->GetNbins(); v++) {
153 fBinsFMD.Add(new VertexBin(fVtxAxis->GetBinLowEdge(v), fVtxAxis->GetBinUpEdge(v), n,
154 "FMD", (fgDispVtx ? kFALSE : kTRUE), fFMDCut));
155 fBinsSPD.Add(new VertexBin(fVtxAxis->GetBinLowEdge(v), fVtxAxis->GetBinUpEdge(v), n,
156 "SPD", kFALSE, fSPDCut));
161 //_____________________________________________________________________
162 void AliForwardFlowTaskQC::InitHists()
165 // Init histograms and add vertex bin histograms to the sum list
168 fSumList = new TList();
169 fSumList->SetName("Sums");
170 fSumList->SetOwner();
172 if (!fVtxAxis) fVtxAxis = new TAxis(20, -10, 10);
173 fVtxAxis->SetName("VtxAxis");
174 fHistCent = new TH1D("hCent", "Centralities", 100, 0, 100);
175 fHistVertexSel = new TH1D("hVertexSel", "Selected vertices", fVtxAxis->GetNbins(), fVtxAxis->GetXmin(), fVtxAxis->GetXmax());
177 TList* dList = new TList();
178 dList->SetName("Diagnostics");
179 dList->Add(fVtxAxis);
180 dList->Add(fHistCent);
181 dList->Add(fHistVertexSel);
182 fSumList->Add(dList);
184 TIter nextFMD(&fBinsFMD);
186 while ((bin = static_cast<VertexBin*>(nextFMD()))) {
187 bin->AddOutput(fSumList);
189 TIter nextSPD(&fBinsSPD);
190 while ((bin = static_cast<VertexBin*>(nextSPD()))) {
191 bin->AddOutput(fSumList);
194 //_____________________________________________________________________
195 void AliForwardFlowTaskQC::UserExec(Option_t */*option*/)
198 // Calls the analyze function - called every event
206 PostData(1, fSumList);
210 //_____________________________________________________________________
211 Bool_t AliForwardFlowTaskQC::Analyze()
214 // Load FMD and SPD objects from aod tree and call the cumulants
215 // calculation for the correct vertexbin
218 // Reset data members
223 fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
224 if (!fAOD) return kFALSE;
226 const AliAODForwardMult* aodfmult = static_cast<AliAODForwardMult*>(fAOD->FindListObject("Forward"));
227 const AliAODCentralMult* aodcmult = static_cast<AliAODCentralMult*>(fAOD->FindListObject("CentralClusters"));
228 if (!aodfmult) return kFALSE;
230 // Check event for triggers, get centrality, vtx etc.
231 if (!CheckEvent(aodfmult)) return kFALSE;
232 Int_t vtx = fVtxAxis->FindBin(fVtx)-1;
234 // If everything is OK: get histos and run analysis
235 const TH2D& fmddNdetadphi = aodfmult->GetHistogram();
236 FillVtxBinList(fBinsFMD, fmddNdetadphi, vtx);
239 const TH2D& spddNdetadphi = aodcmult->GetHistogram();
240 FillVtxBinList(fBinsSPD, spddNdetadphi, vtx);
245 //_____________________________________________________________________
246 Bool_t AliForwardFlowTaskQC::FillVtxBinList(const TList& list, const TH2D& h, Int_t vtx) const
249 // Loops over list of VtxBins, fills hists of bins for current vertex
250 // and runs analysis on those bins
253 // list: list of VtxBins
254 // h: dN/detadphi histogram
255 // vBin: current vertex bin
257 // return true on success
261 Int_t nVtxBins = fVtxAxis->GetNbins();
263 while ((bin = static_cast<VertexBin*>(list.At(vtx+(nVtxBins*i))))) {
264 if (!bin->FillHists(h, fCent)) return kFALSE;
265 bin->CumulantsAccumulate(fCent);
271 //_____________________________________________________________________
272 void AliForwardFlowTaskQC::Terminate(Option_t */*option*/)
275 // Calls the finalize function, done at the end of the analysis
281 // Make sure pointers are set to the correct lists
282 fSumList = dynamic_cast<TList*> (GetOutputData(1));
284 AliError("Could not retrieve TList fSumList");
289 fOutputList = new TList();
290 fOutputList->SetName("Results");
291 fOutputList->SetOwner();
296 // We make summary histograms of accepted events.
297 for (Int_t i = 1; i < fSumList->GetEntries(); i++) {
298 list = (TList*)fSumList->At(i);
299 hist = (TH3D*)list->At(0);
300 const char* histname = hist->GetName();
302 for (Int_t j = 0; ; j++) {
303 if (histname[j] == 'v') break;
306 cent = (TH1D*)fOutputList->FindObject(name.Data());
308 cent = new TH1D(name.Data(), name.Data(), hist->GetNbinsY(), hist->GetYaxis()->GetXmin(), hist->GetYaxis()->GetXmax());
309 fOutputList->Add(cent);
311 for (Int_t k = 1; k <= hist->GetNbinsY(); k++) {
312 Double_t centrality = hist->GetYaxis()->GetBinCenter(k);
313 Double_t events = hist->GetBinContent(0, k, 0);
314 cent->Fill(centrality, events);
318 // Run finalize on VertexBins
321 // Collect centralities
322 MakeCentralityHists(fOutputList);
323 TList* vtxList = (TList*)fOutputList->FindObject("vtxList");
324 if (vtxList) MakeCentralityHists(vtxList);
326 PostData(2, fOutputList);
330 //_____________________________________________________________________
331 void AliForwardFlowTaskQC::Finalize()
334 // Finalize command, called by Terminate()
337 // Reinitiate vertex bins if Terminate is called separately!
338 if (fBinsFMD.GetEntries() == 0) InitVertexBins();
340 // Iterate over all vertex bins objects and finalize cumulants
342 EndVtxBinList(fBinsFMD);
343 EndVtxBinList(fBinsSPD);
347 //_____________________________________________________________________
348 void AliForwardFlowTaskQC::EndVtxBinList(const TList& list) const
351 // Loop over VertexBin list and call terminate on each
354 // list VertexBin list
358 while ((bin = static_cast<VertexBin*>(next()))) {
359 bin->CumulantsTerminate(fSumList, fOutputList);
363 // _____________________________________________________________________
364 void AliForwardFlowTaskQC::MakeCentralityHists(TList* list)
367 // Loop over a list containing a TProfile2D with flow results and project
368 // and project to TH1's in specific centrality bins
371 // list Flow results list
373 TProfile2D* hist2D = 0;
377 TIter nextProfile(list);
378 while ((helper = dynamic_cast<TObject*>(nextProfile()))) {
379 if (!(hist2D = dynamic_cast<TProfile2D*>(helper))) continue;
380 for (Int_t cBin = 1; cBin <= hist2D->GetNbinsY(); cBin++) {
381 Int_t cRat = 100/hist2D->GetNbinsY();
382 Int_t cMin = cBin - 1;
383 Int_t cMax = (cMin == 60/cRat ? cMin + 20/cRat : ((cMin < 20/cRat || cMin >= 90) ? cMin + 5/cRat : cMin + 10/cRat));
386 cMin = Int_t(hist2D->GetYaxis()->GetBinLowEdge(cBin));
387 cMax = Int_t(hist2D->GetYaxis()->GetBinUpEdge(cBin));
389 TString name = Form("cent_%d-%d", cMin*cRat, cMax*cRat);
390 centList = (TList*)list->FindObject(name.Data());
392 centList = new TList();
393 centList->SetName(name.Data());
396 if (!fgDispVtx) hist1D = hist2D->ProjectionX(Form("%s_%s", hist2D->GetName(), name.Data()),
398 else if ( fgDispVtx) hist1D = hist2D->ProjectionX(Form("%s_%s", hist2D->GetName(), name.Data()),
400 hist1D->SetTitle(hist1D->GetName());
401 if (!fgDispVtx) hist1D->Scale(1./(cMax-cMin));
402 centList->Add(hist1D);
404 if (!fgDispVtx) cBin = cMax;
408 // _____________________________________________________________________
409 Bool_t AliForwardFlowTaskQC::CheckEvent(const AliAODForwardMult* aodfm)
412 // Function to check that and AOD event meets the cuts
415 // AliAODForwardMult: forward mult object with trigger and vertex info
417 // Returns false if there is no trigger or if the centrality or vertex
418 // is out of range. Otherwise true.
421 // First check for trigger
422 if (!CheckTrigger(aodfm)) return kFALSE;
424 // Then check for centrality
425 if (!GetCentrality(aodfm)) return kFALSE;
427 // And finally check for vertex
428 if (!GetVertex(aodfm)) return kFALSE;
430 // Ev. accepted - filling diag. hists
431 fHistCent->Fill(fCent);
432 fHistVertexSel->Fill(fVtx);
436 // _____________________________________________________________________
437 Bool_t AliForwardFlowTaskQC::CheckTrigger(const AliAODForwardMult* aodfm) const
440 // Function to look for a trigger string in the event.
443 // AliAODForwardMult: forward mult object with trigger and vertex info
445 // Returns true if offline trigger is present
447 return aodfm->IsTriggerBits(AliAODForwardMult::kOffline);
449 // _____________________________________________________________________
450 Bool_t AliForwardFlowTaskQC::GetCentrality(const AliAODForwardMult* aodfm)
453 // Function to look get centrality of the event.
456 // AliAODForwardMult: forward mult object with trigger and vertex info
458 // Returns true if centrality determination is present
460 if (aodfm->HasCentrality()) {
461 fCent = (Double_t)aodfm->GetCentrality();
462 if (0. >= fCent || fCent >= 100.) return kFALSE;
468 // _____________________________________________________________________
469 Bool_t AliForwardFlowTaskQC::GetVertex(const AliAODForwardMult* aodfm)
472 // Function to look for vertex determination in the event.
475 // AliAODForwardMult: forward mult object with trigger and vertex info
477 // Returns true if vertex is determined
479 fVtx = aodfm->GetIpZ();
480 if (fVtx < fVtxAxis->GetXmin() || fVtx > fVtxAxis->GetXmax()) return kFALSE;
484 //_____________________________________________________________________
485 AliForwardFlowTaskQC::VertexBin::VertexBin()
487 fMoment(0), // Flow moment for this vertexbin
488 fVzMin(0), // Vertex z-coordinate min
489 fVzMax(0), // Vertex z-coordinate max
490 fType(), // Data type name e.g., FMD/SPD/FMDTR/SPDTR/MC
491 fSymEta(1), // Use forward-backward symmetry, if detector allows it
492 fSigmaCut(-1), // Sigma cut to remove outlier events
493 fCumuRef(), // Histogram for reference flow
494 fCumuDiff(), // Histogram for differential flow
495 fCumuHist(), // Sum histogram for cumulants
496 fdNdedpAcc(), // Diagnostics histogram to make acc. maps
497 fOutliers(), // Histogram for sigma distribution
498 fDebug() // Debug level
501 // Default constructor
504 //_____________________________________________________________________
505 AliForwardFlowTaskQC::VertexBin::VertexBin(Int_t vLow, Int_t vHigh,
506 UShort_t moment, TString name,
507 Bool_t sym, Double_t cut)
509 fMoment(moment), // Flow moment for this vertexbin
510 fVzMin(vLow), // Vertex z-coordinate min
511 fVzMax(vHigh), // Vertex z-coordinate max
512 fType(name), // Data type name e.g., FMD/SPD/FMDTR/SPDTR/MC
513 fSymEta(sym), // Use forward-backward symmetry, if detector allows it
514 fSigmaCut(cut), // Sigma cut to remove outlier events
515 fCumuRef(), // Histogram for reference flow
516 fCumuDiff(), // Histogram for differential flow
517 fCumuHist(), // Sum histogram for cumulants
518 fdNdedpAcc(), // Diagnostics histogram to make acc. maps
519 fOutliers(), // Histogram for sigma distribution
520 fDebug(0) // Debug level
526 // vLow: min z-coordinate
527 // vHigh: max z-coordinate
528 // moment: flow moment
529 // name: data type name (FMD/SPD/FMDTR/SPDTR/MC)
530 // sym: data is symmetric in eta
534 SetName(Form("%svertexBin%d_%d_%d", fType.Data(), moment, vLow, vHigh));
535 SetTitle(Form("%svertexBin%d_%d_%d", fType.Data(), moment, vLow, vHigh));
537 fDebug = AliAnalysisManager::GetAnalysisManager()->GetDebugLevel();
540 //_____________________________________________________________________
541 AliForwardFlowTaskQC::VertexBin&
542 AliForwardFlowTaskQC::VertexBin::operator=(const AliForwardFlowTaskQC::VertexBin& o)
545 // Assignment operator
548 // o: AliForwardFlowTaskQC::VertexBin
550 if (&o == this) return *this;
552 fCumuRef = o.fCumuRef;
553 fCumuDiff = o.fCumuDiff;
554 fCumuHist = o.fCumuHist;
555 fdNdedpAcc = o.fdNdedpAcc;
556 fOutliers = o.fOutliers;
561 //_____________________________________________________________________
562 void AliForwardFlowTaskQC::VertexBin::AddOutput(TList* outputlist)
565 // Add histograms to outputlist
568 // outputlist: list of histograms
571 // First we try to find an outputlist for this vertexbin
572 TList* list = (TList*)outputlist->FindObject(Form("%svertex_%d_%d", fType.Data(), fVzMin, fVzMax));
574 // If it doesn't exist we make one
577 list->SetName(Form("%svertex_%d_%d", fType.Data(), fVzMin, fVzMax));
578 outputlist->Add(list);
581 // We initiate the reference histogram according to an acceptance correction map,
582 // so we don't shift the SPD coverage within a reference bin
583 // We start with many bins, to avoid memory problems. After checking for acc maps we
584 // rebin so those with full coverage only have 2 bins.
585 fCumuRef = new TH2D(Form("%s_v%d_%d_%d_ref", fType.Data(), fMoment, fVzMin, fVzMax),
586 Form("%s_v%d_%d_%d_ref", fType.Data(), fMoment, fVzMin, fVzMax),
587 48, -6., 6., 5, 0.5, 5.5);
588 TFile acc("$ALICE_ROOT/PWGLF/FORWARD/corrections/FlowCorrections/FlowAccMap.root", "READ");
589 TH1D* accMap = (TH1D*)acc.Get(Form("%saccVertex_%d_%d", fType.Data(), fVzMin, fVzMax));
590 if (accMap && !fType.EqualTo("FMD")) {
591 Int_t nBins = accMap->GetNbinsX();
592 Double_t eta[48] = { 0. };
594 // Double_t newOcc[48] = { 0. };
596 for (Int_t i = 0; i < nBins; i++) {
597 Double_t occ = accMap->GetBinContent(i+1);
598 if (prev != occ && (((occ > 0.6 || occ == 0) && i*0.25-6 < 4) || ((occ == 0) && i*0.25-6 >= 4))) {
602 if (fDebug > 5) AliInfo(Form("eta: %f \t occ: %f \t Vertex: %d \n", eta[n-1], occ, fVzMin));
607 fCumuRef->GetXaxis()->Set(n, eta);
609 fCumuRef->RebinX(24);
615 //list->Add(fCumuRef);
617 // We initiate the differential histogram
618 fCumuDiff = new TH2D(Form("%s_v%d_%d_%d_diff", fType.Data(), fMoment, fVzMin, fVzMax),
619 Form("%s_v%d_%d_%d_diff", fType.Data(), fMoment, fVzMin, fVzMax),
620 48, -6., 6., 5, 0.5, 5.5);
622 //list->Add(fCumuDiff);
624 // Initiate the cumulant sum histogram
625 fCumuHist = new TH3D(Form("%sv%d_vertex_%d_%d_cumu", fType.Data(), fMoment, fVzMin, fVzMax),
626 Form("%sv%d_vertex_%d_%d_cumu", fType.Data(), fMoment, fVzMin, fVzMax),
627 48, -6., 6., 20, 0., 100., 26, 0.5, 26.5);
629 SetupCentAxis(fCumuHist->GetYaxis());
631 list->Add(fCumuHist);
633 // We check for diagnostics histograms (only done per type and moment, not vertexbin)
634 // If they are not found we create them.
635 TList* dList = (TList*)outputlist->FindObject("Diagnostics");
636 if (!dList) AliFatal("No diagnostics list found, what kind of game are you running here?!?!");
638 // Acceptance hists are shared over all moments
639 fdNdedpAcc = (TH2F*)dList->FindObject(Form("h%sdNdedpAcc_%d_%d", fType.Data(), fVzMin, fVzMax));
641 fdNdedpAcc = new TH2F(Form("h%sdNdedpAcc_%d_%d", fType.Data(), fVzMin, fVzMax),
642 Form("%s acceptance map for %d cm < v_{z} < %d cm", fType.Data(), fVzMin, fVzMax),
643 48, -6, 6, 20, 0, TMath::TwoPi());
645 dList->Add(fdNdedpAcc);
647 TAxis* axis = (TAxis*)dList->FindObject(Form("axis%s_%d_%d", fType.Data(), fVzMin, fVzMax));
649 axis = fCumuRef->GetXaxis();
650 axis->SetName(Form("axis%s_%d_%d", fType.Data(), fVzMin, fVzMax));
651 // dList->Add(fCumuRef);
654 fOutliers = new TH2F(Form("hOutliers_%s_v%d_%d_%d", fType.Data(), fMoment, fVzMin, fVzMax),
655 Form("Maximum #sigma from mean N_{ch} pr. bin - %s v_{%d}, %d < v_{z} < %d",
656 fType.Data(), fMoment, fVzMin, fVzMax),
657 20, 0., 100., 500, 0., (fType.Contains("MC") ? 15. : 5.));
658 dList->Add(fOutliers);
661 //_____________________________________________________________________
662 Bool_t AliForwardFlowTaskQC::VertexBin::FillHists(const TH2D& dNdetadphi, Double_t cent)
665 // Fill reference and differential eta-histograms
668 // dNdetadphi: 2D histogram with input data
671 if (!fCumuRef) AliFatal("You have not called AddOutput() - Terminating!");
673 // Fist we reset histograms
677 // Numbers to cut away bad events and acceptance.
682 Int_t nBins = (dNdetadphi.GetNbinsX() * 6) / (fCumuDiff->GetNbinsX() * 5);
684 Int_t nCurBin = 0, nPrevBin = 0;
685 Int_t nCurRefBin = 0, nPrevRefBin = 0;
687 // Then we loop over the input and calculate sum cos(k*n*phi)
688 // and fill it in the reference and differential histograms
689 Double_t eta, phi, weight;
690 Double_t dQnRe = 0, dQ2nRe = 0, dQnIm = 0, dQ2nIm = 0;
691 for (Int_t etaBin = 1; etaBin <= dNdetadphi.GetNbinsX(); etaBin++) {
692 eta = dNdetadphi.GetXaxis()->GetBinCenter(etaBin);
693 nCurBin = fCumuDiff->GetXaxis()->FindBin(eta);
694 nCurRefBin = fCumuRef->GetXaxis()->FindBin(eta);
695 // If we have moved to a new bin in the flow hist, and less than half the eta
696 // region has been covered by it we cut it away.
697 if (!nPrevBin) nPrevBin = nCurBin;
698 if (!nPrevRefBin) nPrevRefBin = nCurRefBin;
699 if (nCurBin != nPrevBin) {
700 if (nCurRefBin != nPrevRefBin) {
701 if (nInBin <= nBins/2) {
702 for (Int_t qBin = 1; qBin <= fCumuDiff->GetNbinsY(); qBin++) {
703 Double_t removeContent = fCumuDiff->GetBinContent(nPrevBin, qBin);
704 Double_t removeEta = fCumuDiff->GetXaxis()->GetBinCenter(nPrevBin);
705 fCumuRef->Fill(removeEta, qBin, -removeContent);
706 if (fSymEta) fCumuRef->Fill(-1.*removeEta, qBin, -removeContent);
707 fCumuDiff->SetBinContent(nPrevBin, qBin, 0);
708 fCumuDiff->SetBinError(nPrevBin, qBin, 0);
711 nPrevRefBin = nCurRefBin;
716 Bool_t data = kFALSE;
717 for (Int_t phiBin = 0; phiBin <= dNdetadphi.GetNbinsY(); phiBin++) {
719 if (dNdetadphi.GetBinContent(etaBin, phiBin) == 0) break;
724 if (!AliForwardFlowTaskQC::fgDispVtx && (nCurBin == 34 || nCurBin == 35) && (phiBin == 17 || phiBin == 18)) continue;
725 if ( AliForwardFlowTaskQC::fgDispVtx && eta < 0 && (phiBin == 17 || phiBin == 18)) continue;
726 phi = dNdetadphi.GetYaxis()->GetBinCenter(phiBin);
727 weight = dNdetadphi.GetBinContent(etaBin, phiBin);
728 // We calculate the average Nch per. bin
729 avgSqr += weight*weight;
732 if (weight == 0) continue;
733 if (weight > max) max = weight;
735 dQnRe = weight*TMath::Cos(fMoment*phi);
736 dQnIm = weight*TMath::Sin(fMoment*phi);
737 dQ2nRe = weight*TMath::Cos(2.*fMoment*phi);
738 dQ2nIm = weight*TMath::Sin(2.*fMoment*phi);
740 fCumuRef->Fill(eta, kHmult, weight);
741 fCumuRef->Fill(eta, kHQnRe, dQnRe);
742 fCumuRef->Fill(eta, kHQnIm, dQnIm);
743 fCumuRef->Fill(eta, kHQ2nRe, dQ2nRe);
744 fCumuRef->Fill(eta, kHQ2nIm, dQ2nIm);
746 fCumuDiff->Fill(eta, kHmult, weight);
747 fCumuDiff->Fill(eta, kHQnRe, dQnRe);
748 fCumuDiff->Fill(eta, kHQnIm, dQnIm);
749 fCumuDiff->Fill(eta, kHQ2nRe, dQ2nRe);
750 fCumuDiff->Fill(eta, kHQ2nIm, dQ2nIm);
753 fdNdedpAcc->Fill(eta, phi, weight);
755 if (!fSymEta) continue;
757 fCumuRef->Fill(-eta, kHmult, weight);
758 fCumuRef->Fill(-eta, kHQnRe, dQnRe);
759 fCumuRef->Fill(-eta, kHQnIm, dQnIm);
760 fCumuRef->Fill(-eta, kHQ2nRe, dQ2nRe);
761 fCumuRef->Fill(-eta, kHQ2nIm, dQ2nIm);
770 Double_t stdev = TMath::Sqrt(nInAvg/(nInAvg-1))*TMath::Sqrt(avgSqr - runAvg*runAvg);
771 Double_t nSigma = (stdev == 0 ? 0 : (max-runAvg)/stdev);
772 if (fSigmaCut > 0. && nSigma >= fSigmaCut && cent <= 60) return kFALSE;
773 fOutliers->Fill(cent, nSigma);
784 //_____________________________________________________________________
785 void AliForwardFlowTaskQC::VertexBin::CumulantsAccumulate(Double_t cent)
788 // Calculate the Q cumulant of order fMoment
791 // cent: Centrality of event
794 if (!fCumuRef) AliFatal("You have not called AddOutput() - Terminating!");
796 // We create the objects needed for the analysis
797 Double_t dQnRe = 0, dQ2nRe = 0, dQnIm = 0, dQ2nIm = 0, mult = 0;
798 Double_t pnRe = 0, p2nRe = 0, qnRe = 0, q2nRe = 0, pnIm = 0, p2nIm = 0, qnIm = 0, q2nIm = 0;
799 Double_t two = 0, four = 0, twoPrime = 0, fourPrime = 0;
800 Double_t cosPhi1Phi2 = 0, cosPhi1Phi2Phi3m = 0;
801 Double_t sinPhi1Phi2 = 0, sinPhi1Phi2Phi3m = 0;
802 Double_t cosPsi1Phi2 = 0, cosPsi1Phi2Phi3m = 0, cosPsi1Phi2Phi3p = 0;
803 Double_t sinPsi1Phi2 = 0, sinPsi1Phi2Phi3m = 0, sinPsi1Phi2Phi3p = 0;
805 Double_t multi = 0, multp = 0, mp = 0, mq = 0;
806 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
809 // We loop over the data 1 time!
810 for (Int_t etaBin = 1; etaBin <= fCumuDiff->GetNbinsX(); etaBin++) {
811 eta = fCumuDiff->GetXaxis()->GetBinCenter(etaBin);
812 refEtaBin = fCumuRef->GetXaxis()->FindBin(eta);
813 // The values for each individual etaBin bins are reset
827 multi = fCumuRef->GetBinContent(refEtaBin, kHmult);
828 dQnRe = fCumuRef->GetBinContent(refEtaBin, kHQnRe);
829 dQnIm = fCumuRef->GetBinContent(refEtaBin, kHQnIm);
830 dQ2nRe = fCumuRef->GetBinContent(refEtaBin, kHQ2nRe);
831 dQ2nIm = fCumuRef->GetBinContent(refEtaBin, kHQ2nIm);
834 // For each etaBin bin the necessary values for differential flow
835 // is calculated. Here is the loop over the phi's.
836 multp = fCumuDiff->GetBinContent(etaBin, kHmult);
837 pnRe = fCumuDiff->GetBinContent(etaBin, kHQnRe);
838 pnIm = fCumuDiff->GetBinContent(etaBin, kHQnIm);
839 p2nRe = fCumuDiff->GetBinContent(etaBin, kHQ2nRe);
840 p2nIm = fCumuDiff->GetBinContent(etaBin, kHQ2nIm);
843 if (mult <= 3) continue;
845 if (mp == 0) continue;
846 // The reference flow is calculated
849 w2 = mult * (mult - 1.);
850 two = dQnRe*dQnRe + dQnIm*dQnIm - mult;
852 fCumuHist->Fill(eta, cent, kW2Two, two);
853 fCumuHist->Fill(eta, cent, kW2, w2);
855 fCumuHist->Fill(eta, cent, kQnRe, dQnRe);
856 fCumuHist->Fill(eta, cent, kQnIm, dQnIm);
857 fCumuHist->Fill(eta, cent, kM, mult);
860 w4 = mult * (mult - 1.) * (mult - 2.) * (mult - 3.);
862 four = 2.*mult*(mult-3.) + TMath::Power((TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.)),2.)
863 -4.*(mult-2.)*(TMath::Power(dQnRe,2.) + TMath::Power(dQnIm,2.))
864 -2.*(TMath::Power(dQnRe,2.)*dQ2nRe+2.*dQnRe*dQnIm*dQ2nIm-TMath::Power(dQnIm,2.)*dQ2nRe)
865 +(TMath::Power(dQ2nRe,2.)+TMath::Power(dQ2nIm,2.));
867 fCumuHist->Fill(eta, cent, kW4Four, four);
868 fCumuHist->Fill(eta, cent, kW4, w4);
870 cosPhi1Phi2 = dQnRe*dQnRe - dQnIm*dQnIm - dQ2nRe;
871 sinPhi1Phi2 = 2.*dQnRe*dQnIm - dQ2nIm;
873 cosPhi1Phi2Phi3m = dQnRe*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))-dQnRe*dQ2nRe-dQnIm*dQ2nIm-2.*(mult-1)*dQnRe;
875 sinPhi1Phi2Phi3m = -dQnIm*(TMath::Power(dQnRe,2)+TMath::Power(dQnIm,2))+dQnRe*dQ2nIm-dQnIm*dQ2nRe+2.*(mult-1)*dQnIm;
877 fCumuHist->Fill(eta, cent, kCosphi1phi2, cosPhi1Phi2);
878 fCumuHist->Fill(eta, cent, kSinphi1phi2, sinPhi1Phi2);
879 fCumuHist->Fill(eta, cent, kCosphi1phi2phi3m, cosPhi1Phi2Phi3m);
880 fCumuHist->Fill(eta, cent, kSinphi1phi2phi3m, sinPhi1Phi2Phi3m);
881 fCumuHist->Fill(eta, cent, kMm1m2, mult*(mult-1.)*(mult-2.));
883 // Differential flow calculations for each eta bin bin is done:
890 // 2-particle differential flow
891 w2p = mp * mult - mq;
892 twoPrime = pnRe*dQnRe + pnIm*dQnIm - mq;
894 fCumuHist->Fill(eta, cent, kw2two, twoPrime);
895 fCumuHist->Fill(eta, cent, kw2, w2p);
897 fCumuHist->Fill(eta, cent, kpnRe, pnRe);
898 fCumuHist->Fill(eta, cent, kpnIm, pnIm);
899 fCumuHist->Fill(eta, cent, kmp, mp);
901 // 4-particle differential flow
902 w4p = (mp * mult - 3.*mq)*(mult - 1.)*(mult - 2.);
904 fourPrime = (TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*(pnRe*dQnRe+pnIm*dQnIm)
905 - q2nRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))
906 - 2.*q2nIm*dQnRe*dQnIm
907 - pnRe*(dQnRe*dQ2nRe+dQnIm*dQ2nIm)
908 + pnIm*(dQnIm*dQ2nRe-dQnRe*dQ2nIm)
909 - 2.*mult*(pnRe*dQnRe+pnIm*dQnIm)
910 - 2.*(TMath::Power(dQnRe,2.)+TMath::Power(dQnIm,2.))*mq
911 + 6.*(qnRe*dQnRe+qnIm*dQnIm)
912 + 1.*(q2nRe*dQ2nRe+q2nIm*dQ2nIm)
913 + 2.*(pnRe*dQnRe+pnIm*dQnIm)
917 fCumuHist->Fill(eta, cent, kw4four, fourPrime);
918 fCumuHist->Fill(eta, cent, kw4, w4p);
920 cosPsi1Phi2 = pnRe*dQnRe - pnIm*dQnIm - q2nRe;
921 sinPsi1Phi2 = pnRe*dQnIm + pnIm*dQnRe - q2nIm;
923 cosPsi1Phi2Phi3p = pnRe*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
924 - 1.*(q2nRe*dQnRe+q2nIm*dQnIm)
927 sinPsi1Phi2Phi3p = pnIm*(TMath::Power(dQnIm,2.)+TMath::Power(dQnRe,2.)-mult)
928 - 1.*(q2nIm*dQnRe-q2nRe*dQnIm)
931 cosPsi1Phi2Phi3m = pnRe*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))+2.*pnIm*dQnRe*dQnIm
932 - 1.*(pnRe*dQ2nRe+pnIm*dQ2nIm)
933 - 2.*mq*dQnRe+2.*qnRe;
935 sinPsi1Phi2Phi3m = pnIm*(TMath::Power(dQnRe,2.)-TMath::Power(dQnIm,2.))-2.*pnRe*dQnRe*dQnIm
936 - 1.*(pnIm*dQ2nRe-pnRe*dQ2nIm)
937 + 2.*mq*dQnIm-2.*qnIm;
939 fCumuHist->Fill(eta, cent, kCospsi1phi2, cosPsi1Phi2);
940 fCumuHist->Fill(eta, cent, kSinpsi1phi2, sinPsi1Phi2);
941 fCumuHist->Fill(eta, cent, kCospsi1phi2phi3m, cosPsi1Phi2Phi3m);
942 fCumuHist->Fill(eta, cent, kSinpsi1phi2phi3m, sinPsi1Phi2Phi3m);
943 fCumuHist->Fill(eta, cent, kmpmq, (mp*mult-2.*mq)*(mult-1.));
944 fCumuHist->Fill(eta, cent, kCospsi1phi2phi3p, cosPsi1Phi2Phi3p);
945 fCumuHist->Fill(eta, cent, kSinpsi1phi2phi3p, sinPsi1Phi2Phi3p);
948 fCumuHist->Fill(-7., cent, -0.5, 1.);
951 //_____________________________________________________________________
952 void AliForwardFlowTaskQC::VertexBin::CumulantsTerminate(TList* inlist, TList* outlist)
955 // Finalizes the Q cumulant calculations
958 // inlist: input sumlist
959 // outlist: output result list
962 // Re-find cumulants hist if Terminate is called separately
964 TList* list = (TList*)inlist->FindObject(Form("%svertex_%d_%d", fType.Data(), fVzMin, fVzMax));
965 fCumuHist = (TH3D*)list->FindObject(Form("%sv%d_vertex_%d_%d_cumu", fType.Data(), fMoment, fVzMin, fVzMax));
968 // Create result profiles
969 TList* vtxList = (TList*)outlist->FindObject("vtxList");
971 vtxList = new TList();
972 vtxList->SetName("vtxList");
973 outlist->Add(vtxList);
975 TH1I* quality = (TH1I*)outlist->FindObject(Form("hQCquality%s", fType.Data()));
977 quality = new TH1I(Form("hQCquality%s", fType.Data()), Form("hQCquality%s", fType.Data()),
979 quality->GetXaxis()->SetBinLabel( 1, "QC_{2}{2} > 0");
980 quality->GetXaxis()->SetBinLabel( 2, "QC_{2}{2} <= 0");
981 quality->GetXaxis()->SetBinLabel( 3, "QC'_{2}{2} > 0");
982 quality->GetXaxis()->SetBinLabel( 4, "QC'_{2}{2} <= 0");
983 quality->GetXaxis()->SetBinLabel( 5, "QC_{2}{4} < 0");
984 quality->GetXaxis()->SetBinLabel( 6, "QC_{2}{4} >= 0");
985 quality->GetXaxis()->SetBinLabel( 7, "QC'_{2}{4} < 0");
986 quality->GetXaxis()->SetBinLabel( 8, "QC'_{2}{4} >= 0");
987 quality->GetXaxis()->SetBinLabel( 9, "QC_{3}{2} > 0");
988 quality->GetXaxis()->SetBinLabel(10, "QC_{3}{2} <= 0");
989 quality->GetXaxis()->SetBinLabel(11, "QC'_{3}{2} > 0");
990 quality->GetXaxis()->SetBinLabel(12, "QC'_{3}{2} <= 0");
991 quality->GetXaxis()->SetBinLabel(13, "QC_{3}{4} < 0");
992 quality->GetXaxis()->SetBinLabel(14, "QC_{3}{4} >= 0");
993 quality->GetXaxis()->SetBinLabel(15, "QC'_{3}{4} < 0");
994 quality->GetXaxis()->SetBinLabel(16, "QC'_{3}{4} >= 0");
995 quality->GetXaxis()->SetBinLabel(17, "QC_{4G}{2} > 0");
996 quality->GetXaxis()->SetBinLabel(18, "QC_{4G}{2} <= 0");
997 quality->GetXaxis()->SetBinLabel(19, "QC'_{4G}{2} > 0");
998 quality->GetXaxis()->SetBinLabel(20, "QC'_{4G}{2} <= 0");
999 quality->GetXaxis()->SetBinLabel(21, "QC_{4G}{4} < 0");
1000 quality->GetXaxis()->SetBinLabel(22, "QC_{4G}{4} >= 0");
1001 quality->GetXaxis()->SetBinLabel(23, "QC'_{3}{4} < 0");
1002 quality->GetXaxis()->SetBinLabel(24, "QC'_{4G}{4} >= 0");
1003 quality->GetXaxis()->SetBinLabel(25, "QC_{5}{2} > 0");
1004 quality->GetXaxis()->SetBinLabel(26, "QC_{5}{2} <= 0");
1005 quality->GetXaxis()->SetBinLabel(27, "QC'_{5}{2} > 0");
1006 quality->GetXaxis()->SetBinLabel(28, "QC'_{5}{2} <= 0");
1007 quality->GetXaxis()->SetBinLabel(29, "QC_{5}{4} < 0");
1008 quality->GetXaxis()->SetBinLabel(30, "QC_{5}{4} >= 0");
1009 quality->GetXaxis()->SetBinLabel(31, "QC'_{5}{4} < 0");
1010 quality->GetXaxis()->SetBinLabel(32, "QC'_{5}{4} >= 0");
1011 quality->GetXaxis()->SetBinLabel(33, "QC_{6}{2} > 0");
1012 quality->GetXaxis()->SetBinLabel(34, "QC_{6}{2} <= 0");
1013 quality->GetXaxis()->SetBinLabel(35, "QC'_{6}{2} > 0");
1014 quality->GetXaxis()->SetBinLabel(36, "QC'_{6}{2} <= 0");
1015 quality->GetXaxis()->SetBinLabel(37, "QC_{6}{4} < 0");
1016 quality->GetXaxis()->SetBinLabel(38, "QC_{6}{4} >= 0");
1017 quality->GetXaxis()->SetBinLabel(39, "QC'_{6}{4} < 0");
1018 quality->GetXaxis()->SetBinLabel(40, "QC'_{6}{4} >= 0");
1019 outlist->Add(quality);
1022 TProfile2D* cumu2Sum = (TProfile2D*)outlist->FindObject(Form("%sQC2_v%d_unCorr", fType.Data(), fMoment));
1023 TProfile2D* cumu4Sum = (TProfile2D*)outlist->FindObject(Form("%sQC4_v%d_unCorr", fType.Data(), fMoment));
1025 cumu2Sum = new TProfile2D(Form("%sQC2_v%d_unCorr", fType.Data(), fMoment),
1026 Form("%sQC2_v%d_unCorr", fType.Data(), fMoment),
1027 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
1028 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
1029 SetupCentAxis(cumu2Sum->GetYaxis());
1030 outlist->Add(cumu2Sum);
1033 cumu4Sum = new TProfile2D(Form("%sQC4_v%d_unCorr", fType.Data(), fMoment),
1034 Form("%sQC4_v%d_unCorr", fType.Data(), fMoment),
1035 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
1036 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
1037 SetupCentAxis(cumu4Sum->GetYaxis());
1038 outlist->Add(cumu4Sum);
1041 TProfile2D* cumu2 = new TProfile2D(Form("%sQC2_v%d_unCorr_vtx%3.1f", fType.Data(), fMoment, (fVzMin+fVzMax)/2.),
1042 Form("%sQC2_v%d_unCorr_vtx%3.1f", fType.Data(), fMoment, (fVzMin+fVzMax)/2.),
1043 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
1044 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
1045 SetupCentAxis(cumu2->GetYaxis());
1046 vtxList->Add(cumu2);
1047 TProfile2D* cumu4 = new TProfile2D(Form("%sQC4_v%d_unCorr_vtx%3.1f", fType.Data(), fMoment, (fVzMin+fVzMax)/2.),
1048 Form("%sQC4_v%d_unCorr_vtx%3.1f", fType.Data(), fMoment, (fVzMin+fVzMax)/2.),
1049 fCumuHist->GetNbinsX(), fCumuHist->GetXaxis()->GetXmin(), fCumuHist->GetXaxis()->GetXmax(),
1050 fCumuHist->GetNbinsY(), fCumuHist->GetYaxis()->GetXmin(), fCumuHist->GetYaxis()->GetXmax());
1051 SetupCentAxis(cumu4->GetYaxis());
1052 vtxList->Add(cumu4);
1054 TH1D* hCent = (TH1D*)outlist->FindObject(fType.Data());
1055 if (!hCent) AliFatal(Form("No cent hist found for %s", fType.Data()));
1057 // For flow calculations
1058 Double_t two = 0, qc2 = 0, vnTwo = 0, four = 0, qc4 = 0, vnFour = 0;
1059 Double_t twoPrime = 0, qc2Prime = 0, vnTwoDiff = 0, fourPrime = 0, qc4Prime = 0, vnFourDiff = 0;
1060 Double_t w2 = 0, w4 = 0, w2p = 0, w4p = 0;
1061 Double_t w2Two = 0, w2pTwoPrime = 0, w4Four = 0, w4pFourPrime = 0;
1062 Double_t cosP1nPhi = 0, sinP1nPhi = 0, mult = 0, cosP1nPhi1P1nPhi2 = 0, sinP1nPhi1P1nPhi2 = 0;
1063 Double_t cosP1nPhi1M1nPhi2M1nPhi3 = 0, sinP1nPhi1M1nPhi2M1nPhi3 = 0, multm1m2 = 0;
1064 Double_t cosP1nPsi = 0, sinP1nPsi = 0, mp = 0, cosP1nPsi1P1nPhi2 = 0, sinP1nPsi1P1nPhi2 = 0;
1065 Double_t cosP1nPsi1M1nPhi2M1nPhi3 = 0, sinP1nPsi1M1nPhi2M1nPhi3 = 0, mpqMult = 0;
1066 Double_t cosP1nPsi1P1nPhi2M1nPhi3 = 0, sinP1nPsi1P1nPhi2M1nPhi3 = 0;
1068 // Loop over cumulant histogram for final calculations
1070 for (Int_t cBin = 1; cBin <= fCumuHist->GetNbinsY(); cBin++) {
1071 // for weighted avg.
1073 Double_t totalEvents = hCent->GetBinContent(cBin);
1074 Double_t theseEvents = fCumuHist->GetBinContent(0, cBin, 0);
1075 Double_t weight = 1;
1076 if (totalEvents != 0) weight = theseEvents / totalEvents;
1078 Double_t cent = fCumuHist->GetYaxis()->GetBinCenter(cBin);
1079 // Double_t nEv = 0;
1080 if (fDebug > 0) AliInfo(Form("%s - v_%d: centrality %3.1f:..", fType.Data(), fMoment, cent));
1082 for (Int_t etaBin = 1; etaBin <= fCumuHist->GetNbinsX(); etaBin++) {
1083 Double_t eta = fCumuHist->GetXaxis()->GetBinCenter(etaBin);
1084 // 2-particle reference flow
1085 w2Two = fCumuHist->GetBinContent(etaBin, cBin, kW2Two);
1086 w2 = fCumuHist->GetBinContent(etaBin, cBin, kW2);
1087 mult = fCumuHist->GetBinContent(etaBin, cBin, kM);
1088 if (!w2 || !mult) continue;
1089 cosP1nPhi = fCumuHist->GetBinContent(etaBin, cBin, kQnRe);
1090 sinP1nPhi = fCumuHist->GetBinContent(etaBin, cBin, kQnIm);
1095 qc2 = two - TMath::Power(cosP1nPhi, 2) - TMath::Power(sinP1nPhi, 2);
1097 if (fDebug > 0) AliInfo(Form("%s: QC_%d{2} = %1.3f for eta = %1.2f and centrality %3.1f - skipping", fType.Data(), fMoment, qc2, eta, cent));
1098 quality->Fill((fMoment-2)*8+2);
1101 vnTwo = TMath::Sqrt(qc2);
1102 if (!TMath::IsNaN(vnTwo*mult))
1103 quality->Fill((fMoment-2)*8+1);
1104 // cumu2->Fill(eta, cent, vnTwo, fCumuHist->GetBinContent(0,cBin,0));
1106 // 2-particle differential flow
1107 w2pTwoPrime = fCumuHist->GetBinContent(etaBin, cBin, kw2two);
1108 w2p = fCumuHist->GetBinContent(etaBin, cBin, kw2);
1109 mp = fCumuHist->GetBinContent(etaBin, cBin, kmp);
1110 if (!w2p || !mp) continue;
1111 cosP1nPsi = fCumuHist->GetBinContent(etaBin, cBin, kpnRe);
1112 sinP1nPsi = fCumuHist->GetBinContent(etaBin, cBin, kpnIm);
1116 twoPrime = w2pTwoPrime / w2p;
1117 qc2Prime = twoPrime - sinP1nPsi*sinP1nPhi - cosP1nPsi*cosP1nPhi;
1119 vnTwoDiff = qc2Prime / TMath::Sqrt(qc2);
1120 if (!TMath::IsNaN(vnTwoDiff*mp)) {
1121 cumu2->Fill(eta, cent, vnTwoDiff/*, weight*/);
1122 quality->Fill((fMoment-2)*8+3);
1125 quality->Fill((fMoment-2)*8+4);
1127 if (fDebug > 1) AliInfo(Form("%s: v_%d{2} = %1.3f for eta = %1.2f and centrality %3.1f", fType.Data(), fMoment, vnTwoDiff, eta, cent));
1129 // 4-particle reference flow
1130 w4Four = fCumuHist->GetBinContent(etaBin, cBin, kW4Four);
1131 w4 = fCumuHist->GetBinContent(etaBin, cBin, kW4);
1132 multm1m2 = fCumuHist->GetBinContent(etaBin, cBin, kMm1m2);
1133 if (!w4 || !multm1m2) continue;
1134 cosP1nPhi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kCosphi1phi2);
1135 sinP1nPhi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kSinphi1phi2);
1136 cosP1nPhi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCosphi1phi2phi3m);
1137 sinP1nPhi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinphi1phi2phi3m);
1139 cosP1nPhi1P1nPhi2 /= w2;
1140 sinP1nPhi1P1nPhi2 /= w2;
1141 cosP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
1142 sinP1nPhi1M1nPhi2M1nPhi3 /= multm1m2;
1144 qc4 = four-2.*TMath::Power(two,2.)
1145 - 4.*cosP1nPhi*cosP1nPhi1M1nPhi2M1nPhi3
1146 + 4.*sinP1nPhi*sinP1nPhi1M1nPhi2M1nPhi3-TMath::Power(cosP1nPhi1P1nPhi2,2.)-TMath::Power(sinP1nPhi1P1nPhi2,2.)
1147 + 4.*cosP1nPhi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
1148 + 8.*sinP1nPhi1P1nPhi2*sinP1nPhi*cosP1nPhi
1149 + 8.*two*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
1150 - 6.*TMath::Power((TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.)),2.);
1153 if (fDebug > 0) AliInfo(Form("%s: QC_%d{4} = %1.3f for eta = %1.2f and centrality %3.1f - skipping", fType.Data(), fMoment, qc2, eta, cent));
1154 quality->Fill((fMoment-2)*8+6);
1157 vnFour = TMath::Power(-qc4, 0.25);
1158 if (!TMath::IsNaN(vnFour*mult))
1159 quality->Fill((fMoment-2)*8+5);
1160 // cumu4->Fill(eta, cent, vnFour, fCumuHist->GetBinContent(0,cBin,0));
1162 // 4-particle differential flow
1163 w4pFourPrime = fCumuHist->GetBinContent(etaBin, cBin, kw4four);
1164 w4p = fCumuHist->GetBinContent(etaBin, cBin, kw4);
1165 mpqMult = fCumuHist->GetBinContent(etaBin, cBin, kmpmq);
1166 if (!w4p || !mpqMult) continue;
1167 cosP1nPsi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2);
1168 sinP1nPsi1P1nPhi2 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2);
1169 cosP1nPsi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2phi3m);
1170 sinP1nPsi1M1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2phi3m);
1171 cosP1nPsi1P1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kCospsi1phi2phi3p);
1172 sinP1nPsi1P1nPhi2M1nPhi3 = fCumuHist->GetBinContent(etaBin, cBin, kSinpsi1phi2phi3p);
1174 cosP1nPsi1P1nPhi2 /= w2p;
1175 sinP1nPsi1P1nPhi2 /= w2p;
1176 cosP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
1177 sinP1nPsi1M1nPhi2M1nPhi3 /= mpqMult;
1178 cosP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
1179 sinP1nPsi1P1nPhi2M1nPhi3 /= mpqMult;
1181 fourPrime = w4pFourPrime / w4p;
1183 qc4Prime = fourPrime-2.*twoPrime*two
1184 - cosP1nPsi*cosP1nPhi1M1nPhi2M1nPhi3
1185 + sinP1nPsi*sinP1nPhi1M1nPhi2M1nPhi3
1186 - cosP1nPhi*cosP1nPsi1M1nPhi2M1nPhi3
1187 + sinP1nPhi*sinP1nPsi1M1nPhi2M1nPhi3
1188 - 2.*cosP1nPhi*cosP1nPsi1P1nPhi2M1nPhi3
1189 - 2.*sinP1nPhi*sinP1nPsi1P1nPhi2M1nPhi3
1190 - cosP1nPsi1P1nPhi2*cosP1nPhi1P1nPhi2
1191 - sinP1nPsi1P1nPhi2*sinP1nPhi1P1nPhi2
1192 + 2.*cosP1nPhi1P1nPhi2*(cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
1193 + 2.*sinP1nPhi1P1nPhi2*(cosP1nPsi*sinP1nPhi+sinP1nPsi*cosP1nPhi)
1194 + 4.*two*(cosP1nPsi*cosP1nPhi+sinP1nPsi*sinP1nPhi)
1195 + 2.*cosP1nPsi1P1nPhi2*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
1196 + 4.*sinP1nPsi1P1nPhi2*cosP1nPhi*sinP1nPhi
1197 + 4.*twoPrime*(TMath::Power(cosP1nPhi,2.)+TMath::Power(sinP1nPhi,2.))
1198 - 6.*(TMath::Power(cosP1nPhi,2.)-TMath::Power(sinP1nPhi,2.))
1199 * (cosP1nPsi*cosP1nPhi-sinP1nPsi*sinP1nPhi)
1200 - 12.*cosP1nPhi*sinP1nPhi
1201 * (sinP1nPsi*cosP1nPhi+cosP1nPsi*sinP1nPhi);
1203 vnFourDiff = - qc4Prime / TMath::Power(-qc4, 0.75);
1204 if (!TMath::IsNaN(vnFourDiff*mp) && vnFourDiff > 0) {
1205 cumu4->Fill(eta, cent, vnFourDiff/*, weight*/);
1206 quality->Fill((fMoment-2)*8+7);
1209 quality->Fill((fMoment-2)*8+8);
1211 if (fDebug > 1) AliInfo(Form("%s: v_%d{4} = %1.3f for eta = %1.2f and centrality %3.1f", fType.Data(), fMoment, vnFourDiff, eta, cent));
1212 } // End of eta loop
1213 } // End of centrality loop
1215 cumu2Sum->Add(cumu2);
1216 cumu4Sum->Add(cumu4);
1220 //_____________________________________________________________________
1221 void AliForwardFlowTaskQC::VertexBin::SetupCentAxis(TAxis* axis)
1224 // Setup centrality axis for histogram
1227 // axis: centrality axis
1230 AliError("Null pointer passed for axis");
1233 // Double_t cent[11] = {0, 5, 10, 15, 20, 30, 40, 50, 60, 80, 100 };
1234 // axis->Set(10, cent);
1236 if (AliForwardFlowTaskQC::fgDispVtx) {
1237 Double_t cent[3] = {0, 40, 100};
1240 Double_t cent[21] = { 0. };
1241 for (Int_t i = 0; i <= 20; i++) {
1244 axis->Set(20, cent);
1249 //_____________________________________________________________________
1250 void AliForwardFlowTaskQC::PrintFlowSetup() const
1253 // Print the setup of the flow task
1255 Printf("AliForwardFlowTaskQC::Print");
1256 Printf("Number of bins in vertex axis:\t%d", fVtxAxis->GetNbins());
1257 Printf("Range of vertex axis :\t[%3.1f,%3.1f]",
1258 fVtxAxis->GetXmin(), fVtxAxis->GetXmax());
1259 printf("Doing flow analysis for :\t");
1260 for (Int_t n = 2; n <= 6; n++) if (fv[n]) printf("v%d ", n);
1262 Printf("Displaced vertex flag :\t%s", (fgDispVtx ? "true" : "false"));
1263 Printf("FMD sigma cut: :\t%f", fFMDCut);
1264 Printf("SPD sigma cut: :\t%f", fSPDCut);
1267 //_____________________________________________________________________