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