/************************************************************************** * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * * * * Author: The ALICE Off-line Project. * * Contributors are mentioned in the code where appropriate. * * * * Permission to use, copy, modify and distribute this software and its * * documentation strictly for non-commercial purposes is hereby granted * * without fee, provided that the above copyright notice appears in all * * copies and that both the copyright notice and this permission notice * * appear in the supporting documentation. The authors make no claims * * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ #include "Riostream.h" //needed as include #include "AliFlowCommonConstants.h" //needed as include #include "AliFlowLYZConstants.h" //needed as include #include "AliFlowAnalysisWithLeeYangZeros.h" #include "AliFlowLYZHist1.h" //needed as include #include "AliFlowLYZHist2.h" //needed as include #include "AliFlowCommonHist.h" //needed as include #include "AliFlowCommonHistResults.h" //needed as include #include "AliFlowEventSimple.h" //needed as include #include "AliFlowTrackSimple.h" //needed as include class AliFlowVector; #include "TMath.h" //needed as include #include "TFile.h" //needed as include #include "TList.h" class TComplex; class TProfile; class TH1F; class TH1D; //Description: Maker to analyze Flow using the LeeYangZeros method // Equation numbers are from Big Paper (BP): Nucl. Phys. A 727, 373 (2003) // Practical Guide (PG): J. Phys. G: Nucl. Part. Phys. 30, S1213 (2004) // Adapted from StFlowLeeYangZerosMaker.cxx // by Markus Oldenberg and Art Poskanzer, LBNL // with advice from Jean-Yves Ollitrault and Nicolas Borghini // //Author: Naomi van der Kolk (kolk@nikhef.nl) ClassImp(AliFlowAnalysisWithLeeYangZeros) //----------------------------------------------------------------------- AliFlowAnalysisWithLeeYangZeros::AliFlowAnalysisWithLeeYangZeros(): fQsum(NULL), fQ2sum(0), fEventNumber(0), fFirstRun(kTRUE), fUseSum(kTRUE), fDoubleLoop(kFALSE), fDebug(kFALSE), fHistList(NULL), firstRunFileName(0), firstRunFile(NULL), fHistProVtheta(NULL), fHistProVeta(NULL), fHistProVPt(NULL), fHistProR0theta(NULL), fHistProReDenom(NULL), fHistProImDenom(NULL), fHistProReDtheta(NULL), fHistProImDtheta(NULL), fCommonHists(NULL), fCommonHistsRes(NULL) { //default constructor if (fDebug) cout<<"****AliFlowAnalysisWithLeeYangZeros::AliFlowAnalysisWithLeeYangZeros default constructor****"<Add(fCommonHists->GetHistList()); fHistList->Add(fCommonHists->GetHistMultOrig()); fHistList->Add(fCommonHists->GetHistMultInt()); fHistList->Add(fCommonHists->GetHistMultDiff()); fHistList->Add(fCommonHists->GetHistPtInt()); fHistList->Add(fCommonHists->GetHistPtDiff()); fHistList->Add(fCommonHists->GetHistPhiInt()); fHistList->Add(fCommonHists->GetHistPhiDiff()); fHistList->Add(fCommonHists->GetHistEtaInt()); fHistList->Add(fCommonHists->GetHistEtaDiff()); fHistList->Add(fCommonHists->GetHistProMeanPtperBin()); fHistList->Add(fCommonHists->GetHistQ()); fCommonHistsRes = new AliFlowCommonHistResults("LYZ"); //fHistList->Add(fCommonHistsRes->GetHistList()); fHistList->Add(fCommonHistsRes->GetHistDiffFlow()); fHistList->Add(fCommonHistsRes->GetHistChi()); fHistList->Add(fCommonHistsRes->GetHistIntFlow()); //for first loop over events if (fFirstRun){ fHistProR0theta = new TProfile("First_FlowPro_r0theta_LYZ","First_FlowPro_r0theta_LYZ",iNtheta,-0.5,iNtheta-0.5); fHistProR0theta->SetXTitle("#theta"); fHistProR0theta->SetYTitle("r_{0}^{#theta}"); fHistList->Add(fHistProR0theta); fHistProVtheta = new TProfile("First_FlowPro_Vtheta_LYZ","First_FlowPro_Vtheta_LYZ",iNtheta,-0.5,iNtheta-0.5); fHistProVtheta->SetXTitle("#theta"); fHistProVtheta->SetYTitle("V_{n}^{#theta}"); fHistList->Add(fHistProVtheta); //class AliFlowLYZHist1 defines the histograms: fHistProGtheta, fHistProReGtheta, fHistProImGtheta, fHistProR0theta for (Int_t theta=0;thetaAdd(fHist1[theta]->GetHistList() ); fHistList->Add(fHist1[theta]->GetHistGtheta() ); fHistList->Add(fHist1[theta]->GetHistProReGtheta() ); fHistList->Add(fHist1[theta]->GetHistProImGtheta() ); } } //for second loop over events else { fHistProReDenom = new TProfile("Second_FlowPro_ReDenom_LYZ","Second_FlowPro_ReDenom_LYZ" , iNtheta, -0.5, iNtheta-0.5); fHistProReDenom->SetXTitle("#theta"); fHistProReDenom->SetYTitle("Re(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})"); fHistList->Add(fHistProReDenom); fHistProImDenom = new TProfile("Second_FlowPro_ImDenom_LYZ","Second_FlowPro_ImDenom_LYZ" , iNtheta, -0.5, iNtheta-0.5); fHistProImDenom->SetXTitle("#theta"); fHistProImDenom->SetYTitle("Im(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})"); fHistList->Add(fHistProImDenom); fHistProVeta = new TProfile("Second_FlowPro_Veta_LYZ","Second_FlowPro_Veta_LYZ",iNbinsEta,dEtaMin,dEtaMax); fHistProVeta->SetXTitle("rapidity"); fHistProVeta->SetYTitle("v (%)"); fHistList->Add(fHistProVeta); fHistProVPt = new TProfile("Second_FlowPro_VPt_LYZ","Second_FlowPro_VPt_LYZ",iNbinsPt,dPtMin,dPtMax); fHistProVPt->SetXTitle("Pt"); fHistProVPt->SetYTitle("v (%)"); fHistList->Add(fHistProVPt); fHistProReDtheta = new TProfile("Second_FlowPro_ReDtheta_LYZ","Second_FlowPro_ReDtheta_LYZ",iNtheta, -0.5, iNtheta-0.5); fHistProReDtheta->SetXTitle("#theta"); fHistProReDtheta->SetYTitle("Re(D^{#theta})"); fHistList->Add(fHistProReDtheta); fHistProImDtheta = new TProfile("Second_FlowPro_ImDtheta_LYZ","Second_FlowPro_ImDtheta_LYZ",iNtheta, -0.5, iNtheta-0.5); fHistProImDtheta->SetXTitle("#theta"); fHistProImDtheta->SetYTitle("Im(D^{#theta})"); fHistList->Add(fHistProImDtheta); //class AliFlowLYZHist2 defines the histograms: for (Int_t theta=0;thetaAdd(fHist2[theta]->GetHistList() ); fHistList->Add(fHist2[theta]->GetHistProReNumer() ); fHistList->Add(fHist2[theta]->GetHistProImNumer() ); fHistList->Add(fHist2[theta]->GetHistProReNumerPt() ); fHistList->Add(fHist2[theta]->GetHistProImNumerPt() ); //fHistList->Add(fHist2[theta]->GetHistProReNumer2D() ); //gives error in compilation //fHistList->Add(fHist2[theta]->GetHistProImNumer2D() ); //gives error in compilation } //read hists from first run file //firstRunFile = new TFile("fof_flowLYZAnal_firstrun.root","READ"); //default is read if (firstRunFile->IsZombie()){ //check if file exists cout << "Error opening file, run first with fFirstrun = kTRUE" << endl; exit(-1); } else if (firstRunFile->IsOpen()){ cout<<"----firstRunFile is open----"<Get("cobj1"); if (!list) {cout<<"list is NULL pointer!"<FindObject("First_FlowPro_r0theta_LYZ"); if (!fHistProR0theta) {cout<<"fHistProR0theta has a NULL pointer!"<Add(fHistProR0theta); } } if (fDebug) cout<<"****Histograms initialised****"<FillControlHistograms(anEvent); FillFromFlowEvent(anEvent); } else { fCommonHists->FillControlHistograms(anEvent); SecondFillFromFlowEvent(anEvent); } } else { cout<<"##### FlowLeeYangZero: Stack pointer null"<FillGtheta(); dR0 = fHist1[theta]->GetR0(); //calculate integrated flow if (dR0!=0) dVtheta = dJ01/dR0; //for estimating systematic error resulting from d0 Double_t dBinsize = (AliFlowLYZConstants::fgMax)/(AliFlowLYZConstants::kNbins); Double_t dVplus = dJ01/(dR0+dBinsize); Double_t dVmin = dJ01/(dR0-dBinsize); dv = dVtheta; Double_t dvplus = dVplus; Double_t dvmin = dVmin; cout<<"dv = "<FillIntegratedFlow(dv2pro, dv2Err); if (fDebug) cout<<"****histograms filled****"<GetBinContent(theta+1); if (fDebug) cerr<<"dR0 = "< Vn^theta = j01/r0^theta if (fHistProReDenom && fHistProImDenom) { dReDenom = fHistProReDenom->GetBinContent(theta+1); dImDenom = fHistProImDenom->GetBinContent(theta+1); } else { cout << "Hist pointer fDenom in file does not exist" <GetBinContent(theta+1); cDtheta = dR0*cDenom/dJ01; fHistProReDtheta->Fill(theta,cDtheta.Re()); fHistProImDtheta->Fill(theta,cDtheta.Im()); } cDenom *= TComplex::Power(i, m-1); //cerr<<"TComplex::Power(i, m-1) = "<GetBinCenter(be); cNumer = fHist2[theta]->GetNumerEta(be); if (cNumer.Rho()==0) { if (fDebug) cerr<<"WARNING: modulus of cNumer is zero in Finish()"<GetQ(); //weight by the multiplicity Double_t dQX = 0; Double_t dQY = 0; if (vQ.GetMult() != 0) { dQX = vQ.X()/vQ.GetMult(); dQY = vQ.Y()/vQ.GetMult(); } vQ.Set(dQX,dQY); //for chi calculation: *fQsum += vQ; fQ2sum += vQ.Mod2(); //cerr<<"fQ2sum = "<GetBinCenter(bin); //bincentre of bins in histogram //FIXED??? //if (theta == 0) cerr<<"cerr::dR = "< 100.) break; } fHist1[theta]->Fill(dR,cGtheta); //fill real and imaginary part of cGtheta } //loop over bins } //loop over theta return kTRUE; } //----------------------------------------------------------------------- Bool_t AliFlowAnalysisWithLeeYangZeros::SecondFillFromFlowEvent(AliFlowEventSimple* anEvent) { //for differential flow if (fDebug) cout<<"****AliFlowAnalysisWithLeeYangZeros::SecondFillFromFlowEvent()****"<GetQ(); //weight by the multiplicity Double_t dQX = 0.; Double_t dQY = 0.; if (vQ.GetMult() != 0) { dQX = vQ.X()/vQ.GetMult(); dQY = vQ.Y()/vQ.GetMult(); } vQ.Set(dQX,dQY); //for chi calculation: *fQsum += vQ; fQ2sum += vQ.Mod2(); for (Int_t theta=0;thetaFill(dEta,dPt,cNumer); } else { cout << "fHist2 pointer mising" <Fill(theta,cDenom.Re()); //fill the real part of fDenom fHistProImDenom->Fill(theta,cDenom.Im()); //fill the imaginary part of fDenom } else { cout << "Pointers to cDenom mising" << endl; } }//end of loop over theta return kTRUE; } //----------------------------------------------------------------------- Double_t AliFlowAnalysisWithLeeYangZeros::GetQtheta(AliFlowVector aQ, Double_t aTheta) { //calculate Qtheta. Qtheta is the sum over all particles of cos(dOrder*(dPhi-dTheta)) BP eq. 3 if (fDebug) cout<<"****AliFlowAnalysisWithLeeYangZeros::GetQtheta()****"<NumberOfTracks(); for (Int_t i=0;iGetTrack(i) ; if (pTrack){ if (pTrack->UseForIntegratedFlow()) { Double_t dPhi = pTrack->Phi(); Double_t dGIm = aR * dWgt*cos(dOrder*(dPhi - aTheta)); TComplex cGi(1., dGIm); cG *= cGi; //product over all tracks } } else {cerr << "no particle pointer !!!"<NumberOfTracks(); Int_t iNtheta = AliFlowLYZConstants::kTheta; Double_t dTheta = ((double)theta/iNtheta)*TMath::Pi()/dOrder; for (Int_t i=0;iGetTrack(i) ; if (pTrack){ if (pTrack->UseForDifferentialFlow()) { Double_t dPhi = pTrack->Phi(); Double_t dCosTerm = dWgt*cos(dOrder*(dPhi - dTheta)); //GetGr0theta Double_t dGIm = aR0 * dCosTerm; TComplex cGi(1., dGIm); cG *= cGi; //product over all tracks //GetdGr0theta TComplex cCosTermComplex(1., aR0*dCosTerm); cdGr0 +=(dCosTerm / cCosTermComplex); //sum over all tracks } } //if particle else {cerr << "no particle!!!"<GetTrack(i) ; if (pTrack){ if (pTrack->UseForDifferentialFlow()) { Double_t dEta = pTrack->Eta(); Double_t dPt = pTrack->Pt(); Double_t dPhi = pTrack->Phi(); Double_t dCosTerm = cos(dOrder*(dPhi-dTheta)); TComplex cCosTermComplex(1.,aR0*dCosTerm); TComplex cNumer = cG*dCosTerm/cCosTermComplex; //PG Eq. 9 fHist2[theta]->Fill(dEta,dPt,cNumer); } } //if particle else {cerr << "no particle pointer!!!"<