In AliStack: TClonesArray* fParticles replaced by TClonesArray
[u/mrichter/AliRoot.git] / EVGEN / AliGenCocktailAfterBurner.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 // 
19 // Container class for AliGenerator and AfterBurners 
20 // (which are AliGenerators as well) through recursion.
21 // The container is itself an AliGenerator a
22 // what is stored are not the pointers to the generators directly 
23 // but to objects of type
24 // AliGenCocktailAfterBurner entry.   
25 // The class provides also iterator functionality.  
26 // Author: andreas.morsch@cern.ch and piotr.skowronski@cern.ch
27 //
28 // 24.09.2001  Piotr Skowronski
29 //             debug -> gDebug,
30 //             fNEvents replaced with gAlice->GetEventsPerRun()
31 //
32
33
34 #include <Riostream.h>
35
36 #include <TList.h>
37 #include <TObjArray.h>
38 #include <TParticle.h>
39
40 #include "AliGenCocktailAfterBurner.h"
41 #include "AliGenCocktailEntry.h"
42 #include "AliCollisionGeometry.h"
43 #include "AliStack.h"
44 #include "AliMC.h"
45
46
47 ClassImp(AliGenCocktailAfterBurner)
48 /*********************************************************************/ 
49 /*********************************************************************/ 
50
51     AliGenCocktailAfterBurner::AliGenCocktailAfterBurner():
52         fNAfterBurners(0),
53         fAfterBurnerEntries(new TList()),
54         fGenerationDone(kFALSE),
55         fInternalStacks(0),
56         fCollisionGeometries(0),
57         fCurrentEvent(0),
58         fActiveStack(0),
59         fActiveEvent(-1),
60         fCurrentGenerator(0),
61         fNBgEvents(0)
62 {
63 // Constructor
64     if (gDebug > 0) 
65         cout<<"AliGenCocktailAfterBurner::AliGenCocktailAfterBurner()"<<endl;
66     SetName("AliGenCocktailAfterBurner");
67     SetTitle("AliGenCocktailAfterBurner");
68 }
69
70 /*********************************************************************/ 
71
72 AliGenCocktailAfterBurner::~AliGenCocktailAfterBurner()
73   {
74 //destructor
75
76     if (fInternalStacks) //delete stacks
77      { 
78        fInternalStacks->SetOwner();
79        delete fInternalStacks;
80     }
81     if (fAfterBurnerEntries) delete fAfterBurnerEntries; //delete entries
82     delete[] fCollisionGeometries;
83   }
84 /*********************************************************************/ 
85 /*********************************************************************/ 
86
87 void AliGenCocktailAfterBurner::
88 AddAfterBurner(AliGenerator *AfterBurner, char* Name, Float_t RateExp)
89 {
90 //
91 //  Forward parameters to the new AfterBurner
92     
93     if (gDebug>0)cout<<"AliGenCocktailAfterBurner::AddAfterBurner  Named "<<Name<<endl;
94
95     if(TestBit(kPtRange)) 
96         AfterBurner->SetPtRange(fPtMin,fPtMax);
97     if(TestBit(kMomentumRange))
98         AfterBurner->SetMomentumRange(fPMin,fPMax);
99     
100     AfterBurner->SetYRange(fYMin,fYMax);
101     AfterBurner->SetPhiRange(fPhiMin*180/TMath::Pi(),fPhiMax*180/TMath::Pi());
102     AfterBurner->SetThetaRange(fThetaMin*180/TMath::Pi(),fThetaMax*180/TMath::Pi());
103     AfterBurner->SetOrigin(fOrigin[0], fOrigin[1], fOrigin[2]);
104     AfterBurner->SetSigma(fOsigma[0], fOsigma[1], fOsigma[2]);
105     AfterBurner->SetVertexSmear(fVertexSmear);
106     AfterBurner->SetTrackingFlag(fTrackIt);    
107 //
108 //  Add AfterBurner to list   
109     
110     AliGenCocktailEntry *entry = 
111         new AliGenCocktailEntry(AfterBurner, Name, RateExp);
112     fAfterBurnerEntries->Add(entry);
113     fNAfterBurners++;
114 //
115     
116 }
117 /*********************************************************************/ 
118 /*********************************************************************/ 
119
120 void AliGenCocktailAfterBurner::Init()
121 {
122 // Initialisation
123     fGenerationDone = kFALSE;
124     if (fInternalStacks) //delete stacks
125      { 
126        fInternalStacks->SetOwner();
127        fInternalStacks->Delete(); //clean after previous generation cycle
128      }
129
130 // ANDREAS MORSCH ---------------------------------------------------(
131     if (fCollisionGeometries) delete[] fCollisionGeometries;
132 // ANDREAS MORSCH ---------------------------------------------------)
133     
134     this->AliGenCocktail::Init(); 
135     
136     if (gDebug>0) cout<<"AliGenCocktailAfterBurner::Init"<<endl;
137     TIter next(fAfterBurnerEntries);
138     AliGenCocktailEntry *entry;
139     //
140     // Loop over generators and initialize
141     while((entry = (AliGenCocktailEntry*)next())) {
142         entry->Generator()->Init();
143     }  
144 }
145 /*********************************************************************/ 
146 /*********************************************************************/ 
147
148 void AliGenCocktailAfterBurner::Generate()
149 {
150 //
151 // Generate event
152 //  Firsts runs each generator for all events
153 //  than after burners ones for each event
154 //
155 //  It generates and processes all events during
156 //  first call only.
157 //  In next calls it just returns already generated 
158 //  and processed events to the gAlice
159
160     if (gDebug>0)
161       cout<<"#####################################"<<endl
162           <<"#AliGenCocktailAfterBurner::Generate#"<<endl
163           <<"#####################################"<<endl;
164     
165     Int_t i; //iterator
166     AliStack * stack;
167     
168     if (fGenerationDone)
169     {//if generation is done (in first call) 
170      //just copy particles from the stack to the gAlice
171       SetTracks(++fCurrentEvent);
172       cout<<"Returning event "<<fCurrentEvent<<endl;
173       return;  
174     }
175     else
176     { //Here we are in the first call of the method
177       fCurrentEvent=0;
178       Int_t numberOfEvents = gAlice->GetEventsPerRun();
179       //Create stacks
180       fInternalStacks      = new TObjArray(numberOfEvents + fNBgEvents); //Create array of internal stacks
181       fCollisionGeometries = new AliCollisionGeometry*[numberOfEvents + fNBgEvents]; //Create array of collision geometries
182       for(i=0;i<numberOfEvents + fNBgEvents;i++) 
183        {        
184         stack = new AliStack(10000);
185         stack->Reset();
186         fInternalStacks->Add(stack);
187        }
188 /*********************************************************************/ 
189       TIter next(fEntries);
190       AliGenCocktailEntry *entry;
191       AliGenCocktailEntry *e1;
192       AliGenCocktailEntry *e2;
193       const TObjArray *partArray;
194   //
195   // Loop over generators and generate events
196       Int_t igen=0;
197       while((entry = (AliGenCocktailEntry*)next())) 
198       {
199         igen++;
200         cout<<"Generator "<<igen<<"  : "<<entry->GetName()<<endl;
201 /***********************************************/
202 //First generator for all evenets, than second for all events, etc...
203         for(i=0;i<numberOfEvents + fNBgEvents;i++) 
204           {  
205             cout<<"                  EVENT "<<i<<endl;
206             stack = GetStack(i);
207             partArray = stack->Particles();
208             fCurrentGenerator = entry->Generator();
209             fCurrentGenerator->SetStack(stack);
210             if (igen ==1) 
211               {
212                 entry->SetFirst(0);
213               } 
214             else 
215               {
216                 entry->SetFirst((partArray->GetEntriesFast())+1);
217               }
218                 fCurrentGenerator->Generate();
219                 entry->SetLast(partArray->GetEntriesFast());
220                 
221 // ANDREAS MORSCH ---------------------------------------------------(
222                 if (fCurrentGenerator->ProvidesCollisionGeometry())  fCollisionGeometries[i] = fCurrentGenerator->CollisionGeometry();
223 // ANDREAS MORSCH ---------------------------------------------------)
224                 
225            }
226 /***********************************************/
227       }
228       next.Reset();
229       while((entry = (AliGenCocktailEntry*)next())) 
230         {
231           entry->PrintInfo();
232         }
233       for ( entry=FirstGenerator();entry;entry=NextGenerator() ) 
234         {
235           entry->PrintInfo();
236         }
237       for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
238         {
239           printf("\n -----------------------------");
240           e1->PrintInfo();
241           e2->PrintInfo();
242         }
243         
244         
245       /***********************************************/
246       /*******After Burners Processing****************/
247       /***********************************************/
248       TIter nextAfterBurner(fAfterBurnerEntries);
249       AliGenCocktailEntry *afterBurnerEntry;
250       Int_t iab =0; //number of current after burner / counter
251       
252       cout<<"\n\nRunning After Burners"<<endl;
253       while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
254         {
255           cout<<"After Burner "<<iab++<<"  :"<<afterBurnerEntry->GetName()<<endl;
256           fCurrentGenerator = afterBurnerEntry->Generator();
257           fCurrentGenerator->Generate();
258         }
259       cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
260
261       /***********************************************/
262       /***********************************************/
263       /***********************************************/       
264         
265       fGenerationDone=kTRUE; 
266       SetTracks(0); //copy event 0 to gAlice stack
267         
268 /*********************************************************************/
269         
270     }//else generated
271 }
272 /*********************************************************************/
273 /*********************************************************************/ 
274
275 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
276 {
277 //Returns the pointer to the N'th stack (event)
278   if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
279     {
280       Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
281       return 0; 
282     }
283     return ((AliStack*) fInternalStacks->At(n) );
284 }
285
286 /*********************************************************************/ 
287 /*********************************************************************/ 
288
289 // ANDREAS MORSCH ---------------------------------------------------(
290
291 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
292 {
293 //Returns the pointer to the N'th stack (event)
294   if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
295     {
296       Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
297       return 0; 
298     }
299     return fCollisionGeometries[n];
300 }
301
302 // ANDREAS MORSCH ---------------------------------------------------)
303
304 /*********************************************************************/ 
305 /*********************************************************************/ 
306
307 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
308 {
309 //Set Active Events Number and Active Stack
310 //There is only one active event number
311 //Made fo convinience of work with AfterBurners (HBT processor)
312
313     fActiveEvent = actev;
314     fActiveStack = GetStack(actev);
315 }
316 /*********************************************************************/ 
317 /*********************************************************************/ 
318
319 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
320 {
321 //Method which copies tracks from given stack to the
322 //gAlice's stack
323     AliStack* instack = GetStack(stackno);
324     Int_t done;
325     Int_t parent; 
326     Int_t pdg;
327     Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
328     TMCProcess mech;
329     Int_t ntr;
330     Float_t weight;
331     TVector3 pol;
332     
333     TParticle * p;
334     Int_t n = instack->GetNtrack();
335     if (gDebug) 
336     {
337       cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
338     }
339     
340     for(Int_t i = 0; i < n; i++)
341     {
342         
343       p = instack->Particle(i);
344       done = !p->TestBit(kDoneBit);
345       parent = p->GetMother(0);
346       pdg = p->GetPdgCode();
347       px = p->Px();
348       py = p->Py();
349       pz = p->Pz();
350       e  = p->Energy();
351       vx = p->Vx();
352       vy = p->Vy();
353       vz = p->Vz();
354       tof = p->T();
355       p->GetPolarisation(pol);
356       polx = pol.X();
357       poly = pol.Y();
358       polz = pol.Z();
359       mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
360       weight = p->GetWeight();
361
362       gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
363
364 // ANDREAS MORSCH ---------------------------------------------------(
365       SetHighWaterMark(ntr) ; 
366 // ANDREAS MORSCH ---------------------------------------------------)
367
368     }
369 }
370 /*********************************************************************/ 
371 /*********************************************************************/ 
372
373 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
374 {
375  //Mothod used to convert uniqueID (integer) to TMCProcess type
376     const TMCProcess kMCprocesses[kMaxMCProcess] = 
377     {
378      kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL, 
379      kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
380      kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
381      kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic, 
382      kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess, 
383      kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
384     };
385     
386     for (Int_t i = 0;i<kMaxMCProcess;i++)
387     {
388       if (kMCprocesses[i] == no)
389         {
390           return kMCprocesses[i];
391         }
392     } 
393     return kPNoProcess;
394 }
395