ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Event generator that using an instance of type AliGenReader
// reads particles from a file and applies cuts.
// Example: In your Config.C you can include the following lines
//  AliGenExtFile *gener = new AliGenExtFile(-1);
//  gener->SetMomentumRange(0,999);
//  gener->SetPhiRange(-180.,180.);
//  gener->SetThetaRange(0,180);
//  gener->SetYRange(-999,999);
//  AliGenReaderTreeK * reader = new AliGenReaderTreeK();
//  reader->SetFileName("myFileWithTreeK.root");
//  gener->SetReader(reader);
//  gener->Init();


#include <Riostream.h>

#include "AliLog.h"
#include "AliGenExtFile.h"
#include "AliRunLoader.h"
#include "AliHeader.h"
#include "AliStack.h"
#include "AliGenEventHeader.h"
#include "AliGenReader.h"

#include <TParticle.h>
#include <TFile.h>
#include <TTree.h>


using std::cout;
using std::endl;
using std::map;

ClassImp(AliGenExtFile)

AliGenExtFile::AliGenExtFile()
    :AliGenMC(),
     fFileName(0),
     fReader(0),
     fStartEvent(0)
{
//  Constructor
//
//  Read all particles
    fNpart  = -1;
}

AliGenExtFile::AliGenExtFile(Int_t npart)
    :AliGenMC(npart),
     fFileName(0),
     fReader(0),
     fStartEvent(0)
{
//  Constructor
    fName   = "ExtFile";
    fTitle  = "Primaries from ext. File";
}

//____________________________________________________________
AliGenExtFile::~AliGenExtFile()
{
// Destructor
    delete fReader;
}

//___________________________________________________________
void AliGenExtFile::Init()
{
// Initialize
    if (fReader) fReader->Init();
}

//___________________________________________________________
void AliGenExtFile::Generate()
{
// Generate particles

  Double_t polar[3]  = {0,0,0};
  //
  Double_t origin[3] = {0,0,0};
  Double_t time = 0.;
  Double_t p[4];
  Float_t random[6];
  Int_t i=0, j, nt;
  //
  //
  if (fVertexSmear == kPerEvent) Vertex();

  // Fast forward up to start Event
  for (Int_t ie=0; ie<fStartEvent; ++ie ) {
    Int_t nTracks = fReader->NextEvent(); 	
    if (nTracks == 0) {
      // printf("\n No more events !!! !\n");
      Warning("AliGenExtFile::Generate","\nNo more events in external file!!!\nLast event may be empty or incomplete.\n");
      return;
    }
    for (i = 0; i < nTracks; ++i) {
      if (NULL == fReader->NextParticle())
	AliFatal("Error while skipping tracks");
    }
    cout << "Skipping event " << ie << endl;
  }  
  fStartEvent = 0; // do not skip events the second time 

  while(1) {
    Int_t nTracks = fReader->NextEvent(); 	
    if (nTracks == 0) {
      // printf("\n No more events !!! !\n");
      Warning("AliGenExtFile::Generate","\nNo more events in external file!!!\nLast event may be empty or incomplete.\n");
      return;
    }

    //
    // Particle selection loop
    //
    // The selection criterium for the external file generator is as follows:
    //
    // 1) All tracks are subject to the cuts defined by AliGenerator, i.e.
    //    fThetaMin, fThetaMax, fPhiMin, fPhiMax, fPMin, fPMax, fPtMin, fPtMax,
    //    fYMin, fYMax.
    //    If the particle does not satisfy these cuts, it is not put on the
    //    stack.
    // 2) If fCutOnChild and some specific child is selected (e.g. if
    //    fForceDecay==kSemiElectronic) the event is rejected if NOT EVEN ONE
    //    child falls into the child-cuts.
    TParticle* iparticle = 0x0;
    
    if(fCutOnChild) {
      // Count the selected children
      Int_t nSelected = 0;
      while ((iparticle=fReader->NextParticle()) ) {
	  Int_t kf = CheckPDGCode(iparticle->GetPdgCode());
	  kf = TMath::Abs(kf);
	  if (ChildSelected(kf) && KinematicSelection(iparticle, 1)) {
	      nSelected++;
	  }
      }
      if (!nSelected) continue;    // No particle selected:  Go to next event
      fReader->RewindEvent();
    }

    //
    // Stack selection loop
    //
    class SelectorLogic { // need to do recursive back tracking, requires a "nested" function
    private:
       Int_t idCount;
       map<Int_t,Int_t> firstMotherMap;
       map<Int_t,Int_t> secondMotherMap;
       map<Int_t,Bool_t> selectedIdMap;
       map<Int_t,Int_t> newIdMap;
       void selectMothersToo(Int_t particleId) {
	 Int_t mum1 = firstMotherMap[particleId];
          if (mum1 > -1 && !selectedIdMap[mum1]) {
             selectedIdMap[mum1] = true;
             selectMothersToo(mum1);
          }
          Int_t mum2 = secondMotherMap[particleId];
          if (mum2 > -1 && !selectedIdMap[mum2]) {
             selectedIdMap[mum2] = true;
             selectMothersToo(mum2);
          }
       }
    public:
      SelectorLogic():idCount(0), firstMotherMap(), secondMotherMap(), selectedIdMap(), newIdMap() {}
      void init() {
          idCount = 0;
       }
       void setData(Int_t id, Int_t mum1, Int_t mum2, Bool_t selected) {
          idCount++; // we know that this function is called in succession of ids, so counting is fine to determine max id
          firstMotherMap[id] = mum1;
          secondMotherMap[id] = mum2;
          selectedIdMap[id] = selected;
       }
       void reselectCuttedMothersAndRemapIDs() {
          for (Int_t id = 0; id < idCount; ++id) {
             if (selectedIdMap[id]) {
                selectMothersToo(id);
             }
          }
          Int_t newId0 = 0;
          for (Int_t id = 0; id < idCount; id++) {
             if (selectedIdMap[id]) {
                newIdMap[id] = newId0; ++newId0;
             } else {
                newIdMap[id] = -1;
             }
          }
       }
       Bool_t isSelected(Int_t id) {
          return selectedIdMap[id];
       }
       Int_t newId(Int_t id) {
          if (id == -1) return -1;
          return newIdMap[id];
       }
    };
    SelectorLogic selector;
    selector.init();
    for (i = 0; i < nTracks; i++) {
       TParticle* jparticle = fReader->NextParticle();
       selector.setData(i,
             jparticle->GetFirstMother(),
             jparticle->GetSecondMother(),
             KinematicSelection(jparticle,0));
    }
    selector.reselectCuttedMothersAndRemapIDs();
    fReader->RewindEvent();

    //
    // Stack filling loop
    //
    fNprimaries = 0;
    for (i = 0; i < nTracks; i++) {
       TParticle* jparticle = fReader->NextParticle();
       Bool_t selected = selector.isSelected(i);
       if (!selected) {
          continue;
       }
       Int_t parent = selector.newId(jparticle->GetFirstMother());
//       printf("particle %d -> %d, with mother %d -> %d\n", i, selector.newId(i), jparticle->GetFirstMother(), parent);

	p[0] = jparticle->Px();
	p[1] = jparticle->Py();
	p[2] = jparticle->Pz();
	p[3] = jparticle->Energy();
	
	Int_t idpart = jparticle->GetPdgCode();
	if(fVertexSmear==kPerTrack) 
	{
	    Rndm(random,6);
	    for (j = 0; j < 3; j++) {
		origin[j]=fOrigin[j]+
		    fOsigma[j]*TMath::Cos(2*random[2*j]*TMath::Pi())*
		    TMath::Sqrt(-2*TMath::Log(random[2*j+1]));
	    }
	    Rndm(random,2);
	    time = fTimeOrigin + fOsigma[2]/TMath::Ccgs()*
	      TMath::Cos(2*random[0]*TMath::Pi())*
	      TMath::Sqrt(-2*TMath::Log(random[1]));
	} else {
	    origin[0] = fVertex[0] + jparticle->Vx();
	    origin[1] = fVertex[1] + jparticle->Vy();
	    origin[2] = fVertex[2] + jparticle->Vz();
	    time = fTime + jparticle->T();
	}
	Int_t doTracking = fTrackIt && selected && (jparticle->TestBit(kTransportBit));
	
	PushTrack(doTracking, parent, idpart,
		  p[0], p[1], p[2], p[3], origin[0], origin[1], origin[2], time,
		  polar[0], polar[1], polar[2],
		  kPPrimary, nt, 1., jparticle->GetStatusCode());

	KeepTrack(nt);
	fNprimaries++;
    } // track loop

    // Generated event header
    AliGenEventHeader * header = fReader->GetGenEventHeader();
    if (!header) header = new AliGenEventHeader();
    header->SetNProduced(fNprimaries);
    header->SetPrimaryVertex(fVertex);
    header->SetInteractionTime(fTime);
    AddHeader(header);
    break;
    
  } // event loop
  
  SetHighWaterMark(nt);
  CdEventFile();
}

//___________________________________________________________
void AliGenExtFile::CdEventFile()
{
// CD back to the event file
  AliRunLoader::Instance()->CdGAFile();
}





 AliGenExtFile.cxx:1
 AliGenExtFile.cxx:2
 AliGenExtFile.cxx:3
 AliGenExtFile.cxx:4
 AliGenExtFile.cxx:5
 AliGenExtFile.cxx:6
 AliGenExtFile.cxx:7
 AliGenExtFile.cxx:8
 AliGenExtFile.cxx:9
 AliGenExtFile.cxx:10
 AliGenExtFile.cxx:11
 AliGenExtFile.cxx:12
 AliGenExtFile.cxx:13
 AliGenExtFile.cxx:14
 AliGenExtFile.cxx:15
 AliGenExtFile.cxx:16
 AliGenExtFile.cxx:17
 AliGenExtFile.cxx:18
 AliGenExtFile.cxx:19
 AliGenExtFile.cxx:20
 AliGenExtFile.cxx:21
 AliGenExtFile.cxx:22
 AliGenExtFile.cxx:23
 AliGenExtFile.cxx:24
 AliGenExtFile.cxx:25
 AliGenExtFile.cxx:26
 AliGenExtFile.cxx:27
 AliGenExtFile.cxx:28
 AliGenExtFile.cxx:29
 AliGenExtFile.cxx:30
 AliGenExtFile.cxx:31
 AliGenExtFile.cxx:32
 AliGenExtFile.cxx:33
 AliGenExtFile.cxx:34
 AliGenExtFile.cxx:35
 AliGenExtFile.cxx:36
 AliGenExtFile.cxx:37
 AliGenExtFile.cxx:38
 AliGenExtFile.cxx:39
 AliGenExtFile.cxx:40
 AliGenExtFile.cxx:41
 AliGenExtFile.cxx:42
 AliGenExtFile.cxx:43
 AliGenExtFile.cxx:44
 AliGenExtFile.cxx:45
 AliGenExtFile.cxx:46
 AliGenExtFile.cxx:47
 AliGenExtFile.cxx:48
 AliGenExtFile.cxx:49
 AliGenExtFile.cxx:50
 AliGenExtFile.cxx:51
 AliGenExtFile.cxx:52
 AliGenExtFile.cxx:53
 AliGenExtFile.cxx:54
 AliGenExtFile.cxx:55
 AliGenExtFile.cxx:56
 AliGenExtFile.cxx:57
 AliGenExtFile.cxx:58
 AliGenExtFile.cxx:59
 AliGenExtFile.cxx:60
 AliGenExtFile.cxx:61
 AliGenExtFile.cxx:62
 AliGenExtFile.cxx:63
 AliGenExtFile.cxx:64
 AliGenExtFile.cxx:65
 AliGenExtFile.cxx:66
 AliGenExtFile.cxx:67
 AliGenExtFile.cxx:68
 AliGenExtFile.cxx:69
 AliGenExtFile.cxx:70
 AliGenExtFile.cxx:71
 AliGenExtFile.cxx:72
 AliGenExtFile.cxx:73
 AliGenExtFile.cxx:74
 AliGenExtFile.cxx:75
 AliGenExtFile.cxx:76
 AliGenExtFile.cxx:77
 AliGenExtFile.cxx:78
 AliGenExtFile.cxx:79
 AliGenExtFile.cxx:80
 AliGenExtFile.cxx:81
 AliGenExtFile.cxx:82
 AliGenExtFile.cxx:83
 AliGenExtFile.cxx:84
 AliGenExtFile.cxx:85
 AliGenExtFile.cxx:86
 AliGenExtFile.cxx:87
 AliGenExtFile.cxx:88
 AliGenExtFile.cxx:89
 AliGenExtFile.cxx:90
 AliGenExtFile.cxx:91
 AliGenExtFile.cxx:92
 AliGenExtFile.cxx:93
 AliGenExtFile.cxx:94
 AliGenExtFile.cxx:95
 AliGenExtFile.cxx:96
 AliGenExtFile.cxx:97
 AliGenExtFile.cxx:98
 AliGenExtFile.cxx:99
 AliGenExtFile.cxx:100
 AliGenExtFile.cxx:101
 AliGenExtFile.cxx:102
 AliGenExtFile.cxx:103
 AliGenExtFile.cxx:104
 AliGenExtFile.cxx:105
 AliGenExtFile.cxx:106
 AliGenExtFile.cxx:107
 AliGenExtFile.cxx:108
 AliGenExtFile.cxx:109
 AliGenExtFile.cxx:110
 AliGenExtFile.cxx:111
 AliGenExtFile.cxx:112
 AliGenExtFile.cxx:113
 AliGenExtFile.cxx:114
 AliGenExtFile.cxx:115
 AliGenExtFile.cxx:116
 AliGenExtFile.cxx:117
 AliGenExtFile.cxx:118
 AliGenExtFile.cxx:119
 AliGenExtFile.cxx:120
 AliGenExtFile.cxx:121
 AliGenExtFile.cxx:122
 AliGenExtFile.cxx:123
 AliGenExtFile.cxx:124
 AliGenExtFile.cxx:125
 AliGenExtFile.cxx:126
 AliGenExtFile.cxx:127
 AliGenExtFile.cxx:128
 AliGenExtFile.cxx:129
 AliGenExtFile.cxx:130
 AliGenExtFile.cxx:131
 AliGenExtFile.cxx:132
 AliGenExtFile.cxx:133
 AliGenExtFile.cxx:134
 AliGenExtFile.cxx:135
 AliGenExtFile.cxx:136
 AliGenExtFile.cxx:137
 AliGenExtFile.cxx:138
 AliGenExtFile.cxx:139
 AliGenExtFile.cxx:140
 AliGenExtFile.cxx:141
 AliGenExtFile.cxx:142
 AliGenExtFile.cxx:143
 AliGenExtFile.cxx:144
 AliGenExtFile.cxx:145
 AliGenExtFile.cxx:146
 AliGenExtFile.cxx:147
 AliGenExtFile.cxx:148
 AliGenExtFile.cxx:149
 AliGenExtFile.cxx:150
 AliGenExtFile.cxx:151
 AliGenExtFile.cxx:152
 AliGenExtFile.cxx:153
 AliGenExtFile.cxx:154
 AliGenExtFile.cxx:155
 AliGenExtFile.cxx:156
 AliGenExtFile.cxx:157
 AliGenExtFile.cxx:158
 AliGenExtFile.cxx:159
 AliGenExtFile.cxx:160
 AliGenExtFile.cxx:161
 AliGenExtFile.cxx:162
 AliGenExtFile.cxx:163
 AliGenExtFile.cxx:164
 AliGenExtFile.cxx:165
 AliGenExtFile.cxx:166
 AliGenExtFile.cxx:167
 AliGenExtFile.cxx:168
 AliGenExtFile.cxx:169
 AliGenExtFile.cxx:170
 AliGenExtFile.cxx:171
 AliGenExtFile.cxx:172
 AliGenExtFile.cxx:173
 AliGenExtFile.cxx:174
 AliGenExtFile.cxx:175
 AliGenExtFile.cxx:176
 AliGenExtFile.cxx:177
 AliGenExtFile.cxx:178
 AliGenExtFile.cxx:179
 AliGenExtFile.cxx:180
 AliGenExtFile.cxx:181
 AliGenExtFile.cxx:182
 AliGenExtFile.cxx:183
 AliGenExtFile.cxx:184
 AliGenExtFile.cxx:185
 AliGenExtFile.cxx:186
 AliGenExtFile.cxx:187
 AliGenExtFile.cxx:188
 AliGenExtFile.cxx:189
 AliGenExtFile.cxx:190
 AliGenExtFile.cxx:191
 AliGenExtFile.cxx:192
 AliGenExtFile.cxx:193
 AliGenExtFile.cxx:194
 AliGenExtFile.cxx:195
 AliGenExtFile.cxx:196
 AliGenExtFile.cxx:197
 AliGenExtFile.cxx:198
 AliGenExtFile.cxx:199
 AliGenExtFile.cxx:200
 AliGenExtFile.cxx:201
 AliGenExtFile.cxx:202
 AliGenExtFile.cxx:203
 AliGenExtFile.cxx:204
 AliGenExtFile.cxx:205
 AliGenExtFile.cxx:206
 AliGenExtFile.cxx:207
 AliGenExtFile.cxx:208
 AliGenExtFile.cxx:209
 AliGenExtFile.cxx:210
 AliGenExtFile.cxx:211
 AliGenExtFile.cxx:212
 AliGenExtFile.cxx:213
 AliGenExtFile.cxx:214
 AliGenExtFile.cxx:215
 AliGenExtFile.cxx:216
 AliGenExtFile.cxx:217
 AliGenExtFile.cxx:218
 AliGenExtFile.cxx:219
 AliGenExtFile.cxx:220
 AliGenExtFile.cxx:221
 AliGenExtFile.cxx:222
 AliGenExtFile.cxx:223
 AliGenExtFile.cxx:224
 AliGenExtFile.cxx:225
 AliGenExtFile.cxx:226
 AliGenExtFile.cxx:227
 AliGenExtFile.cxx:228
 AliGenExtFile.cxx:229
 AliGenExtFile.cxx:230
 AliGenExtFile.cxx:231
 AliGenExtFile.cxx:232
 AliGenExtFile.cxx:233
 AliGenExtFile.cxx:234
 AliGenExtFile.cxx:235
 AliGenExtFile.cxx:236
 AliGenExtFile.cxx:237
 AliGenExtFile.cxx:238
 AliGenExtFile.cxx:239
 AliGenExtFile.cxx:240
 AliGenExtFile.cxx:241
 AliGenExtFile.cxx:242
 AliGenExtFile.cxx:243
 AliGenExtFile.cxx:244
 AliGenExtFile.cxx:245
 AliGenExtFile.cxx:246
 AliGenExtFile.cxx:247
 AliGenExtFile.cxx:248
 AliGenExtFile.cxx:249
 AliGenExtFile.cxx:250
 AliGenExtFile.cxx:251
 AliGenExtFile.cxx:252
 AliGenExtFile.cxx:253
 AliGenExtFile.cxx:254
 AliGenExtFile.cxx:255
 AliGenExtFile.cxx:256
 AliGenExtFile.cxx:257
 AliGenExtFile.cxx:258
 AliGenExtFile.cxx:259
 AliGenExtFile.cxx:260
 AliGenExtFile.cxx:261
 AliGenExtFile.cxx:262
 AliGenExtFile.cxx:263
 AliGenExtFile.cxx:264
 AliGenExtFile.cxx:265
 AliGenExtFile.cxx:266
 AliGenExtFile.cxx:267
 AliGenExtFile.cxx:268
 AliGenExtFile.cxx:269
 AliGenExtFile.cxx:270
 AliGenExtFile.cxx:271
 AliGenExtFile.cxx:272
 AliGenExtFile.cxx:273
 AliGenExtFile.cxx:274
 AliGenExtFile.cxx:275
 AliGenExtFile.cxx:276
 AliGenExtFile.cxx:277
 AliGenExtFile.cxx:278
 AliGenExtFile.cxx:279
 AliGenExtFile.cxx:280
 AliGenExtFile.cxx:281
 AliGenExtFile.cxx:282
 AliGenExtFile.cxx:283
 AliGenExtFile.cxx:284
 AliGenExtFile.cxx:285
 AliGenExtFile.cxx:286
 AliGenExtFile.cxx:287
 AliGenExtFile.cxx:288
 AliGenExtFile.cxx:289
 AliGenExtFile.cxx:290
 AliGenExtFile.cxx:291
 AliGenExtFile.cxx:292
 AliGenExtFile.cxx:293
 AliGenExtFile.cxx:294
 AliGenExtFile.cxx:295
 AliGenExtFile.cxx:296
 AliGenExtFile.cxx:297
 AliGenExtFile.cxx:298
 AliGenExtFile.cxx:299
 AliGenExtFile.cxx:300