38 #ifndef EGS_RADIONUCLIDE_SOURCE_
39 #define EGS_RADIONUCLIDE_SOURCE_
56 #ifdef BUILD_RADIONUCLIDE_SOURCE_DLL
57 #define EGS_RADIONUCLIDE_SOURCE_EXPORT __declspec(dllexport)
59 #define EGS_RADIONUCLIDE_SOURCE_EXPORT __declspec(dllimport)
61 #define EGS_RADIONUCLIDE_SOURCE_LOCAL
65 #ifdef HAVE_VISIBILITY
66 #define EGS_RADIONUCLIDE_SOURCE_EXPORT __attribute__ ((visibility ("default")))
67 #define EGS_RADIONUCLIDE_SOURCE_LOCAL __attribute__ ((visibility ("hidden")))
69 #define EGS_RADIONUCLIDE_SOURCE_EXPORT
70 #define EGS_RADIONUCLIDE_SOURCE_LOCAL
95 vector<BetaRecordLeaf *> myBetas = decays->getBetaRecords();
97 for (vector<BetaRecordLeaf *>::iterator beta = myBetas.begin();
98 beta != myBetas.end(); beta++) {
101 if ((*beta)->getCharge() == 1 &&
102 (*beta)->getPositronIntensity() == 0) {
106 unsigned short int daughterZ = (*beta)->getZ();
109 "Energy, Z, A, forbidden: %f %d %d %d\n",
110 (*beta)->getFinalEnergy(), daughterZ,
111 (*beta)->getAtomicWeight(), (*beta)->getForbidden()
115 EGS_Float *e =
new EGS_Float [nbin];
116 EGS_Float *spec =
new EGS_Float [nbin];
117 EGS_Float *spec_y =
new EGS_Float [nbin];
119 double de, s_y, factor, se_y;
125 emax = (*beta)->getFinalEnergy();
126 zzz[0] = (double)daughterZ;
127 rmass = (*beta)->getAtomicWeight();
134 if (daughterZ == 18 && (*beta)->getCharge() == -1) {
139 else if (daughterZ == 54 && emax < 0.154 && emax > 0.150) {
144 else if (daughterZ == 56 && emax > 1.173 && emax < 1.177) {
149 else if (daughterZ == 82) {
154 else if (daughterZ == 84) {
158 lamda[0] = (*beta)->getForbidden();
163 if ((*beta)->getCharge() == 1) {
176 de=((int)(etop[0]*10.0+1)/10.)/nbin;
180 for (
int ib=0; ib<nbin; ib++) {
187 for (
int ib=0; ib<nbin; ib++) {
190 sp(e[ib],spec_y[ib],factor);
197 se_y=se_y+spec_y[ib]*e[ib];
200 for (
int ib=0; ib<nbin; ib++) {
201 spec[ib]=1/de*(spec_y[ib]/s_y);
206 (*beta)->setSpectrum(bspec);
209 if (outputBetaSpectra ==
"yes") {
212 fname +=
"_" + decays->radionuclide +
"_" + std::to_string(emax);
219 egsInformation(
"EGS_RadionuclideBetaSpectrum: Outputting beta spectrum to file: %s\n", fname.c_str());
222 specStream.open(fname.c_str());
223 for (
int ib=0; ib<nbin; ib++) {
224 spec[ib]=1/de*(spec_y[ib]/s_y);
225 specStream << e[ib] <<
" " << spec[ib] << endl;
234 complex<double> cgamma(complex<double> z) {
236 static const int g=7;
237 static const double pi = 3.1415926535897932384626433832795028841972;
238 static const double p[g+2] = {0.99999999999980993, 676.5203681218851,
243 -0.13857109526572012,
244 9.9843695780195716e-6,
245 1.5056327351493116e-7
249 return pi / (sin(pi*z)*cgamma(
double(1.0)-z));
253 complex<double> x=p[0];
254 for (
int i=1; i<g+2; i++) {
255 x += p[i]/(z+complex<double>(i,0));
257 complex<double> t = z + (g + double(0.5));
259 return double(sqrt(2.*pi)) * pow(t,z+
double(0.5)) * exp(-t) * x;
262 complex<double> clgamma(complex<double> z) {
263 complex<double> u, v, h, p, r;
265 static const double pi = 3.1415926535897932384626433832795028841972;
266 static const double c1 = 9.189385332046727e-1;
267 static const double c2 = 1.144729885849400;
268 static const double c[10] = {8.333333333333333e-2,
269 -2.777777777777777e-3,
270 7.936507936507936e-4,
271 -5.952380952380952e-4,
272 8.417508417508417e-4,
273 -1.917526917526917e-3,
274 6.410256410256410e-3,
275 -2.955065359477124e-2,
276 1.796443723688305e-1,
280 static const double hf = 0.5;
286 if (y == 0 && -abs(x) ==
int(x)) {
292 u = double(1.) - complex<double>(x, ya);
295 u = complex<double>(x, ya);
305 for (
int i=1; i<=6-int(ur); i++) {
307 u = complex<double>(ur, ui);
309 a = a + atan2(ui, ur);
311 h = complex<double>(hf * log(pow(real(h),2) + pow(imag(h),2)),
317 r = double(1.) / pow(u,2);
320 for (
int i=8; i>=1; i--) {
324 h = c1 + (u-hf)*log(u) - u + (c[0]+p) / u - h;
327 ur = double(
int(x)) - 1.;
330 double t = exp(-x-x);
332 t = x + hf * log(t*pow(a,2)+pow(hf*(1.-t),2));
333 a = atan2(cos(ui)*tanh(x),a) - ur*pi;
334 h = c2 - complex<double>(t,a) - h;
344 void slfact(
double p,
double z,
double radf,
double xl[4]) {
347 double dfac[4]= {1.0, 3.0, 15.0, 105.0};
348 double pi,c137,az,w,rad,pr,y,x1,gk,bb,cc,dd,x2;
360 for (
int k=1; k<=4; k++) {
362 gk = sqrt(k*k-az*az);
363 x1 = pow((pow(p,k-1)/dfac[k-1]),2);
365 aa = clgamma(complex<double>(gk,y));
366 double aa_real = real(aa);
368 bb=lgamma((
double)k);
369 cc=lgamma(2.0*k +1.0);
370 dd=lgamma(2.0*gk+1.0);
373 pow(2.0*pr, 2.0*(gk-k)) *
374 exp(pi*y+2.0*(aa_real+cc-bb-dd)) *
379 az*pr*(2.0*w*(2.0*k+1.0)/(p*k*(2.0*gk+1.0)) -
380 2.0*p*gk/(w*k*(2.0*gk+1.0))) -
381 2.0*k*pr*pr/((2.0*k+1.0)*(k+gk));
382 xl[k-1] = x1*ff[k-1]/ff[0]*x2;
388 void bsp(
double e,
double &bspec,
double &factor) {
411 double pi,c137,zab,v,z,x,w,psq,p,y,qsq,g,cab,f,radf;
426 v = 1.13*pow(zab,1.333)/pow(c137,2);
436 psq = w*w-double(1.0);
440 qsq = 3.83*pow(emax-e,2);
445 g = qsq*2.0*pi*pow(z,(2.0*x-1.0));
449 a = complex<double>(x,y);
452 f = pow(psq,x-1.0)*exp(pi*y)*pow(cab,2);
462 radf = 1.2*pow(rmass,0.333);
463 slfact(p,zz,radf,xl);
466 bspec = g*(qsq*xl[0]+9.0*xl[1]);
470 bspec = g*(pow(qsq,2)*xl[0]+30.0*qsq*xl[1]+225.0*xl[2]);
474 bspec = g*(pow(qsq,3.0)*xl[0]+63.0*pow(qsq,2)*xl[1]+
475 1575.0*qsq*xl[2] + 11025.0*xl[3]);
485 bspec = bspec*(qsq*xl[0]+20.07*xl[1]);
490 bspec = bspec*(psq+10.0*qsq);
495 bspec = bspec*(qsq*xl[0]+0.045*xl[1]);
500 bspec = bspec*(1.0-1.677*e+ 2.77*e*e);
505 bspec = bspec*(1.78-2.35*e+e*e);
513 void sp(
double e,
double &spec,
double &factor) {
518 for (
int icomp=0; icomp<ncomps; icomp++) {
523 spec= spec+bspec*rel[icomp]/area[icomp];
529 double zz,emax,rmass;
530 double zzz[9],etop[9],rel[9],area[9],lamda[9];
657 const EGS_Float relativeActivity,
const string relaxType,
const string outputBetaSpectra,
const bool scoreAlphasLocally,
const bool allowMultiTransition);
702 return spectrumWeight;
707 spectrumWeight = newWeight;
734 void printSampledEmissions();
740 bool storeState(ostream &data)
const {
744 bool setState(istream &data) {
748 void resetCounter() {
752 totalGammaEnergy = 0;
761 vector<BetaRecordLeaf *> myBetas;
762 vector<AlphaRecord *> myAlphas;
763 vector<GammaRecord *> myGammas,
765 myUncorrelatedGammas;
766 vector<LevelRecord *> myLevels;
767 vector<double> xrayIntensities,
771 vector<EGS_I64> numSampledXRay,
773 vector<const LevelRecord *> multiTransitions;
777 unsigned int emissionType;
778 EGS_Float currentTime,
784 string relaxationType;
785 bool scoreAlphasLocal;
998 if (!baseSource->deref()) {
1002 for (vector<EGS_RadionuclideSpectrum * >::iterator it =
1004 it!=decays.end(); it++) {
1013 int &q,
int &latch, EGS_Float &E, EGS_Float &wt,
1023 return (ishower+1)*(baseSource->getFluence()/sCount);
1033 return lastDisintTime;
1043 return experimentTime;
1051 unsigned int getEmissionType()
const {
1052 return emissionType;
1057 egsInformation(
"\n======================================================\n");
1059 for (
unsigned int i=0; i<decays.size(); ++i) {
1060 decays[i]->printSampledEmissions();
1063 egsInformation(
"======================================================\n\n");
1105 vector<EGS_Ensdf *> decayEnsdf;
1106 for (
auto dec: decays) {
1107 decayEnsdf.push_back(dec->getRadionuclideEnsdf());
1124 vector<int> q_allowed;
1125 vector<EGS_RadionuclideSpectrum *> decays;
1129 bool disintegrationOccurred;
1136 unsigned int emissionType;
A class for sampling random values from a given probability distribution using the alias table techni...
Base class for advanced EGSnrc C++ applications.
static EGS_Application * activeApplication()
Get the active application.
const string & getOutputFile() const
Returns the base name of the output file(s)
const string & getAppDir() const
Returns the absolute path to the user code directory.
Base source class. All particle sources must be derived from this class.
virtual bool addState(istream &data_in)
Add data from the stream data_in to the source state.
virtual void resetCounter()
Reset the source state.
virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, int &q, int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u)=0
Sample the next source particle from the source probability distribution.
virtual bool setState(istream &data_in)
Set the source state based on data from the stream data_in.
virtual vector< EGS_Ensdf * > getRadionuclideEnsdf()
Get the radionuclide ENSDF object from the source.
virtual bool storeState(ostream &data_out) const
Store the source state into the stream data_out.
The ensdf class for reading ensdf format data files.
Beta spectrum generation for EGS_RadionuclideSpectrum.
EGS_RadionuclideBetaSpectrum(EGS_Ensdf *decays, const string outputBetaSpectra)
Construct beta spectra for a radionuclide.
double getTime() const
Returns the emission time of the most recent particle.
EGS_Float getEmax() const
Returns the maximum energy out of all the spectra.
void printSampledEmissions()
Outputs the emission stats of the spectra.
EGS_Float getFluence() const
Returns the current fluence (number of disintegrations)
bool isValid() const
Checks the validity of the source.
~EGS_RadionuclideSource()
Destructor.
double getLastTime() const
Returns the time of the last emission for decay.
double getExperimentTime() const
Get the total possible length of the experiment that is being modelled.
EGS_I64 getShowerIndex() const
Returns the shower index of the most recent particle.
unsigned int getEmissionType() const
Get the emission type of the most recent source particle.
~EGS_RadionuclideSpectrum()
Destructor.
EGS_Float getSpectrumWeight() const
Get the relative weight assigned to this spectrum.
EGS_Float maxEnergy() const
Returns the maximum energy that may be emitted.
EGS_I64 getShowerIndex() const
Get the shower index of the most recent emission.
double getTime() const
Get the emission time of the most recent emission.
EGS_Float getEdep() const
Get energy that should be deposited locally from relaxations/alphas.
void setSpectrumWeight(EGS_Float newWeight)
Set the relative weight assigned to this spectrum.
int getCharge() const
Get the charge of the most recent emission.
Base random number generator class. All random number generators should be derived from this class.
A class representing 3D vectors.
EGS_Application class header file.
EGS_BaseGeometry class header file.
EGS_BaseSource class header file.
The ensdf implementation.
#define EGS_EXPORT
Export symbols from the egspp library.
Attempts to fix broken math header files.
EGS_RandomGenerator class header file.
EGS_BaseShape and shape classes header file.
EGS_Vector methods for the manipulation of 3D vectors in cartesian co-ordinates.
bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n)
Writes the 64 bit integer n to the output stream data and returns true on success,...
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
bool egsIsAbsolutePath(const string &path)
Does the string path represent an absolute path name?
bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n)
Reads a 64 bit integer from the stream data and assigns it to n. Returns true on success,...
string egsJoinPath(const string &first, const string &second)
Join two path variables (or a path and a file name) using the platform specific directory separator a...