56 fAccumSpectrum.clear();
59 fFa.resize(fNMCPhotons);
60 fSs.resize(fNMCPhotons);
61 fSc.resize(fNMCPhotons);
62 fSsx.resize(fNMCPhotons);
63 fSsy.resize(fNMCPhotons);
64 fScx.resize(fNMCPhotons);
65 fScy.resize(fNMCPhotons);
66 std::fill(fFa.begin(), fFa.end(), 0.);
67 std::fill(fSs.begin(), fSs.end(), 0.);
68 std::fill(fSc.begin(), fSc.end(), 0.);
69 std::fill(fSsx.begin(), fSsx.end(), 0.);
70 std::fill(fSsy.begin(), fSsy.end(), 0.);
71 std::fill(fScx.begin(), fScx.end(), 0.);
72 std::fill(fScy.begin(), fScy.end(), 0.);
75 fMeanPhotonAngleX =0.;
77 fParamPhotonAngleX=1.e-3*CLHEP::rad;
79 fMeanPhotonAngleY =0.;
81 fParamPhotonAngleY=1.e-3*CLHEP::rad;
87 fParticleAnglesX.clear();
88 fParticleAnglesY.clear();
89 fScatteringAnglesX.clear();
90 fScatteringAnglesY.clear();
93 fParticleCoordinatesXYZ.clear();
101 fTotalRadiationProbabilityAlongTrajectory.clear();
103 fTotalRadiationProbabilityAlongTrajectory.push_back(0.);
112 fMinPhotonEnergy = emin;
113 fMaxPhotonEnergy = emax;
114 fNBinsSpectrum = numberOfBins;
116 fLogEmaxdEmin =
G4Log(fMaxPhotonEnergy/fMinPhotonEnergy);
119 fNPhotonsPerBin.resize(fNBinsSpectrum);
120 std::fill(fNPhotonsPerBin.begin(), fNPhotonsPerBin.end(), 0);
123 fSpectrum.resize(fNBinsSpectrum);
124 std::fill(fSpectrum.begin(), fSpectrum.end(), 0);
127 fAccumTotalSpectrum.resize(fNBinsSpectrum);
128 std::fill(fAccumTotalSpectrum.begin(), fAccumTotalSpectrum.end(), 0);
131 fTotalSpectrum.resize(fNBinsSpectrum);
132 std::fill(fTotalSpectrum.begin(), fTotalSpectrum.end(), 0);
134 fPhotonEnergyInSpectrum.clear();
135 for (
G4int j=0;j<fNBinsSpectrum;j++)
138 fPhotonEnergyInSpectrum.push_back(fMinPhotonEnergy*
139 (std::exp(fLogEmaxdEmin*j/fNBinsSpectrum)+
140 std::exp(fLogEmaxdEmin*(j+1)/fNBinsSpectrum))/2.);
152 G4int timesPhotonStatistics)
155 if(timesPhotonStatistics<=1)
157 G4cout <<
"G4BaierKatkov model, "
158 "function AddStatisticsInPhotonEnergyRegion("
159 << emin/CLHEP::MeV <<
" MeV, "
160 << emax/CLHEP::MeV <<
" MeV, "
161 << timesPhotonStatistics <<
")" <<
G4endl;
162 G4cout <<
"Warning: the statistics factor cannot be <=1." <<
G4endl;
166 else if(fMinPhotonEnergy>emin)
168 G4cout <<
"G4BaierKatkov model, "
169 "function AddStatisticsInPhotonEnergyRegion("
170 << emin/CLHEP::MeV <<
" MeV, "
171 << emax/CLHEP::MeV <<
" MeV, "
172 << timesPhotonStatistics <<
")" <<
G4endl;
173 G4cout <<
"Warning: the minimal energy inserted is less then "
174 "the minimal energy cut of the spectrum: "
175 << fMinPhotonEnergy/CLHEP::MeV <<
" MeV." <<
G4endl;
181 G4cout <<
"G4BaierKatkov model, "
182 "function AddStatisticsInPhotonEnergyRegion("
183 << emin/CLHEP::MeV <<
" MeV, "
184 << emax/CLHEP::MeV <<
" MeV, "
185 << timesPhotonStatistics <<
")" <<
G4endl;
186 G4cout <<
"Warning: the maximal energy <= the minimal energy." <<
G4endl;
193 G4double logAddRangeEmindEmin =
G4Log(emin/fMinPhotonEnergy);
194 G4double logAddRangeEmaxdEmin =
G4Log(emax/fMinPhotonEnergy);
196 G4int nAddRange = (
G4int)fTimesPhotonStatistics.size();
197 for (
G4int j=0;j<nAddRange;j++)
199 if((logAddRangeEmindEmin>=fLogAddRangeEmindEmin[j]&&
200 logAddRangeEmindEmin< fLogAddRangeEmaxdEmin[j])||
201 (logAddRangeEmaxdEmin> fLogAddRangeEmindEmin[j]&&
202 logAddRangeEmaxdEmin<=fLogAddRangeEmaxdEmin[j])||
203 (logAddRangeEmindEmin<=fLogAddRangeEmindEmin[j]&&
204 logAddRangeEmaxdEmin>=fLogAddRangeEmaxdEmin[j]))
206 G4cout <<
"G4BaierKatkov model, "
207 "function AddStatisticsInPhotonEnergyRegion("
208 << emin/CLHEP::MeV <<
" MeV, "
209 << emax/CLHEP::MeV <<
" MeV, "
210 << timesPhotonStatistics <<
")" <<
G4endl;
211 G4cout <<
"Warning: the energy range intersects another "
212 "added energy range." <<
G4endl;
221 fLogAddRangeEmindEmin.push_back(logAddRangeEmindEmin);
222 fLogAddRangeEmaxdEmin.push_back(logAddRangeEmaxdEmin);
223 fTimesPhotonStatistics.push_back(timesPhotonStatistics);
225 G4cout <<
"G4BaierKatkov model: increasing the statistics of photon sampling "
226 "in Baier-Katkov with a factor of "
227 << timesPhotonStatistics <<
G4endl;
228 G4cout <<
"in the energy spectrum range: ("
229 << emin/CLHEP::MeV <<
" MeV, "
230 << emax/CLHEP::MeV <<
" MeV)" <<
G4endl;
237void G4BaierKatkov::SetPhotonSamplingParameters(
G4double ekin,
243 fLogEdEmin =
G4Log(ekin/fMinPhotonEnergy);
244 fMeanPhotonAngleX = (maxPhotonAngleX+minPhotonAngleX)/2.;
245 fParamPhotonAngleX = (maxPhotonAngleX-minPhotonAngleX)/2.;
246 fMeanPhotonAngleY = (maxPhotonAngleY+minPhotonAngleY)/2.;
247 fParamPhotonAngleY = (maxPhotonAngleY-minPhotonAngleY)/2.;
252void G4BaierKatkov::GeneratePhotonSampling()
254 fPhotonEnergyInIntegral.clear();
255 fPhotonAngleInIntegralX.clear();
256 fPhotonAngleInIntegralY.clear();
257 fPhotonAngleNormCoef.clear();
258 fInsideVirtualCollimator.clear();
259 fIBinsSpectrum.clear();
262 std::vector<G4int> moreStatistics;
263 moreStatistics.resize(fTimesPhotonStatistics.size());
264 std::fill(moreStatistics.begin(), moreStatistics.end(), 0);
265 G4int nAddRange = (
G4int)fTimesPhotonStatistics.size();
269 for (
G4int j=0;j<fNMCPhotons;j++)
272 fIBinsSpectrum.push_back((
G4int)std::trunc(
273 ksi*fNBinsSpectrum/fLogEmaxdEmin));
277 if(fIBinsSpectrum[j]<fNBinsSpectrum) {fNPhotonsPerBin[fIBinsSpectrum[j]]+=1;}
279 fPhotonEnergyInIntegral.push_back(fMinPhotonEnergy*std::exp(ksi));
281 fPhotonAngleNormCoef.push_back(1.);
283 for (
G4int j2=0;j2<nAddRange;j2++)
285 if(ksi>fLogAddRangeEmindEmin[j2]&&
286 ksi<fLogAddRangeEmaxdEmin[j2])
290 moreStatistics[j2]+=1;
291 fPhotonAngleNormCoef[j]/=fTimesPhotonStatistics[j2];
297 for (
G4int j2=0;j2<nAddRange;j2++)
299 G4int totalAddRangeStatistics = moreStatistics[j2]*fTimesPhotonStatistics[j2];
300 for (
G4int j=moreStatistics[j2];j<totalAddRangeStatistics;j++)
302 ksi = fLogAddRangeEmindEmin[j2]+
303 G4UniformRand()*(std::min(fLogAddRangeEmaxdEmin[j2],fLogEdEmin)-
304 fLogAddRangeEmindEmin[j2]);
305 fIBinsSpectrum.push_back((
G4int)std::trunc(
306 ksi*fNBinsSpectrum/fLogEmaxdEmin));
313 fPhotonEnergyInIntegral.push_back(fMinPhotonEnergy*std::exp(ksi));
315 fPhotonAngleNormCoef.push_back(1./fTimesPhotonStatistics[j2]);
321 G4double norm=std::atan(rhocut*rhocut)*
322 CLHEP::pi*fParamPhotonAngleX*fParamPhotonAngleY;
326 G4int nmctotal = (
G4int)fPhotonEnergyInIntegral.size();
327 for (
G4int j=0;j<nmctotal;j++)
339 fPhotonAngleInIntegralX.push_back(fMeanPhotonAngleX+
341 rho*std::cos(CLHEP::twopi*ksi));
342 fPhotonAngleInIntegralY.push_back(fMeanPhotonAngleY+
344 rho*std::sin(CLHEP::twopi*ksi));
345 fPhotonAngleNormCoef[j]*=(1.+rho*rho*rho*rho)*norm;
350 if(fVirtualCollimatorTypeID == 1)
352 fInsideVirtualCollimator.push_back(1. >
353 std::sqrt((fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX)*
354 (fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX)/
355 fVirtualCollimatorAngularHalfWidthX2 +
356 (fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY)*
357 (fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY)/
358 fVirtualCollimatorAngularHalfWidthY2));
360 else if (fVirtualCollimatorTypeID == 2)
362 fInsideVirtualCollimator.push_back(
363 std::abs(fPhotonAngleInIntegralX[j]-fVirtualCollimatorAngularCenterX) <
364 fVirtualCollimatorAngularHalfWidthX&&
365 std::abs(fPhotonAngleInIntegralY[j]-fVirtualCollimatorAngularCenterY) <
366 fVirtualCollimatorAngularHalfWidthY);
368 else{fInsideVirtualCollimator.push_back(
true);}
371 fPhotonProductionCDF.resize(nmctotal+1);
372 std::fill(fPhotonProductionCDF.begin(), fPhotonProductionCDF.end(), 0.);
375 if (nmctotal>fNMCPhotons)
378 fFa.resize(nmctotal);
379 fSs.resize(nmctotal);
380 fSc.resize(nmctotal);
381 fSsx.resize(nmctotal);
382 fSsy.resize(nmctotal);
383 fScx.resize(nmctotal);
384 fScy.resize(nmctotal);
385 std::fill(fFa.begin(), fFa.end(), 0.);
386 std::fill(fSs.begin(), fSs.end(), 0.);
387 std::fill(fSc.begin(), fSc.end(), 0.);
388 std::fill(fSsx.begin(), fSsx.end(), 0.);
389 std::fill(fSsy.begin(), fSsy.end(), 0.);
390 std::fill(fScx.begin(), fScx.end(), 0.);
391 std::fill(fScy.begin(), fScy.end(), 0.);
398 std::vector<G4double> &vectorParticleAnglesX,
399 std::vector<G4double> &vectorParticleAnglesY,
400 std::vector<G4double> &vectorScatteringAnglesX,
401 std::vector<G4double> &vectorScatteringAnglesY,
402 std::vector<G4double> &vectorSteps,
410 G4double vxin =0.,vyin=0.,vxno=0.,vyno=0.;
413 G4double fa1=0.,faseBefore=0.,faseBeforedz=0.,faseBeforedzd2=0.;
414 G4double faseAfter=0.,fa2dfaseBefore2=0.;
420 std::size_t nparts=vectorParticleAnglesX.size();
422 if(imin==0) {kmin=1;}
425 G4double totalRadiationProbabilityPhj = 0.;
428 fTotalRadiationProbabilityAlongTrajectory.resize(nparts);
431 std::fill(fSpectrum.begin(), fSpectrum.end(), 0.);
434 std::vector<G4double> axt;
436 std::vector<G4double> ayt;
438 std::vector<G4double> dz;
441 for(std::size_t k=kmin;k<nparts;k++)
443 dz[k]=vectorSteps[k]/CLHEP::hbarc;
446 axt[k]=(vectorParticleAnglesX[k]-vectorScatteringAnglesX[k]-
447 vectorParticleAnglesX[k-1])/dz[k];
448 ayt[k]=(vectorParticleAnglesY[k]-vectorScatteringAnglesY[k]-
449 vectorParticleAnglesY[k-1])/dz[k];
457 G4double gammaInverse2 = mass*mass/(etotal*etotal);
459 G4double coefNormLogdNMC = fLogEdEmin/fNMCPhotons;
462 G4double coefNorm = CLHEP::fine_structure_const/(8*(CLHEP::pi2))*coefNormLogdNMC;
467 std::size_t nmctotal = fPhotonEnergyInIntegral.size();
468 for (std::size_t j=0;j<nmctotal;j++)
471 om = fPhotonEnergyInIntegral[j];
473 eprime2 = eprime*eprime;
474 e2pluseprime2 =e2+eprime2;
475 omprime=etotal*
om/eprime;
477 coefNormom2deprime2 = coefNorm*
om*
om/eprime2;
478 gammaInverse2om2 = gammaInverse2*
om*
om;
480 for(std::size_t k=kmin;k<nparts;k++)
483 vxin = vectorParticleAnglesX[k]-fPhotonAngleInIntegralX[j];
484 vyin = vectorParticleAnglesY[k]-fPhotonAngleInIntegralY[j];
486 vxno = vxin-vectorScatteringAnglesX[k];
487 vyno = vyin-vectorScatteringAnglesY[k];
490 faseBefore=omprimed2*(gammaInverse2+vxno*vxno+vyno*vyno);
492 faseBeforedz = faseBefore*dz[k];
493 faseBeforedzd2 = faseBeforedz/2.;
494 fFa[j]+=faseBeforedz;
495 fa1=fFa[j]-faseBeforedzd2;
496 dzmod=2*std::sin(faseBeforedzd2)/faseBefore;
499 fa2dfaseBefore2 = omprime*(axt[k]*vxno+ayt[k]*vyno)/(faseBefore*faseBefore);
502 faseAfter=omprimed2*(gammaInverse2+vxin*vxin+vyin*vyin);
504 skJ=1/faseAfter-1/faseBefore-fa2dfaseBefore2*dzmod;
505 skIx=vxin/faseAfter-vxno/faseBefore+dzmod*(axt[k]/faseBefore-
506 vxno*fa2dfaseBefore2);
507 skIy=vyin/faseAfter-vyno/faseBefore+dzmod*(ayt[k]/faseBefore-
508 vyno*fa2dfaseBefore2);
510 sinfa1 = std::sin(fa1);
511 cosfa1 = std::cos(fa1);
515 fSsx[j]+=sinfa1*skIx;
516 fSsy[j]+=sinfa1*skIy;
517 fScx[j]+=cosfa1*skIx;
518 fScy[j]+=cosfa1*skIy;
520 i2=fSsx[j]*fSsx[j]+fScx[j]*fScx[j]+fSsy[j]*fSsy[j]+fScy[j]*fScy[j];
521 j2=fSs[j]*fSs[j]+fSc[j]*fSc[j];
524 totalRadiationProbabilityPhj = coefNormom2deprime2*fPhotonAngleNormCoef[j]*
525 (i2*e2pluseprime2+j2*gammaInverse2om2);
526 fTotalRadiationProbabilityAlongTrajectory[k] += totalRadiationProbabilityPhj;
529 fPhotonProductionCDF[j+1] = fTotalRadiationProbabilityAlongTrajectory.back();
536 if((fIBinsSpectrum[j]<fNBinsSpectrum)&&fInsideVirtualCollimator[j])
537 {fSpectrum[fIBinsSpectrum[j]] += totalRadiationProbabilityPhj/
538 (
om*coefNormLogdNMC);}
542 fAccumSpectrum.push_back(fSpectrum);
544 return fTotalRadiationProbabilityAlongTrajectory.back();
549G4int G4BaierKatkov::FindVectorIndex(std::vector<G4double> &myvector,
G4double value)
551 auto iteratorbegin = myvector.begin();
552 auto iteratorend = myvector.end();
555 auto loweriterator = std::lower_bound(iteratorbegin, iteratorend, value);
557 return (
G4int)std::distance(iteratorbegin, loweriterator);
565 G4bool flagPhotonProduced =
false;
569 std::size_t nodeNumber = fAccumSpectrum.size()-1;
577 if (ksi< fTotalRadiationProbabilityAlongTrajectory.back())
583 G4int iphoton = FindVectorIndex(fPhotonProductionCDF,ksi1)-1;
587 fEph0 = fPhotonEnergyInIntegral[iphoton];
589 G4double photonAngleX = fPhotonAngleInIntegralX[iphoton];
590 G4double photonAngleY = fPhotonAngleInIntegralY[iphoton];
593 std::sqrt(1.+std::pow(std::tan(photonAngleX),2)+
594 std::pow(std::tan(photonAngleY),2));
597 PhMomentumDirection.set(momentumDirectionZ*std::tan(photonAngleX),
598 momentumDirectionZ*std::tan(photonAngleY),
603 std::vector<G4double> temporaryVector;
604 temporaryVector.assign(fTotalRadiationProbabilityAlongTrajectory.begin(),
605 fTotalRadiationProbabilityAlongTrajectory.end());
606 std::sort(temporaryVector.begin(), temporaryVector.end());
609 G4int iNode = FindVectorIndex(temporaryVector,ksi);
612 auto it = std::find_if(fTotalRadiationProbabilityAlongTrajectory.begin(),
613 fTotalRadiationProbabilityAlongTrajectory.end(),
615 {return std::abs(value - temporaryVector[iNode]) < DBL_EPSILON;});
616 iNode = (
G4int)std::distance(fTotalRadiationProbabilityAlongTrajectory.begin(), it);
619 nodeNumber = FindVectorIndex(fImax0,iNode*1.)-1;
624 fNewParticleEnergy = etotal-fEph0;
625 fNewParticleAngleX = fParticleAnglesX[iNode];
626 fNewParticleAngleY = fParticleAnglesY[iNode];
627 fNewGlobalTime = fGlobalTimes[iNode];
628 fNewParticleCoordinateXYZ = fParticleCoordinatesXYZ[iNode];
633 G4double pratio = fEph0/std::sqrt(etotal*etotal-mass*mass);
634 fNewParticleAngleX -= std::asin(pratio*std::sin(photonAngleX));
635 fNewParticleAngleY -= std::asin(pratio*std::sin(photonAngleY));
637 flagPhotonProduced =
true;
641 for (
G4int j=0;j<fNBinsSpectrum;j++)
643 fAccumTotalSpectrum[j] += fAccumSpectrum[nodeNumber][j];
646 if(fNPhotonsPerBin[j]==0)
648 fTotalSpectrum[j] = 0;
652 fTotalSpectrum[j] = fAccumTotalSpectrum[j]/fNPhotonsPerBin[j]*fItrajectories;
656 return flagPhotonProduced;
700 G4bool flagPhotonProduced =
false;
703 fParticleAnglesX.push_back(angleX);
704 fParticleAnglesY.push_back(angleY);
705 fScatteringAnglesX.push_back(angleScatteringX);
706 fScatteringAnglesY.push_back(angleScatteringY);
707 fSteps.push_back(step);
708 fGlobalTimes.push_back(globalTime);
709 fParticleCoordinatesXYZ.push_back(coordinateXYZ);
712 if((imax==fImin0+fNSmallTrajectorySteps)||flagEndTrajectory)
718 G4double radiationAngleLimit=fRadiationAngleFactor*mass/etotal;
720 SetPhotonSamplingParameters(etotal-mass,
721 *std::min_element(fParticleAnglesX.begin(),
722 fParticleAnglesX.end())-radiationAngleLimit,
723 *std::max_element(fParticleAnglesX.begin(),
724 fParticleAnglesX.end())+radiationAngleLimit,
725 *std::min_element(fParticleAnglesY.begin(),
726 fParticleAnglesY.end())-radiationAngleLimit,
727 *std::max_element(fParticleAnglesY.begin(),
728 fParticleAnglesY.end())+radiationAngleLimit);
732 GeneratePhotonSampling();
737 fTotalRadiationProbability = RadIntegral(etotal,mass,
738 fParticleAnglesX,fParticleAnglesY,
739 fScatteringAnglesX,fScatteringAnglesY,
744 fImax0.push_back(imax*1.);
748 if(fTotalRadiationProbability>fSinglePhotonRadiationProbabilityLimit||
753 flagPhotonProduced = SetPhotonProductionParameters(etotal,mass);
762 return flagPhotonProduced;
770 PhMomentumDirection,fEph0);
Definition of the G4BaierKatkov class This class is designed for the calculation of radiation probabi...
G4double G4Log(G4double x)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void GeneratePhoton(G4FastStep &fastStep)
void SetSpectrumEnergyRange(G4double emin, G4double emax, G4int numberOfBins)
void AddStatisticsInPhotonEnergyRegion(G4double emin, G4double emax, G4int timesPhotonStatistics)
G4bool DoRadiation(G4double etotal, G4double mass, G4double angleX, G4double angleY, G4double angleScatteringX, G4double angleScatteringY, G4double step, G4double globalTime, G4ThreeVector coordinateXYZ, G4bool flagEndTrajectory=false)
G4Track * CreateSecondaryTrack(const G4DynamicParticle &, G4ThreeVector, G4ThreeVector, G4double, G4bool localCoordinates=true)