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