Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Generator.h"
00020 #include "GN_Messenger.h"
00021
00022
00023
00024 #include "G4ParticleGun.hh"
00025 #include "G4Event.hh"
00026 #include "G4ThreeVector.hh"
00027 #include "G4ParticleTable.hh"
00028 #include "Randomize.hh"
00029
00030
00031
00032 #include <cmath>
00033
00034
00035
00036
00037
00038 using namespace std;
00039
00040
00041
00042
00043
00044 Generator::Generator() {
00045
00046
00047
00048 Ebeam = 2.0 * GeV;
00049
00050 BeamCharge = -1;
00051
00052 ep_Elastic = true;
00053
00054
00055
00056 GN_Messenger::Instance()->setGNptr( this );
00057
00058
00059
00060 epKin = new ep_Kinematics( Ebeam );
00061
00062 epTheta_Min = 15.0 * degree;
00063 epTheta_Max = 90.0 * degree;
00064
00065 cos_epThMin = cos( epTheta_Min );
00066 cos_epThMax = cos( epTheta_Max );
00067
00068 epPhi_Min = -20.0 * degree;
00069 epPhi_Max = 20.0 * degree;
00070
00071 particleGun = new G4ParticleGun( 1 );
00072
00073 }
00074
00075
00076
00077 Generator::~Generator() {
00078 delete epKin;
00079 delete particleGun;
00080 }
00081
00082
00083
00084 void Generator::GeneratePrimaries( G4Event * event ) {
00085
00086
00087
00088 G4double theta3 = acos( CLHEP::RandFlat::shoot() *
00089 ( cos_epThMax - cos_epThMin ) + cos_epThMin );
00090
00091 G4double phi = CLHEP::RandFlat::shoot() *
00092 ( epPhi_Max - epPhi_Min ) + epPhi_Min;
00093
00094 if( CLHEP::RandFlat::shoot() > 0.5 ) phi += CLHEP::pi;
00095
00096 G4double cosTH3 = cos( theta3 );
00097 G4double sinTH3 = sin( theta3 );
00098 G4double cosPH = cos( phi );
00099 G4double sinPH = sin( phi );
00100
00101 G4double E3, E4, Q2, theta4;
00102
00103 epKin->for_e_angle( theta3, E3, E4, Q2, theta4 );
00104
00105 G4double cosTH4 = cos( theta4 );
00106 G4double sinTH4 = sin( theta4 );
00107
00108 G4ThreeVector vertex = Target_Distribution();
00109
00110
00111
00112 static G4ParticleTable * particletable = G4ParticleTable::GetParticleTable();
00113
00114
00115
00116 if( BeamCharge == -1 ) {
00117 particleGun->SetParticleDefinition( particletable->FindParticle("e-") );
00118 }
00119 else {
00120 particleGun->SetParticleDefinition( particletable->FindParticle("e+") );
00121 }
00122 particleGun->SetParticleEnergy( E3 - CLHEP::electron_mass_c2 );
00123 particleGun->SetParticlePosition( vertex );
00124 particleGun->SetParticleMomentumDirection(
00125 G4ThreeVector( sinTH3 * cosPH, sinTH3 * sinPH, cosTH3 ) );
00126
00127 particleGun->GeneratePrimaryVertex( event );
00128
00129
00130
00131 particleGun->SetParticleDefinition( particletable->FindParticle("proton") );
00132 particleGun->SetParticleEnergy( E4 - CLHEP::proton_mass_c2 );
00133 particleGun->SetParticlePosition( vertex );
00134 particleGun->SetParticleMomentumDirection(
00135 G4ThreeVector( -sinTH4 * cosPH, -sinTH4 * sinPH, cosTH4 ) );
00136
00137 particleGun->GeneratePrimaryVertex( event );
00138
00139 }
00140
00141 G4ThreeVector Generator::Target_Distribution() {
00142
00143 static G4double Half_Target_Length = 60.0 * cm / 2.0;
00144
00145 G4double x, y, z, rand;
00146
00147 x = CLHEP::RandGauss::shoot( 0.0, 0.1 * cm );
00148
00149 y = CLHEP::RandGauss::shoot( 0.0, 0.1 * cm );
00150
00151 rand = CLHEP::RandFlat::shoot();
00152
00153 if( rand < 0.5 ) z = Half_Target_Length * ( sqrt( 2.0 * rand ) - 1.0 );
00154 else z = Half_Target_Length * ( 1.0 - sqrt( 2.0 * ( 1.0 - rand ) ) );
00155
00156 return G4ThreeVector( x, y, z );
00157 }
00158
00159
00160
00161 G4double Generator::setEbeam( G4double energy ) {
00162 Ebeam = energy;
00163 delete epKin;
00164 epKin = new ep_Kinematics( Ebeam );
00165 return Ebeam;
00166 }
00167 G4double Generator::getEbeam() { return Ebeam; }
00168
00169
00170
00171 G4int Generator::setBeamCharge( G4int q ) {
00172 if( q == 1 || q == -1 ) BeamCharge = q;
00173 return BeamCharge;
00174 }
00175 G4int Generator::getBeamCharge() { return BeamCharge; }
00176
00177
00178
00179 G4double Generator::setepThetaMin( G4double min ) {
00180 epTheta_Min = min;
00181 cos_epThMin = cos( epTheta_Min );
00182 return epTheta_Min;
00183 }
00184 G4double Generator::getepThetaMin() { return epTheta_Min; }
00185
00186
00187
00188 G4double Generator::setepThetaMax( G4double max ) {
00189 epTheta_Max = max;
00190 cos_epThMax = cos( epTheta_Max );
00191 return epTheta_Max;
00192 }
00193 G4double Generator::getepThetaMax() { return epTheta_Max; }
00194
00195
00196
00197 G4double Generator::setepPhiMin( G4double min ) { return epPhi_Min = min; }
00198 G4double Generator::getepPhiMin() { return epPhi_Min; }
00199
00200
00201
00202 G4double Generator::setepPhiMax( G4double max ) { return epPhi_Max = max; }
00203 G4double Generator::getepPhiMax() { return epPhi_Max; }
00204
00205
00206
00207 void Generator::Print() {
00208 G4cout << "Generator\n"
00209 << " Ebeam = " << Ebeam / MeV << " [MeV]\n"
00210 << " Charge = " << BeamCharge << "\n"
00211 << " epElastic = " << ep_Elastic << "\n"
00212 << " epTheta_Min = " << epTheta_Min / degree << " [degree]\n"
00213 << " epTheta_Max = " << epTheta_Max / degree << " [degree]\n"
00214 << G4endl;
00215 }
00216
00217
00218
00219 ep_Kinematics::ep_Kinematics( G4double Ebeam ) {
00220
00221 G4double Me = CLHEP::electron_mass_c2;
00222 G4double Mp = CLHEP::proton_mass_c2;
00223
00224
00225
00226
00227 E1 = Ebeam + Me;
00228 p1 = sqrt( Ebeam * Ebeam + 2.0 * Me * Ebeam );
00229
00230 beta = p1 / ( E1 + Mp );
00231
00232 E3cmbyG = ( Me * Me + Mp * E1 ) / ( E1 + Mp );
00233
00234 }
00235
00236
00237
00238 ep_Kinematics::~ep_Kinematics() {}
00239
00240
00241
00242 void ep_Kinematics::for_e_angle( G4double theta3, G4double & E3, G4double & E4,
00243 G4double & Q2, G4double & theta4 ) {
00244
00245 G4double Me = CLHEP::electron_mass_c2;
00246 G4double Mp = CLHEP::proton_mass_c2;
00247
00248 G4double cos3 = cos( theta3 );
00249 G4double bbcos = 1.0 - beta * beta * cos3 * cos3;
00250
00251 E3 = ( E3cmbyG + beta * cos3 *
00252 sqrt( E3cmbyG * E3cmbyG - bbcos * Me * Me ) ) / bbcos;
00253
00254 G4double p3 = sqrt( E3 * E3 - Me * Me );
00255
00256 Q2 = 2.0 * ( E1 * E3 - p1 * p3 * cos3 - Me * Me );
00257
00258 E4 = E1 + Mp - E3;
00259
00260 G4double p4 = sqrt( E4 * E4 - Mp * Mp );
00261
00262 theta4 = acos( ( p1 - p3 * cos3 ) / p4 );
00263
00264 return;
00265 }
00266
00267
00268
00269 void ep_Kinematics::Print() {
00270
00271 G4cout << "ep_Kinenmatics\n"
00272 << " E1 = " << E1 / MeV << " [MeV]\n"
00273 << " p1 = " << p1 / MeV << " [MeV]\n"
00274 << " beta = " << beta << "\n"
00275 << " E3cm = " << E3cmbyG / MeV << " [MeV]\n"
00276 << G4endl;
00277 }
00278
00279
00280
00281 G4double epCrossSection( const G4double & E, const G4double & theta3,
00282 const G4double & Ep, const G4double & Q2 ) {
00283
00284 static G4double Mp = CLHEP::proton_mass_c2;
00285 static G4double Alpha = 1.0 / 137.035999679;
00286 static G4double Mu_p2 = pow( 2.792847356, 2 );
00287 static G4double hbarc = CLHEP::hbarc;
00288
00289 G4double th = theta3 / 2.0;
00290 G4double costh = cos( th );
00291 G4double costh2 = pow( cos( th ), 2 );
00292 G4double sinth2 = pow( sin( th ), 2 );
00293
00294 G4double Mott = pow( ( Alpha * costh * hbarc ) /
00295 ( 2.0 * E * sinth2 ), 2 );
00296
00297 G4double GE2 = pow( 1.0 - Q2 / ( 0.71 * GeV * GeV ), -4 );
00298 G4double GM2 = Mu_p2 * GE2;
00299
00300 G4double tau = Q2 / ( 4.0 * Mp * Mp );
00301
00302 return Mott * Ep / E * ( ( GE2 + tau * GM2 ) / ( 1.0 + tau ) +
00303 2.0 * tau * GM2 * sinth2 / costh2 );
00304
00305 }