In stand-allone mode, pass stack to entries.
[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
35 ClassImp(AliGenCocktail)
36
37 AliGenCocktail::AliGenCocktail()
38                  :AliGenerator()
39 {
40 // Constructor
41     fName = "Cocktail";
42     fTitle= "Particle Generator using cocktail of generators";
43     flnk1 = 0;
44     flnk2 = 0;
45     fNGenerators=0;
46     fEntries = 0;
47     
48 }
49
50 AliGenCocktail::AliGenCocktail(const AliGenCocktail & cocktail):
51     AliGenerator(cocktail)
52 {
53 // Copy constructor
54     cocktail.Copy(*this);
55 }
56
57 AliGenCocktail::~AliGenCocktail()
58 {
59 // Destructor
60     delete fEntries;
61 }
62
63 void AliGenCocktail::
64 AddGenerator(AliGenerator *Generator, const char* Name, Float_t RateExp)
65 {
66 //
67 // Add a generator to the list 
68 // First check that list exists
69     if (!fEntries) fEntries = new TList();
70
71 //
72 //  Forward parameters to the new generator
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());
84     if (!(Generator->TestBit(kVertexRange))) 
85         Generator->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
86
87     Generator->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
88     Generator->SetVertexSmear(fVertexSmear);
89     Generator->SetVertexSource(kContainer);
90     Generator->SetTrackingFlag(fTrackIt);
91         
92 //
93 //  Add generator to list   
94     char theName[256];
95     sprintf(theName, "%s_%d",Name, fNGenerators);
96     Generator->SetName(theName);
97
98     AliGenCocktailEntry *entry = 
99         new AliGenCocktailEntry(Generator, Name, RateExp);
100     
101      fEntries->Add(entry);
102      fNGenerators++;
103  }
104
105   void AliGenCocktail::Init()
106 {
107 // Initialisation
108     TIter next(fEntries);
109     AliGenCocktailEntry *entry;
110     //
111     // Loop over generators and initialize
112     while((entry = (AliGenCocktailEntry*)next())) {
113         if (fStack)  entry->Generator()->SetStack(fStack);
114         entry->Generator()->Init();
115     }  
116 }
117
118   void AliGenCocktail::FinishRun()
119 {
120 // Initialisation
121     TIter next(fEntries);
122     AliGenCocktailEntry *entry;
123     //
124     // Loop over generators and initialize
125     while((entry = (AliGenCocktailEntry*)next())) {
126         entry->Generator()->FinishRun();
127     }  
128 }
129
130  void AliGenCocktail::Generate()
131 {
132 //
133 // Generate event 
134     TIter next(fEntries);
135     AliGenCocktailEntry *entry = 0;
136     AliGenCocktailEntry *preventry = 0;
137     AliGenerator* gen = 0;
138
139     TObjArray *partArray = gAlice->GetMCApp()->Particles();
140
141 //
142 //  Generate the vertex position used by all generators
143 //    
144     if(fVertexSmear == kPerEvent) Vertex();
145
146     
147   //
148     // Loop over generators and generate events
149     Int_t igen=0;
150     
151     while((entry = (AliGenCocktailEntry*)next())) {
152         igen++;
153         if (igen ==1) {
154             entry->SetFirst(0);
155         } else {
156             entry->SetFirst((partArray->GetEntriesFast())+1);
157         }
158 //
159 //      Handle case in which current generator needs collision geometry from previous generator
160 //
161         gen = entry->Generator();
162         if (gen->NeedsCollisionGeometry())
163         {
164             if (preventry && preventry->Generator()->ProvidesCollisionGeometry())
165             {
166                 gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry());
167             } else {
168                 Fatal("Generate()", "No Collision Geometry Provided");
169             }
170         }
171         entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
172         entry->Generator()->Generate();
173         entry->SetLast(partArray->GetEntriesFast());
174         preventry = entry;
175     }  
176     next.Reset();
177 }
178
179 AliGenCocktailEntry *  AliGenCocktail::FirstGenerator()
180 {
181 // Iterator over generators: Initialisation
182     flnk1 = fEntries->FirstLink();
183     if (flnk1) {
184         return (AliGenCocktailEntry*) (flnk1->GetObject());
185     } else {
186         return 0;
187     }
188 }
189
190 AliGenCocktailEntry*  AliGenCocktail::NextGenerator()
191 {
192 // Iterator over generators: Increment
193     flnk1 = flnk1->Next();
194     if (flnk1) {
195         return (AliGenCocktailEntry*) (flnk1->GetObject());
196     } else {
197         return 0;
198     }
199 }
200
201 void AliGenCocktail::
202 FirstGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
203 {
204 // Iterator over generator pairs: Initialisation
205     flnk2 = flnk1 = fEntries->FirstLink();
206     if (flnk1) {
207         e2 = e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
208     } else {
209         e2= e1 = 0;
210     }
211 }
212
213 void AliGenCocktail::
214 NextGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
215 {
216 // Iterator over generators: Increment
217     flnk2 = flnk2->Next();
218     if (flnk2) {
219         e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
220         e2 = (AliGenCocktailEntry*) (flnk2->GetObject());       
221     } else {
222         flnk2 = flnk1 = flnk1->Next();
223         if (flnk1) {
224             e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
225             e2 = (AliGenCocktailEntry*) (flnk2->GetObject());
226         } else {
227             e1=0;
228             e2=0;
229         }
230     }
231 }
232
233 AliGenCocktail& AliGenCocktail::operator=(const  AliGenCocktail& rhs)
234 {
235 // Assignment operator
236     rhs.Copy(*this); 
237     return (*this);
238 }
239
240 void AliGenCocktail::Copy(TObject &) const
241 {
242     Fatal("Copy","Not implemented!\n");
243 }
244
245
246