00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BDSComptonEngine.hh"
00010 #include "G4ios.hh"
00011 #include "G4UnitsTable.hh"
00012 #include "Randomize.hh"
00013 #include "G4LorentzRotation.hh"
00014
00015 BDSComptonEngine::BDSComptonEngine(){}
00016
00017
00018 BDSComptonEngine::BDSComptonEngine(G4LorentzVector InGam,
00019 G4LorentzVector InEl )
00020 : itsIncomingEl(InEl),itsIncomingGam(InGam)
00021 {
00022 if(itsIncomingGam.e()<=0.)
00023 {G4Exception("BDSComptonEngine: Invalid Photon Energy", "-1", FatalException, "");}
00024 }
00025
00026
00027 BDSComptonEngine::~BDSComptonEngine(){}
00028
00029
00030 void BDSComptonEngine::PerformCompton()
00031 {
00032
00033
00034
00035
00036 G4double phi=twopi * G4UniformRand() ;
00037 G4double sinphi=sin(phi);
00038 G4double cosphi=cos(phi);
00039
00040
00041 G4int ntry=0;
00042
00043 G4LorentzVector GamInLab;
00044 G4double x;
00045 G4ThreeVector Boost;
00046 G4double costh, costh2,sinth,sinth2;
00047
00048 Boost = itsIncomingEl.boostVector();
00049
00050 G4LorentzRotation BoostToLab(-Boost);
00051 GamInLab=BoostToLab*(itsIncomingGam);
00052 G4ThreeVector LabGammaDir= GamInLab.vect().unit();
00053
00054 G4double weight_CovT=0;
00055 do {ntry++;
00056
00057 if(G4UniformRand()>0.25){costh=2.*G4UniformRand()-1.;}
00058 else
00059 {
00060 costh=G4UniformRand();
00061 G4double r1=G4UniformRand();
00062 G4double r2=G4UniformRand();
00063 if(r1>costh)costh=r1;
00064 if(r2>costh)costh=r2;
00065 if(G4UniformRand()<0.5)costh=-costh;
00066 }
00067
00068 costh2=costh*costh;
00069 sinth2=1.-costh2;
00070
00071
00072 x = 1/(1+ GamInLab.e()*(1-costh)/electron_mass_c2);
00073
00074
00075 weight_CovT= x* x * (x+1/x-sinth2)/(1+costh2);
00076 } while(ntry<ntryMax && G4UniformRand()>weight_CovT);
00077
00078 if(ntry==ntryMax)
00079 G4Exception("BDSComptonEngine:Max number of loops exceeded", "-1", FatalException, "");
00080
00081
00082
00083 G4double Egam = x * GamInLab.e();
00084
00085
00086
00087 sinth=sqrt(sinth2);
00088 itsScatteredGam.setPx(Egam*sinth*cosphi);
00089 itsScatteredGam.setPy(Egam*sinth*sinphi);
00090 itsScatteredGam.setPz(Egam*costh);
00091 itsScatteredGam.setE(Egam);
00092
00093 itsScatteredEl.setPx(-itsScatteredGam.px());
00094 itsScatteredEl.setPy(-itsScatteredGam.py());
00095 itsScatteredEl.setPz(GamInLab.e()-itsScatteredGam.pz());
00096 itsScatteredEl.setE( sqrt( pow(electron_mass_c2,2) +
00097 pow(itsScatteredEl.px(),2)+
00098 pow(itsScatteredEl.py(),2)+
00099 pow(itsScatteredEl.pz(),2) ) );
00100
00101
00102 itsScatteredGam.rotateUz(LabGammaDir);
00103 itsScatteredEl.rotateUz(LabGammaDir);
00104
00105
00106 G4LorentzRotation BoostFromLab(Boost);
00107 itsScatteredGam *= BoostFromLab;
00108 itsScatteredEl *= BoostFromLab;
00109
00110 }
00111
00112 G4double BDSComptonEngine::ComptonDifferentialCrossSection(G4double costh, G4double lgamma){
00113 G4double f1=(1+costh*costh)/(1+lgamma*(1-costh)*(1-costh));
00114 G4double f2=1+(lgamma*lgamma*(1-costh)*(1-costh))/((1+costh*costh)*(1+lgamma*(1-costh)));
00115 G4double f=f1*f2;
00116 return f;
00117 }
00118
00119 G4double BDSComptonEngine::PeakAmplitudeOfComptonDifferentialCrossSection(G4double lgamma){
00120 G4double ndiv=1e6;
00121 G4double divsize=2/ndiv;
00122 G4double costh=-1;
00123 G4double fmax=0;
00124 G4double f=0;
00125 for(G4int i=0; i<ndiv; i++){
00126 f=ComptonDifferentialCrossSection(costh,lgamma);
00127 if(f>fmax) fmax=f;
00128 costh+=divsize;
00129 }
00130 return fmax;
00131 }
00132
00133
00134 void BDSComptonEngine::PerformHighEnergyCompton2()
00135 {
00136
00137
00138
00139
00140 G4double phi=twopi * G4UniformRand() ;
00141 G4double sinphi=sin(phi);
00142 G4double cosphi=cos(phi);
00143
00144 G4LorentzVector GamInLab, ElInLab;
00145 G4double x;
00146 G4ThreeVector Boost;
00147 G4double costh, costh2,sinth,sinth2;
00148
00149 Boost = itsIncomingEl.boostVector();
00150
00151 G4LorentzRotation BoostToLab(-Boost);
00152 GamInLab=BoostToLab*(itsIncomingGam);
00153 ElInLab=BoostToLab*(itsIncomingEl);
00154 G4ThreeVector LabGammaDir= GamInLab.vect().unit();
00155
00156 G4double beta = (GamInLab.e()-ElInLab.e())/(GamInLab.e()+ElInLab.e());
00157 G4double lgamma = 1/(sqrt(1-beta*beta));
00158
00159 G4double crsSecNormFact= PeakAmplitudeOfComptonDifferentialCrossSection(lgamma);
00160
00161 G4double r1, r2, result;
00162
00163 do {
00164 r1=G4UniformRand()*2-1;
00165 r2=G4UniformRand();
00166 result = ComptonDifferentialCrossSection(r1,lgamma)/crsSecNormFact;
00167 } while (result<r2);
00168
00169 costh = r1;
00170 costh2=costh*costh;
00171 sinth2=1.-costh2;
00172 sinth=sqrt(sinth2);
00173
00174
00175 x = 1/(1+ GamInLab.e()*(1-costh)/electron_mass_c2);
00176
00177 G4double Egam = x * GamInLab.e();
00178
00179
00180 sinth=sqrt(sinth2);
00181 itsScatteredGam.setPx(Egam*sinth*cosphi);
00182 itsScatteredGam.setPy(Egam*sinth*sinphi);
00183 itsScatteredGam.setPz(Egam*costh);
00184 itsScatteredGam.setE(Egam);
00185
00186 itsScatteredEl.setPx(-itsScatteredGam.px());
00187 itsScatteredEl.setPy(-itsScatteredGam.py());
00188 itsScatteredEl.setPz(GamInLab.e()-itsScatteredGam.pz());
00189 itsScatteredEl.setE( sqrt( pow(electron_mass_c2,2) +
00190 pow(itsScatteredEl.px(),2)+
00191 pow(itsScatteredEl.py(),2)+
00192 pow(itsScatteredEl.pz(),2) ) );
00193
00194
00195 itsScatteredGam.rotateUz(LabGammaDir);
00196 itsScatteredEl.rotateUz(LabGammaDir);
00197
00198
00199 G4LorentzRotation BoostFromLab(Boost);
00200 itsScatteredGam *= BoostFromLab;
00201 itsScatteredEl *= BoostFromLab;
00202 }
00203
00204
00205
00206
00207 void BDSComptonEngine::PerformHighEnergyCompton()
00208 {
00209
00210
00211 G4double phi=twopi * G4UniformRand() ;
00212 G4double sinphi=sin(phi);
00213 G4double cosphi=cos(phi);
00214
00215 G4LorentzVector GamInCM;
00216 G4LorentzVector ElInCM;
00217 G4double costh, costh2,sinth,sinth2;
00218
00219
00220 G4ThreeVector Boost=(itsIncomingEl+itsIncomingGam)/(itsIncomingEl.e()+itsIncomingGam.e());
00221
00222
00223 G4LorentzRotation BoostToCM(-Boost);
00224 GamInCM=BoostToCM*(itsIncomingGam);
00225 ElInCM=BoostToCM*(itsIncomingEl);
00226 G4ThreeVector CMGammaDir= GamInCM.vect().unit();
00227
00228 G4double e_cms=GamInCM.e()+ElInCM.e();
00229 G4double s=pow(e_cms,2);
00230 G4double eps= s*(1e-6 );
00231 G4double t_max=0;
00232 G4double t_min=-s+eps;
00233 G4double w_max = 0.5*(pow((s+t_max)/s,2)+1);
00234 G4double w=0;
00235 G4double t=0;
00236 G4double r1=0;
00237 G4double r2=0;
00238
00239 #ifdef DEBUG
00240 G4cout << "e_cms = " << e_cms << ", r2 = " << r2 << G4endl;
00241
00242 G4cout << "Gamma CM E = " << GamInCM.e() << G4endl;
00243 G4cout << "Gamma CM px = " << GamInCM.px() << G4endl;
00244 G4cout << "Gamma CM py = " << GamInCM.py() << G4endl;
00245 G4cout << "Gamma CM pz = " << GamInCM.pz() << G4endl;
00246
00247 G4cout << "e- CM E = " << ElInCM.e() << G4endl;
00248 G4cout << "e- CM px = " << ElInCM.px() << G4endl;
00249 G4cout << "e- CM py = " << ElInCM.py() << G4endl;
00250 G4cout << "e- CM pz = " << ElInCM.pz() << G4endl;
00251 #endif
00252
00253
00254 do{
00255 r1=G4UniformRand();
00256 r2=G4UniformRand();
00257 t = pow(s+t_max,r1)*pow(s+t_min,1.-r1)-s;
00258 w = 0.5*(pow((s+t)/s,2)+1);
00259 #ifdef DEBUG
00260 G4cout << "r1 = " << r1 << ", r2 = " << r2 << G4endl;
00261 G4cout << "s= " << s << ", t = " << t << ", w = " << w << ", w_max = " << w_max << G4endl;
00262 #endif
00263 }
00264 while(r2>(w/w_max));
00265 #ifdef DEBUG
00266 G4cout << "Finished: t = " << t << ", w = " << w << ", w_max = " << w_max << G4endl;
00267 #endif
00268
00269 G4double theta_cms = acos(2.*t/s + 1.);
00270
00271 costh=cos(theta_cms);
00272 costh2=costh*costh;
00273 sinth2=1.-costh2;
00274 sinth=sqrt(sinth2);
00275
00276 G4double p_trans_x_cms = (e_cms/2)*sinth*cosphi;
00277 G4double p_trans_y_cms = (e_cms/2)*sinth*sinphi;
00278 G4double p_long_cms = (e_cms/2)*costh;
00279
00280
00281 itsScatteredGam.setPx(p_trans_x_cms);
00282 itsScatteredGam.setPy(p_trans_y_cms);
00283 itsScatteredGam.setPz(p_long_cms);
00284 itsScatteredGam.setE(e_cms/2);
00285
00286
00287 itsScatteredEl.setPx(-p_trans_x_cms);
00288 itsScatteredEl.setPy(-p_trans_y_cms);
00289 itsScatteredEl.setPz(-p_long_cms);
00290 itsScatteredEl.setE(e_cms/2);
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 itsScatteredGam.rotateUz(CMGammaDir);
00309 itsScatteredEl.rotateUz(CMGammaDir);
00310
00311
00312 G4LorentzRotation BoostFromCM(Boost);
00313 itsScatteredGam *= BoostFromCM;
00314 itsScatteredEl *= BoostFromCM;
00315 }