Warning, file /geant4/examples/extended/medical/dna/jetcounter/src/PrimaryGeneratorAction.cc was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "PrimaryGeneratorAction.hh"
0030
0031 #include "G4Event.hh"
0032 #include "G4ParticleGun.hh"
0033 #include "G4PhysicalConstants.hh"
0034 #include "G4SystemOfUnits.hh"
0035 #include "Randomize.hh"
0036
0037 #include <fstream>
0038
0039 PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* detector)
0040 : G4VUserPrimaryGeneratorAction(), fDetector(detector)
0041 {
0042 fpParticleGun = std::make_unique<G4ParticleGun>();
0043 fpParticleGun->SetParticleEnergy(-1);
0044 }
0045
0046
0047
0048 void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
0049 {
0050
0051 G4double energy = fpParticleGun->GetParticleEnergy();
0052
0053
0054
0055 if (energy == -1) {
0056
0057
0058 fMonoEnergetic = false;
0059 }
0060
0061 if (!fMonoEnergetic) {
0062 energy = GenerateParticleEnergy();
0063 }
0064
0065 fpParticleGun->SetParticleEnergy(energy);
0066 fpParticleGun->SetParticlePosition(GenerateParticlePosition());
0067 fpParticleGun->SetParticleMomentumDirection(
0068 GenerateParticleDirection());
0069
0070 fpParticleGun->GeneratePrimaryVertex(anEvent);
0071 }
0072
0073
0074
0075 G4double PrimaryGeneratorAction::GenerateParticleEnergy()
0076 {
0077 if (fEnergySpectrum_length == 0) {
0078 std::ifstream fin(fEnergySpectrumFilename);
0079 G4String len, gain, offset, counts;
0080 fin >> len >> gain >> offset;
0081 fEnergySpectrum_length = std::stoi(len);
0082 fEnergySpectrum_gain = std::stod(gain);
0083 fEnergySpectrum_offset = std::stod(offset);
0084
0085 fEnergySpectrum_counts.resize(fEnergySpectrum_length);
0086 for (G4int i = 0; i < fEnergySpectrum_length; i++) {
0087 fin >> counts;
0088 fEnergySpectrum_counts[i] = std::stoi(counts);
0089 }
0090 }
0091
0092 auto max_en_counter = fEnergySpectrum_counts[fEnergySpectrum_length - 1] - 1;
0093 auto rand_count = 1 + G4int(G4UniformRand() * max_en_counter);
0094
0095
0096
0097 G4int en_id = 0;
0098 for (; rand_count > fEnergySpectrum_counts[en_id]; en_id++)
0099 ;
0100
0101 G4int left = fEnergySpectrum_counts[en_id - 1];
0102 G4int right = fEnergySpectrum_counts[en_id];
0103
0104 G4double en_left = (en_id - 1) * fEnergySpectrum_gain + fEnergySpectrum_offset;
0105 G4double en_right = en_id * fEnergySpectrum_gain + fEnergySpectrum_offset;
0106
0107
0108 G4double slope = (en_right - en_left) / (right - left);
0109 return (en_left + slope * (rand_count - left)) * MeV;
0110 }
0111
0112
0113
0114 G4ThreeVector PrimaryGeneratorAction::GenerateParticlePosition()
0115 {
0116
0117 G4double r = std::sqrt(G4UniformRand()) * fDetector->GetCollDiameter() / 2.;
0118 G4double phi = G4UniformRand() * twopi;
0119
0120 G4double x = fDetector->GetCollExitPosistion() - fDetector->GetCollLength();
0121 G4double y = r * std::cos(phi);
0122 G4double z = r * std::sin(phi);
0123
0124 return {x, y, z};
0125 }
0126
0127
0128
0129 G4ThreeVector PrimaryGeneratorAction::GenerateParticleDirection()
0130 {
0131 G4double phi, theta;
0132 G4double px, py, pz;
0133
0134 phi = G4UniformRand() * twopi;
0135
0136
0137
0138
0139
0140
0141
0142 G4double cos_max_theta =
0143 std::cos(std::atan(fDetector->GetCollDiameter() / fDetector->GetCollLength()));
0144 theta = std::acos(cos_max_theta + G4UniformRand() * (1 - cos_max_theta));
0145
0146 px = std::cos(theta);
0147 py = std::sin(theta) * std::sin(phi);
0148 pz = std::sin(theta) * std::cos(phi);
0149
0150 return {px, py, pz};
0151 }
0152