]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVGEN/AliGenBeamGasNew.cxx
Corrected version (Jochen Klein).
[u/mrichter/AliRoot.git] / EVGEN / AliGenBeamGasNew.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 /* $Id$ */
17
18
19
20 //-------------------------------------------------------------
21 //  Generate Beam-Gas-Events 
22 //  Default: underlying event: pO @ 7 TeV (fixed target)
23 //
24 //  underlying event can be changed by adding generators 
25 //  in the same way as to AliGenCocktail before calling 
26 //  the Init()
27 //  Author: Jochen Klein
28 //-------------------------------------------------------------
29
30 #include <TList.h>
31 #include <TObjArray.h>
32 #include <TParticle.h>
33
34 #include "AliGenBeamGasNew.h"
35 #include "AliGenCocktail.h" 
36 #include "AliGenCocktailEntry.h"
37 #include "AliGenCocktailEventHeader.h"
38 #include "../THijing/AliGenHijing.h" 
39 #include "AliCollisionGeometry.h"
40 #include "AliRun.h"
41 #include "AliMC.h"
42 #include "AliStack.h"
43 #include "AliLog.h"
44
45 #include "AliHeader.h"
46 #include "AliGenEventHeader.h"
47
48 ClassImp(AliGenBeamGasNew)
49
50 Float_t EtaToTheta(Float_t arg) { return (180./TMath::Pi())*2.*atan(exp(-arg)); }
51
52 AliGenBeamGasNew::AliGenBeamGasNew() : 
53     AliGenCocktail(), 
54     fItime(0), 
55     fTwindow(88e-6), 
56     fZwindow(2000), 
57     fRate(1e3)
58 {
59   // Default constructor
60 }
61
62 AliGenBeamGasNew::~AliGenBeamGasNew()
63 {
64   delete fEntries;
65   delete fHeader;
66 }
67
68 void AliGenBeamGasNew::SetTimeWindow(Float_t twindow) { fTwindow = twindow; }
69
70 bool AliGenBeamGasNew::SetRate(Float_t rate) {
71   if (rate >= 0) {  
72     fRate = rate; 
73     return true;
74   } else
75     return false;
76 }
77
78 void AliGenBeamGasNew::SetZWindow(Float_t zwindow) { fZwindow = zwindow; }
79
80 void AliGenBeamGasNew::Init()
81 {
82   //  Initialisation of the class
83   //  if no generators were added before calling Init()
84   //  AliGenHijing is added configured for pO
85
86   fVertexSmear = kPerEvent;
87   fVertexSource = kInternal;
88   fRandom = kTRUE;
89
90   // Adding default underlying event in case none was specified
91   // p-O-collision at 7 TeV (fixed target)
92   if (!fEntries) {
93     AliGenHijing *gen = new AliGenHijing(-1);
94     gen->SetReferenceFrame("LAB");
95     gen->SetEnergyCMS(7000);
96     gen->SetProjectile("P",1,1);
97     gen->SetTarget("A",16,8);
98     gen->SetPhiRange(0,360);
99     Float_t thmin = EtaToTheta(8);
100     Float_t thmax = EtaToTheta(-8);
101     gen->SetThetaRange(thmin, thmax);
102     gen->SetOrigin(0,0,0);
103     gen->SetSigma(0,0,0);
104     gen->KeepFullEvent();
105     gen->SetShadowing(1);
106     gen->SetDecaysOff(1);
107     gen->SetSpectators(1);
108     gen->SetSelectAll(1);
109     gen->SetRandomPz(kFALSE);
110     gen->SetPileUpTimeWindow(0.);
111     AddGenerator(gen,"Hijing pO",1);
112   }
113
114   TIter next(fEntries);
115   AliGenCocktailEntry *entry;
116
117   // Loop over generators and initialize
118   while((entry = (AliGenCocktailEntry*)next())) {
119     if (fStack)  entry->Generator()->SetStack(fStack);
120     entry->Generator()->Init();
121   }  
122   
123   next.Reset();
124   
125   if (fRandom) {
126     fProb.Set(fNGenerators);
127     next.Reset();
128     Float_t sum = 0.;
129     while((entry = (AliGenCocktailEntry*)next())) {
130       sum += entry->Rate();
131     } 
132     
133     next.Reset();
134     Int_t i = 0;
135     Float_t psum = 0.;
136     while((entry = (AliGenCocktailEntry*)next())) {
137       psum +=  entry->Rate() / sum;
138       fProb[i++] = psum;
139     }
140   }
141   next.Reset();
142 }
143
144 void AliGenBeamGasNew::VertexInternal()
145 {
146   // calculation of the interaction vertex for the beam gas event
147   // both spatial and time coordinate are adjusted.
148   
149   Float_t random[2];
150   Float_t nbunch;
151   Float_t bunch;
152   
153   gRandom->RndmArray(2,random);
154   fVertex[0] = fVertex[1] = 0;
155   fVertex[2] = random[0] * 2 * fZwindow - fZwindow;
156   nbunch = fTwindow/25e-9;
157   bunch = floor(2*nbunch * random[1] - nbunch);
158   fItime = fVertex[2] / 100 / 3e8 + bunch * 25e-9;
159   AliInfo(Form("fItime: %13.3e \n", fItime));
160 }
161
162 void AliGenBeamGasNew::Generate()
163 {
164 //    
165 // Generate the collisions for one event
166 //
167   Int_t numbg = gRandom->Poisson(fRate*fZwindow/100*2*fTwindow);
168   if (numbg == 0) return;
169   
170   TIter next(fEntries);
171   AliGenCocktailEntry *entry = 0;
172   AliGenCocktailEntry *preventry = 0;
173   AliGenerator* gen = 0;
174   TLorentzVector v;
175   TArrayF eventVertex;
176   Int_t lastpart=0;
177   Float_t sign;
178   
179   if (fHeader) delete fHeader;
180   fHeader = new AliGenCocktailEventHeader("Beamgas Header");
181   
182   TObjArray *partArray = gAlice->GetMCApp()->Particles();
183   AliStack *stack = gAlice->GetRunLoader()->Stack();
184   
185   for (Int_t l = 0; l < numbg; l++) {
186     Vertex();
187     sign = (gRandom->Rndm() < 0.5)? -1. : 1.;
188     eventVertex.Set(3);
189     for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];
190     
191     if (!fRandom) {
192       Int_t igen=0;
193       while((entry = (AliGenCocktailEntry*)next())) {
194         if (fUsePerEventRate && (gRandom->Rndm() > entry->Rate())) continue;
195         
196         igen++;
197         if (igen ==1) {
198           entry->SetFirst(lastpart);
199         } else {
200           entry->SetFirst((partArray->GetEntriesFast())+1);
201         }
202         //
203         //      Handle case in which current generator needs collision geometry from previous generator
204         //
205         gen = entry->Generator();
206         if (gen->NeedsCollisionGeometry())
207           {
208             if (preventry && preventry->Generator()->ProvidesCollisionGeometry())
209               {
210                 gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry());
211               } else {
212                 Fatal("Generate()", "No Collision Geometry Provided");
213               }
214           }
215         entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
216         entry->Generator()->Generate();
217         entry->SetLast(partArray->GetEntriesFast());
218         preventry = entry;
219       }  
220     } else {
221       //
222       // Select a generator randomly
223       //
224       Int_t i;
225       Float_t p0 =  gRandom->Rndm();
226       
227       for (i = 0; i < fNGenerators; i++) {
228         if (p0 < fProb[i]) break;
229       }
230       
231       entry = (AliGenCocktailEntry*) fEntries->At(i);
232       entry->SetFirst(lastpart);
233       gen = entry->Generator();
234       entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
235       entry->Generator()->Generate();
236       entry->SetLast(partArray->GetEntriesFast());
237     } 
238     
239     for (int k = lastpart; k < stack->GetNprimary(); k++) {
240       stack->Particle(k)->ProductionVertex(v);
241       v[2] *= sign;
242       v[3] = fItime;  // ??? +=
243       stack->Particle(k)->SetProductionVertex(v);
244       stack->Particle(k)->Momentum(v);
245       v[2] *= sign;
246       stack->Particle(k)->SetMomentum(v);
247     }
248
249     lastpart = stack->GetNprimary();
250     next.Reset();
251   } 
252   // Event Vertex
253   fHeader->SetPrimaryVertex(eventVertex);
254   fHeader->CalcNProduced();
255
256   if (fContainer) {
257     fContainer->AddHeader(fHeader);
258   } else {
259     gAlice->SetGenEventHeader(fHeader); 
260   }
261 }