/scratch0/jsnuveri/BDSIM/BDSIMgit/bdsim/src/BDSComptonEngine.cc

00001 /* BDSIM code.    Version 1.0
00002    Author: Grahame A. Blair, Royal Holloway, Univ. of London.
00003    Last modified 24.7.2002
00004    Copyright (c) 2002 by G.A.Blair.  ALL RIGHTS RESERVED. 
00005 */
00006 //      ------------ BDSComptonEngine physics process --------
00007 //                     by Grahame Blair, 19 October 2001
00008 
00009 #include "BDSComptonEngine.hh"
00010 #include "G4ios.hh"
00011 #include "G4LorentzRotation.hh"
00012 #include "Randomize.hh" 
00013 #include "CLHEP/Units/PhysicalConstants.h"
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   // Generate compton event; using method described in
00034   // H.Burkardt, SL/Note 93-73
00035   
00036   G4double phi=CLHEP::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    //   BoostToLab.boost(-Boost);
00050   G4LorentzRotation BoostToLab(-Boost);
00051   GamInLab=BoostToLab*(itsIncomingGam);
00052   G4ThreeVector LabGammaDir= GamInLab.vect().unit();
00053   
00054   G4double weight_CovT=0;  //ratio of Compton to Thompson cross sections:
00055   do {ntry++;
00056   // 1+cos^2 theta distribution
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   // x is ratio of scattered to unscattered photon energy:
00072   x = 1/(1+ GamInLab.e()*(1-costh)/CLHEP::electron_mass_c2);
00073   
00074   //calculate weight of Compton relative to Thompson cross sections:
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   // G4LorentzVector ElInLab=BoostToLab*(itsIncomingEl);
00082   
00083   G4double Egam = x * GamInLab.e();
00084   
00085   // Generate final momenta:
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(CLHEP::electron_mass_c2,2) +
00097                              pow(itsScatteredEl.px(),2)+
00098                              pow(itsScatteredEl.py(),2)+
00099                              pow(itsScatteredEl.pz(),2) ) );
00100   
00101   // Rotates the reference frame from Uz to newUz (unit vector).
00102   itsScatteredGam.rotateUz(LabGammaDir);
00103   itsScatteredEl.rotateUz(LabGammaDir);
00104   
00105   // now boost back to the original frame:
00106   G4LorentzRotation BoostFromLab(Boost);
00107   itsScatteredGam *= BoostFromLab;
00108   itsScatteredEl *= BoostFromLab;
00109 
00110 }
00111 
00112 G4double BDSComptonEngine::ComptonDifferentialCrossSection(G4double costh, G4double lgamma){ //lgamma is the lorentz gamma, costheta is the scattering angle
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   // Generate compton event; using method described in
00138   // H.Burkardt, SL/Note 93-73
00139   
00140   G4double phi=CLHEP::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    //   BoostToLab.boost(-Boost);
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); //Normalisation factor
00160   
00161   G4double r1, r2, result; //Random variable
00162 
00163   do { //Rejection method
00164     r1=G4UniformRand()*2-1; //Random costh
00165     r2=G4UniformRand(); //Random number betweeon 0 and 1  
00166     result = ComptonDifferentialCrossSection(r1,lgamma)/crsSecNormFact; //Result between 0 and 1
00167   } while (result<r2); //Rejection
00168   
00169   costh = r1;
00170   costh2=costh*costh;
00171   sinth2=1.-costh2;
00172   sinth=sqrt(sinth2);
00173 
00174   // x is ratio of scattered to unscattered photon energy:
00175   x = 1/(1+ GamInLab.e()*(1-costh)/CLHEP::electron_mass_c2);
00176 
00177   G4double Egam = x * GamInLab.e();
00178   
00179   // Generate final momenta:
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(CLHEP::electron_mass_c2,2) +
00190                              pow(itsScatteredEl.px(),2)+
00191                              pow(itsScatteredEl.py(),2)+
00192                              pow(itsScatteredEl.pz(),2) ) );
00193   
00194   // Rotates the reference frame from Uz to newUz (unit vector).
00195   itsScatteredGam.rotateUz(LabGammaDir);
00196   itsScatteredEl.rotateUz(LabGammaDir);
00197   
00198   // now boost back to the original frame:
00199   G4LorentzRotation BoostFromLab(Boost);
00200   itsScatteredGam *= BoostFromLab;
00201   itsScatteredEl *= BoostFromLab;
00202 }
00203 
00204 
00205 
00206 
00207 void BDSComptonEngine::PerformHighEnergyCompton()
00208 {
00209 
00210   // Generate high energy compton event
00211   G4double phi=CLHEP::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   //Boost the electron and gamma to the cm frame
00220   G4ThreeVector Boost=(itsIncomingEl+itsIncomingGam)/(itsIncomingEl.e()+itsIncomingGam.e());
00221   //  G4ThreeVector Boost=itsIncomingEl.boostVector();
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); // overrides CLHEP::s
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 BDSDEBUG
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 BDSDEBUG
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 BDSDEBUG
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   //generate final momenta
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   //  itsScatteredGam.setE(e_cms/2);
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   //  itsScatteredEl.setE(sqrt( pow(CLHEP::electron_mass_c2,2)+pow(its);
00292 
00293   /*
00294   itsScatteredGam.setPx(p_trans_x_cms);
00295   itsScatteredGam.setPy(p_trans_y_cms);
00296   itsScatteredGam.setPz(p_long_cms);
00297   itsScatteredGam.setE(e_cms);
00298 
00299   itsScatteredEl.setPx(-itsScatteredGam.px());
00300   itsScatteredEl.setPy(-itsScatteredGam.py());
00301   itsScatteredEl.setPz(GamInCM.e()-itsScatteredGam.pz());
00302   itsScatteredEl.setE( sqrt( pow(CLHEP::electron_mass_c2,2) +
00303                              pow(itsScatteredEl.px(),2)+
00304                              pow(itsScatteredEl.py(),2)+
00305                              pow(itsScatteredEl.pz(),2) ) );
00306   */
00307   // Rotates the reference frame from Uz to newUz (unit vector).
00308   itsScatteredGam.rotateUz(CMGammaDir);
00309   itsScatteredEl.rotateUz(CMGammaDir);
00310   
00311   // now boost back to the original frame:
00312   G4LorentzRotation BoostFromCM(Boost);
00313   itsScatteredGam *= BoostFromCM;
00314   itsScatteredEl *= BoostFromCM;
00315 }

Generated on 28 Jun 2015 for BDSIM by  doxygen 1.4.7