]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVGEN/AliGenCocktailAfterBurner.cxx
Correctly retrieve the number of events per run during event generation.
[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 AliRunLoader::GetNumberOfEvents()
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 = AliRunLoader::Instance()->GetNumberOfEventsPerRun();
179       cout << Nnumber of events per run" <<  numberOfEvents << endl;
180       
181       //Create stacks
182       fInternalStacks      = new TObjArray(numberOfEvents + fNBgEvents); //Create array of internal stacks
183       fCollisionGeometries = new AliCollisionGeometry*[numberOfEvents + fNBgEvents]; //Create array of collision geometries
184       for(i=0;i<numberOfEvents + fNBgEvents;i++) 
185        {        
186         stack = new AliStack(10000);
187         stack->Reset();
188         fInternalStacks->Add(stack);
189        }
190 /*********************************************************************/ 
191       TIter next(fEntries);
192       AliGenCocktailEntry *entry;
193       AliGenCocktailEntry *e1;
194       AliGenCocktailEntry *e2;
195       const TObjArray *partArray;
196   //
197   // Loop over generators and generate events
198       Int_t igen=0;
199       while((entry = (AliGenCocktailEntry*)next())) 
200       {
201         igen++;
202         cout<<"Generator "<<igen<<"  : "<<entry->GetName()<<endl;
203 /***********************************************/
204 //First generator for all evenets, than second for all events, etc...
205         for(i=0;i<numberOfEvents + fNBgEvents;i++) 
206           {  
207               cout<<"                  EVENT "<<i << endl;
208             stack = GetStack(i);
209             partArray = stack->Particles();
210             fCurrentGenerator = entry->Generator();
211             fCurrentGenerator->SetStack(stack);
212             if (igen ==1) 
213               {
214                 entry->SetFirst(0);
215               } 
216             else 
217               {
218                 entry->SetFirst((partArray->GetEntriesFast())+1);
219               }
220                 fCurrentGenerator->Generate();
221                 entry->SetLast(partArray->GetEntriesFast());
222                 
223 // ANDREAS MORSCH ---------------------------------------------------(
224                 if (fCurrentGenerator->ProvidesCollisionGeometry())  fCollisionGeometries[i] = fCurrentGenerator->CollisionGeometry();
225 // ANDREAS MORSCH ---------------------------------------------------)
226                 
227            }
228 /***********************************************/
229       }
230       next.Reset();
231       while((entry = (AliGenCocktailEntry*)next())) 
232         {
233           entry->PrintInfo();
234         }
235       for ( entry=FirstGenerator();entry;entry=NextGenerator() ) 
236         {
237           entry->PrintInfo();
238         }
239       for (FirstGeneratorPair(e1,e2); (e1&&e2); NextGeneratorPair(e1,e2) )
240         {
241           printf("\n -----------------------------");
242           e1->PrintInfo();
243           e2->PrintInfo();
244         }
245         
246         
247       /***********************************************/
248       /*******After Burners Processing****************/
249       /***********************************************/
250       TIter nextAfterBurner(fAfterBurnerEntries);
251       AliGenCocktailEntry *afterBurnerEntry;
252       Int_t iab =0; //number of current after burner / counter
253       
254       cout<<"\n\nRunning After Burners"<<endl;
255       while((afterBurnerEntry = (AliGenCocktailEntry*)nextAfterBurner()))
256         {
257           cout<<"After Burner "<<iab++<<"  :"<<afterBurnerEntry->GetName()<<endl;
258           fCurrentGenerator = afterBurnerEntry->Generator();
259           fCurrentGenerator->Generate();
260         }
261       cout<<endl<<"Finished. Processed "<<iab<<" After Burners"<<endl;
262
263       /***********************************************/
264       /***********************************************/
265       /***********************************************/       
266         
267       fGenerationDone=kTRUE; 
268       SetTracks(0); //copy event 0 to gAlice stack
269         
270 /*********************************************************************/
271         
272     }//else generated
273 }
274 /*********************************************************************/
275 /*********************************************************************/ 
276
277 AliStack* AliGenCocktailAfterBurner::GetStack(Int_t n) const
278 {
279 //Returns the pointer to the N'th stack (event)
280   if( ( n<0 ) || ( n >= (GetNumberOfEvents()) ) )
281     {
282       Fatal("AliGenCocktailAfterBurner::GetStack","Asked for non existing stack (%d)",n);
283       return 0; 
284     }
285     return ((AliStack*) fInternalStacks->At(n) );
286 }
287
288 /*********************************************************************/ 
289 /*********************************************************************/ 
290
291 // ANDREAS MORSCH ---------------------------------------------------(
292
293 AliCollisionGeometry* AliGenCocktailAfterBurner::GetCollisionGeometry(Int_t n) const
294 {
295 //Returns the pointer to the N'th stack (event)
296   if( ( n<0 ) || ( n>=GetNumberOfEvents() ) )
297     {
298       Fatal("AliGenCocktailAfterBurner::GetCollisionGeometry","Asked for non existing stack (%d)",n);
299       return 0; 
300     }
301     return fCollisionGeometries[n];
302 }
303
304 // ANDREAS MORSCH ---------------------------------------------------)
305
306 /*********************************************************************/ 
307 /*********************************************************************/ 
308
309 void AliGenCocktailAfterBurner::SetActiveEventNumber(Int_t actev)
310 {
311 //Set Active Events Number and Active Stack
312 //There is only one active event number
313 //Made fo convinience of work with AfterBurners (HBT processor)
314
315     fActiveEvent = actev;
316     fActiveStack = GetStack(actev);
317 }
318 /*********************************************************************/ 
319 /*********************************************************************/ 
320
321 void AliGenCocktailAfterBurner::SetTracks(Int_t stackno)
322 {
323 //Method which copies tracks from given stack to the
324 //gAlice's stack
325     AliStack* instack = GetStack(stackno);
326     Int_t done;
327     Int_t parent; 
328     Int_t pdg;
329     Double_t px, py, pz, e, vx, vy, vz, tof, polx, poly, polz;
330     TMCProcess mech;
331     Int_t ntr;
332     Float_t weight;
333     TVector3 pol;
334     
335     TParticle * p;
336     Int_t n = instack->GetNtrack();
337     if (gDebug) 
338     {
339       cout<<"AliGenCocktailAfterBurner::SetTracks("<<stackno<<"). Number of particles is: "<<n<<"\n";
340     }
341     
342     for(Int_t i = 0; i < n; i++)
343     {
344         
345       p = instack->Particle(i);
346       done = !p->TestBit(kDoneBit);
347       parent = p->GetMother(0);
348       pdg = p->GetPdgCode();
349       px = p->Px();
350       py = p->Py();
351       pz = p->Pz();
352       e  = p->Energy();
353       vx = p->Vx();
354       vy = p->Vy();
355       vz = p->Vz();
356       tof = p->T();
357       p->GetPolarisation(pol);
358       polx = pol.X();
359       poly = pol.Y();
360       polz = pol.Z();
361       mech = AliGenCocktailAfterBurner::IntToMCProcess(p->GetUniqueID());
362       weight = p->GetWeight();
363
364       gAlice->GetMCApp()->PushTrack(done, parent, pdg, px, py, pz, e, vx, vy, vz, tof,polx, poly, polz, mech, ntr, weight);
365
366 // ANDREAS MORSCH ---------------------------------------------------(
367       SetHighWaterMark(ntr) ; 
368 // ANDREAS MORSCH ---------------------------------------------------)
369
370     }
371 }
372 /*********************************************************************/ 
373 /*********************************************************************/ 
374
375 TMCProcess AliGenCocktailAfterBurner::IntToMCProcess(Int_t no)
376 {
377  //Mothod used to convert uniqueID (integer) to TMCProcess type
378     const TMCProcess kMCprocesses[kMaxMCProcess] = 
379     {
380      kPNoProcess, kPMultipleScattering, kPEnergyLoss, kPMagneticFieldL, 
381      kPDecay, kPPair, kPCompton, kPPhotoelectric, kPBrem, kPDeltaRay,
382      kPAnnihilation, kPHadronic, kPNoProcess, kPEvaporation, kPNuclearFission,
383      kPNuclearAbsorption, kPPbarAnnihilation, kPNCapture, kPHElastic, 
384      kPHInhelastic, kPMuonNuclear, kPTOFlimit,kPPhotoFission, kPNoProcess, 
385      kPRayleigh, kPNoProcess, kPNoProcess, kPNoProcess, kPNull, kPStop
386     };
387     
388     for (Int_t i = 0;i<kMaxMCProcess;i++)
389     {
390       if (kMCprocesses[i] == no)
391         {
392           return kMCprocesses[i];
393         }
394     } 
395     return kPNoProcess;
396 }
397