20 #include "G4ParticleGun.hh"
21 #include "G4IonTable.hh"
22 #include "G4ParticleDefinition.hh"
23 #include "Randomize.hh"
24 #include "G4UImanager.hh"
25 #include "G4SystemOfUnits.hh"
34 _shootAxis(0, 0, 1), _acceptanceFlag(false), _rndmMinPositionFlag(false), _rndmMaxPositionFlag(false), _rndmFromFlat(
35 false), _rndmFromSphere(false), _rndmSphereCenter(0., 0., 0.), _rndmSphereCapExtRand(0.), _rndmSphereCapAlpha(
36 0.), _rndmSphereCapBeta(0.), _rndmSphereCapRotMat(G4RotationMatrix::IDENTITY), _rndmSphereRadius(0.), _rndmMinEnergyFlag(
37 false), _rndmMaxEnergyFlag(false), _spectralIndexFlag(false), _rndmMinThetaFlag(false), _rndmMaxThetaFlag(
38 false), _rndmMinPhiFlag(false), _rndmMaxPhiFlag(false), _rndmPosFlag(false), _rndmDirFlag(false), _position(0.,
39 0., 0.), _minPosition(0., 0., 0.), _maxPosition(0., 0., 0.), _energy(10. * GeV), _minEnergy(10. * GeV), _maxEnergy(
40 10. * GeV), _spectralIndex(-3.2), _sinTheta(0.), _cosTheta(1.), _minThetaRand(0.), _maxThetaRand(.5), _minCos2ThetaRand(
41 0.), _maxCos2ThetaRand(1.), _sinPhi(0.), _cosPhi(1.), _minPhi(0.), _maxPhi(2 * CLHEP::pi), _direction(0., 0.,
46 _gunGenerator =
new G4ParticleGun(1);
47 _gunGenerator->SetParticleDefinition(G4ParticleTable::GetParticleTable()->FindParticle(
"geantino"));
64 if (particle ==
"C12") {
66 G4ParticleDefinition* c12 = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(6, 12, 0.);
67 ((G4ParticleGun*) _gunGenerator)->SetParticleDefinition(c12);
68 ((G4ParticleGun*) _gunGenerator)->SetParticleCharge(6 * eplus);
70 else if (particle ==
"Fe56") {
72 G4ParticleDefinition* fe56 = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(26, 56, 0.);
73 ((G4ParticleGun*) _gunGenerator)->SetParticleDefinition(fe56);
74 ((G4ParticleGun*) _gunGenerator)->SetParticleCharge(26 * eplus);
77 G4UImanager::GetUIpointer()->ApplyCommand(G4String(
"/gun/particle ").append(particle));
82 G4RotationMatrix& GGSGunGeneratorAction::_ComputeRotMatrix(
double cosAlpha,
double sinAlpha,
double cosBeta,
86 class Rot3:
public G4RotationMatrix {
88 void SetMatrix(
double mxx,
double mxy,
double mxz,
double myx,
double myy,
double myz,
double mzx,
double mzy,
102 static Rot3 retMatrix;
127 double xx = cosAlpha * cosBeta * cosBeta + sinBeta * sinBeta;
128 double xy = cosBeta * cosAlpha * sinBeta - cosBeta * sinBeta;
129 double xz = cosBeta * sinAlpha;
130 double yx = sinBeta * cosAlpha * cosBeta - sinBeta * cosBeta;
131 double yy = sinBeta * cosAlpha * sinBeta + cosBeta * cosBeta;
132 double yz = sinBeta * sinAlpha;
133 double zx = -sinAlpha * cosBeta;
134 double zy = -sinAlpha * sinBeta;
135 double zz = cosAlpha;
137 retMatrix.SetMatrix(xx, xy, xz, yx, yy, yz, zx, zy, zz);
145 void GGSGunGeneratorAction::_ResetFlat() {
147 _rndmFromFlat =
false;
148 _minPosition = _maxPosition = G4ThreeVector(0., 0., 0.);
149 _shootAxis = G4ThreeVector(0, 0, 1);
154 void GGSGunGeneratorAction::_ResetSphere() {
156 _rndmFromSphere =
false;
157 _rndmSphereCenter = G4ThreeVector(0., 0., 0.);
158 _rndmSphereRadius = 0;
159 _rndmSphereCapExtRand = 0.;
160 _rndmSphereCapRotMat = G4RotationMatrix::IDENTITY;
165 void GGSGunGeneratorAction::_SetRndmFromSurface(
int surfType) {
171 else if (surfType == 1) {
172 if (_minPosition[0] < _maxPosition[0] && _minPosition[1] < _maxPosition[1] && _minPosition[2] == _maxPosition[2]) {
173 _rndmFromFlat =
true;
174 _shootAxis = G4ThreeVector(0, 0, 1);
176 else if (_minPosition[0] == _maxPosition[0] && _minPosition[1] < _maxPosition[1]
177 && _minPosition[2] < _maxPosition[2]) {
178 _rndmFromFlat =
true;
179 _shootAxis = G4ThreeVector(1, 0, 0);
181 else if (_minPosition[0] < _maxPosition[0] && _minPosition[1] == _maxPosition[1]
182 && _minPosition[2] < _maxPosition[2]) {
183 _rndmFromFlat =
true;
184 _shootAxis = G4ThreeVector(0, 1, 0);
187 _rndmFromFlat =
false;
188 _shootAxis = G4ThreeVector(0, 0, 1);
194 else if (surfType == 2) {
195 if (_rndmSphereRadius > 0. && _rndmSphereCapExtRand > 0.) {
196 _rndmFromSphere =
true;
198 _rndmSphereCapRotMat = _ComputeRotMatrix(cos(_rndmSphereCapAlpha), sin(_rndmSphereCapAlpha),
199 cos(_rndmSphereCapBeta), sin(_rndmSphereCapBeta));
209 void GGSGunGeneratorAction::_SetRndmDirFlag() {
210 if ((_rndmMinThetaFlag && _rndmMaxThetaFlag) || (_rndmMinPhiFlag && _rndmMaxPhiFlag))
213 _rndmDirFlag =
false;
218 void GGSGunGeneratorAction::_SetRndmPosFlag() {
219 if (_rndmMinPositionFlag && _rndmMaxPositionFlag)
222 _rndmPosFlag =
false;
229 static const std::string routineName(
"GGSGunGeneratorAction::GeneratePrimaries");
230 static const G4ThreeVector xDirection(1, 0, 0);
231 static const G4ThreeVector yDirection(0, 1, 0);
236 G4ThreeVector position(_position);
237 G4ThreeVector direction(_direction);
238 G4double energy(_energy);
240 bool acceptanceCheck =
true;
249 G4double cosPhi(_cosPhi);
250 G4double sinPhi(_sinPhi);
251 if (_rndmMinPhiFlag && _rndmMaxPhiFlag) {
252 double phi = CLHEP::RandFlat::shoot(_minPhi, _maxPhi);
257 G4double sinTheta(_sinTheta);
258 G4double cosTheta(_cosTheta);
259 if (_rndmMinThetaFlag && _rndmMaxThetaFlag) {
260 if (_rndmFromFlat || _rndmFromSphere) {
262 float cos2Theta = CLHEP::RandFlat::shoot(_minCos2ThetaRand, _maxCos2ThetaRand);
263 cosTheta = sqrt(cos2Theta);
264 sinTheta = sqrt(1 - cos2Theta);
271 cosTheta = 1 - 2 * CLHEP::RandFlat::shoot(_minThetaRand, _maxThetaRand);
272 sinTheta = sqrt(1 - cosTheta * cosTheta);
278 direction[0] = -sinTheta * cosPhi;
279 direction[1] = -sinTheta * sinPhi;
280 direction[2] = -cosTheta;
285 if (_rndmMinPositionFlag && _rndmMaxPositionFlag) {
287 position[0] = CLHEP::RandFlat::shoot(_minPosition(0), _maxPosition(0));
288 position[1] = CLHEP::RandFlat::shoot(_minPosition(1), _maxPosition(1));
289 position[2] = CLHEP::RandFlat::shoot(_minPosition(2), _maxPosition(2));
296 if (_shootAxis == xDirection) {
297 double buf = direction[0];
298 direction[0] = direction[2];
299 direction[2] = direction[1];
302 else if (_shootAxis == yDirection) {
303 double buf = direction[0];
304 direction[0] = direction[1];
305 direction[1] = direction[2];
310 else if (_rndmFromSphere) {
314 float cosGamma = 1 - 2 * CLHEP::RandFlat::shoot(0., _rndmSphereCapExtRand);
315 float delta = CLHEP::RandFlat::shoot(0., 2 * CLHEP::pi);
316 float sinGamma = sqrt(1 - cosGamma * cosGamma);
317 float sinDelta = sin(delta);
318 float cosDelta = cos(delta);
321 position[0] = _rndmSphereRadius * sinGamma * cosDelta;
322 position[1] = _rndmSphereRadius * sinGamma * sinDelta;
323 position[2] = _rndmSphereRadius * cosGamma;
326 position *= _rndmSphereCapRotMat;
327 position += _rndmSphereCenter;
335 direction *= _ComputeRotMatrix(cosGamma, sinGamma, cosDelta, sinDelta);
336 direction *= _rndmSphereCapRotMat;
341 if (_acceptanceFlag && (_rndmPosFlag || _rndmDirFlag)) {
345 if (!acceptanceCheck)
349 }
while (!acceptanceCheck);
352 if (_rndmMinEnergyFlag && _rndmMaxEnergyFlag) {
353 if (_spectralIndexFlag) {
354 energy = _GenSpectrumPowerLaw(_minEnergy, _maxEnergy, _spectralIndex);
357 energy = CLHEP::RandFlat::shoot(_minEnergy, _maxEnergy);
361 COUT(DEEPDEB) <<
"Generated primary:" <<
ENDL;
362 CCOUT(DEEPDEB) <<
" PDG code: " << _gunGenerator->GetParticleDefinition()->GetPDGEncoding() <<
ENDL;
363 CCOUT(DEEPDEB) <<
" position: " << position <<
ENDL;
364 CCOUT(DEEPDEB) <<
" direction: " << direction <<
ENDL;
365 CCOUT(DEEPDEB) <<
" energy: " << energy <<
ENDL;
370 _gunGenerator->SetParticlePosition(position);
371 _gunGenerator->SetParticleMomentumDirection(direction);
372 _gunGenerator->SetParticleEnergy(energy);
375 _gunGenerator->GeneratePrimaryVertex(anEvent);
380 G4double GGSGunGeneratorAction::_GenSpectrumPowerLaw(G4double Emin, G4double Emax, G4double gamma) {
384 energy = CLHEP::RandFlat::shoot(Emin, Emax);
387 G4double alpha = 1. + gamma;
389 energy = exp(log(Emin) + CLHEP::RandFlat::shoot(0., 1.) * (log(Emax) - log(Emin)));
394 energy = pow((CLHEP::RandFlat::shoot(0., 1.) * (pow(Emax, alpha) - pow(Emin, alpha)) + pow(Emin, alpha)),
GGSGunGeneratorAction()
Constructor.
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
Class for GGS detector construction.
void SetMaxPhi(G4double val)
Sets the maximum value for phi.
Messenger class for gun generator action.
A single-particle generator.
const GGSVGeometryConstruction * GetGeometry() const
Returns a pointer to the geometry.
#define CCOUT(level)
Smart log utility which prints no header at the beginning of the line.
void SetGunParticle(const G4String &particle)
Sets the particle to be used by G4ParticleGun.
static GGSRunManager * GetRunManager()
Static getter function the run manager.
~GGSGunGeneratorAction()
Destructor.
#define RegisterGA(gaClassName, gaName)
Macro for registration of user generator actions.
void GeneratePrimaries(G4Event *)
GeneratePrimaries.
void SetMinPhi(G4double val)
Sets the minimum value for phi.
virtual bool IsInsideAcceptance(const G4ThreeVector &, const G4ThreeVector &) const
Checks if a particle is inside the instrument's acceptance.