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