50 #define S_STREAM std::istringstream
53 #define S_STREAM std::istrstream
81 sprintf(buf,
"monoenergetic %g MeV",E);
85 EGS_Float expectedAverage()
const {
88 EGS_Float maxEnergy()
const {
103 static bool have_x =
false;
104 static EGS_Float the_x;
109 EGS_Float r = sqrt(-2*log(1-rndm->
getUniform()));
110 EGS_Float cphi, sphi;
145 if (Eo <= 0)
egsFatal(
"EGS_GaussianSpectrum: attempt to construct "
146 "a spectrum with a negative mean energy (%g)\n",Eo);
148 sigma = -sigma*0.4246609;
152 sprintf(buf,
"Gaussian spectrum with Eo = %g and sigma = %g",Eo,sigma);
154 if (Eo - 5*sigma > 0) {
162 EGS_Float expectedAverage()
const {
165 EGS_Float maxEnergy()
const {
172 E = Eo + sigma*getGaussianRN(rndm);
174 while (E <= 0 || E > Emax);
222 sleft(sig_left), sright(sig_right) {
224 sleft = -sleft*0.4246609;
227 sright= -sright*0.4246609;
229 Emax = Eo + 4*sright;
230 if (Eo - 4*sleft < 0)
egsWarning(
"EGS_DoubleGaussianSpectrum: "
231 "for Eo=%g, sigma=%g there will be negative energy sampled\n");
232 p = sleft/(sleft + sright);
234 sprintf(buf,
"Double Gaussian spectrum with Eo = %g sig(left) = %g"
235 " and sig(right) = %g",Eo,sleft,sright);
239 EGS_Float maxEnergy()
const {
242 EGS_Float expectedAverage()
const {
243 return Eo + sqrt(2/M_PI)*(sright-sleft);
259 E = Eo-sleft*fabs(getGaussianRN(rndm));
265 E = Eo+sright*fabs(getGaussianRN(rndm));
298 Emin(emin), Emax(emax), de(emax - emin) {
300 sprintf(buf,
"Uniform spectrum with Emin = %g Emax = %g",Emin,Emax);
304 EGS_Float maxEnergy()
const {
307 EGS_Float expectedAverage()
const {
308 return (Emin+Emax)/2;
401 EGS_Float maxEnergy()
const {
402 return table->getMaximum();
404 EGS_Float expectedAverage()
const {
405 return table->getAverage();
411 void setType(
int Type,
const char *fname) {
413 type =
"tabulated line spectrum";
415 else if (Type == 1) {
416 type =
"tabulated histogram spectrum";
419 type =
"tabulated spectrum";
422 type +=
" defined in ";
426 type +=
" defined inline";
431 return table->
sample(rndm);
442 istream &skipsep(istream &in) {
444 for (EGS_I64 loopCount=0; loopCount<=
loopMax; ++loopCount) {
446 egsFatal(
"skipsep: Too many iterations were required! Input may be invalid, or consider increasing loopMax.");
450 if (in.eof() || in.fail() || !in.good()) {
464 static char spec_msg1[] =
"EGS_BaseSpectrum::createSpectrum:";
472 bool delete_it =
false;
473 if (!input->
isA(
"spectrum")) {
476 egsWarning(
"%s no 'spectrum' input!\n",spec_msg1);
482 int err = inp->
getInput(
"type",stype);
484 egsWarning(
"%s wrong/missing 'type' input\n",spec_msg1);
491 if (inp->
compare(stype,
"monoenergetic")) {
494 if (err)
egsWarning(
"%s wrong/missing 'energy' input for a "
495 "monoenergetic spectrum\n",spec_msg1);
500 else if (inp->
compare(stype,
"Gaussian")) {
501 EGS_Float Eo, sig, fwhm;
502 int err1 = inp->
getInput(
"mean energy",Eo);
503 int err2 = inp->
getInput(
"sigma",sig);
504 int err3 = inp->
getInput(
"fwhm",fwhm);
505 if (err1 || (err2 && err3)) {
506 if (err1)
egsWarning(
"%s wrong/missing 'mean energy' input"
507 " for a Gaussian spectrum\n",spec_msg1);
508 else egsWarning(
"%s wrong/missing 'sigma' and 'FWHM' input for a "
509 "Gaussian spectrum\n",spec_msg1);
513 if (Eo <= 0)
egsWarning(
"%s mean energy must be positive but your"
514 " input was %g\n",Eo);
517 if (sig <= 0)
egsWarning(
"%s sigma must be positive"
518 " but your input was %g\n",spec_msg1,sig);
524 if (fwhm <= 0)
egsWarning(
"%s FWHM must be positive"
525 " but your input was %g\n",spec_msg1,fwhm);
533 else if (inp->
compare(stype,
"Double Gaussian")) {
535 vector<EGS_Float> sig, fwhm;
536 int err1 = inp->
getInput(
"mean energy",Eo);
537 int err2 = inp->
getInput(
"sigma",sig);
538 int err3 = inp->
getInput(
"fwhm",fwhm);
539 if (!err1 && Eo <= 0) {
542 if (!err2 && sig.size() != 2) {
545 if (!err2 && (sig[0] <= 0 || sig[1] <= 0)) {
548 if (!err3 && fwhm.size() != 2) {
551 if (!err3 && (fwhm[0] <= 0 || fwhm[1] <= 0)) {
554 if (err1 || (err2 && err3)) {
555 if (err1)
egsWarning(
"%s wrong/missing 'mean energy' input"
556 " for a Double Gaussian spectrum\n",spec_msg1);
557 if (err2 && err3)
egsWarning(
"%s wrong/missing 'sigma' and 'FWHM'"
558 " input for a Double Gaussian spectrum\n",spec_msg1);
561 if (!err2 && !err3)
egsWarning(
"%s found 'sigma' and 'FWHM' "
562 "input, using 'sigma'\n",spec_msg1);
571 else if (inp->
compare(stype,
"uniform")) {
572 vector<EGS_Float> range;
573 EGS_Float Emin, Emax;
574 int err1 = inp->
getInput(
"range",range);
575 int err2 = inp->
getInput(
"minimum energy",Emin);
576 int err3 = inp->
getInput(
"maximum energy",Emax);
577 if (!err2 && !err3 && Emin > Emax) {
578 egsWarning(
"%s Emin (%g) is greater than Emax (%g)?\n",
579 spec_msg1,Emin,Emax);
583 if (err1 && err2 && err3)
egsWarning(
"%s wrong/missing 'range' and"
584 " 'minimum/maximum energy' input\n",spec_msg1);
586 if (!err2 && !err3) {
590 if (range[0] < range[1]) {
599 else if (inp->
compare(stype,
"tabulated spectrum")) {
601 err = inp->
getInput(
"spectrum file",spec_file);
605 ifstream sdata(spec_file.c_str());
606 if (!sdata)
egsWarning(
"%s failed to open spectrum file %s\n",
607 spec_msg1,spec_file.c_str());
610 sdata.getline(title,1023);
611 if (sdata.eof() || sdata.fail() || !sdata.good()) {
612 egsWarning(
"%s error while reading title of spectrum file"
613 "%s\n",spec_msg1,spec_file.c_str());
619 if (sdata.eof() || sdata.fail() || !sdata.good()) {
620 egsWarning(
"%s error while reading spectrum type and "
621 "number of bins in spectrum file %s\n",
622 spec_msg1,spec_file.c_str());
630 sdata >> nbin >> skipsep >> dum >> skipsep >> mode;
631 if (sdata.eof() || sdata.fail() || !sdata.good()) {
632 egsWarning(
"%s error while reading spectrum type and "
633 "number of bins in spectrum file %s\n",
634 spec_msg1,spec_file.c_str());
641 egsWarning(
"%s nbin in a spectrum must be at least 2\n"
642 " you have %d in the spectrum file %s\n",
643 spec_msg1,nbin,spec_file.c_str());
649 if (mode < 0 || mode > 3) {
650 egsWarning(
"%s unknown spectrum type %d in spectrum file"
651 " %s\n",spec_msg1,mode,spec_file.c_str());
657 EGS_Float *en_array, *f_array;
659 f_array =
new EGS_Float [nbin];
660 if (mode == 0 || mode == 1) {
661 en_array =
new EGS_Float [nbin+1];
666 en_array =
new EGS_Float [nbin];
669 for (
int j=0; j<nbin; j++) {
670 sdata >> en_array[ibin++] >> skipsep >> f_array[j];
671 if (sdata.eof() || sdata.fail() || !sdata.good()) {
672 egsWarning(
"%s error on line %d in spectrum file %s\n",
673 spec_msg1,j+2,spec_file.c_str());
681 if (mode != 2 && ibin > 1) {
682 if (en_array[ibin-1] <= en_array[ibin-2]) {
683 egsWarning(
"%s energies must be in increasing "
684 "order.\n This is not the case for input on "
685 "lines %d,%d in spectrum file %s\n",
686 spec_msg1,j+2,j+1,spec_file.c_str());
694 f_array[j]/=(en_array[ibin-1]-en_array[ibin-2]);
701 else if (mode == 3) {
704 int nb = itype == 1 ? nbin+1 : nbin;
712 vector<EGS_Float> eners, probs;
714 int err1 = inp->
getInput(
"energies",eners);
715 int err2 = inp->
getInput(
"probabilities",probs);
716 int err3 = inp->
getInput(
"spectrum mode",mode);
718 err3 = inp->
getInput(
"spectrum type",mode);
721 egsWarning(
"%s wrong/missing 'spectrum mode' input\n",spec_msg1);
728 if (mode < 0 || mode > 3) {
730 " %s\n",spec_msg1,mode,spec_file.c_str());
739 else if (mode == 3) {
744 if (err1)
egsWarning(
"%s wrong/missing 'energies' input\n",
746 if (err2)
egsWarning(
"%s wrong/missing 'probabilities' "
747 "input\n",spec_msg1);
750 if (itype == 1 && probs.size() != eners.size()-1)
751 egsWarning(
"%s for spectrum type 1 the number of energies"
752 " must be the number of probabilities + 1\n",
754 else if ((itype == 0 || itype == 2) &&
755 probs.size() != eners.size())
756 egsWarning(
"%s for spectrum types 0 and 2 the number of "
757 "energies must be equal to the number of probabilities\n",
760 int nbin = eners.size();
761 int nbin1 = itype == 1 ? nbin-1 : nbin;
762 EGS_Float *x =
new EGS_Float [nbin],
763 *f =
new EGS_Float [nbin1];
769 for (
int j=0; j<nbin1; j++) {
770 x[ibin] = eners[ibin];
772 f[j] = mode == 0 ? probs[j]/(eners[ibin-1]-eners[ibin-2]) : probs[j];
773 if (itype != 0 && ibin > 1) {
774 if (x[ibin-1] <= x[ibin-2]) {
776 "increasing order\n This is not the case"
777 " for inputs %d and %d (%g,%g) %d\n",
778 spec_msg1,ibin-2,ibin-1,x[ibin-2],x[ibin-1],
797 egsWarning(
"%s unknown spectrum type %s\n",spec_msg1,stype.c_str());
A class for sampling random values from a given probability distribution using the alias table techni...
EGS_Float sample(EGS_RandomGenerator *rndm) const
Get a random point from this table using the RNG rndm.
Base class for energy spectra. All energy spectra in the EGSnrc C++ class library are derived from th...
static EGS_BaseSpectrum * createSpectrum(EGS_Input *inp)
Create and return a pointer to a spectrum object from the information pointed to by inp.
A double-Gaussian spectrum.
EGS_Float sright
The width of the spectrum right of Eo.
EGS_Float Eo
The mean energy.
EGS_DoubleGaussianSpectrum(EGS_Float mean_energy, EGS_Float sig_left, EGS_Float sig_right)
Construct a double-Gaussian spectrum with mean energy mean_energy and widths sig_left and sig_right.
EGS_Float Emax
The maximum energy.
EGS_Float sleft
The width of the spectrum left of Eo.
EGS_GaussianSpectrum(EGS_Float mean_energy, EGS_Float Sigma)
Construct a Gaussian spectrum with mean energy mean_energy and width Sigma.
EGS_Float sigma
The Gaussian width.
EGS_Float Emax
The maximum energy.
EGS_Float Eo
The mean energy.
A monoenergetic particle spectrum.
EGS_Float E
The spectrum energy.
EGS_MonoEnergy(EGS_Float energy)
Construct a monoenergetic spectrum with energy energy.
Base random number generator class. All random number generators should be derived from this class.
void getAzimuth(EGS_Float &cphi, EGS_Float &sphi)
Sets cphi and sphi to the cosine and sine of a random angle uniformely distributed between 0 and .
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
EGS_AliasTable * table
The alias table object used to sample energies.
EGS_TabulatedSpectrum(int N, const EGS_Float *x, const EGS_Float *f, int Type=1, const char *fname=0)
Construct a tabulated spectrum from the energies x and the probabilities f.
EGS_AliasTable class header file.
EGS_BaseSource class header file.
#define EGS_EXPORT
Export symbols from the egspp library.
Attempts to fix broken math header files.
EGS_RandomGenerator class header file.
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
string egsExpandPath(const string &aname)
Expands first environment variable found in a file name.
const EGS_I64 loopMax
The maximum number of iterations for near-infinite loops.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.