Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /// \file eventgenerator/particleGun/src/PrimaryGeneratorAction2.cc 27 /// \brief Implementation of the PrimaryGeneratorAction2 class 28 // 29 // 30 // 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 33 34 #include "PrimaryGeneratorAction2.hh" 35 36 #include "PrimaryGeneratorAction.hh" 37 38 #include "G4Event.hh" 39 #include "G4ParticleDefinition.hh" 40 #include "G4ParticleGun.hh" 41 #include "G4ParticleTable.hh" 42 #include "G4PhysicalConstants.hh" 43 #include "G4SystemOfUnits.hh" 44 #include "Randomize.hh" 45 46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 47 48 PrimaryGeneratorAction2::PrimaryGeneratorAction2(G4ParticleGun* gun) : fParticleGun(gun) 49 { 50 // energy distribution 51 // 52 InitFunction(); 53 } 54 55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 56 57 void PrimaryGeneratorAction2::GeneratePrimaries(G4Event* anEvent) 58 { 59 // uniform solid angle 60 G4double cosAlpha = 1. - 2 * G4UniformRand(); // cosAlpha uniform in [-1,+1] 61 G4double sinAlpha = std::sqrt(1. - cosAlpha * cosAlpha); 62 G4double psi = twopi * G4UniformRand(); // psi uniform in [0, 2*pi] 63 G4ThreeVector dir(sinAlpha * std::cos(psi), sinAlpha * std::sin(psi), cosAlpha); 64 65 fParticleGun->SetParticleMomentumDirection(dir); 66 67 // set energy from a tabulated distribution 68 // 69 // G4double energy = RejectAccept(); 70 G4double energy = InverseCumul(); 71 fParticleGun->SetParticleEnergy(energy); 72 73 // create vertex 74 // 75 fParticleGun->GeneratePrimaryVertex(anEvent); 76 } 77 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 78 79 void PrimaryGeneratorAction2::InitFunction() 80 { 81 // tabulated function 82 // Y is assumed positive, linear per segment, continuous 83 // 84 fNPoints = 16; 85 const G4double xx[] = {37 * keV, 39 * keV, 45 * keV, 51 * keV, 57 * keV, 69 * keV, 86 71 * keV, 75 * keV, 83 * keV, 91 * keV, 97 * keV, 107 * keV, 87 125 * keV, 145 * keV, 159 * keV, 160 * keV}; 88 89 const G4double yy[] = {0.000, 0.077, 0.380, 2.044, 5.535, 15.077, 12.443, 14.766, 90 17.644, 18.518, 17.772, 14.776, 8.372, 3.217, 0.194, 0.000}; 91 92 // copy arrays in std::vector and compute fMax 93 // 94 fX.resize(fNPoints); 95 fY.resize(fNPoints); 96 fYmax = 0.; 97 for (G4int j = 0; j < fNPoints; j++) { 98 fX[j] = xx[j]; 99 fY[j] = yy[j]; 100 if (fYmax < fY[j]) fYmax = fY[j]; 101 }; 102 103 // compute slopes 104 // 105 fSlp.resize(fNPoints); 106 for (G4int j = 0; j < fNPoints - 1; j++) { 107 fSlp[j] = (fY[j + 1] - fY[j]) / (fX[j + 1] - fX[j]); 108 }; 109 110 // compute cumulative function 111 // 112 fYC.resize(fNPoints); 113 fYC[0] = 0.; 114 for (G4int j = 1; j < fNPoints; j++) { 115 fYC[j] = fYC[j - 1] + 0.5 * (fY[j] + fY[j - 1]) * (fX[j] - fX[j - 1]); 116 }; 117 } 118 119 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 120 121 G4double PrimaryGeneratorAction2::RejectAccept() 122 { 123 // tabulated function 124 // Y is assumed positive, linear per segment, continuous 125 // (see Particle Data Group: pdg.lbl.gov --> Monte Carlo techniques) 126 // 127 G4double Xrndm = 0., Yrndm = 0., Yinter = -1.; 128 129 while (Yrndm > Yinter) { 130 // choose a point randomly 131 Xrndm = fX[0] + G4UniformRand() * (fX[fNPoints - 1] - fX[0]); 132 Yrndm = G4UniformRand() * fYmax; 133 // find bin 134 G4int j = fNPoints - 2; 135 while ((fX[j] > Xrndm) && (j > 0)) 136 j--; 137 // compute Y(x_rndm) by linear interpolation 138 Yinter = fY[j] + fSlp[j] * (Xrndm - fX[j]); 139 }; 140 return Xrndm; 141 } 142 143 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 144 145 G4double PrimaryGeneratorAction2::InverseCumul() 146 { 147 // tabulated function 148 // Y is assumed positive, linear per segment, continuous 149 // --> cumulative function is second order polynomial 150 // (see Particle Data Group: pdg.lbl.gov --> Monte Carlo techniques) 151 152 // choose y randomly 153 G4double Yrndm = G4UniformRand() * fYC[fNPoints - 1]; 154 // find bin 155 G4int j = fNPoints - 2; 156 while ((fYC[j] > Yrndm) && (j > 0)) 157 j--; 158 // y_rndm --> x_rndm : fYC(x) is second order polynomial 159 G4double Xrndm = fX[j]; 160 G4double a = fSlp[j]; 161 if (a != 0.) { 162 G4double b = fY[j] / a, c = 2 * (Yrndm - fYC[j]) / a; 163 G4double delta = b * b + c; 164 G4int sign = 1; 165 if (a < 0.) sign = -1; 166 Xrndm += sign * std::sqrt(delta) - b; 167 } 168 else if (fY[j] > 0.) { 169 Xrndm += (Yrndm - fYC[j]) / fY[j]; 170 }; 171 return Xrndm; 172 } 173 174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 175