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 **************************************************************************/
16 /*****************************************************************
17 AliFlowEventSimple: A simple event
20 origin: Naomi van der Kolk (kolk@nikhef.nl)
21 Ante Bilandzic (anteb@nikhef.nl)
22 Raimond Snellings (Raimond.Snellings@nikhef.nl)
23 mods: Mikolaj Krzewicki (mikolaj.krzewicki@cern.ch)
24 *****************************************************************/
26 #include "Riostream.h"
27 #include "TObjArray.h"
31 #include "TParticle.h"
37 #include "TParameter.h"
39 #include "AliFlowVector.h"
40 #include "AliFlowTrackSimple.h"
41 #include "AliFlowEventSimple.h"
42 #include "AliFlowTrackSimpleCuts.h"
45 ClassImp(AliFlowEventSimple)
47 //-----------------------------------------------------------------------
48 AliFlowEventSimple::AliFlowEventSimple():
49 fTrackCollection(NULL),
50 fReferenceMultiplicity(0),
53 fMCReactionPlaneAngle(0.),
54 fMCReactionPlaneAngleIsSet(kFALSE),
55 fAfterBurnerPrecision(0.001),
56 fNumberOfTracksWrap(NULL),
57 fNumberOfRPsWrap(NULL),
58 fMCReactionPlaneAngleWrap(NULL)
60 cout << "AliFlowEventSimple: Default constructor to be used only by root for io" << endl;
63 //-----------------------------------------------------------------------
64 AliFlowEventSimple::AliFlowEventSimple(Int_t aLength):
65 fTrackCollection(new TObjArray(aLength)),
66 fReferenceMultiplicity(0),
69 fMCReactionPlaneAngle(0.),
70 fMCReactionPlaneAngleIsSet(kFALSE),
71 fAfterBurnerPrecision(0.001),
72 fNumberOfTracksWrap(NULL),
73 fNumberOfRPsWrap(NULL),
74 fMCReactionPlaneAngleWrap(NULL)
79 //-----------------------------------------------------------------------
80 AliFlowEventSimple::AliFlowEventSimple( Int_t nParticles,
86 fTrackCollection(new TObjArray(nParticles)),
87 fReferenceMultiplicity(nParticles),
90 fMCReactionPlaneAngle(0.),
91 fMCReactionPlaneAngleIsSet(kFALSE),
92 fAfterBurnerPrecision(0.001),
93 fNumberOfTracksWrap(NULL),
94 fNumberOfRPsWrap(NULL),
95 fMCReactionPlaneAngleWrap(NULL)
97 //ctor. generates nParticles random tracks with given Pt distribution
98 //phi and eta are uniform
99 Generate(nParticles,ptDist,phiMin,phiMax,etaMin,etaMax);
102 //-----------------------------------------------------------------------
103 AliFlowEventSimple::AliFlowEventSimple(const AliFlowEventSimple& anEvent):
105 fTrackCollection((TObjArray*)(anEvent.fTrackCollection)->Clone()),
106 fReferenceMultiplicity(anEvent.fReferenceMultiplicity),
107 fNumberOfTracks(anEvent.fNumberOfTracks),
108 fNumberOfRPs(anEvent.fNumberOfRPs),
109 fMCReactionPlaneAngle(anEvent.fMCReactionPlaneAngle),
110 fMCReactionPlaneAngleIsSet(anEvent.fMCReactionPlaneAngleIsSet),
111 fAfterBurnerPrecision(anEvent.fAfterBurnerPrecision),
112 fNumberOfTracksWrap(anEvent.fNumberOfTracksWrap),
113 fNumberOfRPsWrap(anEvent.fNumberOfRPsWrap),
114 fMCReactionPlaneAngleWrap(anEvent.fMCReactionPlaneAngleWrap)
119 //-----------------------------------------------------------------------
120 AliFlowEventSimple& AliFlowEventSimple::operator=(const AliFlowEventSimple& anEvent)
122 //assignment operator
123 delete fTrackCollection;
124 fTrackCollection = (TObjArray*)(anEvent.fTrackCollection)->Clone(); //deep copy
125 fReferenceMultiplicity = anEvent.fReferenceMultiplicity;
126 fNumberOfTracks = anEvent.fNumberOfTracks;
127 fNumberOfRPs = anEvent.fNumberOfRPs;
128 fMCReactionPlaneAngle = anEvent.fMCReactionPlaneAngle;
129 fMCReactionPlaneAngleIsSet = anEvent.fMCReactionPlaneAngleIsSet;
130 fAfterBurnerPrecision = anEvent.fAfterBurnerPrecision;
131 fNumberOfTracksWrap = anEvent.fNumberOfTracksWrap;
132 fNumberOfRPsWrap = anEvent.fNumberOfRPsWrap;
133 fMCReactionPlaneAngleWrap=anEvent.fMCReactionPlaneAngleWrap;
137 //-----------------------------------------------------------------------
138 AliFlowEventSimple::~AliFlowEventSimple()
141 if (fTrackCollection) fTrackCollection->Delete();
142 delete fTrackCollection;
143 if (fNumberOfTracksWrap) delete fNumberOfTracksWrap;
144 if (fNumberOfRPsWrap) delete fNumberOfRPsWrap;
145 if (fMCReactionPlaneAngleWrap) delete fMCReactionPlaneAngleWrap;
148 //-----------------------------------------------------------------------
149 void AliFlowEventSimple::Generate(Int_t nParticles,
156 //generate nParticles random tracks uniform in phi and eta
157 //according to the specified pt distribution
158 for (Int_t i=0; i<nParticles; i++)
160 AddTrack(new AliFlowTrackSimple( gRandom->Uniform(phiMin,phiMax),
161 gRandom->Uniform(etaMin,etaMax),
162 ptDist->GetRandom()));
166 //-----------------------------------------------------------------------
167 AliFlowTrackSimple* AliFlowEventSimple::GetTrack(Int_t i)
169 //get track i from collection
170 if (i>=fNumberOfTracks) return NULL;
171 AliFlowTrackSimple* pTrack = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i)) ;
175 //-----------------------------------------------------------------------
176 void AliFlowEventSimple::AddTrack( AliFlowTrackSimple* track )
179 fTrackCollection->AddLast(track);
183 //-----------------------------------------------------------------------
184 AliFlowVector AliFlowEventSimple::GetQ(Int_t n, TList *weightsList, Bool_t usePhiWeights, Bool_t usePtWeights, Bool_t useEtaWeights)
186 // calculate Q-vector in harmonic n without weights (default harmonic n=2)
193 Double_t iUsedTracks = 0;
198 AliFlowTrackSimple* pTrack = NULL;
201 Double_t dBinWidthPt=0.;
203 Double_t dBinWidthEta=0.;
206 Double_t wPhi=1.; // weight Phi
207 Double_t wPt=1.; // weight Pt
208 Double_t wEta=1.; // weight Eta
210 TH1F *phiWeights = NULL;
211 TH1D *ptWeights = NULL;
212 TH1D *etaWeights = NULL;
218 phiWeights = dynamic_cast<TH1F *>(weightsList->FindObject("phi_weights"));
219 if(phiWeights) nBinsPhi = phiWeights->GetNbinsX();
223 ptWeights = dynamic_cast<TH1D *>(weightsList->FindObject("pt_weights"));
226 dBinWidthPt = ptWeights->GetBinWidth(1); // assuming that all bins have the same width
227 dPtMin = (ptWeights->GetXaxis())->GetXmin();
232 etaWeights = dynamic_cast<TH1D *>(weightsList->FindObject("eta_weights"));
235 dBinWidthEta = etaWeights->GetBinWidth(1); // assuming that all bins have the same width
236 dEtaMin = (etaWeights->GetXaxis())->GetXmin();
239 } // end of if(weightsList)
242 for(Int_t i=0; i<fNumberOfTracks; i++)
244 pTrack = (AliFlowTrackSimple*)fTrackCollection->At(i);
247 if(pTrack->InRPSelection())
249 dPhi = pTrack->Phi();
251 dEta = pTrack->Eta();
253 // determine Phi weight: (to be improved, I should here only access it + the treatment of gaps in the if statement)
254 if(phiWeights && nBinsPhi)
256 wPhi = phiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*nBinsPhi/TMath::TwoPi())));
258 // determine v'(pt) weight:
259 if(ptWeights && dBinWidthPt)
261 wPt=ptWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-dPtMin)/dBinWidthPt)));
263 // determine v'(eta) weight:
264 if(etaWeights && dBinWidthEta)
266 wEta=etaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-dEtaMin)/dBinWidthEta)));
269 // building up the weighted Q-vector:
270 dQX += wPhi*wPt*wEta*TMath::Cos(iOrder*dPhi);
271 dQY += wPhi*wPt*wEta*TMath::Sin(iOrder*dPhi);
273 // weighted multiplicity:
274 iUsedTracks+=wPhi*wPt*wEta;
276 } // end of if (pTrack->InRPSelection())
277 } // end of if (pTrack)
280 cerr << "no particle!!!"<<endl;
282 } // loop over particles
285 vQ.SetMult(iUsedTracks);
291 //-----------------------------------------------------------------------
292 void AliFlowEventSimple::Get2Qsub(AliFlowVector* Qarray, Int_t n, TList *weightsList, Bool_t usePhiWeights, Bool_t usePtWeights, Bool_t useEtaWeights)
295 // calculate Q-vector in harmonic n without weights (default harmonic n=2)
300 Double_t iUsedTracks = 0;
305 AliFlowTrackSimple* pTrack = NULL;
308 Double_t dBinWidthPt = 0.;
309 Double_t dPtMin = 0.;
310 Double_t dBinWidthEta= 0.;
311 Double_t dEtaMin = 0.;
313 Double_t dWphi = 1.; // weight Phi
314 Double_t dWpt = 1.; // weight Pt
315 Double_t dWeta = 1.; // weight Eta
317 TH1F* phiWeights = NULL;
318 TH1D* ptWeights = NULL;
319 TH1D* etaWeights = NULL;
325 phiWeights = dynamic_cast<TH1F *>(weightsList->FindObject("phi_weights"));
328 iNbinsPhi = phiWeights->GetNbinsX();
333 ptWeights = dynamic_cast<TH1D *>(weightsList->FindObject("pt_weights"));
336 dBinWidthPt = ptWeights->GetBinWidth(1); // assuming that all bins have the same width
337 dPtMin = (ptWeights->GetXaxis())->GetXmin();
342 etaWeights = dynamic_cast<TH1D *>(weightsList->FindObject("eta_weights"));
345 dBinWidthEta = etaWeights->GetBinWidth(1); // assuming that all bins have the same width
346 dEtaMin = (etaWeights->GetXaxis())->GetXmin();
349 } // end of if(weightsList)
351 //loop over the two subevents
352 for (Int_t s=0; s<2; s++)
355 for(Int_t i=0; i<fNumberOfTracks; i++)
357 pTrack = (AliFlowTrackSimple*)fTrackCollection->At(i);
360 if(pTrack->InRPSelection())
362 if (pTrack->InSubevent(s))
364 dPhi = pTrack->Phi();
366 dEta = pTrack->Eta();
368 // determine Phi weight: (to be improved, I should here only access it + the treatment of gaps in the if statement)
369 if(phiWeights && iNbinsPhi)
371 dWphi = phiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*iNbinsPhi/TMath::TwoPi())));
373 // determine v'(pt) weight:
374 if(ptWeights && dBinWidthPt)
376 dWpt=ptWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-dPtMin)/dBinWidthPt)));
378 // determine v'(eta) weight:
379 if(etaWeights && dBinWidthEta)
381 dWeta=etaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-dEtaMin)/dBinWidthEta)));
384 // building up the weighted Q-vector:
385 dQX += dWphi*dWpt*dWeta*TMath::Cos(iOrder*dPhi);
386 dQY += dWphi*dWpt*dWeta*TMath::Sin(iOrder*dPhi);
388 // weighted multiplicity:
389 iUsedTracks+=dWphi*dWpt*dWeta;
392 } // end of if (pTrack->InRPSelection())
393 } // end of if (pTrack)
396 cerr << "no particle!!!"<<endl;
398 } // loop over particles
399 Qarray[s].Set(dQX,dQY);
400 Qarray[s].SetMult(iUsedTracks);
410 //-----------------------------------------------------------------------
411 void AliFlowEventSimple::Print(Option_t *option) const
413 // -*-*-*-*-*Print some global quantities for this histogram collection class *-*-*-*-*-*-*-*
414 // ===============================================
415 // printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
416 printf( "Class.Print Name = %s, Total number of tracks= %d, Number of selected tracks= %d, MC EventPlaneAngle= %f\n",
417 GetName(),fNumberOfTracks, fNumberOfRPs, fMCReactionPlaneAngle );
419 if (fTrackCollection)
421 fTrackCollection->Print(option);
425 printf( "Empty track collection \n");
429 //-----------------------------------------------------------------------
430 void AliFlowEventSimple::Browse(TBrowser *b)
433 if (!fNumberOfTracksWrap)
435 fNumberOfTracksWrap = new TParameter<int>("fNumberOfTracks", fNumberOfTracks);
436 b->Add(fNumberOfTracksWrap);
438 if (!fNumberOfRPsWrap)
440 fNumberOfRPsWrap = new TParameter<int>("fNumberOfRPs", fNumberOfRPs);
441 b->Add(fNumberOfRPsWrap);
443 if (!fMCReactionPlaneAngleWrap)
445 fMCReactionPlaneAngleWrap = new TParameter<double>(" fMCReactionPlaneAngle", fMCReactionPlaneAngle);
446 b->Add( fMCReactionPlaneAngleWrap);
448 if (fTrackCollection) b->Add(fTrackCollection,"AliFlowTracksSimple");
451 //-----------------------------------------------------------------------
452 AliFlowEventSimple::AliFlowEventSimple( TTree* inputTree,
453 const AliFlowTrackSimpleCuts* rpCuts,
454 const AliFlowTrackSimpleCuts* poiCuts):
455 fTrackCollection(NULL),
456 fReferenceMultiplicity(0),
459 fMCReactionPlaneAngle(0.),
460 fMCReactionPlaneAngleIsSet(kFALSE),
461 fAfterBurnerPrecision(0.001),
462 fNumberOfTracksWrap(NULL),
463 fNumberOfRPsWrap(NULL),
464 fMCReactionPlaneAngleWrap(NULL)
466 //constructor, fills the event from a TTree of kinematic.root files
467 //applies RP and POI cuts, tags the tracks
469 Int_t numberOfInputTracks = inputTree->GetEntries() ;
470 fTrackCollection = new TObjArray(numberOfInputTracks/2);
472 TParticle* pParticle = new TParticle();
473 inputTree->SetBranchAddress("Particles",&pParticle);
475 Int_t iSelParticlesPOI = 0;
477 for (Int_t i=0; i<numberOfInputTracks; i++)
479 inputTree->GetEntry(i); //get input particle
481 if (!pParticle) continue; //no particle
482 if (!pParticle->IsPrimary()) continue;
484 Bool_t rpOK = rpCuts->PassesCuts(pParticle);
485 Bool_t poiOK = poiCuts->PassesCuts(pParticle);
489 AliFlowTrackSimple* pTrack = new AliFlowTrackSimple(pParticle);
491 //marking the particles used for int. flow:
494 pTrack->SetForRPSelection(kTRUE);
497 //marking the particles used for diff. flow:
500 pTrack->SetForPOISelection(kTRUE);
503 //adding a particles which were used either for int. or diff. flow to the list
510 //_____________________________________________________________________________
511 void AliFlowEventSimple::CloneTracks(Int_t n)
513 //clone every track n times to add non-flow
514 Int_t ntracks = fNumberOfTracks;
515 fTrackCollection->Expand((n+1)*fNumberOfTracks);
516 for (Int_t i=0; i<n; i++)
518 for (Int_t itrack=0; itrack<ntracks; itrack++)
520 AliFlowTrackSimple* track = dynamic_cast<AliFlowTrackSimple*>(fTrackCollection->At(itrack));
521 if (!track) continue;
522 AddTrack(static_cast<AliFlowTrackSimple*>(track->Clone()));
527 //_____________________________________________________________________________
528 void AliFlowEventSimple::ResolutionPt(Double_t res)
530 //smear pt of all tracks by gaussian with sigma=res
531 for (Int_t i=0; i<fNumberOfTracks; i++)
533 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
534 if (track) track->ResolutionPt(res);
538 //_____________________________________________________________________________
539 void AliFlowEventSimple::TagSubeventsInEta(Double_t etaMinA, Double_t etaMaxA, Double_t etaMinB, Double_t etaMaxB )
541 //Flag two subevents in given eta ranges
542 for (Int_t i=0; i<fNumberOfTracks; i++)
544 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
545 Double_t eta=track->Eta();
546 if (eta >= etaMinA && eta <= etaMaxA) track->SetForSubevent(0);
547 if (eta >= etaMinB && eta <= etaMaxB) track->SetForSubevent(1);
551 //_____________________________________________________________________________
552 void AliFlowEventSimple::AddV1(Double_t v1)
554 //add v2 to all tracks wrt the reaction plane angle
555 for (Int_t i=0; i<fNumberOfTracks; i++)
557 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
558 if (track) track->AddV1(v1, fMCReactionPlaneAngle, fAfterBurnerPrecision);
562 //_____________________________________________________________________________
563 void AliFlowEventSimple::AddV2(Double_t v2)
565 //add v2 to all tracks wrt the reaction plane angle
566 for (Int_t i=0; i<fNumberOfTracks; i++)
568 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
569 if (track) track->AddV2(v2, fMCReactionPlaneAngle, fAfterBurnerPrecision);
573 //_____________________________________________________________________________
574 void AliFlowEventSimple::AddV4(Double_t v4)
576 //add v4 to all tracks wrt the reaction plane angle
577 for (Int_t i=0; i<fNumberOfTracks; i++)
579 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
580 if (track) track->AddV4(v4, fMCReactionPlaneAngle, fAfterBurnerPrecision);
584 //_____________________________________________________________________________
585 void AliFlowEventSimple::AddFlow(Double_t v1, Double_t v2, Double_t v4)
587 //add flow to all tracks wrt the reaction plane angle
588 for (Int_t i=0; i<fNumberOfTracks; i++)
590 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
591 if (track) track->AddFlow(v1,v2,v4,fMCReactionPlaneAngle, fAfterBurnerPrecision);
595 //_____________________________________________________________________________
596 void AliFlowEventSimple::TagRP(AliFlowTrackSimpleCuts* cuts)
598 //tag tracks as reference particles (RPs)
599 for (Int_t i=0; i<fNumberOfTracks; i++)
601 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
602 if (!track) continue;
603 if (cuts->PassesCuts(track)) track->SetForRPSelection();
607 //_____________________________________________________________________________
608 void AliFlowEventSimple::TagPOI(AliFlowTrackSimpleCuts* cuts)
610 //tag tracks as particles of interest (POIs)
611 for (Int_t i=0; i<fNumberOfTracks; i++)
613 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
614 if (!track) continue;
615 if (cuts->PassesCuts(track)) track->SetForPOISelection();