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