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