4c039060 |
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 | |
88cb7938 |
16 | /* $Id$ */ |
4c039060 |
17 | |
675e9664 |
18 | // Container class for AliGenerator through recursion. |
19 | // Container is itself an AliGenerator. |
20 | // What is stored are not the pointers to the generators directly but to objects of type |
21 | // AliGenCocktail entry. |
22 | // The class provides also iterator functionality. |
23 | // Author: andreas.morsch@cern.ch |
24 | // |
25 | |
116cbefd |
26 | #include <TList.h> |
27 | #include <TObjArray.h> |
28 | |
fe4da5cc |
29 | #include "AliGenCocktail.h" |
374924b5 |
30 | #include "AliGenCocktailEntry.h" |
09e2e187 |
31 | #include "AliCollisionGeometry.h" |
fe4da5cc |
32 | #include "AliRun.h" |
5d12ce38 |
33 | #include "AliMC.h" |
4f85aa78 |
34 | #include "AliGenCocktailEventHeader.h" |
fe4da5cc |
35 | |
36 | ClassImp(AliGenCocktail) |
37 | |
38 | AliGenCocktail::AliGenCocktail() |
1c56e311 |
39 | :AliGenerator(), |
40 | fNGenerators(0), |
41 | fRandom(kFALSE), |
42 | fUsePerEventRate(kFALSE), |
43 | fProb(0), |
44 | fEntries(0), |
45 | flnk1(0), |
46 | flnk2(0), |
47 | fHeader(0) |
fe4da5cc |
48 | { |
374924b5 |
49 | // Constructor |
8b31bfac |
50 | fName = "Cocktail"; |
51 | fTitle= "Particle Generator using cocktail of generators"; |
fe4da5cc |
52 | } |
53 | |
fe4da5cc |
54 | AliGenCocktail::~AliGenCocktail() |
55 | { |
374924b5 |
56 | // Destructor |
fe4da5cc |
57 | delete fEntries; |
373c1a55 |
58 | fEntries = 0; |
59 | // delete fHeader; // It is removed in AliRunLoader |
60 | fHeader = 0; |
fe4da5cc |
61 | } |
62 | |
63 | void AliGenCocktail:: |
a764b7de |
64 | AddGenerator(AliGenerator *Generator, const char* Name, Float_t RateExp) |
fe4da5cc |
65 | { |
b1403e15 |
66 | // |
67 | // Add a generator to the list |
68 | // First check that list exists |
69 | if (!fEntries) fEntries = new TList(); |
70 | |
fe4da5cc |
71 | // |
72 | // Forward parameters to the new generator |
212bcf04 |
73 | if(TestBit(kPtRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange))) |
74 | Generator->SetPtRange(fPtMin,fPtMax); |
75 | if(TestBit(kMomentumRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange))) |
76 | Generator->SetMomentumRange(fPMin,fPMax); |
77 | |
78 | if (!(Generator->TestBit(kYRange))) |
79 | Generator->SetYRange(fYMin,fYMax); |
80 | if (!(Generator->TestBit(kPhiRange))) |
81 | Generator->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi()); |
82 | if (!(Generator->TestBit(kThetaRange))) |
83 | Generator->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi()); |
4a6ca8fc |
84 | if (!(Generator->TestBit(kVertexRange))) { |
212bcf04 |
85 | Generator->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]); |
4a6ca8fc |
86 | Generator->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]); |
87 | Generator->SetVertexSmear(fVertexSmear); |
88 | Generator->SetVertexSource(kContainer); |
89 | } |
c8f7f6f9 |
90 | Generator->SetTrackingFlag(fTrackIt); |
4f85aa78 |
91 | Generator->SetContainer(this); |
92 | |
c97002cc |
93 | |
fe4da5cc |
94 | // |
95 | // Add generator to list |
c5c3e4b0 |
96 | char theName[256]; |
97 | sprintf(theName, "%s_%d",Name, fNGenerators); |
98 | Generator->SetName(theName); |
99 | |
374924b5 |
100 | AliGenCocktailEntry *entry = |
fe4da5cc |
101 | new AliGenCocktailEntry(Generator, Name, RateExp); |
c5c3e4b0 |
102 | |
374924b5 |
103 | fEntries->Add(entry); |
fe4da5cc |
104 | fNGenerators++; |
373c1a55 |
105 | flnk1 = 0; |
106 | flnk2 = 0; |
107 | fRandom = kFALSE; |
108 | fHeader = 0; |
109 | } |
fe4da5cc |
110 | |
111 | void AliGenCocktail::Init() |
374924b5 |
112 | { |
113 | // Initialisation |
114 | TIter next(fEntries); |
115 | AliGenCocktailEntry *entry; |
116 | // |
117 | // Loop over generators and initialize |
118 | while((entry = (AliGenCocktailEntry*)next())) { |
c97002cc |
119 | if (fStack) entry->Generator()->SetStack(fStack); |
374924b5 |
120 | entry->Generator()->Init(); |
121 | } |
1ebe6dc8 |
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(); |
374924b5 |
142 | } |
fe4da5cc |
143 | |
09e2e187 |
144 | void AliGenCocktail::FinishRun() |
145 | { |
146 | // Initialisation |
147 | TIter next(fEntries); |
148 | AliGenCocktailEntry *entry; |
149 | // |
150 | // Loop over generators and initialize |
151 | while((entry = (AliGenCocktailEntry*)next())) { |
152 | entry->Generator()->FinishRun(); |
153 | } |
154 | } |
155 | |
fe4da5cc |
156 | void AliGenCocktail::Generate() |
374924b5 |
157 | { |
158 | // |
159 | // Generate event |
160 | TIter next(fEntries); |
a8408367 |
161 | AliGenCocktailEntry *entry = 0; |
162 | AliGenCocktailEntry *preventry = 0; |
163 | AliGenerator* gen = 0; |
4f85aa78 |
164 | if (fHeader) delete fHeader; |
c89fc3f1 |
165 | |
166 | |
4f85aa78 |
167 | fHeader = new AliGenCocktailEventHeader("Cocktail Header"); |
09e2e187 |
168 | |
5d12ce38 |
169 | TObjArray *partArray = gAlice->GetMCApp()->Particles(); |
c8f7f6f9 |
170 | |
171 | // |
172 | // Generate the vertex position used by all generators |
173 | // |
174 | if(fVertexSmear == kPerEvent) Vertex(); |
175 | |
67db3ff2 |
176 | TArrayF eventVertex; |
177 | eventVertex.Set(3); |
178 | for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j]; |
179 | |
1ebe6dc8 |
180 | if (!fRandom) { |
181 | // |
182 | // Loop over generators and generate events |
183 | Int_t igen=0; |
1ebe6dc8 |
184 | while((entry = (AliGenCocktailEntry*)next())) { |
c89fc3f1 |
185 | if (fUsePerEventRate && (gRandom->Rndm() > entry->Rate())) continue; |
186 | |
1ebe6dc8 |
187 | igen++; |
188 | if (igen ==1) { |
189 | entry->SetFirst(0); |
190 | } else { |
191 | entry->SetFirst((partArray->GetEntriesFast())+1); |
192 | } |
a8408367 |
193 | // |
194 | // Handle case in which current generator needs collision geometry from previous generator |
195 | // |
1ebe6dc8 |
196 | gen = entry->Generator(); |
197 | if (gen->NeedsCollisionGeometry()) |
a8408367 |
198 | { |
1ebe6dc8 |
199 | if (preventry && preventry->Generator()->ProvidesCollisionGeometry()) |
200 | { |
201 | gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry()); |
202 | } else { |
203 | Fatal("Generate()", "No Collision Geometry Provided"); |
204 | } |
a8408367 |
205 | } |
1ebe6dc8 |
206 | entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2)); |
207 | entry->Generator()->Generate(); |
208 | entry->SetLast(partArray->GetEntriesFast()); |
209 | preventry = entry; |
210 | } |
c89fc3f1 |
211 | } else if (fRandom) { |
1ebe6dc8 |
212 | // |
213 | // Select a generator randomly |
214 | // |
215 | Int_t i; |
216 | Float_t p0 = gRandom->Rndm(); |
217 | |
218 | for (i = 0; i < fNGenerators; i++) { |
219 | if (p0 < fProb[i]) break; |
a8408367 |
220 | } |
1ebe6dc8 |
221 | |
222 | entry = (AliGenCocktailEntry*) fEntries->At(i); |
223 | entry->SetFirst(0); |
224 | gen = entry->Generator(); |
c8f7f6f9 |
225 | entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2)); |
374924b5 |
226 | entry->Generator()->Generate(); |
227 | entry->SetLast(partArray->GetEntriesFast()); |
c89fc3f1 |
228 | } |
1ebe6dc8 |
229 | |
374924b5 |
230 | next.Reset(); |
4f85aa78 |
231 | |
67db3ff2 |
232 | // Event Vertex |
4f85aa78 |
233 | fHeader->SetPrimaryVertex(eventVertex); |
234 | gAlice->SetGenEventHeader(fHeader); |
374924b5 |
235 | } |
fe4da5cc |
236 | |
c44d1c08 |
237 | void AliGenCocktail::SetVertexSmear(VertexSmear_t smear) |
238 | { |
239 | // Set vertex smearing and propagate it to the generators |
240 | |
241 | AliGenerator::SetVertexSmear(smear); |
242 | TIter next(fEntries); |
243 | while (AliGenCocktailEntry* entry = (AliGenCocktailEntry*)next()) { |
244 | entry->Generator()->SetVertexSmear(smear); |
245 | } |
246 | } |
247 | |
fe4da5cc |
248 | AliGenCocktailEntry * AliGenCocktail::FirstGenerator() |
249 | { |
374924b5 |
250 | // Iterator over generators: Initialisation |
fe4da5cc |
251 | flnk1 = fEntries->FirstLink(); |
252 | if (flnk1) { |
253 | return (AliGenCocktailEntry*) (flnk1->GetObject()); |
254 | } else { |
255 | return 0; |
256 | } |
257 | } |
258 | |
259 | AliGenCocktailEntry* AliGenCocktail::NextGenerator() |
260 | { |
374924b5 |
261 | // Iterator over generators: Increment |
fe4da5cc |
262 | flnk1 = flnk1->Next(); |
263 | if (flnk1) { |
264 | return (AliGenCocktailEntry*) (flnk1->GetObject()); |
265 | } else { |
266 | return 0; |
267 | } |
268 | } |
269 | |
270 | void AliGenCocktail:: |
271 | FirstGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2) |
272 | { |
374924b5 |
273 | // Iterator over generator pairs: Initialisation |
fe4da5cc |
274 | flnk2 = flnk1 = fEntries->FirstLink(); |
275 | if (flnk1) { |
276 | e2 = e1 = (AliGenCocktailEntry*) (flnk1->GetObject()); |
277 | } else { |
278 | e2= e1 = 0; |
279 | } |
280 | } |
281 | |
282 | void AliGenCocktail:: |
283 | NextGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2) |
284 | { |
374924b5 |
285 | // Iterator over generators: Increment |
fe4da5cc |
286 | flnk2 = flnk2->Next(); |
287 | if (flnk2) { |
288 | e1 = (AliGenCocktailEntry*) (flnk1->GetObject()); |
289 | e2 = (AliGenCocktailEntry*) (flnk2->GetObject()); |
290 | } else { |
291 | flnk2 = flnk1 = flnk1->Next(); |
292 | if (flnk1) { |
293 | e1 = (AliGenCocktailEntry*) (flnk1->GetObject()); |
294 | e2 = (AliGenCocktailEntry*) (flnk2->GetObject()); |
295 | } else { |
296 | e1=0; |
297 | e2=0; |
298 | } |
299 | } |
300 | } |
301 | |
4f85aa78 |
302 | void AliGenCocktail::AddHeader(AliGenEventHeader* header) |
303 | { |
304 | // Add a header to the list |
305 | if (fHeader) fHeader->AddHeader(header); |
306 | } |
fe4da5cc |
307 | |
198bb1c7 |
308 | |
309 | |
fe4da5cc |
310 | |