Exemplo n.º 1
0
G4ThreeVector BIPrimaryGeneratorAction::GetParVec(G4double limit)
{
   G4double theta = acos(1. - G4UniformRand() * (1. - cos(limit)));
   G4double phi = G4UniformRand() * 2. * CLHEP::pi;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   G4ThreeVector particleVec = G4ThreeVector(vx, vy, vz);

   return particleVec;
}
Exemplo n.º 2
0
void BIPrimaryGeneratorAction::FirstBeamGun()
{
   G4AutoLock lock(&mutexInPGA);
   fEnergy = fEneFnc->GetRandom() * MeV;
   lock.unlock();
   
   //G4double x = (G4UniformRand() * 12.5 - 6.25)*mm;
   G4double x = (G4UniformRand() * 12.5 - 6.25) * 1.41421356*mm;
   G4double y = (G4UniformRand() * 48.75 - 24.375)*mm;

   fParticleGun->SetParticlePosition(G4ThreeVector(x, y, fZPosition));
}
// Primary event
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
   /*
   * To avoid dependence on Detector Construction we will get an envelope volume
   * from the G4LogicalVolumeStore
   *
   * Here we will be assuming our box is sitting in a world where the radiation flux
   * is coming from the -x direction. Thus we will have a uniform random start location
   * through the YZ plane
   */
  G4double envSizeX = 0.;
  G4double envSizeYZ  = 0.;

  if ( !EnvelopeBox )
  {
     G4LogicalVolume* envLV = G4LogicalVolumeStore::GetInstance() -> GetVolume("World");
     if ( envLV ) EnvelopeBox = dynamic_cast<G4Box*>( envLV -> GetSolid() );
  }

  if ( EnvelopeBox ) 
  {
     envSizeYZ = EnvelopeBox -> GetYHalfLength() *2.;
     envSizeX  = EnvelopeBox -> GetXHalfLength() *2.;
  }
  else
  {
     G4ExceptionDescription msg;
     msg << "World volume of box shape is not found.\n";
     msg << "Perhaps you have changed the geometry.\n";
     msg << "\nWhere has the world gone?";
     G4Exception("PrimaryGeneratorAction::GeneratePrimaries()","Mycode0001",JustWarning,msg);
  }

  // We won't use the outer 10% edge
  G4double size = 0.9;
  // Since we are starting in the -x direction and firing in the x direction we want the
  // particles to come uniformly out of the YZ plane
  G4double x0 = 0.5 * envSizeX; 
  G4double y0 = size * envSizeYZ * (G4UniformRand() - 0.5);
  G4double z0 = size * envSizeYZ  * (G4UniformRand() - 0.5);

  particleGun -> SetParticlePosition(G4ThreeVector(-x0,y0,z0));
  //particleGun -> SetParticleMomentumDirection(G4ThreeVector(1.0,0.,0.));  // Pure x momentum
 
  particleGun -> GeneratePrimaryVertex(anEvent);  // creates the initial momentum
}
Exemplo n.º 4
0
void BIPrimaryGeneratorAction::ThirdBeamGun()
{
   G4AutoLock lock(&mutexInPGA);
   fEnergy = fEneFnc->GetRandom() * MeV;
   lock.unlock();
   
   G4double theta;
   if(fEnergy > 30.*MeV){
      lock.lock();
      theta = fAngFnc->GetRandom() * deg;
      lock.unlock();
   }
   else
      theta = acos(1. - G4UniformRand() * (1. - cos(20.*deg)));
   G4double phi = G4UniformRand() * fPhiLimit;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   fParVec = G4ThreeVector(vx, vy, vz);
   fParticleGun->SetParticleMomentumDirection(fParVec);
}
Exemplo n.º 5
0
void	GSMS::Digitizer::Digitize() {

	m_coll = new DigitsCollection("GSMSDigitizer", "DigitsCollection");

	G4DigiManager*	digiMan = G4DigiManager::GetDMpointer();

	G4int	hCollID = digiMan->GetHitsCollectionID("eDep");

	G4THitsMap<G4double>* evtMap = NULL;
	evtMap = (G4THitsMap<G4double>*)(digiMan->GetHitsCollection(hCollID));

	if(!evtMap) return;

	
	std::map<G4int, G4double*>::iterator itr = evtMap->GetMap()->begin();
	for(; itr != evtMap->GetMap()->end(); itr++) {

		G4double	eneDep = *(itr->second);
		G4double	eneChan = 0;
//		if (eneChan > 10.)
//		{
			double dResCs137 = 0.085;//ResolutionScale;
			G4double dResA = std::sqrt(0.662)*dResCs137;
			double dRes = dResA/std::sqrt(eneDep);//ResolutionScale;
			
			G4double sigma = dRes*eneDep/2.355;
//			std::cerr << "Mean: " << eneDep << ", Sigma: " << sigma << ", Res: " << dRes;
			eneChan = G4RandGauss::shoot(eneDep,sigma) / 3 * 1024;
//			std::cerr << ", Value: "  << eneChan << std::endl;
//		}
//		else
//		{
//			eneChan = G4int(G4Poisson(eneChan));
//		};

//		std::cerr << ", Channel: "  << eneChan;

		G4double	time = G4UniformRand() * (m_etime - m_stime);

		if(eneChan >= m_dnu)
		{
			Digi*	digi = new Digi;
			digi->set_time(time);
			digi->set_channel(int(eneChan));
			digi->set_ene(eneDep);
			m_coll->insert(digi);
		}
	}

	StoreDigiCollection(m_coll);
}
Exemplo n.º 6
0
void BIPrimaryGeneratorAction::SecondBeamGun()
{
   G4double x, y;
   fHisSource->GetRandom2(x, y);

   fEnergy = pow(10., (y - 152.) / fDy) * 20 * MeV;

   G4double theta = CLHEP::pi * ((x - 78.) / fDx) / 180.;
   G4double phi = G4UniformRand() * fPhiLimit;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   fParVec = G4ThreeVector(vx, vy, vz);
   fParticleGun->SetParticleMomentumDirection(fParVec);
}
Exemplo n.º 7
0
G4ThreeVector BIPrimaryGeneratorAction::GetParVecEne()
{
   G4double x, y;
   while(1){// HisSource should be changed start with 0
      fHisSource->GetRandom2(x, y);
      if(x >= 78) break;
   }

   fEnergy = pow(10., (y - 152.) / fDy) * 20;

   G4double theta = CLHEP::pi * ((x - 78.) / fDx) / 180.;
   G4double phi = G4UniformRand() * 2. * CLHEP::pi;
   G4double vx = sin(theta) * cos(phi);
   G4double vy = sin(theta) * sin(phi);
   G4double vz = cos(theta);
   G4ThreeVector particleVec = G4ThreeVector(vx, vy, vz);

   return particleVec;
}
Exemplo n.º 8
0
int AddSmallCons(G4double dist, G4double density, G4LogicalVolume* motherLogical, int level) {
	G4double dTheta = THETA_DIST_FACTOR * 2 * asin(SMALL_CONS_R / dist) * mm; /* Theta distance between adjacent cons */

		const G4double SMALL_CONS_R   = 25; /* Radius of the samll cons */
		
	int cnt = 0;
	for(G4double theta = dTheta; theta + dTheta < M_PI; theta += dTheta) { // theta is between [0, Pi] 

		G4double dPhi = PHI_DIST_FACTOR * 2 * asin(SMALL_CONS_R / (dist * sin(theta))); /* Phi distance between adjacent spheres */

		for (G4double phi = dPhi; 2 * phi + dPhi < M_PI; phi += dPhi ) // phi is between [0, Pi/2]
			if (density == 1.0 || G4UniformRand() <= density)
			{
				/* Cons from the outer layers will have bigger radius */
				G4Cons* smallCons = new G4Cons("", 0 * mm, SMALL_CONS_R * mm, 0 * mm, 0.1 * mm, 50 * level * mm, 0 * deg, 360 * deg);
					
				/* Calculate the new center of the cons */
				G4ThreeVector v(dist * sin(theta) * cos(phi) * mm, dist * sin(theta) * sin(phi) * mm, dist * cos(theta) * mm);

				G4RotationMatrix* rot = new G4RotationMatrix();								
				
			    G4double alfa = v.angle(G4ThreeVector(0, 0, 1));
				rot->rotateY(M_PI-v.theta()/*(M_PI-alfa) * rad*/);
				rot->rotateX(-v.phi());
	
				G4LogicalVolume* logicSmallCons = new G4LogicalVolume(smallCons, Air, "", 0, 0, 0);
					
				G4PVPlacement* physiSmallCons = new G4PVPlacement(0, v, logicSmallCons, "", motherLogical, false, 0, false);

				//assert(physiSmallCons->CheckOverlaps());
				cnt++; 
		    }
		}

	return cnt;
}
Exemplo n.º 9
0
G4VParticleChange*
RichG4Cerenkov::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){

  // Do not do RICH stuff
  //  return G4Cerenkov::PostStepDoIt(aTrack,aStep);


  // Get the current point
  G4Material &material=*aTrack.GetMaterial();

  if(!(material.GetName()==aerogel_name) && 
     !(material.GetName()==naf_name))
    return G4Cerenkov::PostStepDoIt(aTrack,aStep);

  // This is a RICH radiator, use the tools already available to compute everything
  // Copy and paste of original G4Cerenkov class

  aParticleChange.Initialize(aTrack);

  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
  const G4Material* aMaterial = aTrack.GetMaterial();

  G4StepPoint* pPreStepPoint  = aStep.GetPreStepPoint();
  G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
if(!aParticle || !aMaterial || !pPreStepPoint || !pPostStepPoint)return pParticleChange;
  G4ThreeVector x0 = pPreStepPoint->GetPosition();
  G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
  G4double t0 = pPreStepPoint->GetGlobalTime();


  G4MaterialPropertiesTable* aMaterialPropertiesTable =
    aMaterial->GetMaterialPropertiesTable();
  if (!aMaterialPropertiesTable) return pParticleChange;
  const G4MaterialPropertyVector* Rindex =
    aMaterialPropertiesTable->GetProperty("RINDEX");
  if (!Rindex) return pParticleChange;
  
  // particle charge
  const G4double charge = aParticle->GetDefinition()->GetPDGCharge();
  
  // particle beta
  const G4double beta = (pPreStepPoint ->GetBeta() +
			 pPostStepPoint->GetBeta())/2.;

  G4double step_length = aStep.GetStepLength();

  G4double MeanNumberOfPhotons=GetAverageNumberOfPhotons(charge,beta,step_length/cm,x0,p0);

  // Copy and paste from the original function
  if (MeanNumberOfPhotons <= 0.0) {
    // return unchanged particle and no secondaries
    aParticleChange.SetNumberOfSecondaries(0);
    return pParticleChange;
  }
  
  MeanNumberOfPhotons *= step_length;
  
  G4int NumPhotons = (G4int) G4Poisson(MeanNumberOfPhotons);
  
  if (NumPhotons <= 0) {
    // return unchanged particle and no secondaries  
    aParticleChange.SetNumberOfSecondaries(0);
    return pParticleChange;
  }

  ////////////////////////////////////////////////////////////////
  
  aParticleChange.SetNumberOfSecondaries(NumPhotons);
  
  if (fTrackSecondariesFirst) {
    if (aTrack.GetTrackStatus() == fAlive )
      aParticleChange.ProposeTrackStatus(fSuspend);
  }
  
  ////////////////////////////////////////////////////////////////

  G4double BetaInverse = 1./beta;
  for (G4int i = 0; i < NumPhotons; i++) {
    G4double sampledEnergy, sampledRI; 
    G4double cosTheta, sin2Theta;

    geant _RINDEX;
    geant _p;
    _p=getmomentum_(&_RINDEX); // _p is in GeV/c, _RINDEX is the refractive index for this guy

    sampledEnergy=_p*GeV;     // energy in G4 units
    sampledRI=_RINDEX;
    cosTheta = BetaInverse / sampledRI;  
    sin2Theta = (1.0 - cosTheta)*(1.0 + cosTheta);

    // Generate random position of photon on cone surface 
    // defined by Theta 
    G4double rand = G4UniformRand();
    G4double phi = twopi*rand;
    G4double sinPhi = sin(phi);
    G4double cosPhi = cos(phi);
    // calculate x,y, and z components of photon energy
    // (in coord system with primary particle direction 
    //  aligned with the z axis)
    
    G4double sinTheta = sqrt(sin2Theta); 
    G4double px = sinTheta*cosPhi;
    G4double py = sinTheta*sinPhi;
    G4double pz = cosTheta;
    // Create photon momentum direction vector 
    // The momentum direction is still with respect
    // to the coordinate system where the primary
    // particle direction is aligned with the z axis  
    G4ParticleMomentum photonMomentum(px, py, pz);
    // Rotate momentum direction back to global reference
    // system 
    photonMomentum.rotateUz(p0);
    // Determine polarization of new photon 
    G4double sx = cosTheta*cosPhi;
    G4double sy = cosTheta*sinPhi; 
    G4double sz = -sinTheta;
    G4ThreeVector photonPolarization(sx, sy, sz);
    // Rotate back to original coord system 
    photonPolarization.rotateUz(p0);
    // Generate a new photon:

    G4DynamicParticle* aCerenkovPhoton =
      new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(), 
			    photonMomentum);
    aCerenkovPhoton->SetPolarization
      (photonPolarization.x(),
       photonPolarization.y(),
       photonPolarization.z());
    aCerenkovPhoton->SetKineticEnergy(sampledEnergy);
    rand = G4UniformRand();
    G4double delta=rand*aStep.GetStepLength();
    G4double deltaTime = delta /
      ((pPreStepPoint->GetVelocity()+
	pPostStepPoint->GetVelocity())/2.);
    
    G4double aSecondaryTime = t0 + deltaTime;
    
    G4ThreeVector aSecondaryPosition = x0 + rand * aStep.GetDeltaPosition();
    
    G4Track* aSecondaryTrack = new G4Track(aCerenkovPhoton,aSecondaryTime,aSecondaryPosition);
    aSecondaryTrack->SetTouchableHandle(aStep.GetPreStepPoint()->GetTouchableHandle());
    aSecondaryTrack->SetParentID(aTrack.GetTrackID());
    aParticleChange.AddSecondary(aSecondaryTrack);
  }

  if (verboseLevel>0) {
    G4cout << "\n Exiting from RichG4Cerenkov::DoIt -- NumberOfSecondaries = " 
	   << aParticleChange.GetNumberOfSecondaries() << G4endl;
  }
  
  return pParticleChange;
}
Exemplo n.º 10
0
G4VParticleChange*
RichG4OpBoundaryProcess::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep)
{
  // I do not know where these guys come, but I kill them explicitly
  if(isnan(aTrack.GetPosition()[0]) || isnan(aTrack.GetMomentum()[0])){
    aParticleChange.ProposeTrackStatus(fStopAndKill);
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }

  // Initialization
  aParticleChange.Initialize(aTrack);

  // Get the properties of the particle
  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();

  G4double thePhotonMomentum      = aParticle->GetTotalMomentum();
  G4StepPoint* pPreStepPoint  = aStep.GetPreStepPoint();
  G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();


  if(isnan(pPreStepPoint->GetPosition()[0])){
    aParticleChange.ProposeTrackStatus(fStopAndKill);
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }
  
  if (pPostStepPoint->GetStepStatus() != fGeomBoundary){
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }

  if (aTrack.GetStepLength()<=1e-7){
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }
  
  G4Material *Material1 = pPreStepPoint  -> GetMaterial();
  G4Material *Material2 = pPostStepPoint -> GetMaterial();
  
  // Follow the standard path if not RICH radiator to vacuum transition
  if(!(Material1->GetName()==aerogel_name))
    return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);
//      return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);

  if(Material2->GetName()==aerogel_name)
    return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);
//      return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);
   
  if(!Material1->GetMaterialPropertiesTable() ||
     !Material2->GetMaterialPropertiesTable()){
    aParticleChange.ProposeTrackStatus(fStopAndKill);
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }


  OldMomentum       = aParticle->GetMomentumDirection();
  OldPolarization   = aParticle->GetPolarization();


  // Get the normal of the surface
  G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();


  G4Navigator* theNavigator =
    G4TransportationManager::GetTransportationManager()->
    GetNavigatorForTracking();
  
  G4ThreeVector theLocalPoint = theNavigator->
    GetGlobalToLocalTransform().
    TransformPoint(theGlobalPoint);
  
  G4ThreeVector theLocalNormal;   // Normal points back into volume
  
  G4bool valid;
  theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
  
  if (valid) {
    theLocalNormal = -theLocalNormal;
  }
  else {
    aParticleChange.ProposeTrackStatus(fStopAndKill);
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);

    G4cerr << " RichG4OpBoundaryProcess/PostStepDoIt(): "
	   << " The Navigator reports that it returned an invalid normal"
	   << G4endl;
    G4Exception("RichG4OpBoundaryProcess::PostStepDoIt",
		"Invalid Surface Normal",
		EventMustBeAborted,
		"Geometry must return valid surface normal");
    //    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }
  
  theGlobalNormal = theNavigator->GetLocalToGlobalTransform().
    TransformAxis(theLocalNormal);
  
  if (OldMomentum * theGlobalNormal > 0.0) {
    theGlobalNormal = -theGlobalNormal;
  }
  
  // Get the refractive index
  G4ThreeVector position = aTrack.GetPosition();
  const G4double cvpwl=1.2398E-6;
  G4double wavelength=cvpwl/thePhotonMomentum*GeV;

  Rindex1=RichRadiatorTileManager::get_refractive_index(position[0]/cm,position[1]/cm,wavelength);
  G4MaterialPropertyVector* Rindex = Material2->GetMaterialPropertiesTable()->GetProperty("RINDEX");

  if(!Rindex){
    aParticleChange.ProposeTrackStatus(fStopAndKill);
    return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
  }
#if G4VERSION_NUMBER >945
  Rindex2 = Rindex->Value(thePhotonMomentum);
#else
  Rindex2 = Rindex->GetProperty(thePhotonMomentum);
#endif
  
  // SKIP photons exiting through the lateral sides of the tiles
   if(std::abs(theGlobalNormal[2])<1e-6){
cout <<" g4rich::abs "<<std::abs(theGlobalNormal[2])<<" "<<abs(theGlobalNormal[2])<<" "<<theGlobalNormal[2]<<endl;
     return G4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);
   } 
//   if(abs(theGlobalNormal[2])<1e-6)  return TOFG4OpBoundaryProcess::PostStepDoIt(aTrack,aStep);  

  DielectricDielectric();
  //  return G4OpBoundaryProcess::PostStepDoIt(aTrack, aStep); //CJD this solves the f*****g problem 

  NewMomentum = NewMomentum.unit();
  NewPolarization = NewPolarization.unit();

  if(Material1->GetName()==aerogel_name){
    // Simple parameterization to get the right number of p.e.
    if(G4UniformRand()<RICHDB::scatloss){
      aParticleChange.ProposeTrackStatus(fStopAndKill);
      return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
    }
    
    // Forward scattering
    if(G4UniformRand()<RICHDB::scatprob){
      // Aerogel scattering effect
      double phi=2*M_PI*G4UniformRand();
      double theta=sqrt(-2*log(G4UniformRand()))*RICHDB::scatang;
      
      // Build the vector
    G4ThreeVector direction(sin(theta)*cos(phi),sin(theta)*sin(phi),cos(theta));
    direction.rotateUz(NewMomentum);
    NewMomentum=direction.unit();
    }
  }

  aParticleChange.ProposeMomentumDirection(NewMomentum);
  aParticleChange.ProposePolarization(NewPolarization);

  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
Exemplo n.º 11
0
/*
// For using ROOT classes.
// When using ROOT classes, it have to be thread local or mutex locked.
// I don't know _G4MT_TLS_ is truely needed or not.
// https://indico.cern.ch/event/226961/material-old/0/0?contribId=0
// In case without, this code looks like working well...
G4ThreadLocal TF1 *fEneFnc_G4MT_TLS_ = 0;
*/
BIPrimaryGeneratorAction::BIPrimaryGeneratorAction(BeamType beamType, G4bool gridFlag, G4bool quarterFlag)
   : G4VUserPrimaryGeneratorAction(),
     fParticleGun(nullptr),
     fInputFile(nullptr),
     fHisSource(nullptr),
     fEneFnc(nullptr),
     fAngFnc(nullptr)
{
   fBeamType = beamType;

   fForGrid = gridFlag;

   fUseQuarter = quarterFlag;
   if(fUseQuarter) fPhiLimit = 0.5 * CLHEP::pi;
   else fPhiLimit = 2. * CLHEP::pi;
   
   fDx = (458. - 78.) / 15.;
   fDy = (332 - 152) / (log10(60.) - log10(20.));

   G4AutoLock lock(&mutexInPGA);
   
   Int_t seed = G4UniformRand() * 1000000;
   G4cout << "Seed of PGA = " << seed << G4endl;
   gRandom->SetSeed(seed);
   
   G4int nPar = 1;
   fParticleGun = new G4ParticleGun(nPar);

   fZPosition = -300.*mm;
   //fZPosition = -160.*mm; // Minimum distance for new beam

   fParVec = G4ThreeVector(0., 0., 1.);
   
   G4ParticleTable *parTable = G4ParticleTable::GetParticleTable();
   G4ParticleDefinition *proton = parTable->FindParticle("proton");
   fParticleGun->SetParticleDefinition(proton);
   fParticleGun->SetParticlePosition(G4ThreeVector(0., 0., fZPosition));
   fParticleGun->SetParticleMomentumDirection(fParVec);
   fParticleGun->SetParticleEnergy(fEnergy);

   fInputFile = new TFile("randomSource.root", "OPEN");
   fHisSource = (TH2D*)fInputFile->Get("HisMap");
   fHisSource->SetName("fHisSource");
   
   DefineCommands();

// Pointer of Function is not good for readable code?
// And also, use if statement does not make program slow.
   if(fBeamType == kFirstBeam){
      fEneFnc = new TF1("fncEne", "exp([0]*x)", 0., 100.);
      fEneFnc->SetParameter(0, -4.77205e-02);
      
      GunFuncPointer = &BIPrimaryGeneratorAction::FirstBeamGun;
   }
   else if(fBeamType == kSecondBeam)
      GunFuncPointer = &BIPrimaryGeneratorAction::SecondBeamGun;
   
   else if(fBeamType == kThirdBeam){
      fEneFnc = new TF1("fncEne", "exp([0]*x)", 0., 100.);
      fEneFnc->SetParameter(0, -4.77205e-02);
      
      fAngFnc = new TF1("fAngFnc", "exp([0]*x)", 0., 20.);
      fAngFnc->SetParameter(0, -8.98131e-02);

      GunFuncPointer = &BIPrimaryGeneratorAction::ThirdBeamGun;
   }
   else{
      G4cout << "Beam type is wrong.  Please check it." << G4endl;
      exit(0);
   }
}