#include "PrimaryGeneratorAction.hh" #include "DetectorConstruction.hh" #include "G4Event.hh" #include "G4ParticleGun.hh" #include "G4ParticleTable.hh" #include "G4ParticleDefinition.hh" #include "G4ThreeVector.hh" #include "G4SystemOfUnits.hh" #include "Randomize.hh" // Toggle this to true if you want to place primaries uniformly in the crystal static const bool kUniformInVolume = false; PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* det) : G4VUserPrimaryGeneratorAction(), fDetector(det), fParticleGun(new G4ParticleGun(1)) // 1 primary per event { auto* eMinus = G4ParticleTable::GetParticleTable()->FindParticle("e-"); fParticleGun->SetParticleDefinition(eMinus); fParticleGun->SetParticleEnergy(500. * keV); const G4double L = fDetector->GetScintillatorSize(); // Start just INSIDE the -X face, shoot along +X so track crosses the crystal const G4double eps = 0.5 * mm; fParticleGun->SetParticlePosition(G4ThreeVector(0.,0.,0.)); fParticleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., +1.)); } PrimaryGeneratorAction::~PrimaryGeneratorAction() { delete fParticleGun; } void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent) { if (kUniformInVolume) { // Optional: uniformly distribute the source inside the scintillator const G4double L = fDetector->GetScintillatorSize(); const auto rU = []() { return 2. * G4UniformRand() - 1.; }; const G4ThreeVector pos(0.5 * L * rU(), 0.5 * L * rU(), 0.5 * L * rU()); fParticleGun->SetParticlePosition(pos); } fParticleGun->GeneratePrimaryVertex(anEvent); }