Hi everyone,
I want to use ParticleGun to create multiple sources with the following parameters:
- Shape: Cylinder, r=1.35 mm, halfz=14.5 mm
- Particle: gamma
- Energy: 1.173 and 1.332 MeV (cobalt 60)
- Number of sources: 30. Each source will be placed on a sphere. They focus on the center of the sphere. The position and rotation of each source will depend on spherical coordinates, including the phi and theta angles.
Here is my code to implement a single source. Can anyone help me please to create multiple sources using the ParticleGun? Thank you in advance.
PrimaryGeneratorAction::PrimaryGeneratorAction()
{
fParticleGun = new G4ParticleGun(1);
// Particle
//
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
G4String particleName;
G4ParticleDefinition* particle = particleTable->FindParticle(particleName="gamma");
fParticleGun->SetParticleDefinition(particle);
InitFunction();
}
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete fParticleGun;
}
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
// Shape and Position
//
G4double x0 = 0.*cm, y0 = 0.*cm, z0 = 384.2*mm;
G4double radius = 1.35*mm;
G4double halfz = 14.5*mm;
G4ThreeVector pos;
G4double rho, alpha;
rho = G4UniformRand()*radius;
alpha = G4UniformRand()*twopi;
pos.setX(rho*std::sin(alpha));
pos.setY(rho*std::cos(alpha));
G4double z = z0 + halfz*(2*G4UniformRand() - 1); //z uniform in (-halfz, +halfz)
pos.setZ(z);
fParticleGun->SetParticlePosition(pos);
// Direction uniform in solid angle
//
G4double alphaMin = 0*deg; //alpha in [0,pi]
G4double alphaMax = 3*deg;
G4double fCosAlphaMin, fCosAlphaMax; //solid angle
G4double fPsiMin, fPsiMax;
fCosAlphaMin = std::cos(alphaMin);
fCosAlphaMax = std::cos(alphaMax);
fPsiMin = 0*deg; //psi in [0, 2*pi]
fPsiMax = 360*deg;
G4double cosAlpha = fCosAlphaMin-G4UniformRand()*(fCosAlphaMin-fCosAlphaMax);
G4double sinAlpha = std::sqrt(1. - cosAlpha*cosAlpha);
G4double psi = fPsiMin + G4UniformRand()*(fPsiMax - fPsiMin);
G4double ux = sinAlpha*std::cos(psi),
uy = sinAlpha*std::sin(psi),
uz = cosAlpha;
G4double theta = 180*deg, phi = 0*deg;
G4ThreeVector rotationAxis = G4ThreeVector(std::sin(theta)*std::cos(phi),
std::sin(theta)*std::sin(phi),
std::cos(theta));
G4ThreeVector dir(ux, uy, uz);
dir.rotateUz(rotationAxis);
fParticleGun->SetParticleMomentumDirection(dir);
// Energy
//
G4double energy = InverseCumul();
fParticleGun->SetParticleEnergy(energy);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
G4double PrimaryGeneratorAction::InverseCumul()
{
// tabulated function
// Y is assumed positive, linear per segment, continuous
// --> cumulative function is second order polynomial
//choose y randomly
G4double Yrndm = G4UniformRand()*fYC[fNPoints-1];
//find bin
G4int j = fNPoints-2;
while ((fYC[j] > Yrndm) && (j > 0)) j--;
//y_rndm --> x_rndm : fYC(x) is second order polynomial
G4double Xrndm = fX[j];
G4double a = fSlp[j];
if (a != 0.)
{
G4double b = fY[j]/a, c = 2*(Yrndm - fYC[j])/a;
G4double delta = b*b + c;
G4int sign = 1; if (a < 0.) sign = -1;
Xrndm += sign*std::sqrt(delta) - b;
}
else if (fY[j] > 0.)
{
Xrndm += (Yrndm - fYC[j])/fY[j];
};
return Xrndm;
}
void PrimaryGeneratorAction::InitFunction()
{
// tabulated function
// Y is assumed positive, linear per segment, continuous
//
fNPoints = 2;
const G4double xx[] = {1.173*MeV, 1.332*MeV};
const G4double yy[] = {0.5, 0.5};
//copy arrays in std::vector and compute fMax
//
fX.resize(fNPoints); fY.resize(fNPoints);
fYmax = 0.;
for (G4int j=0; j<fNPoints; j++) {
fX[j] = xx[j]; fY[j] = yy[j];
if (fYmax < fY[j]) fYmax = fY[j];
};
//compute slopes
//
fSlp.resize(fNPoints);
for (G4int j=0; j<fNPoints-1; j++) {
fSlp[j] = (fY[j+1] - fY[j])/(fX[j+1] - fX[j]);
};
//compute cumulative function
//
fYC.resize(fNPoints);
fYC[0] = 0.;
for (G4int j=1; j<fNPoints; j++) {
fYC[j] = fYC[j-1] + 0.5*(fY[j] + fY[j-1])*(fX[j] - fX[j-1]);
};
}