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 "AliFlowTrackSimpleCuts.h"
42 #include "AliFlowEventSimple.h"
48 ClassImp(AliFlowEventSimple)
50 //-----------------------------------------------------------------------
51 AliFlowEventSimple::AliFlowEventSimple():
52 fTrackCollection(NULL),
53 fReferenceMultiplicity(0),
55 fUseGlauberMCSymmetryPlanes(kFALSE),
56 fUseExternalSymmetryPlanes(kFALSE),
65 fMCReactionPlaneAngle(0.),
66 fMCReactionPlaneAngleIsSet(kFALSE),
67 fAfterBurnerPrecision(0.001),
68 fUserModified(kFALSE),
69 fNumberOfTracksWrap(NULL),
70 fNumberOfRPsWrap(NULL),
71 fNumberOfPOIsWrap(NULL),
72 fMCReactionPlaneAngleWrap(NULL),
73 fShuffledIndexes(NULL),
74 fShuffleTracks(kFALSE),
75 fMothersCollection(NULL),
80 cout << "AliFlowEventSimple: Default constructor to be used only by root for io" << endl;
83 //-----------------------------------------------------------------------
84 AliFlowEventSimple::AliFlowEventSimple( Int_t n,
85 ConstructionMethod method,
91 fTrackCollection(new TObjArray(n)),
92 fReferenceMultiplicity(0),
94 fUseGlauberMCSymmetryPlanes(kFALSE),
95 fUseExternalSymmetryPlanes(kFALSE),
104 fMCReactionPlaneAngle(0.),
105 fMCReactionPlaneAngleIsSet(kFALSE),
106 fAfterBurnerPrecision(0.001),
107 fUserModified(kFALSE),
108 fNumberOfTracksWrap(NULL),
109 fNumberOfRPsWrap(NULL),
110 fNumberOfPOIsWrap(NULL),
111 fMCReactionPlaneAngleWrap(NULL),
112 fShuffledIndexes(NULL),
113 fShuffleTracks(kFALSE),
114 fMothersCollection(new TObjArray()),
116 fNumberOfPOItypes(2),
117 fNumberOfPOIs(new Int_t[fNumberOfPOItypes])
120 // if second argument is set to AliFlowEventSimple::kGenerate
121 // it generates n random tracks with given Pt distribution
122 // (a sane default is provided), phi and eta are uniform
124 if (method==kGenerate)
125 Generate(n,ptDist,phiMin,phiMax,etaMin,etaMax);
128 //-----------------------------------------------------------------------
129 AliFlowEventSimple::AliFlowEventSimple(const AliFlowEventSimple& anEvent):
131 fTrackCollection((TObjArray*)(anEvent.fTrackCollection)->Clone()),
132 fReferenceMultiplicity(anEvent.fReferenceMultiplicity),
133 fNumberOfTracks(anEvent.fNumberOfTracks),
134 fUseGlauberMCSymmetryPlanes(anEvent.fUseGlauberMCSymmetryPlanes),
135 fUseExternalSymmetryPlanes(anEvent.fUseExternalSymmetryPlanes),
136 fPsi1(anEvent.fPsi1),
137 fPsi2(anEvent.fPsi2),
138 fPsi3(anEvent.fPsi3),
139 fPsi4(anEvent.fPsi4),
140 fPsi5(anEvent.fPsi5),
141 fPsi1Psi3(anEvent.fPsi1Psi3),
142 fPsi2Psi4(anEvent.fPsi2Psi4),
143 fPsi3Psi5(anEvent.fPsi3Psi5),
144 fMCReactionPlaneAngle(anEvent.fMCReactionPlaneAngle),
145 fMCReactionPlaneAngleIsSet(anEvent.fMCReactionPlaneAngleIsSet),
146 fAfterBurnerPrecision(anEvent.fAfterBurnerPrecision),
147 fUserModified(anEvent.fUserModified),
148 fNumberOfTracksWrap(anEvent.fNumberOfTracksWrap),
149 fNumberOfRPsWrap(anEvent.fNumberOfRPsWrap),
150 fNumberOfPOIsWrap(anEvent.fNumberOfPOIsWrap),
151 fMCReactionPlaneAngleWrap(anEvent.fMCReactionPlaneAngleWrap),
152 fShuffledIndexes(NULL),
153 fShuffleTracks(anEvent.fShuffleTracks),
154 fMothersCollection(new TObjArray()),
155 fCentrality(anEvent.fCentrality),
156 fNumberOfPOItypes(anEvent.fNumberOfPOItypes),
157 fNumberOfPOIs(new Int_t[fNumberOfPOItypes])
160 memcpy(fNumberOfPOIs,anEvent.fNumberOfPOIs,fNumberOfPOItypes*sizeof(Int_t));
163 //-----------------------------------------------------------------------
164 void AliFlowEventSimple::SetNumberOfPOIs( Int_t numberOfPOIs, Int_t poiType)
166 //set the number of poi classes, resize the array if larger is needed
167 //never shrink the array
168 //never decrease the stored number
169 if (poiType>=fNumberOfPOItypes)
172 Int_t* tmp = new Int_t[n];
173 for (Int_t j=0; j<n; j++) { tmp[j]=0; }
174 memcpy(tmp,fNumberOfPOIs,fNumberOfPOItypes*sizeof(Int_t));
175 delete [] fNumberOfPOIs;
177 fNumberOfPOItypes = n;
180 fNumberOfPOIs[poiType] = numberOfPOIs;
183 //-----------------------------------------------------------------------
184 void AliFlowEventSimple::IncrementNumberOfPOIs(Int_t poiType)
187 if (poiType>=fNumberOfPOItypes) SetNumberOfPOIs(0,poiType);
188 fNumberOfPOIs[poiType]++;
191 //-----------------------------------------------------------------------
192 AliFlowEventSimple& AliFlowEventSimple::operator=(const AliFlowEventSimple& anEvent)
194 //assignment operator
195 if (&anEvent==this) return *this; //check self-assignment
196 if (fTrackCollection) fTrackCollection->Delete();
197 delete fTrackCollection;
198 fTrackCollection = (TObjArray*)(anEvent.fTrackCollection)->Clone(); //deep copy
199 fReferenceMultiplicity = anEvent.fReferenceMultiplicity;
200 fNumberOfTracks = anEvent.fNumberOfTracks;
201 fNumberOfPOItypes = anEvent.fNumberOfPOItypes;
202 delete [] fNumberOfPOIs;
203 fNumberOfPOIs=new Int_t[fNumberOfPOItypes];
204 memcpy(fNumberOfPOIs,anEvent.fNumberOfPOIs,fNumberOfPOItypes*sizeof(Int_t));
205 fUseGlauberMCSymmetryPlanes = anEvent.fUseGlauberMCSymmetryPlanes;
206 fUseExternalSymmetryPlanes = anEvent.fUseExternalSymmetryPlanes;
207 fPsi1 = anEvent.fPsi1;
208 fPsi2 = anEvent.fPsi2;
209 fPsi3 = anEvent.fPsi3;
210 fPsi4 = anEvent.fPsi4;
211 fPsi5 = anEvent.fPsi5;
212 fPsi1Psi3 = anEvent.fPsi1Psi3;
213 fPsi2Psi4 = anEvent.fPsi2Psi4;
214 fPsi3Psi5 = anEvent.fPsi3Psi5;
215 fMCReactionPlaneAngle = anEvent.fMCReactionPlaneAngle;
216 fMCReactionPlaneAngleIsSet = anEvent.fMCReactionPlaneAngleIsSet;
217 fAfterBurnerPrecision = anEvent.fAfterBurnerPrecision;
218 fUserModified=anEvent.fUserModified;
219 fNumberOfTracksWrap = anEvent.fNumberOfTracksWrap;
220 fNumberOfRPsWrap = anEvent.fNumberOfRPsWrap;
221 fNumberOfPOIsWrap = anEvent.fNumberOfPOIsWrap;
222 fMCReactionPlaneAngleWrap=anEvent.fMCReactionPlaneAngleWrap;
223 fShuffleTracks=anEvent.fShuffleTracks;
224 delete [] fShuffledIndexes;
228 //-----------------------------------------------------------------------
229 AliFlowEventSimple::~AliFlowEventSimple()
232 if (fTrackCollection) fTrackCollection->Delete();
233 delete fTrackCollection;
234 delete fNumberOfTracksWrap;
235 delete fNumberOfRPsWrap;
236 delete fNumberOfPOIsWrap;
237 delete fMCReactionPlaneAngleWrap;
238 delete fShuffledIndexes;
239 delete fMothersCollection;
240 delete [] fNumberOfPOIs;
243 //-----------------------------------------------------------------------
244 void AliFlowEventSimple::SetUseExternalSymmetryPlanes(TF1 *gPsi1Psi3,
247 //Use symmetry planes, setup correlations between different Psi_n
248 fUseExternalSymmetryPlanes = kTRUE;
250 //Correlations between Psi_1 and Psi_3
251 if(gPsi1Psi3) fPsi1Psi3 = gPsi1Psi3;
253 fPsi1Psi3 = new TF1("fPsi1Psi3","[0]*x+[1]",0.,2.*TMath::Pi());
254 fPsi1Psi3->SetParameter(0,1.);
255 fPsi1Psi3->SetParameter(1,0.);
258 //Correlations between Psi_2 and Psi_4
259 if(gPsi2Psi4) fPsi2Psi4 = gPsi2Psi4;
261 fPsi2Psi4 = new TF1("fPsi2Psi4","[0]*x+[1]",0.,2.*TMath::Pi());
262 fPsi2Psi4->SetParameter(0,1.);
263 fPsi2Psi4->SetParameter(1,0.);
266 //Correlations between Psi_3 and Psi_5
267 if(gPsi3Psi5) fPsi3Psi5 = gPsi3Psi5;
269 fPsi3Psi5 = new TF1("fPsi3Psi5","[0]*x+[1]",0.,2.*TMath::Pi());
270 fPsi3Psi5->SetParameter(0,1.);
271 fPsi3Psi5->SetParameter(1,0.);
275 //-----------------------------------------------------------------------
276 void AliFlowEventSimple::Generate(Int_t nParticles,
283 //generate nParticles random tracks uniform in phi and eta
284 //according to the specified pt distribution
287 static TF1 ptdistribution("ptSpectra","x*TMath::Exp(-pow(0.13957*0.13957+x*x,0.5)/0.4)",0.1,10.);
288 ptDist=&ptdistribution;
291 for (Int_t i=0; i<nParticles; i++)
293 AliFlowTrackSimple* track = new AliFlowTrackSimple();
294 track->SetPhi( gRandom->Uniform(phiMin,phiMax) );
295 track->SetEta( gRandom->Uniform(etaMin,etaMax) );
296 track->SetPt( ptDist->GetRandom() );
297 track->SetCharge( (gRandom->Uniform()-0.5<0)?-1:1 );
300 if(fUseExternalSymmetryPlanes) {
301 Double_t betaParameter = gRandom->Gaus(0.,1.3);
302 fPsi1Psi3->SetParameter(1,betaParameter);
304 betaParameter = gRandom->Gaus(0.,0.9);
305 fPsi2Psi4->SetParameter(1,betaParameter);
307 betaParameter = gRandom->Gaus(0.,1.5);
308 fPsi3Psi5->SetParameter(1,betaParameter);
310 fPsi1 = gRandom->Uniform(2.*TMath::Pi());
311 fPsi2 = gRandom->Uniform(2.*TMath::Pi());
312 fPsi3 = fPsi1Psi3->Eval(fPsi1);
313 if(fPsi3 < 0) fPsi3 += 2.*TMath::Pi();
314 else if(fPsi3 > 2.*TMath::Pi()) fPsi3 -= 2.*TMath::Pi();
315 fPsi4 = fPsi2Psi4->Eval(fPsi2);
316 if(fPsi4 < 0) fPsi4 += 2.*TMath::Pi();
317 else if(fPsi4 > 2.*TMath::Pi()) fPsi4 -= 2.*TMath::Pi();
318 fPsi5 = fPsi3Psi5->Eval(fPsi3);
319 if(fPsi5 < 0) fPsi5 += 2.*TMath::Pi();
320 else if(fPsi5 > 2.*TMath::Pi()) fPsi5 -= 2.*TMath::Pi();
322 fMCReactionPlaneAngle=fPsi2;
323 fMCReactionPlaneAngleIsSet=kTRUE;
326 fMCReactionPlaneAngle=gRandom->Uniform(0.0,TMath::TwoPi());
327 fMCReactionPlaneAngleIsSet=kTRUE;
332 //-----------------------------------------------------------------------
333 AliFlowTrackSimple* AliFlowEventSimple::GetTrack(Int_t i)
335 //get track i from collection
336 if (i>=fNumberOfTracks) return NULL;
338 //if asked use the shuffled index
341 if (!fShuffledIndexes) ShuffleTracks();
342 trackIndex=fShuffledIndexes[i];
344 AliFlowTrackSimple* pTrack = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(trackIndex)) ;
348 //-----------------------------------------------------------------------
349 void AliFlowEventSimple::ShuffleTracks()
351 //shuffle track indexes
352 if (!fShuffledIndexes)
354 //initialize the table with shuffled indexes
355 fShuffledIndexes = new Int_t[fNumberOfTracks];
356 for (Int_t j=0; j<fNumberOfTracks; j++) { fShuffledIndexes[j]=j; }
359 std::random_shuffle(&fShuffledIndexes[0], &fShuffledIndexes[fNumberOfTracks]);
360 Printf("Tracks shuffled! tracks: %i",fNumberOfTracks);
363 //-----------------------------------------------------------------------
364 void AliFlowEventSimple::AddTrack( AliFlowTrackSimple* track )
366 //add a track, delete the old one if necessary
367 if (fNumberOfTracks < fTrackCollection->GetEntriesFast())
369 TObject* o = fTrackCollection->At(fNumberOfTracks);
372 fTrackCollection->AddAtAndExpand(track,fNumberOfTracks);
373 if (track->GetNDaughters()>0)
375 //if there track has daughters cache in the collection of mothers
376 fMothersCollection->Add(track);
381 //-----------------------------------------------------------------------
382 void AliFlowEventSimple::TrackAdded()
384 //book keeping after a new track has been added
386 if (fShuffledIndexes)
388 delete [] fShuffledIndexes;
389 fShuffledIndexes=NULL;
393 //-----------------------------------------------------------------------
394 AliFlowTrackSimple* AliFlowEventSimple::MakeNewTrack()
396 AliFlowTrackSimple *t=dynamic_cast<AliFlowTrackSimple *>(fTrackCollection->RemoveAt(fNumberOfTracks));
397 if( !t ) { // If there was no track at the end of the list then create a new track
398 t=new AliFlowTrackSimple();
404 //-----------------------------------------------------------------------
405 AliFlowVector AliFlowEventSimple::GetQ( Int_t n,
407 Bool_t usePhiWeights,
409 Bool_t useEtaWeights )
411 // calculate Q-vector in harmonic n without weights (default harmonic n=2)
418 Double_t sumOfWeights = 0.;
422 Double_t dWeight = 1.;
424 AliFlowTrackSimple* pTrack = NULL;
427 Double_t dBinWidthPt = 0.;
428 Double_t dPtMin = 0.;
429 Double_t dBinWidthEta = 0.;
430 Double_t dEtaMin = 0.;
432 Double_t wPhi = 1.; // weight Phi
433 Double_t wPt = 1.; // weight Pt
434 Double_t wEta = 1.; // weight Eta
436 TH1F *phiWeights = NULL;
437 TH1D *ptWeights = NULL;
438 TH1D *etaWeights = NULL;
444 phiWeights = dynamic_cast<TH1F *>(weightsList->FindObject("phi_weights"));
445 if(phiWeights) nBinsPhi = phiWeights->GetNbinsX();
449 ptWeights = dynamic_cast<TH1D *>(weightsList->FindObject("pt_weights"));
452 dBinWidthPt = ptWeights->GetBinWidth(1); // assuming that all bins have the same width
453 dPtMin = (ptWeights->GetXaxis())->GetXmin();
458 etaWeights = dynamic_cast<TH1D *>(weightsList->FindObject("eta_weights"));
461 dBinWidthEta = etaWeights->GetBinWidth(1); // assuming that all bins have the same width
462 dEtaMin = (etaWeights->GetXaxis())->GetXmin();
465 } // end of if(weightsList)
468 for(Int_t i=0; i<fNumberOfTracks; i++)
470 pTrack = (AliFlowTrackSimple*)fTrackCollection->At(i);
473 if(pTrack->InRPSelection())
475 dPhi = pTrack->Phi();
477 dEta = pTrack->Eta();
478 dWeight = pTrack->Weight();
480 // determine Phi weight: (to be improved, I should here only access it + the treatment of gaps in the if statement)
481 if(phiWeights && nBinsPhi)
483 wPhi = phiWeights->GetBinContent(1+(Int_t)(TMath::Floor(dPhi*nBinsPhi/TMath::TwoPi())));
485 // determine v'(pt) weight:
486 if(ptWeights && dBinWidthPt)
488 wPt=ptWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-dPtMin)/dBinWidthPt)));
490 // determine v'(eta) weight:
491 if(etaWeights && dBinWidthEta)
493 wEta=etaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-dEtaMin)/dBinWidthEta)));
496 // building up the weighted Q-vector:
497 dQX += dWeight*wPhi*wPt*wEta*TMath::Cos(iOrder*dPhi);
498 dQY += dWeight*wPhi*wPt*wEta*TMath::Sin(iOrder*dPhi);
500 // weighted multiplicity:
501 sumOfWeights += dWeight*wPhi*wPt*wEta;
503 } // end of if (pTrack->InRPSelection())
504 } // end of if (pTrack)
507 cerr << "no particle!!!"<<endl;
509 } // loop over particles
512 vQ.SetMult(sumOfWeights);
513 vQ.SetHarmonic(iOrder);
514 vQ.SetPOItype(AliFlowTrackSimple::kRP);
515 vQ.SetSubeventNumber(-1);
521 //-----------------------------------------------------------------------
522 void AliFlowEventSimple::Get2Qsub( AliFlowVector* Qarray,
525 Bool_t usePhiWeights,
527 Bool_t useEtaWeights )
530 // calculate Q-vector in harmonic n without weights (default harmonic n=2)
535 Double_t sumOfWeights = 0.;
539 Double_t dWeight = 1.;
541 AliFlowTrackSimple* pTrack = NULL;
543 Int_t iNbinsPhiSub0 = 0;
544 Int_t iNbinsPhiSub1 = 0;
545 Double_t dBinWidthPt = 0.;
546 Double_t dPtMin = 0.;
547 Double_t dBinWidthEta= 0.;
548 Double_t dEtaMin = 0.;
550 Double_t dWphi = 1.; // weight Phi
551 Double_t dWpt = 1.; // weight Pt
552 Double_t dWeta = 1.; // weight Eta
554 TH1F* phiWeightsSub0 = NULL;
555 TH1F* phiWeightsSub1 = NULL;
556 TH1D* ptWeights = NULL;
557 TH1D* etaWeights = NULL;
563 phiWeightsSub0 = dynamic_cast<TH1F *>(weightsList->FindObject("phi_weights_sub0"));
565 iNbinsPhiSub0 = phiWeightsSub0->GetNbinsX();
567 phiWeightsSub1 = dynamic_cast<TH1F *>(weightsList->FindObject("phi_weights_sub1"));
569 iNbinsPhiSub1 = phiWeightsSub1->GetNbinsX();
574 ptWeights = dynamic_cast<TH1D *>(weightsList->FindObject("pt_weights"));
577 dBinWidthPt = ptWeights->GetBinWidth(1); // assuming that all bins have the same width
578 dPtMin = (ptWeights->GetXaxis())->GetXmin();
583 etaWeights = dynamic_cast<TH1D *>(weightsList->FindObject("eta_weights"));
586 dBinWidthEta = etaWeights->GetBinWidth(1); // assuming that all bins have the same width
587 dEtaMin = (etaWeights->GetXaxis())->GetXmin();
590 } // end of if(weightsList)
592 //loop over the two subevents
593 for (Int_t s=0; s<2; s++)
596 for(Int_t i=0; i<fNumberOfTracks; i++)
598 pTrack = (AliFlowTrackSimple*)fTrackCollection->At(i);
601 cerr << "no particle!!!"<<endl;
604 if(pTrack->InRPSelection() && (pTrack->InSubevent(s)))
606 dPhi = pTrack->Phi();
608 dEta = pTrack->Eta();
609 dWeight = pTrack->Weight();
611 // determine Phi weight: (to be improved, I should here only access it + the treatment of gaps in the if statement)
614 if(phiWeightsSub0 && iNbinsPhiSub0) {
615 Int_t phiBin = 1+(Int_t)(TMath::Floor(dPhi*iNbinsPhiSub0/TMath::TwoPi()));
616 //use the phi value at the center of the bin
617 dPhi = phiWeightsSub0->GetBinCenter(phiBin);
618 dWphi = phiWeightsSub0->GetBinContent(phiBin);
623 if(phiWeightsSub1 && iNbinsPhiSub1) {
624 Int_t phiBin = 1+(Int_t)(TMath::Floor(dPhi*iNbinsPhiSub1/TMath::TwoPi()));
625 //use the phi value at the center of the bin
626 dPhi = phiWeightsSub1->GetBinCenter(phiBin);
627 dWphi = phiWeightsSub1->GetBinContent(phiBin);
631 // determine v'(pt) weight:
632 if(ptWeights && dBinWidthPt)
634 dWpt=ptWeights->GetBinContent(1+(Int_t)(TMath::Floor((dPt-dPtMin)/dBinWidthPt)));
637 // determine v'(eta) weight:
638 if(etaWeights && dBinWidthEta)
640 dWeta=etaWeights->GetBinContent(1+(Int_t)(TMath::Floor((dEta-dEtaMin)/dBinWidthEta)));
643 // building up the weighted Q-vector:
644 dQX += dWeight*dWphi*dWpt*dWeta*TMath::Cos(iOrder*dPhi);
645 dQY += dWeight*dWphi*dWpt*dWeta*TMath::Sin(iOrder*dPhi);
647 // weighted multiplicity:
648 sumOfWeights+=dWeight*dWphi*dWpt*dWeta;
650 } // end of if (pTrack->InRPSelection())
651 } // loop over particles
653 Qarray[s].Set(dQX,dQY);
654 Qarray[s].SetMult(sumOfWeights);
655 Qarray[s].SetHarmonic(iOrder);
656 Qarray[s].SetPOItype(AliFlowTrackSimple::kRP);
657 Qarray[s].SetSubeventNumber(s);
668 //-----------------------------------------------------------------------
669 void AliFlowEventSimple::Print(Option_t *option) const
671 // -*-*-*-*-*Print some global quantities for this histogram collection class *-*-*-*-*-*-*-*
672 // ===============================================
673 // printf( "TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
674 printf( "Class.Print Name = %s, #tracks= %d, Number of RPs= %d, Number of POIs = %d, MC EventPlaneAngle= %f\n",
675 GetName(),fNumberOfTracks, fNumberOfPOIs[0], fNumberOfPOIs[1], fMCReactionPlaneAngle );
677 TString optionstr(option);
678 if (!optionstr.Contains("all")) return;
679 if (fTrackCollection)
681 fTrackCollection->Print(option);
685 printf( "Empty track collection \n");
689 //-----------------------------------------------------------------------
690 void AliFlowEventSimple::Browse(TBrowser *b)
694 if (!fNumberOfTracksWrap)
696 fNumberOfTracksWrap = new TParameter<int>("fNumberOfTracks", fNumberOfTracks);
697 b->Add(fNumberOfTracksWrap);
699 if (!fNumberOfRPsWrap)
701 fNumberOfRPsWrap = new TParameter<int>("fNumberOfRPs", GetNumberOfRPs());
702 b->Add(fNumberOfRPsWrap);
704 if (!fNumberOfPOIsWrap)
706 fNumberOfPOIsWrap = new TParameter<int>("fNumberOfPOIs", GetNumberOfPOIs());
707 b->Add(fNumberOfPOIsWrap);
709 if (!fMCReactionPlaneAngleWrap)
711 fMCReactionPlaneAngleWrap = new TParameter<double>(" fMCReactionPlaneAngle", fMCReactionPlaneAngle);
712 b->Add( fMCReactionPlaneAngleWrap);
714 if (fTrackCollection) b->Add(fTrackCollection,"AliFlowTracksSimple");
717 //-----------------------------------------------------------------------
718 AliFlowEventSimple::AliFlowEventSimple( TTree* inputTree,
719 const AliFlowTrackSimpleCuts* rpCuts,
720 const AliFlowTrackSimpleCuts* poiCuts):
721 fTrackCollection(NULL),
722 fReferenceMultiplicity(0),
724 fUseGlauberMCSymmetryPlanes(kFALSE),
725 fUseExternalSymmetryPlanes(kFALSE),
734 fMCReactionPlaneAngle(0.),
735 fMCReactionPlaneAngleIsSet(kFALSE),
736 fAfterBurnerPrecision(0.001),
737 fUserModified(kFALSE),
738 fNumberOfTracksWrap(NULL),
739 fNumberOfRPsWrap(NULL),
740 fNumberOfPOIsWrap(NULL),
741 fMCReactionPlaneAngleWrap(NULL),
742 fShuffledIndexes(NULL),
743 fShuffleTracks(kFALSE),
744 fMothersCollection(new TObjArray()),
746 fNumberOfPOItypes(2),
747 fNumberOfPOIs(new Int_t[fNumberOfPOItypes])
749 //constructor, fills the event from a TTree of kinematic.root files
750 //applies RP and POI cuts, tags the tracks
752 Int_t numberOfInputTracks = inputTree->GetEntries() ;
753 fTrackCollection = new TObjArray(numberOfInputTracks/2);
755 TParticle* pParticle = new TParticle();
756 inputTree->SetBranchAddress("Particles",&pParticle);
758 for (Int_t i=0; i<numberOfInputTracks; i++)
760 inputTree->GetEntry(i); //get input particle
762 if (!pParticle) continue; //no particle
763 if (!pParticle->IsPrimary()) continue;
765 Bool_t rpOK = (rpCuts->PassesCuts(pParticle)>0);
766 Bool_t poiOK = poiCuts->PassesCuts(pParticle);
767 Int_t poiType = poiCuts->GetPOItype();
771 AliFlowTrackSimple* pTrack = new AliFlowTrackSimple(pParticle);
773 //marking the particles used for int. flow:
776 pTrack->TagRP(kTRUE);
777 IncrementNumberOfPOIs(0);
778 cout<<"numberOfRPs = "<<fNumberOfPOIs[0]<<endl;
780 //marking the particles used for diff. flow:
783 pTrack->Tag(poiType);
784 IncrementNumberOfPOIs(poiType);
785 printf("fNumberOfPOIs[%i] = %i",poiType,fNumberOfPOIs[poiType]);
787 //adding a particles which were used either for int. or diff. flow to the list
794 //_____________________________________________________________________________
795 void AliFlowEventSimple::CloneTracks(Int_t n)
797 //clone every track n times to add non-flow
798 if (n<=0) return; //no use to clone stuff zero or less times
799 Int_t ntracks = fNumberOfTracks;
800 fTrackCollection->Expand((n+1)*fNumberOfTracks);
801 for (Int_t i=0; i<n; i++)
803 for (Int_t itrack=0; itrack<ntracks; itrack++)
805 AliFlowTrackSimple* track = dynamic_cast<AliFlowTrackSimple*>(fTrackCollection->At(itrack));
806 if (!track) continue;
807 AddTrack(static_cast<AliFlowTrackSimple*>(track->Clone()));
813 //_____________________________________________________________________________
814 void AliFlowEventSimple::ResolutionPt(Double_t res)
816 //smear pt of all tracks by gaussian with sigma=res
817 for (Int_t i=0; i<fNumberOfTracks; i++)
819 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
820 if (track) track->ResolutionPt(res);
825 //_____________________________________________________________________________
826 void AliFlowEventSimple::TagSubeventsInEta( Double_t etaMinA,
831 //Flag two subevents in given eta ranges
832 for (Int_t i=0; i<fNumberOfTracks; i++)
834 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
835 if (!track) continue;
836 track->ResetSubEventTags();
837 Double_t eta=track->Eta();
838 if (eta >= etaMinA && eta <= etaMaxA) track->SetForSubevent(0);
839 if (eta >= etaMinB && eta <= etaMaxB) track->SetForSubevent(1);
843 //_____________________________________________________________________________
844 void AliFlowEventSimple::TagSubeventsByCharge()
846 //Flag two subevents in given eta ranges
847 for (Int_t i=0; i<fNumberOfTracks; i++)
849 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
850 if (!track) continue;
851 track->ResetSubEventTags();
852 Int_t charge=track->Charge();
853 if (charge<0) track->SetForSubevent(0);
854 if (charge>0) track->SetForSubevent(1);
858 //_____________________________________________________________________________
859 void AliFlowEventSimple::AddV1( Double_t v1 )
861 //add v2 to all tracks wrt the reaction plane angle
862 for (Int_t i=0; i<fNumberOfTracks; i++)
864 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
866 if((fUseExternalSymmetryPlanes)||(fUseGlauberMCSymmetryPlanes))
867 track->AddV1(v1, fPsi1, fAfterBurnerPrecision);
869 track->AddV1(v1, fMCReactionPlaneAngle, fAfterBurnerPrecision);
875 //_____________________________________________________________________________
876 void AliFlowEventSimple::AddV2( Double_t v2 )
878 //add v2 to all tracks wrt the reaction plane angle
879 for (Int_t i=0; i<fNumberOfTracks; i++)
881 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
883 if((fUseExternalSymmetryPlanes)||(fUseGlauberMCSymmetryPlanes))
884 track->AddV2(v2, fPsi2, fAfterBurnerPrecision);
886 track->AddV2(v2, fMCReactionPlaneAngle, fAfterBurnerPrecision);
892 //_____________________________________________________________________________
893 void AliFlowEventSimple::AddV3( Double_t v3 )
895 //add v3 to all tracks wrt the reaction plane angle
896 for (Int_t i=0; i<fNumberOfTracks; i++)
898 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
900 if((fUseExternalSymmetryPlanes)||(fUseGlauberMCSymmetryPlanes))
901 track->AddV3(v3, fPsi3, fAfterBurnerPrecision);
903 track->AddV3(v3, fMCReactionPlaneAngle, fAfterBurnerPrecision);
909 //_____________________________________________________________________________
910 void AliFlowEventSimple::AddV4( Double_t v4 )
912 //add v4 to all tracks wrt the reaction plane angle
913 for (Int_t i=0; i<fNumberOfTracks; i++)
915 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
917 if((fUseExternalSymmetryPlanes)||(fUseGlauberMCSymmetryPlanes))
918 track->AddV4(v4, fPsi4, fAfterBurnerPrecision);
920 track->AddV4(v4, fMCReactionPlaneAngle, fAfterBurnerPrecision);
926 //_____________________________________________________________________________
927 void AliFlowEventSimple::AddV5( Double_t v5 )
929 //add v4 to all tracks wrt the reaction plane angle
930 for (Int_t i=0; i<fNumberOfTracks; i++)
932 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
934 if((fUseExternalSymmetryPlanes)||(fUseGlauberMCSymmetryPlanes))
935 track->AddV5(v5, fPsi5, fAfterBurnerPrecision);
937 track->AddV5(v5, fMCReactionPlaneAngle, fAfterBurnerPrecision);
943 //_____________________________________________________________________________
944 void AliFlowEventSimple::AddFlow( Double_t v1, Double_t v2, Double_t v3, Double_t v4, Double_t v5,
945 Double_t rp1, Double_t rp2, Double_t rp3, Double_t rp4, Double_t rp5 )
947 //add flow to all tracks wrt the reaction plane angle, for all harmonic separate angle
948 for (Int_t i=0; i<fNumberOfTracks; i++)
950 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
951 if (track) track->AddFlow(v1,v2,v3,v4,v5,rp1,rp2,rp3,rp4,rp5,fAfterBurnerPrecision);
956 //_____________________________________________________________________________
957 void AliFlowEventSimple::AddFlow( Double_t v1, Double_t v2, Double_t v3, Double_t v4, Double_t v5 )
959 //add flow to all tracks wrt the reaction plane angle
960 for (Int_t i=0; i<fNumberOfTracks; i++)
962 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
963 if (track) track->AddFlow(v1,v2,v3,v4,v5,fMCReactionPlaneAngle, fAfterBurnerPrecision);
968 //_____________________________________________________________________________
969 void AliFlowEventSimple::AddV2( TF1* ptDepV2 )
971 //add v2 to all tracks wrt the reaction plane angle
972 for (Int_t i=0; i<fNumberOfTracks; i++)
974 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
975 if (!track) continue;
976 Double_t v2 = ptDepV2->Eval(track->Pt());
977 track->AddV2(v2, fMCReactionPlaneAngle, fAfterBurnerPrecision);
982 //_____________________________________________________________________________
983 void AliFlowEventSimple::TagRP( const AliFlowTrackSimpleCuts* cuts )
985 //tag tracks as reference particles (RPs)
986 for (Int_t i=0; i<fNumberOfTracks; i++)
988 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
989 if (!track) continue;
990 Bool_t pass=cuts->PassesCuts(track);
991 Bool_t rpTrack=track->InRPSelection();
994 if (!rpTrack) fNumberOfPOIs[0]++; //only increase if not already tagged
998 if (rpTrack) fNumberOfPOIs[0]--; //only decrease if detagging
1000 track->SetForRPSelection(pass);
1004 //_____________________________________________________________________________
1005 void AliFlowEventSimple::TagPOI( const AliFlowTrackSimpleCuts* cuts, Int_t poiType )
1007 //tag tracks as particles of interest (POIs)
1008 for (Int_t i=0; i<fNumberOfTracks; i++)
1010 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
1011 if (!track) continue;
1012 Bool_t pass=cuts->PassesCuts(track);
1013 Bool_t poiTrack=track->InPOISelection();
1016 if (!poiTrack) fNumberOfPOIs[poiType]++; //only increase if not already tagged
1020 if (poiTrack) fNumberOfPOIs[poiType]--; //only decrease if detagging
1022 track->Tag(poiType,pass);
1026 //_____________________________________________________________________________
1027 void AliFlowEventSimple::TagTracks( const AliFlowTrackSimpleCuts* cutsRP, const AliFlowTrackSimpleCuts* cutsPOI)
1029 // simple interface to tagging poi's and rp's
1033 //_____________________________________________________________________________
1034 void AliFlowEventSimple::DefineDeadZone( Double_t etaMin,
1039 //mark tracks in given eta-phi region as dead
1040 //by resetting the flow bits
1041 for (Int_t i=0; i<fNumberOfTracks; i++)
1043 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
1044 Double_t eta = track->Eta();
1045 Double_t phi = track->Phi();
1046 if (eta>etaMin && eta<etaMax && phi>phiMin && phi<phiMax)
1048 if (track->InRPSelection()) {fNumberOfPOIs[0]--;}
1049 for (Int_t j=1; j<fNumberOfPOItypes; j++)
1051 if (track->CheckTag(j)) {fNumberOfPOIs[j]--;}
1053 track->ResetPOItype();
1058 //_____________________________________________________________________________
1059 Int_t AliFlowEventSimple::CleanUpDeadTracks()
1061 //remove tracks that have no flow tags set and cleanup the container
1062 //returns number of cleaned tracks
1064 for (Int_t i=0; i<fNumberOfTracks; i++)
1066 AliFlowTrackSimple* track = static_cast<AliFlowTrackSimple*>(fTrackCollection->At(i));
1067 if (!track) continue;
1068 if (track->IsDead()) {delete track;track=NULL;ncleaned++;}
1070 fTrackCollection->Compress(); //clean up empty slots
1071 fNumberOfTracks-=ncleaned; //update number of tracks
1072 delete [] fShuffledIndexes; fShuffledIndexes=NULL;
1076 //_____________________________________________________________________________
1077 TF1* AliFlowEventSimple::SimplePtDepV2()
1079 //return a standard pt dependent v2 formula, user has to clean up!
1080 return new TF1("StandardPtDepV2","((x<1.0)*(0.05/1.0)*x+(x>=1.0)*0.05)");
1083 //_____________________________________________________________________________
1084 TF1* AliFlowEventSimple::SimplePtSpectrum()
1086 //return a standard pt spectrum, user has to clean up!
1087 return new TF1("StandardPtSpectrum","x*TMath::Exp(-pow(0.13957*0.13957+x*x,0.5)/0.4)",0.1,10.);
1090 //_____________________________________________________________________________
1091 void AliFlowEventSimple::ClearFast()
1093 //clear the counters without deleting allocated objects so they can be reused
1094 fReferenceMultiplicity = 0;
1095 fNumberOfTracks = 0;
1096 for (Int_t i=0; i<fNumberOfPOItypes; i++)
1098 fNumberOfPOIs[i] = 0;
1100 fMCReactionPlaneAngle = 0.0;
1101 fMCReactionPlaneAngleIsSet = kFALSE;
1102 fAfterBurnerPrecision = 0.001;
1103 fUserModified = kFALSE;
1104 delete [] fShuffledIndexes; fShuffledIndexes=NULL;