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