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