/************************************************************************** * 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. * ***************************************************************************/ /////////////////////////////////////////////////////////////////////////// // Class to generate decays of particles generated by a // // previous generator. It works as a generator, but pratically it // // performs only decays. It works with this scheme: first loops over // // particles on the stack, selects those to be decayed, decays them // // and then pushes the decay products on the stack. // // // // Giuseppe E. Bruno & Fiorella Fionda // // (Giuseppe.Bruno@ba.infn.it) (Fiorella.Fionda@ba.infn.it) // /////////////////////////////////////////////////////////////////////////// #include "AliStack.h" #include "AliGenEvtGen.h" #include "AliRun.h" #include "AliLog.h" #include ClassImp(AliGenEvtGen) /////////////////////////////////////////////////////////////////////////// AliGenEvtGen::AliGenEvtGen(): fStack(0x0), fDecayer(0x0), fForceDecay(kAll), fSwitchOff(kBeautyPart), fUserDecay(kFALSE), fUserDecayTablePath(0x0) { // // Default Construction // } /////////////////////////////////////////////////////////////////////////////////////////// AliGenEvtGen::~AliGenEvtGen() { // // Standard Destructor // if(fStack) {delete fStack;} fStack = 0; if(fDecayer) {delete fDecayer;} fDecayer = 0; if(fUserDecayTablePath) {delete fUserDecayTablePath;} fUserDecayTablePath = 0; } /////////////////////////////////////////////////////////////////////////////////////////// void AliGenEvtGen::Init() { // // Standard AliGenerator Initializer - no input // 1) initialize EvtGen with default decay and particle table // 2) set the decay mode to force particle // 3) set a user decay table if defined // if(fDecayer) { AliWarning("AliGenEvtGen already initialized!!!"); return; } fDecayer = new AliDecayerEvtGen(); fDecayer->Init(); //read the default decay table DECAY.DEC and particle table //if is set a decay mode: default decay mode is kAll fDecayer->SetForceDecay(fForceDecay); fDecayer->ForceDecay(); //if is defined a user decay table if(fUserDecay) { fDecayer->SetDecayTablePath(fUserDecayTablePath); fDecayer->ReadDecayTable(); } } ///////////////////////////////////////////////////////////////////////////////////////////// void AliGenEvtGen::Generate() { // //Generate method - Input none - Output none //For each event: //1)return the stack of the previous generator and select particles to be decayed by EvtGen //2)decay particles selected and put the decay products on the stack // // Float_t polar[3]= {0,0,0}; // Polarisation of daughter particles Float_t origin0[3]; // Origin of the parent particle Float_t pc[3], och[3]; // Momentum and origin of the children particles from EvtGen Int_t nt; Float_t tof; Int_t nPrimsPythia; TLorentzVector *mom=new TLorentzVector(); static TClonesArray *particles; if(!particles) particles = new TClonesArray("TParticle",1000); fStack = AliRunLoader::Instance()->Stack(); if(!fStack) {Info("Generate","Error: No stack found!"); return;} nPrimsPythia = fStack->GetNprimary(); AliDebug(1,Form("nPrimsPythia = %d \n",nPrimsPythia)); for (Int_t iTrack = 0; iTrack < nPrimsPythia; ++iTrack) { TParticle *part = fStack->Particle(iTrack); Int_t pdg=part->GetPdgCode(); AliDebug(1,Form("GetFlavour = %d e pdg = %d \n",GetFlavour(pdg),pdg)); switch(fSwitchOff) { case kAllPart: break; case kBeautyPart: if(GetFlavour(pdg)!=5) continue; break; case kCharmPart: if(GetFlavour(pdg)!=4) continue; break; } //check if particle is already decayed by Pythia if(part->GetStatusCode() != 1 || part->GetNDaughters()>0) { AliDebug(1,Form("Attention: particle %d is already decayed by Pythia!",pdg)); continue; } part->SetStatusCode(11); //Set particle as decayed : change the status code part->SetBit(kDoneBit); part->ResetBit(kTransportBit); mom->SetPxPyPzE(part->Px(),part->Py(),part->Pz(),part->Energy()); Int_t np; do{ fDecayer->Decay(part->GetPdgCode(),mom); np = fDecayer->ImportParticles(particles); }while(np<0); Int_t* trackIt = new Int_t[np]; Int_t* pParent = new Int_t[np]; AliDebug(1,Form("np = %d \n",np)); for (int i = 0; i < np; i++) { pParent[i] = -1; trackIt[i] = 0; } //select trackable particle if (np >1) { TParticle* iparticle = 0;//(TParticle *) particles->At(0);//parent particle for (int i = 1; iAt(i); Int_t ks = iparticle->GetStatusCode(); //track last decay products if(ks==1) trackIt[i]=1; }//decay particles loop }// if decay products origin0[0]=part->Vx(); //[cm] origin0[1]=part->Vy(); //[cm] origin0[2]=part->Vz(); //[cm] // // Put decay products on the stack // for (int i = 1; i < np; i++) { TParticle* iparticle = (TParticle *) particles->At(i); Int_t kf = iparticle->GetPdgCode(); Int_t ksc = iparticle->GetStatusCode(); Int_t jpa = iparticle->GetFirstMother()-1; //jpa = 0 for daughters of beauty particles Int_t iparent = (jpa > 0) ? pParent[jpa] : iTrack; och[0] = origin0[0]+iparticle->Vx(); //[cm] och[1] = origin0[1]+iparticle->Vy(); //[cm] och[2] = origin0[2]+iparticle->Vz(); //[cm] pc[0] = iparticle->Px(); //[GeV/c] pc[1] = iparticle->Py(); //[GeV/c] pc[2] = iparticle->Pz(); //[GeV/c] tof = part->T()+iparticle->T(); AliDebug(1,Form("FirstMother = %d e indicePart = %d e pdg = %d \n",jpa,i,kf)); PushTrack(trackIt[i], iparent, kf, pc, och, polar,tof, kPDecay, nt, 1., ksc); if(trackIt[i]==1) AliDebug(1,Form("Trackable particles: %d e pdg %d \n",i,kf)); pParent[i] = nt; KeepTrack(nt); SetHighWaterMark(nt); }// Particle loop particles->Clear(); if (trackIt) delete[] trackIt; if (pParent) delete[] pParent; } Info("Generate","AliGenEvtGen DONE"); } ////////////////////////////////////////////////////////////////////////////////////////// Int_t AliGenEvtGen::GetFlavour(Int_t pdgCode) { // // return the flavour of a particle // input: pdg code of the particle // output: Int_t // 3 in case of strange (open and hidden) // 4 in case of charm (") // 5 in case of beauty (") // Int_t pdg = TMath::Abs(pdgCode); //Resonance if (pdg > 100000) pdg %= 100000; if(pdg > 10000) pdg %= 10000; // meson ? if(pdg > 10) pdg/=100; // baryon ? if(pdg > 10) pdg/=10; return pdg; } ///////////////////////////////////////////////////////////////////////////////////////// Bool_t AliGenEvtGen::SetUserDecayTable(Char_t *path) { // //Set the path of user decay table if it is defined // //put a comment to control if path exists if(gSystem->AccessPathName(path)) { AliWarning("Attention: This path not exist!\n"); return kFALSE; } fUserDecayTablePath = path; fUserDecay = kTRUE; return kTRUE; }