Constant magnetic field in barrel. (A. Dainese)
[u/mrichter/AliRoot.git] / EVGEN / AliGenCocktail.cxx
CommitLineData
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
36ClassImp(AliGenCocktail)
37
38AliGenCocktail::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 52AliGenCocktail::AliGenCocktail(const AliGenCocktail & cocktail):
53 AliGenerator(cocktail)
374924b5 54{
198bb1c7 55// Copy constructor
56 cocktail.Copy(*this);
374924b5 57}
fe4da5cc 58
59AliGenCocktail::~AliGenCocktail()
60{
374924b5 61// Destructor
fe4da5cc 62 delete fEntries;
4f85aa78 63 delete fHeader;
fe4da5cc 64}
65
66void AliGenCocktail::
a764b7de 67AddGenerator(AliGenerator *Generator, const char* Name, Float_t RateExp)
fe4da5cc 68{
69//
b1403e15 70// Add a generator to the list
71// First check that list exists
72 if (!fEntries) fEntries = new TList();
73
74//
fe4da5cc 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 234void 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 245AliGenCocktailEntry * 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
256AliGenCocktailEntry* 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
267void AliGenCocktail::
268FirstGeneratorPair(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
279void AliGenCocktail::
280NextGeneratorPair(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 299void AliGenCocktail::AddHeader(AliGenEventHeader* header)
300{
301// Add a header to the list
302 if (fHeader) fHeader->AddHeader(header);
303}
304
374924b5 305AliGenCocktail& AliGenCocktail::operator=(const AliGenCocktail& rhs)
306{
307// Assignment operator
198bb1c7 308 rhs.Copy(*this);
309 return (*this);
fe4da5cc 310}
311
dc1d768c 312void AliGenCocktail::Copy(TObject &) const
198bb1c7 313{
314 Fatal("Copy","Not implemented!\n");
315}
316
317
fe4da5cc 318