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 me 0.511E-3 //electron restmass (GeV)
00031 #define Euler 0.5772157
00032 #define d2r pi/180.
00033 #define r2d 180/pi
00034
00035 #define gevfm 0.1973
00036 #define pmu 2.79
00037 #define alpha 0.007299
00038
00039 double SigT(double k);
00040
00041 void MollerPrimaryGenAction::GeneratePrimaries_inelasticep_dustin(G4Event* anEvent)
00042 {
00043
00044
00045
00046
00047 double initial_x = 0.0;
00048 double initial_y = 0.0;
00049 double initial_z = 0.0;
00050
00051 double initial_px = 0.0;
00052 double initial_py = 0.0;
00053 double initial_pz = 0.0;
00054
00055
00056 double vertex;
00057 double t = 150.0;
00058 double rho = 0.0715;
00059 double radiationLength = 63.04;
00060 double t_rad = radiationLength/rho;
00061 double z = G4UniformRand();
00062 vertex = z*t;
00063
00064 double Evertex = ebeam;
00065
00066
00067 double cut=0.000001;
00068 double Ekin = ebeam - me;
00069 double fracrl = vertex/t_rad;
00070 double bt = fracrl*4./3.;
00071
00072 double prob, prob_sample, sample, eloss, env, value, ref;
00073
00074 prob = 1.- pow(cut/Ekin,bt) - bt/(bt+1.)*(1.- pow(cut/Ekin,bt+1.))
00075 + 0.75*bt/(2.+bt)*(1.- pow(cut/Ekin,bt+2.));
00076 prob = prob/(1.- bt*Euler + bt*bt/2.*(Euler*Euler+pi*pi/6.));
00077
00078 prob_sample = G4UniformRand();
00079
00080 if (prob_sample <= prob) {
00081
00082 do {
00083 sample = G4UniformRand();
00084 eloss = cut*pow(Ekin/cut,sample);
00085
00086 env = 1./eloss;
00087 value = 1./eloss*(1.-eloss/Ekin+0.75*pow(eloss/Ekin,2))*pow(eloss/Ekin,bt);
00088
00089 sample = G4UniformRand();
00090 ref = value/env;
00091 } while (sample > ref);
00092
00093 Evertex = ebeam - eloss;
00094 }
00095
00096 if( Evertex < me ) return;
00097
00098 double vertex_x = (-0.25 + (0.5*(G4UniformRand())));
00099 double vertex_y = (-0.25 + (0.5*(G4UniformRand())));
00100 initial_x = vertex_x;
00101 initial_y = vertex_y;
00102 initial_z = vertex - t/2.;
00103
00104
00105
00106
00107
00108
00109
00110
00111 initial_px = 0.0;
00112 initial_py = 0.0;
00113 initial_pz = Evertex;
00114
00115
00116
00117
00118
00119
00120 double thetaIneEP[2];
00121 thetaIneEP[0] = 0.1;
00122 thetaIneEP[1] = 2.0;
00123
00124 double e = Evertex;
00125 double eprime_max = e - 0.150;
00126 double eprime_min = eprime_max/nbinIneEP;
00127 if(Evertex<eprime_min) G4cout <<"Evertex is less than eprime_min..."<<"\n";
00128 else if(Evertex<eprime_max) eprime_max = Evertex;
00129
00130 if( eprime_min < me ){
00131 eprime_min = me;
00132 }
00133
00134 for(int i=0;i<nbinIneEP;i++) {
00135 for (int j=0;j<nbinIneEP;j++) {
00136 double theta = (thetaIneEP[1] - thetaIneEP[0])/(nbinIneEP-1)*i + thetaIneEP[0];
00137 double costh = cos(theta*d2r/2.);
00138 double sinth = sin(theta*d2r/2.);
00139 double sin2 = sinth*sinth;
00140 double cos2 = costh*costh;
00141 double eprime = (eprime_max - eprime_min)/(nbinIneEP-1)*j + eprime_min;
00142 double q2 = 4.*e*eprime*sin2;
00143 double x = q2/2./mp/(e-eprime);
00144 double nu = q2/2./mp/x;
00145
00146 double k = nu - q2/2./mp;
00147 double sigt=SigT(k);
00148
00149 double f1 = (nu - q2 / 2. / mp) * mp / 4. / (pi*pi) / alpha * sigt /0.389 ;
00150
00151
00152 double r = q2;
00153 double f2 = f1 / ( (1. + (2. * mp * x) * (2. * mp * x) /q2) / 2. / x / (1. + r )) ;
00154
00155 double sig=5.2E-9/e/e/sin2/sin2* (cos2 * f2 / nu + sin2 * 2. * f1 / mp);
00156 sig *= sin(theta*d2r);
00157 DDtable[i][j].Eprime = eprime;
00158 DDtable[i][j].theta = theta;
00159 DDtable[i][j].xs = sig;
00160 }
00161 }
00162
00163 double_differential_t XStable_theta[nbinIneEP];
00164 double_differential_t XStable_Eprime[nbinIneEP];
00165
00166
00167 double Im=0.0;
00168 double save;
00169
00170 for(int i = 0;i<nbinIneEP; i++) {
00171 XStable_theta[i].xs = 0.0;
00172 XStable_theta[i].theta = (thetaIneEP[1] - thetaIneEP[0])/(nbinIneEP-1)*i + thetaIneEP[0];
00173 for(int j = 0;j<nbinIneEP-1;j++){
00174 XStable_theta[i].xs += (DDtable[i][j].xs + DDtable[i][j+1].xs)/2.0;
00175 }
00176 if( i == 0 ){
00177 save = XStable_theta[i].xs;
00178 XStable_theta[i].xs = 0.0;
00179 } else {
00180 Im += (save+XStable_theta[i].xs)/2.0;
00181 save = XStable_theta[i].xs;
00182 XStable_theta[i].xs = Im;
00183 }
00184 }
00185 double totXS = Im*(thetaIneEP[1]-thetaIneEP[0])*d2r*(eprime_max - eprime_min)/(nbinIneEP-1.0)/(nbinIneEP-1.0)*2*pi;
00186 double factor = 6.0221415*0.1*1.0E-6/1.602176487E-19;
00187 double rate = totXS*t*rho/1.008*1.0*factor;
00188 gRootAnalysis->SetTotXS(totXS);
00189 gRootAnalysis->SetRate(rate);
00190
00191 if( !(Im > 0.0) ){
00192
00193
00194
00195 return;
00196 }
00197
00198 assert( Im > 0.0 );
00199
00200
00201 for(int k=0;k<nbinIneEP;k++){
00202 XStable_theta[k].xs /= Im;
00203 }
00204
00205
00206 double ss = (G4UniformRand());
00207 int index;
00208 double slope, b;
00209 for(index=0;index<nbinIneEP-1;index++) if(ss <= XStable_theta[index+1].xs) break;
00210 assert( index < nbinIneEP-1 );
00211
00212 slope = (XStable_theta[index+1].xs - XStable_theta[index].xs)/(XStable_theta[index+1].theta - XStable_theta[index].theta);
00213 b = XStable_theta[index].xs;
00214 double lab_theta = XStable_theta[index].theta + (ss - b)/slope;
00215 int theIndex = index;
00216
00217
00218 double intpar = (ss - b)/(XStable_theta[index+1].xs - XStable_theta[index].xs);
00219
00220 assert( 0.0 <= intpar && intpar < 1.0 );
00221
00222
00223
00224 double Im2=0.0;
00225
00226 save = DDtable[theIndex][0].xs*(1.0-intpar) + DDtable[theIndex+1][0].xs*intpar;
00227 XStable_Eprime[0].xs = 0.0;
00228 XStable_Eprime[0].Eprime = eprime_min;
00229
00230 for(int j = 1;j<nbinIneEP;j++) {
00231
00232 Im2 += (save + DDtable[theIndex][j].xs*(1.0-intpar) + DDtable[theIndex+1][j].xs*intpar)/2.0;
00233 save = DDtable[theIndex][j].xs*(1.0-intpar) + DDtable[theIndex+1][j].xs*intpar;
00234 XStable_Eprime[j].xs = Im2;
00235 XStable_Eprime[j].Eprime = (eprime_max - eprime_min)/(nbinIneEP-1)*j + eprime_min;
00236 }
00237
00238 assert( Im2 > 0.0 );
00239
00240
00241
00242 for(int k=0;k<nbinIneEP;k++){
00243 XStable_Eprime[k].xs /= Im2;
00244 }
00245
00246 double ss2 = (G4UniformRand());
00247 int index2;
00248 double slope2, b2;
00249 for(index2=0;index2<nbinIneEP-1;index2++) if(ss2 <= XStable_Eprime[index2+1].xs) break;
00250 assert( index2 < nbinIneEP-1 );
00251
00252 slope2 = (XStable_Eprime[index2+1].xs - XStable_Eprime[index2].xs)/(XStable_Eprime[index2+1].Eprime - XStable_Eprime[index2].Eprime);
00253 b2 = XStable_Eprime[index2].xs;
00254 double lab_Eprime = XStable_Eprime[index2].Eprime + (ss2 - b2)/slope2;
00255
00256
00257 double lab_phi = (2.0*pi*(G4UniformRand())) - pi;
00258
00259
00260
00261
00262
00263
00264 double costh = cos(lab_theta*d2r);
00265 double sinth = sin(lab_theta*d2r);
00266 e = lab_Eprime;
00267 assert( e > 0.0 );
00268 double p = sqrt(e*e - me*me);
00269 assert( p > 0.0 );
00270
00271 double cosphie = cos( lab_phi );
00272 double sinphie = sin( lab_phi );
00273
00274
00275
00276
00277
00278
00279 double e1, p1[3];
00280 e1 = e;
00281 for(int i=0;i<3;i++) {
00282 p1[i] = 0.0;
00283 }
00284
00285 p1[2] = p*costh;
00286 p1[0] = p*sinth*cosphie;
00287 p1[1] = p*sinth*sinphie;
00288
00289 double pmag1 = p;
00290 double pmag0 = sqrt(initial_px*initial_px+initial_py*initial_py+initial_pz*initial_pz);
00291
00292
00293
00294
00295
00296
00297 G4ParticleDefinition* particle_e = G4Electron::ElectronDefinition();
00298
00299 particleGun->SetParticleDefinition(particle_e);
00300 particleGun->SetParticleMomentumDirection(G4ThreeVector(p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1));
00301 particleGun->SetParticleEnergy(e1*1000);
00302 particleGun->SetParticlePosition(G4ThreeVector(initial_x*10, initial_y*10, initial_z*10));
00303 particleGun->GeneratePrimaryVertex(anEvent);
00304
00305 gRootAnalysis->SetMomentum0(Evertex*1000,initial_px/pmag0,initial_py/pmag0,initial_pz/pmag0);
00306 gRootAnalysis->SetMomentum1(e1*1000,p1[0]/pmag1,p1[1]/pmag1,p1[2]/pmag1);
00307
00308
00309 anEvent->GetPrimaryVertex(0)->GetPrimary(0);
00310
00311 }
00312
00313
00314 double SigT(double k) {
00315 double sigt ;
00316 sigt=0 ;
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 static const int nbin = 37;
00360
00361
00362 double kval[nbin] = { 0.175, 0.196, 0.214, 0.233, 0.251, 0.251, 0.251, 0.271, 0.290, 0.310, 0.330, 0.350, 0.370, 0.390, 0.410, 0.430, 0.450, 0.470, 0.520, 0.550, 0.600, 0.650, 0.700, 0.750, 0.800, 0.750, 0.800, 0.900, 0.950, 1.000, 1.050, 1.100, 1.150, 1.200, 1.300, 1.400, 1.5 };
00363
00364 double tval[nbin] = { 0.08, 0.12, 0.17, 0.21, 0.32, 0.32, 0.32, 0.40, 0.50, 0.53, 0.50, 0.45, 0.41, 0.32, 0.24, 0.22, 0.18, 0.17, 0.18, 0.21, 0.22, 0.24, 0.27, 0.25, 0.25, 0.25, 0.22, 0.21, 0.215, 0.225, 0.215, 0.185, 0.165, 0.15, 0.16, 0.15, 0.15};
00365
00366
00367 int idx = 0;
00368
00369 if(k > 1.5){
00370 sigt=0.0987 + 0.0649/sqrt(k) ;
00371 } else {
00372
00373 while( !( kval[idx] < k && k <= kval[idx+1] ) && idx < nbin-1 ){ idx++; }
00374
00375
00376 if( idx == nbin-1 ) {
00377 assert( k < 0.175 );
00378 sigt = 0.0;
00379 }
00380 else {
00381 assert( 0 <= idx && idx < nbin-1 );
00382
00383 double intval = (k - kval[idx])/(kval[idx+1]-kval[idx]);
00384
00385 assert( 0.0 <= intval && intval < 1.0 );
00386
00387 sigt = tval[idx]*(1.0-intval) + tval[idx+1]*intval;
00388 }
00389 }
00390
00391 return sigt ;
00392 }
00393