EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_base_source.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ base source headers
5 # Copyright (C) 2015 National Research Council Canada
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Iwan Kawrakow, 2005
25 #
26 # Contributors: Reid Townson
27 # Ernesto Mainegra-Hing
28 # Blake Walters
29 # Alexandre Demelo
30 #
31 ###############################################################################
32 */
33 
34 
43 #ifndef EGS_BASE_SOURCE_
44 #define EGS_BASE_SOURCE_
45 
46 #include "egs_vector.h"
47 #include "egs_object_factory.h"
48 #include "egs_functions.h"
49 #include "egs_ensdf.h"
50 
51 #include <string>
52 #include <iostream>
53 #include "egs_math.h"
54 
55 using namespace std;
56 
57 class EGS_Input;
59 
85 
86 public:
87 
91  EGS_BaseSource(const string &Name="", EGS_ObjectFactory *f = 0) :
92  EGS_Object(Name,f), time_index(-1) {};
93 
103  EGS_Object(input,f), time_index(-1) {};
104  virtual ~EGS_BaseSource() {};
105 
111  const char *getSourceDescription() const {
112  return description.c_str();
113  };
114 
135  virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm,
136  int &q, int &latch, // charge and latch
137  EGS_Float &E, EGS_Float &wt, // energy and weight
138  EGS_Vector &x, EGS_Vector &u) = 0; // position and direction
139 
147  virtual void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun, int npar, int nchunk) { };
148 
156  virtual int getCharge() const {
157  return -99;
158  };
169  virtual EGS_Float getEmax() const = 0;
170 
184  virtual EGS_Float getFluence() const = 0;
185 
186  /* A virtual function which can be implemented in derived classes
187  * to return a fractional monitor unit associated with each source
188  * particle. Currently only makes sense for IAEA_PhspSource and
189  * EGS_BeamSource.
190  */
191  //virtual EGS_Float getTimeIndex() {
192  //return -1;
193  //};
194 
195  //virtual void setTimeIndex(EGS_Float temp_time) {};
196 
198  virtual void printSampledEmissions() {};
199 
204  virtual vector<EGS_Ensdf *> getRadionuclideEnsdf() {
205  return vector<EGS_Ensdf *>();
206  };
207 
219  virtual bool storeState(ostream &data_out) const {
220  return true;
221  };
222 
233  virtual bool setState(istream &data_in) {
234  return true;
235  };
236 
249  virtual bool addState(istream &data_in) {
250  return true;
251  };
252 
264  virtual void resetCounter() {};
265 
292  static EGS_BaseSource *createSource(EGS_Input *);
293 
302  static EGS_BaseSource *getSource(const string &Name);
303 
311  static void addKnownSource(EGS_BaseSource *o);
312 
321  static void addKnownTypeId(const char *name);
322 
323  /* Centralize the time index parameter so that it can be saved to and
324  * accessed from a single point. In almost any instance where a time index
325  * parameter is created, it is saved in the source object using
326  * setTimeIndex. When other objects would like to access the time index
327  * (most relevant example being the dynamic geometry checking if the source
328  * has provided a time index before setting its own), they can call
329  * getTimeIndex. In many cases, this method is indirectly called via the
330  * getTimeIndex in the application class, which returns the results of
331  * getTimeIndex call on the simulation source. Note there are two cases
332  * which behave slightly differently and may need some modifications. While
333  * the dynamicSource time index implementation was completely absorbed into
334  * the basesource, this was not done for the beam source and the iaea_phsp
335  * source, as they had slightly more involved time index implementations
336  * that seemed best left alone. They do not have setTimeIndex methods, \
337  * and may not return the right thing if we set the time using the geometry,
338  * as calling get may try to get the beam or iaea_phsp time index and not
339  * the basesource index we set with the geometry. */
340  EGS_Float getTimeIndex() {
341  return time_index;
342 
343  };
344 
345  void setTimeIndex(EGS_Float temp_time) {
346  time_index=temp_time;
347  };
348 
349  /* This method is essentially used to determine whether the simulation
350  * source contains a dynamic source. The only
351  * non-empty implementations of this function are in composite sources
352  * (where it simply calls containsDynamic on its components),
353  * where it will update the boolean reference to true and
354  * call containsDynamic on its base geometry, and sources that
355  * can contain time indices (dynamic, phsp, beam sources).
356  * This function was conceived to be used in the
357  * view/viewcontrol (to determine whether time index objects are visible or
358  * hidden), and track scoring */
359  virtual void containsDynamic(bool &hasdynamic) { };
360 
361 protected:
362 
368  string description;
369 
373  EGS_Float time_index;
374 
375 };
376 
395 
396 public:
397 
403  EGS_BaseSpectrum() : count(0), sum_E(0), sum_E2(0),
404  type("Unknown spectrum") {};
405 
407  virtual ~EGS_BaseSpectrum() {};
408 
415  const string &getType() const {
416  return type;
417  };
418 
425  inline EGS_Float sampleEnergy(EGS_RandomGenerator *rndm) {
426  EGS_Float e = sample(rndm);
427  count++;
428  sum_E += e;
429  sum_E2 += e*e;
430  return e;
431  };
432 
438  virtual EGS_Float maxEnergy() const = 0;
439 
445  virtual EGS_Float expectedAverage() const = 0;
446 
459  virtual bool storeState(ostream &data_out) const {
460  if (!egsStoreI64(data_out,count)) {
461  return false;
462  }
463  data_out << " " << sum_E << " " << sum_E2 << endl;
464  if (!data_out.good() || data_out.fail()) {
465  return false;
466  }
467  return true;
468  };
469 
483  virtual bool setState(istream &data_in) {
484  if (!egsGetI64(data_in,count)) {
485  return false;
486  }
487  data_in >> sum_E >> sum_E2;
488  if (data_in.eof() || !data_in.good() || data_in.fail()) {
489  return false;
490  }
491  return true;
492  };
493 
506  virtual bool addState(istream &data_in) {
507  EGS_I64 count_save = count;
508  double sum_E_save = sum_E, sum_E2_save = sum_E2;
509  if (!setState(data_in)) {
510  return false;
511  }
512  count += count_save;
513  sum_E += sum_E_save;
514  sum_E2 += sum_E2_save;
515  return true;
516  };
517 
529  virtual void resetCounter() {
530  count = 0;
531  sum_E = 0;
532  sum_E2 = 0;
533  };
534 
548  static EGS_BaseSpectrum *createSpectrum(EGS_Input *inp);
549 
555  void getSampledAverage(EGS_Float &e, EGS_Float &de) const {
556  if (count > 1) {
557  e = sum_E/count;
558  de = sum_E2/count;
559  de -= e*e;
560  if (de > 0) {
561  de = sqrt(de/(count-1));
562  }
563  }
564  };
565 
571  void reportAverageEnergy() const {
572  egsInformation("expected average energy: %g\n",expectedAverage());
573  EGS_Float e=0,de=0;
574  getSampledAverage(e,de);
575  egsInformation("sampled average energy: %g +/- %g\n",e,de);
576  };
577 
578 protected:
579 
586  virtual EGS_Float sample(EGS_RandomGenerator *rndm) = 0;
587 
589  EGS_I64 count;
590 
592  double sum_E;
593 
595  double sum_E2;
596 
600  string type;
601 
602 };
603 
623 
624 public:
625 
634  const string &Name="", EGS_ObjectFactory *f=0) :
635  EGS_BaseSource(Name,f), q(Q), s(Spec), count(0) { };
636 
648 
654  if (s) {
655  delete s;
656  }
657  };
658 
669  virtual bool isValid() const {
670  return (s != 0);
671  };
672 
684  virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm,
685  int &Q, int &latch, EGS_Float &E, EGS_Float &wt,
686  EGS_Vector &x, EGS_Vector &u) {
687  Q = q;
688  E = s->sampleEnergy(rndm);
689  getPositionDirection(rndm,x,u,wt);
690  setLatch(latch);
691  return ++count;
692  };
693 
703  EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) = 0;
704 
710  virtual EGS_Float getEmax() const {
711  return s->maxEnergy();
712  };
713 
718  int getCharge() const {
719  return q;
720  };
721 
732  virtual bool storeFluenceState(ostream &data_out) const {
733  return true;
734  };
735 
741  virtual bool storeState(ostream &data_out) const {
742  if (!egsStoreI64(data_out,count)) {
743  return false;
744  }
745  if (!s->storeState(data_out)) {
746  return false;
747  }
748  if (!storeFluenceState(data_out)) {
749  return false;
750  }
751  return true;
752  };
753 
760  virtual bool addState(istream &data) {
761  EGS_I64 count_save = count;
762  if (!egsGetI64(data,count)) {
763  return false;
764  }
765  if (!s->addState(data)) {
766  return false;
767  }
768  if (!addFluenceData(data)) {
769  return false;
770  }
771  count += count_save;
772  return true;
773  };
774 
781  virtual void resetCounter() {
782  count = 0;
783  s->resetCounter();
784  resetFluenceCounter();
785  };
786 
796  virtual bool addFluenceData(istream &data) {
797  return true;
798  }
799 
810  virtual void resetFluenceCounter() { };
811 
822  virtual bool setFluenceState(istream &data) {
823  return true;
824  };
825 
832  virtual bool setState(istream &data) {
833  if (!egsGetI64(data,count)) {
834  return false;
835  }
836  if (!s->setState(data)) {
837  return false;
838  }
839  if (!setFluenceState(data)) {
840  return false;
841  }
842  return true;
843  };
844 
845 protected:
846 
853  virtual void setLatch(int &latch) {
854  latch = 0;
855  };
856 
858  int q;
859 
862 
864  string type;
865 
867  EGS_I64 count;
868 
869 };
870 
880 template <class T>
882  EGS_ObjectFactory *f, const char *name) {
883  EGS_BaseSource::addKnownTypeId(typeid(T).name());
884  if (!input) {
885  egsWarning("createSource(%s): null input?\n",name);
886  return 0;
887  }
888  T *res = new T(input,f);
889  if (!res->isValid()) {
890  egsWarning("createSource(%s): the input is not "
891  "sufficient to create a valid source\n",name);
892  delete res;
893  return 0;
894  }
895  return res;
896 };
897 
898 #endif
899 
Base class for 'simple' particle sources.
string type
A short description of the source type.
EGS_BaseSimpleSource(int Q, EGS_BaseSpectrum *Spec, const string &Name="", EGS_ObjectFactory *f=0)
Constructor.
~EGS_BaseSimpleSource()
Destructor.
int q
The charge of this simple source.
virtual bool addFluenceData(istream &data)
Add fluence data from the stream data to the current state.
virtual void getPositionDirection(EGS_RandomGenerator *rndm, EGS_Vector &x, EGS_Vector &u, EGS_Float &wt)=0
Sample a particle position and direction.
EGS_BaseSpectrum * s
The energy spectrum of this source.
virtual bool isValid() const
Is this a valid source?
virtual bool setState(istream &data)
Set the source state according to the data in the stream data.
virtual void resetFluenceCounter()
Reset the data related to the sampling of positions and directions to a state with zero sampled parti...
virtual bool storeFluenceState(ostream &data_out) const
Store the fluence state of this source to the data stream data_out.
virtual bool addState(istream &data)
Add the source state from the stream data to the current state.
int getCharge() const
Get the charge of the source.
virtual bool storeState(ostream &data_out) const
Store the source state to the data stream data_out.
virtual EGS_Float getEmax() const
Get the maximum energy of the source.
virtual void resetCounter()
Reset the source to a state with zero sampled particles.
virtual void setLatch(int &latch)
virtual bool setFluenceState(istream &data)
Set the data related to the sampling of positions and directions to a state contained in the stream d...
EGS_I64 count
Number of statistically independent particles delivered so far.
virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, int &Q, int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u)
Sample the next source particle from the source probability distribution.
Base source class. All particle sources must be derived from this class.
virtual int getCharge() const
Get the charge of the source.
virtual bool addState(istream &data_in)
Add data from the stream data_in to the source state.
EGS_BaseSource(EGS_Input *input, EGS_ObjectFactory *f=0)
Construct a source from the input pointed to by inp.
const char * getSourceDescription() const
Get a short description of this source.
EGS_BaseSource(const string &Name="", EGS_ObjectFactory *f=0)
Construct a source named Name.
virtual void printSampledEmissions()
Print statistics on what was sampled from the source.
virtual EGS_Float getEmax() const =0
Return the maximum energy of this source.
EGS_Float time_index
time index corresponding to a particle. This stores the current time index for all objects in the sim...
virtual EGS_Float getFluence() const =0
Return the fluence this source has emitted so far.
virtual void resetCounter()
Reset the source state.
string description
A short source description.
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.
static void addKnownTypeId(const char *name)
Add a known source object typeid to the source factory.
virtual bool setState(istream &data_in)
Set the source state based on data from the stream data_in.
virtual void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun, int npar, int nchunk)
Set the next simulation chunk to start at nstart and to consist of nrun particles.
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.
Base class for energy spectra. All energy spectra in the EGSnrc C++ class library are derived from th...
EGS_Float sampleEnergy(EGS_RandomGenerator *rndm)
Sample a particle energy.
virtual bool setState(istream &data_in)
Set the state of the spectrum object from the data in the stream data_in.
virtual ~EGS_BaseSpectrum()
Destructor. Does nothing.
double sum_E2
Sum of energies squared sampled so far.
void reportAverageEnergy() const
Report the average energy (expected and actually sampled).
virtual EGS_Float maxEnergy() const =0
Get the maximum energy of this spectrum.
string type
A short string describing the spectrum that must be set by derived classes.
virtual bool addState(istream &data_in)
Add to the state of this object the data from the stream data_in.
virtual EGS_Float sample(EGS_RandomGenerator *rndm)=0
Sample an energy from the spectrum energy distribution.
virtual EGS_Float expectedAverage() const =0
Get the average energy of the spectrum.
EGS_BaseSpectrum()
Constructor.
void getSampledAverage(EGS_Float &e, EGS_Float &de) const
Get the average sampled energy and its statistical uncertainty.
EGS_I64 count
Number of times the sampleEnergy() method was called.
virtual bool storeState(ostream &data_out) const
Store the state of the spectrum object into the stream data_out.
double sum_E
Sum of energies sampled so far.
const string & getType() const
Get the spectrum type.
virtual void resetCounter()
Reset the state of this spectrum object.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
An object factory.
Base egspp object.
Base random number generator class. All random number generators should be derived from this class.
Definition: egs_rndm.h:67
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_BaseSource * createSourceTemplate(EGS_Input *input, EGS_ObjectFactory *f, const char *name)
A template source creation function.
The ensdf library header file.
Global egspp functions header file.
#define EGS_EXPORT
Export symbols from the egspp library.
Definition: egs_libconfig.h:90
Attempts to fix broken math header files.
EGS_Object and EGS_ObjectFactory class 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 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,...
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.