]>
Commit | Line | Data |
---|---|---|
30a892e3 | 1 | ////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // $Id$ | |
4 | // | |
5 | // Author: Emanuele Simili | |
6 | // | |
7 | ////////////////////////////////////////////////////////////////////// | |
8 | // | |
9 | //_____________________________________________________________ | |
10 | // | |
11 | // Description: | |
12 | // AliFlowEvent is the basic class to perform flow study in ALICE. | |
13 | // The AliFlowEvent object contains data mebers wich summarize the ESD | |
14 | // informations that are most useful for flow study, together with a | |
15 | // collection of tracks (AliFlowTrackCollection) and reconstructed v0s. | |
16 | // The class also implements member functions to calculate Multiplicity, | |
17 | // Mean P and Pt, Q (the event plane vector), Psi (the event plane angle), | |
18 | // normalized q (Q/sqrt(Mult) and Q/sqrt(sum of weights^2)), moreover, | |
19 | // functions to separate random or eta sub-events, to fill the bayesian vector | |
20 | // of particle abundance (for bayesian p.id calculation), to plug-in weights | |
21 | // (to make the tracks' distribution isotropic and to enhance the resolution), | |
22 | // and to select the tracks that are used in the event plane calculation (for | |
23 | // each harmonic, selection, and subevent. | |
24 | // AliFlowEvent supports the standard analysis as well as the Cumulant | |
25 | // Analysis: method to extract the generating functions for the old and new | |
26 | // cumulant methods is also there. | |
27 | // The Flow Event structure (AliFlowEvent, AliFlowTrack, AliFlowV0 and | |
28 | // AliFlowSelection) is independent from AliRoot, i.e. once the FlowEvents | |
29 | // are filled from the AliESD or the MC KineTree (see AliFlowInterface: here | |
30 | // AliRoot is needed), the flow analysis itself can be performed just under | |
31 | // ROOT (see AliFlowAnalysisMaker). | |
32 | // | |
33 | // AliFlowEvent is adapted from the original class StFlowEvent, succesfully | |
34 | // employed to study flow in the STAR experiment at RICH. | |
35 | // Original Authors: Raimond Snellings & Art Poskanzer | |
36 | // | |
37 | ||
38 | #include "AliFlowEvent.h" | |
92016a03 | 39 | #include "AliFlowTrack.h" |
40 | #include "AliFlowV0.h" | |
41 | #include "AliFlowSelection.h" | |
30a892e3 | 42 | #include "AliFlowConstants.h" |
92016a03 | 43 | |
30a892e3 | 44 | #include "TVector.h" |
45 | #include "TVector2.h" | |
46 | #include "TVector3.h" | |
92016a03 | 47 | #include "TClonesArray.h" |
48 | #include "TMath.h" | |
49 | #include "TRandom.h" | |
50 | #include "TString.h" | |
30a892e3 | 51 | #include <iostream> |
52 | using namespace std; //required for resolving the 'cout' symbol | |
53 | ||
54 | // - Flags & Sets | |
92016a03 | 55 | Bool_t AliFlowEvent::fgPtWgt = kFALSE ; // gives pT-based weights |
56 | Bool_t AliFlowEvent::fgEtaWgt = kFALSE ; // gives eta-based weights | |
4e566f2f | 57 | Bool_t AliFlowEvent::fgOnePhiWgt = kTRUE ; // kTRUE --> ENABLEs SINGLE WEIGHT ISTOGRAM , kFALSE --> ENABLEs 3 WEIGHT ISTOGRAMS |
92016a03 | 58 | Bool_t AliFlowEvent::fgNoWgt = kFALSE ; // No Weight is used |
30a892e3 | 59 | // - Eta Sub-Events (later used to calculate the resolution) |
4e566f2f | 60 | Bool_t AliFlowEvent::fgEtaSubs = kFALSE ; // makes eta subevents |
61 | Bool_t AliFlowEvent::fgCustomRespFunc = kFALSE ; // custom "detector response function" is used for P.Id (see AliFlowTrack) | |
30a892e3 | 62 | |
f847c9e2 | 63 | ClassImp(AliFlowEvent) |
30a892e3 | 64 | //----------------------------------------------------------- |
4e566f2f | 65 | AliFlowEvent::AliFlowEvent(Int_t lenght): |
d8b98e74 | 66 | fEventID(0), fRunID(0), fOrigMult(0), fL0Trigger(0), fZDCpart(0), fCentrality(-1), fDone(kFALSE), |
67 | fTrackCollection(0x0), fV0Collection(0x0) | |
30a892e3 | 68 | { |
69 | // Default constructor: initializes the ObjArray of FlowTracks and FlowV0s, | |
70 | // cleans the internal variables, sets all the weights to 1, sets default flags. | |
71 | ||
30a892e3 | 72 | for(int zz=0;zz<3;zz++) { fZDCenergy[zz] = 0. ; } |
92016a03 | 73 | for(int i=0;i<AliFlowConstants::kHars;i++) { fExtPsi[i] = 0. ; fExtRes[i] = 0.; } |
30a892e3 | 74 | |
75 | // Make a new track collection | |
92016a03 | 76 | fTrackCollection = new TClonesArray("AliFlowTrack",lenght) ; fTrackCollection->BypassStreamer(kTRUE) ; |
77 | fV0Collection = new TClonesArray("AliFlowV0",lenght) ; fV0Collection->BypassStreamer(kTRUE) ; | |
30a892e3 | 78 | |
79 | // Set Weights Arrays to 1 (default) | |
327288af | 80 | for(int nS=0;nS<AliFlowConstants::kSels;nS++) |
30a892e3 | 81 | { |
327288af | 82 | for(int nH=0;nH<AliFlowConstants::kHars;nH++) |
30a892e3 | 83 | { |
327288af | 84 | for(int nP=0;nP<AliFlowConstants::kPhiBins;nP++) |
30a892e3 | 85 | { |
86 | // enable this with: SetOnePhiWgt() | |
87 | fPhiWgt[nS][nH][nP] = 1. ; // cout << nS << nH << nP << " val " << fPhiWgt[nS][nH][nP] << endl ; | |
88 | // enable these with: SetFirstLastPhiWgt() | |
89 | fPhiWgtPlus[nS][nH][nP] = 1. ; // cout << nS << nH << nP << " val " << fPhiWgtPlus[nS][nH][nP] << endl ; | |
90 | fPhiWgtMinus[nS][nH][nP] = 1. ; // cout << nS << nH << nP << " val " << fPhiWgtMinus[nS][nH][nP] << endl ; | |
91 | fPhiWgtCross[nS][nH][nP] = 1. ; // cout << nS << nH << nP << " val " << fPhiWgtCross[nS][nH][nP] << endl ; | |
92 | } | |
93 | } | |
94 | } | |
327288af | 95 | //for(int nH=0;nH<AliFlowConstants::kHars;nH++) { fExtPsi[nH] = 0. ; fExtRes[nH] = 0. ; } |
30a892e3 | 96 | |
327288af | 97 | // The Expected particles abundance is taken directly from AliFlowConstants::fgBayesian[] (see Bayesian P.Id.) |
30a892e3 | 98 | |
30a892e3 | 99 | } |
100 | //----------------------------------------------------------- | |
101 | AliFlowEvent::~AliFlowEvent() | |
102 | { | |
103 | // Default distructor: deletes the ObjArrays. | |
104 | ||
105 | fTrackCollection->Delete() ; delete fTrackCollection ; | |
106 | fV0Collection->Delete() ; delete fV0Collection ; | |
107 | } | |
108 | //------------------------------------------------------------- | |
109 | ||
110 | //------------------------------------------------------------- | |
111 | Double_t AliFlowEvent::PhiWeightRaw(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const | |
112 | { | |
113 | // Weight for making the event plane isotropic in the lab. | |
114 | ||
115 | float phi = pFlowTrack->Phi() ; if(phi < 0.) { phi += 2*TMath::Pi() ; } | |
116 | Double_t eta = (Double_t)pFlowTrack->Eta() ; | |
327288af | 117 | int n = (int)((phi/(2*TMath::Pi()))*AliFlowConstants::kPhiBins); |
30a892e3 | 118 | |
119 | Double_t phiWgt = 1. ; | |
120 | if(OnePhiWgt()) | |
121 | { | |
122 | phiWgt = (Double_t)fPhiWgt[selN][harN][n]; //cout << "Selection " << selN << " ; Harmonic " << harN << " ; PhiBin " << n << " - Wgt = " << phiWgt << endl ; | |
123 | } | |
124 | else if(FirstLastPhiWgt()) | |
125 | { | |
126 | float zFirstPoint = pFlowTrack->ZFirstPoint(); // float zLastPoint = pFlowTrack->ZLastPoint(); | |
127 | ||
128 | if (zFirstPoint > 0. && eta > 0.) { phiWgt = (Double_t)fPhiWgtPlus[selN][harN][n] ; } | |
129 | else if(zFirstPoint < 0. && eta < 0.) { phiWgt = (Double_t)fPhiWgtMinus[selN][harN][n] ; } | |
130 | else { phiWgt = (Double_t)fPhiWgtCross[selN][harN][n] ; } | |
131 | } | |
132 | ||
30a892e3 | 133 | return phiWgt ; |
134 | } | |
135 | //------------------------------------------------------------- | |
136 | Double_t AliFlowEvent::Weight(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const | |
137 | { | |
138 | // Weight for enhancing the resolution (eta gives sign +/- for Odd Harmonics) | |
139 | ||
327288af | 140 | if(selN>AliFlowConstants::kSels) { selN = 0 ; } |
30a892e3 | 141 | bool oddHar = (harN+1) % 2 ; |
142 | Double_t phiWgt = 1. ; | |
143 | if(PtWgt()) | |
144 | { | |
145 | Double_t pt = (Double_t)pFlowTrack->Pt(); | |
327288af | 146 | if(pt < AliFlowConstants::fgPtWgtSaturation) { phiWgt *= pt ; } |
147 | else { phiWgt *= AliFlowConstants::fgPtWgtSaturation ; } // pt weighting going constant | |
30a892e3 | 148 | } |
149 | Double_t eta = (Double_t)pFlowTrack->Eta(); | |
150 | Double_t etaAbs = TMath::Abs(eta); | |
151 | if(EtaWgt() && oddHar) { phiWgt *= etaAbs ; } | |
152 | if(oddHar && eta < 0.) { phiWgt *= -1. ; } | |
153 | ||
154 | return phiWgt ; | |
155 | } | |
156 | //------------------------------------------------------------- | |
157 | Double_t AliFlowEvent::PhiWeight(Int_t selN, Int_t harN, AliFlowTrack* pFlowTrack) const | |
158 | { | |
159 | // Weight for making the event plane isotropic in the lab and enhancing the resolution | |
92016a03 | 160 | // (it simply rerurns PhiWeightRaw() * Weight()). If fgNoWgt = kTRUE, returns +/-1 , |
30a892e3 | 161 | // basing on Sign(eta), for odd harmonics . |
162 | ||
92016a03 | 163 | if(fgNoWgt) // no weights (but +/- according to eta) |
30a892e3 | 164 | { |
165 | bool oddHar = (harN+1) % 2 ; | |
166 | if(oddHar) { return TMath::Sign((Double_t)1.,(Double_t)pFlowTrack->Eta()) ; } | |
167 | else { return (Double_t)1. ; } | |
168 | } | |
169 | Double_t phiWgtRaw = PhiWeightRaw(selN, harN, pFlowTrack); | |
170 | Double_t weight = Weight(selN, harN, pFlowTrack); | |
327288af | 171 | if(AliFlowConstants::fgDebug) { cout << "[PhiWeight]: phiWgtRaw = " << phiWgtRaw << " , weight = " << weight << " , eta = " << pFlowTrack->Eta() << endl ; } |
30a892e3 | 172 | |
173 | return phiWgtRaw * weight; | |
174 | } | |
175 | //------------------------------------------------------------- | |
92016a03 | 176 | Int_t AliFlowEvent::Mult(AliFlowSelection* pFlowSelect) const |
30a892e3 | 177 | { |
178 | // Multiplicity of tracks in the specified Selection | |
179 | ||
180 | if(fDone) | |
181 | { | |
182 | int sub = pFlowSelect->Sub() ; | |
183 | if(sub<0) { return fMult[pFlowSelect->Sel()][pFlowSelect->Har()] ; } | |
184 | else { return fMultSub[sub][pFlowSelect->Sel()][pFlowSelect->Har()] ; } | |
185 | } | |
186 | // - | |
187 | Int_t mult = 0; | |
188 | Int_t itr ; | |
189 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
190 | { | |
191 | AliFlowTrack* pFlowTrack ; | |
192 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
193 | if(pFlowSelect->Select(pFlowTrack)) { mult++ ; } | |
194 | } | |
195 | return mult; | |
196 | } | |
197 | //------------------------------------------------------------- | |
92016a03 | 198 | Float_t AliFlowEvent::MeanPt(AliFlowSelection* pFlowSelect) const |
30a892e3 | 199 | { |
200 | // Mean pt of tracks in the specified Selection | |
201 | ||
202 | Double_t meanPt = 0. ; | |
203 | Float_t sumPt = 0. ; | |
204 | UInt_t mult = 0 ; | |
205 | Int_t itr ; | |
206 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
207 | { | |
208 | AliFlowTrack* pFlowTrack ; | |
209 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
210 | if (pFlowSelect->Select(pFlowTrack)) | |
211 | { | |
212 | sumPt += pFlowTrack->Pt(); | |
213 | mult++; | |
214 | } | |
215 | } | |
216 | if(mult) { meanPt = sumPt/(float)mult ; } | |
217 | ||
218 | return meanPt ; | |
219 | } | |
220 | //------------------------------------------------------------- | |
92016a03 | 221 | TVector2 AliFlowEvent::Q(AliFlowSelection* pFlowSelect) const |
30a892e3 | 222 | { |
223 | // Event plane vector for the specified Selection | |
224 | ||
225 | if(fDone) | |
226 | { | |
227 | int sub = pFlowSelect->Sub() ; | |
228 | if(sub<0) { return fQ[pFlowSelect->Sel()][pFlowSelect->Har()] ; } | |
229 | else { return fQSub[sub][pFlowSelect->Sel()][pFlowSelect->Har()] ; } | |
230 | } | |
231 | // - | |
232 | TVector2 mQ ; | |
233 | Double_t mQx=0. , mQy=0. ; | |
234 | int selN = pFlowSelect->Sel() ; | |
235 | int harN = pFlowSelect->Har() ; | |
236 | double order = (double)(harN + 1) ; | |
237 | ||
238 | Int_t itr ; | |
239 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
240 | { | |
241 | AliFlowTrack* pFlowTrack ; | |
242 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
243 | if(pFlowSelect->Select(pFlowTrack)) | |
244 | { | |
245 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
246 | float phi = pFlowTrack->Phi(); | |
247 | mQx += phiWgt * cos(phi * order) ; | |
248 | mQy += phiWgt * sin(phi * order) ; | |
327288af | 249 | if(AliFlowConstants::fgDebug) { cout << itr << " phi = " << phi << " , wgt = " << phiWgt << endl ; } |
30a892e3 | 250 | } |
251 | } | |
252 | mQ.Set(mQx, mQy); | |
253 | ||
254 | return mQ; | |
255 | } | |
256 | //------------------------------------------------------------- | |
92016a03 | 257 | Float_t AliFlowEvent::Psi(AliFlowSelection* pFlowSelect) const |
30a892e3 | 258 | { |
259 | // Event plane angle for the specified Selection | |
260 | ||
261 | int harN = pFlowSelect->Har() ; | |
262 | float order = (float)(harN + 1) ; | |
263 | Float_t psi = 0. ; | |
264 | ||
265 | TVector2 mQ = Q(pFlowSelect); | |
266 | if(mQ.Mod()) // if vector is not 0 | |
267 | { | |
268 | psi= mQ.Phi() / order ; | |
269 | if (psi < 0.) { psi += 2*TMath::Pi() / order ; } | |
270 | } | |
271 | return psi; | |
272 | } | |
273 | //------------------------------------------------------------- | |
92016a03 | 274 | TVector2 AliFlowEvent::NormQ(AliFlowSelection* pFlowSelect) const |
30a892e3 | 275 | { |
276 | // Normalized Q = Q/sqrt(sum of weights^2) for the specified Selection | |
277 | ||
278 | if(fDone) | |
279 | { | |
280 | TVector2 mQ = fQ[pFlowSelect->Sel()][pFlowSelect->Har()] ; | |
92016a03 | 281 | double sumOfWeightSqr = fSumOfWeightSqr[pFlowSelect->Sel()][pFlowSelect->Har()] ; |
282 | if(sumOfWeightSqr) { mQ /= TMath::Sqrt(sumOfWeightSqr) ; } | |
30a892e3 | 283 | else { mQ.Set(0.,0.) ; } |
284 | return mQ ; | |
285 | } | |
286 | // - | |
287 | TVector2 mQ ; | |
288 | Double_t mQx=0. , mQy=0. ; | |
92016a03 | 289 | double sumOfWeightSqr = 0 ; |
30a892e3 | 290 | int selN = pFlowSelect->Sel() ; |
291 | int harN = pFlowSelect->Har() ; | |
292 | double order = (double)(harN + 1) ; | |
293 | Int_t itr ; | |
294 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
295 | { | |
296 | AliFlowTrack* pFlowTrack ; | |
297 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
298 | if (pFlowSelect->Select(pFlowTrack)) | |
299 | { | |
300 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
92016a03 | 301 | sumOfWeightSqr += phiWgt*phiWgt; |
30a892e3 | 302 | |
303 | float phi = pFlowTrack->Phi(); | |
304 | mQx += phiWgt * cos(phi * order); | |
305 | mQy += phiWgt * sin(phi * order); | |
306 | } | |
307 | } | |
92016a03 | 308 | if(sumOfWeightSqr) { mQ.Set(mQx/TMath::Sqrt(sumOfWeightSqr), mQy/TMath::Sqrt(sumOfWeightSqr)); } |
30a892e3 | 309 | else { mQ.Set(0.,0.); } |
310 | ||
311 | return mQ; | |
312 | } | |
313 | //------------------------------------------------------------- | |
92016a03 | 314 | Float_t AliFlowEvent::OldQ(AliFlowSelection* pFlowSelect) const |
30a892e3 | 315 | { |
316 | // Magnitude of normalized Q vector (without pt or eta weighting) for the specified Selection | |
317 | ||
318 | TVector2 mQ ; | |
319 | Double_t mQx = 0. , mQy = 0. ; | |
320 | int selN = pFlowSelect->Sel() ; | |
321 | int harN = pFlowSelect->Har() ; | |
322 | double order = (double)(harN + 1) ; | |
92016a03 | 323 | double sumOfWeightSqr = 0 ; |
30a892e3 | 324 | |
325 | Int_t itr ; | |
326 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
327 | { | |
328 | AliFlowTrack* pFlowTrack ; | |
329 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
330 | if(pFlowSelect->Select(pFlowTrack)) | |
331 | { | |
332 | double phiWgt = PhiWeightRaw(selN, harN, pFlowTrack); // Raw | |
92016a03 | 333 | sumOfWeightSqr += phiWgt*phiWgt; |
30a892e3 | 334 | float phi = pFlowTrack->Phi(); |
335 | mQx += phiWgt * cos(phi * order); | |
336 | mQy += phiWgt * sin(phi * order); | |
337 | } | |
338 | } | |
92016a03 | 339 | if(sumOfWeightSqr) { mQ.Set(mQx/TMath::Sqrt(sumOfWeightSqr), mQy/TMath::Sqrt(sumOfWeightSqr)); } |
30a892e3 | 340 | else { mQ.Set(0.,0.); } |
341 | ||
342 | return mQ.Mod(); | |
343 | } | |
344 | //----------------------------------------------------------------------- | |
92016a03 | 345 | Double_t AliFlowEvent::NewG(AliFlowSelection* pFlowSelect, Double_t Zx, Double_t Zy) const |
30a892e3 | 346 | { |
347 | // Generating function for the new cumulant method. Eq. 3 in the Practical Guide | |
348 | ||
349 | int selN = pFlowSelect->Sel(); | |
350 | int harN = pFlowSelect->Har(); | |
351 | double order = (double)(harN + 1); | |
352 | ||
353 | double mult = (double)Mult(pFlowSelect); | |
354 | Double_t theG = 1.; | |
355 | ||
356 | Int_t itr ; | |
357 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
358 | { | |
359 | AliFlowTrack* pFlowTrack ; | |
360 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
361 | if (pFlowSelect->Select(pFlowTrack)) | |
362 | { | |
363 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
364 | float phi = pFlowTrack->Phi(); | |
365 | theG *= (1. + (phiWgt/mult) * (2.* Zx * cos(phi * order) + 2.* Zy * sin(phi * order) ) ); | |
366 | } | |
367 | } | |
368 | return theG; | |
369 | } | |
370 | //----------------------------------------------------------------------- | |
92016a03 | 371 | Double_t AliFlowEvent::OldG(AliFlowSelection* pFlowSelect, Double_t Zx, Double_t Zy) const |
30a892e3 | 372 | { |
373 | // Generating function for the old cumulant method (if expanded in Taylor | |
92016a03 | 374 | // series, one recovers NewG() in new new cumulant method) |
30a892e3 | 375 | |
92016a03 | 376 | TVector2 normQ = NormQ(pFlowSelect) ; |
30a892e3 | 377 | |
378 | return exp(2*Zx*normQ.X() + 2*Zy*normQ.Y()); | |
379 | } | |
380 | //----------------------------------------------------------------------- | |
92016a03 | 381 | Double_t AliFlowEvent::SumWeightSquare(AliFlowSelection* pFlowSelect) const |
30a892e3 | 382 | { |
383 | // Return sum of weights^2 for the specified Selection (used for normalization) | |
384 | ||
92016a03 | 385 | if(fDone) { return fSumOfWeightSqr[pFlowSelect->Sel()][pFlowSelect->Har()] ; } |
386 | ||
30a892e3 | 387 | int selN = pFlowSelect->Sel(); |
388 | int harN = pFlowSelect->Har(); | |
92016a03 | 389 | Double_t sumOfWeightSqr = 0; |
30a892e3 | 390 | Int_t itr ; |
391 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
392 | { | |
393 | AliFlowTrack* pFlowTrack ; | |
394 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
395 | if (pFlowSelect->Select(pFlowTrack)) | |
396 | { | |
397 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
92016a03 | 398 | sumOfWeightSqr += phiWgt*phiWgt; |
30a892e3 | 399 | } |
400 | } | |
92016a03 | 401 | if(sumOfWeightSqr < 0.) { return Mult(pFlowSelect) ; } |
30a892e3 | 402 | |
92016a03 | 403 | return sumOfWeightSqr; |
30a892e3 | 404 | } |
405 | //------------------------------------------------------------- | |
92016a03 | 406 | Double_t AliFlowEvent::WgtMultQ4(AliFlowSelection* pFlowSelect) const |
30a892e3 | 407 | { |
408 | // Used only for the old cumulant method, for getting q4 when weight is on. | |
409 | // Replace multiplicity in Eq.(74b) by this quantity when weight is on. | |
410 | // This is derived based on (A4) in the old cumulant paper. | |
411 | ||
412 | int selN = pFlowSelect->Sel(); | |
413 | int harN = pFlowSelect->Har(); | |
414 | double theMult = 0.; | |
415 | double theMeanWj4 = 0.; | |
416 | double theMeanWj2 = 0.; | |
417 | double theSumOfWgtSqr = 0; | |
418 | double phiWgtSq; | |
419 | ||
420 | Int_t itr ; | |
421 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
422 | { | |
423 | AliFlowTrack* pFlowTrack ; | |
424 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
425 | if (pFlowSelect->Select(pFlowTrack)) | |
426 | { | |
427 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
428 | phiWgtSq = phiWgt*phiWgt; | |
429 | theSumOfWgtSqr += phiWgtSq; | |
430 | theMeanWj4 += phiWgtSq*phiWgtSq; | |
431 | theMult += 1.; | |
432 | } | |
433 | } | |
434 | if (theMult <= 0.) return theMult; | |
435 | ||
436 | theMeanWj4 /= theMult; | |
437 | theMeanWj2 = theSumOfWgtSqr / theMult; | |
438 | ||
439 | return (theSumOfWgtSqr*theSumOfWgtSqr)/(theMult*(-theMeanWj4+2*theMeanWj2*theMeanWj2)); | |
440 | } | |
441 | //------------------------------------------------------------- | |
92016a03 | 442 | Double_t AliFlowEvent::WgtMultQ6(AliFlowSelection* pFlowSelect) const |
30a892e3 | 443 | { |
444 | // Used only for the old cumulant method. For getting q6 when weight is on. | |
445 | // Replace multiplicity in Eq.(74c) by this quantity when weight is on. | |
446 | // This is derived based on (A4) in the old cumulant paper. | |
447 | ||
448 | int selN = pFlowSelect->Sel(); | |
449 | int harN = pFlowSelect->Har(); | |
450 | double theMult = 0.; | |
451 | double theMeanWj6 = 0.; | |
452 | double theMeanWj4 = 0.; | |
453 | double theMeanWj2 = 0.; | |
454 | double theSumOfWgtSqr = 0; | |
455 | double phiWgtSq; | |
456 | ||
457 | Int_t itr ; | |
458 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
459 | { | |
460 | AliFlowTrack* pFlowTrack ; | |
461 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
462 | if (pFlowSelect->Select(pFlowTrack)) | |
463 | { | |
464 | double phiWgt = PhiWeight(selN, harN, pFlowTrack); | |
465 | phiWgtSq = phiWgt*phiWgt; | |
466 | theSumOfWgtSqr += phiWgtSq; | |
467 | theMeanWj4 += phiWgtSq*phiWgtSq; | |
468 | theMeanWj6 += phiWgtSq*phiWgtSq*phiWgtSq; | |
469 | theMult += 1.; | |
470 | } | |
471 | } | |
472 | if (theMult <= 0.) return theMult*theMult; | |
473 | ||
474 | theMeanWj6 /= theMult; | |
475 | theMeanWj4 /= theMult; | |
476 | theMeanWj2 = theSumOfWgtSqr / theMult; | |
477 | ||
478 | return 4.*(theSumOfWgtSqr*theSumOfWgtSqr*theSumOfWgtSqr)/(theMult*(theMeanWj6-9.*theMeanWj2*theMeanWj4+12.*theMeanWj2*theMeanWj2*theMeanWj2)); | |
479 | } | |
480 | //------------------------------------------------------------- | |
481 | void AliFlowEvent::SetSelections(AliFlowSelection* pFlowSelect) | |
482 | { | |
483 | // Sets the selection of tracks used in the Reaction Plane calculation | |
484 | // for the specific Harmonic and Selection - this does not cut trow away | |
485 | // tracks from the event, neither exclude them from flow study. See also | |
486 | // the AliFlowSelection class. | |
487 | // Strategy of Selection: | |
488 | // For the specific Harmonic and Selection, IF cuts | |
489 | // are defined (such that low<high) and IF the track satisfies them, THEN | |
490 | // the respective track's flag (bool AliFlowTrack::mSelection[har][sel]) | |
491 | // is set kTRUE so that the track, from now on, will be included in the | |
492 | // R.P. determination for that selection. | |
493 | // If NO cuts are defined -> ALL Flags are setted kTRUE (all particle | |
494 | // used for all the Reaction Planes -> no difference in Psi[har][sel]). | |
495 | // ------------------------------------------------------------------- | |
496 | // The first selection (all harmonics) is set kTRUE : no conditions. | |
497 | ||
498 | Int_t itr ; | |
499 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
500 | { | |
501 | AliFlowTrack* pFlowTrack ; | |
502 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
503 | pFlowTrack->ResetSelection() ; // this re-sets all the mSelection flags to 0 | |
504 | ||
505 | // * this sets all the selection n.[0] flag kTRUE (all harmonics) * | |
327288af | 506 | for(int harN=0;harN<AliFlowConstants::kHars;harN++) { pFlowTrack->SetSelect(harN,0) ; } |
30a892e3 | 507 | |
508 | // Track need to be Constrainable | |
509 | if(pFlowSelect->ConstrainCut() && !pFlowTrack->IsConstrainable()) continue ; | |
510 | ||
511 | // PID - gets rid of the track with AliFlowTrack::Pid() != AliFlowSelection::Pid() (if there) | |
512 | if(pFlowSelect->Pid()[0] != '\0') | |
513 | { | |
514 | if(strstr(pFlowSelect->Pid(), "h")!=0) | |
515 | { | |
516 | int charge = pFlowTrack->Charge() ; | |
517 | if(strcmp("h+",pFlowSelect->Pid())==0 && charge != 1) continue; | |
518 | if(strcmp("h-",pFlowSelect->Pid())==0 && charge != -1) continue; | |
519 | } | |
520 | else | |
521 | { | |
522 | Char_t pid[10]; | |
523 | strcpy(pid, pFlowTrack->Pid()); | |
524 | if(strstr(pid, pFlowSelect->Pid())==0) continue; | |
525 | } | |
526 | } | |
527 | double eta = (double)(pFlowTrack->Eta()); | |
92016a03 | 528 | float pt = pFlowTrack->Pt(); |
30a892e3 | 529 | float gDca = pFlowTrack->Dca() ; |
530 | ||
531 | // Global DCA - gets rid of the track with DCA outside the range | |
532 | if((pFlowSelect->DcaGlobalCutHi()>pFlowSelect->DcaGlobalCutLo()) && (gDca<pFlowSelect->DcaGlobalCutLo() || gDca>pFlowSelect->DcaGlobalCutHi())) continue ; | |
533 | ||
534 | // Pt & Eta - this is done differently for different Harmonic & Selection | |
327288af | 535 | for(int selN = 1; selN < AliFlowConstants::kSels; selN++) // not even consider the 0th selection (no cut applied there) |
30a892e3 | 536 | { |
537 | // min. TPC hits required | |
538 | if(pFlowSelect->NhitsCut(selN) && (pFlowTrack->FitPtsTPC()<pFlowSelect->NhitsCut(selN))) continue ; | |
539 | ||
327288af | 540 | for(int harN = 0; harN < AliFlowConstants::kHars; harN++) |
30a892e3 | 541 | { |
542 | // Eta - gets rid of the track with Eta outside the range | |
543 | if((pFlowSelect->EtaCutHi(harN%2,selN)>pFlowSelect->EtaCutLo(harN%2,selN)) && (TMath::Abs(eta)<pFlowSelect->EtaCutLo(harN%2,selN) || TMath::Abs(eta)>pFlowSelect->EtaCutHi(harN%2,selN))) continue ; | |
544 | // Pt - gets rid of the track with Pt outside the range | |
92016a03 | 545 | if((pFlowSelect->PtCutHi(harN%2,selN)>pFlowSelect->PtCutLo(harN%2,selN)) && (pt<pFlowSelect->PtCutLo(harN%2,selN) || pt>pFlowSelect->PtCutHi(harN%2,selN))) continue ; |
30a892e3 | 546 | |
547 | pFlowTrack->SetSelect(harN, selN) ; // if cuts defined (low<high) && track is in the range -> Set [har][sel] Flag ON | |
548 | ||
327288af | 549 | if(AliFlowConstants::fgDebug) |
30a892e3 | 550 | { |
92016a03 | 551 | if(harN==1) |
552 | { | |
553 | cout << " n. " << itr << " , pFlowTrack->PrintSelection() = " ; pFlowTrack->PrintSelection() ; | |
554 | if(pFlowSelect->Pid()[0] != '\0') { cout << " track: pid " << pFlowTrack->Pid() << " = "<< pFlowSelect->Pid() << endl ; } | |
555 | cout << " track: dca " << pFlowSelect->DcaGlobalCutLo() << " < " << gDca << " < " << pFlowSelect->DcaGlobalCutHi() << endl ; | |
556 | cout << " track: eta " << pFlowSelect->EtaCutLo(harN,selN) << " < |" << eta << "| < " << pFlowSelect->EtaCutHi(harN,selN) << endl ; | |
557 | cout << " track: pT " << pFlowSelect->PtCutLo(harN,selN) << " < " << pt << " < " << pFlowSelect->PtCutHi(harN,selN) << endl ; | |
558 | cout << " pFlowTrack->PrintSelection() = " ; pFlowTrack->PrintSelection() ; | |
559 | } | |
560 | // cout << " selN " << selN << " , harN " << harN%2 << " - si" << endl ; | |
30a892e3 | 561 | } |
562 | } | |
563 | } | |
564 | } | |
565 | } | |
566 | //------------------------------------------------------------- | |
567 | void AliFlowEvent::SetPids() | |
568 | { | |
4e566f2f | 569 | // Re-sets the tracks P.id. (using the current AliFlowConstants::fgBayesian[] array). |
570 | // To use the Raw P.Id (just the detector response function), set fgBayesian[] = {1,1,1,1,1,1}. | |
30a892e3 | 571 | |
92016a03 | 572 | const Int_t kCode[] = {11,13,211,321,2212,10010020} ; |
30a892e3 | 573 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) |
574 | { | |
575 | AliFlowTrack* pFlowTrack ; | |
576 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
4e566f2f | 577 | |
578 | Float_t bayPid[AliFlowConstants::kPid] ; | |
579 | if(fgCustomRespFunc) { pFlowTrack->PidProbsC(bayPid) ; } | |
580 | else { pFlowTrack->PidProbs(bayPid) ; } | |
581 | ||
582 | Int_t maxN = 2 ; // if No id. -> then is a Pi | |
583 | Float_t pidMax = bayPid[2] ; // (if all equal, Pi probability was the first) | |
327288af | 584 | for(Int_t nP=0;nP<AliFlowConstants::kPid;nP++) |
30a892e3 | 585 | { |
92016a03 | 586 | if(bayPid[nP]>pidMax) { maxN = nP ; pidMax = bayPid[nP] ; } |
30a892e3 | 587 | } |
92016a03 | 588 | Int_t pdgCode = TMath::Sign(kCode[maxN],pFlowTrack->Charge()) ; |
4e566f2f | 589 | pFlowTrack->SetMostLikelihoodPID(pdgCode) ; |
30a892e3 | 590 | } |
591 | } | |
592 | //------------------------------------------------------------- | |
92016a03 | 593 | void AliFlowEvent::MakeSubEvents() const |
30a892e3 | 594 | { |
595 | // Make random or eta sub-events | |
596 | ||
92016a03 | 597 | if(fgEtaSubs) { MakeEtaSubEvents() ; } |
30a892e3 | 598 | else { MakeRndSubEvents() ; } |
599 | } | |
600 | //------------------------------------------------------------- | |
92016a03 | 601 | void AliFlowEvent::MakeRndSubEvents() const |
30a892e3 | 602 | { |
603 | // Make random subevents | |
604 | ||
327288af | 605 | int eventMult[AliFlowConstants::kHars][AliFlowConstants::kSels] = {{0}}; |
30a892e3 | 606 | int harN, selN, subN = 0; |
607 | ||
608 | // loop to count the total number of tracks for each selection | |
609 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) | |
610 | { | |
611 | AliFlowTrack* pFlowTrack ; | |
612 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
327288af | 613 | for (selN = 0; selN < AliFlowConstants::kSels; selN++) |
30a892e3 | 614 | { |
327288af | 615 | for (harN = 0; harN < AliFlowConstants::kHars; harN++) |
30a892e3 | 616 | { |
617 | if(pFlowTrack->Select(harN, selN)) { eventMult[harN][selN]++ ; } | |
618 | } | |
619 | } | |
620 | } | |
621 | // loop to set the SubEvent member | |
327288af | 622 | for (selN = 0; selN < AliFlowConstants::kSels; selN++) |
30a892e3 | 623 | { |
327288af | 624 | for (harN = 0; harN < AliFlowConstants::kHars; harN++) |
30a892e3 | 625 | { |
327288af | 626 | int subEventMult = eventMult[harN][selN] / AliFlowConstants::kSubs; |
30a892e3 | 627 | if (subEventMult) |
628 | { | |
629 | subN = 0; | |
630 | int countN = 0; | |
631 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) | |
632 | { | |
633 | AliFlowTrack* pFlowTrack ; | |
634 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
635 | if(pFlowTrack->Select(harN, selN)) | |
636 | { | |
637 | pFlowTrack->SetSubevent(harN, selN, subN); | |
638 | countN++; | |
639 | if (countN % subEventMult == 0.) { subN++ ; } | |
640 | } | |
641 | } | |
642 | } | |
643 | } | |
644 | } | |
645 | return ; | |
646 | } | |
647 | //------------------------------------------------------------- | |
92016a03 | 648 | void AliFlowEvent::MakeEtaSubEvents() const |
30a892e3 | 649 | { |
650 | // Make subevents for positive and negative eta | |
92016a03 | 651 | // (when done, fgEtaSubs flag setted to kTRUE). |
30a892e3 | 652 | |
653 | int harN, selN = 0; | |
654 | // loop to set the SubEvent member | |
327288af | 655 | for (selN = 0; selN < AliFlowConstants::kSels; selN++) |
30a892e3 | 656 | { |
327288af | 657 | for (harN = 0; harN < AliFlowConstants::kHars; harN++) |
30a892e3 | 658 | { |
659 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) | |
660 | { | |
661 | AliFlowTrack* pFlowTrack ; | |
662 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
663 | if(pFlowTrack->Select(harN, selN)) | |
664 | { | |
665 | float eta = pFlowTrack->Eta(); | |
666 | if (eta > 0.) { pFlowTrack->SetSubevent(harN, selN, 0) ; } | |
667 | else { pFlowTrack->SetSubevent(harN, selN, 1) ; } | |
668 | } | |
669 | } | |
670 | } | |
671 | } | |
672 | } | |
673 | //------------------------------------------------------------- | |
674 | void AliFlowEvent::RandomShuffle() | |
675 | { | |
676 | // Randomly re-shuffles the tracks in the array; if a track is not | |
677 | // primary, the reference carried by the reconstructed mother (in | |
678 | // the v0 array) is changed accordingly. | |
679 | ||
92016a03 | 680 | return ; // ...at the moment is disabled ... // |
681 | ||
682 | // Int_t tot = 0 ; | |
683 | // UInt_t imax = fTrackCollection->GetEntries() ; | |
684 | // TRandom* rnd = new TRandom(0) ; // SetSeed(0) ; | |
685 | // TClonesArray* newTrackCollection = new TClonesArray("AliFlowTrack",imax) ; | |
686 | // | |
687 | // // re-arranges the ObjArray (TrackCollection()) | |
688 | // for(UInt_t itr=0;itr<imax;itr++) | |
689 | // { | |
690 | // AliFlowTrack* pFlowTrack ; | |
691 | // pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
692 | // | |
693 | // UInt_t rndNumber = rnd->Integer(imax) ; | |
694 | // Bool_t put = kFALSE ; | |
695 | // while(!put) | |
696 | // { | |
697 | // if(!newTrackCollection->AddrAt(rndNumber)) | |
698 | // { | |
699 | // ... new(newTrackCollection[rndNumber]) AliFlowTrack(*pFlowTrack) ; | |
700 | // put = kTRUE ; tot++ ; | |
701 | // if(AliFlowConstants::fgDebug) { cout << " " << itr << " --> " << rndNumber << endl ; } | |
702 | // } | |
703 | // else | |
704 | // { | |
705 | // rndNumber++ ; if(rndNumber>=imax) { rndNumber -= imax ; } | |
706 | // } | |
707 | // } | |
708 | // } | |
709 | // if(AliFlowConstants::fgDebug) { cout << "* RandomShuffle() : " << tot << "/" << imax << " flow tracks have been shuffled " << endl ; } | |
710 | // fTrackCollection = newTrackCollection ; | |
30a892e3 | 711 | } |
712 | //----------------------------------------------------------------------- | |
713 | UInt_t AliFlowEvent::Centrality() | |
714 | { | |
715 | // Returns the Centrality Class as stored | |
716 | ||
717 | if(fCentrality < 0) { SetCentrality() ; } | |
718 | return fCentrality ; | |
719 | } | |
720 | //----------------------------------------------------------------------- | |
30a892e3 | 721 | void AliFlowEvent::SetCentrality() |
722 | { | |
723 | // Sets the Centrality Classes basing on Multiplicity at mid rapidity, | |
724 | // ... (ZDC information can be added) . | |
725 | ||
726 | Float_t* cent ; | |
727 | Int_t tracks = MultEta() ; | |
728 | ||
729 | if(RunID() == -1) | |
730 | { | |
327288af | 731 | cent = AliFlowConstants::fgCentNorm ; |
30a892e3 | 732 | //if centrality classes are not defined, does it now (with CentNorm & MaxMult) |
327288af | 733 | if(cent[AliFlowConstants::kCents-1] <= 1) |
30a892e3 | 734 | { |
327288af | 735 | for(Int_t ic=0;ic<AliFlowConstants::kCents;ic++) |
30a892e3 | 736 | { |
327288af | 737 | cent[ic] *= AliFlowConstants::fgMaxMult ; |
738 | if(AliFlowConstants::fgDebug) { cout << "Centrality[" << ic << "] = " << cent[ic] << " . " << endl ; } | |
30a892e3 | 739 | } |
740 | } | |
741 | } | |
742 | else if((RunID() != -1) && (CenterOfMassEnergy() == 5500.)) | |
743 | { | |
327288af | 744 | cent = (Float_t*)AliFlowConstants::fgCent0 ; |
30a892e3 | 745 | } |
92016a03 | 746 | else // other definition of centrality are possible ... |
30a892e3 | 747 | { |
327288af | 748 | cent = (Float_t*)AliFlowConstants::fgCent0 ; |
30a892e3 | 749 | } |
750 | if (tracks < cent[0]) { fCentrality = 0; } | |
751 | else if (tracks < cent[1]) { fCentrality = 1; } | |
752 | else if (tracks < cent[2]) { fCentrality = 2; } | |
753 | else if (tracks < cent[3]) { fCentrality = 3; } | |
754 | else if (tracks < cent[4]) { fCentrality = 4; } | |
755 | else if (tracks < cent[5]) { fCentrality = 5; } | |
756 | else if (tracks < cent[6]) { fCentrality = 6; } | |
757 | else if (tracks < cent[7]) { fCentrality = 7; } | |
758 | else if (tracks < cent[8]) { fCentrality = 8; } | |
759 | else { fCentrality = 9; } | |
760 | ||
327288af | 761 | if(AliFlowConstants::fgDebug) { cout << " * Centrality Class : " << fCentrality << " . " << endl ; } |
30a892e3 | 762 | } |
763 | //----------------------------------------------------------------------- | |
92016a03 | 764 | TVector AliFlowEvent::Bayesian() const |
30a892e3 | 765 | { |
92016a03 | 766 | // Returns bayesian array of particle abundances (from AliFlowConstants::) |
767 | ||
327288af | 768 | TVector bayes(AliFlowConstants::kPid) ; |
769 | for(Int_t i=0;i<AliFlowConstants::kPid;i++) { bayes[i] = AliFlowConstants::fgBayesian[i] ; } | |
30a892e3 | 770 | return bayes ; |
771 | } | |
772 | //----------------------------------------------------------------------- | |
773 | void AliFlowEvent::PrintFlagList() const | |
774 | { | |
775 | // Prints the list of selection cuts ( called in AliFlowInterface::Finish() ) | |
776 | ||
777 | cout << "#######################################################" << endl; | |
778 | cout << "# Weighting and Striping:" << endl; | |
779 | if(PtWgt()) | |
780 | { | |
781 | cout << "# PtWgt = kTRUE " << endl ; // (also for output of PhiWgt file?) | |
327288af | 782 | cout << "# PtWgt Saturation = " << AliFlowConstants::fgPtWgtSaturation << endl; |
30a892e3 | 783 | } |
784 | else | |
785 | { | |
786 | cout << "# PtWgt = kFALSE" << endl; | |
787 | } | |
788 | if(EtaWgt()) | |
789 | { | |
790 | cout << "# EtaWgt = kTRUE " << endl ; // (also for output of PhiWgt file for odd harmonics?) | |
791 | } | |
792 | else | |
793 | { | |
794 | cout << "# EtaWgt = kFALSE" << endl; | |
795 | } | |
796 | cout << "#######################################################" << endl; | |
797 | } | |
798 | //----------------------------------------------------------------------- | |
92016a03 | 799 | Int_t AliFlowEvent::MultEta() const |
30a892e3 | 800 | { |
327288af | 801 | // Returns the multiplicity in the interval |eta|<(AliFlowConstants::fgEetaMid), used |
30a892e3 | 802 | // for centrality measurement (see centrality classes in fCentrality) . |
803 | ||
804 | Int_t goodtracks = 0 ; | |
805 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) | |
806 | { | |
807 | AliFlowTrack* pFlowTrack ; | |
808 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
327288af | 809 | if((pFlowTrack->Charge()) && (TMath::Abs(pFlowTrack->Eta())<AliFlowConstants::fgEtaMid)) { goodtracks++ ; } |
30a892e3 | 810 | } |
811 | return goodtracks ; | |
812 | } | |
813 | //----------------------------------------------------------------------- | |
814 | Int_t AliFlowEvent::UncorrNegMult(Float_t eta) const | |
815 | { | |
816 | // Negative multiplicity in the interval (-eta..eta) | |
327288af | 817 | // (default is AliFlowConstants::fgEetaGood = 0.9) |
30a892e3 | 818 | |
819 | Int_t negMult = 0 ; | |
820 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) | |
821 | { | |
822 | AliFlowTrack* pFlowTrack ; | |
823 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
824 | if((pFlowTrack->Charge()<0) && (TMath::Abs(pFlowTrack->Eta())<TMath::Abs(eta))) { negMult++ ; } | |
825 | delete pFlowTrack ; | |
826 | } | |
827 | return negMult; | |
828 | } | |
829 | //----------------------------------------------------------------------- | |
830 | Int_t AliFlowEvent::UncorrPosMult(Float_t eta) const | |
831 | { | |
832 | // Positive multiplicity in the interval (-eta..eta) | |
327288af | 833 | // (default is AliFlowConstants::fgEetaGood = 0.9) |
30a892e3 | 834 | |
51a9b7d8 | 835 | Int_t posMult = 0 ; |
30a892e3 | 836 | for(Int_t itr=0;itr<TrackCollection()->GetEntries();itr++) |
837 | { | |
838 | AliFlowTrack* pFlowTrack ; | |
839 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
840 | if((pFlowTrack->Charge()>0) && (TMath::Abs(pFlowTrack->Eta())<TMath::Abs(eta))) { posMult++ ; } | |
841 | delete pFlowTrack ; | |
842 | } | |
843 | return posMult; | |
844 | } | |
845 | //----------------------------------------------------------------------- | |
30a892e3 | 846 | TVector3 AliFlowEvent::VertexPos() const |
847 | { | |
92016a03 | 848 | // Returns primary vertex position as a TVector3 |
849 | ||
30a892e3 | 850 | Float_t vertex[3] ; |
851 | VertexPos(vertex) ; | |
852 | return TVector3(vertex) ; | |
853 | } | |
854 | //----------------------------------------------------------------------- | |
30a892e3 | 855 | void AliFlowEvent::MakeAll() |
856 | { | |
92016a03 | 857 | // calculates all quantities in 1 shoot |
30a892e3 | 858 | |
327288af | 859 | Double_t mQx[AliFlowConstants::kSels][AliFlowConstants::kHars] ; |
860 | Double_t mQy[AliFlowConstants::kSels][AliFlowConstants::kHars] ; | |
861 | Double_t mQxSub[AliFlowConstants::kSubs][AliFlowConstants::kSels][AliFlowConstants::kHars] ; | |
862 | Double_t mQySub[AliFlowConstants::kSubs][AliFlowConstants::kSels][AliFlowConstants::kHars] ; | |
30a892e3 | 863 | // - |
864 | int selN, harN, subN ; | |
327288af | 865 | for(selN=0;selN<AliFlowConstants::kSels;selN++) |
30a892e3 | 866 | { |
327288af | 867 | for(harN=0;harN<AliFlowConstants::kHars;harN++) |
30a892e3 | 868 | { |
869 | mQx[selN][harN] = 0. ; | |
870 | mQy[selN][harN] = 0. ; | |
871 | fMult[selN][harN] = 0 ; | |
872 | fSumOfWeightSqr[selN][harN] = 0. ; | |
327288af | 873 | for(subN=0;subN<AliFlowConstants::kSubs;subN++) |
30a892e3 | 874 | { |
875 | mQxSub[subN][selN][harN] = 0. ; | |
876 | mQySub[subN][selN][harN] = 0. ; | |
877 | fMultSub[subN][selN][harN] = 0 ; | |
878 | } | |
879 | } | |
880 | } | |
881 | ||
882 | double order = 0. ; | |
883 | double phiWgt = 0. ; | |
884 | float phi = 0. ; | |
885 | // - | |
886 | int itr ; | |
887 | for(itr=0;itr<TrackCollection()->GetEntries();itr++) | |
888 | { | |
889 | AliFlowTrack* pFlowTrack ; | |
890 | pFlowTrack = (AliFlowTrack*)TrackCollection()->At(itr) ; | |
891 | phi = pFlowTrack->Phi(); | |
327288af | 892 | for(selN=0;selN<AliFlowConstants::kSels;selN++) |
30a892e3 | 893 | { |
327288af | 894 | for(harN=0;harN<AliFlowConstants::kHars;harN++) |
30a892e3 | 895 | { |
896 | order = (double)(harN+1) ; | |
897 | if(pFlowTrack->Select(harN,selN)) | |
898 | { | |
899 | phiWgt = PhiWeight(selN,harN,pFlowTrack) ; | |
900 | fSumOfWeightSqr[selN][harN] += phiWgt*phiWgt ; | |
901 | mQx[selN][harN] += phiWgt * cos(phi * order) ; | |
902 | mQy[selN][harN] += phiWgt * sin(phi * order) ; | |
903 | fMult[selN][harN]++ ; | |
327288af | 904 | for(subN=0;subN<AliFlowConstants::kSubs;subN++) |
30a892e3 | 905 | { |
906 | if(pFlowTrack->Select(harN,selN,subN)) | |
907 | { | |
908 | mQxSub[subN][selN][harN] += phiWgt * cos(phi * order) ; | |
909 | mQySub[subN][selN][harN] += phiWgt * sin(phi * order) ; | |
910 | fMultSub[subN][selN][harN]++ ; | |
911 | } | |
912 | } // sub | |
913 | } // if | |
914 | } // har | |
915 | } // sel | |
916 | } //itr | |
917 | ||
327288af | 918 | for(selN=0;selN<AliFlowConstants::kSels;selN++) |
30a892e3 | 919 | { |
327288af | 920 | for(harN=0;harN<AliFlowConstants::kHars;harN++) |
30a892e3 | 921 | { |
922 | fQ[selN][harN].Set(mQx[selN][harN],mQy[selN][harN]) ; | |
327288af | 923 | for(subN=0;subN<AliFlowConstants::kSubs;subN++) { fQSub[subN][selN][harN].Set(mQxSub[subN][selN][harN],mQySub[subN][selN][harN]) ; } |
30a892e3 | 924 | } |
925 | } | |
926 | ||
927 | fDone = kTRUE ; | |
928 | } | |
30a892e3 | 929 | //----------------------------------------------------------------------- |