Coding Convention Violation correction
[u/mrichter/AliRoot.git] / EVGEN / AliGenAfterBurnerFlow.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 // 
20 // AliGenAfterBurnerFlow is a After Burner event generator applying flow.
21 // The generator changes Phi coordinate of the particle momentum.
22 // Flow (directed and elliptical) can be defined on particle type level
23 //
24 // For examples, parameters and testing macros refer to:
25 // http:/home.cern.ch/radomski
26 //
27 // Author:
28 // Sylwester Radomski,
29 // GSI, April 2002
30 // 
31 // S.Radomski@gsi.de
32 //
33 //////////////////////////////////////////////////////////////////////////////
34
35 #include <Riostream.h>
36 #include "TParticle.h"
37 #include "TLorentzVector.h"
38 #include "AliStack.h"
39 #include "AliGenAfterBurnerFlow.h"
40 #include "AliGenCocktailAfterBurner.h"
41
42 ClassImp(AliGenAfterBurnerFlow)
43
44 ////////////////////////////////////////////////////////////////////////////////////////////////////
45
46 AliGenAfterBurnerFlow::AliGenAfterBurnerFlow() {
47   //
48   // Deafult Construction
49   //
50
51   fReactionPlane = 0;
52   fCounter = 0;
53 }
54
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
56
57 AliGenAfterBurnerFlow::AliGenAfterBurnerFlow(Float_t reactionPlane) {
58   //
59   // Standard Construction
60   // 
61   // reactionPlane - Reaction Plane Angle in Deg [0-360]
62   //
63
64   if (reactionPlane < 0 || reactionPlane > 360)
65     Error("AliGenAfterBurnerFlow", 
66           "Reaction Plane Angle - %d - ot of bounds [0-360]", reactionPlane);
67
68   fReactionPlane = reactionPlane;
69   fCounter = 0;
70 }
71
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
73
74 AliGenAfterBurnerFlow::~AliGenAfterBurnerFlow() {
75   // Standard Destructor
76
77 }
78
79 ////////////////////////////////////////////////////////////////////////////////////////////////////
80
81 void AliGenAfterBurnerFlow::SetDirectedSimple(Int_t pdg, Float_t v1) {
82   //
83   // Set Directed Flow 
84   // The same directed flow is applied to all specified particles 
85   // independently on transverse momentum or rapidity
86   //
87   // PDG - particle type to apply directed flow
88   //       if (PDG == 0) use as default  
89   //
90
91   SetFlowParameters(pdg, 1, 0, v1, 0, 0, 0);
92 }
93
94 ////////////////////////////////////////////////////////////////////////////////////////////////////
95
96 void AliGenAfterBurnerFlow::SetDirectedParam
97 (Int_t pdg, Float_t v11, Float_t v12, Float_t v13, Float_t v14) {
98   //
99   // Set Directed Flow 
100   // Directed flow is parameterised as follows
101   //
102   // V1(Pt,Y) = (V11 + V12*Pt) * sign(Y) * (V13 + V14 * Y^3)
103   //
104   // where sign = 1 for Y > 0 and -1 for Y < 0
105   // 
106   // Defaults values
107   // v12 = v14 = 0
108   // v13 = 1
109   //  
110   // PDG - particle type to apply directed flow
111   //       if (PDG == 0) use as default  
112   //
113   
114   SetFlowParameters(pdg, 1, 1, v11, v12, v13, v14);
115 }
116
117 ////////////////////////////////////////////////////////////////////////////////////////////////////
118
119 void AliGenAfterBurnerFlow::SetEllipticSimple(Int_t pdg, Float_t v2) {
120   //
121   // Set Elliptic Flow
122   // The same Elliptic flow is applied to all specified particles
123   // independently on transverse momentum or rapidity
124   //
125   // PDG - particle type to apply directed flow
126   //       if (PDG == 0) use as default  
127   //
128   // V2 - flow coefficient
129   //      
130   // NOTE: for starting playing with FLOW 
131   //       start with this function and values 0.05 - 0.1
132   //
133
134   SetFlowParameters(pdg, 2, 0, v2, 0, 0, 0);
135 }
136
137 ////////////////////////////////////////////////////////////////////////////////////////////////////
138
139 void AliGenAfterBurnerFlow::SetEllipticParamPion
140 (Int_t pdg, Float_t v21, Float_t pTmax, Float_t v22) {
141   //
142   // Set Elliptic Flow
143   //
144   // Elliptic flow is parametrised to reproduce 
145   // V2 of Pions at RHIC energies and is given by:
146   // 
147   // V2 = v21 * (pT/pTMax ) * exp (-v22 * y^2)    where pT <= pTmax  
148   //      v21 * exp (-v22 * y^2)                   where pT > pTmax  
149   //
150   // v21   - value at saturation
151   // pTmax - saturation transverse momentum
152   // v22   - rapidity decrising
153   //
154
155   SetFlowParameters(pdg, 2, 1, v21, pTmax, v22, 0);
156 }
157
158 ////////////////////////////////////////////////////////////////////////////////////////////////////
159
160 void AliGenAfterBurnerFlow::SetEllipticParamOld
161 (Int_t pdg, Float_t v21, Float_t v22, Float_t v23) {
162   //
163   // Set Elliptic Flow
164   //
165   // Elliptic flow is parameterised using 
166   // old MevSim parameterisation
167   // 
168   // V2 = (V21 + V22 pT^2) * exp (-v22 * y^2)
169   //
170
171   SetFlowParameters(pdg, 2, 2, v21, v22, v23, 0);
172 }
173
174 ////////////////////////////////////////////////////////////////////////////////////////////////////
175
176 void AliGenAfterBurnerFlow::SetFlowParameters
177 (Int_t pdg, Int_t order, Int_t type, Float_t v1, Float_t v2,Float_t v3,Float_t v4) {
178   // 
179   // private function
180   // 
181   
182   Int_t index = 0;
183   Bool_t newEntry = kTRUE;
184
185   // Defaults
186
187   if (pdg == 0) {
188     index = fgkN - order;
189     newEntry = kFALSE;
190   }
191
192   // try to find existing entry
193   for (Int_t i=0; i<fCounter; i++) {
194     if (pdg == (Int_t)fParams[i][0] && 
195         order == (Int_t)fParams[i][1]) {
196       
197       index = i;
198       newEntry = kFALSE;
199     }
200   }
201   
202   // check fCounter
203
204   if (newEntry && (fCounter > fgkN-3)) {
205     Error("AliAfterBurnerFlow","Overflow");
206     return;
207   }
208   
209   if (newEntry) {
210     index = fCounter;
211     fCounter++;
212   }
213   
214   // Set new particle type
215
216   fParams[index][0] = pdg;
217   fParams[index][1] = order;
218   fParams[index][2] = type;
219   fParams[index][3] = v1;
220   fParams[index][4] = v2;
221   fParams[index][5] = v3;
222   fParams[index][6] = v4;  
223 }
224
225 ////////////////////////////////////////////////////////////////////////////////////////////////////
226
227 void AliGenAfterBurnerFlow::Init() {
228   // 
229   // Standard AliGenerator Initializer
230   //
231
232 }
233
234 ////////////////////////////////////////////////////////////////////////////////////////////////////
235
236 Float_t AliGenAfterBurnerFlow::GetCoefficient
237 (Int_t pdg, Int_t n, Float_t Pt, Float_t Y) {
238   //
239   // private function
240   // Return Flow Coefficient for a given particle type flow order
241   // and particle momentum (Pt, Y)
242   //
243
244   Int_t index = fgkN - n;  // default index 
245   Float_t v = 0;
246
247   // try to find specific parametrs
248
249   for (Int_t i=0; i<fCounter; i++) {
250     
251     if ((Int_t)fParams[i][0] == pdg &&
252         (Int_t)fParams[i][1] == n) {
253       
254       index = i;
255       break;
256     }
257   } 
258   
259   // calculate v
260   
261   Int_t type = (Int_t)fParams[index][2];
262
263   if ((Int_t)fParams[index][1] == 1) { // Directed
264
265     if (type == 0 )
266       v = fParams[index][3];
267     else 
268       v = (fParams[index][3] + fParams[index][4] * Pt) * TMath::Sign((Float_t)1.,Y) *
269         (fParams[index][5] + fParams[index][6] * TMath::Abs(Y*Y*Y) );
270
271   } else {  // Elliptic
272
273     if (type == 0) v = fParams[index][3];
274
275     // Pion parameterisation 
276
277     if (type == 1) { 
278       if (Pt < fParams[index][4]) 
279         v = fParams[index][3] * (Pt / fParams[index][4]) ;
280       else 
281         v = fParams[index][3];
282       
283       v *= TMath::Exp( - fParams[index][5] * Y * Y);
284     }
285
286     // Old parameterisation
287     
288     if (type == 2) 
289       v = (fParams[index][3] + fParams[index][4] * Pt * Pt) *
290         TMath::Exp( - fParams[index][5] * Y * Y);
291   }
292   
293   return v;
294 }
295
296 ////////////////////////////////////////////////////////////////////////////////////////////////////
297
298 void AliGenAfterBurnerFlow::Generate() {
299   // 
300   // AliGenerator generate function doing actual job.
301   // Algorythm:
302   //
303   // 1. loop over particles on the stack
304   // 2. find direct and elliptical flow coefficients for 
305   //    a particle type ore use defaults
306   // 3. calculate delta phi
307   // 4. change phi in orginal particle
308   // 
309   // Algorythm based on:
310   // A.M. Poskanzer, S.A. Voloshin
311   // "Methods of analysisng anisotropic flow in relativistic nuclear collisions"
312   // PRC 58, 1671 (September 1998)
313   //
314   
315   AliGenCocktailAfterBurner *gen;
316   AliStack *stack;
317   TParticle *particle;
318   TLorentzVector momentum;
319
320   Int_t pdg;
321   Float_t phi, dPhi;
322   Float_t pt, y;
323
324   // Get Stack of the first Generator
325   gen = (AliGenCocktailAfterBurner *)gAlice->Generator();
326   stack = gen->GetStack(0);
327
328   // Loop over particles
329
330   for (Int_t i=0; i<stack->GetNtrack(); i++) {
331
332     particle = stack->Particle(i);
333
334     particle->Momentum(momentum);
335     pdg = particle->GetPdgCode();
336     phi = particle->Phi();
337
338     // get Pt, Y
339
340     pt = momentum.Pt();
341     y = momentum.Rapidity();
342
343     // Calculate Delta Phi for Directed and Elliptic Flow
344     
345     dPhi = -2 * GetCoefficient(pdg, 1, pt, y) * TMath::Sin( phi - fReactionPlane );
346     dPhi -= GetCoefficient(pdg, 2, pt, y) * TMath::Sin( 2 * (phi - fReactionPlane));
347     
348     // Set new phi 
349     
350     phi += dPhi;
351     momentum.SetPhi(phi);
352     particle->SetMomentum(momentum);
353   }
354
355   Info("Generate","Flow After Burner: DONE");  
356 }
357
358 ////////////////////////////////////////////////////////////////////////////////////////////////////
359