Small corrections from A.Morsch for weighted events handling
[u/mrichter/AliRoot.git] / EVGEN / AliGenParam.cxx
1 #include "AliGenParam.h"
2 #include "AliGenMUONlib.h"
3 #include "AliRun.h"
4 #include "AliPythia.h"
5 #include <TDirectory.h>
6 #include <TFile.h>
7 #include <TTree.h>
8 #include <stdlib.h>
9 #include <TParticle.h>
10
11 ClassImp(AliGenParam)
12
13 //------------------------------------------------------------
14
15   //Begin_Html
16   /*
17     <img src="picts/AliGenParam.gif">
18   */
19   //End_Html
20
21 //____________________________________________________________
22 //____________________________________________________________
23 AliGenParam::AliGenParam()
24                  :AliGenerator()
25 {
26   fPtPara = 0;
27   fYPara  = 0;
28   fParam  = jpsi_p;
29   fAnalog = analog;
30   SetCutOnChild();
31 }
32
33 //____________________________________________________________
34 AliGenParam::AliGenParam(Int_t npart, Param_t param) 
35 //                                 Double_t (*PtPara)(Double_t*, Double_t*), 
36 //                                 Double_t (*YPara) (Double_t* ,Double_t*))
37     :AliGenerator(npart)
38 {
39   //
40   //  fName="HMESONpara";
41   //  fTitle="Heavy Mesons Parametrisation";
42   fPtParaFunc = AliGenMUONlib::GetPt(param);
43   fYParaFunc  = AliGenMUONlib::GetY(param);
44   fIpParaFunc = AliGenMUONlib::GetIp(param);
45   
46   fPtPara = 0;
47   fYPara  = 0;
48   fParam  = param;
49   fAnalog = analog;
50   fChildSelect.Set(5);
51   for (Int_t i=0; i<5; i++) fChildSelect[i]=0;
52   ForceDecay();
53   SetCutOnChild();
54 }
55
56 //____________________________________________________________
57 AliGenParam::~AliGenParam()
58 {
59     delete  fPtPara;
60     delete  fYPara;
61 }
62
63 //____________________________________________________________
64 void AliGenParam::Init()
65 {
66     SetMC(new AliPythia());
67     fPythia= (AliPythia*) fgMCEvGen;
68
69 //  End of the test !!!
70   //Begin_Html
71   /*
72     <img src="picts/AliGenParam.gif">
73   */
74   //End_Html
75  
76   fPtPara = new TF1("Pt-Parametrization",fPtParaFunc,fPtMin,fPtMax,0);
77   fYPara  = new TF1("Y -Parametrization",fYParaFunc,fYMin,fYMax,0);
78   TF1* PtPara = new TF1("Pt-Parametrization",fPtParaFunc,0,15,0);
79   TF1* YPara  = new TF1("Y -Parametrization",fYParaFunc,-6,6,0);
80
81 //
82 // dN/dy| y=0
83   Double_t y1=0;
84   Double_t y2=0;
85   
86   fdNdy0=fYParaFunc(&y1,&y2);
87 //
88 // Integral over generation region
89   Float_t IntYS  = YPara ->Integral(fYMin, fYMax);
90   Float_t IntPt0 = PtPara->Integral(0,15);
91   Float_t IntPtS = PtPara->Integral(fPtMin,fPtMax);
92   Float_t PhiWgt=(fPhiMax-fPhiMin)/2./TMath::Pi();
93   if (fAnalog == analog) {
94      fYWgt  = IntYS/fdNdy0;
95      fPtWgt = IntPtS/IntPt0;
96      fParentWeight = fYWgt*fPtWgt*PhiWgt/fNpart;
97   } else {
98       fYWgt = IntYS/fdNdy0;
99       fPtWgt = (fPtMax-fPtMin)/IntPt0;
100       fParentWeight = fYWgt*fPtWgt*PhiWgt/fNpart;
101   }
102 //
103 // particle decay related initialization
104   fPythia->DefineParticles();
105 // semimuonic decays of charm and beauty
106   fPythia->ForceDecay(fForceDecay);
107 //
108     switch (fForceDecay) 
109     {
110     case semielectronic:
111     case dielectron:
112     case b_jpsi_dielectron:
113     case b_psip_dielectron:
114         fChildSelect[0]=11;     
115         break;
116     case semimuonic:
117     case dimuon:
118     case b_jpsi_dimuon:
119     case b_psip_dimuon:
120         fChildSelect[0]=13;
121         break;
122     case pitomu:
123         fChildSelect[0]=13;
124         break;
125     case katomu:
126         fChildSelect[0]=13;
127         break;
128     }
129
130 }
131
132 //____________________________________________________________
133 void AliGenParam::Generate()
134 {
135 // Generate 'npart' of heavy mesons (J/Psi, upsilon or phi) in the
136 // the desired theta, phi and momentum windows; Gaussian smearing 
137 // on the vertex is done if selected
138
139
140   //printf("Generate !!!!!!!!!!!!!\n");
141
142   Float_t polar[3]= {0,0,0};
143   //
144   Float_t origin[3], origin0[3];
145   Float_t pt, pl, ptot;
146   Float_t phi, theta;
147   Float_t p[3], pc[3], och[3], pch[10][3];
148   Float_t ty, xmt;
149   Int_t nt, i, j, kfch[10];
150   Float_t  wgtp, wgtch;
151   Double_t dummy;
152   static TClonesArray *particles;
153   //
154   if(!particles) particles=new TClonesArray("TParticle",1000);
155   //
156   Float_t random[6];
157   for (j=0;j<3;j++) origin0[j]=fOrigin[j];
158   if(fVertexSmear==perEvent) {
159       gMC->Rndm(random,6);
160       for (j=0;j<3;j++) {
161           origin0[j]+=fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
162               TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
163       }
164   }
165   Int_t ipa=0;
166   while (ipa<fNpart) {
167     while(1) {
168 //
169 // particle type
170           Int_t Ipart = fIpParaFunc();
171           fChildWeight=(fPythia->GetBraPart(Ipart))*fParentWeight;        
172           Float_t am=fPythia->GetPMAS(fPythia->LuComp(Ipart),1);
173           gMC->Rndm(random,2);
174 //
175 // phi
176           phi=fPhiMin+random[0]*(fPhiMax-fPhiMin);
177 //
178 // y
179           ty=Float_t(TMath::TanH(fYPara->GetRandom()));
180 //
181 // pT
182           if (fAnalog == analog) {
183               pt=fPtPara->GetRandom();
184               wgtp=fParentWeight;
185               wgtch=fChildWeight;
186           } else {
187               pt=fPtMin+random[1]*(fPtMax-fPtMin);
188               Double_t ptd=pt;
189               wgtp=fParentWeight*fPtParaFunc(& ptd, &dummy);
190               wgtch=fChildWeight*fPtParaFunc(& ptd, &dummy);
191           }
192           xmt=sqrt(pt*pt+am*am);
193           pl=xmt*ty/sqrt(1.-ty*ty);
194           theta=TMath::ATan2(pt,pl);
195           if(theta<fThetaMin || theta>fThetaMax) continue;
196           ptot=TMath::Sqrt(pt*pt+pl*pl);
197           if(ptot<fPMin || ptot>fPMax) continue;
198           p[0]=pt*TMath::Cos(phi);
199           p[1]=pt*TMath::Sin(phi);
200           p[2]=pl;
201           if(fVertexSmear==perTrack) {
202               gMC->Rndm(random,6);
203               for (j=0;j<3;j++) {
204                   origin0[j]=
205                       fOrigin[j]+fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
206                       TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
207               }
208           }
209 //
210 // use lujet to decay particle
211
212           Float_t energy=TMath::Sqrt(ptot*ptot+am*am);
213           fPythia->DecayParticle(Ipart,energy,theta,phi);
214           //      fPythia->LuList(1);
215
216
217           //printf("origin0 %f %f %f\n",origin0[0],origin0[1],origin0[2]);
218           //printf("fCutOnChild %d \n",fCutOnChild);
219 //
220 // select muons
221           Int_t np=fPythia->ImportParticles(particles,"All");
222           //printf("np     %d \n",np);
223           Int_t ncsel=0;
224           for (i = 1; i<np; i++) {
225               TParticle *  iparticle = (TParticle *) particles->At(i);
226               Int_t kf = iparticle->GetPdgCode();
227               //printf("kf %d\n",kf);
228 //
229 // children
230               if (ChildSelected(TMath::Abs(kf)))
231               {
232                   pc[0]=iparticle->Px();
233                   pc[1]=iparticle->Py();
234                   pc[2]=iparticle->Pz();
235                   och[0]=origin0[0]+iparticle->Vx()/10;
236                   och[1]=origin0[1]+iparticle->Vy()/10;
237                   och[2]=origin0[2]+iparticle->Vz()/10;
238                   if (fCutOnChild) {
239                     Float_t PtChild=TMath::Sqrt(pc[0]*pc[0]+pc[1]*pc[1]);
240                     Float_t PChild=TMath::Sqrt(PtChild*PtChild+pc[2]*pc[2]);
241                     Float_t ThetaChild=TMath::ATan2(PtChild,pc[2]);
242                     Float_t PhiChild=TMath::ATan2(pc[1],pc[0])+TMath::Pi();
243                     Bool_t childok = 
244                       ((PtChild   > fPtMin   && PtChild   <fPtMax)      &&
245                         (PChild    > fPMin    && PChild    <fPMax)       &&
246                         (ThetaChild>fThetaMin && ThetaChild<fThetaMax)   &&
247                         (PhiChild  >  fPhiMin && PhiChild  <fPhiMax));
248                     if(childok)
249                       {
250                         pch[ncsel][0]=pc[0];
251                         pch[ncsel][1]=pc[1];
252                         pch[ncsel][2]=pc[2];
253                         kfch[ncsel]=kf;
254                         ncsel++;
255                       } else {
256                         ncsel=-1;
257                         break;
258                       } // child kine cuts
259                   } else {
260                     pch[ncsel][0]=pc[0];
261                     pch[ncsel][1]=pc[1];
262                     pch[ncsel][2]=pc[2];
263                     kfch[ncsel]=kf;
264                     ncsel++;
265                   } // if child selection
266               } // select muon
267           } // decay particle loop
268           Int_t iparent;
269           if ((fCutOnChild && ncsel >0) || !fCutOnChild){
270               ipa++;
271 //
272 // parent
273               gAlice->
274                   SetTrack(0,-1,Ipart,p,origin,polar,0,"Primary",nt,wgtp);
275               iparent=nt;
276
277               for (i=0; i< ncsel; i++) {
278                   gAlice->SetTrack(fTrackIt,iparent,kfch[i],
279                                    &pch[i][0],och,polar,
280                                    0,"Decay",nt,wgtch);
281                   gAlice->KeepTrack(nt); 
282               }
283               
284           } // kinematic selection
285           break;
286     } // while
287   } // event loop
288 }
289
290 Bool_t AliGenParam::ChildSelected(Int_t ip)
291 {
292     for (Int_t i=0; i<5; i++)
293     {
294         if (fChildSelect[i]==ip) return kTRUE;
295     }
296     return kFALSE;
297 }
298
299 Bool_t AliGenParam::KinematicSelection(TParticle *particle)
300 {
301     Float_t px=particle->Px();
302     Float_t py=particle->Py();
303     Float_t pz=particle->Pz();
304 //
305 // momentum cut
306     Float_t p=TMath::Sqrt(px*px+py*py+pz*pz);
307     if (p > fPMax || p < fPMin) 
308     {
309 //      printf("\n failed p cut %f %f %f \n",p,fPMin,fPMax);
310         return kFALSE;
311     }
312     Float_t pt=TMath::Sqrt(px*px+py*py);
313     
314 //
315 // theta cut
316     Float_t  theta = Float_t(TMath::ATan2(Double_t(pt),Double_t(p)));
317     if (theta > fThetaMax || theta < fThetaMin) 
318     {
319 //      printf("\n failed theta cut %f %f %f \n",theta,fThetaMin,fThetaMax);
320         return kFALSE;
321     }
322
323     return kTRUE;
324 }
325
326
327
328