00001 #include "G4ParticleGun.hh"
00002 #include "G4Electron.hh"
00003 #include "G4Event.hh"
00004 #include "globals.hh"
00005
00006 #include "MollerPrimaryGenAction.hh"
00007 #include "RootAnalysis.hh"
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define r0 2.818 //electron radius in fm
00029 #define pi 3.14159
00030 #define Euler 0.5772157
00031 #define d2r pi/180.
00032 #define r2d 180/pi
00033
00034 #define gevfm 0.1973
00035 #define pmu 2.79
00036 #define alpha 0.007299
00037
00038 void MollerPrimaryGenAction::GeneratePrimaries_moller_dustin(G4Event* anEvent)
00039 {
00040
00041
00042
00043
00044 double initial_x = 0.0;
00045 double initial_y = 0.0;
00046 double initial_z = 0.0;
00047
00048 double initial_px = 0.0;
00049 double initial_py = 0.0;
00050 double initial_pz = 0.0;
00051
00052
00053 double vertex;
00054 double t = 150.0;
00055 double rho = 0.0715;
00056 double radiationLength = 63.04;
00057 double t_rad = radiationLength/rho;
00058 double z = G4UniformRand();
00059 vertex = z*t;
00060
00061 double Evertex = ebeam;
00062
00063
00064 double cut=0.000001;
00065 double Ekin = ebeam - me;
00066 double fracrl = vertex/t_rad;
00067 double bt = fracrl*4./3.;
00068
00069 double prob, prob_sample, sample, eloss, env, value, ref;
00070
00071 prob = 1.- pow(cut/Ekin,bt) - bt/(bt+1.)*(1.- pow(cut/Ekin,bt+1.))
00072 + 0.75*bt/(2.+bt)*(1.- pow(cut/Ekin,bt+2.));
00073 prob = prob/(1.- bt*Euler + bt*bt/2.*(Euler*Euler+pi*pi/6.));
00074
00075 prob_sample = G4UniformRand();
00076
00077 if (prob_sample <= prob) {
00078
00079 do {
00080 sample = G4UniformRand();
00081 eloss = cut*pow(Ekin/cut,sample);
00082
00083 env = 1./eloss;
00084 value = 1./eloss*(1.-eloss/Ekin+0.75*pow(eloss/Ekin,2))*pow(eloss/Ekin,bt);
00085
00086 sample = G4UniformRand();
00087 ref = value/env;
00088 } while (sample > ref);
00089
00090 Evertex = ebeam - eloss;
00091 }
00092
00093 if( Evertex < me ) return;
00094
00095 double vertex_x = (-0.25 + (0.5*(G4UniformRand())));
00096 double vertex_y = (-0.25 + (0.5*(G4UniformRand())));
00097 initial_x = vertex_x;
00098 initial_y = vertex_y;
00099 initial_z = vertex - t/2.;
00100
00101
00102
00103
00104
00105
00106
00107
00108 initial_px = 0.0;
00109 initial_py = 0.0;
00110 initial_pz = Evertex;
00111
00112
00113
00114
00115
00116 double thetaMoller[2];
00117 thetaMoller[0] = 53.13010;
00118 thetaMoller[1] = 126.8699;
00119 double x1 = cos(thetaMoller[1]*d2r);
00120 double x2 = cos(thetaMoller[0]*d2r);
00121 double y2 = (1 - x1)/2.;
00122 double y1 = (1 - x2)/2.;
00123 double ds = me*me+me*me+2.*me*Evertex;
00124 double ecm = sqrt(ds);
00125 double decm[2];
00126 decm[0] = ds/2./ecm;
00127 double dps = pow(decm[0],2)-me*me;
00128 double dp = sqrt(dps);
00129 decm[1] = sqrt(dps+me*me);
00130
00131 for(int i =0;i<nbin;i++) {
00132 double y = y1 + ((y2 - y1)/nbin*i)+(y2 - y1)/nbin/2.;
00133 double dt = -1.*y*ds;
00134 double ct = (dt-me*me-me*me+2.*pow(decm[0],2))/(2.*pow(dp,2));
00135 if( !( -1.0 < ct && ct < 1.0 )){
00136
00137
00138
00139
00140 return;
00141 }
00142 double ct2 = pow(ct,2);
00143 double st2 = 1. - ct2;
00144 double st = sqrt(st2);
00145 double th = acos(ct);
00146
00147 double ecmp = ecm/2.;
00148 double vcmp = sqrt(pow(ecmp,2)-me*me)/ecmp;
00149 double dsig = 0.;
00150
00151 double eom = ecmp/me;
00152 double eom2 = pow(eom,2);
00153 double d1 = pow(r0,2)*pow((2.*eom2-1.),2)/4./pow(vcmp,4)/pow(eom2,3);
00154 double d2 = 4./pow(st2,2)-3./st2+pow((eom2-1.),2)/pow((2.*eom2-1),2)*(1+4./pow(st,2));
00155
00156 dsig = d1*d2;
00157
00158 assert( dsig > 0.0 );
00159
00160 dsig = dsig*2.;
00161 dsig = dsig/100;
00162 XStable[i].y = y;
00163 XStable[i].theta = th;
00164 XStable[i].xs = dsig;
00165 }
00166
00167 cms_cross_section_t *moller = XStable;
00168
00169
00170
00171 double Im=0.0;
00172 double save = moller[0].xs;
00173 moller[0].xs = Im;
00174
00175 for(int j = 1;j<nbin;j++) {
00176 Im += (save + moller[j].xs)/2.0;
00177 save = moller[j].xs;
00178 moller[j].xs = Im;
00179 }
00180
00181 double totXS = Im*(y2-y1)/(nbin-1.0)*2*pi;
00182 double factor = 6.0221415*0.1*1.0E-6/1.602176487E-19;
00183 double rate = totXS*t*rho/1.008*1.0*factor;
00184 gRootAnalysis->SetTotXS(totXS);
00185 gRootAnalysis->SetRate(rate);
00186
00187 if( !(Im > 0.0) ){
00188 printf("Im = %f, Evertex = %f\n", Im, Evertex);
00189 }
00190 assert( Im > 0.0 );
00191
00192
00193 moller = XStable;
00194 for(int k=0;k<nbin;k++){
00195 moller[k].xs /= Im;
00196 }
00197
00198
00199 double ss = (G4UniformRand());
00200
00201
00202 int index;
00203 double slope, b;
00204 for(index=0;index<nbin-1;index++) if(ss <= moller[index+1].xs) break;
00205 assert( index < nbin-1 );
00206 slope = (moller[index+1].xs - moller[index].xs)/(moller[index+1].theta - moller[index].theta);
00207 b = moller[index].xs;
00208
00209 double cms_theta = moller[index].theta + (ss - b)/slope;
00210
00211 double cms_phi = (2.0*pi*(G4UniformRand())) - pi;
00212
00213
00214
00215
00216
00217
00218 double gammap = Evertex/ecm;
00219 double betap = 1/gammap*sqrt(pow(gammap,2)-1);
00220
00221 double e1cm = gammap*me;
00222 double e2cm = e1cm;
00223
00224
00225 double costheta1 = cos( cms_theta );
00226 double sintheta1 = sin( cms_theta );
00227
00228 double cosphi1 = cos( cms_phi );
00229 double sinphi1 = sin( cms_phi );
00230
00231 double p1cm[3];
00232
00233
00234 p1cm[0] = e1cm * sintheta1 * cosphi1;
00235 p1cm[1] = e1cm * sintheta1 * sinphi1;
00236 p1cm[2] = e1cm * costheta1;
00237
00238
00239 double costheta2 = cos( pi - cms_theta );
00240 double sintheta2 = sin( pi - cms_theta );
00241
00242 double cosphi2 = cos( cms_phi - pi);
00243 double sinphi2 = sin( cms_phi - pi);
00244 if (cms_phi<0.0){
00245 cosphi2 = cos( cms_phi + pi);
00246 sinphi2 = sin( cms_phi + pi);
00247 } else {
00248
00249 }
00250
00251 double p2cm[3];
00252 p2cm[0] = e2cm * sintheta2 * cosphi2;
00253 p2cm[1] = e2cm * sintheta2 * sinphi2;
00254 p2cm[2] = e2cm * costheta2;
00255
00256
00257
00258 double e1, p1[3], e2, p2[3];
00259 e1 = 0.0;
00260 e2 = 0.0;
00261 for(int i=0;i<3;i++) {
00262 p1[i] = 0.0;
00263 p2[i] = 0.0;
00264 }
00265
00266 p1[2] = gammap * (p1cm[2] + betap*e1cm);
00267 p2[2] = gammap * (p2cm[2] + betap*e2cm);
00268 p1[0] = p1cm[0];
00269 p1[1] = p1cm[1];
00270 p2[0] = p2cm[0];
00271 p2[1] = p2cm[1];
00272
00273 double pmag1 = sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]);
00274 double pmag2 = sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]);
00275 double pmag0 = sqrt(initial_px*initial_px+initial_py*initial_py+initial_pz*initial_pz);
00276
00277 e1 = gammap * ( e1cm + betap*p1cm[2] );
00278 e2 = gammap * ( e2cm + betap*p2cm[2] );
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 G4ParticleDefinition* particle = G4Electron::ElectronDefinition();
00294
00295 assert( pmag1 > 0.0 && pmag2 > 0.0 && pmag0 > 0.0 );
00296
00297 assert( e1 > 0.0 && e2 > 0.0 );
00298
00299 if(e1>=e2) {
00300 particleGun->SetParticleDefinition(particle);
00301 particleGun->SetParticleMomentumDirection(G4ThreeVector(p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1));
00302 particleGun->SetParticleEnergy(e1*1000);
00303 particleGun->SetParticlePosition(G4ThreeVector(initial_x*10, initial_y*10, initial_z*10));
00304 particleGun->GeneratePrimaryVertex(anEvent);
00305
00306 particleGun->SetParticleDefinition(particle);
00307 particleGun->SetParticleMomentumDirection(G4ThreeVector(p2[0]/pmag2,p2[1]/pmag2,p2[2]/pmag2));
00308 particleGun->SetParticleEnergy(e2*1000);
00309 particleGun->SetParticlePosition(G4ThreeVector(initial_x*10, initial_y*10, initial_z*10));
00310 particleGun->GeneratePrimaryVertex(anEvent);
00311
00312 gRootAnalysis->SetMomentum0(Evertex*1000,initial_px/pmag0,initial_py/pmag0,initial_pz/pmag0);
00313 gRootAnalysis->SetMomentum1(e1*1000,p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1);
00314 gRootAnalysis->SetMomentum2(e2*1000,p2[0]/pmag2,p2[1]/pmag2,p2[2]/pmag2);
00315 } else {
00316 particleGun->SetParticleDefinition(particle);
00317 particleGun->SetParticleMomentumDirection(G4ThreeVector(p2[0]/pmag2,p2[1]/pmag2,p2[2]/pmag2));
00318 particleGun->SetParticleEnergy(e2*1000);
00319 particleGun->SetParticlePosition(G4ThreeVector(initial_x*10, initial_y*10, initial_z*10));
00320 particleGun->GeneratePrimaryVertex(anEvent);
00321
00322 particleGun->SetParticleDefinition(particle);
00323 particleGun->SetParticleMomentumDirection(G4ThreeVector(p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1));
00324 particleGun->SetParticleEnergy(e1*1000);
00325 particleGun->SetParticlePosition(G4ThreeVector(initial_x*10, initial_y*10, initial_z*10));
00326 particleGun->GeneratePrimaryVertex(anEvent);
00327
00328 gRootAnalysis->SetMomentum0(Evertex*1000,initial_px/pmag0,initial_py/pmag0,initial_pz/pmag0);
00329 gRootAnalysis->SetMomentum2(e1*1000,p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1);
00330 gRootAnalysis->SetMomentum1(e2*1000,p2[0]/pmag2,p2[1]/pmag2,p2[2]/pmag2);
00331 }
00332
00333 anEvent->GetPrimaryVertex(0)->GetPrimary(0);
00334
00335 }