Implemented a remapper for parent identification in the particle tree when adding...
[u/mrichter/AliRoot.git] / EVGEN / AliGenExtFile.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 // Event generator that using an instance of type AliGenReader
19 // reads particles from a file and applies cuts.
20 // Example: In your Config.C you can include the following lines
21 //  AliGenExtFile *gener = new AliGenExtFile(-1);
22 //  gener->SetMomentumRange(0,999);
23 //  gener->SetPhiRange(-180.,180.);
24 //  gener->SetThetaRange(0,180);
25 //  gener->SetYRange(-999,999);
26 //  AliGenReaderTreeK * reader = new AliGenReaderTreeK();
27 //  reader->SetFileName("myFileWithTreeK.root");
28 //  gener->SetReader(reader);
29 //  gener->Init();
30
31
32 #include <Riostream.h>
33
34 #include "AliLog.h"
35 #include "AliGenExtFile.h"
36 #include "AliRunLoader.h"
37 #include "AliHeader.h"
38 #include "AliStack.h"
39 #include "AliGenEventHeader.h"
40 #include "AliGenReader.h"
41
42 #include <TParticle.h>
43 #include <TFile.h>
44 #include <TTree.h>
45
46
47 using std::cout;
48 using std::endl;
49 ClassImp(AliGenExtFile)
50
51 AliGenExtFile::AliGenExtFile()
52     :AliGenMC(),
53      fFileName(0),
54      fReader(0),
55      fStartEvent(0)
56 {
57 //  Constructor
58 //
59 //  Read all particles
60     fNpart  = -1;
61 }
62
63 AliGenExtFile::AliGenExtFile(Int_t npart)
64     :AliGenMC(npart),
65      fFileName(0),
66      fReader(0),
67      fStartEvent(0)
68 {
69 //  Constructor
70     fName   = "ExtFile";
71     fTitle  = "Primaries from ext. File";
72 }
73
74 //____________________________________________________________
75 AliGenExtFile::~AliGenExtFile()
76 {
77 // Destructor
78     delete fReader;
79 }
80
81 //___________________________________________________________
82 void AliGenExtFile::Init()
83 {
84 // Initialize
85     if (fReader) fReader->Init();
86 }
87
88 //___________________________________________________________
89 void AliGenExtFile::Generate()
90 {
91 // Generate particles
92
93   Double_t polar[3]  = {0,0,0};
94   //
95   Double_t origin[3] = {0,0,0};
96   Double_t time = 0.;
97   Double_t p[4];
98   Float_t random[6];
99   Int_t i = 0, j, nt;
100   //
101   //
102   if (fVertexSmear == kPerEvent) Vertex();
103
104   // Fast forward up to start Event
105   for (Int_t ie=0; ie<fStartEvent; ++ie ) {
106     Int_t nTracks = fReader->NextEvent();       
107     if (nTracks == 0) {
108       // printf("\n No more events !!! !\n");
109       Warning("AliGenExtFile::Generate","\nNo more events in external file!!!\nLast event may be empty or incomplete.\n");
110       return;
111     }
112     for (Int_t i=0; i<nTracks; ++i) {
113       if (NULL == fReader->NextParticle())
114         AliFatal("Error while skipping tracks");
115     }
116     cout << "Skipping event " << ie << endl;
117   }  
118   fStartEvent = 0; // do not skip events the second time 
119
120   while(1) {
121     Int_t nTracks = fReader->NextEvent();       
122     if (nTracks == 0) {
123       // printf("\n No more events !!! !\n");
124       Warning("AliGenExtFile::Generate","\nNo more events in external file!!!\nLast event may be empty or incomplete.\n");
125       return;
126     }
127
128     //
129     // Particle selection loop
130     //
131     // The selection criterium for the external file generator is as follows:
132     //
133     // 1) All tracks are subject to the cuts defined by AliGenerator, i.e.
134     //    fThetaMin, fThetaMax, fPhiMin, fPhiMax, fPMin, fPMax, fPtMin, fPtMax,
135     //    fYMin, fYMax.
136     //    If the particle does not satisfy these cuts, it is not put on the
137     //    stack.
138     // 2) If fCutOnChild and some specific child is selected (e.g. if
139     //    fForceDecay==kSemiElectronic) the event is rejected if NOT EVEN ONE
140     //    child falls into the child-cuts.
141     TParticle* iparticle = 0x0;
142     
143     if(fCutOnChild) {
144       // Count the selected children
145       Int_t nSelected = 0;
146       while ((iparticle=fReader->NextParticle()) ) {
147           Int_t kf = CheckPDGCode(iparticle->GetPdgCode());
148           kf = TMath::Abs(kf);
149           if (ChildSelected(kf) && KinematicSelection(iparticle, 1)) {
150               nSelected++;
151           }
152       }
153       if (!nSelected) continue;    // No particle selected:  Go to next event
154       fReader->RewindEvent();
155     }
156
157     //
158     // Stack filling loop
159     //
160     map<Int_t,Int_t> newIdMap;
161     map<Int_t,Int_t> newFirstMotherMap;
162     fNprimaries = 0;
163     for (i = 0; i < nTracks; i++) {
164        TParticle* jparticle = fReader->NextParticle();
165        Int_t parent = jparticle->GetFirstMother();
166        if (parent > -1) {
167           Int_t parentNewId = newIdMap[parent];
168           if (parentNewId == -1) { // if parent was skipped
169              parent = newFirstMotherMap[parent]; // re-adjust parent using stored information
170           } else {
171              parent = parentNewId; // otherwise re-map parent to new id
172           }
173        }
174        newFirstMotherMap[i] = parent; // store re-mapped parent data so child nodes can use it
175        Bool_t selected = KinematicSelection(jparticle,0);
176        if (!selected) {
177           newIdMap[i] = -1; // -1 marks this particle was skipped
178           continue;
179        }
180        newIdMap[i] = fNprimaries; // maps old id to new id
181
182         p[0] = jparticle->Px();
183         p[1] = jparticle->Py();
184         p[2] = jparticle->Pz();
185         p[3] = jparticle->Energy();
186         
187         Int_t idpart = jparticle->GetPdgCode();
188         if(fVertexSmear==kPerTrack) 
189         {
190             Rndm(random,6);
191             for (j = 0; j < 3; j++) {
192                 origin[j]=fOrigin[j]+
193                     fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
194                     TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
195             }
196             Rndm(random,2);
197             time = fTimeOrigin + fOsigma[2]/TMath::Ccgs()*
198               TMath::Cos(2*random[0]*TMath::Pi())*
199               TMath::Sqrt(-2*TMath::Log(random[1]));
200         } else {
201             origin[0] = fVertex[0] + jparticle->Vx();
202             origin[1] = fVertex[1] + jparticle->Vy();
203             origin[2] = fVertex[2] + jparticle->Vz();
204             time = fTime + jparticle->T();
205         }
206         Int_t doTracking = fTrackIt && selected && (jparticle->TestBit(kTransportBit));
207         
208         PushTrack(doTracking, parent, idpart,
209                   p[0], p[1], p[2], p[3], origin[0], origin[1], origin[2], time,
210                   polar[0], polar[1], polar[2],
211                   kPPrimary, nt, 1., jparticle->GetStatusCode());
212
213         KeepTrack(nt);
214         fNprimaries++;
215     } // track loop
216
217     // Generated event header
218     AliGenEventHeader * header = fReader->GetGenEventHeader();
219     if (!header) header = new AliGenEventHeader();
220     header->SetNProduced(fNprimaries);
221     header->SetPrimaryVertex(fVertex);
222     header->SetInteractionTime(fTime);
223     AddHeader(header);
224     break;
225     
226   } // event loop
227   
228   SetHighWaterMark(nt);
229   CdEventFile();
230 }
231
232 //___________________________________________________________
233 void AliGenExtFile::CdEventFile()
234 {
235 // CD back to the event file
236   AliRunLoader::Instance()->CdGAFile();
237 }
238
239
240
241
242