1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
20 #include "Riostream.h"
21 #include "AliFlowLeeYangZerosMaker.h"
22 #include "AliFlowEvent.h"
23 #include "AliFlowSelection.h"
24 #include "AliFlowConstants.h" //??
25 #include "AliFlowLYZHist1.h"
26 #include "AliFlowLYZHist2.h"
27 #include "AliFlowLYZConstants.h" //??
32 #include "TObjArray.h"
36 #include "TGraphErrors.h"
46 //class Riostream; //does not compile
47 //class TMath; //does not compile
48 //class TVector; //does not compile
50 //Description: Maker to analyze Flow using the LeeYangZeros method
51 // Equation numbers are from Big Paper (BP): Nucl. Phys. A 727, 373 (2003)
52 // Practical Guide (PG): J. Phys. G: Nucl. Part. Phys. 30, S1213 (2004)
53 // Adapted from StFlowLeeYangZerosMaker.cxx
54 // by Markus Oldenberg and Art Poskanzer, LBNL
55 // with advice from Jean-Yves Ollitrault and Nicolas Borghini
57 //Author: Naomi van der Kolk (kolk@nikhef.nl)
61 ClassImp(AliFlowLeeYangZerosMaker)
63 //-----------------------------------------------------------------------
65 AliFlowLeeYangZerosMaker::AliFlowLeeYangZerosMaker():
76 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::AliFlowLeeYangZerosMaker default constructor****"<<endl;
78 fFlowSelect = new AliFlowSelection();
79 if (fDebug) { cerr<<"****fFlowSelect in constructor AliFlowLeeYangZerosMaker ("<<fFlowSelect<<")****"<<endl;}
80 // output file (histograms)
81 TString fHistFileName = "flowLYZAnalysPlot.root" ;
85 AliFlowLeeYangZerosMaker::AliFlowLeeYangZerosMaker(const AliFlowSelection* flowSelect):
95 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::AliFlowLeeYangZerosMaker custum constructor****"<<endl;
97 if(flowSelect) { fFlowSelect = new AliFlowSelection(*flowSelect); }
99 fFlowSelect = new AliFlowSelection() ;
100 if (fDebug) cerr<<"****fFlowSelect in constructor AliFlowLeeYangZerosMaker ("<<fFlowSelect<<")****"<<endl;
102 // output file (histograms)
103 TString fHistFileName = "flowLYZAnalysPlot.root" ;
106 //-----------------------------------------------------------------------
109 AliFlowLeeYangZerosMaker::~AliFlowLeeYangZerosMaker()
112 if (fDebug) cout<<"****~AliFlowLeeYangZerosMaker****"<<endl;
116 //-----------------------------------------------------------------------
118 Bool_t AliFlowLeeYangZerosMaker::Init()
121 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::Init()****"<<endl;
123 // Open output files (->plots)
124 fHistFile = new TFile(fHistFileName.Data(), "RECREATE");
125 //fHistFile->cd() ; //all histograms will be saved in this file
127 //for each harmonic ???
132 Int_t fNtheta = AliFlowLYZConstants::kTheta;
135 //for control histograms
136 fHistOrigMult = new TH1F("Control_FlowLYZ_OrigMult", "Control_FlowLYZ_OrigMult",1000, 0., 10000.);
137 fHistOrigMult->SetXTitle("Original Multiplicity");
138 fHistOrigMult->SetYTitle("Counts");
140 fHistMult = new TH1F("Control_FlowLYZ_Mult", "Control_FlowLYZ_Mult",1000, 0., 10000.);
141 fHistMult->SetXTitle("Multiplicity from selection");
142 fHistMult->SetYTitle("Counts");
144 fHistQ = new TH1F("Control_FlowLYZ_Q","Control_FlowLYZ_Q",500, 0., 10.);
145 fHistQ->SetXTitle("Qvector");
146 fHistQ->SetYTitle("Counts");
148 fHistPt = new TH1F("Control_FlowLYZ_Pt","Control_FlowLYZ_Pt",200, 0., 10.);
149 fHistPt->SetXTitle("Pt (GeV/c)");
150 fHistPt->SetYTitle("Counts");
152 fHistPhi = new TH1F("Control_FlowLYZ_Phi","Control_FlowLYZ_Phi",70, 0., 7.);
153 fHistPhi->SetXTitle("Phi");
154 fHistPhi->SetYTitle("Counts");
156 fHistEta = new TH1F("Control_FlowLYZ_Eta","Control_FlowLYZ_Eta",40, 0., 2.);
157 fHistEta->SetXTitle("Eta");
158 fHistEta->SetYTitle("Counts");
160 fHistQtheta = new TH1F("Control_FlowLYZ_Qtheta","Control_FlowLYZ_Qtheta",50,-1000.,1000.);
161 fHistQtheta->SetXTitle("Qtheta");
162 fHistQtheta->SetYTitle("Counts");
165 //for first loop over events
166 fHistProR0thetaHar1 = new TProfile("First_FlowProLYZ_r0theta_Har1","First_FlowProLYZ_r0theta_Har1",fNtheta,-0.5,fNtheta-0.5);
167 fHistProR0thetaHar1->SetXTitle("#theta");
168 fHistProR0thetaHar1->SetYTitle("r_{0}^{#theta}");
170 fHistProR0thetaHar2 = new TProfile("First_FlowProLYZ_r0theta_Har2","First_FlowProLYZ_r0theta_Har2",fNtheta,-0.5,fNtheta-0.5);
171 fHistProR0thetaHar2->SetXTitle("#theta");
172 fHistProR0thetaHar2->SetYTitle("r_{0}^{#theta}");
174 fHistProVthetaHar1 = new TProfile("First_FlowProLYZ_Vtheta_Har1","First_FlowProLYZ_Vtheta_Har1",fNtheta,-0.5,fNtheta-0.5);
175 fHistProVthetaHar1->SetXTitle("#theta");
176 fHistProVthetaHar1->SetYTitle("V_{n}^{#theta}");
178 fHistProVthetaHar2 = new TProfile("First_FlowProLYZ_Vtheta_Har2","First_FlowProLYZ_Vtheta_Har2",fNtheta,-0.5,fNtheta-0.5);
179 fHistProVthetaHar2->SetXTitle("#theta");
180 fHistProVthetaHar2->SetYTitle("V_{n}^{#theta}");
182 fHistProVR0 = new TProfile("First_FlowProLYZ_vR0","First_FlowProLYZ_vR0",2,0.5,2.5,-100.,100.);
183 fHistProVR0->SetXTitle("Harmonic");
184 fHistProVR0->SetYTitle("v integrated from r0 (%)");
186 fHistVR0 = new TH1D("First_FlowLYZ_vR0","First_FlowLYZ_vR0",2,0.5,2.5);
187 fHistVR0->SetXTitle("Harmonic");
188 fHistVR0->SetYTitle("v integrated from r0 (%)");
190 fHistProV = new TProfile("First_FlowProLYZ_V","First_FlowProLYZ_V",2,0.5,2.5,-1000.,1000.);
191 fHistProV->SetXTitle("Harmonic");
192 fHistProV->SetYTitle("v integrated");
194 //class AliFlowLYZHist1 defines the histograms: fHistProGtheta, fHistProReGtheta, fHistProImGtheta, fHistProR0theta
195 for (Int_t j=0;j<AliFlowConstants::kHars;j++)
197 for (Int_t theta=0;theta<fNtheta;theta++)
199 fHist1[j][theta]=new AliFlowLYZHist1(theta,j+1);
204 //for second loop over events
205 fHistProReDenomHar1 = new TProfile("Second_FlowProLYZ_ReDenom_Har1","Second_FlowProLYZ_ReDenom_Har1" , fNtheta, -0.5, fNtheta-0.5);
206 fHistProReDenomHar1->SetXTitle("#theta");
207 fHistProReDenomHar1->SetYTitle("Re(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
209 fHistProReDenomHar2 = new TProfile("Second_FlowProLYZ_ReDenom_Har2","Second_FlowProLYZ_ReDenom_Har2" , fNtheta, -0.5, fNtheta-0.5);
210 fHistProReDenomHar2->SetXTitle("#theta");
211 fHistProReDenomHar2->SetYTitle("Re(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
213 fHistProImDenomHar1 = new TProfile("Second_FlowProLYZ_ImDenom_Har1","Second_FlowProLYZ_ImDenom_Har1" , fNtheta, -0.5, fNtheta-0.5);
214 fHistProImDenomHar1->SetXTitle("#theta");
215 fHistProImDenomHar1->SetYTitle("Im(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
217 fHistProImDenomHar2 = new TProfile("Second_FlowProLYZ_ImDenom_Har2","Second_FlowProLYZ_ImDenom_Har2" , fNtheta, -0.5, fNtheta-0.5);
218 fHistProImDenomHar2->SetXTitle("#theta");
219 fHistProImDenomHar2->SetYTitle("Im(Q^{#theta}e^{ir_{0}^{#theta}Q^{#theta}})");
221 fHistProVetaHar1 = new TProfile("Second_FlowProLYZ_Veta_Har1","Second_FlowProLYZ_Veta_Har1",40,-2.,2.);
222 fHistProVetaHar1->SetXTitle("rapidity");
223 fHistProVetaHar1->SetYTitle("v (%)");
225 fHistProVetaHar2 = new TProfile("Second_FlowProLYZ_Veta_Har2","Second_FlowProLYZ_Veta_Har2",40,-2.,2.);
226 fHistProVetaHar2->SetXTitle("rapidity");
227 fHistProVetaHar2->SetYTitle("v (%)");
229 fHistProVPtHar1 = new TProfile("Second_FlowProLYZ_VPt_Har1","Second_FlowProLYZ_VPt_Har1",100,0.,10.);
230 fHistProVPtHar1->SetXTitle("Pt");
231 fHistProVPtHar1->SetYTitle("v (%)");
233 fHistProVPtHar2 = new TProfile("Second_FlowProLYZ_VPt_Har2","Second_FlowProLYZ_VPt_Har2",100,0.,10.);
234 fHistProVPtHar2->SetXTitle("Pt");
235 fHistProVPtHar2->SetYTitle("v (%)");
237 fHistVPtHar2 = new TH1D("Second_FlowLYZ_VPt_Har2","Second_FlowLYZ_VPt_Har2",100,0.,10.);
238 fHistVPtHar2->SetXTitle("Pt");
239 fHistVPtHar2->SetYTitle("v (%)");
241 fHistProReDtheta = new TProfile("Second_FlowProLYZ_ReDtheta_Har2","Second_FlowProLYZ_ReDtheta_Har2",fNtheta, -0.5, fNtheta-0.5);
242 fHistProReDtheta->SetXTitle("#theta");
243 fHistProReDtheta->SetYTitle("Re(D^{#theta})");
245 fHistProImDtheta = new TProfile("Second_FlowProLYZ_ImDtheta_Har2","Second_FlowProLYZ_ImDtheta_Har2",fNtheta, -0.5, fNtheta-0.5);
246 fHistProImDtheta->SetXTitle("#theta");
247 fHistProImDtheta->SetYTitle("Im(D^{#theta})");
250 //class AliFlowLYZHist2 defines the histograms:
251 for (Int_t j=0;j<AliFlowConstants::kHars;j++)
253 for (Int_t theta=0;theta<fNtheta;theta++)
255 fHist2[j][theta]=new AliFlowLYZHist2(theta,j+1);
259 //read hists from first run file
260 //firstRunFile = new TFile("fof_flowLYZAnal_firstrun.root","READ"); //default is read
261 if (firstRunFile->IsZombie()){ //check if file exists
262 cout << "Error opening file, run first with fFirstrun = kTRUE" << endl;
264 } else if (firstRunFile->IsOpen()){
265 cout<<"----firstRunFile is open----"<<endl<<endl;
266 fHistProVthetaHar1 = (TProfile*)firstRunFile->Get("First_FlowProLYZ_Vtheta_Har1");
267 fHistProVthetaHar2 = (TProfile*)firstRunFile->Get("First_FlowProLYZ_Vtheta_Har2");
268 fHistProR0thetaHar2 = (TProfile*)firstRunFile->Get("First_FlowProLYZ_r0theta_Har2");
269 fHistProV = (TProfile*)firstRunFile->Get("First_FlowProLYZ_V");
274 if (fDebug) cout<<"****Histograms initialised****"<<endl;
275 if (fDebug) cout<<"****fFlowSelect in Init() "<<fFlowSelect<<"****"<<endl;
277 fEventNumber = 0; //set event counter to zero
281 //initialize LYZ summary class
282 fLYZSummary = new AliFlowLYZSummary();
283 fSummaryFile = new TFile("fFlowSummary.root","RECREATE","Flow LYZ summary file");
284 fSummaryFile->SetCompressionLevel(1);
285 fFlowTree = new TTree("FlowTree", "Flow Summary Tree");
286 fFlowTree->SetAutoSave(1000000); // autosave when 1 Mbyte written
287 fFlowTree->Branch("fLYZSummary","AliFlowLYZSummary",&fLYZSummary,25000,99);
293 //-----------------------------------------------------------------------
295 Bool_t AliFlowLeeYangZerosMaker::Make(AliFlowEvent* fFlowEvent)
298 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::Make()****"<<endl;
300 //get tracks from event
302 fFlowTracks = fFlowEvent->TrackCollection();
303 if (fDebug) cout<<"****fFlowSelect in Make() "<<fFlowSelect<<"****"<<endl;
304 if (fDebug) fFlowSelect->PrintSelectionList() ;
305 if (fDebug) fFlowSelect->PrintList() ;
307 if (fFlowSelect && fFlowSelect->Select(fFlowEvent)) // check if event is selected
309 fFlowTracks = fFlowEvent->TrackCollection(); //get tracks from event
310 fFlowEvent->SetSelections(fFlowSelect) ; // does the selection of tracks for r.p. calculation (sets flags in AliFlowTrack)
312 MakeControlHistograms(fFlowEvent);
313 FillFromFlowEvent(fFlowEvent);
316 MakeControlHistograms(fFlowEvent);
317 SecondFillFromFlowEvent(fFlowEvent);
322 cout<<"##### FlowLeeYangZero: FlowEvent pointer null"<<endl;
332 //-----------------------------------------------------------------------
333 Bool_t AliFlowLeeYangZerosMaker::Finish()
336 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::Finish()****"<<endl;
338 //define variables for both runs
344 Float_t fJ01 = 2.405;
345 Int_t fNtheta = AliFlowLYZConstants::kTheta;
349 for (Int_t j=0;j<AliFlowConstants::kHars;j++)
350 //loop over harmonics j=0 ->first harmonic, j=1 ->second harmonic
352 Float_t fMeanMult = fHistMult->GetMean();
353 //cerr<<"fMeanMult = "<<fMeanMult<<endl;
355 for (Int_t theta=0;theta<fNtheta;theta++)
357 //get the first minimum r0
358 fHist1[j][theta]->FillGtheta();
359 fR0 = fHist1[j][theta]->GetR0();
360 //cerr<<"fR0 = "<<fR0<<endl;
362 //calculate integrated flow
363 if (fR0!=0) fVtheta = fJ01/fR0;
366 fv = fVtheta/fMeanMult;
367 cerr<<"fv = "<<fv<<endl;
371 //fill the histograms
374 fHistProR0thetaHar1->Fill(theta,fR0);
375 fHistProVthetaHar1->Fill(theta,fVtheta);
376 fHistProV->Fill(j+1,fVtheta); //profile takes care of the averaging over theta.
380 fHistProR0thetaHar2->Fill(theta,fR0);
381 fHistProVthetaHar2->Fill(theta,fVtheta);
382 fHistProV->Fill(j+1,fVtheta); //profile takes care of the averaging over theta.
385 fHistProVR0->Fill(j+1,fv*100); //*100 to get % //profile takes care of the averaging over theta.
387 } //end of loop over theta
390 if (j==1) //second harmonic only temporarily
392 if (fEventNumber!=0) {
393 fQsum /= fEventNumber;
394 //cerr<<"fQsum.X() = "<<fQsum.X()<<endl;
395 //cerr<<"fQsum.Y() = "<<fQsum.Y()<<endl;
396 fQ2sum /= fEventNumber;
397 //cerr<<"fQ2sum = "<<fQ2sum<<endl;
398 fV = fHistProV->GetBinContent(j+1);
399 fSigma2 = fQ2sum - TMath::Power(fQsum.X(),2.) - TMath::Power(fQsum.Y(),2.) - TMath::Power(fV,2.); //BP eq. 62
400 if (fSigma2>0) fChi = fV/TMath::Sqrt(fSigma2);
402 cerr<<"fV = "<<fV<<" and chi = "<<fChi<<endl;
407 } //end of loop over harmonics
409 // recalculate statistical errors on integrated flow
410 //combining 5 theta angles to 1 relative error BP eq. 89
411 Double_t fRelErr2comb = 0.;
412 Int_t nEvts = fEventNumber;
413 for (Int_t theta=0;theta<fNtheta;theta++){
414 Double_t fTheta = ((double)theta/fNtheta)*TMath::Pi();
415 Double_t fApluscomb = TMath::Exp((fJ01*fJ01)/(2*fChi*fChi)*
417 Double_t fAmincomb = TMath::Exp(-(fJ01*fJ01)/(2*fChi*fChi)*
419 fRelErr2comb += (1/(2*nEvts*(fJ01*fJ01)*TMath::BesselJ1(fJ01)*
420 TMath::BesselJ1(fJ01)))*
421 (fApluscomb*TMath::BesselJ0(2*fJ01*TMath::Sin(fTheta/2)) +
422 fAmincomb*TMath::BesselJ0(2*fJ01)*TMath::Cos(fTheta/2));
424 fRelErr2comb /= fNtheta;
425 Double_t fRelErrcomb = TMath::Sqrt(fRelErr2comb);
426 cerr<<"fRelErrcomb = "<<fRelErrcomb<<endl;
428 //copy content of profile into TH1D and add error
429 for(Int_t b=0;b<2;b++){
430 Double_t fv2pro = fHistProVR0->GetBinContent(b+1);
431 fHistVR0->SetBinContent(b+1,fv2pro);
432 Double_t fv2Err = fv2pro*fRelErrcomb ;
433 cerr<<"fv2pro +- fv2Err = "<<fv2pro<<" +- "<<fv2Err<<" for bin "<<b+1<<endl;
434 fHistVR0->SetBinError(b+1,fv2Err);
438 if (fDebug) cout<<"****histograms filled****"<<endl;
442 if (fSummaryFile->IsOpen())
444 fSummaryFile->Write(0,TObject::kOverwrite);
445 fSummaryFile->Close();
450 //save histograms in file //temp for testing selector
455 fEventNumber =0; //set to zero for second round over events
461 //calculate differential flow
463 Float_t fEta, fPt, fReRatio, fVeta, fVPt;
464 Float_t fReDenom = 0;
465 Float_t fImDenom = 0;
467 TComplex fDenom, fNumer, fDtheta;
469 TComplex i = TComplex::I();
470 Float_t fBesselRatio[3] = {1., 1.202, 2.69};
471 Double_t fErrdifcomb = 0.; //set error to zero
472 Double_t fErr2difcomb = 0.; //set error to zero
476 for (Int_t j=0;j<AliFlowConstants::kHars;j++) //loop over harmonics j=0 ->first harmonic, j=1 ->second harmonic
478 for (Int_t theta=0;theta<fNtheta;theta++)
480 //get the first minimum r0
481 //fR0 = GetR0(fHist1[j][theta]->FillGtheta());
483 fReDenom = fHistProReDenomHar2->GetBinContent(theta+1);
484 fImDenom = fHistProImDenomHar2->GetBinContent(theta+1);
485 TComplex fDenom(fReDenom,fImDenom);
489 }//end of loop over theta
490 }//end of loop over harmonics
494 //for (Int_t j=0;j<AliFlowConstants::kHars;j++) //loop over harmonics j=0 ->first harmonic, j=1 ->second harmonic
496 Int_t j=1; //temp only harm 2
497 //fFlowSelect->SetHarmonic(j); //not needed here?
499 for (Int_t theta=0;theta<fNtheta;theta++) { //loop over theta
501 fR0 = fHistProR0thetaHar1->GetBinContent(theta+1);
503 //fVtheta = fHistProVthetaHar1->GetBinContent(theta+1); // BP Eq. 9 -> Vn^theta = j01/r0^theta
504 fReDenom = fHistProReDenomHar1->GetBinContent(theta+1);
505 fImDenom = fHistProImDenomHar1->GetBinContent(theta+1);
508 fR0 = fHistProR0thetaHar2->GetBinContent(theta+1);
509 if (fDebug) cerr<<"fR0 = "<<fR0<<endl;
510 fVtheta = 2.405/fR0; // BP Eq. 9 -> Vn^theta = j01/r0^theta
511 fReDenom = fHistProReDenomHar2->GetBinContent(theta+1);
512 fImDenom = fHistProImDenomHar2->GetBinContent(theta+1);
515 fDenom(fReDenom,fImDenom);
518 //for new method and use by others (only with the sum generating function):
520 fR0 = fHistProR0thetaHar2->GetBinContent(theta+1);
521 fDtheta = fR0*fDenom;
522 fHistProReDtheta->Fill(theta,fDtheta.Re());
523 fHistProImDtheta->Fill(theta,fDtheta.Im());
526 fDenom *= TComplex::Power(i, m-1);
527 //cerr<<"TComplex::Power(i, m-1) = "<<TComplex::Power(i, m-1).Rho()<<endl; //checked ok
529 //v as a function of eta
530 Int_t fEtaBins = AliFlowLYZConstants::kEtaBins;
531 for (Int_t be=1;be<=fEtaBins;be++) {
532 fEta = fHist2[j][theta]->GetBinCenter(be);
533 fNumer = fHist2[j][theta]->GetfNumer(be);
534 if (fNumer.Rho()==0) {
535 if (fDebug) cerr<<"WARNING: modulus of fNumer is zero in Finish()"<<endl;
538 else if (fDenom.Rho()==0) {
539 if (fDebug) cerr<<"WARNING: modulus of fDenom is zero"<<endl;
543 //if ( j==1 && theta==0) cerr<<"modulus of fNumer = "<<fNumer.Rho() <<endl; //always a number smaller than 1, or 0.
544 fReRatio = (fNumer/fDenom).Re();
547 fVeta = fBesselRatio[m-1]*fReRatio*fVtheta*100.; //BP eq. 12
548 //if ( j==1 && theta==0) cerr<<"eta = "<<fEta<<" cerr::fReRatio for eta = "<<fReRatio<<" cerr::fVeta for eta = "<<fVeta<<endl;
550 if (j==0) fHistProVetaHar1->Fill(fEta,fVeta);
551 if (j==1) fHistProVetaHar2->Fill(fEta,fVeta);
552 } //loop over bins be
554 //v as a function of Pt
555 Int_t fPtBins = AliFlowLYZConstants::kPtBins;
556 for (Int_t bp=1;bp<=fPtBins;bp++) {
557 fPt = fHist2[j][theta]->GetBinCenterPt(bp);
558 fNumer = fHist2[j][theta]->GetfNumerPt(bp);
559 if (fNumer.Rho()==0) {
560 if (fDebug) cerr<<"modulus of fNumer is zero"<<endl;
563 else if (fDenom.Rho()==0) {
564 if (fDebug) cerr<<"modulus of fDenom is zero"<<endl;
568 //if ( j==1 && theta==0) cerr<<"modulus of fNumer = "<<fNumer.Rho() <<endl; //always a number smaller than 1, or 0.
569 fReRatio = (fNumer/fDenom).Re();
572 fVPt = fBesselRatio[m-1]*fReRatio*fVtheta*100.; //BP eq. 12
573 //cerr<<"fBesselRatio[m-1] = "<<fBesselRatio[m-1]<<endl; //checked ok
574 //if ( j==1 && theta==0) cerr<<"pt = "<<fPt<<" cerr::fReRatio for pt = "<<fReRatio<<" cerr::fVPt for pt = "<<fVeta<<endl;
576 if (j==0) fHistProVPtHar1->Fill(fPt,fVPt);
577 if (j==1) fHistProVPtHar2->Fill(fPt,fVPt);
578 } //loop over bins bp
580 }//end of loop over theta
583 //sigma2 and chi (for statistical error calculations)
584 if (j==1) { //second harmonic only temporarily
586 if (fEventNumber!=0) {
587 fQsum /= fEventNumber;
588 //cerr<<"fQsum.X() = "<<fQsum.X()<<endl;
589 //cerr<<"fQsum.Y() = "<<fQsum.Y()<<endl;
590 fQ2sum /= fEventNumber;
591 cerr<<"fQ2sum = "<<fQ2sum<<endl;
592 fV = fHistProV->GetBinContent(j+1);
593 fSigma2 = fQ2sum - TMath::Power(fQsum.X(),2.) - TMath::Power(fQsum.Y(),2.) - TMath::Power(fV,2.); //BP eq. 62
594 if (fSigma2>0) fChi = fV/TMath::Sqrt(fSigma2);
596 cerr<<"fV = "<<fV<<" and chi = "<<fChi<<endl;
602 //copy content of profile into TH1D and add error
603 for(Int_t b=0;b<100;b++){
604 Double_t fv2pro = fHistProVPtHar2->GetBinContent(b);
606 for (Int_t theta=0;theta<fNtheta;theta++) {
607 Double_t fTheta = ((double)theta/fNtheta)*TMath::Pi();
608 Int_t Nprime = fHist2[j][theta]->GetNprimePt(b);
609 //cerr<<"Nprime = "<<Nprime<<endl;
611 Double_t fApluscomb = TMath::Exp((fJ01*fJ01)/(2*fChi*fChi)*
613 Double_t fAmincomb = TMath::Exp(-(fJ01*fJ01)/(2*fChi*fChi)*
615 fErr2difcomb += (TMath::Cos(fTheta)/(4*Nprime*TMath::BesselJ1(fJ01)*
616 TMath::BesselJ1(fJ01)))*
617 ((fApluscomb*TMath::BesselJ0(2*fJ01*TMath::Sin(fTheta/2))) -
618 (fAmincomb*TMath::BesselJ0(2*fJ01*TMath::Cos(fTheta/2))));
622 if (fErr2difcomb!=0.) {
623 fErr2difcomb /= fNtheta;
624 fErrdifcomb = TMath::Sqrt(fErr2difcomb)*100;
625 //cerr<<"fErrdifcomb = "<<fErrdifcomb<<endl;
627 else {fErrdifcomb = 0.;}
631 fHistVPtHar2->SetBinContent(b,fv2pro);
632 fHistVPtHar2->SetBinError(b,fErrdifcomb);
634 //check that error is set
635 //if (j==1) { cout<<"difference between calculated error and error in hostogram: "<< fErrdifcomb - fHistVPtHar2->GetBinError(b)<<endl; }
640 //} //end of loop over harmonics //temporarily out
642 //save histograms in file
646 //Note that when the file is closed, all histograms and Trees in memory associated with this file are deleted
647 if (fDebug) cout<<"****Histograms saved and fHistFile closed, all histograms deleted****"<<endl;
649 //close the first run file
650 firstRunFile->Close();
656 cout<<"----LYZ analysis finished....----"<<endl<<endl;
662 //-----------------------------------------------------------------------
663 Bool_t AliFlowLeeYangZerosMaker::MakeControlHistograms(AliFlowEvent* fFlowEvent)
665 //contol histograms of pt, eta, phi, Q, mult
666 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::MakeControlHistograms()****"<<endl;
670 Float_t fPt, fPhi, fEta, fQmult;
673 cout<<"##### FlowLeeYangZero: FlowEvent pointer null"<<endl;
678 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
682 //set selection and harmonic
683 fFlowSelect->SetSelection(1);
684 fFlowSelect->SetHarmonic(1); //second harmonic
686 //cerr<<"selection in MakeControlHistograms()"<<endl;
687 //fFlowSelect->PrintSelectionList() ;
688 //fFlowSelect->PrintList() ;
690 fFlowTracks = fFlowEvent->TrackCollection();
691 Int_t fNumberOfTracks = fFlowTracks->GetEntries();
692 fHistOrigMult->Fill(fNumberOfTracks);
693 //cerr<<"fNumberOfTracks = "<<fNumberOfTracks<<endl;
694 Int_t fMult = fFlowEvent->Mult(fFlowSelect); // Multiplicity of tracks in the specified Selection
695 fHistMult->Fill(fMult);
696 //cerr<<"Mult = "<<fMult<<endl;
698 fQ = fFlowEvent ->Q(fFlowSelect);
699 fQmult = fQ.Mod()/TMath::Sqrt(fNumberOfTracks);
700 fHistQ->Fill(fQmult);
702 Int_t tempmult = 0; //for testing
703 for (Int_t i=0;i<fNumberOfTracks;i++)
705 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
706 //if (fFlowSelect->SelectPart(fFlowTrack)) //if track is selected
707 if (fFlowSelect->Select(fFlowTrack))
709 fPt = fFlowTrack->Pt();
712 fPhi = fFlowTrack->Phi();
713 if (fPhi<0.) fPhi+=2*TMath::Pi();
714 fHistPhi->Fill(fPhi);
715 fEta = fFlowTrack->Eta();
716 fHistEta->Fill(fEta);
719 if (fMult!=tempmult){cerr<<"ERROR: Mult() is not tempmult! "<<fMult<<" :: "<<tempmult<<endl<<endl;}
720 //else {cerr<<"Mult()= tempmult "<<fMult<<" :: "<<tempmult<<endl<<endl;}
729 //-----------------------------------------------------------------------
731 Bool_t AliFlowLeeYangZerosMaker::FillFromFlowEvent(AliFlowEvent* fFlowEvent)
733 // Get event quantities from AliFlowEvent for all particles
735 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::FillFromFlowEvent()****"<<endl;
738 cout<<"##### FlowLeeYangZero: FlowEvent pointer null"<<endl;
743 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
749 TComplex fExpo, fGtheta, fGthetaNew, fZ;
751 Int_t fNtheta = AliFlowLYZConstants::kTheta;
752 Int_t fNbins = AliFlowLYZConstants::kNbins;
756 fFlowSelect->SetSelection(1);
758 for (Int_t j=0;j<AliFlowConstants::kHars;j++) //loop over harmonics j=0 ->first harmonic, j=1 ->second harmonic
761 fFlowSelect->SetHarmonic(j);
762 Float_t fOrder = (double)((j+1)/m);
763 //cerr<<"fOrder = "<<fOrder<<endl;
765 //get the Q vector from the FlowEvent
766 TVector2 fQ = fFlowEvent->Q(fFlowSelect);
767 //for chi calculation:
768 if (j==1) //second harmonic only temporarily
772 //cerr<<"fQ2sum = "<<fQ2sum<<endl;
775 fFlowTracks = fFlowEvent->TrackCollection();
777 for (Int_t theta=0;theta<fNtheta;theta++)
779 fTheta = ((float)theta/fNtheta)*TMath::Pi()/fOrder;
780 //cerr<<"fTheta = "<<fTheta<<endl;
782 //calculate fQtheta = cos(fOrder*(fPhi-fTheta);the projection of the Q vector on the reference direction fTheta
783 fQtheta = GetQtheta(fFlowSelect,fFlowTracks,fTheta);
784 //save fQtheta in AliFlowLYZSummary class
787 //AliFlowLYZSummary::SetQtheta(theta,fQtheta);
789 if (j==1 && theta==0) fHistQtheta->Fill(fQtheta);
790 //cerr<<"fQtheta = "<<fQtheta<<endl;
792 for (Int_t bin=1;bin<=fNbins;bin++)
794 Float_t fR = fHist1[j][theta]->GetBinCenter(bin); //bincentre of bins in histogram
795 //if (theta == 0) cerr<<"cerr::fR = "<<fR<<endl;
798 //calculate the sum generating function
799 fExpo(0.,fR*fQtheta); //Re=0 ; Im=fR*fQtheta
800 fGtheta = TComplex::Exp(fExpo);
804 //calculate the product generating function
805 fGtheta = GetGrtheta(fFlowSelect,fR,fTheta); //make this function
806 if (fGtheta.Rho2() > 100.) break;
809 fHist1[j][theta]->Fill(fR,fGtheta); //fill real and imaginary part of fGtheta
813 } //loop over harmonics
820 //-----------------------------------------------------------------------
821 Bool_t AliFlowLeeYangZerosMaker::SecondFillFromFlowEvent(AliFlowEvent* fFlowEvent)
823 //for differential flow
825 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::SecondFillFromFlowEvent()****"<<endl;
828 cout<<"##### FlowLeeYangZero: FlowEvent pointer null"<<endl;
833 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
839 TComplex fExpo, fDenom, fNumer,fCosTermComplex;
840 Float_t fOrder, fR0, fPhi, fEta, fPt;
843 Int_t fNtheta = AliFlowLYZConstants::kTheta;
846 fFlowSelect->SetSelection(1);
848 //cerr<<"selection in SecondFillFromFlowEvent()"<<endl;
849 //fFlowSelect->PrintSelectionList() ;
850 //fFlowSelect->PrintList() ;
853 for (Int_t j=0;j<AliFlowConstants::kHars;j++) //loop over harmonics j=0 ->first harmonic, j=1 ->second harmonic
856 fFlowSelect->SetHarmonic(j);
857 fOrder = (double)((j+1)/m);
859 //get the Q vector from the FlowEvent
860 TVector2 fQ = fFlowEvent->Q(fFlowSelect);
861 //for chi calculation:
862 if (j==1) //second harmonic only temporarily
866 //cerr<<"fQ2sum = "<<fQ2sum<<endl;
869 fFlowTracks = fFlowEvent->TrackCollection();
871 for (Int_t theta=0;theta<fNtheta;theta++)
873 fTheta = ((float)theta/fNtheta)*TMath::Pi()/fOrder;
875 //calculate fQtheta = cos(fOrder*(fPhi-fTheta);the projection of the Q vector on the reference direction fTheta
876 fQtheta = GetQtheta(fFlowSelect,fFlowTracks,fTheta);
877 //cerr<<"fQtheta for fdenom = "<<fQtheta<<endl;
880 if (j==0) //first harmonic
882 //denominator for differential v
883 fR0 = fHistProR0thetaHar1->GetBinContent(theta+1);
884 fExpo(0.,fR0*fQtheta);
885 fDenom = fQtheta*(TComplex::Exp(fExpo)); //BP eq 12
886 //cerr<<"fDenom.Re() = "<<fDenom.Re()<<endl;
887 //cerr<<"fDenom.Im() = "<<fDenom.Im()<<endl;
889 //denominator for differential v
890 // ****put in product generating function!!
893 fHistProReDenomHar1->Fill(theta,fDenom.Re()); //fill the real part of fDenom
894 fHistProImDenomHar1->Fill(theta,fDenom.Im()); //fill the imaginary part of fDenom
898 if (j==1) //second harmonic
900 //denominator for differential v
901 fR0 = fHistProR0thetaHar2->GetBinContent(theta+1);
902 //cerr<<"fR0 = "<<fR0 <<endl;
904 if (fUseSum) //sum generating function
906 fExpo(0.,fR0*fQtheta);
907 fDenom = fQtheta*(TComplex::Exp(fExpo)); //BP eq 12
908 //loop over tracks in event
909 fFlowTracks = fFlowEvent->TrackCollection();
910 Int_t fNumberOfTracks = fFlowTracks->GetEntries();
911 for (Int_t i=0;i<fNumberOfTracks;i++)
913 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
914 if (fFlowSelect->SelectPart(fFlowTrack)) //if track is selected
916 fPhi = fFlowTrack->Phi();
917 fCosTerm = cos(m*fOrder*(fPhi-fTheta));
918 //cerr<<"fCosTerm = "<<fCosTerm <<endl;
919 fNumer = fCosTerm*(TComplex::Exp(fExpo));
920 if (fNumer.Rho()==0) {cerr<<"WARNING: modulus of fNumer is zero in SecondFillFromFlowEvent"<<endl;}
921 if (fDebug) cerr<<"modulus of fNumer is "<<fNumer.Rho()<<endl;
922 fEta = fFlowTrack->Eta(); //rapidity
923 fPt = fFlowTrack->Pt();
924 fHist2[j][theta]->Fill(fEta,fPt,fNumer);
929 else //product generating function
931 fDenom = GetDiffFlow(fFlowSelect,fR0,theta);
935 fHistProReDenomHar2->Fill(theta,fDenom.Re()); //fill the real part of fDenom
936 fHistProImDenomHar2->Fill(theta,fDenom.Im()); //fill the imaginary part of fDenom
940 }//end of loop over theta
942 }//loop over harmonics
950 //-----------------------------------------------------------------------
951 Double_t AliFlowLeeYangZerosMaker::GetQtheta(AliFlowSelection* fFlowSelect, TObjArray* fFlowTracks, Float_t fTheta)
953 //calculate Qtheta. Qtheta is the sum over all particles of cos(fOrder*(fPhi-fTheta)) BP eq. 3
954 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::GetQtheta()****"<<endl;
957 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
962 Double_t fQtheta = 0.;
963 Int_t fHarmonic = fFlowSelect->Har();
964 Double_t fOrder = (double)(fHarmonic+1);
966 Int_t fNumberOfTracks = fFlowTracks->GetEntries();
967 //cerr<<"GetQtheta::fNumberOfTracks = "<<fNumberOfTracks<<endl;
969 for (Int_t i=0;i<fNumberOfTracks;i++) //loop over tracks in event
971 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
972 if(fFlowSelect->Select(fFlowTrack)) //if track is selected //gives the same number of particles as Mult(fFlowSelect) method
974 Float_t fPhi = fFlowTrack->Phi();
975 fQtheta += cos(fOrder*(fPhi-fTheta));
984 //-----------------------------------------------------------------------
985 TComplex AliFlowLeeYangZerosMaker::GetGrtheta(AliFlowSelection* fFlowSelect, Float_t fR, Float_t fTheta)
987 // Product Generating Function for LeeYangZeros method
988 // PG Eq. 3 (J. Phys. G Nucl. Part. Phys 30 S1213 (2004))
990 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::GetGrtheta()****"<<endl;
993 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
997 TComplex fG = TComplex::One();
998 Int_t fHarmonic = fFlowSelect->Har();
999 Double_t fOrder = (double)(fHarmonic+1);
1002 Int_t fNumberOfTracks = fFlowTracks->GetEntries();
1003 //cerr<<"GetGrtheta::fNumberOfTracks = "<<fNumberOfTracks<<endl;
1005 for (Int_t i=0;i<fNumberOfTracks;i++) //loop over tracks in event
1007 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
1008 if (fFlowSelect->SelectPart(fFlowTrack)) //if track is selected
1010 Float_t fPhi = fFlowTrack->Phi();
1011 Double_t fGIm = fR * fWgt*cos(fOrder*(fPhi - fTheta));
1012 TComplex fGi(1., fGIm);
1013 fG *= fGi; //product over all tracks
1022 //-----------------------------------------------------------------------
1023 TComplex AliFlowLeeYangZerosMaker::GetDiffFlow(AliFlowSelection* fFlowSelect, Float_t fR0, Int_t theta)
1025 // Sum for the denominator for diff. flow for the Product Generating Function for LeeYangZeros method
1026 // PG Eq. 9 (J. Phys. G Nucl. Part. Phys 30 S1213 (2004))
1027 // Also for v1 mixed harmonics: DF Eq. 5
1028 // It is the deriverative of Grtheta at r0 divided by Grtheta at r0
1030 if (fDebug) cout<<"****AliFlowLeeYangZerosMaker::GetGrtheta()****"<<endl;
1033 cout<<"##### FlowLeeYangZero: FlowSelect pointer null"<<endl;
1038 TComplex fG = TComplex::One();
1039 TComplex fdGr0(0.,0.);
1040 Int_t fHarmonic = fFlowSelect->Har();
1041 Double_t fOrder = (double)(fHarmonic+1);
1044 Int_t fNumberOfTracks = fFlowTracks->GetEntries();
1045 //cerr<<"GetGrtheta::fNumberOfTracks = "<<fNumberOfTracks<<endl;
1047 Int_t fNtheta = AliFlowLYZConstants::kTheta;
1048 Float_t fTheta = ((float)theta/fNtheta)*TMath::Pi()/fOrder;
1050 for (Int_t i=0;i<fNumberOfTracks;i++) //loop over tracks in event
1052 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
1053 if (fFlowSelect->SelectPart(fFlowTrack)) //if track is selected
1055 Float_t fPhi = fFlowTrack->Phi();
1056 Double_t fCosTerm = fWgt*cos(fOrder*(fPhi - fTheta));
1058 Double_t fGIm = fR0 * fCosTerm;
1059 TComplex fGi(1., fGIm);
1060 fG *= fGi; //product over all tracks
1062 TComplex fCosTermComplex(1., fR0*fCosTerm);
1063 fdGr0 +=(fCosTerm / fCosTermComplex); //sum over all tracks
1067 for (Int_t i=0;i<fNumberOfTracks;i++)
1069 fFlowTrack = (AliFlowTrack*)fFlowTracks->At(i) ; //get object at array position i
1070 if (fFlowSelect->SelectPart(fFlowTrack)) //if track is selected
1072 Float_t fPhi = fFlowTrack->Phi();
1073 Double_t fCosTerm = cos(fOrder*(fPhi-fTheta));
1074 TComplex fCosTermComplex(1.,fR0*fCosTerm);
1076 TComplex fNumer = fG*fCosTerm/fCosTermComplex; //PG Eq. 9
1077 Float_t fEta = fFlowTrack->Eta(); //rapidity
1078 Float_t fPt = fFlowTrack->Pt();
1079 fHist2[1][theta]->Fill(fEta,fPt,fNumer);
1083 TComplex fDenom = fG*fdGr0;
1088 //-------------------------------------------------