G4QAtomicElectronScattering.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // $Id$
00027 //
00028 //      ---------------- G4QAtomicElectronScattering class -----------------
00029 //                 by Mikhail Kossov, December 2003.
00030 // G4QAtomicElectronScattering class of the CHIPS Simulation Branch in GEANT4
00031 // ---------------------------------------------------------------
00032 // ****************************************************************************************
00033 // ********** This CLASS is temporary moved from the photolepton_hadron directory *********
00034 // ****************************************************************************************
00035 // Short description: CHIPS is re3sponsible for photo- and lepto-nuclear
00036 // reactions. In particular for thr electron-nuclear reactions. At High
00037 // Energies the nucleons (including neutrons) and nuclear fragments can
00038 // interact with atomic electrons (reversed electro-nuclear reaction -
00039 // antilab), while they are missing the nucler-nuclear (ion-ion) reac-
00040 // tions. This nucleo-electron process comes "for-free" in CHIPS, as the
00041 // cross-sections of the interaction is known from the electro-nuclear
00042 // reactions. The only problem is to move the output from the antilab to
00043 // lab system. This is what this process is aiming to do. It can be used
00044 // for the ion transport in Geant4.
00045 // ---------------------------------------------------------------------
00046    
00047 //#define debug
00048 //#define pdebug
00049 
00050 #include "G4QAtomicElectronScattering.hh"
00051 #include "G4PhysicalConstants.hh"
00052 #include "G4HadronicDeprecate.hh"
00053 
00054 
00055 G4QAtomicElectronScattering::G4QAtomicElectronScattering(const G4String& processName):
00056  G4VDiscreteProcess(processName, fElectromagnetic)
00057 {
00058 
00059  G4HadronicDeprecate("G4QAtomicElectronScattering");
00060 
00061 #ifdef debug
00062   G4cout<<"G4QAtomicElectronScattering::Constructor is called"<<G4endl;
00063 #endif
00064   if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl;
00065 
00066   G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World with 234 particles
00067   G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,mediRatio); // Clusterization param's
00068   G4Quasmon::SetParameters(Temperature,SSin2Gluons,EtaEtaprime);  // Hadronic parameters
00069   G4QEnvironment::SetParameters(SolidAngle); // SolAngle of pbar-A secondary mesons capture
00070 }
00071 
00072 G4bool   G4QAtomicElectronScattering::manualFlag=false; // If false:use standard parameters
00073 G4double G4QAtomicElectronScattering::Temperature=180.; // Critical Temperature (High Ener)
00074 G4double G4QAtomicElectronScattering::SSin2Gluons=0.3;  // Supression of s-quarks (to u&d)
00075 G4double G4QAtomicElectronScattering::EtaEtaprime=0.3;  // Supression of eta(gg->qq/3g->qq)
00076 G4double G4QAtomicElectronScattering::freeNuc=0.5;      // % of free nucleons on a surface
00077 G4double G4QAtomicElectronScattering::freeDib=0.05;     // % of free diBaryons on a surface
00078 G4double G4QAtomicElectronScattering::clustProb=5.;     // Nuclear clusterization parameter
00079 G4double G4QAtomicElectronScattering::mediRatio=10.;    // medium/vacuum hadronizationRatio
00080 //G4int    G4QAtomicElectronScattering::nPartCWorld=152;// #of particles in the CHIPS World
00081 //G4int    G4QAtomicElectronScattering::nPartCWorld=122;// #of particles in the CHIPS World
00082 G4int    G4QAtomicElectronScattering::nPartCWorld=85;// #of particles in CHIPS World Reduce
00083 G4double G4QAtomicElectronScattering::SolidAngle=0.5;   // A part of Solid Angle to capture
00084 G4bool   G4QAtomicElectronScattering::EnergyFlux=false; // Flag to use EnergyFlux or MultyQ
00085 G4double G4QAtomicElectronScattering::PiPrThresh=141.4; // PiProductionThreshold for gammas
00086 G4double G4QAtomicElectronScattering::M2ShiftVir=20000.;// M2=-Q2=m_pi^2 shift of virtGamma
00087 G4double G4QAtomicElectronScattering::DiNuclMass=1880.; // Double Nucleon Mass for VirtNorm
00088 
00089 void G4QAtomicElectronScattering::SetManual()   {manualFlag=true;}
00090 void G4QAtomicElectronScattering::SetStandard() {manualFlag=false;}
00091 
00092 // Fill the private parameters
00093 void G4QAtomicElectronScattering::SetParameters(G4double temper, G4double ssin2g,
00094                                                 G4double etaetap, G4double fN, G4double fD,
00095                                                 G4double cP, G4double mR, G4int nParCW,
00096                                                 G4double solAn, G4bool efFlag,
00097                                                 G4double piThresh, G4double mpisq,
00098                                                 G4double dinum)
00099 {
00100   Temperature=temper;
00101   SSin2Gluons=ssin2g;
00102   EtaEtaprime=etaetap;
00103   freeNuc=fN;
00104   freeDib=fD;
00105   clustProb=cP;
00106   mediRatio=mR;
00107   nPartCWorld = nParCW;
00108   EnergyFlux=efFlag;
00109   SolidAngle=solAn;
00110   PiPrThresh=piThresh;
00111   M2ShiftVir=mpisq;
00112   DiNuclMass=dinum;
00113   G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World with 234 particles
00114   G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,mediRatio); // Clusterization param's
00115   G4Quasmon::SetParameters(Temperature,SSin2Gluons,EtaEtaprime);  // Hadronic parameters
00116   G4QEnvironment::SetParameters(SolidAngle); // SolAngle of pbar-A secondary mesons capture
00117 }
00118 
00119 // Destructor
00120 
00121 G4QAtomicElectronScattering::~G4QAtomicElectronScattering() {}
00122 
00123 
00124 G4LorentzVector G4QAtomicElectronScattering::GetEnegryMomentumConservation()
00125 {
00126   return EnMomConservation;
00127 }
00128 
00129 G4int G4QAtomicElectronScattering::GetNumberOfNeutronsInTarget()
00130 {
00131   return nOfNeutrons;
00132 }
00133 
00134 G4double G4QAtomicElectronScattering::GetMeanFreePath(const G4Track& aTrack,
00135                                                       G4double,G4ForceCondition* Fc)
00136 {
00137   *Fc = NotForced;
00138   const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle();
00139   G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition();
00140   if( !IsApplicable(*incidentParticleDefinition))
00141     G4cout<<"-Wa-G4QAtElScat::GetMeanFreePath called for not implemented particle"<<G4endl;
00142   // Calculate the mean Cross Section for the set of Elements(*Isotopes) in the Material
00143   G4double Momentum = incidentParticle->GetTotalMomentum(); // 3-momentum of the Particle
00144   const G4Material* material = aTrack.GetMaterial();        // Get the current material
00145   const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume();
00146   const G4ElementVector* theElementVector = material->GetElementVector();
00147   G4int nE=material->GetNumberOfElements();
00148 #ifdef debug
00149   G4cout<<"G4QAtomElectScattering::GetMeanFreePath:"<<nE<<" Elem's in theMaterial"<<G4endl;
00150 #endif
00151   //G4bool leptoNuc=false;       // By default the reaction is not lepto-nuclear
00152   G4VQCrossSection* CSmanager=G4QElectronNuclearCrossSection::GetPointer();
00153   if(incidentParticleDefinition == G4Electron::Electron())
00154   {
00155     CSmanager=G4QElectronNuclearCrossSection::GetPointer();
00156     //leptoNuc=true;
00157   }
00158   else G4cout<<"G4QAtomEScattering::GetMeanFreePath:Particle isn't known in CHIPS"<<G4endl;
00159   
00160   G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singelton
00161   G4double sigma=0.;
00162   for(G4int i=0; i<nE; ++i)
00163   {
00164     G4int Z = static_cast<G4int>((*theElementVector)[i]->GetZ()); // Z of the Element
00165     std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z); // Pointer to CS
00166     G4int nIs=cs->size();                         // A#Of Isotopes in the Element
00167     if(nIs) for(G4int j=0; j<nIs; j++)            // Calculate CS for eachIsotope of El
00168     {
00169       std::pair<G4int,G4double>* curIs=(*cs)[j];  // A pointer, which is used twice
00170       G4int N=curIs->first;                       // #ofNeuterons in the isotope
00171       curIs->second = CSmanager->GetCrossSection(true,Momentum,Z,N,13); // CS calculation
00172     } // End of temporary initialization of the cross sections in the G4QIsotope singeltone
00173     sigma+=Isotopes->GetMeanCrossSection(Z)*NOfNucPerVolume[i]; // SUM(MeanCS*NOFNperV)
00174   } // End of LOOP over Elements
00175 
00176   // Check that cross section is not zero and return the mean free path
00177   if(sigma > 0.) return 1./sigma;                 // Mean path [distance] 
00178   return DBL_MAX;
00179 }
00180 
00181 
00182 G4bool G4QAtomicElectronScattering::IsApplicable(const G4ParticleDefinition& particle) 
00183 {
00184   if      (particle == *(     G4MuonPlus::MuonPlus()     )) return true;
00185   else if (particle == *(    G4MuonMinus::MuonMinus()    )) return true; 
00186   else if (particle == *(      G4TauPlus::TauPlus()      )) return true;
00187   else if (particle == *(     G4TauMinus::TauMinus()     )) return true;
00188   else if (particle == *(     G4Electron::Electron()     )) return true;
00189   else if (particle == *(     G4Positron::Positron()     )) return true;
00190   else if (particle == *(        G4Gamma::Gamma()        )) return true;
00191   else if (particle == *(       G4Proton::Proton()       )) return true;
00192   //else if (particle == *(      G4Neutron::Neutron()      )) return true;
00193   //else if (particle == *(    G4PionMinus::PionMinus()    )) return true;
00194   //else if (particle == *(     G4PionPlus::PionPlus()     )) return true;
00195   //else if (particle == *(     G4KaonPlus::KaonPlus()     )) return true;
00196   //else if (particle == *(    G4KaonMinus::KaonMinus()    )) return true;
00197   //else if (particle == *( G4KaonZeroLong::KaonZeroLong() )) return true;
00198   //else if (particle == *(G4KaonZeroShort::KaonZeroShort())) return true;
00199   //else if (particle == *(       G4Lambda::Lambda()       )) return true;
00200   //else if (particle == *(    G4SigmaPlus::SigmaPlus()    )) return true;
00201   //else if (particle == *(   G4SigmaMinus::SigmaMinus()   )) return true;
00202   //else if (particle == *(    G4SigmaZero::SigmaZero()    )) return true;
00203   //else if (particle == *(      G4XiMinus::XiMinus()      )) return true;
00204   //else if (particle == *(       G4XiZero::XiZero()       )) return true;
00205   //else if (particle == *(   G4OmegaMinus::OmegaMinus()   )) return true;
00206   //else if (particle == *(  G4AntiNeutron::AntiNeutron()  )) return true;
00207   //else if (particle == *(   G4AntiProton::AntiProton()   )) return true;
00208 #ifdef debug
00209   G4cout<<"***G4QAtomElScattering::IsApplicable: PDG="<<particle.GetPDGEncoding()<<G4endl;
00210 #endif
00211   return false;
00212 }
00213 
00214 G4VParticleChange* G4QAtomicElectronScattering::PostStepDoIt(const G4Track& track,
00215                                                              const G4Step& step)
00216 {
00217   static const G4double mu=G4MuonMinus::MuonMinus()->GetPDGMass(); // muon mass
00218   static const G4double mu2=mu*mu;                                 // squared muon mass
00219   //static const G4double dpi=M_PI+M_PI;   // 2*pi (for Phi distr.) ***changed to twopi***
00220   static const G4double mNeut= G4QPDGCode(2112).GetMass();
00221   static const G4double mProt= G4QPDGCode(2212).GetMass();
00222   static const G4double dM=mProt+mNeut;                            // doubled nucleon mass
00223   //static const G4double mPi0 = G4QPDGCode(111).GetMass();
00224   //static const G4double mDeut= G4QPDGCode(2112).GetNuclMass(1,1,0);
00225   //static const G4double mPi  = G4QPDGCode(211).GetMass();
00226   //static const G4double mMu  = G4QPDGCode(13).GetMass();
00227   //static const G4double mTau = G4QPDGCode(15).GetMass();
00228   //static const G4double mEl  = G4QPDGCode(11).GetMass();
00229   //
00230   const G4DynamicParticle* projHadron = track.GetDynamicParticle();
00231   const G4ParticleDefinition* particle=projHadron->GetDefinition();
00232   G4LorentzVector proj4M=projHadron->Get4Momentum();
00233   G4double momentum = projHadron->GetTotalMomentum(); // 3-momentum of the Particle
00234   G4double Momentum=proj4M.rho();
00235   if(std::fabs(Momentum-momentum)>.001) G4cerr<<"G4QAtElScat::PSDI P="<<Momentum<<"="
00236                                               <<momentum<<G4endl;
00237 #ifdef debug
00238   G4double mp=proj4M.m();
00239   G4cout<<"G4QAtomElScattering::PostStepDoIt called, P="<<Momentum<<"="<<momentum<<G4endl;
00240 #endif
00241   if (!IsApplicable(*particle))  // Check applicability
00242   {
00243     G4cerr<<"G4QAtomElectScat::PostStepDoIt:Only gam,e+,e-,mu+,mu-,t+,t-,p are implemented"
00244           <<G4endl;
00245     return 0;
00246   }
00247   const G4Material* material = track.GetMaterial();      // Get the current material
00248   G4int Z=0;
00249   const G4ElementVector* theElementVector = material->GetElementVector();
00250   G4int i=0;
00251   G4double sum=0.;
00252   G4int nE=material->GetNumberOfElements();
00253 #ifdef debug
00254   G4cout<<"G4QAtomElectronScat::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl;
00255 #endif
00256   G4int projPDG=0;                           // PDG Code prototype for the captured hadron
00257   // Not all these particles are implemented yet (see Is Applicable)
00258   if      (particle ==      G4MuonPlus::MuonPlus()     ) projPDG=  -13;
00259   else if (particle ==     G4MuonMinus::MuonMinus()    ) projPDG=   13;
00260   else if (particle ==      G4Electron::Electron()     ) projPDG=   11;
00261   else if (particle ==      G4Positron::Positron()     ) projPDG=  -11;
00262   else if (particle ==         G4Gamma::Gamma()        ) projPDG=   22;
00263   else if (particle ==        G4Proton::Proton()       ) projPDG= 2212;
00264   else if (particle ==       G4Neutron::Neutron()      ) projPDG= 2112;
00265   else if (particle ==     G4PionMinus::PionMinus()    ) projPDG= -211;
00266   else if (particle ==      G4PionPlus::PionPlus()     ) projPDG=  211;
00267   else if (particle ==      G4KaonPlus::KaonPlus()     ) projPDG= 2112;
00268   else if (particle ==     G4KaonMinus::KaonMinus()    ) projPDG= -321;
00269   else if (particle ==  G4KaonZeroLong::KaonZeroLong() ) projPDG=  130;
00270   else if (particle == G4KaonZeroShort::KaonZeroShort()) projPDG=  310;
00271   else if (particle ==       G4TauPlus::TauPlus()      ) projPDG=  -15;
00272   else if (particle ==      G4TauMinus::TauMinus()     ) projPDG=   15;
00273   else if (particle ==        G4Lambda::Lambda()       ) projPDG= 3122;
00274   else if (particle ==     G4SigmaPlus::SigmaPlus()    ) projPDG= 3222;
00275   else if (particle ==    G4SigmaMinus::SigmaMinus()   ) projPDG= 3112;
00276   else if (particle ==     G4SigmaZero::SigmaZero()    ) projPDG= 3212;
00277   else if (particle ==       G4XiMinus::XiMinus()      ) projPDG= 3312;
00278   else if (particle ==        G4XiZero::XiZero()       ) projPDG= 3322;
00279   else if (particle ==    G4OmegaMinus::OmegaMinus()   ) projPDG= 3334;
00280   else if (particle ==   G4AntiNeutron::AntiNeutron()  ) projPDG=-2112;
00281   else if (particle ==    G4AntiProton::AntiProton()   ) projPDG=-2212;
00282 #ifdef debug
00283   G4int prPDG=particle->GetPDGEncoding();
00284   G4cout<<"G4QAtomElScat::PostStepRestDoIt: projPDG="<<projPDG<<",stPDG="<<prPDG<<G4endl;
00285 #endif
00286   if(!projPDG)
00287   {
00288     G4cerr<<"-Warning-G4QAtomElScattering::PostStepDoIt:Undefined captured hadron"<<G4endl;
00289     return 0;
00290   }
00291   // @@ It's a standard randomization procedure, which can be placed in G4QMaterial class
00292   std::vector<G4double> sumfra;
00293   for(i=0; i<nE; ++i)
00294   {
00295     G4double frac=material->GetFractionVector()[i];
00296     sum+=frac;
00297     sumfra.push_back(sum);             // remember the summation steps
00298   }
00299   G4double rnd = sum*G4UniformRand();
00300   for(i=0; i<nE; ++i) if (rnd<sumfra[i]) break;
00301   G4Element* pElement=(*theElementVector)[i];
00302   Z=static_cast<G4int>(pElement->GetZ());
00303   if(Z<=0)
00304   {
00305     G4cerr<<"-Warning-G4QAtomicElectronScattering::PostStepDoIt: Element's Z="<<Z<<G4endl;
00306     if(Z<0) return 0;
00307   }
00308   G4int N = Z;
00309   G4int isoSize=0;                         // The default for the isoVectorLength is 0
00310   G4IsotopeVector* isoVector=pElement->GetIsotopeVector();
00311   if(isoVector) isoSize=isoVector->size(); // Get real size of the isotopeVector if exists
00312 #ifdef debug
00313   G4cout<<"G4QAtomicElectronScattering::PostStepDoIt: isovectorLength="<<isoSize<<G4endl;
00314 #endif
00315   if(isoSize)                         // The Element has not trivial abumdance set
00316   {
00317     // @@ the following solution is temporary till G4Element can contain the QIsotopIndex
00318     G4int curInd=G4QIsotope::Get()->GetLastIndex(Z);
00319     if(!curInd)                       // The new artificial element must be defined 
00320     {
00321       std::vector<std::pair<G4int,G4double>*>* newAbund =
00322                                                new std::vector<std::pair<G4int,G4double>*>;
00323       G4double* abuVector=pElement->GetRelativeAbundanceVector();
00324       for(G4int j=0; j<isoSize; j++)
00325       {
00326         N=pElement->GetIsotope(j)->GetN()-Z;
00327         if(pElement->GetIsotope(j)->GetZ()!=Z) G4cerr<<"*G4QCaptureAtRest::AtRestDoIt: Z="
00328                                         <<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl;
00329         G4double abund=abuVector[j];
00330         std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund);
00331 #ifdef debug
00332         G4cout<<"G4QAtomElScat::PostStepDoIt:pair#="<<j<<", N="<<N<<",ab="<<abund<<G4endl;
00333 #endif
00334         newAbund->push_back(pr);
00335       }
00336 #ifdef debug
00337       G4cout<<"G4QAtomElectScat::PostStepDoIt:pairVectorLength="<<newAbund->size()<<G4endl;
00338 #endif
00339       curInd=G4QIsotope::Get()->InitElement(Z,1,newAbund);
00340       for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k];
00341       delete newAbund;
00342     }
00343     // @@ ^^^^^^^^^^ End of the temporary solution ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
00344     N = G4QIsotope::Get()->GetNeutrons(Z,curInd);
00345   }
00346   else  N = G4QIsotope::Get()->GetNeutrons(Z);
00347   nOfNeutrons=N;                                       // Remember it for energy-mom. check
00348   G4double dd=0.025;
00349   G4double am=Z+N;
00350   G4double value_sr=std::sqrt(am);
00351   G4double dsr=0.01*(value_sr+value_sr);
00352   if(dsr<dd)dsr=dd;
00353   if(manualFlag) G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,mediRatio); // ManualP
00354   else if(projPDG==-2212) G4QNucleus::SetParameters(1.-dsr-dsr,dd+dd,5.,10.);//aP ClustPars
00355   else if(projPDG==-211)  G4QNucleus::SetParameters(.67-dsr,.32-dsr,5.,9.);//Pi- ClustPars
00356 #ifdef debug
00357   G4cout<<"G4QAtomElectScattering::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl;
00358 #endif
00359   if(N<0)
00360   {
00361     G4cerr<<"---Warning---G4QAtomElectScat::PostStepDoIt:Element with N="<<N<< G4endl;
00362     return 0;
00363   }
00364   if(projPDG==11||projPDG==-11||projPDG==13||projPDG==-13||projPDG==15||projPDG==-15)
00365   { // Lepto-nuclear case with the equivalent photon algorithm. @@InFuture + neutrino & QE
00366     G4double kinEnergy= projHadron->GetKineticEnergy();
00367     G4ParticleMomentum dir = projHadron->GetMomentumDirection();
00368     G4VQCrossSection* CSmanager=G4QElectronNuclearCrossSection::GetPointer();
00369     G4int aProjPDG=std::abs(projPDG);
00370     if(aProjPDG==13) CSmanager=G4QMuonNuclearCrossSection::GetPointer();
00371     if(aProjPDG==15) CSmanager=G4QTauNuclearCrossSection::GetPointer();
00372     G4double xSec=CSmanager->GetCrossSection(false,Momentum,Z,N,13);//Recalculate CrossSect
00373     // @@ check a possibility to separate p, n, or alpha (!)
00374     if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
00375     {
00376       //Do Nothing Action insead of the reaction
00377       aParticleChange.ProposeEnergy(kinEnergy);
00378       aParticleChange.ProposeLocalEnergyDeposit(0.);
00379       aParticleChange.ProposeMomentumDirection(dir) ;
00380       return G4VDiscreteProcess::PostStepDoIt(track,step);
00381     }
00382     G4double photonEnergy = CSmanager->GetExchangeEnergy(); // Energy of EqivExchangePart
00383     if( kinEnergy < photonEnergy )
00384     {
00385       //Do Nothing Action insead of the reaction
00386       G4cerr<<"G4QAtomElectScat::PSDoIt: phE="<<photonEnergy<<">leptE="<<kinEnergy<<G4endl;
00387       aParticleChange.ProposeEnergy(kinEnergy);
00388       aParticleChange.ProposeLocalEnergyDeposit(0.);
00389       aParticleChange.ProposeMomentumDirection(dir) ;
00390       return G4VDiscreteProcess::PostStepDoIt(track,step);
00391     }
00392     G4double photonQ2 = CSmanager->GetExchangeQ2(photonEnergy);// Q2(t) of EqivExchangePart
00393     G4double W=photonEnergy-photonQ2/dM;// HadronicEnergyFlow (W-energy) for virtual photon
00394     if(W<0.) 
00395     {
00396       //Do Nothing Action insead of the reaction
00397       G4cout<<"G4QAtomElScat::PostStepDoIt:(lN) negative equivalent energy W="<<W<<G4endl;
00398       aParticleChange.ProposeEnergy(kinEnergy);
00399       aParticleChange.ProposeLocalEnergyDeposit(0.);
00400       aParticleChange.ProposeMomentumDirection(dir) ;
00401       return G4VDiscreteProcess::PostStepDoIt(track,step);
00402     }
00403     // Update G4VParticleChange for the scattered muon
00404     G4VQCrossSection* thePhotonData=G4QPhotonNuclearCrossSection::GetPointer();
00405     G4double sigNu=thePhotonData->GetCrossSection(true,photonEnergy, Z, N);// Integrated CS
00406     G4double sigK =thePhotonData->GetCrossSection(true, W, Z, N);          // Real CrosSect
00407     G4double rndFraction = CSmanager->GetVirtualFactor(photonEnergy, photonQ2);
00408     if(sigNu*G4UniformRand()>sigK*rndFraction) 
00409     {
00410       //Do NothingToDo Action insead of the reaction
00411       G4cout<<"G4QAtomElectScat::PostStepDoIt: probability correction - DoNothing"<<G4endl;
00412       aParticleChange.ProposeEnergy(kinEnergy);
00413       aParticleChange.ProposeLocalEnergyDeposit(0.);
00414       aParticleChange.ProposeMomentumDirection(dir) ;
00415       return G4VDiscreteProcess::PostStepDoIt(track,step);
00416     }
00417     G4double iniE=kinEnergy+mu;          // Initial total energy of the muon
00418     G4double finE=iniE-photonEnergy;     // Final total energy of the muon
00419     if(finE>0) aParticleChange.ProposeEnergy(finE) ;
00420     else
00421     {
00422       aParticleChange.ProposeEnergy(0.) ;
00423       aParticleChange.ProposeTrackStatus(fStopAndKill);
00424     }
00425     // Scatter the muon
00426     G4double EEm=iniE*finE-mu2;          // Just an intermediate value to avoid "2*"
00427     G4double iniP=std::sqrt(iniE*iniE-mu2);   // Initial momentum of the electron
00428     G4double finP=std::sqrt(finE*finE-mu2);   // Final momentum of the electron
00429     G4double cost=(EEm+EEm-photonQ2)/iniP/finP; // cos(theta) for the electron scattering
00430     if(cost>1.) cost=1.;                 // To avoid the accuracy of calculation problem
00431     //else if(cost>1.001)                // @@ error report can be done, but not necessary
00432     if(cost<-1.) cost=-1.;               // To avoid the accuracy of calculation problem
00433     //else if(cost<-1.001)               // @@ error report can be done, but not necessary
00434     // --- Example from electromagnetic physics --
00435     //G4ThreeVector newMuonDirection(dirx,diry,dirz);
00436     //newMuonDirection.rotateUz(dir);
00437     //aParticleChange.ProposeMomentumDirection(newMuonDirection1) ;
00438     // The scattering in respect to the derection of the incident muon is made impicitly:
00439     G4ThreeVector ort=dir.orthogonal();  // Not normed orthogonal vector (!) (to dir)
00440     G4ThreeVector ortx = ort.unit();     // First unit vector orthogonal to the direction
00441     G4ThreeVector orty = dir.cross(ortx);// Second unit vector orthoganal to the direction
00442     G4double sint=std::sqrt(1.-cost*cost);    // Perpendicular component
00443     G4double phi=twopi*G4UniformRand();  // phi of scattered electron
00444     G4double sinx=sint*std::sin(phi);         // x-component
00445     G4double siny=sint*std::cos(phi);         // y-component
00446     G4ThreeVector findir=cost*dir+sinx*ortx+siny*orty;
00447     aParticleChange.ProposeMomentumDirection(findir); // new direction for the muon
00448     const G4ThreeVector photon3M=iniP*dir-finP*findir;
00449     projPDG=22;
00450     proj4M=G4LorentzVector(photon3M,photon3M.mag());
00451   }
00452   G4int targPDG=90000000+Z*1000+N;       // PDG Code of the target nucleus
00453   G4QPDGCode targQPDG(targPDG);
00454   G4double tM=targQPDG.GetMass();
00455   EnMomConservation=proj4M+G4LorentzVector(0.,0.,0.,tM);    // Total 4-mom of the reaction
00456   G4QHadronVector* output=new G4QHadronVector; // Prototype of the output G4QHadronVector
00457   // @@@@@@@@@@@@@@ Temporary for the testing purposes --- Begin
00458   //G4bool elF=false; // Flag of the ellastic scattering is "false" by default
00459   //G4double eWei=1.;
00460   // @@@@@@@@@@@@@@ Temporary for the testing purposes --- End  
00461 #ifdef debug
00462   G4cout<<"G4QAtomElScat::PostStepDoIt: projPDG="<<projPDG<<", targPDG="<<targPDG<<G4endl;
00463 #endif
00464   G4QHadron* pH = new G4QHadron(projPDG,proj4M);                // ---> DELETED -->------*
00465   //if(momentum<1000.)// Condition for using G4QEnvironment (not G4QuasmonString)         |
00466   //{//                                                                                   |
00467     G4QHadronVector projHV;                                 //                           |
00468     projHV.push_back(pH);                                   // DESTROYED over 2 lines -* |
00469     G4QEnvironment* pan= new G4QEnvironment(projHV,targPDG);// ---> DELETED --->-----* | |
00470     std::for_each(projHV.begin(), projHV.end(), DeleteQHadron()); // <---<------<----+-+-*
00471     projHV.clear(); // <------------<---------------<-------------------<------------+-* .
00472 #ifdef debug
00473     G4cout<<"G4QAtomElectScat::PostStepDoIt: pPDG="<<projPDG<<", mp="<<mp<<G4endl;// |   .
00474 #endif
00475     try                                                           //                 |   ^
00476     {                                                             //                 |   .
00477       delete output;                                              //                 |   ^
00478       output = pan->Fragment();// DESTROYED in the end of the LOOP work space        |   .
00479     }                                                             //                 |   ^
00480     catch (G4QException& error)//                                                    |   .
00481     {                                                             //                 |   ^
00482       //#ifdef pdebug
00483       G4cerr<<"**G4QAtomElectScat::PostStepDoIt:G4QE Exception is catched"<<G4endl;//|   .
00484       //#endif
00485       // G4Exception("G4QAtomElScat::PostStepDoIt:","27",FatalException,"CHIPScrash");//|   .
00486       G4Exception("G4QAtomElScat::PostStepDoIt()", "HAD_CHPS_0027",
00487                   FatalException, "CHIPScrash");
00488     }                                                             //                 |   ^
00489     delete pan;                              // Delete the Nuclear Environment <--<--*   .
00490   //}//                                                                                   ^
00491   //else              // Use G4QuasmonString                                              .
00492   //{//                                                                                   ^
00493   //  G4QuasmonString* pan= new G4QuasmonString(pH,false,targPDG,false);//-> DELETED --*  .
00494   //  delete pH;                                                    // --------<-------+--+
00495   //#ifdef debug
00496   //  G4double mp=G4QPDGCode(projPDG).GetMass();   // Mass of the projectile particle  |
00497   //  G4cout<<"G4QAtomElectScat::PostStepDoIt: pPDG="<<projPDG<<", pM="<<mp<<G4endl; //|
00498   //#endif
00499   //  G4int tNH=0;                    // Prototype of the number of secondaries inOut|
00500   //  try                                                           //                 |
00501   //  {                                                             //                 |
00502   //    delete output;                                              //                 |
00503   //    output = pan->Fragment();// DESTROYED in the end of the LOOP work space        |
00504   //    // @@@@@@@@@@@@@@ Temporary for the testing purposes --- Begin                 |
00505   //    //tNH=pan->GetNOfHadrons();     // For the test purposes of the String         |
00506   //    //if(tNH==2)                    // At least 2 hadrons are in the Constr.Output |
00507   //    //{//                                                                          |
00508   //    //  elF=true;                   // Just put a flag for the ellastic Scattering |
00509   //    //  delete output;              // Delete a prototype of dummy G4QHadronVector |
00510   //    //  output = pan->GetHadrons(); // DESTROYED in the end of the LOOP work space |
00511   //    //}//                                                                          |
00512   //    //eWei=pan->GetWeight();        // Just an example for the weight of the event |
00513   //#ifdef debug
00514   //    //G4cout<<"=---=>>G4QAtomElScat::PostStepDoIt:elF="<<elF<<",n="<<tNH<<G4endl;//|
00515   //#endif
00516   //    // @@@@@@@@@@@@@@ Temporary for the testing purposes --- End                   |
00517   //  }                                                             //                 |
00518   //  catch (G4QException& error)//                                                    |
00519   //  {                                                             //                 |
00520   //    //#ifdef pdebug
00521   //    G4cerr<<"**G4QAtomElectScat::PostStepDoIt: GEN Exception is catched"<<G4endl;//|
00522   //    //#endif
00523   //    G4Exception("G4QAtomElSct::AtRestDoIt:","27",FatalException,"QString Excep");//|
00524   //  }                                                             //                 |
00525   //  delete pan;                              // Delete the Nuclear Environment ---<--*
00526   //}
00527   aParticleChange.Initialize(track);
00528   G4double localtime = track.GetGlobalTime();
00529   G4ThreeVector position = track.GetPosition();
00530   G4TouchableHandle trTouchable = track.GetTouchableHandle();
00531   // ------------- From here the secondaries are filled -------------------------
00532   G4int tNH = output->size();       // A#of hadrons in the output
00533   aParticleChange.SetNumberOfSecondaries(tNH); 
00534   // Now add nuclear fragments
00535 #ifdef debug
00536   G4cout<<"G4QAtomElectronScat::PostStepDoIt: "<<tNH<<" particles are generated"<<G4endl;
00537 #endif
00538   G4int nOut=output->size();               // Real length of the output @@ Temporary
00539   if(tNH==1) tNH=0;                        // @@ Temporary
00540   if(tNH==2&&2!=nOut) G4cout<<"--Warning--G4QAtomElScat::PostStepDoIt: 2 # "<<nOut<<G4endl;
00541   // Deal with ParticleChange final state interface to GEANT4 output of the process
00542   //if(tNH==2) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
00543   if(tNH) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
00544   {
00545     // Note that one still has to take care of Hypernuclei (with Lambda or Sigma inside)
00546     // Hypernucleus mass calculation and ion-table interface upgrade => work for Hisaya @@
00547     // The decau process for hypernuclei must be developed in GEANT4 (change CHIPS body)
00548     G4QHadron* hadr=output->operator[](i);   // Pointer to the output hadron    
00549     G4int PDGCode = hadr->GetPDGCode();
00550     G4int nFrag   = hadr->GetNFragments();
00551 #ifdef pdebug
00552     G4cout<<"G4QAtomElectScat::AtRestDoIt: H#"<<i<<",PDG="<<PDGCode<<",nF="<<nFrag<<G4endl;
00553 #endif
00554     if(nFrag)                // Skip intermediate (decayed) hadrons
00555     {
00556 #ifdef debug
00557       G4cout<<"G4QAtomElScat::PostStepDoIt: Intermediate particle is found i="<<i<<G4endl;
00558 #endif
00559       delete hadr;
00560       continue;
00561     }
00562     G4DynamicParticle* theSec = new G4DynamicParticle;  
00563     G4ParticleDefinition* theDefinition;
00564     if     (PDGCode==90000001) theDefinition = G4Neutron::Neutron();
00565     else if(PDGCode==90001000) theDefinition = G4Proton::Proton();//While it can be in ions
00566     else if(PDGCode==91000000) theDefinition = G4Lambda::Lambda();
00567     else if(PDGCode==311 || PDGCode==-311)
00568     {
00569       if(G4UniformRand()>.5) theDefinition = G4KaonZeroLong::KaonZeroLong();   // K_L
00570       else                   theDefinition = G4KaonZeroShort::KaonZeroShort(); // K_S
00571     }
00572     else if(PDGCode==91000999) theDefinition = G4SigmaPlus::SigmaPlus();
00573     else if(PDGCode==90999001) theDefinition = G4SigmaMinus::SigmaMinus();
00574     else if(PDGCode==91999000) theDefinition = G4XiMinus::XiMinus();
00575     else if(PDGCode==91999999) theDefinition = G4XiZero::XiZero();
00576     else if(PDGCode==92998999) theDefinition = G4OmegaMinus::OmegaMinus();
00577     else if(PDGCode >80000000) // Defines hypernuclei as normal nuclei (N=N+S Correction!)
00578     {
00579       G4int aZ = hadr->GetCharge();
00580       G4int aA = hadr->GetBaryonNumber();
00581 #ifdef pdebug
00582       G4cout<<"G4QAtomicElectronScattering::AtRestDoIt:Ion Z="<<aZ<<", A="<<aA<<G4endl;
00583 #endif
00584       theDefinition = G4ParticleTable::GetParticleTable()->FindIon(aZ,aA,0,aZ);
00585     }
00586     //else theDefinition = G4ParticleTable::GetParticleTable()->FindParticle(PDGCode);
00587     else
00588     {
00589 #ifdef pdebug
00590       G4cout<<"G4QAtomElectScat::PostStepDoIt:Define particle with PDG="<<PDGCode<<G4endl;
00591 #endif
00592       theDefinition = G4QPDGToG4Particle::Get()->GetParticleDefinition(PDGCode);
00593 #ifdef pdebug
00594       G4cout<<"G4QAtomElScat::PostStepDoIt:AfterParticleDefinition PDG="<<PDGCode<<G4endl;
00595 #endif
00596     }
00597     if(!theDefinition)
00598     {
00599       G4cout<<"---Warning---G4QAtomElScattering::PostStepDoIt: drop PDG="<<PDGCode<<G4endl;
00600       delete hadr;
00601       continue;
00602     }
00603 #ifdef pdebug
00604     G4cout<<"G4QAtomElScat::PostStepDoIt:Name="<<theDefinition->GetParticleName()<<G4endl;
00605 #endif
00606     theSec->SetDefinition(theDefinition);
00607     G4LorentzVector h4M=hadr->Get4Momentum();
00608     EnMomConservation-=h4M;
00609 #ifdef tdebug
00610     G4cout<<"G4QCollis::PSDI:"<<i<<","<<PDGCode<<h4M<<h4M.m()<<EnMomConservation<<G4endl;
00611 #endif
00612 #ifdef debug
00613     G4cout<<"G4QAtomElectScat::PostStepDoIt:#"<<i<<",PDG="<<PDGCode<<",4M="<<h4M<<G4endl;
00614 #endif
00615     theSec->Set4Momentum(h4M); //                                                         ^
00616     delete hadr; // <-----<-----------<-------------<---------------------<---------<-----*
00617 #ifdef debug
00618     G4ThreeVector curD=theSec->GetMomentumDirection();              //                    ^
00619     G4double curM=theSec->GetMass();                                //                    |
00620     G4double curE=theSec->GetKineticEnergy()+curM;                  //                    ^
00621     G4cout<<"G4QCollis::PSDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl;// |
00622 #endif
00623     G4Track* aNewTrack = new G4Track(theSec, localtime, position ); //                    ^
00624     aNewTrack->SetTouchableHandle(trTouchable);                     //                    |
00625     aParticleChange.AddSecondary( aNewTrack );                      //                    |
00626 #ifdef debug
00627     G4cout<<"G4QAtomicElectronScattering::PostStepDoIt:#"<<i<<" is done."<<G4endl; //     |
00628 #endif
00629   } //                                                                                    |
00630   delete output; // instances of the G4QHadrons from the output are already deleted above *
00631   aParticleChange.ProposeTrackStatus(fStopAndKill);        // Kill the absorbed particle
00632   //return &aParticleChange;                               // This is not enough (ClearILL)
00633 #ifdef debug
00634     G4cout<<"G4QAtomicElectronScattering::PostStepDoIt:****PostStepDoIt done****"<<G4endl;
00635 #endif
00636   return G4VDiscreteProcess::PostStepDoIt(track, step);
00637 }

Generated on Mon May 27 17:49:30 2013 for Geant4 by  doxygen 1.4.7