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