54 #include "G4SeltzerBergerModel95.hh"
55 #include "G4Electron.hh"
56 #include "G4Positron.hh"
58 #include "Randomize.hh"
59 #include "G4Material.hh"
60 #include "G4Element.hh"
61 #include "G4ElementVector.hh"
62 #include "G4ProductionCutsTable.hh"
63 #include "G4ParticleChangeForLoss.hh"
64 #include "G4LossTableManager.hh"
65 #include "G4ModifiedTsai.hh"
67 #include "G4Physics2DVector95.hh"
78 G4SeltzerBergerModel95::G4SeltzerBergerModel95(
const G4ParticleDefinition*
p,
80 : G4eBremsstrahlungRelModel95(p,name)
82 SetLowEnergyLimit(0.0);
89 G4SeltzerBergerModel95::~G4SeltzerBergerModel95()
91 for(
size_t i=0;
i<101; ++
i) {
delete dataSB[
i]; }
96 void G4SeltzerBergerModel95::Initialise(
const G4ParticleDefinition* p,
97 const G4DataVector&
cuts)
101 char*
path = getenv(
"G4LEDATA");
104 const G4ElementTable* theElmTable = G4Element::GetElementTable();
105 size_t numOfElm = G4Element::GetNumberOfElements();
107 for(
size_t i=0;
i<numOfElm; ++
i) {
108 G4int
Z = G4int(((*theElmTable)[
i])->GetZ());
110 else if(Z > 100) { Z = 100; }
113 if(!dataSB[Z]) { ReadData(Z, path); }
117 G4eBremsstrahlungRelModel95::Initialise(p, cuts);
122 void G4SeltzerBergerModel95::ReadData(
size_t Z,
const char* path)
127 if(dataSB[Z]) {
return; }
131 datadir = getenv(
"G4LEDATA");
133 G4Exception(
"G4SeltzerBergerModel95::ReadData() Environment variable G4LEDATA not defined");
139 std::ostringstream ost;
140 ost << datadir <<
"/brem_SB/br" <<
Z;
141 std::ifstream
fin(ost.str().c_str());
142 if( !
fin.is_open()) {
144 G4cout <<
"Bremsstrahlung data file <" << ost.str().c_str()
145 <<
"> is not opened!" << G4endl;
146 G4Exception(
"G4SeltzerBergerModel95::ReadData() G4LEDATA version should be G4EMLOW6.23 or later.");
151 G4Physics2DVector95*
v =
new G4Physics2DVector95();
152 if(v->Retrieve(
fin)) { dataSB[
Z] =
v; }
155 G4cout <<
"Bremsstrahlung data file <" << ost.str().c_str()
156 <<
"> is not retrieved!" << G4endl;
157 G4Exception(
"G4SeltzerBergerModel95::ReadData() G4LEDATA version should be G4EMLOW6.23 or later.");
165 G4double G4SeltzerBergerModel95::ComputeDXSectionPerAtom(G4double gammaEnergy)
168 if(gammaEnergy < 0.0 || kinEnergy <= 0.0) {
return 0.0; }
169 G4double
x = gammaEnergy/kinEnergy;
170 G4double
y =
log(kinEnergy/MeV);
171 G4int Z = G4int(currentZ);
174 if(!dataSB[Z]) { ReadData(Z); }
175 G4double invb2 = totalEnergy*totalEnergy/(kinEnergy*(kinEnergy + 2*particleMass));
176 G4double
cross = dataSB[
Z]->Value(x,y)*invb2*millibarn/bremFactor;
179 if(1 - x < 1.
e-20) { cross = 0.0; }
181 G4double invbeta1 =
sqrt(invb2);
182 G4double e2 = kinEnergy - gammaEnergy;
183 G4double invbeta2 = (e2 + particleMass)/
sqrt(e2*(e2 + 2*particleMass));
184 cross *=
exp(twopi*fine_structure_const*currentZ*(invbeta1 - invbeta2));
194 G4SeltzerBergerModel95::SampleSecondaries(std::vector<G4DynamicParticle*>* vdp,
195 const G4MaterialCutsCouple* couple,
196 const G4DynamicParticle* dp,
200 G4double kineticEnergy = dp->GetKineticEnergy();
202 G4double emax =
std::min(maxEnergy, kineticEnergy);
203 if(cut >= emax) {
return; }
205 SetupForMaterial(particle, couple->GetMaterial(), kineticEnergy);
207 const G4Element*
elm =
208 SelectRandomAtom(couple,particle,kineticEnergy,cut,emax);
209 SetCurrentElement(elm->GetZ());
210 G4int Z = G4int(currentZ);
212 totalEnergy = kineticEnergy + particleMass;
213 densityCorr = densityFactor*totalEnergy*totalEnergy;
214 G4double totMomentum =
sqrt(kineticEnergy*(totalEnergy + electron_mass_c2));
215 G4ThreeVector direction = dp->GetMomentumDirection();
222 G4double xmin =
log(cut*cut + densityCorr);
223 G4double xmax =
log(emax*emax + densityCorr);
224 G4double y =
log(kineticEnergy/MeV);
226 G4double gammaEnergy,
v;
229 G4double vmax = dataSB[
Z]->Value(cut/kineticEnergy, y);
230 if(
isElectron && Z > 12 && kineticEnergy < 100*keV) {
231 if((Z < 41 && kineticEnergy < 10*keV) ||
232 (Z >= 41 && Z < 61 && kineticEnergy < 50*keV) ||
235 v = 1.05*dataSB[
Z]->Value(emax/kineticEnergy, y);
236 if(v > vmax) { vmax =
v; }
243 G4double x =
exp(xmin + G4UniformRand()*(xmax - xmin)) - densityCorr;
244 if(x < 0.0) { x = 0.0; }
245 gammaEnergy =
sqrt(x);
246 G4double x1 = gammaEnergy/kineticEnergy;
247 v = dataSB[
Z]->Value(x1, y);
250 if(1 - x1 < 1.
e-20) { v = 0.0; }
252 G4double e1 = kineticEnergy -
cut;
253 G4double invbeta1 = (e1 + particleMass)/
sqrt(e1*(e1 + 2*particleMass));
254 G4double e2 = kineticEnergy - gammaEnergy;
255 G4double invbeta2 = (e2 + particleMass)/
sqrt(e2*(e2 + 2*particleMass));
256 v *=
exp(twopi*fine_structure_const*currentZ*(invbeta1 - invbeta2));
260 if ( v > 1.5*vmax ) {
261 G4cout <<
"### G4SeltzerBergerModel95 Warning: Majoranta exceeded! "
262 << v <<
" > " << vmax
263 <<
" Egamma(MeV)= " << gammaEnergy
264 <<
" Ee(MeV)= " << kineticEnergy
265 <<
" Z= " << Z <<
" " << particle->GetParticleName()
269 }
while (v < vmax*G4UniformRand());
276 GetAngularDistribution()->PolarAngle(totalEnergy,totalEnergy-gammaEnergy,Z);
278 G4double sint =
sin(theta);
279 G4double
phi = twopi * G4UniformRand();
280 G4ThreeVector gammaDirection(sint*
cos(phi),sint*
sin(phi),
cos(theta));
281 gammaDirection.rotateUz(direction);
284 G4DynamicParticle*
g =
285 new G4DynamicParticle(theGamma,gammaDirection,gammaEnergy);
288 G4ThreeVector
dir = totMomentum*direction - gammaEnergy*gammaDirection;
289 direction = dir.unit();
292 G4double finalE = kineticEnergy - gammaEnergy;
295 if(gammaEnergy > SecondaryThreshold()) {
296 fParticleChange->ProposeTrackStatus(fStopAndKill);
297 fParticleChange->SetProposedKineticEnergy(0.0);
298 G4DynamicParticle* el =
299 new G4DynamicParticle(const_cast<G4ParticleDefinition*>(particle),
305 fParticleChange->SetProposedMomentumDirection(direction);
306 fParticleChange->SetProposedKineticEnergy(finalE);
const double Z[kNumberCalorimeter]
Sin< T >::type sin(const T &t)
Geom::Theta< T > theta() const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
const TString datadir("/src/Fireworks/Core/")
bool isElectron(const Candidate &part)
Cos< T >::type cos(const T &t)
Basic3DVector cross(const Basic3DVector &v) const
Vector product, or "cross" product, with a vector of same type.