Correct the logics for SetForceDecay
[u/mrichter/AliRoot.git] / EVGEN / AliGenParam.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.12  1999/11/03 17:43:20  fca
19 New version from G.Martinez & A.Morsch
20
21 Revision 1.11  1999/09/29 09:24:14  fca
22 Introduction of the Copyright and cvs Log
23
24 */
25
26 #include "AliGenParam.h"
27 #include "AliGenMUONlib.h"
28 #include "AliGenPHOSlib.h"
29 #include "AliRun.h"
30 #include "AliPythia.h"
31 #include <TDirectory.h>
32 #include <TFile.h>
33 #include <TTree.h>
34 #include <stdlib.h>
35 #include <TParticle.h>
36
37 ClassImp(AliGenParam)
38
39 //------------------------------------------------------------
40
41   //Begin_Html
42   /*
43     <img src="picts/AliGenParam.gif">
44   */
45   //End_Html
46
47 //____________________________________________________________
48 //____________________________________________________________
49 AliGenParam::AliGenParam()
50                  :AliGenerator()
51 {
52   fPtPara = 0;
53   fYPara  = 0;
54   fParam  = jpsi_p;
55   fAnalog = analog;
56   SetCutOnChild();
57 }
58
59 //____________________________________________________________
60
61 AliGenParam::AliGenParam(Int_t npart, Param_t param) :AliGenerator(npart)
62 {
63   //
64   //  fName="HMESONpara";
65   //  fTitle="Heavy Mesons Parametrisation";
66   fPtParaFunc = AliGenMUONlib::GetPt(param);
67   fYParaFunc  = AliGenMUONlib::GetY(param);
68   fIpParaFunc = AliGenMUONlib::GetIp(param);
69   
70   fPtPara = 0;
71   fYPara  = 0;
72   fParam  = param;
73   fAnalog = analog;
74   fChildSelect.Set(5);
75   for (Int_t i=0; i<5; i++) fChildSelect[i]=0;
76   SetForceDecay();
77   SetCutOnChild();
78 }
79
80 AliGenParam::AliGenParam(Int_t npart, Param_t param,
81                          Double_t (*PtPara) (Double_t*, Double_t*),
82                          Double_t (*YPara ) (Double_t* ,Double_t*),
83                          Int_t    (*IpPara) ())                  
84     :AliGenerator(npart)
85 {
86 // Gines Martinez 1/10/99 
87     fPtParaFunc = PtPara; 
88     fYParaFunc  = YPara;  
89     fIpParaFunc = IpPara;
90 //  
91     fPtPara = 0;
92     fYPara  = 0;
93     fParam  = param;
94     fAnalog = analog;
95     fChildSelect.Set(5);
96     for (Int_t i=0; i<5; i++) fChildSelect[i]=0;
97     SetForceDecay();
98     SetCutOnChild();
99 }
100
101 //____________________________________________________________
102 AliGenParam::~AliGenParam()
103 {
104     delete  fPtPara;
105     delete  fYPara;
106 }
107
108 //____________________________________________________________
109 void AliGenParam::Init()
110 {
111     SetMC(new AliPythia());
112     fPythia= (AliPythia*) fgMCEvGen;
113
114 //  End of the test !!!
115   //Begin_Html
116   /*
117     <img src="picts/AliGenParam.gif">
118   */
119   //End_Html
120  
121   fPtPara = new TF1("Pt-Parametrization",fPtParaFunc,fPtMin,fPtMax,0);
122   fYPara  = new TF1("Y -Parametrization",fYParaFunc,fYMin,fYMax,0);
123   TF1* PtPara = new TF1("Pt-Parametrization",fPtParaFunc,0,15,0);
124   TF1* YPara  = new TF1("Y -Parametrization",fYParaFunc,-6,6,0);
125
126 //
127 // dN/dy| y=0
128   Double_t y1=0;
129   Double_t y2=0;
130   
131   fdNdy0=fYParaFunc(&y1,&y2);
132 //
133 // Integral over generation region
134   Float_t IntYS  = YPara ->Integral(fYMin, fYMax);
135   Float_t IntPt0 = PtPara->Integral(0,15);
136   Float_t IntPtS = PtPara->Integral(fPtMin,fPtMax);
137   Float_t PhiWgt=(fPhiMax-fPhiMin)/2./TMath::Pi();
138   if (fAnalog == analog) {
139      fYWgt  = IntYS/fdNdy0;
140      fPtWgt = IntPtS/IntPt0;
141      fParentWeight = fYWgt*fPtWgt*PhiWgt/fNpart;
142   } else {
143       fYWgt = IntYS/fdNdy0;
144       fPtWgt = (fPtMax-fPtMin)/IntPt0;
145       fParentWeight = fYWgt*fPtWgt*PhiWgt/fNpart;
146   }
147 //
148 // particle decay related initialization
149   fPythia->DefineParticles();
150 // semimuonic decays of charm and beauty
151   fPythia->ForceDecay(fForceDecay);
152 //
153     switch (fForceDecay) 
154     {
155     case semielectronic:
156     case dielectron:
157     case b_jpsi_dielectron:
158     case b_psip_dielectron:
159         fChildSelect[0]=11;     
160         break;
161     case semimuonic:
162     case dimuon:
163     case b_jpsi_dimuon:
164     case b_psip_dimuon:
165         fChildSelect[0]=13;
166         break;
167     case pitomu:
168         fChildSelect[0]=13;
169         break;
170     case katomu:
171         fChildSelect[0]=13;
172         break;
173     case nodecay:
174         break;
175     case all:
176         break;
177     }
178 }
179
180 //____________________________________________________________
181 void AliGenParam::Generate()
182 {
183 //
184 // Generate 'npart' of light and heavy mesons (J/Psi, upsilon or phi, Pion,
185 // Kaons, Etas, Omegas) and Baryons (proton, antiprotons, neutrons and 
186 // antineutrons in the the desired theta, phi and momentum windows; 
187 // Gaussian smearing on the vertex is done if selected. 
188 // The decay of heavy mesons is done using lujet, and the childern particle are tracked by GEANT
189 // However, light mesons are directly tracked by GEANT setting fForceDecay = nodecay (SetForceDecay(nodecay)) 
190 //
191
192 // printf("Generate !!!!!!!!!!!!!\n");
193
194   Float_t polar[3]= {0,0,0};  // Polarisation of the parent particle (for GEANT tracking)
195   Float_t origin0[3];         // Origin of the generated parent particle (for GEANT tracking)
196   Float_t pt, pl, ptot;       // Transverse, logitudinal and total momenta of the parent particle
197   Float_t phi, theta;         // Phi and theta spherical angles of the parent particle momentum
198   Float_t p[3], pc[3], 
199           och[3], pch[10][3]; // Momentum, polarisation and origin of the children particles from lujet
200   Float_t ty, xmt;
201   Int_t nt, i, j, kfch[10];
202   Float_t  wgtp, wgtch;
203   Double_t dummy;
204   static TClonesArray *particles;
205   //
206   if(!particles) particles=new TClonesArray("TParticle",1000);
207   //
208   Float_t random[6];
209  
210 // Calculating vertex position per event
211   for (j=0;j<3;j++) origin0[j]=fOrigin[j];
212   if(fVertexSmear==perEvent) {
213       gMC->Rndm(random,6);
214       for (j=0;j<3;j++) {
215           origin0[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
216               TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
217       }
218   }
219   Int_t ipa=0;
220 // Generating fNpart particles
221   while (ipa<fNpart) {
222     while(1) {
223 //
224 // particle type
225           Int_t Ipart = fIpParaFunc();
226           fChildWeight=(fPythia->GetBraPart(Ipart))*fParentWeight;        
227           Float_t am=fPythia->GetPMAS(fPythia->LuComp(Ipart),1);
228           gMC->Rndm(random,2);
229 //
230 // phi
231           phi=fPhiMin+random[0]*(fPhiMax-fPhiMin);
232 //
233 // y
234           ty=Float_t(TMath::TanH(fYPara->GetRandom()));
235 //
236 // pT
237           if (fAnalog == analog) {
238               pt=fPtPara->GetRandom();
239               wgtp=fParentWeight;
240               wgtch=fChildWeight;
241           } else {
242               pt=fPtMin+random[1]*(fPtMax-fPtMin);
243               Double_t ptd=pt;
244               wgtp=fParentWeight*fPtParaFunc(& ptd, &dummy);
245               wgtch=fChildWeight*fPtParaFunc(& ptd, &dummy);
246           }
247           xmt=sqrt(pt*pt+am*am);
248           pl=xmt*ty/sqrt(1.-ty*ty);
249           theta=TMath::ATan2(pt,pl);
250           if(theta<fThetaMin || theta>fThetaMax) continue;
251           ptot=TMath::Sqrt(pt*pt+pl*pl);
252           if(ptot<fPMin || ptot>fPMax) continue;
253           p[0]=pt*TMath::Cos(phi);
254           p[1]=pt*TMath::Sin(phi);
255           p[2]=pl;
256           if(fVertexSmear==perTrack) {
257               gMC->Rndm(random,6);
258               for (j=0;j<3;j++) {
259                   origin0[j]=
260                       fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
261                       TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
262               }
263           }
264           
265 // Looking at fForceDecay : 
266 //                          if fForceDecay != none Primary particle decays using 
267 //                             AliPythia  and children are tracked by GEANT
268 //
269 //                          if fForceDecay == none Primary particle is tracked by GEANT 
270 //                          (In the latest, make sure that GEANT actually does all the decays you want)   
271 //
272           if (fForceDecay != nodecay) {
273 // Using lujet to decay particle
274               Float_t energy=TMath::Sqrt(ptot*ptot+am*am);
275               fPythia->DecayParticle(Ipart,energy,theta,phi);
276               //          fPythia->LuList(1);
277               //printf("origin0 %f %f %f\n",origin0[0],origin0[1],origin0[2]);
278               //printf("fCutOnChild %d \n",fCutOnChild);
279 //
280 // select muons
281               Int_t np=fPythia->ImportParticles(particles,"All");
282               //printf("np     %d \n",np);
283               Int_t ncsel=0;
284               for (i = 1; i<np; i++) {
285                   TParticle *  iparticle = (TParticle *) particles->At(i);
286                   Int_t kf = iparticle->GetPdgCode();
287 //
288 // children
289                   if (ChildSelected(TMath::Abs(kf)))
290                   {
291                       pc[0]=iparticle->Px();
292                       pc[1]=iparticle->Py();
293                       pc[2]=iparticle->Pz();
294                       och[0]=origin0[0]+iparticle->Vx()/10;
295                       och[1]=origin0[1]+iparticle->Vy()/10;
296                       och[2]=origin0[2]+iparticle->Vz()/10;
297                       if (fCutOnChild) {
298                           Float_t PtChild=TMath::Sqrt(pc[0]*pc[0]+pc[1]*pc[1]);
299                           Float_t PChild=TMath::Sqrt(PtChild*PtChild+pc[2]*pc[2]);
300                           Float_t ThetaChild=TMath::ATan2(PtChild,pc[2]);
301                           Float_t PhiChild=TMath::ATan2(pc[1],pc[0])+TMath::Pi();
302                           Bool_t childok = 
303                               ((PtChild   > fPtMin   && PtChild   <fPtMax)      &&
304                                (PChild    > fPMin    && PChild    <fPMax)       &&
305                                (ThetaChild>fThetaMin && ThetaChild<fThetaMax)   &&
306                                (PhiChild  >  fPhiMin && PhiChild  <fPhiMax));
307                           if(childok)
308                           {
309                               pch[ncsel][0]=pc[0];
310                               pch[ncsel][1]=pc[1];
311                               pch[ncsel][2]=pc[2];
312                               kfch[ncsel]=kf;
313                               ncsel++;
314                           } else {
315                               ncsel=-1;
316                               break;
317                           } // child kine cuts
318                       } else {
319                           pch[ncsel][0]=pc[0];
320                           pch[ncsel][1]=pc[1];
321                           pch[ncsel][2]=pc[2];
322                           kfch[ncsel]=kf;
323                           ncsel++;
324                       } // if child selection
325                   } // select muon
326               } // decay particle loop
327               Int_t iparent;
328               if ((fCutOnChild && ncsel >0) || !fCutOnChild){
329                   ipa++;
330 //
331 // parent
332                   gAlice->
333                       SetTrack(0,-1,Ipart,p,origin0,polar,0,"Primary",nt,wgtp);
334                   iparent=nt;
335
336                   for (i=0; i< ncsel; i++) {
337                       gAlice->SetTrack(fTrackIt,iparent,kfch[i],
338                                        &pch[i][0],och,polar,
339                                        0,"Decay",nt,wgtch);
340                       gAlice->KeepTrack(nt); 
341                   }
342               }  // Decays by Lujet
343           } // kinematic selection
344           else  // nodecay option, so parent will be tracked by GEANT (pions, kaons, eta, omegas, baryons)
345           {
346             gAlice->
347                 SetTrack(fTrackIt,-1,Ipart,p,origin0,polar,0,"Primary",nt,wgtp);
348             ipa++; 
349           }
350           break;
351     } // while
352   } // event loop
353 }
354
355 Bool_t AliGenParam::ChildSelected(Int_t ip)
356 {
357     for (Int_t i=0; i<5; i++)
358     {
359         if (fChildSelect[i]==ip) return kTRUE;
360     }
361     return kFALSE;
362 }
363
364 Bool_t AliGenParam::KinematicSelection(TParticle *particle)
365 {
366     Float_t px=particle->Px();
367     Float_t py=particle->Py();
368     Float_t pz=particle->Pz();
369 //
370 // momentum cut
371     Float_t p=TMath::Sqrt(px*px+py*py+pz*pz);
372     if (p > fPMax || p < fPMin) 
373     {
374 //      printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
375         return kFALSE;
376     }
377     Float_t pt=TMath::Sqrt(px*px+py*py);
378     
379 //
380 // theta cut
381     Float_t  theta = Float_t(TMath::ATan2(Double_t(pt),Double_t(p)));
382     if (theta > fThetaMax || theta < fThetaMin) 
383     {
384 //      printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
385         return kFALSE;
386     }
387
388     return kTRUE;
389 }
390
391
392
393