00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "G4QInelastic.hh"
00046 #include "G4PhysicalConstants.hh"
00047 #include "G4SystemOfUnits.hh"
00048 #include "G4HadronicDeprecate.hh"
00049
00050
00051
00052 std::vector<G4int> G4QInelastic::ElementZ;
00053 std::vector<G4double> G4QInelastic::ElProbInMat;
00054 std::vector<std::vector<G4int>*> G4QInelastic::ElIsoN;
00055 std::vector<std::vector<G4double>*>G4QInelastic::IsoProbInEl;
00056
00057 G4QInelastic::G4QInelastic(const G4String& processName):
00058 G4VDiscreteProcess(processName, fHadronic)
00059 {
00060 G4HadronicDeprecate("G4QInelastic");
00061
00062 EnMomConservation = G4LorentzVector(0.,0.,0.,0.);
00063 nOfNeutrons = 0;
00064 #ifdef debug
00065 G4cout<<"G4QInelastic::Constructor is called"<<G4endl;
00066 #endif
00067 if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl;
00068
00069 G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,mediRatio);
00070 G4Quasmon::SetParameters(Temperature,SSin2Gluons,EtaEtaprime);
00071 G4QEnvironment::SetParameters(SolidAngle);
00072
00073 }
00074
00075 G4bool G4QInelastic::manualFlag=false;
00076 G4double G4QInelastic::Temperature=140.;
00077 G4double G4QInelastic::SSin2Gluons=0.3;
00078 G4double G4QInelastic::EtaEtaprime=0.3;
00079 G4double G4QInelastic::freeNuc=.04;
00080 G4double G4QInelastic::freeDib=.08;
00081 G4double G4QInelastic::clustProb=4.;
00082 G4double G4QInelastic::mediRatio=1.;
00083
00084
00085 G4int G4QInelastic::nPartCWorld=85;
00086 G4double G4QInelastic::SolidAngle=0.5;
00087 G4bool G4QInelastic::EnergyFlux=false;
00088 G4double G4QInelastic::PiPrThresh=141.4;
00089 G4double G4QInelastic::M2ShiftVir=20000.;
00090 G4double G4QInelastic::DiNuclMass=1870.;
00091 G4double G4QInelastic::photNucBias=1.;
00092 G4double G4QInelastic::weakNucBias=1.;
00093
00094 void G4QInelastic::SetManual() {manualFlag=true;}
00095 void G4QInelastic::SetStandard() {manualFlag=false;}
00096
00097
00098 void G4QInelastic::SetParameters(G4double temper, G4double ssin2g, G4double etaetap,
00099 G4double fN, G4double fD, G4double cP, G4double mR,
00100 G4int nParCW, G4double solAn, G4bool efFlag,
00101 G4double piThresh, G4double mpisq, G4double dinum)
00102 {
00103 Temperature=temper;
00104 SSin2Gluons=ssin2g;
00105 EtaEtaprime=etaetap;
00106 freeNuc=fN;
00107 freeDib=fD;
00108 clustProb=cP;
00109 mediRatio=mR;
00110 nPartCWorld = nParCW;
00111 EnergyFlux=efFlag;
00112 SolidAngle=solAn;
00113 PiPrThresh=piThresh;
00114 M2ShiftVir=mpisq;
00115 DiNuclMass=dinum;
00116 G4QCHIPSWorld::Get()->GetParticles(nPartCWorld);
00117 G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,mediRatio);
00118 G4Quasmon::SetParameters(Temperature,SSin2Gluons,EtaEtaprime);
00119 G4QEnvironment::SetParameters(SolidAngle);
00120 }
00121
00122 void G4QInelastic::SetPhotNucBias(G4double phnB) {photNucBias=phnB;}
00123 void G4QInelastic::SetWeakNucBias(G4double ccnB) {weakNucBias=ccnB;}
00124
00125
00126
00127 G4QInelastic::~G4QInelastic()
00128 {
00129
00130
00131 G4int IPIE=IsoProbInEl.size();
00132 if(IPIE) for(G4int ip=0; ip<IPIE; ++ip)
00133 {
00134 std::vector<G4double>* SPI=IsoProbInEl[ip];
00135 SPI->clear();
00136 delete SPI;
00137 std::vector<G4int>* IsN=ElIsoN[ip];
00138 IsN->clear();
00139 delete IsN;
00140 }
00141 ElProbInMat.clear();
00142 ElementZ.clear();
00143 IsoProbInEl.clear();
00144 ElIsoN.clear();
00145 }
00146
00147
00148 G4LorentzVector G4QInelastic::GetEnegryMomentumConservation()
00149 {
00150 return EnMomConservation;
00151 }
00152
00153 G4int G4QInelastic::GetNumberOfNeutronsInTarget()
00154 {
00155 return nOfNeutrons;
00156 }
00157
00158
00159
00160
00161 G4double G4QInelastic::GetMeanFreePath(const G4Track& aTrack,G4double,G4ForceCondition* Fc)
00162 {
00163 #ifdef debug
00164 G4cout<<"G4QInelastic::GetMeanFreePath: Called Fc="<<*Fc<<G4endl;
00165 #endif
00166 *Fc = NotForced;
00167 #ifdef debug
00168 G4cout<<"G4QInelastic::GetMeanFreePath: Before GetDynPart"<<G4endl;
00169 #endif
00170 const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle();
00171 #ifdef debug
00172 G4cout<<"G4QInelastic::GetMeanFreePath: Before GetDef"<<G4endl;
00173 #endif
00174 G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition();
00175 if( !IsApplicable(*incidentParticleDefinition))
00176 {
00177 G4cout<<"-W-G4QInelastic::GetMeanFreePath called for not implemented particle"<<G4endl;
00178 return DBL_MAX;
00179 }
00180
00181 G4double Momentum = incidentParticle->GetTotalMomentum();
00182 #ifdef debug
00183 G4cout<<"G4QInelastic::GetMeanFreePath: BeforeGetMaterial"<<G4endl;
00184 #endif
00185 const G4Material* material = aTrack.GetMaterial();
00186 const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume();
00187 const G4ElementVector* theElementVector = material->GetElementVector();
00188 G4int nE=material->GetNumberOfElements();
00189 #ifdef debug
00190 G4cout<<"G4QInelastic::GetMeanFreePath:"<<nE<<" Elem's in theMaterial"<<G4endl;
00191 #endif
00192
00193 G4VQCrossSection* CSmanager=0;
00194 G4VQCrossSection* CSmanager2=0;
00195 G4QNeutronCaptureRatio* capMan=0;
00196 G4int pPDG=0;
00197 G4int pZ = incidentParticleDefinition->GetAtomicNumber();
00198 G4int pA = incidentParticleDefinition->GetAtomicMass();
00199 if(incidentParticleDefinition == G4Neutron::Neutron())
00200 {
00201 CSmanager=G4QNeutronNuclearCrossSection::GetPointer();
00202 capMan=G4QNeutronCaptureRatio::GetPointer();
00203 #ifdef debug
00204 G4cout<<"G4QInelastic::GetMeanFreePath: CSmanager is defined for the neutron"<<G4endl;
00205 #endif
00206 pPDG=2112;
00207 }
00208 else if(incidentParticleDefinition == G4Proton::Proton())
00209 {
00210 CSmanager=G4QProtonNuclearCrossSection::GetPointer();
00211 pPDG=2212;
00212 }
00213 else if(incidentParticleDefinition == G4PionMinus::PionMinus())
00214 {
00215 CSmanager=G4QPionMinusNuclearCrossSection::GetPointer();
00216 pPDG=-211;
00217 }
00218 else if(incidentParticleDefinition == G4PionPlus::PionPlus())
00219 {
00220 CSmanager=G4QPionPlusNuclearCrossSection::GetPointer();
00221 pPDG=211;
00222 }
00223 else if(incidentParticleDefinition == G4KaonMinus::KaonMinus())
00224 {
00225 CSmanager=G4QKaonMinusNuclearCrossSection::GetPointer();
00226 pPDG=-321;
00227 }
00228 else if(incidentParticleDefinition == G4KaonPlus::KaonPlus())
00229 {
00230 CSmanager=G4QKaonPlusNuclearCrossSection::GetPointer();
00231 pPDG=321;
00232 }
00233 else if(incidentParticleDefinition == G4KaonZeroLong::KaonZeroLong() ||
00234 incidentParticleDefinition == G4KaonZeroShort::KaonZeroShort() ||
00235 incidentParticleDefinition == G4KaonZero::KaonZero() ||
00236 incidentParticleDefinition == G4AntiKaonZero::AntiKaonZero() )
00237 {
00238 CSmanager=G4QKaonZeroNuclearCrossSection::GetPointer();
00239 if(G4UniformRand() > 0.5) pPDG= 311;
00240 else pPDG=-311;
00241 }
00242 else if(incidentParticleDefinition == G4Lambda::Lambda())
00243 {
00244 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00245 pPDG=3122;
00246 }
00247 else if(pZ > 0 && pA > 1)
00248 {
00249 G4cout<<"-Warning-G4QInelastic::GetMeanFreePath: G4QInelastic called for ions"<<G4endl;
00250 CSmanager=G4QProtonNuclearCrossSection::GetPointer();
00251 pPDG=90000000+999*pZ+pA;
00252 }
00253 else if(incidentParticleDefinition == G4SigmaPlus::SigmaPlus())
00254 {
00255 CSmanager=G4QHyperonPlusNuclearCrossSection::GetPointer();
00256 pPDG=3222;
00257 }
00258 else if(incidentParticleDefinition == G4SigmaMinus::SigmaMinus())
00259 {
00260 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00261 pPDG=3112;
00262 }
00263 else if(incidentParticleDefinition == G4SigmaZero::SigmaZero())
00264 {
00265 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00266 pPDG=3212;
00267 }
00268 else if(incidentParticleDefinition == G4XiMinus::XiMinus())
00269 {
00270 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00271 pPDG=3312;
00272 }
00273 else if(incidentParticleDefinition == G4XiZero::XiZero())
00274 {
00275 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00276 pPDG=3322;
00277 }
00278 else if(incidentParticleDefinition == G4OmegaMinus::OmegaMinus())
00279 {
00280 CSmanager=G4QHyperonNuclearCrossSection::GetPointer();
00281 pPDG=3334;
00282 }
00283 else if(incidentParticleDefinition == G4MuonPlus::MuonPlus() ||
00284 incidentParticleDefinition == G4MuonMinus::MuonMinus())
00285 {
00286 CSmanager=G4QMuonNuclearCrossSection::GetPointer();
00287
00288 pPDG=13;
00289 }
00290 else if(incidentParticleDefinition == G4AntiNeutron::AntiNeutron())
00291 {
00292 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00293 pPDG=-2112;
00294 }
00295 else if(incidentParticleDefinition == G4AntiProton::AntiProton())
00296 {
00297 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00298 pPDG=-2212;
00299 }
00300 else if(incidentParticleDefinition == G4AntiLambda::AntiLambda())
00301 {
00302 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00303 pPDG=-3122;
00304 }
00305 else if(incidentParticleDefinition == G4AntiSigmaPlus::AntiSigmaPlus())
00306 {
00307 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00308 pPDG=-3222;
00309 }
00310 else if(incidentParticleDefinition == G4AntiSigmaMinus::AntiSigmaMinus())
00311 {
00312 CSmanager=G4QAntiBaryonPlusNuclearCrossSection::GetPointer();
00313 pPDG=-3112;
00314 }
00315 else if(incidentParticleDefinition == G4AntiSigmaZero::AntiSigmaZero())
00316 {
00317 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00318 pPDG=-3212;
00319 }
00320 else if(incidentParticleDefinition == G4AntiXiMinus::AntiXiMinus())
00321 {
00322 CSmanager=G4QAntiBaryonPlusNuclearCrossSection::GetPointer();
00323 pPDG=-3312;
00324 }
00325 else if(incidentParticleDefinition == G4AntiXiZero::AntiXiZero())
00326 {
00327 CSmanager=G4QAntiBaryonNuclearCrossSection::GetPointer();
00328 pPDG=-3322;
00329 }
00330 else if(incidentParticleDefinition == G4AntiOmegaMinus::AntiOmegaMinus())
00331 {
00332 CSmanager=G4QAntiBaryonPlusNuclearCrossSection::GetPointer();
00333 pPDG=-3334;
00334 }
00335 else if(incidentParticleDefinition == G4Gamma::Gamma())
00336 {
00337 CSmanager=G4QPhotonNuclearCrossSection::GetPointer();
00338 pPDG=22;
00339 }
00340 else if(incidentParticleDefinition == G4Electron::Electron() ||
00341 incidentParticleDefinition == G4Positron::Positron())
00342 {
00343 CSmanager=G4QElectronNuclearCrossSection::GetPointer();
00344
00345 pPDG=11;
00346 }
00347 else if(incidentParticleDefinition == G4TauPlus::TauPlus() ||
00348 incidentParticleDefinition == G4TauMinus::TauMinus())
00349 {
00350 CSmanager=G4QTauNuclearCrossSection::GetPointer();
00351
00352 pPDG=15;
00353 }
00354 else if(incidentParticleDefinition == G4NeutrinoMu::NeutrinoMu() )
00355 {
00356 CSmanager=G4QNuMuNuclearCrossSection::GetPointer();
00357 CSmanager2=G4QNuNuNuclearCrossSection::GetPointer();
00358
00359 pPDG=14;
00360 }
00361 else if(incidentParticleDefinition == G4AntiNeutrinoMu::AntiNeutrinoMu() )
00362 {
00363 CSmanager=G4QANuMuNuclearCrossSection::GetPointer();
00364 CSmanager2=G4QANuANuNuclearCrossSection::GetPointer();
00365
00366 pPDG=-14;
00367 }
00368 else if(incidentParticleDefinition == G4NeutrinoE::NeutrinoE() )
00369 {
00370 CSmanager=G4QNuENuclearCrossSection::GetPointer();
00371 CSmanager2=G4QNuNuNuclearCrossSection::GetPointer();
00372
00373 pPDG=12;
00374 }
00375 else if(incidentParticleDefinition == G4AntiNeutrinoE::AntiNeutrinoE() )
00376 {
00377 CSmanager=G4QANuENuclearCrossSection::GetPointer();
00378 CSmanager2=G4QANuANuNuclearCrossSection::GetPointer();
00379
00380 pPDG=-12;
00381 }
00382 else
00383 {
00384 G4cout<<"-Warning-G4QInelastic::GetMeanFreePath:Particle "
00385 <<incidentParticleDefinition->GetPDGEncoding()<<" isn't supported"<<G4endl;
00386 return DBL_MAX;
00387 }
00388 G4QIsotope* Isotopes = G4QIsotope::Get();
00389 G4double sigma=0.;
00390 G4int IPIE=IsoProbInEl.size();
00391 if(IPIE) for(G4int ip=0; ip<IPIE; ++ip)
00392 {
00393 std::vector<G4double>* SPI=IsoProbInEl[ip];
00394 SPI->clear();
00395 delete SPI;
00396 std::vector<G4int>* IsN=ElIsoN[ip];
00397 IsN->clear();
00398 delete IsN;
00399 }
00400 ElProbInMat.clear();
00401 ElementZ.clear();
00402 IsoProbInEl.clear();
00403 ElIsoN.clear();
00404 for(G4int i=0; i<nE; ++i)
00405 {
00406 G4Element* pElement=(*theElementVector)[i];
00407 G4int Z = static_cast<G4int>(pElement->GetZ());
00408 ElementZ.push_back(Z);
00409 G4int isoSize=0;
00410 G4int indEl=0;
00411 G4IsotopeVector* isoVector=pElement->GetIsotopeVector();
00412 if(isoVector) isoSize=isoVector->size();
00413 #ifdef debug
00414 G4cout<<"G4QInelastic::GetMeanFreePath: isovectorLength="<<isoSize<<G4endl;
00415 #endif
00416 if(isoSize)
00417 {
00418 indEl=pElement->GetIndex()+1;
00419 if(!Isotopes->IsDefined(Z,indEl))
00420 {
00421 std::vector<std::pair<G4int,G4double>*>* newAbund =
00422 new std::vector<std::pair<G4int,G4double>*>;
00423 G4double* abuVector=pElement->GetRelativeAbundanceVector();
00424 for(G4int j=0; j<isoSize; j++)
00425 {
00426 G4int N=pElement->GetIsotope(j)->GetN()-Z;
00427 if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QInelastic::GetMeanFreePath"
00428 <<": Z="<<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl;
00429 G4double abund=abuVector[j];
00430 std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund);
00431 #ifdef debug
00432 G4cout<<"G4QInelastic::GetMeanFreePath: p#="<<j<<",N="<<N<<",ab="<<abund<<G4endl;
00433 #endif
00434 newAbund->push_back(pr);
00435 }
00436 #ifdef debug
00437 G4cout<<"G4QInelastic::GetMeanFreePath: pairVectLength="<<newAbund->size()<<G4endl;
00438 #endif
00439 indEl=G4QIsotope::Get()->InitElement(Z,indEl,newAbund);
00440 for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k];
00441 delete newAbund;
00442 }
00443 }
00444 std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z,indEl);
00445 std::vector<G4double>* SPI = new std::vector<G4double>;
00446 IsoProbInEl.push_back(SPI);
00447 std::vector<G4int>* IsN = new std::vector<G4int>;
00448 ElIsoN.push_back(IsN);
00449 G4int nIs=cs->size();
00450 G4double susi=0.;
00451 #ifdef debug
00452 G4cout<<"G4QInelastic::GetMeanFreePath: Before Loop nIs="<<nIs<<G4endl;
00453 #endif
00454 if(nIs) for(G4int j=0; j<nIs; j++)
00455 {
00456 std::pair<G4int,G4double>* curIs=(*cs)[j];
00457 G4int N=curIs->first;
00458 IsN->push_back(N);
00459 #ifdef debug
00460 G4cout<<"G4QInel::GetMeanFrP: Before CS, P="<<Momentum<<",Z="<<Z<<",N="<<N<<G4endl;
00461 #endif
00462 if(!pPDG) G4cout<<"-Warning-G4QInelastic::GetMeanFrP: (1) projectile PDG=0"<<G4endl;
00463 G4double CSI=CSmanager->GetCrossSection(true,Momentum,Z,N,pPDG);
00464 if(CSmanager2)CSI+=CSmanager2->GetCrossSection(true,Momentum,Z,N,pPDG);
00465 if(capMan) CSI*=(1.-capMan->GetRatio(Momentum, Z, N));
00466 #ifdef debug
00467 G4cout<<"GQC::GMF:X="<<CSI<<",M="<<Momentum<<",Z="<<Z<<",N="<<N<<",P="<<pPDG<<G4endl;
00468 #endif
00469 curIs->second = CSI;
00470 susi+=CSI;
00471 SPI->push_back(susi);
00472 }
00473 sigma+=Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i];
00474 ElProbInMat.push_back(sigma);
00475 }
00476 #ifdef debug
00477 G4cout<<"G4QInel::GetMeanFrPa:S="<<sigma<<",e="<<photNucBias<<",w="<<weakNucBias<<G4endl;
00478 #endif
00479
00480 if(photNucBias!=1.) if(incidentParticleDefinition == G4Gamma::Gamma() ||
00481 incidentParticleDefinition == G4MuonPlus::MuonPlus() ||
00482 incidentParticleDefinition == G4MuonMinus::MuonMinus() ||
00483 incidentParticleDefinition == G4Electron::Electron() ||
00484 incidentParticleDefinition == G4Positron::Positron() ||
00485 incidentParticleDefinition == G4TauMinus::TauMinus() ||
00486 incidentParticleDefinition == G4TauPlus::TauPlus() )
00487 sigma*=photNucBias;
00488 if(weakNucBias!=1.) if(incidentParticleDefinition==G4NeutrinoE::NeutrinoE() ||
00489 incidentParticleDefinition==G4AntiNeutrinoE::AntiNeutrinoE() ||
00490 incidentParticleDefinition==G4NeutrinoTau::NeutrinoTau() ||
00491 incidentParticleDefinition==G4AntiNeutrinoTau::AntiNeutrinoTau()||
00492 incidentParticleDefinition==G4NeutrinoMu::NeutrinoMu() ||
00493 incidentParticleDefinition==G4AntiNeutrinoMu::AntiNeutrinoMu() )
00494 sigma*=weakNucBias;
00495 if(sigma > 0.) return 1./sigma;
00496 return DBL_MAX;
00497 }
00498
00499
00500 G4bool G4QInelastic::IsApplicable(const G4ParticleDefinition& particle)
00501 {
00502 G4int Z=particle.GetAtomicNumber();
00503 G4int A=particle.GetAtomicMass();
00504 if (particle == *( G4Neutron::Neutron() )) return true;
00505 else if (particle == *( G4Proton::Proton() )) return true;
00506 else if (particle == *( G4MuonPlus::MuonPlus() )) return true;
00507 else if (particle == *( G4MuonMinus::MuonMinus() )) return true;
00508 else if (particle == *( G4Gamma::Gamma() )) return true;
00509 else if (particle == *( G4Electron::Electron() )) return true;
00510 else if (particle == *( G4Positron::Positron() )) return true;
00511 else if (particle == *( G4PionMinus::PionMinus() )) return true;
00512 else if (particle == *( G4PionPlus::PionPlus() )) return true;
00513 else if (particle == *( G4KaonPlus::KaonPlus() )) return true;
00514 else if (particle == *( G4KaonMinus::KaonMinus() )) return true;
00515 else if (particle == *( G4KaonZeroLong::KaonZeroLong() )) return true;
00516 else if (particle == *( G4KaonZeroShort::KaonZeroShort() )) return true;
00517 else if (particle == *( G4Lambda::Lambda() )) return true;
00518 else if (particle == *( G4SigmaPlus::SigmaPlus() )) return true;
00519 else if (particle == *( G4SigmaMinus::SigmaMinus() )) return true;
00520 else if (particle == *( G4SigmaZero::SigmaZero() )) return true;
00521 else if (particle == *( G4XiMinus::XiMinus() )) return true;
00522 else if (particle == *( G4XiZero::XiZero() )) return true;
00523 else if (particle == *( G4OmegaMinus::OmegaMinus() )) return true;
00524 else if (particle == *(G4GenericIon::GenericIon()) || (Z > 0 && A > 1)) return true;
00525 else if (particle == *( G4AntiNeutron::AntiNeutron() )) return true;
00526 else if (particle == *( G4AntiProton::AntiProton() )) return true;
00527 else if (particle == *( G4AntiLambda::AntiLambda() )) return true;
00528 else if (particle == *( G4AntiSigmaPlus::AntiSigmaPlus() )) return true;
00529 else if (particle == *(G4AntiSigmaMinus::AntiSigmaMinus())) return true;
00530 else if (particle == *( G4AntiSigmaZero::AntiSigmaZero() )) return true;
00531 else if (particle == *( G4AntiXiMinus::AntiXiMinus() )) return true;
00532 else if (particle == *( G4AntiXiZero::AntiXiZero() )) return true;
00533 else if (particle == *(G4AntiOmegaMinus::AntiOmegaMinus())) return true;
00534 else if (particle == *( G4TauPlus::TauPlus() )) return true;
00535 else if (particle == *( G4TauMinus::TauMinus() )) return true;
00536 else if (particle == *( G4AntiNeutrinoE::AntiNeutrinoE() )) return true;
00537 else if (particle == *( G4NeutrinoE::NeutrinoE() )) return true;
00538 else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true;
00539 else if (particle == *( G4NeutrinoMu::NeutrinoMu() )) return true;
00540
00541
00542 #ifdef debug
00543 G4cout<<"***G4QInelastic::IsApplicable: PDG="<<particle.GetPDGEncoding()<<G4endl;
00544 #endif
00545 return false;
00546 }
00547
00548 G4VParticleChange* G4QInelastic::PostStepDoIt(const G4Track& track, const G4Step& step)
00549 {
00550 static const G4double third = 1./3.;
00551 static const G4double me=G4Electron::Electron()->GetPDGMass();
00552 static const G4double me2=me*me;
00553 static const G4double mu=G4MuonMinus::MuonMinus()->GetPDGMass();
00554 static const G4double mu2=mu*mu;
00555 static const G4double mt=G4TauMinus::TauMinus()->GetPDGMass();
00556 static const G4double mt2=mt*mt;
00557
00558 static const G4double mNeut= G4QPDGCode(2112).GetMass();
00559 static const G4double mNeut2= mNeut*mNeut;
00560 static const G4double mProt= G4QPDGCode(2212).GetMass();
00561 static const G4double mProt2= mProt*mProt;
00562 static const G4double dM=mProt+mNeut;
00563 static const G4double hdM=dM/2.;
00564 static const G4double hdM2=hdM*hdM;
00565 static const G4double mLamb= G4QPDGCode(3122).GetMass();
00566 static const G4double mPi0 = G4QPDGCode(111).GetMass();
00567 static const G4double mPi0s= mPi0*mPi0;
00568 static const G4double mDeut= G4QPDGCode(2112).GetNuclMass(1,1,0);
00569
00570 static const G4double mTrit= G4QPDGCode(2112).GetNuclMass(1,2,0);
00571 static const G4double mHel3= G4QPDGCode(2112).GetNuclMass(2,1,0);
00572 static const G4double mAlph= G4QPDGCode(2112).GetNuclMass(2,2,0);
00573 static const G4double mPi = G4QPDGCode(211).GetMass();
00574 static const G4double tmPi = mPi+mPi;
00575 static const G4double stmPi= tmPi*tmPi;
00576 static const G4double mPPi = mPi+mProt;
00577 static const G4double mPPi2= mPPi*mPPi;
00578
00579
00580 static const G4double meN = mNeut+me;
00581 static const G4double meN2= meN*meN;
00582 static const G4double fmeN= 4*mNeut2*me2;
00583 static const G4double mesN= mNeut2+me2;
00584 static const G4double meP = mProt+me;
00585 static const G4double meP2= meP*meP;
00586 static const G4double fmeP= 4*mProt2*me2;
00587 static const G4double mesP= mProt2+me2;
00588 static const G4double medM= me2/dM;
00589 static const G4double meD = mPPi+me;
00590 static const G4double meD2= meD*meD;
00591
00592 static const G4double muN = mNeut+mu;
00593 static const G4double muN2= muN*muN;
00594 static const G4double fmuN= 4*mNeut2*mu2;
00595 static const G4double musN= mNeut2+mu2;
00596 static const G4double muP = mProt+mu;
00597 static const G4double muP2= muP*muP;
00598 static const G4double fmuP= 4*mProt2*mu2;
00599 static const G4double musP= mProt2+mu2;
00600 static const G4double mudM= mu2/dM;
00601 static const G4double muD = mPPi+mu;
00602 static const G4double muD2= muD*muD;
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 static const G4LorentzVector vacuum4M(0.,0.,0.,0.);
00616
00617 static G4bool CWinit = true;
00618 if(CWinit)
00619 {
00620 CWinit=false;
00621 G4QCHIPSWorld::Get()->GetParticles(nPartCWorld);
00622 }
00623
00624 const G4DynamicParticle* projHadron = track.GetDynamicParticle();
00625 const G4ParticleDefinition* particle=projHadron->GetDefinition();
00626 #ifdef debug
00627 G4cout<<"G4QInelastic::PostStepDoIt: Before the GetMeanFreePath is called"<<G4endl;
00628 #endif
00629 G4ForceCondition cond=NotForced;
00630 GetMeanFreePath(track, 1., &cond);
00631 #ifdef debug
00632 G4cout<<"G4QInelastic::PostStepDoIt: After the GetMeanFreePath is called"<<G4endl;
00633 #endif
00634 G4bool scat=false;
00635 G4int scatPDG=0;
00636 G4LorentzVector proj4M=projHadron->Get4Momentum();
00637 G4LorentzVector scat4M=proj4M;
00638 G4double momentum = projHadron->GetTotalMomentum();
00639 G4double Momentum=proj4M.rho();
00640 if(std::fabs(Momentum-momentum)>.001)
00641 G4cerr<<"*G4QInelastic::PostStepDoIt: P="<<Momentum<<"#"<<momentum<<G4endl;
00642 #ifdef debug
00643 G4double mp=proj4M.m();
00644 G4cout<<"-->G4QInel::PostStDoIt:*called*, 4M="<<proj4M<<", P="<<Momentum<<"="<<momentum
00645 <<",m="<<mp<<G4endl;
00646 #endif
00647 if (!IsApplicable(*particle))
00648 {
00649 G4cerr<<"G4QInelastic::PostStepDoIt:Only gam,e+,e-,mu+,mu-,t+,t-,p are implemented."
00650 <<G4endl;
00651 return 0;
00652 }
00653 const G4Material* material = track.GetMaterial();
00654 G4int Z=0;
00655 const G4ElementVector* theElementVector = material->GetElementVector();
00656 G4int nE=material->GetNumberOfElements();
00657 #ifdef debug
00658 G4cout<<"G4QInelastic::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl;
00659 #endif
00660 G4int projPDG=0;
00661 G4int pZ=particle->GetAtomicNumber();
00662 G4int pA=particle->GetAtomicMass();
00663 if (particle == G4Neutron::Neutron() ) projPDG= 2112;
00664 else if (particle == G4Proton::Proton() ) projPDG= 2212;
00665 else if (particle == G4PionMinus::PionMinus() ) projPDG= -211;
00666 else if (particle == G4PionPlus::PionPlus() ) projPDG= 211;
00667 else if (particle == G4KaonPlus::KaonPlus() ) projPDG= 321;
00668 else if (particle == G4KaonMinus::KaonMinus() ) projPDG= -321;
00669 else if (particle == G4KaonZeroLong::KaonZeroLong() ||
00670 particle == G4KaonZeroShort::KaonZeroShort() ||
00671 particle == G4KaonZero::KaonZero() ||
00672 particle == G4AntiKaonZero::AntiKaonZero() )
00673 {
00674 if(G4UniformRand() > 0.5) projPDG= 311;
00675 else projPDG= -311;
00676 }
00677 else if ( pZ > 0 && pA > 1 ) projPDG = 90000000+999*pZ+pA;
00678 else if (particle == G4Lambda::Lambda() ) projPDG= 3122;
00679 else if (particle == G4SigmaPlus::SigmaPlus() ) projPDG= 3222;
00680 else if (particle == G4SigmaMinus::SigmaMinus() ) projPDG= 3112;
00681 else if (particle == G4SigmaZero::SigmaZero() ) projPDG= 3212;
00682 else if (particle == G4XiMinus::XiMinus() ) projPDG= 3312;
00683 else if (particle == G4XiZero::XiZero() ) projPDG= 3322;
00684 else if (particle == G4OmegaMinus::OmegaMinus() ) projPDG= 3334;
00685 else if (particle == G4AntiNeutron::AntiNeutron() ) projPDG=-2112;
00686 else if (particle == G4AntiProton::AntiProton() ) projPDG=-2212;
00687 else if (particle == G4MuonPlus::MuonPlus() ) projPDG= -13;
00688 else if (particle == G4MuonMinus::MuonMinus() ) projPDG= 13;
00689 else if (particle == G4Gamma::Gamma() ) projPDG= 22;
00690 else if (particle == G4Electron::Electron() ) projPDG= 11;
00691 else if (particle == G4Positron::Positron() ) projPDG= -11;
00692 else if (particle == G4NeutrinoMu::NeutrinoMu() ) projPDG= 14;
00693 else if (particle == G4AntiNeutrinoMu::AntiNeutrinoMu() ) projPDG= -14;
00694 else if (particle == G4AntiLambda::AntiLambda() ) projPDG=-3122;
00695 else if (particle == G4AntiSigmaPlus::AntiSigmaPlus() ) projPDG=-3222;
00696 else if (particle == G4AntiSigmaMinus::AntiSigmaMinus() ) projPDG=-3112;
00697 else if (particle == G4AntiSigmaZero::AntiSigmaZero() ) projPDG=-3212;
00698 else if (particle == G4AntiXiMinus::AntiXiMinus() ) projPDG=-3312;
00699 else if (particle == G4AntiXiZero::AntiXiZero() ) projPDG=-3322;
00700 else if (particle == G4AntiOmegaMinus::AntiOmegaMinus() ) projPDG=-3334;
00701 else if (particle == G4NeutrinoE::NeutrinoE() ) projPDG= 12;
00702 else if (particle == G4AntiNeutrinoE::AntiNeutrinoE() ) projPDG= -12;
00703 else if (particle == G4TauPlus::TauPlus() ) projPDG= -15;
00704 else if (particle == G4TauMinus::TauMinus() ) projPDG= 15;
00705 else if (particle == G4NeutrinoTau::NeutrinoTau() ) projPDG= 16;
00706 else if (particle == G4AntiNeutrinoTau::AntiNeutrinoTau()) projPDG= -16;
00707 G4int aProjPDG=std::abs(projPDG);
00708 #ifdef debug
00709 G4int prPDG=particle->GetPDGEncoding();
00710 G4cout<<"G4QInelastic::PostStepDoIt: projPDG="<<projPDG<<", stPDG="<<prPDG<<G4endl;
00711 #endif
00712 if(!projPDG)
00713 {
00714 G4cerr<<"---Warning---G4QInelastic::PostStepDoIt:Undefined interacting hadron"<<G4endl;
00715 return 0;
00716 }
00717 G4int EPIM=ElProbInMat.size();
00718 #ifdef debug
00719 G4cout<<"G4QInel::PostStDoIt: m="<<EPIM<<",n="<<nE<<",T="<<ElProbInMat[EPIM-1]<<G4endl;
00720 #endif
00721 G4int i=0;
00722 if(EPIM>1)
00723 {
00724 G4double rnd = ElProbInMat[EPIM-1]*G4UniformRand();
00725 for(i=0; i<nE; ++i)
00726 {
00727 #ifdef debug
00728 G4cout<<"G4QInelastic::PostStepDoIt:E["<<i<<"]="<<ElProbInMat[i]<<",r="<<rnd<<G4endl;
00729 #endif
00730 if (rnd<ElProbInMat[i]) break;
00731 }
00732 if(i>=nE) i=nE-1;
00733 }
00734 G4Element* pElement=(*theElementVector)[i];
00735 Z=static_cast<G4int>(pElement->GetZ());
00736 #ifdef debug
00737 G4cout<<"G4QInelastic::PostStepDoIt: i="<<i<<", Z(element)="<<Z<<G4endl;
00738 #endif
00739 if(Z<=0)
00740 {
00741 G4cerr<<"---Warning---G4QInelastic::PostStepDoIt: Element with Z="<<Z<<G4endl;
00742 if(Z<0) return 0;
00743 }
00744 std::vector<G4double>* SPI = IsoProbInEl[i];
00745 std::vector<G4int>* IsN = ElIsoN[i];
00746 G4int nofIsot=SPI->size();
00747 #ifdef debug
00748 G4cout<<"G4QInel::PosStDoIt:n="<<nofIsot<<",T="<<(*SPI)[nofIsot-1]<<G4endl;
00749 #endif
00750 G4int j=0;
00751 if(nofIsot>1)
00752 {
00753 G4double rndI=(*SPI)[nofIsot-1]*G4UniformRand();
00754 for(j=0; j<nofIsot; ++j)
00755 {
00756 #ifdef debug
00757 G4cout<<"G4QInelastic::PostStepDoIt: SP["<<j<<"]="<<(*SPI)[j]<<", r="<<rndI<<G4endl;
00758 #endif
00759 if(rndI < (*SPI)[j]) break;
00760 }
00761 if(j>=nofIsot) j=nofIsot-1;
00762 }
00763 G4int N =(*IsN)[j]; ;
00764 #ifdef debug
00765 G4cout<<"G4QInelastic::PostStepDoIt: Z="<<Z<<", j="<<i<<", N(isotope)="<<N<<G4endl;
00766 #endif
00767 G4double kinEnergy= projHadron->GetKineticEnergy();
00768 G4ParticleMomentum dir = projHadron->GetMomentumDirection();
00769 if(projPDG==22 && Z==1 && !N && Momentum<150.)
00770 {
00771 #ifdef debug
00772 G4cerr<<"---LowPHOTON---G4QInelastic::PSDoIt: Called for zero Cross-section"<<G4endl;
00773 #endif
00774
00775 aParticleChange.ProposeEnergy(kinEnergy);
00776 aParticleChange.ProposeLocalEnergyDeposit(0.);
00777 aParticleChange.ProposeMomentumDirection(dir);
00778 aParticleChange.ProposeTrackStatus(fAlive);
00779 return G4VDiscreteProcess::PostStepDoIt(track,step);
00780 }
00781 if(N<0)
00782 {
00783 G4cerr<<"-Warning-G4QInelastic::PostStepDoIt: Isotope with Z="<<Z<<", 0>N="<<N<<G4endl;
00784 return 0;
00785 }
00786 nOfNeutrons=N;
00787
00788 G4int am=Z+N;
00789
00790
00791
00792
00793
00794 G4double medRA=mediRatio;
00795 if(manualFlag) G4QNucleus::SetParameters(freeNuc,freeDib,clustProb,medRA);
00796
00797
00798
00799
00800
00801
00802 #ifdef debug
00803 G4cout<<"G4QInelastic::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl;
00804 #endif
00805 aParticleChange.Initialize(track);
00806 G4double weight = track.GetWeight();
00807 #ifdef debug
00808 G4cout<<"G4QInelastic::PostStepDoIt: weight="<<weight<<G4endl;
00809 #endif
00810 if(photNucBias!=1.) weight/=photNucBias;
00811 else if(weakNucBias!=1.) weight/=weakNucBias;
00812 G4double localtime = track.GetGlobalTime();
00813 #ifdef debug
00814 G4cout<<"G4QInelastic::PostStepDoIt: localtime="<<localtime<<G4endl;
00815 #endif
00816 G4ThreeVector position = track.GetPosition();
00817 G4TouchableHandle trTouchable = track.GetTouchableHandle();
00818 #ifdef debug
00819 G4cout<<"G4QInelastic::PostStepDoIt: position="<<position<<G4endl;
00820 #endif
00821
00822 G4int targPDG=90000000+Z*1000+N;
00823 G4QPDGCode targQPDG(targPDG);
00824 G4double tgM=targQPDG.GetMass();
00825 G4double tM=tgM;
00826 G4QHadronVector* output=new G4QHadronVector;
00827 G4double absMom = 0.;
00828 G4QHadronVector* leadhs=new G4QHadronVector;
00829 G4LorentzVector lead4M(0.,0.,0.,0.);
00830 #ifdef debug
00831 G4cout<<"G4QInelastic::PostStepDoIt: projPDG="<<aProjPDG<<", targPDG="<<targPDG<<G4endl;
00832 #endif
00833
00834
00835
00836
00837 if (aProjPDG == 11 || aProjPDG == 13 || aProjPDG == 15)
00838 {
00839 #ifdef debug
00840 G4cout<<"G4QInelastic::PostStDoIt:startSt="<<aParticleChange.GetTrackStatus()<<G4endl;
00841 #endif
00842 G4VQCrossSection* CSmanager=G4QElectronNuclearCrossSection::GetPointer();
00843 G4double ml=me;
00844 G4double ml2=me2;
00845 if(aProjPDG== 13)
00846 {
00847 CSmanager=G4QMuonNuclearCrossSection::GetPointer();
00848 ml=mu;
00849 ml2=mu2;
00850 }
00851 if(aProjPDG== 15)
00852 {
00853 CSmanager=G4QTauNuclearCrossSection::GetPointer();
00854 ml=mt;
00855 ml2=mt2;
00856 }
00857
00858 if(!aProjPDG) G4cout<<"-Warning-G4QInelast::PostStepDoIt:(2) projectile PDG=0"<<G4endl;
00859 G4double xSec=CSmanager->GetCrossSection(false,Momentum,Z,N,aProjPDG);
00860
00861 if(Z==1 && !N && Momentum<150.) xSec=0.;
00862 #ifdef debug
00863 G4cout<<"-Forse-G4QInel::PStDoIt:P="<<Momentum<<",PDG="<<projPDG<<",xS="<<xSec<<G4endl;
00864 #endif
00865 if(xSec <= 0.)
00866 {
00867 #ifdef debug
00868 G4cerr<<"---OUT---G4QInelastic::PSDoIt: Called for zero Cross-section"<<G4endl;
00869 #endif
00870
00871 aParticleChange.ProposeEnergy(kinEnergy);
00872 aParticleChange.ProposeLocalEnergyDeposit(0.);
00873 aParticleChange.ProposeMomentumDirection(dir);
00874 aParticleChange.ProposeTrackStatus(fAlive);
00875 delete output;
00876 return G4VDiscreteProcess::PostStepDoIt(track,step);
00877 }
00878 G4double photonEnergy = CSmanager->GetExchangeEnergy();
00879 #ifdef debug
00880 G4cout<<"G4QInel::PStDoIt:kE="<<kinEnergy<<",dir="<<dir<<",phE="<<photonEnergy<<G4endl;
00881 #endif
00882 if( kinEnergy < photonEnergy || photonEnergy < 0.)
00883 {
00884
00885 G4cerr<<"--G4QInelastic::PSDoIt: photE="<<photonEnergy<<">leptE="<<kinEnergy<<G4endl;
00886 aParticleChange.ProposeEnergy(kinEnergy);
00887 aParticleChange.ProposeLocalEnergyDeposit(0.);
00888 aParticleChange.ProposeMomentumDirection(dir);
00889 aParticleChange.ProposeTrackStatus(fAlive);
00890 delete output;
00891 return G4VDiscreteProcess::PostStepDoIt(track,step);
00892 }
00893 G4double photonQ2 = CSmanager->GetExchangeQ2(photonEnergy);
00894 G4double W=photonEnergy-photonQ2/dM;
00895 if(tM<999.) W-=mPi0+mPi0s/dM;
00896 if(W<0.)
00897 {
00898
00899 #ifdef debug
00900 G4cout<<"--G4QInelastic::PostStepDoIt:(lN) negative equivalent energy W="<<W<<G4endl;
00901 #endif
00902 aParticleChange.ProposeEnergy(kinEnergy);
00903 aParticleChange.ProposeLocalEnergyDeposit(0.);
00904 aParticleChange.ProposeMomentumDirection(dir);
00905 aParticleChange.ProposeTrackStatus(fAlive);
00906 delete output;
00907 return G4VDiscreteProcess::PostStepDoIt(track,step);
00908 }
00909
00910 G4VQCrossSection* thePhotonData=G4QPhotonNuclearCrossSection::GetPointer();
00911 G4double sigNu=thePhotonData->GetCrossSection(true,photonEnergy,Z,N,22);
00912 G4double sigK =thePhotonData->GetCrossSection(true, W, Z, N, 22);
00913 G4double rndFraction = CSmanager->GetVirtualFactor(photonEnergy, photonQ2);
00914 if(sigNu*G4UniformRand()>sigK*rndFraction)
00915 {
00916
00917 #ifdef debug
00918 G4cout<<"-DoNoth-G4QInelastic::PostStepDoIt: probab. correction - DoNothing"<<G4endl;
00919 #endif
00920 aParticleChange.ProposeEnergy(kinEnergy);
00921 aParticleChange.ProposeLocalEnergyDeposit(0.);
00922 aParticleChange.ProposeMomentumDirection(dir);
00923 aParticleChange.ProposeTrackStatus(fAlive);
00924 delete output;
00925 return G4VDiscreteProcess::PostStepDoIt(track,step);
00926 }
00927 G4double iniE=kinEnergy+ml;
00928 G4double finE=iniE-photonEnergy;
00929 #ifdef pdebug
00930 G4cout<<"G4QInelastic::PoStDoIt:E="<<iniE<<",lE="<<finE<<"-"<<ml<<"="<<finE-ml<<G4endl;
00931 #endif
00932 aParticleChange.ProposeEnergy(finE-ml);
00933 if(finE<=ml)
00934 {
00935 aParticleChange.ProposeEnergy(0.);
00936 if(aProjPDG== 11) aParticleChange.ProposeTrackStatus(fStopAndKill);
00937 else aParticleChange.ProposeTrackStatus(fStopButAlive);
00938 aParticleChange.ProposeMomentumDirection(dir);
00939 }
00940 else aParticleChange.ProposeTrackStatus(fAlive);
00941 G4double iniP=std::sqrt(iniE*iniE-ml2);
00942 G4double finP=std::sqrt(finE*finE-ml2);
00943 G4double cost=(iniE*finE-ml2-photonQ2/2)/iniP/finP;
00944 #ifdef pdebug
00945 G4cout<<"G4QI::PSDoIt:Q2="<<photonQ2<<",ct="<<cost<<",Pi="<<iniP<<",Pf="<<finP<<G4endl;
00946 #endif
00947 if(cost>1.) cost=1.;
00948 if(cost<-1.) cost=-1.;
00949
00950
00951
00952 G4double absEn = G4QThd(am)*GeV;
00953
00954 if(am>1 && absEn < photonEnergy)
00955
00956 {
00957 G4double abtEn = absEn+hdM;
00958 G4double abEn2 = abtEn*abtEn;
00959 G4double abMo2 = abEn2-hdM2;
00960 G4double phEn2 = photonEnergy*photonEnergy;
00961 G4double phMo2 = phEn2+photonQ2;
00962 G4double phMo = std::sqrt(phMo2);
00963 absMom = std::sqrt(abMo2);
00964 if(absMom < phMo)
00965 {
00966 G4double dEn = photonEnergy - absEn;
00967 G4double dMo = phMo - absMom;
00968 G4double sF = dEn*dEn - dMo*dMo;
00969 #ifdef ppdebug
00970 G4cout<<"-PhotoAbsorption-G4QIn::PStDoIt: sF="<<sF<<",phEn="<<photonEnergy<<G4endl;
00971 #endif
00972 if(sF > stmPi)
00973 {
00974 photonEnergy = absEn;
00975 photonQ2=abMo2-absEn*absEn;
00976 absEn = dEn;
00977 }
00978 else absMom=0.;
00979 }
00980 else absMom=0.;
00981 }
00982
00983
00984
00985 G4ThreeVector ort=dir.orthogonal();
00986 G4ThreeVector ortx = ort.unit();
00987 G4ThreeVector orty = dir.cross(ortx);
00988 G4double sint=std::sqrt(1.-cost*cost);
00989 G4double phi=twopi*G4UniformRand();
00990 G4double sinx=sint*std::sin(phi);
00991 G4double siny=sint*std::cos(phi);
00992 G4ThreeVector findir=cost*dir+sinx*ortx+siny*orty;
00993 aParticleChange.ProposeMomentumDirection(findir);
00994 #ifdef pdebug
00995 G4cout<<"G4QInelastic::PostStepDoIt: E="<<aParticleChange.GetEnergy()<<"="<<finE<<"-"
00996 <<ml<<", d="<<*aParticleChange.GetMomentumDirection()<<","<<findir<<G4endl;
00997 #endif
00998 G4ThreeVector photon3M=iniP*dir-finP*findir;
00999 if(absMom)
01000 {
01001 G4double ptm=photon3M.mag();
01002 #ifdef ppdebug
01003 G4cout<<"-Absorption-G4QInelastic::PostStepDoIt: ph3M="<<photon3M<<", eIn3M="
01004 <<iniP*dir<<", eFin3M="<<finP*findir<<", abs3M="<<absMom<<"<ptm="<<ptm<<G4endl;
01005 #endif
01006 G4ThreeVector lead3M=photon3M*(ptm-absMom)/ptm;
01007 photon3M-=lead3M;
01008 proj4M=G4LorentzVector(lead3M,absEn);
01009 #ifdef ppdebug
01010 G4cout<<"-->G4QI::PoStDoIt: new sF="<<proj4M.m2()<<", lead4M="<<proj4M<<G4endl;
01011 #endif
01012 lead4M=proj4M;
01013 G4Quasmon* pan= new G4Quasmon(G4QContent(1,1,0,1,1,0),proj4M);
01014 try
01015 {
01016 if(leadhs) delete leadhs;
01017 G4QNucleus vac(90000000);
01018 leadhs=pan->Fragment(vac,1);
01019 }
01020 catch (G4QException& error)
01021 {
01022 G4cerr<<"***G4QInelastic::PostStepDoIt: G4Quasmon Exception is catched"<<G4endl;
01023
01024 G4Exception("G4QInelastic::PostStepDoIt()","HAD_CHPS_0072",
01025 FatalException, "QuasmonCrash");
01026 }
01027 delete pan;
01028 #ifdef ppdebug
01029 G4cout<<"G4QInel::PStDoIt: l4M="<<proj4M<<proj4M.m2()<<", N="<<leadhs->size()<<",pt="
01030 <<ptm<<",pa="<<absMom<<",El="<<absEn<<",Pl="<<ptm-absMom<<G4endl;
01031 #endif
01032 }
01033 else
01034 {
01035 G4int qNH=0;
01036 if(leadhs) qNH=leadhs->size();
01037 if(qNH) for(G4int iq=0; iq<qNH; iq++) delete (*leadhs)[iq];
01038 if(leadhs) delete leadhs;
01039 leadhs=0;
01040 }
01041 projPDG=22;
01042 proj4M=G4LorentzVector(photon3M,photonEnergy);
01043 #ifdef debug
01044 G4cout<<"G4QInelastic::PostStDoIt: St="<<aParticleChange.GetTrackStatus()<<", g4m="
01045 <<proj4M<<", lE="<<finE<<", lP="<<finP*findir<<", d="<<findir.mag2()<<G4endl;
01046 #endif
01047
01048
01049
01050
01051 }
01052 else if (aProjPDG == 12 || aProjPDG == 14)
01053 {
01054 kinEnergy= projHadron->GetKineticEnergy()/MeV;
01055 G4double dKinE=kinEnergy+kinEnergy;
01056 #ifdef debug
01057 G4cout<<"G4QInelastic::PostStDoIt: 2*nuEnergy="<<dKinE<<"(MeV), PDG="<<projPDG<<G4endl;
01058 #endif
01059 dir = projHadron->GetMomentumDirection();
01060 G4double ml = mu;
01061 G4double ml2 = mu2;
01062
01063 G4double mlN2= muN2;
01064 G4double fmlN= fmuN;
01065 G4double mlsN= musN;
01066
01067 G4double mlP2= muP2;
01068 G4double fmlP= fmuP;
01069 G4double mlsP= musP;
01070 G4double mldM= mudM;
01071
01072 G4double mlD2= muD2;
01073 if(aProjPDG==12)
01074 {
01075 ml = me;
01076 ml2 = me2;
01077
01078 mlN2= meN2;
01079 fmlN= fmeN;
01080 mlsN= mesN;
01081
01082 mlP2= meP2;
01083 fmlP= fmeP;
01084 mlsP= mesP;
01085 mldM= medM;
01086
01087 mlD2= meD2;
01088 }
01089 G4VQCrossSection* CSmanager =G4QNuMuNuclearCrossSection::GetPointer();
01090 G4VQCrossSection* CSmanager2=G4QNuNuNuclearCrossSection::GetPointer();
01091 proj4M=G4LorentzVector(dir*kinEnergy,kinEnergy);
01092 G4bool nuanu=true;
01093 scatPDG=13;
01094 if(projPDG==-14)
01095 {
01096 nuanu=false;
01097 CSmanager=G4QANuMuNuclearCrossSection::GetPointer();
01098 CSmanager=G4QANuANuNuclearCrossSection::GetPointer();
01099 scatPDG=-13;
01100 }
01101 else if(projPDG==12)
01102 {
01103 CSmanager=G4QNuENuclearCrossSection::GetPointer();
01104 scatPDG=11;
01105 }
01106 else if(projPDG==-12)
01107 {
01108 nuanu=false;
01109 CSmanager=G4QANuENuclearCrossSection::GetPointer();
01110 CSmanager=G4QANuANuNuclearCrossSection::GetPointer();
01111 scatPDG=-11;
01112 }
01113
01114 if(!projPDG) G4cout<<"-Warning-G4QInelastic::PostStepDoIt:(3)projectile PDG=0"<<G4endl;
01115 G4double xSec1=CSmanager->GetCrossSection(false,Momentum,Z,N,projPDG);
01116 G4double xSec2=CSmanager2->GetCrossSection(false,Momentum,Z,N,projPDG);
01117 G4double xSec=xSec1+xSec2;
01118
01119 if(xSec <= 0.)
01120 {
01121 G4cerr<<"G4QInelastic::PSDoIt:nuE="<<kinEnergy<<",X1="<<xSec1<<",X2="<<xSec2<<G4endl;
01122
01123 aParticleChange.ProposeEnergy(kinEnergy);
01124 aParticleChange.ProposeLocalEnergyDeposit(0.);
01125 aParticleChange.ProposeMomentumDirection(dir);
01126 aParticleChange.ProposeTrackStatus(fAlive);
01127 delete output;
01128 return G4VDiscreteProcess::PostStepDoIt(track,step);
01129 }
01130 G4bool secnu=false;
01131 if(xSec*G4UniformRand()>xSec1)
01132 {
01133 if(scatPDG>0) scatPDG++;
01134 else scatPDG--;
01135 secnu=true;
01136 }
01137 scat=true;
01138 G4double totCS1 = CSmanager->GetLastTOTCS();
01139 G4double totCS2 = CSmanager2->GetLastTOTCS();
01140 G4double totCS = totCS1+totCS2;
01141 if(std::fabs(xSec-totCS*millibarn)/xSec>.0001)
01142 G4cout<<"-Warning-G4QInelastic::PostStepDoIt: xS="<<xSec<<"# CS="<<totCS<<G4endl;
01143 G4double qelCS1 = CSmanager->GetLastQELCS();
01144 G4double qelCS2 = CSmanager2->GetLastQELCS();
01145 G4double qelCS = qelCS1+qelCS2;
01146 if(totCS - qelCS < 0.)
01147 {
01148 totCS = qelCS;
01149 totCS1 = qelCS1;
01150 totCS2 = qelCS2;
01151 }
01152
01153 G4double mIN=mProt;
01154 G4double mOT=mNeut;
01155 G4double OT=mlN2;
01156
01157 G4double mlOT=fmlN;
01158 G4double mlsOT=mlsN;
01159 if(secnu)
01160 {
01161 if(am*G4UniformRand()>Z)
01162 {
01163 targPDG-=1;
01164 projPDG=2112;
01165 mIN =mNeut;
01166 OT =mNeut2;
01167
01168 mlOT=0.;
01169 mlsOT=mNeut2;
01170 }
01171 else
01172 {
01173 targPDG-=1000;
01174 projPDG=2212;
01175 mOT =mProt;
01176 OT =mProt2;
01177
01178 mlOT =0.;
01179 mlsOT=mProt2;
01180 }
01181 ml=0.;
01182 ml2=0.;
01183 mldM=0.;
01184 mlD2=mPPi2;
01185 G4QPDGCode temporary_targQPDG(targPDG);
01186 targQPDG = temporary_targQPDG;
01187 G4double rM=targQPDG.GetMass();
01188 mIN=tM-rM;
01189 tM=rM;
01190 }
01191 else if(nuanu)
01192 {
01193 targPDG-=1;
01194 G4QPDGCode temporary_targQPDG(targPDG);
01195 targQPDG = temporary_targQPDG;
01196 G4double rM=targQPDG.GetMass();
01197 mIN=tM-rM;
01198 tM=rM;
01199 mOT=mProt;
01200 OT=mlP2;
01201
01202 mlOT=fmlP;
01203 mlsOT=mlsP;
01204 projPDG=2212;
01205 }
01206 else
01207 {
01208 if(Z>1||N>0)
01209 {
01210 targPDG-=1000;
01211 G4QPDGCode temporary_targQPDG(targPDG);
01212 targQPDG = temporary_targQPDG;
01213 G4double rM=targQPDG.GetMass();
01214 mIN=tM-rM;
01215 tM=rM;
01216 }
01217 else
01218 {
01219 targPDG=0;
01220 mIN=tM;
01221 tM=0.;
01222 }
01223 projPDG=2112;
01224 }
01225 G4double s_value=mIN*(mIN+dKinE);
01226 #ifdef debug
01227 G4cout<<"G4QInelastic::PostStDoIt: s="<<s_value<<" >? OT="<<OT<<", mlD2="<<mlD2<<G4endl;
01228 #endif
01229 if(s_value<=OT)
01230 {
01231
01232 G4cout<<"G4QInelastic::PostStepDoIt: tooSmallFinalMassOfCompound: DoNothing"<<G4endl;
01233 aParticleChange.ProposeEnergy(kinEnergy);
01234 aParticleChange.ProposeLocalEnergyDeposit(0.);
01235 aParticleChange.ProposeMomentumDirection(dir);
01236 aParticleChange.ProposeTrackStatus(fAlive);
01237 delete output;
01238 return G4VDiscreteProcess::PostStepDoIt(track,step);
01239 }
01240 #ifdef debug
01241 G4cout<<"G4QInelastic::PostStDoIt: Stop and kill the projectile neutrino"<<G4endl;
01242 #endif
01243 aParticleChange.ProposeEnergy(0.);
01244 aParticleChange.ProposeTrackStatus(fStopAndKill);
01245
01246 if ( ((secnu || !nuanu || N) && totCS*G4UniformRand() < qelCS) || s_value < mlD2 )
01247 {
01248 G4double Q2=0.;
01249 if(secnu) Q2=CSmanager2->GetQEL_ExchangeQ2();
01250 else Q2=CSmanager->GetQEL_ExchangeQ2();
01251 #ifdef debug
01252 G4cout<<"G4QInelastic::PostStDoIt:QuasiEl(nu="<<secnu<<"),s="<<s_value<<",Q2="<<Q2<<G4endl;
01253 #endif
01254
01255 G4double sqs=std::sqrt(s_value);
01256 G4double dsqs=sqs+sqs;
01257 G4double p_init=(s_value-mIN*mIN)/dsqs;
01258 G4double dpi=p_init+p_init;
01259 G4double sd=s_value-mlsOT;
01260 G4double qo2=(sd*sd-mlOT)/dsqs;
01261 G4double qo=std::sqrt(qo2);
01262 G4double cost=(dpi*std::sqrt(qo2+ml2)-Q2-ml2)/dpi/qo;
01263 G4LorentzVector t4M(0.,0.,0.,mIN);
01264 G4LorentzVector c4M=t4M+proj4M;
01265 t4M.setT(mOT);
01266 scat4M=G4LorentzVector(0.,0.,0.,ml);
01267 if(!G4QHadron(c4M).RelDecayIn2(scat4M, t4M, proj4M, cost, cost))
01268 {
01269 G4cerr<<"G4QIn::PStD:c4M="<<c4M<<sqs<<",mM="<<ml<<",tM="<<mOT<<",c="<<cost<<G4endl;
01270
01271 G4Exception("G4QInelastic::PostStepDoIt()", "HAD_CHPS_0000",
01272 FatalException, "Hadronize quasmon: Can't dec QE nu,lept Compound");
01273 }
01274 proj4M=t4M;
01275 }
01276 else
01277 {
01278
01279 if ( (secnu && projPDG == 2212) || (!secnu && projPDG == 2112) ) targPDG+=1;
01280 else if ( (secnu && projPDG == 2112) || (!secnu && projPDG == 2212) ) targPDG+=1000;
01281 G4double Q2=0;
01282 if(secnu) Q2=CSmanager->GetNQE_ExchangeQ2();
01283 else Q2=CSmanager2->GetNQE_ExchangeQ2();
01284 #ifdef debug
01285 G4cout<<"G4QInel::PStDoIt: MultiPeriferal s="<<s_value<<",Q2="<<Q2<<",T="<<targPDG<<G4endl;
01286 #endif
01287 if(secnu) projPDG=CSmanager2->GetExchangePDGCode();
01288 else projPDG=CSmanager->GetExchangePDGCode();
01289
01290
01291 G4double r=G4UniformRand();
01292 G4double r1=0.5;
01293 if(r<0.5) r1=std::sqrt(r+r)*(.5+.1579*(r-.5));
01294 else if(r>0.5) r1=1.-std::sqrt(2.-r-r)*(.5+.1579*(.5-r));
01295 G4double xn=1.-mldM/Momentum;
01296 G4double x1=xn*r1;
01297 G4double x=1.-x1;
01298
01299 G4double mx=hdM*x;
01300 G4double we=Q2/(mx+mx);
01301 if(we>=kinEnergy-ml-.001) we=kinEnergy-ml-.0001;
01302 G4double pot=kinEnergy-we;
01303 G4double mlQ2=ml2+Q2;
01304 G4double cost=(pot-mlQ2/dKinE)/std::sqrt(pot*pot-ml2);
01305 if(std::fabs(cost)>1)
01306 {
01307 #ifdef debug
01308 G4cout<<"*G4QInelastic::PostStDoIt: cost="<<cost<<", Q2="<<Q2<<", nu="<<we<<", mx="
01309 <<mx<<", pot="<<pot<<", 2KE="<<dKinE<<G4endl;
01310 #endif
01311 if(cost>1.) cost=1.;
01312 else cost=-1.;
01313 pot=mlQ2/dKinE+dKinE*ml2/mlQ2;
01314 }
01315 G4double lEn=std::sqrt(pot*pot+ml2);
01316 G4double lPl=pot*cost;
01317 G4double lPt=pot*std::sqrt(1.-cost*cost);
01318 std::pair<G4double,G4double> d2d=Random2DDirection();
01319 G4double lPx=lPt*d2d.first;
01320 G4double lPy=lPt*d2d.second;
01321 G4ThreeVector vdir=proj4M.vect();
01322 G4ThreeVector vz= vdir.unit();
01323 G4ThreeVector vv= vz.orthogonal();
01324 G4ThreeVector vx= vv.unit();
01325 G4ThreeVector vy= vz.cross(vx);
01326 G4ThreeVector lP= lPl*vz+lPx*vx+lPy*vy;
01327 scat4M=G4LorentzVector(lP,lEn);
01328 proj4M-=scat4M;
01329 #ifdef debug
01330 G4cout<<"G4QInelastic::PostStDoIt: proj4M="<<proj4M<<", ml="<<ml<<G4endl;
01331 #endif
01332
01333 G4int fintPDG=targPDG;
01334 if(!secnu)
01335 {
01336 if(projPDG<0) fintPDG-= 999;
01337 else fintPDG+= 999;
01338 }
01339 G4double fM=G4QPDGCode(fintPDG).GetMass();
01340 G4double fM2=fM*fM;
01341 G4LorentzVector tg4M=G4LorentzVector(0.,0.,0.,tgM);
01342 G4LorentzVector c4M=tg4M+proj4M;
01343 #ifdef debug
01344 G4cout<<"G4QInelastic::PSDI:fM2="<<fM2<<"<? mc4M="<<c4M.m2()<<",dM="<<fM-tgM<<G4endl;
01345 #endif
01346 if(fM2>=c4M.m2())
01347 {
01348 G4LorentzVector tot4M=tg4M+proj4M+scat4M;
01349 s_value=tot4M.m2();
01350 G4double fs=s_value-fM2-ml2;
01351 G4double fMl=fM2*ml2;
01352 G4double hQ2max=(fs*fs/2-fMl-fMl)/s_value;
01353 cost=1.-Q2/hQ2max;
01354 #ifdef debug
01355 G4cout<<"G4QI::PSDI:ct="<<cost<<",Q2="<<Q2<<",hQ2="<<hQ2max<<",4M="<<tot4M<<G4endl;
01356 #endif
01357 G4double acost=std::fabs(cost);
01358 if(acost>1.)
01359 {
01360 if(acost>1.001) G4cout<<"-Warning-G4QInelastic::PostStDoIt: cost="<<cost<<G4endl;
01361 if (cost> 1.) cost= 1.;
01362 else if(cost<-1.) cost=-1.;
01363 }
01364 G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,fM);
01365 scat4M=G4LorentzVector(0.,0.,0.,ml);
01366 G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-ml)*.01);
01367 if(!G4QHadron(tot4M).RelDecayIn2(scat4M, reco4M, dir4M, cost, cost))
01368 {
01369 G4cerr<<"G4QI::PSDI:t4M="<<tot4M<<",lM="<<ml<<",rM="<<fM<<",cost="<<cost<<G4endl;
01370
01371 }
01372 #ifdef debug
01373 G4cout<<"G4QIn::PStDoI:l4M="<<scat4M<<"+r4M="<<reco4M<<"="<<scat4M+reco4M<<G4endl;
01374 #endif
01375
01376 G4ParticleDefinition* theDefinition=0;
01377
01378 if (scatPDG==-11) theDefinition = G4Positron::Positron();
01379 else if(scatPDG== 11) theDefinition = G4Electron::Electron();
01380 else if(scatPDG== 13) theDefinition = G4MuonMinus::MuonMinus();
01381 else if(scatPDG==-13) theDefinition = G4MuonPlus::MuonPlus();
01382
01383
01384 if (scatPDG==-12) theDefinition = G4AntiNeutrinoE::AntiNeutrinoE();
01385 else if(scatPDG== 12) theDefinition = G4NeutrinoE::NeutrinoE();
01386 else if(scatPDG== 14) theDefinition = G4NeutrinoMu::NeutrinoMu();
01387 else if(scatPDG==-14) theDefinition = G4AntiNeutrinoMu::AntiNeutrinoMu();
01388
01389
01390 else G4cout<<"-Warning-G4QInelastic::PostStDoIt: UnknownLepton="<<scatPDG<<G4endl;
01391 G4DynamicParticle* theScL = new G4DynamicParticle(theDefinition,scat4M);
01392 G4Track* scatLep = new G4Track(theScL, localtime, position );
01393 scatLep->SetWeight(weight);
01394 scatLep->SetTouchableHandle(trTouchable);
01395 aParticleChange.AddSecondary(scatLep);
01396
01397 if (fintPDG==90000001) theDefinition = G4Neutron::Neutron();
01398 else if(fintPDG==90001000) theDefinition = G4Proton::Proton();
01399 else
01400 {
01401 G4int fm=static_cast<G4int>(fintPDG/1000000);
01402 G4int ZN=fintPDG-1000000*fm;
01403 G4int rZ=static_cast<G4int>(ZN/1000);
01404 G4int rA=ZN-999*rZ;
01405 theDefinition = G4ParticleTable::GetParticleTable()->FindIon(rZ,rA,0,rZ);
01406 }
01407 G4DynamicParticle* theReN = new G4DynamicParticle(theDefinition,reco4M);
01408 G4Track* scatReN = new G4Track(theReN, localtime, position );
01409 scatReN->SetWeight(weight);
01410 scatReN->SetTouchableHandle(trTouchable);
01411 aParticleChange.AddSecondary(scatReN);
01412 delete output;
01413 return G4VDiscreteProcess::PostStepDoIt(track, step);
01414 }
01415 }
01416
01417
01418
01419 }
01420
01421 else if(2>3)
01422 {
01423 if(momentum<500. && projPDG == 2112)
01424 {
01425 G4LorentzVector tot4M=G4LorentzVector(0.,0.,0.,tgM)+proj4M;
01426 G4double totM2=tot4M.m2();
01427 G4int tZ=Z;
01428 G4int tN=N;
01429 if(projPDG == 2212) tZ++;
01430 else tN++;
01431 if(momentum<100.)
01432 {
01433 G4QPDGCode FakeP(2112);
01434
01435 G4int m2n=tN-2;
01436
01437
01438 G4double mR2N= FakeP.GetNuclMass(tZ,m2n,0);
01439
01440
01441 G4double minM=mR2N+mNeut+mNeut;
01442
01443 if(totM2 < minM*minM)
01444 {
01445 aParticleChange.ProposeEnergy(kinEnergy);
01446 aParticleChange.ProposeLocalEnergyDeposit(0.);
01447 aParticleChange.ProposeMomentumDirection(dir);
01448 aParticleChange.ProposeTrackStatus(fAlive);
01449 return G4VDiscreteProcess::PostStepDoIt(track,step);
01450 }
01451 }
01452 }
01453
01454 G4QuasiFreeRatios* qfMan=G4QuasiFreeRatios::GetPointer();
01455 std::pair<G4double,G4double> fief=qfMan->GetRatios(momentum, projPDG, Z, N);
01456 G4double qepart=fief.first*fief.second;
01457
01458 const G4int lCl=3;
01459 G4double clProb[lCl]={.65,.85,.95};
01460 if(qepart>0.45) qepart=.45;
01461
01462 qepart=qepart/clProb[0]-qepart;
01463 G4double pickup=1.-qepart;
01464 G4double thresh=100.;
01465
01466 if(momentum > thresh) pickup*=50./momentum/G4QThd(Z+N);
01467
01468 if (N) pickup+=qepart;
01469 else pickup =qepart;
01470 G4double rnd=G4UniformRand();
01471 #ifdef ldebug
01472 G4cout<<"-->G4QInelastic::PSD:QE[p("<<proj4M<<")+(Z="<<Z<<",N="<<N<<")]="<<qepart
01473 <<", pickup="<<pickup<<G4endl;
01474 #endif
01475 if(rnd<pickup)
01476 {
01477 G4double dmom=91.;
01478 G4double fmm=287.;
01479 if(Z>1||N>1) dmom=fmm*std::pow(-std::log(G4UniformRand()),third);
01480
01481 G4LorentzVector r4M(0.,0.,0.,0.);
01482 G4LorentzVector n4M(0.,0.,0.,0.);
01483 G4int nPDG=90000001;
01484 G4int restPDG=targPDG;
01485 G4int rA=Z+N-1;
01486 G4int rZ=Z;
01487 G4int nA=1;
01488 G4int nZ=0;
01489 G4double qM=mNeut;
01490 G4int A = Z + N;
01491 if(rnd<qepart)
01492 {
01493
01494
01495 G4double base=1.;
01496 G4int max=lCl;
01497
01498 if(Z<2 || N<2 || A < 6) base = clProb[--max];
01499 if((Z > 1 && N < 2) || (Z < 2 && N > 1)) base=(clProb[max]+clProb[max-1])/2;
01500 if ( (Z < 2 && N < 2) || A < 5) base=clProb[--max];
01501 if(A<3) base=clProb[--max];
01502
01503 G4int cln=1;
01504
01505 if(max>1)
01506 {
01507 base-=clProb[0];
01508 G4double ran=+clProb[0]+base*G4UniformRand();
01509 G4int ic=1;
01510 if(max>1) while(ic<max) if(ran>clProb[ic++]) cln=ic;
01511 }
01512 G4ParticleDefinition* theDefinition=0;
01513 G4bool cp1 = cln+2==A;
01514 if(!cln || cp1)
01515 {
01516 G4int nln=0;
01517 if(cln==2) nln=1;
01518
01519 if ( ((!cln || cln == 2) && G4UniformRand()*(A-cln) > (N-nln)) ||
01520 ((cln == 3 || cln == 1) && Z > N) )
01521 {
01522 nPDG=90001000;
01523 nZ=1;
01524 qM=mProt;
01525 rZ--;
01526 restPDG-=1000;
01527 }
01528 else restPDG--;
01529 G4LorentzVector t4M(0.,0.,0.,tM);
01530 G4double rM=G4QPDGCode(restPDG).GetMass();
01531 r4M=G4LorentzVector(0.,0.,0.,rM);
01532 G4double rM2=rM*rM;
01533 G4double nM=std::sqrt(rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom));
01534 n4M=G4LorentzVector(0.,0.,0.,nM);
01535 #ifdef qedebug
01536 G4cout<<"G4QInel::PStDoIt:QE,p="<<dmom<<",tM="<<tM<<",R="<<rM<<",N="<<nM<<G4endl;
01537 #endif
01538 if(!G4QHadron(t4M).DecayIn2(r4M, n4M))
01539 {
01540
01541
01542
01543 G4cerr<<"-W-G4QInel::PoStDoI:M="<<tM<<"<rM="<<rM<<"+nM="<<nM<<"="<<rM+nM<<G4endl;
01544 aParticleChange.ProposeEnergy(kinEnergy);
01545 aParticleChange.ProposeLocalEnergyDeposit(0.);
01546 aParticleChange.ProposeMomentumDirection(dir);
01547 aParticleChange.ProposeTrackStatus(fAlive);
01548 return G4VDiscreteProcess::PostStepDoIt(track,step);
01549 }
01550 #ifdef qedebug
01551 G4cout<<"G4QIn::PStDoIt:QE-N, RA="<<r4M.rho()<<r4M<<",QN="<<n4M.rho()<<n4M<<G4endl;
01552 #endif
01553 if(cp1 && cln)
01554 {
01555 qM=rM;
01556 nln=nPDG;
01557 nPDG=restPDG;
01558 restPDG=nln;
01559 t4M=n4M;
01560 n4M=r4M;
01561 r4M=t4M;
01562 nln=nZ;
01563 nZ=rZ;
01564 rZ=nln;
01565 nln=nA;
01566 nA=rA;
01567 rA=nln;
01568 }
01569 }
01570 else
01571 {
01572 if(cln==1)
01573 {
01574 nPDG=90001001;
01575 qM=mDeut;
01576 nA=2;
01577 nZ=1;
01578 restPDG-=1001;
01579
01580 G4ThreeVector sumv=G4ThreeVector(0.,0.,dmom) +
01581 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01582 dmom=sumv.mag();
01583 }
01584 else if(cln==2)
01585 {
01586 nA=3;
01587 if(G4UniformRand()*(A-2)>(N-1))
01588 {
01589 nPDG=90002001;
01590 qM=mHel3;
01591 nZ=2;
01592 restPDG-=2001;
01593 }
01594 else
01595 {
01596 nPDG=90001002;
01597 qM=mTrit;
01598 nZ=1;
01599 restPDG-=1002;
01600 }
01601
01602 G4ThreeVector sumv=G4ThreeVector(0.,0.,dmom) +
01603 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection()+
01604 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01605 dmom=sumv.mag();
01606 }
01607 else
01608 {
01609 nPDG=90002002;
01610 qM=mAlph;
01611 nA=4;
01612 nZ=2;
01613 restPDG-=2002;
01614 G4ThreeVector sumv=G4ThreeVector(0.,0.,dmom) +
01615 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection()+
01616 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection()+
01617 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01618 dmom=sumv.mag();
01619 }
01620 rA=A-nA;
01621 rZ=Z-nZ;
01622
01623
01624
01625
01626
01627
01628 G4LorentzVector t4M(0.,0.,0.,tM);
01629 G4double rM=G4QPDGCode(restPDG).GetMass();
01630 r4M=G4LorentzVector(0.,0.,0.,rM);
01631 G4double rM2=rM*rM;
01632 G4double nM=std::sqrt(rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom));
01633 n4M=G4LorentzVector(0.,0.,0.,nM);
01634 #ifdef qedebug
01635 G4cout<<"G4QInel::PStDoIt:QEC, p="<<dmom<<",T="<<tM<<",R="<<rM<<",N="<<nM<<G4endl;
01636 #endif
01637 if(!G4QHadron(t4M).DecayIn2(r4M, n4M))
01638 {
01639
01640
01641
01642 G4cerr<<"-W-G4QInel::PoStDoI:M="<<tM<<"<rM="<<rM<<"+cM="<<nM<<"="<<rM+nM<<G4endl;
01643 aParticleChange.ProposeEnergy(kinEnergy);
01644 aParticleChange.ProposeLocalEnergyDeposit(0.);
01645 aParticleChange.ProposeMomentumDirection(dir);
01646 aParticleChange.ProposeTrackStatus(fAlive);
01647 return G4VDiscreteProcess::PostStepDoIt(track,step);
01648 }
01649
01650 #ifdef qedebug
01651 G4cout<<"G4QIn::PStDoIt:QEC, RN="<<r4M.rho()<<r4M<<",QCl="<<n4M.rho()<<n4M<<G4endl;
01652 #endif
01653 }
01654 G4LorentzVector s4M=n4M+proj4M;
01655 G4double prjM2 = proj4M.m2();
01656 G4double prjM = std::sqrt(prjM2);
01657 G4double minM = prjM+qM;
01658 G4double cmM2 =s4M.m2();
01659 if(cmM2>minM*minM)
01660 {
01661 #ifdef qedebug
01662 G4cout<<"G4QInel::PStDoIt:***Enter***,cmM2="<<cmM2<<" > minM2="<<minM*minM<<G4endl;
01663 #endif
01664
01665 G4bool chex=false;
01666 G4ParticleDefinition* projpt=G4Proton::Proton();
01667
01668
01669 if(2>3)
01670 {
01671 #ifdef qedebug
01672 G4cout<<"G4QIn::PStDoIt:-Enter, P="<<projPDG<<",cln="<<cln<<",cp1="<<cp1<<G4endl;
01673 #endif
01674 G4double tprM=mProt;
01675 G4double tprM2=mProt2;
01676 G4int tprPDG=2212;
01677 G4int tresPDG=restPDG+999;
01678 if(projPDG==2212)
01679 {
01680 projpt=G4Neutron::Neutron();
01681 tprM=mNeut;
01682 tprM2=mNeut2;
01683 tprPDG=2112;
01684 tresPDG=restPDG-999;
01685 }
01686 minM=tprM+qM;
01687 G4double efE=(cmM2-tprM2-qM*qM)/(qM+qM);
01688 G4double efP=std::sqrt(efE*efE-tprM2);
01689 G4double chl=qfMan->ChExElCoef(efP*MeV, nZ, nA-nZ, projPDG);
01690 #ifdef qedebug
01691 G4cout<<"G4QInel::PStDoIt:chl="<<chl<<",P="<<efP<<",nZ="<<nZ<<",nA="<<nA<<G4endl;
01692 #endif
01693 if(chl>0.&&cmM2>minM*minM&&G4UniformRand()<chl/(1.+chl))
01694 {
01695 projPDG=tprPDG;
01696 prjM=tprM;
01697 G4double rM=G4QPDGCode(tresPDG).GetMass();
01698 r4M=G4LorentzVector(0.,0.,0.,rM);
01699 n4M=G4LorentzVector(0.,0.,0.,tM-rM);
01700 chex=true;
01701 }
01702 }
01703
01704 std::pair<G4LorentzVector,G4LorentzVector> sctout=qfMan->Scatter(nPDG, n4M,
01705 projPDG, proj4M);
01706 #ifdef qedebug
01707 G4cout<<"G4QInelastic::PStDoIt:QElS,proj="<<prjM<<sctout.second<<",qfCl="<<qM
01708 <<sctout.first<<",chex="<<chex<<",nA="<<nA<<",nZ="<<nZ<<G4endl;
01709 #endif
01710 aParticleChange.ProposeLocalEnergyDeposit(0.);
01711
01712 if(chex)
01713 {
01714 aParticleChange.ProposeEnergy(0.);
01715 aParticleChange.ProposeTrackStatus(fStopAndKill);
01716 aParticleChange.SetNumberOfSecondaries(3);
01717 G4DynamicParticle* thePrH = new G4DynamicParticle(projpt,sctout.second);
01718 G4Track* scatPrH = new G4Track(thePrH, localtime, position );
01719 scatPrH->SetWeight(weight);
01720 scatPrH->SetTouchableHandle(trTouchable);
01721 aParticleChange.AddSecondary(scatPrH);
01722 }
01723 else
01724 {
01725 aParticleChange.SetNumberOfSecondaries(2);
01726 G4double ldT=(sctout.second).e()-prjM;
01727 aParticleChange.ProposeEnergy(ldT);
01728 G4ThreeVector ldV=(sctout.second).vect();
01729 aParticleChange.ProposeMomentumDirection(ldV/ldV.mag());
01730 aParticleChange.ProposeTrackStatus(fAlive);
01731 }
01732
01733
01734 if (nPDG==90000001) theDefinition = G4Neutron::Neutron();
01735 else if(nPDG==90001000) theDefinition = G4Proton::Proton();
01736 else if(nZ>0 && nA>1)
01737 theDefinition = G4ParticleTable::GetParticleTable()->FindIon(nZ,nA,0,nZ);
01738 #ifdef debug
01739 else G4cout<<"-Warning_G4QIn::PSD:scatqfPDG="<<nPDG<<", Z="<<nZ<<",A="<<nA<<G4endl;
01740 #endif
01741 if(nZ>0 && nA>0)
01742 {
01743 G4DynamicParticle* theQFN = new G4DynamicParticle(theDefinition,sctout.first);
01744 G4Track* scatQFN = new G4Track(theQFN, localtime, position );
01745 scatQFN->SetWeight(weight);
01746 scatQFN->SetTouchableHandle(trTouchable);
01747 aParticleChange.AddSecondary(scatQFN);
01748 }
01749
01750
01751 if (restPDG==90000001) theDefinition = G4Neutron::Neutron();
01752 else if(restPDG==90001000) theDefinition = G4Proton::Proton();
01753 else if(rZ>0 && rA>1)
01754 theDefinition = G4ParticleTable::GetParticleTable()->FindIon(rZ,rA,0,rZ);
01755 #ifdef debug
01756 else G4cout<<"-Warning_G4QIn::PSD: resPDG="<<restPDG<<",Z="<<rZ<<",A="<<rA<<G4endl;
01757 #endif
01758 if(rZ>0 && rA>0)
01759 {
01760 G4DynamicParticle* theReN = new G4DynamicParticle(theDefinition,r4M);
01761 G4Track* scatReN = new G4Track(theReN, localtime, position );
01762 scatReN->SetWeight(weight);
01763 scatReN->SetTouchableHandle(trTouchable);
01764 aParticleChange.AddSecondary(scatReN);
01765 }
01766 delete output;
01767 return G4VDiscreteProcess::PostStepDoIt(track, step);
01768 }
01769 #ifdef qedebug
01770 else G4cout<<"G4QInel::PSD:OUT,M2="<<s4M.m2()<<"<"<<minM*minM<<", N="<<nPDG<<G4endl;
01771 #endif
01772 }
01773 else
01774 {
01775 if(projPDG==2212) restPDG--;
01776 else
01777 {
01778 restPDG-=1000;
01779 rZ--;
01780 }
01781 G4double mPUF=mDeut;
01782 G4ParticleDefinition* theDefinition = G4Deuteron::Deuteron();
01783
01784 G4bool din=false;
01785 G4bool dip=false;
01786 G4bool pin=false;
01787 G4bool hin=false;
01788 G4double frn=G4UniformRand();
01789 if(N>2 && frn > 0.95)
01790 {
01791 if(projPDG==2212)
01792 {
01793 if(N>1 && G4UniformRand()*(Z+.5*(N-1)) > Z)
01794 {
01795 theDefinition = G4Triton::Triton();
01796 mPUF=mTrit;
01797 restPDG--;
01798 din=true;
01799 }
01800 else
01801 {
01802 theDefinition = G4He3::He3();
01803 mPUF=mHel3;
01804 restPDG-=1000;
01805 rZ--;
01806 pin=true;
01807 }
01808 }
01809 else
01810 {
01811 if(Z>1 && G4UniformRand()*(N+.5*(Z-1)) > N)
01812 {
01813 theDefinition = G4He3::He3();
01814 mPUF=mHel3;
01815 restPDG-=1000;
01816 rZ--;
01817 dip=true;
01818 }
01819 else
01820 {
01821 theDefinition = G4Triton::Triton();
01822 mPUF=mTrit;
01823 restPDG--;
01824 pin=true;
01825 }
01826 }
01827 rA--;
01828
01829 G4ThreeVector sumv=G4ThreeVector(0.,0.,dmom) +
01830 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01831 dmom=sumv.mag();
01832 if(Z>1 && frn > 0.99)
01833 {
01834 theDefinition = G4Alpha::Alpha();
01835 if((din && projPDG==2212) || (pin && projPDG==2112))
01836 {
01837 restPDG-=1000;
01838 rZ--;
01839 }
01840 else if((pin && projPDG==2212) || (dip && projPDG==2112)) restPDG--;
01841 else G4cout<<"-Warning-G4QIn::PSD: PickUp logic error, proj="<<projPDG<<G4endl;
01842 hin=true;
01843 mPUF=mAlph;
01844 rA--;
01845
01846 sumv += fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01847 dmom=sumv.mag();
01848 }
01849 }
01850 G4double mPUF2=mPUF*mPUF;
01851 G4LorentzVector t4M(0.,0.,0.,tM);
01852 G4double rM=G4QPDGCode(restPDG).GetMass();
01853 G4double rM2=rM*rM;
01854 G4double nM2=rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom);
01855 if(nM2 < 0) nM2=0.;
01856 G4double den2=(dmom*dmom+nM2);
01857 G4double den=std::sqrt(den2);
01858 #ifdef qedebug
01859 G4double nM=std::sqrt(nM2);
01860 G4cout<<"G4QInel::PStDoIt:PiU, p="<<dmom<<",tM="<<tM<<", R="<<rM<<",N="<<nM<<G4endl;
01861 #endif
01862 G4double qp=momentum*dmom;
01863 G4double srm=proj4M.e()*den;
01864 G4double mNucl2=mProt2;
01865 if(projPDG == 2112) mNucl2=mNeut2;
01866 G4double cost=(nM2+mNucl2+srm+srm-mPUF2)/(qp+qp);
01867 G4int ict=0;
01868 while(std::fabs(cost)>1. && ict<3)
01869 {
01870 dmom=91.;
01871 if(Z>1||N>1) dmom=fmm*std::pow(-std::log(G4UniformRand()),third);
01872 if(din || pin || dip)
01873 {
01874 G4ThreeVector sumv=G4ThreeVector(0.,0.,dmom) +
01875 fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01876 if(hin)
01877 sumv+=fmm*std::pow(-std::log(G4UniformRand()),third)*G4RandomDirection();
01878 dmom=sumv.mag();
01879 }
01880 nM2=rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom);
01881 if(nM2 < 0) nM2=0.;
01882
01883 den2=(dmom*dmom+nM2);
01884 den=std::sqrt(den2);
01885 qp=momentum*dmom;
01886 srm=proj4M.e()*den;
01887 cost=(nM2+mNucl2+srm+srm-mPUF2)/(qp+qp);
01888 ict++;
01889 #ifdef ldebug
01890 if(ict>2)G4cout<<"G4QInelast::PStDoIt:i="<<ict<<",d="<<dmom<<",ct="<<cost<<G4endl;
01891 #endif
01892 }
01893 if(std::fabs(cost)<=1.)
01894 {
01895 G4ThreeVector vdir = proj4M.vect();
01896 G4ThreeVector vx(0.,0.,1.);
01897 G4ThreeVector vy(0.,1.,0.);
01898 G4ThreeVector vz(1.,0.,0.);
01899 if(vdir.mag2() > 0.)
01900 {
01901 vx = vdir.unit();
01902 G4ThreeVector vv= vx.orthogonal();
01903 vy = vv.unit();
01904 vz = vx.cross(vy);
01905 }
01906
01907 G4double tdom=dmom*std::sqrt(1-cost*cost);
01908 G4double phi=twopi*G4UniformRand();
01909 G4ThreeVector vedm=vx*dmom*cost+vy*tdom*std::sin(phi)+vz*tdom*std::cos(phi);
01910 G4LorentzVector bqf(vedm,den);
01911 r4M=t4M-bqf;
01912 #ifdef debug
01913 if(std::fabs(r4M.m()-rM)>.001) G4cout<<"G4QIn::PSD: rM="<<rM<<"#"<<r4M.m()<<G4endl;
01914 #endif
01915 G4LorentzVector f4M=proj4M+bqf;
01916 #ifdef debug
01917 if(std::fabs(f4M.m()-mPUF)>.001)G4cout<<"G4QI::PSD:m="<<mPUF<<"#"<<f4M.m()<<G4endl;
01918 #endif
01919 aParticleChange.ProposeEnergy(0.);
01920 aParticleChange.ProposeTrackStatus(fStopAndKill);
01921 aParticleChange.SetNumberOfSecondaries(2);
01922
01923 G4DynamicParticle* theQFN = new G4DynamicParticle(theDefinition,f4M);
01924 G4Track* scatQFN = new G4Track(theQFN, localtime, position );
01925 scatQFN->SetWeight(weight);
01926 scatQFN->SetTouchableHandle(trTouchable);
01927 aParticleChange.AddSecondary(scatQFN);
01928 #ifdef pickupd
01929 G4cout<<"G4QInelastic::PStDoIt: f="<<theDefinition<<",f4M="<<f4M.m()<<f4M<<G4endl;
01930 #endif
01931
01932
01933 if (restPDG==90000001) theDefinition = G4Neutron::Neutron();
01934 else if(restPDG==90001000) theDefinition = G4Proton::Proton();
01935 else theDefinition = G4ParticleTable::GetParticleTable()->FindIon(rZ,rA,0,rZ);
01936 G4DynamicParticle* theReN = new G4DynamicParticle(theDefinition,r4M);
01937 G4Track* scatReN = new G4Track(theReN, localtime, position );
01938 scatReN->SetWeight(weight);
01939 scatReN->SetTouchableHandle(trTouchable);
01940 aParticleChange.AddSecondary(scatReN);
01941 #ifdef pickupd
01942 G4cout<<"G4QInelastic::PStDoIt:rZ="<<rZ<<",rA="<<rA<<",r4M="<<r4M.m()<<r4M<<G4endl;
01943 #endif
01944 delete output;
01945 return G4VDiscreteProcess::PostStepDoIt(track, step);
01946 }
01947 }
01948 }
01949 }
01950 EnMomConservation=proj4M+G4LorentzVector(0.,0.,0.,tM);
01951 if(absMom) EnMomConservation+=lead4M;
01952 #ifdef debug
01953 G4cout<<"G4QInelastic::PostStDoIt:before St="<<aParticleChange.GetTrackStatus()<<G4endl;
01954 #endif
01955
01956
01957
01958
01959
01960 #ifdef debug
01961 G4cout<<"^^G4QInelastic::PostStepDoIt: projPDG="<<projPDG<<", targPDG="<<targPDG<<G4endl;
01962 #endif
01963 const G4QNucleus targNuc(Z,N);
01964 if(projPDG>9000000)
01965 {
01966 delete output;
01967 G4QNucleus projNuc(proj4M,projPDG);
01968 G4QIonIonCollision IonIon(projNuc, targNuc);
01969 #ifdef debug
01970 G4cout<<"G4QInel::PStDoIt: ProjNuc="<<projPDG<<proj4M<<", TargNuc="<<targPDG<<G4endl;
01971 #endif
01972 try {output = IonIon.Fragment();}
01973 catch (G4QException& error)
01974 {
01975 G4cerr<<"***G4QInelastic::PostStepDoIt: G4QE Exception is catched in hA"<<G4endl;
01976
01977 G4Exception("G4QInelastic::PostStepDoIt()", "HAD_CHPS_0027",
01978 FatalException, "CHIPS hA crash");
01979 }
01980 }
01981 else
01982 {
01983
01984 #ifdef debug
01985 G4int maxCn=7;
01986 #endif
01987 G4int atCn=0;
01988
01989
01990
01991 #ifdef debug
01992 G4cout<<"G4QInelastic::PStDoIt: atCn="<<atCn<<" <= maxCn="<<maxCn<<G4endl;
01993 #endif
01994 G4int outN=output->size();
01995 if(outN)
01996 {
01997 std::for_each(output->begin(), output->end(), DeleteQHadron());
01998 output->clear();
01999 }
02000 delete output;
02001 const G4QHadron projH(projPDG,proj4M);
02002 #ifdef debug
02003 G4cout<<"G4QInelastic::PStDoIt: Before Fragmentation"<<G4endl;
02004 #endif
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015 G4QFragmentation DINR(targNuc, projH);
02016 #ifdef debug
02017 G4cout<<"G4QInelastic::PStDoIt:Proj="<<projPDG<<proj4M<<",TgNuc="<<targPDG<<G4endl;
02018 #endif
02019 try {output = DINR.Fragment();}
02020 catch (G4QException& error)
02021 {
02022 G4cerr<<"***G4QInelastic::PostStepDoIt: G4QE Exception is catched in hA"<<G4endl;
02023
02024 G4Exception("G4QInelastic::PostStepDoIt()", "HAD_CHPS_0027",
02025 FatalException, "CHIPS hA crash");
02026 }
02027
02028 outN=output->size();
02029 #ifdef debug
02030 G4cout<<"G4QInelastic::PostStepDoIt: At# "<<atCn<<", nSec="<<outN<<", fPDG="
02031 <<(*output)[0]->GetPDGCode()<<", pPDG="<< projPDG<<G4endl;
02032 #endif
02033
02034 if(outN < 2)
02035 {
02036 G4cout<<"-Warning-G4QInelastic::PostStepDoIt: nSec="<<outN<<", At# "<<atCn<<G4endl;
02037
02038 }
02039
02040 #ifdef debug
02041 if(atCn==maxCn)G4cout<<"-Warning-G4QI::PostStDoIt:mAt="<<atCn<<" is reached"<<G4endl;
02042 #endif
02043
02044 }
02045
02046
02047 if(scat)
02048 {
02049 G4QHadron* scatHadron = new G4QHadron(scatPDG,scat4M);
02050 output->push_back(scatHadron);
02051 }
02052 G4int qNH=0;
02053 if(leadhs) qNH=leadhs->size();
02054 if(absMom)
02055 {
02056 if(qNH) for(G4int iq=0; iq<qNH; iq++)
02057 {
02058 G4QHadron* loh=(*leadhs)[iq];
02059 output->push_back(loh);
02060 }
02061 if(leadhs) delete leadhs;
02062 leadhs=0;
02063 }
02064 else
02065 {
02066 if(qNH) for(G4int iq=0; iq<qNH; iq++) delete (*leadhs)[iq];
02067 if(leadhs) delete leadhs;
02068 leadhs=0;
02069 }
02070
02071 G4int tNH = output->size();
02072 aParticleChange.SetNumberOfSecondaries(tNH);
02073
02074 #ifdef debug
02075 G4cout<<"G4QInelastic::PostStepDoIt: "<<tNH<<" particles are generated"<<G4endl;
02076 #endif
02077 #ifdef ppdebug
02078 if(absMom)G4cout<<"G4QInelastic::PostStepDoIt: t="<<tNH<<", q="<<qNH<<G4endl;
02079 #endif
02080 G4int nOut=output->size();
02081 if(tNH==1 && !scat)
02082 {
02083 G4cout<<"-Warning-G4QInelastic::PostStepDoIt: 1 secondary! absMom="<<absMom;
02084 if(absMom) G4cout<<", qNH="<<qNH;
02085 G4cout<<", PDG0="<<(*output)[0]->GetPDGCode();
02086 G4cout<<G4endl;
02087 tNH=0;
02088 delete output->operator[](0);
02089 output->pop_back();
02090 }
02091 if(tNH==2&&2!=nOut) G4cout<<"--Warning--G4QInelastic::PostStepDoIt: 2 # "<<nOut<<G4endl;
02092
02093
02094 if(tNH) for(i=0; i<tNH; i++)
02095 {
02096
02097
02098
02099 G4QHadron* hadr=(*output)[i];
02100 G4int PDGCode = hadr->GetPDGCode();
02101 G4int nFrag = hadr->GetNFragments();
02102 #ifdef pdebug
02103 G4cout<<"G4QInelastic::PostStepDoIt: H#"<<i<<",PDG="<<PDGCode<<",nF="<<nFrag
02104 <<", 4Mom="<<hadr->Get4Momentum()<<G4endl;
02105 #endif
02106 if(nFrag)
02107 {
02108 #ifdef debug
02109 G4cout<<"G4QInelastic::PostStepDoIt: Intermediate particle is found i="<<i<<G4endl;
02110 #endif
02111 delete hadr;
02112 continue;
02113 }
02114 G4DynamicParticle* theSec = new G4DynamicParticle;
02115 G4ParticleDefinition* theDefinition;
02116 if (PDGCode==90000001) theDefinition = G4Neutron::Neutron();
02117 else if(PDGCode==90001000) theDefinition = G4Proton::Proton();
02118 else if(PDGCode==91000000) theDefinition = G4Lambda::Lambda();
02119 else if(PDGCode==311 || PDGCode==-311)
02120 {
02121 if(G4UniformRand()>.5) theDefinition = G4KaonZeroLong::KaonZeroLong();
02122 else theDefinition = G4KaonZeroShort::KaonZeroShort();
02123 }
02124 else if(PDGCode==91000999) theDefinition = G4SigmaPlus::SigmaPlus();
02125 else if(PDGCode==90999001) theDefinition = G4SigmaMinus::SigmaMinus();
02126 else if(PDGCode==91999000) theDefinition = G4XiMinus::XiMinus();
02127 else if(PDGCode==91999999) theDefinition = G4XiZero::XiZero();
02128 else if(PDGCode==92998999) theDefinition = G4OmegaMinus::OmegaMinus();
02129 else if(PDGCode==90000000)
02130 {
02131 #ifdef pdebug
02132 G4cout<<"-Warning-G4QInelastic::PostStepDoIt:Vacuum PDG="<<PDGCode
02133 <<", 4Mom="<<hadr->Get4Momentum()<<G4endl;
02134 #endif
02135 theDefinition = G4Gamma::Gamma();
02136 G4double hM2=(hadr->Get4Momentum()).m2();
02137 if(std::fabs(hM2)>.01) G4cout<<"-Warning-G4QInel::PoStDoIt:90000000M2="<<hM2<<G4endl;
02138 else if(hadr->Get4Momentum()==vacuum4M)
02139 {
02140 delete hadr;
02141 continue;
02142 }
02143 }
02144 else if(PDGCode >80000000)
02145 {
02146 G4int aZ = hadr->GetCharge();
02147 G4int aA = hadr->GetBaryonNumber();
02148 #ifdef pdebug
02149 G4cout<<"G4QInelastic::PostStepDoIt:Ion Z="<<aZ<<", A="<<aA<<G4endl;
02150 #endif
02151 theDefinition = G4ParticleTable::GetParticleTable()->FindIon(aZ,aA,0,aZ);
02152 }
02153
02154 else if(PDGCode==89999998 || PDGCode==89998000 || PDGCode==88000000)
02155 {
02156 G4double rM=mNeut;
02157 G4int rPDG=-2112;
02158 G4ParticleDefinition* BarDef=G4Neutron::Neutron();
02159 if (PDGCode==89998000)
02160 {
02161 rM=mProt;
02162 rPDG=-2212;
02163 BarDef=G4Proton::Proton();
02164 }
02165 else if(PDGCode==88000000)
02166 {
02167 rM=mLamb;
02168 rPDG=-3122;
02169 BarDef=G4Lambda::Lambda();
02170 }
02171 G4LorentzVector t4M=hadr->Get4Momentum();
02172 G4LorentzVector f4M=G4LorentzVector(0.,0.,0.,rM);
02173 G4LorentzVector s4M=G4LorentzVector(0.,0.,0.,rM);
02174 #ifdef qedebug
02175 G4cout<<"G4QInel::PStDoIt:AntiDiBar,t4M="<<tM<<",m="<<rM<<",PDG="<<PDGCode<<G4endl;
02176 #endif
02177 if(!G4QHadron(t4M).DecayIn2(f4M, s4M))
02178 {
02179 G4cerr<<"G4QIn::PostStDoIt: ADB, M="<<t4M.m()<<" < 2*rM="<<rM<<" = "<<2*rM<<G4endl;
02180
02181 G4Exception("G4QInelastic::PostStepDoIt()", "HAD_CHPS_0004",
02182 FatalException, "Hadronize quasmon: Can't decay anti-dibaryon");
02183 }
02184
02185 #ifdef qedebug
02186 G4cout<<"G4QInelastic::PStDoIt: ADB, H1="<<rM<<f4M<<", H2="<<rM<<s4M<<G4endl;
02187 #endif
02188 G4QHadron fH(rPDG,f4M);
02189 hadr->Set4Momentum(f4M);
02190 hadr->SetQPDG(fH.GetQPDG());
02191 theDefinition=BarDef;
02192 #ifdef debug
02193 G4cout<<"G4QInel::PostStDoIt:Anti-DiBar, DecayIn2, h1="<<rPDG<<f4M<<G4endl;
02194 #endif
02195 G4QHadron* sH = new G4QHadron(rPDG,s4M);
02196 output->push_back(sH);
02197 ++tNH;
02198 #ifdef debug
02199 G4cout<<"G4QInel::PostStDoIt:Anti-DiBar, DecayIn2, h2="<<rPDG<<s4M<<G4endl;
02200 #endif
02201 }
02202 else if(PDGCode==90000997 || PDGCode==89997001)
02203 {
02204 G4double rM=mNeut;
02205 G4int rPDG=-2112;
02206 G4double iM=mPi;
02207 G4int iPDG= 211;
02208 G4ParticleDefinition* BarDef=G4Neutron::Neutron();
02209 if(PDGCode==90000997)
02210 {
02211 rM=mProt;
02212 rPDG=-2212;
02213 iPDG=-211;
02214 BarDef=G4Proton::Proton();
02215 }
02216 G4LorentzVector t4M=hadr->Get4Momentum();
02217 G4LorentzVector f4M=G4LorentzVector(0.,0.,0.,rM);
02218 G4LorentzVector s4M=G4LorentzVector(0.,0.,0.,rM);
02219 G4LorentzVector u4M=G4LorentzVector(0.,0.,0.,iM);
02220 #ifdef qedebug
02221 G4cout<<"G4QInel::PStDoIt:AntiNDelta, t4M="<<tM<<",m="<<rM<<",PDG="<<PDGCode<<G4endl;
02222 #endif
02223 if(!G4QHadron(t4M).DecayIn3(f4M, s4M, u4M))
02224 {
02225 G4cerr<<"G4QIn::PostStDoIt: AND, tM="<<t4M.m()<<" < 2*mB+mPi="<<2*rM+iM<<G4endl;
02226
02227 G4Exception("G4QInelastic::PostStepDoIt()", "HAD_CHPS_0005",
02228 FatalException, "Hadronize quasmon: Can't decay anti-NDelta");
02229 }
02230
02231 #ifdef qedebug
02232 G4cout<<"G4QInel::PStDoI:AND,B1="<<rM<<f4M<<",B2="<<rM<<s4M<<",Pi="<<iM<<u4M<<G4endl;
02233 #endif
02234 G4QHadron fH(rPDG,f4M);
02235 hadr->Set4Momentum(f4M);
02236 hadr->SetQPDG(fH.GetQPDG());
02237 theDefinition=BarDef;
02238 #ifdef debug
02239 G4cout<<"G4QInel::PostStDoIt:Anti-NDelta, DecayIn2, h1="<<rPDG<<f4M<<G4endl;
02240 #endif
02241 G4QHadron* sH = new G4QHadron(rPDG,s4M);
02242 output->push_back(sH);
02243 ++tNH;
02244 #ifdef debug
02245 G4cout<<"G4QInel::PostStDoIt:Anti-NDelta, DecayIn2, h2="<<rPDG<<s4M<<G4endl;
02246 #endif
02247 G4QHadron* uH = new G4QHadron(iPDG,u4M);
02248 output->push_back(uH);
02249 ++tNH;
02250 #ifdef debug
02251 G4cout<<"G4QInel::PostStDoIt:Anti-NDelta, DecayIn2, h2="<<rPDG<<s4M<<G4endl;
02252 #endif
02253 }
02254 else
02255 {
02256 #ifdef pdebug
02257 G4cout<<"G4QInelastic::PostStepDoIt:Define particle with PDG="<<PDGCode<<G4endl;
02258 #endif
02259 theDefinition = G4QPDGToG4Particle::Get()->GetParticleDefinition(PDGCode);
02260 #ifdef pdebug
02261 G4cout<<"G4QInelastic::PostStepDoIt:AfterParticleDefinition PDG="<<PDGCode<<G4endl;
02262 #endif
02263 }
02264 if(!theDefinition)
02265 {
02266 if(PDGCode!=90000000 || hadr->Get4Momentum()!=vacuum4M)
02267 G4cout<<"---Warning---G4QInelastic::PostStepDoIt: drop PDG="<<PDGCode<<", 4Mom="
02268 <<hadr->Get4Momentum()<<G4endl;
02269 delete hadr;
02270 continue;
02271 }
02272 #ifdef pdebug
02273 G4cout<<"G4QInelastic::PostStepDoIt:Name="<<theDefinition->GetParticleName()<<G4endl;
02274 #endif
02275 theSec->SetDefinition(theDefinition);
02276 G4LorentzVector h4M=hadr->Get4Momentum();
02277 EnMomConservation-=h4M;
02278 #ifdef tdebug
02279 G4cout<<"G4QInelast::PSDI: "<<i<<","<<PDGCode<<h4M<<h4M.m()<<EnMomConservation<<G4endl;
02280 #endif
02281 #ifdef debug
02282 G4cout<<"G4QInelastic::PostStepDoIt:#"<<i<<",PDG="<<PDGCode<<",4M="<<h4M<<G4endl;
02283 #endif
02284 theSec->Set4Momentum(h4M);
02285 delete hadr;
02286 #ifdef debug
02287 G4ThreeVector curD=theSec->GetMomentumDirection();
02288 G4double curM=theSec->GetMass();
02289 G4double curE=theSec->GetKineticEnergy()+curM;
02290 G4cout<<"G4QInelast::PSDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl;
02291 #endif
02292 G4Track* aNewTrack = new G4Track(theSec, localtime, position );
02293 aNewTrack->SetWeight(weight);
02294 aNewTrack->SetTouchableHandle(trTouchable);
02295 aParticleChange.AddSecondary( aNewTrack );
02296 #ifdef debug
02297 G4cout<<"G4QInelastic::PostStepDoIt:#"<<i<<" is done."<<G4endl;
02298 #endif
02299 }
02300 delete output;
02301 if(leadhs)
02302 {
02303 qNH=leadhs->size();
02304 if(qNH) for(G4int iq=0; iq<qNH; iq++) delete (*leadhs)[iq];
02305 delete leadhs;
02306 leadhs=0;
02307 }
02308 #ifdef debug
02309 G4cout<<"G4QInelastic::PostStDoIt: after St="<<aParticleChange.GetTrackStatus()<<G4endl;
02310 #endif
02311 if(aProjPDG!=11 && aProjPDG!=13 && aProjPDG!=15)
02312 aParticleChange.ProposeTrackStatus(fStopAndKill);
02313 #ifdef pdebug
02314 G4cout<<"G4QInelastic::PostStepDoIt: E="<<aParticleChange.GetEnergy()
02315 <<", d="<<*aParticleChange.GetMomentumDirection()<<G4endl;
02316 #endif
02317 #ifdef ldebug
02318 G4cout<<"G4QInelastic::PostStepDoIt:*** PostStepDoIt is done ***, P="<<aProjPDG<<", St="
02319 <<aParticleChange.GetTrackStatus()<<G4endl;
02320 #endif
02321 return G4VDiscreteProcess::PostStepDoIt(track, step);
02322 }
02323
02324 std::pair<G4double,G4double> G4QInelastic::Random2DDirection()
02325 {
02326 G4double sp=0;
02327 G4double cp=1.;
02328 G4double r2=2.;
02329 while(r2>1. || r2<.0001)
02330 {
02331 G4double sine=G4UniformRand();
02332 G4double cosine=G4UniformRand();
02333 sp=1.-sine-sine;
02334 cp=1.-cosine-cosine;
02335 r2=sp*sp+cp*cp;
02336 }
02337 G4double norm=std::sqrt(r2);
02338 return std::make_pair(sp/norm,cp/norm);
02339 }