Skip to content
Snippets Groups Projects
EventGeneratorAlphaDecay.cc 7.5 KiB
Newer Older
/*****************************************************************************
 * Copyright (C) 2009-2016   this file is part of the NPTool Project         *
 *                                                                           *
 * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
 * For the list of contributors see $NPTOOL/Licence/Contributors             *
 *****************************************************************************/

/*****************************************************************************
 * Original Author: Adrien MATTA  contact address: matta@lpccaen.in2p3.fr    *
 *                                                                           *
 * Creation Date  : January 2009                                             *
 * Last update    :                                                          *
 *---------------------------------------------------------------------------*
 * Decription:                                                               *
 *  This event Generator is used to simulated AlphaDecay ion Source           *
 *  Very usefull to figure out Geometric Efficacity of experimental Set-Up   *
 *---------------------------------------------------------------------------*
 * Comment:                                                                  *
 *                                                                           *
 *                                                                           *
 *****************************************************************************/
// C++
#include<limits>

// G4 headers
#include "G4ParticleTable.hh"
#include "G4IonTable.hh"
// G4 headers including CLHEP headers
// for generating random numbers
#include "Randomize.hh"

// NPS headers
#include "EventGeneratorAlphaDecay.hh"

// NPL headers
#include "RootOutput.h"
#include "NPNucleus.h"
#include "NPOptionManager.h"
#include "NPFunction.h"
using namespace CLHEP;


//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventGeneratorAlphaDecay::EventGeneratorAlphaDecay(){
  // NPTool path
  string GlobalPath = getenv("NPTOOL");
  string StandardPath = GlobalPath + "/Inputs/EventGenerator/";

  m_EnergyLow    =  0  ;
  m_EnergyHigh   =  0  ;
  m_x0           =  0  ;
  m_y0           =  0  ;
  m_z0           =  0  ;
  m_SigmaX       =  0  ;
  m_SigmaY       =  0  ;
  m_SigmaZ       =  0  ;
  m_particle     = NULL;
  m_ExcitationEnergy = 0 ;
  m_direction    = 'z' ;
  m_SourceProfile = "Gauss" ;
  m_ActivityBq   = 1.  ;
  m_TimeWindow   = 50.e-9 ;

  m_ParticleStack = ParticleStack::getInstance();

}



//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
EventGeneratorAlphaDecay::~EventGeneratorAlphaDecay(){
}



//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventGeneratorAlphaDecay::ReadConfiguration(NPL::InputParser parser){
  
  vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("AlphaDecay");
  if(NPOptionManager::getInstance()->GetVerboseLevel())
    cout << endl << "\033[1;35m//// AlphaDecay reaction found " << endl;

  vector<string> token = {"EnergyLow","EnergyHigh","HalfOpenAngleMin","HalfOpenAngleMax","x0","y0","z0","ActivityBq"};
  cout << "block.size() = " << blocks.size() << endl;
  for(unsigned int i = 0 ; i < blocks.size() ; i++){
    cout << "[" << i << "]" << endl;
    if(blocks[i]->HasTokenList(token)){

      m_EnergyLow         = blocks[i]->GetDouble("EnergyLow","MeV");        
      m_EnergyHigh        = blocks[i]->GetDouble("EnergyHigh","MeV");
      m_HalfOpenAngleMin  = blocks[i]->GetDouble("HalfOpenAngleMin","deg"); 
      m_HalfOpenAngleMax  = blocks[i]->GetDouble("HalfOpenAngleMax","deg");
      m_x0                = blocks[i]->GetDouble("x0","mm");                
      m_y0                = blocks[i]->GetDouble("y0","mm");
      m_z0                = blocks[i]->GetDouble("z0","mm");
      m_SourceProfile     = blocks[i]->GetString("SourceProfile");          
      m_SigmaX            = blocks[i]->GetDouble("SigmaX","mm");            
      m_SigmaY            = blocks[i]->GetDouble("SigmaY","mm");
      m_SigmaZ            = blocks[i]->GetDouble("SigmaZ","mm");
      m_direction         = blocks[i]->GetString("Direction");              
      m_ExcitationEnergy  = blocks[i]->GetDouble("ExcitationEnergy","MeV"); 
      m_ActivityBq        = blocks[i]->GetDouble("ActivityBq","Bq");        
      m_TimeWindow        = blocks[i]->GetDouble("TimeWindow","s");         
      cout << "m_parameters done " << endl;
    }
    else{
      cout << "ERROR: check your input file formatting \033[0m" << endl;
      exit(1);
    }
  }
}

//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventGeneratorAlphaDecay::GenerateEvent(G4Event* evt){

  double alpha_t = 0.;
  double step_t  = 1.e-2 / m_ActivityBq; // step size in [s] to have a maximum proba of 1.e-2
  int    step_n  = ((int)(m_TimeWindow / step_t) == 0) ? 1 : (int)(m_TimeWindow / step_t);
  bool   DecayOn = true;

  for(int i=0; i<step_n; i++){
    
    m_particle=NULL;
    if(m_particle==NULL){
      m_particle = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(2, 4,m_ExcitationEnergy);
      if(i>0){
        alpha_t = i*step_t;
        DecayOn = !(RandFlat::shoot() >= 1.e-2);
      }
    }
    if(!DecayOn) continue;

    G4double cos_theta_min   = cos(m_HalfOpenAngleMin);
    G4double cos_theta_max   = cos(m_HalfOpenAngleMax);
    G4double cos_theta       = cos_theta_min + (cos_theta_max - cos_theta_min) * RandFlat::shoot();
    G4double theta           = acos(cos_theta)                                                   ;
    G4double phi             = RandFlat::shoot() * 2 * pi                                        ;
    G4double particle_energy = m_EnergyLow + RandFlat::shoot() * (m_EnergyHigh - m_EnergyLow)    ;

    G4double x0, y0, z0;
    G4double momentum_x, momentum_y, momentum_z;

    if(m_SourceProfile=="Flat"){
      double rand_r     = m_SigmaX*sqrt(RandFlat::shoot());
      double rand_theta = RandFlat::shoot() * 2. * pi;
      x0 = m_x0 + rand_r * cos(rand_theta);
      y0 = m_y0 + rand_r * sin(rand_theta);
      z0 = RandFlat::shoot(m_z0*mm-m_SigmaZ*mm, m_z0*mm+m_SigmaZ*mm);
    }
    else{ // by default gaussian source profile is considered 
      x0 = RandGauss::shoot(m_x0,m_SigmaX);
      y0 = RandGauss::shoot(m_y0,m_SigmaY);
      z0 = RandGauss::shoot(m_z0,m_SigmaZ);
    }
    if(m_direction == 'z')
    {
      // Direction of particle, energy and laboratory angle
      momentum_x = sin(theta) * cos(phi)  ;
      momentum_y = sin(theta) * sin(phi)  ;
      momentum_z = cos(theta)             ;

    }
    else if(m_direction == 'y')
    {
      // Direction of particle, energy and laboratory angle
      momentum_z = sin(theta) * cos(phi)  ;
      momentum_x = sin(theta) * sin(phi)  ;
      momentum_y = cos(theta)             ;
    }
    else // = 'x'
    {
      // Direction of particle, energy and laboratory angle
      momentum_y = sin(theta) * cos(phi)  ;
      momentum_z = sin(theta) * sin(phi)  ;
      momentum_x = cos(theta)             ;
    }
    //cout << "add an alpha particle to stack with global time = " << alpha_t << " s ==> " << alpha_t*1.e9 << " ns" << endl;
    NPS::Particle particle(m_particle, theta, particle_energy, G4ThreeVector(momentum_x, momentum_y, momentum_z), G4ThreeVector(x0, y0, z0),alpha_t*1.e9,true);
    m_ParticleStack->AddParticleToStack(particle);
  }

}


//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void EventGeneratorAlphaDecay::InitializeRootOutput(){

}