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