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