File indexing completed on 2025-12-16 09:29:57
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
0030
0031
0032
0033
0034
0035
0036 #include "XrayFluoMercuryPrimaryGeneratorAction.hh"
0037 #include "XrayFluoMercuryDetectorConstruction.hh"
0038 #include "XrayFluoMercuryPrimaryGeneratorMessenger.hh"
0039 #include "XrayFluoRunAction.hh"
0040 #include "XrayFluoAnalysisManager.hh"
0041 #include "XrayFluoDataSet.hh"
0042 #include "G4PhysicalConstants.hh"
0043 #include "G4SystemOfUnits.hh"
0044 #include "G4DataVector.hh"
0045 #include "G4Event.hh"
0046 #include "G4ParticleGun.hh"
0047 #include "G4ParticleTable.hh"
0048 #include "G4ParticleDefinition.hh"
0049 #include "Randomize.hh"
0050
0051
0052
0053 XrayFluoMercuryPrimaryGeneratorAction::XrayFluoMercuryPrimaryGeneratorAction(const XrayFluoMercuryDetectorConstruction* XrayFluoDC)
0054 :globalFlag(false),spectrum("off")
0055 {
0056
0057 XrayFluoDetector = XrayFluoDC;
0058
0059 G4int n_particle = 1;
0060 particleGun = new G4ParticleGun(n_particle);
0061
0062
0063 gunMessenger = new XrayFluoMercuryPrimaryGeneratorMessenger(this);
0064 runManager = new XrayFluoRunAction();
0065
0066
0067
0068 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0069 G4String particleName;
0070 G4ParticleDefinition* particle
0071 = particleTable->FindParticle(particleName="gamma");
0072 particleGun->SetParticleDefinition(particle);
0073 particleGun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,-1.));
0074
0075
0076 particleGun->SetParticleEnergy(10.*keV);
0077 G4double position = -0.5*(XrayFluoDetector->GetWorldSizeZ());
0078 particleGun->SetParticlePosition(G4ThreeVector(0.*cm,0.*cm,position));
0079
0080 G4cout << "XrayFluoMercuryPrimaryGeneratorAction created" << G4endl;
0081
0082 }
0083
0084
0085
0086
0087 XrayFluoMercuryPrimaryGeneratorAction::~XrayFluoMercuryPrimaryGeneratorAction()
0088 {
0089 delete particleGun;
0090 delete gunMessenger;
0091 delete runManager;
0092
0093 G4cout << "XrayFluoMercuryPrimaryGeneratorAction deleted" << G4endl;
0094
0095 }
0096
0097
0098
0099 void XrayFluoMercuryPrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
0100 {
0101
0102
0103
0104
0105
0106 G4double z0 = -0.5*(XrayFluoDetector->GetWorldSizeZ());
0107 G4double y0 = 0.*m, x0 = 0.*m;
0108
0109
0110
0111
0112 G4double spacecraftLatitude = XrayFluoDetector->GetOrbitInclination();
0113 G4double mercuryDia = XrayFluoDetector->GetMercuryDia();
0114 G4double sunDia = XrayFluoDetector->GetSunDia();
0115 G4double opticField = XrayFluoDetector->GetOpticAperture();
0116
0117
0118 G4double a = 2*std::tan(opticField/2);
0119
0120
0121
0122
0123
0124 G4double theta = std::acos(2.*G4UniformRand() - 1.0);
0125 G4double phi = 2. * pi * G4UniformRand();
0126 G4double rho = sunDia/2;
0127
0128 G4double sunPosX = x0 + rho * std::sin(theta) * std::cos(phi);
0129 G4double sunPosY = y0 + rho * std::sin(theta) * std::sin(phi);
0130 G4double sunPosZ = z0 + rho * std::cos(theta);
0131
0132 particleGun->SetParticlePosition(G4ThreeVector(sunPosX,sunPosY,sunPosZ));
0133
0134
0135 G4double alpha = 2 * a/mercuryDia;
0136
0137 if(!globalFlag){
0138 theta = alpha * G4UniformRand() + (180.*deg - spacecraftLatitude)-alpha/2.;
0139 phi = alpha * G4UniformRand() + 90. * deg - alpha/2.;
0140 }
0141
0142 else if(globalFlag){
0143 theta = pi/2. * rad * G4UniformRand() + 90.*deg ;
0144 phi = 2*pi*rad * G4UniformRand() ;
0145 }
0146
0147 rho = mercuryDia/2.;
0148
0149 G4double mercuryPosX = rho * std::sin(theta) * std::cos(phi);
0150 G4double mercuryPosY = rho * std::sin(theta) * std::sin(phi);
0151 G4double mercuryPosZ = rho * std::cos(theta);
0152
0153 particleGun->SetParticleMomentumDirection(
0154 G4ThreeVector(mercuryPosX-sunPosX ,mercuryPosY-sunPosY,mercuryPosZ-sunPosZ));
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192 if (spectrum =="on")
0193 {
0194 G4String particle = particleGun->GetParticleDefinition()
0195 ->GetParticleName();
0196 if(particle == "proton"|| particle == "alpha")
0197 {
0198 G4DataVector* energies = runManager->GetEnergies();
0199 G4DataVector* data = runManager->GetData();
0200
0201 G4double sum = runManager->GetDataSum();
0202 G4double partSum = 0;
0203 G4int j = 0;
0204 G4double random= sum*G4UniformRand();
0205 while (partSum<random)
0206 {
0207 partSum += (*data)[j];
0208 j++;
0209 }
0210
0211 particleGun->SetParticleEnergy((*energies)[j]);
0212
0213 }
0214 else if (particle == "gamma")
0215 {
0216 const XrayFluoDataSet* dataSet = runManager->GetGammaSet();
0217
0218 G4int i = 0;
0219 G4int id = 0;
0220 G4double minEnergy = 0. * keV;
0221 G4double particleEnergy= 0.;
0222 G4double maxEnergy = 10. * keV;
0223 G4double energyRange = maxEnergy - minEnergy;
0224
0225 while ( i == 0)
0226 {
0227 G4double random = G4UniformRand();
0228
0229 G4double randomNum = G4UniformRand();
0230
0231 particleEnergy = (random*energyRange) + minEnergy;
0232
0233 if ((dataSet->FindValue(particleEnergy,id)) > randomNum)
0234 {
0235 i = 1;
0236
0237 }
0238 }
0239 particleGun->SetParticleEnergy(particleEnergy);
0240 }
0241 }
0242
0243
0244 #ifdef G4ANALYSIS_USE
0245
0246 G4double partEnergy = particleGun->GetParticleEnergy();
0247 XrayFluoAnalysisManager* analysis = XrayFluoAnalysisManager::getInstance();
0248 analysis->analysePrimaryGenerator(partEnergy/keV);
0249
0250 #endif
0251
0252 particleGun->GeneratePrimaryVertex(anEvent);
0253 }
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264