Correct GetWire check on even/odd fnWires
[u/mrichter/AliRoot.git] / EVGEN / AliGenPythia.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 */
19
20 #include "AliGenerator.h"
21 #include "AliGenPythia.h"
22 #include "AliRun.h"
23 #include "AliPythia.h"
24 #include <TDirectory.h>
25 #include <TFile.h>
26 #include <TTree.h>
27 #include <stdlib.h>
28 #include <AliPythia.h>
29 #include <TParticle.h>
30 //#include <GParticle.h>
31  ClassImp(AliGenPythia)
32
33 AliGenPythia::AliGenPythia()
34                  :AliGenerator()
35 {
36 }
37
38 AliGenPythia::AliGenPythia(Int_t npart)
39                  :AliGenerator(npart)
40 {
41 // default charm production at 5. 5 TeV
42 // semimuonic decay
43 // structure function GRVHO
44 //
45     fXsection  = 0.;
46     fParentSelect.Set(5);
47     fChildSelect.Set(5);
48     for (Int_t i=0; i<5; i++) fParentSelect[i]=fChildSelect[i]=0;
49     SetProcess();
50     SetStrucFunc();
51     ForceDecay();
52     SetPtHard();
53     SetEnergyCMS();
54 }
55
56 AliGenPythia::~AliGenPythia()
57 {
58 }
59
60 void AliGenPythia::Init()
61 {
62     SetMC(new AliPythia());
63     fPythia=(AliPythia*) fgMCEvGen;
64 //
65     fParentWeight=1./Float_t(fNpart);
66 //
67 //  Forward Paramters to the AliPythia object
68     fPythia->DefineParticles();
69     fPythia->SetCKIN(3,fPtHardMin);
70     fPythia->SetCKIN(4,fPtHardMax);    
71     fPythia->ProcInit(fProcess,fEnergyCMS,fStrucFunc);
72     fPythia->ForceDecay(fForceDecay);
73     fPythia->LuList(0);
74     fPythia->PyStat(2);
75 //  Parent and Children Selection
76     switch (fProcess) 
77     {
78     case charm:
79
80         fParentSelect[0]=411;
81         fParentSelect[1]=421;
82         fParentSelect[2]=431;
83         fParentSelect[3]=4122;  
84         break;
85     case charm_unforced:
86
87         fParentSelect[0]=411;
88         fParentSelect[1]=421;
89         fParentSelect[2]=431;
90         fParentSelect[3]=4122;  
91         break;
92     case beauty:
93         fParentSelect[0]=511;
94         fParentSelect[1]=521;
95         fParentSelect[2]=531;
96         fParentSelect[3]=5122;  
97         break;
98     case beauty_unforced:
99         fParentSelect[0]=511;
100         fParentSelect[1]=521;
101         fParentSelect[2]=531;
102         fParentSelect[3]=5122;  
103         break;
104     case jpsi_chi:
105     case jpsi:
106         fParentSelect[0]=443;
107         break;
108     case mb:
109         break;
110     }
111
112     switch (fForceDecay) 
113     {
114     case semielectronic:
115     case dielectron:
116     case b_jpsi_dielectron:
117     case b_psip_dielectron:
118         fChildSelect[0]=11;     
119         break;
120     case semimuonic:
121     case dimuon:
122     case b_jpsi_dimuon:
123     case b_psip_dimuon:
124     case pitomu:
125     case katomu:
126         fChildSelect[0]=13;
127         break;
128     }
129 }
130
131 void AliGenPythia::Generate()
132 {
133
134     Float_t polar[3] =   {0,0,0};
135     Float_t origin[3]=   {0,0,0};
136     Float_t origin_p[3]= {0,0,0};
137     Float_t origin0[3]=  {0,0,0};
138     Float_t p[3], p_p[4], random[6];
139     static TClonesArray *particles;
140 //  converts from mm/c to s
141     const Float_t kconv=0.001/2.999792458e8;
142     
143     
144 //
145     Int_t nt=0;
146     Int_t nt_p=0;
147     Int_t jev=0;
148     Int_t j, kf;
149
150     if(!particles) particles=new TClonesArray("TParticle",1000);
151     
152     fTrials=0;
153     for (j=0;j<3;j++) origin0[j]=fOrigin[j];
154     if(fVertexSmear==perEvent) {
155         gMC->Rndm(random,6);
156         for (j=0;j<3;j++) {
157             origin0[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
158                 TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
159             fPythia->SetMSTP(151,0);
160         }
161     } else if (fVertexSmear==perTrack) {
162         fPythia->SetMSTP(151,0);
163         for (j=0;j<3;j++) {
164             fPythia->SetPARP(151+j, fOsigma[j]*10.);
165         }
166     }
167     while(1)
168     {
169         fPythia->PyEvnt();
170         fTrials++;
171         fPythia->ImportParticles(particles,"All");
172         Int_t np = particles->GetEntriesFast();
173         printf("\n **************************************************%d\n",np);
174         Int_t nc=0;
175         if (np == 0 ) continue;
176         if (fProcess != mb) {
177             for (Int_t i = 0; i<np; i++) {
178                 TParticle *  iparticle = (TParticle *) particles->At(i);
179                 kf = CheckPDGCode(iparticle->GetPdgCode());
180                 fChildWeight=(fPythia->GetBraPart(kf))*fParentWeight;     
181 //
182 // Parent
183                 if (ParentSelected(TMath::Abs(kf))) {
184                     if (KinematicSelection(iparticle)) {
185                         if (nc==0) {
186 //
187 // Store information concerning the hard scattering process
188 //
189                             Float_t mass_p = fPythia->GetPARI(13);
190                             Float_t   pt_p = fPythia->GetPARI(17);
191                             Float_t    y_p = fPythia->GetPARI(37);
192                             Float_t  xmt_p = sqrt(pt_p*pt_p+mass_p*mass_p);
193                             Float_t     ty = Float_t(TMath::TanH(y_p));
194                             p_p[0] = pt_p;
195                             p_p[1] = 0;
196                             p_p[2] = xmt_p*ty/sqrt(1.-ty*ty);
197                             p_p[3] = mass_p;
198                             gAlice->SetTrack(0,-1,-1,
199                                              p_p,origin_p,polar,
200                                              0,"Hard Scat.",nt_p,fParentWeight);
201                             gAlice->KeepTrack(nt_p);
202                         }
203                         nc++;
204 //
205 // store parent track information
206                         p[0]=iparticle->Px();
207                         p[1]=iparticle->Py();
208                         p[2]=iparticle->Pz();
209                         origin[0]=origin0[0]+iparticle->Vx()/10;
210                         origin[1]=origin0[1]+iparticle->Vy()/10;
211                         origin[2]=origin0[2]+iparticle->Vz()/10;
212
213                         Int_t ifch=iparticle->GetFirstDaughter();
214                         Int_t ilch=iparticle->GetLastDaughter();        
215                         if (ifch !=0 && ilch !=0) {
216                             gAlice->SetTrack(0,nt_p,kf,
217                                              p,origin,polar,
218                                              0,"Primary",nt,fParentWeight);
219                             gAlice->KeepTrack(nt);
220                             Int_t iparent = nt;
221 //
222 // Children         
223
224                             for (j=ifch; j<=ilch; j++)
225                             {
226                                 TParticle *  ichild = 
227                                     (TParticle *) particles->At(j-1);
228                                 kf = CheckPDGCode(ichild->GetPdgCode());
229 //
230 // 
231                                 if (ChildSelected(TMath::Abs(kf))) {
232                                     origin[0]=ichild->Vx();
233                                     origin[1]=ichild->Vy();
234                                     origin[2]=ichild->Vz();             
235                                     p[0]=ichild->Px();
236                                     p[1]=ichild->Py();
237                                     p[2]=ichild->Pz();
238                                     Float_t tof=kconv*ichild->T();
239                                     gAlice->SetTrack(fTrackIt, iparent, kf,
240                                                      p,origin,polar,
241                                                      tof,"Decay",nt,fChildWeight);
242                                     gAlice->KeepTrack(nt);
243                                 } // select child
244                             } // child loop
245                         }
246                     } // kinematic selection
247                 } // select particle
248             } // particle loop
249         } else {
250             for (Int_t i = 0; i<np; i++) {
251                 TParticle *  iparticle = (TParticle *) particles->At(i);
252                 kf = CheckPDGCode(iparticle->GetPdgCode());
253                 Int_t ks = iparticle->GetStatusCode();
254                 if (ks==1 && kf!=0 && KinematicSelection(iparticle)) {
255                         nc++;
256 //
257 // store track information
258                         p[0]=iparticle->Px();
259                         p[1]=iparticle->Py();
260                         p[2]=iparticle->Pz();
261                         origin[0]=origin0[0]+iparticle->Vx()/10;
262                         origin[1]=origin0[1]+iparticle->Vy()/10;
263                         origin[2]=origin0[2]+iparticle->Vz()/10;
264                         Float_t tof=kconv*iparticle->T();
265                         gAlice->SetTrack(fTrackIt,-1,kf,p,origin,polar,
266                                          tof,"Primary",nt);
267                         gAlice->KeepTrack(nt);
268                 } // select particle
269             } // particle loop 
270             printf("\n I've put %i particles on the stack \n",nc);
271         } // mb ?
272         if (nc > 0) {
273             jev+=nc;
274             if (jev >= fNpart) {
275                 fKineBias=Float_t(fNpart)/Float_t(fTrials);
276                 printf("\n Trials: %i\n",fTrials);
277                 break;
278             }
279         }
280     } // event loop
281 //  adjust weight due to kinematic selection
282     AdjustWeights();
283 //  get cross-section
284     fXsection=fPythia->GetPARI(1);
285 }
286
287 Bool_t AliGenPythia::ParentSelected(Int_t ip)
288 {
289     for (Int_t i=0; i<5; i++)
290     {
291         if (fParentSelect[i]==ip) return kTRUE;
292     }
293     return kFALSE;
294 }
295
296 Bool_t AliGenPythia::ChildSelected(Int_t ip)
297 {
298     for (Int_t i=0; i<5; i++)
299     {
300         if (fChildSelect[i]==ip) return kTRUE;
301     }
302     return kFALSE;
303 }
304
305 Bool_t AliGenPythia::KinematicSelection(TParticle *particle)
306 {
307     Float_t px=particle->Px();
308     Float_t py=particle->Py();
309     Float_t pz=particle->Pz();
310     Float_t  e=particle->Energy();
311
312 //
313 //  transverse momentum cut    
314     Float_t pt=TMath::Sqrt(px*px+py*py);
315     if (pt > fPtMax || pt < fPtMin) 
316     {
317 //      printf("\n failed pt cut %f %f %f \n",pt,fPtMin,fPtMax);
318         return kFALSE;
319     }
320 //
321 // momentum cut
322     Float_t p=TMath::Sqrt(px*px+py*py+pz*pz);
323     if (p > fPMax || p < fPMin) 
324     {
325 //      printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
326         return kFALSE;
327     }
328     
329 //
330 // theta cut
331     Float_t  theta = Float_t(TMath::ATan2(Double_t(pt),Double_t(pz)));
332     if (theta > fThetaMax || theta < fThetaMin) 
333     {
334 //      printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
335         return kFALSE;
336     }
337
338 //
339 // rapidity cut
340     Float_t y = 0.5*TMath::Log((e+pz)/(e-pz));
341     if (y > fYMax || y < fYMin)
342     {
343 //      printf("\n failed y cut %f %f %f \n",y,fYMin,fYMax);
344         return kFALSE;
345     }
346
347 //
348 // phi cut
349     Float_t phi=Float_t(TMath::ATan2(Double_t(py),Double_t(px)))+TMath::Pi();
350     if (phi > fPhiMax || phi < fPhiMin)
351     {
352 //      printf("\n failed phi cut %f %f %f \n",phi,fPhiMin,fPhiMax);
353         return kFALSE;
354     }
355
356     return kTRUE;
357 }
358 void AliGenPythia::AdjustWeights()
359 {
360     TClonesArray *PartArray = gAlice->Particles();
361     TParticle *Part;
362     Int_t ntrack=gAlice->GetNtrack();
363     for (Int_t i=0; i<ntrack; i++) {
364         Part= (TParticle*) PartArray->UncheckedAt(i);
365         Part->SetWeight(Part->GetWeight()*fKineBias);
366     }
367 }
368
369 Int_t AliGenPythia::CheckPDGCode(Int_t pdgcode)
370 {
371 //
372 //  If the particle is in a diffractive state, then take action accordigly
373   switch (pdgcode) {
374   case 110:
375     //rho_diff0 -- difficult to translate, return rho0
376     return 113;
377   case 210:
378     //pi_diffr+ -- change to pi+
379     return 211;
380   case 220:
381     //omega_di0 -- change to omega0
382     return 223;
383   case 330:
384     //phi_diff0 -- return phi0
385     return 333;
386   case 440:
387     //J/psi_di0 -- return J/psi
388     return 443;
389   case 2110:
390     //n_diffr -- return neutron
391     return 2112;
392   case 2210:
393     //p_diffr+ -- return proton
394     return 2212;
395   }
396   //non diffractive state -- return code unchanged
397   return pdgcode;
398 }
399                   
400
401
402
403
404
405
406
407