Rapidity shift calculated in Init().
[u/mrichter/AliRoot.git] / EVGEN / AliGenMC.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 /*
17 $Log$
18 Revision 1.15  2003/04/04 08:13:26  morsch
19 Boost method added.
20
21 Revision 1.14  2003/01/14 10:50:19  alibrary
22 Cleanup of STEER coding conventions
23
24 Revision 1.13  2002/10/14 14:55:35  hristov
25 Merging the VirtualMC branch to the main development branch (HEAD)
26
27 Revision 1.5.4.2  2002/07/24 08:56:28  alibrary
28 Updating EVGEN on TVirtulaMC
29
30 Revision 1.12  2002/07/19 11:42:33  morsch
31 Use CalcMass()
32
33 Revision 1.11  2002/06/06 15:26:24  morsch
34 Correct child-selection for kPhiKK
35
36 Revision 1.10  2002/06/05 14:05:46  morsch
37 Decayer option kPhiKK for forced phi->K+K- decay added.
38
39 Revision 1.9  2002/05/30 14:58:29  morsch
40 Add pointer to AliGeometry to handle geometrical acceptance. (G. MArtinez)
41
42 Revision 1.8  2002/04/26 10:42:35  morsch
43 Case kNoDecayHeavy added. (N. Carrer)
44
45 Revision 1.7  2002/04/17 10:32:32  morsch
46 Coding Rule violations corrected.
47
48 Revision 1.6  2002/03/26 14:19:36  morsch
49 Saver calculation of rapdity.
50
51 Revision 1.5  2002/03/12 17:02:20  morsch
52 Change in calculation of rapidity, include case in which numerically e == pz.
53
54 Revision 1.4  2001/11/27 13:13:07  morsch
55 Maximum lifetime for long-lived particles to be put on the stack is parameter.
56 It can be set via SetMaximumLifetime(..).
57
58 Revision 1.3  2001/10/16 08:48:56  morsch
59 Common vertex related code moved to base class AliGenerator.
60
61 Revision 1.2  2001/10/15 08:15:51  morsch
62 Event vertex and vertex truncation setting moved into AliMC.
63
64 Revision 1.1  2001/07/13 10:56:00  morsch
65 AliGenMC base class for AliGenParam and AliGenPythia commonalities.
66
67 */
68
69 // Base class for generators using external MC generators.
70 // For example AliGenPythia using Pythia.
71 // Provides basic functionality: setting of kinematic cuts on 
72 // decay products and particle selection.
73 // andreas.morsch@cern.ch
74
75 #include <TMath.h>
76 #include <TPDGCode.h>
77 #include <TParticle.h>
78
79 #include "AliGenMC.h"
80
81  ClassImp(AliGenMC)
82
83 AliGenMC::AliGenMC()
84                  :AliGenerator()
85 {
86 // Default Constructor
87     SetCutOnChild();
88     SetChildMomentumRange();
89     SetChildPtRange();
90     SetChildPhiRange();
91     SetChildThetaRange(); 
92     SetChildYRange(); 
93     SetMaximumLifetime();
94     SetGeometryAcceptance();
95     SetPdgCodeParticleforAcceptanceCut();
96     SetNumberOfAcceptedParticles();
97     SetTarget();
98     SetProjectile();
99 }
100
101 AliGenMC::AliGenMC(Int_t npart)
102                  :AliGenerator(npart)
103 {
104 //  Constructor
105     SetCutOnChild();
106     SetChildMomentumRange();
107     SetChildPtRange();
108     SetChildPhiRange();
109     SetChildThetaRange();
110     SetChildYRange(); 
111 // 
112     fParentSelect.Set(8);
113     fChildSelect.Set(8);
114     for (Int_t i=0; i<8; i++) fParentSelect[i]=fChildSelect[i]=0;
115     SetMaximumLifetime();
116     SetGeometryAcceptance();
117     SetPdgCodeParticleforAcceptanceCut();
118     SetNumberOfAcceptedParticles();
119     SetTarget();
120     SetProjectile();
121 }
122
123 AliGenMC::AliGenMC(const AliGenMC & mc)
124 {
125 // copy constructor
126 }
127
128 AliGenMC::~AliGenMC()
129 {
130 // Destructor
131 }
132
133 void AliGenMC::Init()
134 {
135 //
136 //  Initialization
137     switch (fForceDecay) {
138     case kSemiElectronic:
139     case kDiElectron:
140     case kBJpsiDiElectron:
141     case kBPsiPrimeDiElectron:
142         fChildSelect[0] = kElectron;    
143         break;
144     case kSemiMuonic:
145     case kDiMuon:
146     case kBJpsiDiMuon:
147     case kBPsiPrimeDiMuon:
148     case kPiToMu:
149     case kKaToMu:
150         fChildSelect[0]=kMuonMinus;
151         break;
152     case kHadronicD:
153         fChildSelect[0]=kPiPlus;
154         fChildSelect[1]=kKPlus;
155         break;
156     case kPhiKK:
157         fChildSelect[0]=kKPlus;
158     case kOmega:        
159     case kAll:
160     case kNoDecay:
161     case kNoDecayHeavy:
162         break;
163     }
164
165     if (fZTarget != 0 && fAProjectile != 0) 
166     {
167         fDyBoost    = - 0.5 * TMath::Log(Double_t(fZProjectile) * Double_t(fATarget) / 
168                                          (Double_t(fZTarget)    * Double_t(fAProjectile)));
169     }
170 }
171
172
173 Bool_t AliGenMC::ParentSelected(Int_t ip) const
174 {
175 // True if particle is in list of parent particles to be selected
176     for (Int_t i=0; i<8; i++)
177     {
178         if (fParentSelect.At(i) == ip) return kTRUE;
179     }
180     return kFALSE;
181 }
182
183 Bool_t AliGenMC::ChildSelected(Int_t ip) const
184 {
185 // True if particle is in list of decay products to be selected
186     for (Int_t i=0; i<5; i++)
187     {
188         if (fChildSelect.At(i) == ip) return kTRUE;
189     }
190     return kFALSE;
191 }
192
193 Bool_t AliGenMC::KinematicSelection(TParticle *particle, Int_t flag) const
194 {
195 // Perform kinematic selection
196     Float_t px    = particle->Px();
197     Float_t py    = particle->Py();
198     Float_t pz    = particle->Pz();
199     Float_t  e    = particle->Energy();
200     Float_t pt    = particle->Pt();
201     Float_t p     = particle->P();
202     Float_t theta = particle->Theta();
203     Float_t mass  = particle->GetCalcMass();
204     Float_t mt2   = pt * pt + mass * mass;
205     
206     Float_t phi   = Float_t(TMath::ATan2(Double_t(py),Double_t(px)));
207     Double_t y, y0;
208
209     if (TMath::Abs(pz) <  e) {
210         y = 0.5*TMath::Log((e+pz)/(e-pz));
211     } else {
212         y = 1.e10;
213     }
214     
215     if (mt2) {
216         y0 = 0.5*TMath::Log((e+TMath::Abs(pz))*(e+TMath::Abs(pz))/mt2);
217     } else {
218         if (TMath::Abs(y) < 1.e10) {
219             y0 = y;
220         } else {
221             y0 = 1.e10;
222         }
223     }
224       
225     y = (pz < 0) ? -y0 : y0;
226     
227     if (flag == 0) {
228 //
229 // Primary particle cuts
230 //
231 //  transverse momentum cut    
232         if (pt > fPtMax || pt < fPtMin) {
233 //          printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
234             return kFALSE;
235         }
236 //
237 // momentum cut
238         if (p > fPMax || p < fPMin) {
239 //          printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
240             return kFALSE;
241         }
242 //
243 // theta cut
244         if (theta > fThetaMax || theta < fThetaMin) {
245 //          printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
246             return kFALSE;
247         }
248 //
249 // rapidity cut
250         if (y > fYMax || y < fYMin) {
251 //          printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
252             return kFALSE;
253         }
254 //
255 // phi cut
256         if (phi > fPhiMax || phi < fPhiMin) {
257 //          printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
258             return kFALSE;
259         }
260     } else {
261 //
262 // Decay product cuts
263 //
264 //  transverse momentum cut    
265         if (pt > fChildPtMax || pt < fChildPtMin) {
266 //          printf("\n failed pt cut %f %f %f \n",pt,fChildPtMin,fChildPtMax);
267             return kFALSE;
268         }
269 //
270 // momentum cut
271         if (p > fChildPMax || p < fChildPMin) {
272 //          printf("\n failed p cut %f %f %f \n",p,fChildPMin,fChildPMax);
273             return kFALSE;
274         }
275 //
276 // theta cut
277         if (theta > fChildThetaMax || theta < fChildThetaMin) {
278 //          printf("\n failed theta cut %f %f %f \n",theta,fChildThetaMin,fChildThetaMax);
279             return kFALSE;
280         }
281 //
282 // rapidity cut
283         if (y > fChildYMax || y < fChildYMin) {
284 //          printf("\n failed y cut %f %f %f \n",y,fChildYMin,fChildYMax);
285             return kFALSE;
286         }
287 //
288 // phi cut
289         if (phi > fChildPhiMax || phi < fChildPhiMin) {
290 //          printf("\n failed phi cut %f %f %f \n",phi,fChildPhiMin,fChildPhiMax);
291             return kFALSE;
292         }
293     }
294     
295     return kTRUE;
296 }
297
298 Bool_t AliGenMC::CheckAcceptanceGeometry(Int_t np, TClonesArray* particles)
299 {
300   Bool_t Check ;  // All fPdgCodeParticleforAcceptanceCut particles are in in the fGeometryAcceptance acceptance
301   Int_t NumberOfPdgCodeParticleforAcceptanceCut=0;
302   Int_t NumberOfAcceptedPdgCodeParticleforAcceptanceCut=0;
303   TParticle * particle;
304   Int_t i;
305   for (i=0; i<np; i++) {
306     particle =  (TParticle *) particles->At(i);
307     if( TMath::Abs( particle->GetPdgCode() ) == TMath::Abs( fPdgCodeParticleforAcceptanceCut ) ) {
308       NumberOfPdgCodeParticleforAcceptanceCut++;
309       if (fGeometryAcceptance->Impact(particle)) NumberOfAcceptedPdgCodeParticleforAcceptanceCut++;
310     }   
311   }
312   if ( NumberOfAcceptedPdgCodeParticleforAcceptanceCut > (fNumberOfAcceptedParticles-1) )
313     Check = kTRUE;
314   else
315     Check = kFALSE;
316
317   return Check;
318 }
319
320 Int_t AliGenMC::CheckPDGCode(Int_t pdgcode) const
321 {
322 //
323 //  If the particle is in a diffractive state, then take action accordingly
324   switch (pdgcode) {
325   case 91:
326     return 92;
327   case 110:
328     //rho_diff0 -- difficult to translate, return rho0
329     return 113;
330   case 210:
331     //pi_diffr+ -- change to pi+
332     return 211;
333   case 220:
334     //omega_di0 -- change to omega0
335     return 223;
336   case 330:
337     //phi_diff0 -- return phi0
338     return 333;
339   case 440:
340     //J/psi_di0 -- return J/psi
341     return 443;
342   case 2110:
343     //n_diffr -- return neutron
344     return 2112;
345   case 2210:
346     //p_diffr+ -- return proton
347     return 2212;
348   }
349   //non diffractive state -- return code unchanged
350   return pdgcode;
351 }
352
353 void AliGenMC::Boost()
354 {
355 //
356 // Boost cms into LHC lab frame
357 //
358
359     Double_t beta  = TMath::TanH(fDyBoost);
360     Double_t gamma = 1./TMath::Sqrt(1.-beta*beta);
361     Double_t gb    = gamma * beta;
362
363     printf("\n Boosting particles to lab frame %f %f %f", fDyBoost, beta, gamma);
364     
365     Int_t i;
366     Int_t np = fParticles->GetEntriesFast();
367     for (i = 0; i < np; i++) 
368     {
369         TParticle* iparticle = (TParticle*) fParticles->At(i);
370
371         Double_t e   = iparticle->Energy();
372         Double_t px  = iparticle->Px();
373         Double_t py  = iparticle->Py();
374         Double_t pz  = iparticle->Pz();
375
376         Double_t eb  = gamma * e -      gb * pz;
377         Double_t pzb =   -gb * e +   gamma * pz;
378
379         iparticle->SetMomentum(px, py, pzb, eb);
380     }
381 }
382
383
384           
385 AliGenMC& AliGenMC::operator=(const  AliGenMC& rhs)
386 {
387 // Assignment operator
388     return *this;
389 }
390