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