///////////////////////////////////////////////////////////////////////// // G4Tutorial: // // PrimaryGenerator.cc // // Definition of primary particles and their properties (spectrum // of energies, initial vertices, ...) // ///////////////////////////////////////////////////////////////////////// #include "PrimaryGenerator.hh" #include "PrimaryGeneratorMessenger.hh" #include "G4ParticleDefinition.hh" #include "G4ParticleTable.hh" #include "G4Electron.hh" #include "G4Gamma.hh" #include "G4Positron.hh" #include "G4ParticleGun.hh" #include "G4Event.hh" #include "Randomize.hh" PrimaryGenerator::PrimaryGenerator() { // Initialization of particle source properties primaryKineticEnergy = 1.0 * MeV; sigmaKineticEnergy = 0 * keV; incidentAngle = 0.0 * deg; // Instantiation of the particle gun. As default arguments primaries // are assumed to be electrons, and the number of particles per invokation // of the GeneratePrimaryVertex method is set to 1: particleGun = new G4ParticleGun(G4Electron::Electron(), 1); // Instantiation of messenger messenger = new PrimaryGeneratorMessenger(this); } PrimaryGenerator::~PrimaryGenerator() { // The instances of particle gun and messenger are deleted: delete particleGun; delete messenger; } void PrimaryGenerator::GeneratePrimaries(G4Event* event) { // This implementation of the GeneratePrimaries method creates primary // particles, where // *) the particle energy is randomly sampled from a Gaussian distribution // (the primary energy and sigma are defined by the data members // primaryKineticEnergy and sigmaKineticEnergy) // *) the beam axis lies in the z-y-plane (with z < 0) and is assumed to // cross the detector surface in the origin of the coordinate system // (the detector surface lies in the x-y-plane). // The beam axis can be rotated, where the x-axis acts as rotation axis. // The rotation angle is defined as the angle between the negative z-axis // and the beam axis (the rotation angle is given by the data member // incidentAngle). // The G4RandGauss::shoot(mean, sigma) function is used for sampling randomly // the kinetic energy if the user has specified a sigma > 0.0: G4double kineticEnergy = primaryKineticEnergy; if(sigmaKineticEnergy > 0.0 * keV) kineticEnergy = G4RandGauss::shoot(primaryKineticEnergy, sigmaKineticEnergy); // The particle gun (which is a concrete implementation of // G4VPrimaryGenerator) is used to create the primary particle/vertex. // Particle properties can be set by using dedicated member functions of // the particle gun implementation: // // Exercise 2.7 // kineticEnergy = 662.0*keV; particleGun ->SetParticleDefinition(G4Gamma::GammaDefinition()); particleGun -> SetParticleEnergy(kineticEnergy); //the detector has z coordinate going from 0 to 4 cm (0 to boxLenght), //therefore we place it at (0,0,5.0*cm) G4double zOfSource = 5.0*cm; particleGun -> SetParticlePosition(G4ThreeVector(0,0,zOfSource)); G4double cosTheta = -1.0+2.0*G4UniformRand(); G4double phi = twopi*G4UniformRand(); G4double sinTheta = sqrt(1-cosTheta*cosTheta); //these are the cosines for an isotropic direction particleGun -> SetParticleMomentumDirection(G4ThreeVector(sinTheta*cos(phi), sinTheta*sin(phi), cosTheta)); // //End of exercise 2.7 // // Creating the primary vertex: The current event must be passed as argument. particleGun -> GeneratePrimaryVertex(event); } void PrimaryGenerator::SetPrimaryKineticEnergy(G4double kinEnergy) { if(kinEnergy > 0.0 * MeV) { primaryKineticEnergy = kinEnergy; } } void PrimaryGenerator::SetSigmaKineticEnergy(G4double sigma) { if(sigma >= 0.0 * keV) { sigmaKineticEnergy = sigma; } } void PrimaryGenerator::SetIncidentAngle(G4double angle) { if(angle >= 0.0 * deg && angle < 90.0 * deg) { incidentAngle = angle; } } void PrimaryGenerator::SetParticleType(G4String name) { // The particle iterator is used to search the particle table for a // certain particle G4ParticleTable::G4PTblDicIterator* particleIterator = G4ParticleTable::GetParticleTable() -> GetIterator(); particleIterator -> reset(); while( (*particleIterator)() ) { G4ParticleDefinition* particle = particleIterator -> value(); G4String particleName = particle -> GetParticleName(); // Only if the particle was found, the new primary particle type is // forwarded to the particle gun if(particleName == name) { particleGun -> SetParticleDefinition(particle); break; } } }