Line data Source code
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 : // 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 :
26 : #include <TList.h>
27 : #include <TObjArray.h>
28 : #include <TFormula.h>
29 :
30 : #include "AliGenCocktail.h"
31 : #include "AliGenCocktailEntry.h"
32 : #include "AliCollisionGeometry.h"
33 : #include "AliRun.h"
34 : #include "AliLog.h"
35 : #include "AliMC.h"
36 : #include "AliGenCocktailEventHeader.h"
37 :
38 6 : ClassImp(AliGenCocktail)
39 :
40 : AliGenCocktail::AliGenCocktail()
41 13 : :AliGenerator(),
42 13 : fNGenerators(0),
43 13 : fTotalRate(0.),
44 13 : fSRandom(kFALSE),
45 13 : fUsePerEventRate(kFALSE),
46 13 : fProb(0),
47 13 : fEntries(0),
48 13 : flnk1(0),
49 13 : flnk2(0),
50 13 : fHeader(0),
51 13 : fSeed(0)
52 65 : {
53 : // Constructor
54 13 : fName = "Cocktail";
55 13 : fTitle= "Particle Generator using cocktail of generators";
56 26 : }
57 :
58 0 : AliGenCocktail::~AliGenCocktail()
59 78 : {
60 : // Destructor
61 26 : delete fEntries;
62 13 : fEntries = 0;
63 : // delete fHeader; // It is removed in AliRunLoader
64 13 : fHeader = 0;
65 39 : }
66 :
67 : void AliGenCocktail::
68 : AddGenerator(AliGenerator *Generator, const char* Name, Float_t RateExp, TFormula* formula, Int_t ntimes)
69 : {
70 : //
71 : // Add a generator to the list
72 : // First check that list exists
73 58 : if (!fEntries) fEntries = new TList();
74 28 : fTotalRate += RateExp;
75 : //
76 : // Forward parameters to the new generator
77 28 : if(TestBit(kPtRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange)))
78 0 : Generator->SetPtRange(fPtMin,fPtMax);
79 28 : if(TestBit(kMomentumRange) && !(Generator->TestBit(kPtRange)) && !(Generator->TestBit(kMomentumRange)))
80 0 : Generator->SetMomentumRange(fPMin,fPMax);
81 :
82 28 : if (TestBit(kYRange) && !(Generator->TestBit(kYRange)))
83 0 : Generator->SetYRange(fYMin,fYMax);
84 56 : if (TestBit(kPhiRange) && !(Generator->TestBit(kPhiRange)))
85 0 : Generator->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi());
86 56 : if (TestBit(kThetaRange) && !(Generator->TestBit(kThetaRange)) && !(Generator->TestBit(kEtaRange)))
87 0 : Generator->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi());
88 28 : if (!(Generator->TestBit(kVertexRange))) {
89 28 : Generator->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
90 28 : Generator->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
91 28 : Generator->SetVertexSmear(fVertexSmear);
92 28 : Generator->SetVertexSource(kContainer);
93 28 : }
94 28 : Generator->SetTrackingFlag(fTrackIt);
95 28 : Generator->SetContainer(this);
96 :
97 :
98 : //
99 : // Add generator to list
100 28 : char theName[256];
101 28 : snprintf(theName, 256, "%s_%d",Name, fNGenerators);
102 28 : Generator->SetName(theName);
103 :
104 : AliGenCocktailEntry *entry =
105 28 : new AliGenCocktailEntry(Generator, Name, RateExp);
106 28 : if (formula) entry->SetFormula(formula);
107 28 : entry->SetNTimes(ntimes);
108 28 : fEntries->Add(entry);
109 28 : fNGenerators++;
110 28 : flnk1 = 0;
111 28 : flnk2 = 0;
112 28 : fSRandom = kFALSE;
113 28 : fHeader = 0;
114 28 : }
115 :
116 : void AliGenCocktail::Init()
117 : {
118 : // Initialisation
119 2 : TIter next(fEntries);
120 : AliGenCocktailEntry *entry;
121 : //
122 : // Loop over generators and initialize
123 59 : while((entry = (AliGenCocktailEntry*)next())) {
124 28 : if (fStack) entry->Generator()->SetStack(fStack);
125 28 : entry->Generator()->SetSeed(fSeed);
126 28 : entry->Generator()->Init();
127 : }
128 :
129 1 : next.Reset();
130 :
131 1 : if (fSRandom) {
132 0 : fProb.Set(fNGenerators);
133 0 : next.Reset();
134 : Float_t sum = 0.;
135 0 : while((entry = (AliGenCocktailEntry*)next())) {
136 0 : sum += entry->Rate();
137 : }
138 :
139 0 : next.Reset();
140 : Int_t i = 0;
141 : Float_t psum = 0.;
142 0 : while((entry = (AliGenCocktailEntry*)next())) {
143 0 : psum += entry->Rate() / sum;
144 0 : fProb[i++] = psum;
145 : }
146 0 : }
147 1 : next.Reset();
148 1 : }
149 :
150 : void AliGenCocktail::FinishRun()
151 : {
152 : // Initialisation
153 2 : TIter next(fEntries);
154 : AliGenCocktailEntry *entry;
155 : //
156 : // Loop over generators and initialize
157 59 : while((entry = (AliGenCocktailEntry*)next())) {
158 28 : entry->Generator()->FinishRun();
159 : }
160 1 : }
161 :
162 : void AliGenCocktail::Generate()
163 : {
164 : //
165 : // Generate event
166 8 : TIter next(fEntries);
167 : AliGenCocktailEntry *entry = 0;
168 : AliGenCocktailEntry *preventry = 0;
169 : AliGenCocktailEntry *collentry = 0;
170 : AliGenerator* gen = 0;
171 10 : if (fHeader) delete fHeader;
172 :
173 :
174 12 : fHeader = new AliGenCocktailEventHeader("Cocktail Header");
175 :
176 4 : const TObjArray *partArray = gAlice->GetMCApp()->Particles();
177 :
178 : //
179 : // Generate the vertex position used by all generators
180 : //
181 4 : if(fVertexSmear == kPerEvent) Vertex();
182 :
183 4 : TArrayF eventVertex;
184 4 : eventVertex.Set(3);
185 56 : for (Int_t j=0; j < 3; j++) eventVertex[j] = fVertex[j];
186 :
187 4 : if (!fSRandom) {
188 : //
189 : // Loop over generators and generate events
190 : Int_t igen = 0;
191 236 : while((entry = (AliGenCocktailEntry*)next())) {
192 112 : Int_t ntimes = entry->NTimes();
193 112 : if (fUsePerEventRate && (gRandom->Rndm() > entry->Rate())) continue;
194 :
195 112 : igen++;
196 112 : if (igen ==1) {
197 4 : entry->SetFirst(0);
198 4 : } else {
199 216 : entry->SetFirst((partArray->GetEntriesFast())+1);
200 : }
201 112 : gen = entry->Generator();
202 224 : if (gen->ProvidesCollisionGeometry()) collentry = entry;
203 : //
204 : // Handle case in which current generator needs collision geometry from previous generator
205 : //
206 224 : if (gen->NeedsCollisionGeometry() && (entry->Formula() == 0))
207 : {
208 0 : if (preventry && preventry->Generator()->ProvidesCollisionGeometry())
209 : {
210 0 : gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry());
211 : } else {
212 0 : Fatal("Generate()", "No Collision Geometry Provided");
213 : }
214 : }
215 : //
216 : // Number of signals is calculated from Collision Geometry
217 : // and entry with given centrality bin is selected
218 : //
219 112 : if (entry->Formula() != 0)
220 : {
221 0 : if (!collentry) {
222 0 : Fatal("Generate()", "No Collision Geometry Provided");
223 0 : return;
224 : }
225 0 : AliCollisionGeometry* coll = (collentry->Generator())->CollisionGeometry();
226 0 : Float_t b = coll->ImpactParameter();
227 0 : Int_t nsig = Int_t(entry->Formula()->Eval(b));
228 0 : Int_t bin = entry->Bin() - 100;
229 0 : if (bin > 0) {
230 0 : if (bin != nsig) continue;
231 : } else {
232 0 : if (nsig < 1) nsig = 1;
233 0 : AliInfo(Form("Signal Events %13.3f %5d %5d\n", b, coll->HardScatters(), nsig));
234 : ntimes = nsig;
235 : }
236 0 : }
237 448 : gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2), fTime);
238 :
239 112 : gen->GenerateN(ntimes);
240 224 : entry->SetLast(partArray->GetEntriesFast());
241 : preventry = entry;
242 112 : }
243 4 : } else if (fSRandom) {
244 : //
245 : // Select a generator randomly
246 : //
247 : Int_t i;
248 0 : Float_t p0 = gRandom->Rndm();
249 :
250 0 : for (i = 0; i < fNGenerators; i++) {
251 0 : if (p0 < fProb[i]) break;
252 : }
253 :
254 0 : entry = (AliGenCocktailEntry*) fEntries->At(i);
255 0 : entry->SetFirst(0);
256 0 : gen = entry->Generator();
257 0 : gen->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2), fTime);
258 0 : gen->Generate();
259 0 : entry->SetLast(partArray->GetEntriesFast());
260 0 : }
261 :
262 4 : next.Reset();
263 :
264 : // Event Vertex
265 4 : fHeader->SetPrimaryVertex(eventVertex);
266 4 : fHeader->CalcNProduced();
267 4 : if (fContainer) {
268 0 : fHeader->SetName(fName);
269 0 : fContainer->AddHeader(fHeader);
270 : } else {
271 4 : gAlice->SetGenEventHeader(fHeader);
272 : }
273 8 : }
274 :
275 : void AliGenCocktail::SetVertexSmear(VertexSmear_t smear)
276 : {
277 : // Set vertex smearing and propagate it to the generators
278 :
279 0 : AliGenerator::SetVertexSmear(smear);
280 0 : TIter next(fEntries);
281 0 : while (AliGenCocktailEntry* entry = (AliGenCocktailEntry*)next()) {
282 0 : entry->Generator()->SetVertexSmear(smear);
283 0 : }
284 0 : }
285 :
286 : AliGenCocktailEntry * AliGenCocktail::FirstGenerator()
287 : {
288 : // Iterator over generators: Initialisation
289 0 : flnk1 = fEntries->FirstLink();
290 0 : if (flnk1) {
291 0 : return (AliGenCocktailEntry*) (flnk1->GetObject());
292 : } else {
293 0 : return 0;
294 : }
295 0 : }
296 :
297 : AliGenCocktailEntry* AliGenCocktail::NextGenerator()
298 : {
299 : // Iterator over generators: Increment
300 0 : flnk1 = flnk1->Next();
301 0 : if (flnk1) {
302 0 : return (AliGenCocktailEntry*) (flnk1->GetObject());
303 : } else {
304 0 : return 0;
305 : }
306 0 : }
307 :
308 : void AliGenCocktail::
309 : FirstGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
310 : {
311 : // Iterator over generator pairs: Initialisation
312 0 : flnk2 = flnk1 = fEntries->FirstLink();
313 0 : if (flnk1) {
314 0 : e2 = e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
315 0 : } else {
316 0 : e2= e1 = 0;
317 : }
318 0 : }
319 :
320 : void AliGenCocktail::
321 : NextGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
322 : {
323 : // Iterator over generators: Increment
324 0 : flnk2 = flnk2->Next();
325 0 : if (flnk2) {
326 0 : e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
327 0 : e2 = (AliGenCocktailEntry*) (flnk2->GetObject());
328 0 : } else {
329 0 : flnk2 = flnk1 = flnk1->Next();
330 0 : if (flnk1) {
331 0 : e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
332 0 : e2 = (AliGenCocktailEntry*) (flnk2->GetObject());
333 0 : } else {
334 0 : e1=0;
335 0 : e2=0;
336 : }
337 : }
338 0 : }
339 :
340 : void AliGenCocktail::AddHeader(AliGenEventHeader* header)
341 : {
342 : // Add a header to the list
343 48 : if (fHeader) fHeader->AddHeader(header);
344 16 : }
345 :
346 :
347 :
348 :
|