ce2e5edc743496ea143f27ca4aeccae6d889ad60
[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 //  Add generator to list   
93     char theName[256];
94     sprintf(theName, "%s_%d",Name, fNGenerators);
95     Generator->SetName(theName);
96
97     AliGenCocktailEntry *entry = 
98         new AliGenCocktailEntry(Generator, Name, RateExp);
99     
100      fEntries->Add(entry);
101      fNGenerators++;
102  }
103
104   void AliGenCocktail::Init()
105 {
106 // Initialisation
107     TIter next(fEntries);
108     AliGenCocktailEntry *entry;
109     //
110     // Loop over generators and initialize
111     while((entry = (AliGenCocktailEntry*)next())) {
112         entry->Generator()->Init();
113     }  
114 }
115
116   void AliGenCocktail::FinishRun()
117 {
118 // Initialisation
119     TIter next(fEntries);
120     AliGenCocktailEntry *entry;
121     //
122     // Loop over generators and initialize
123     while((entry = (AliGenCocktailEntry*)next())) {
124         entry->Generator()->FinishRun();
125     }  
126 }
127
128  void AliGenCocktail::Generate()
129 {
130 //
131 // Generate event 
132     TIter next(fEntries);
133     AliGenCocktailEntry *entry = 0;
134     AliGenCocktailEntry *preventry = 0;
135     AliGenerator* gen = 0;
136
137     TObjArray *partArray = gAlice->GetMCApp()->Particles();
138
139 //
140 //  Generate the vertex position used by all generators
141 //    
142     if(fVertexSmear == kPerEvent) Vertex();
143
144     
145   //
146     // Loop over generators and generate events
147     Int_t igen=0;
148     
149     while((entry = (AliGenCocktailEntry*)next())) {
150         igen++;
151         if (igen ==1) {
152             entry->SetFirst(0);
153         } else {
154             entry->SetFirst((partArray->GetEntriesFast())+1);
155         }
156 //
157 //      Handle case in which current generator needs collision geometry from previous generator
158 //
159         gen = entry->Generator();
160         if (gen->NeedsCollisionGeometry())
161         {
162             if (preventry && preventry->Generator()->ProvidesCollisionGeometry())
163             {
164                 gen->SetCollisionGeometry(preventry->Generator()->CollisionGeometry());
165             } else {
166                 Fatal("Generate()", "No Collision Geometry Provided");
167             }
168         }
169         entry->Generator()->SetVertex(fVertex.At(0), fVertex.At(1), fVertex.At(2));
170         entry->Generator()->Generate();
171         entry->SetLast(partArray->GetEntriesFast());
172         preventry = entry;
173     }  
174     next.Reset();
175 }
176
177 AliGenCocktailEntry *  AliGenCocktail::FirstGenerator()
178 {
179 // Iterator over generators: Initialisation
180     flnk1 = fEntries->FirstLink();
181     if (flnk1) {
182         return (AliGenCocktailEntry*) (flnk1->GetObject());
183     } else {
184         return 0;
185     }
186 }
187
188 AliGenCocktailEntry*  AliGenCocktail::NextGenerator()
189 {
190 // Iterator over generators: Increment
191     flnk1 = flnk1->Next();
192     if (flnk1) {
193         return (AliGenCocktailEntry*) (flnk1->GetObject());
194     } else {
195         return 0;
196     }
197 }
198
199 void AliGenCocktail::
200 FirstGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
201 {
202 // Iterator over generator pairs: Initialisation
203     flnk2 = flnk1 = fEntries->FirstLink();
204     if (flnk1) {
205         e2 = e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
206     } else {
207         e2= e1 = 0;
208     }
209 }
210
211 void AliGenCocktail::
212 NextGeneratorPair(AliGenCocktailEntry*& e1, AliGenCocktailEntry*& e2)
213 {
214 // Iterator over generators: Increment
215     flnk2 = flnk2->Next();
216     if (flnk2) {
217         e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
218         e2 = (AliGenCocktailEntry*) (flnk2->GetObject());       
219     } else {
220         flnk2 = flnk1 = flnk1->Next();
221         if (flnk1) {
222             e1 = (AliGenCocktailEntry*) (flnk1->GetObject());
223             e2 = (AliGenCocktailEntry*) (flnk2->GetObject());
224         } else {
225             e1=0;
226             e2=0;
227         }
228     }
229 }
230
231 AliGenCocktail& AliGenCocktail::operator=(const  AliGenCocktail& rhs)
232 {
233 // Assignment operator
234     rhs.Copy(*this); 
235     return (*this);
236 }
237
238 void AliGenCocktail::Copy(TObject &) const
239 {
240     Fatal("Copy","Not implemented!\n");
241 }
242
243
244