EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_dynamic_source.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ dynamic 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: Blake Walters, 2017
25 #
26 # Contributors: Reid Townson
27 #
28 ###############################################################################
29 */
30 
31 
37 #ifndef EGS_DYNAMIC_SOURCE_
38 #define EGS_DYNAMIC_SOURCE_
39 
40 #include "egs_vector.h"
41 #include "egs_base_source.h"
42 #include "egs_rndm.h"
43 #include "egs_shapes.h"
44 #include <string>
45 #include <sstream>
46 
47 
48 #ifdef WIN32
49 
50  #ifdef BUILD_DYNAMIC_SOURCE_DLL
51  #define EGS_DYNAMIC_SOURCE_EXPORT __declspec(dllexport)
52  #else
53  #define EGS_DYNAMIC_SOURCE_EXPORT __declspec(dllimport)
54  #endif
55  #define EGS_DYNAMIC_SOURCE_LOCAL
56 
57 #else
58 
59  #ifdef HAVE_VISIBILITY
60  #define EGS_DYNAMIC_SOURCE_EXPORT __attribute__ ((visibility ("default")))
61  #define EGS_DYNAMIC_SOURCE_LOCAL __attribute__ ((visibility ("hidden")))
62  #else
63  #define EGS_DYNAMIC_SOURCE_EXPORT
64  #define EGS_DYNAMIC_SOURCE_LOCAL
65  #endif
66 
67 #endif
68 
169 class EGS_DYNAMIC_SOURCE_EXPORT EGS_DynamicSource :
170  public EGS_BaseSource {
171 
172 public:
173 
174 
176 
177  EGS_Vector iso; //isocentre position
178  EGS_Float dsource; //source-isocentre distance
179  EGS_Float theta; //angle of rotation about Y-axis
180  EGS_Float phi; //angle of rotation about Z-axis
181  EGS_Float phicol; //angle of rotation in source plane
182  EGS_Float mu; //monitor unit index for control point
183  };
184 
189  EGS_DynamicSource(EGS_BaseSource *Source, vector<EGS_ControlPoint> cpts,
190  const string &Name="", EGS_ObjectFactory *f=0) :
191  EGS_BaseSource(Name,f), source(Source), valid(true) {
192  //do some checks on cpts
193  if (cpts.size()<2) {
194  egsWarning("EGS_DynamicSource: not enough or missing control points.\n");
195  valid = false;
196  }
197  else {
198  if (cpts[0].mu > 0.0) {
199  egsWarning("EGS_DynamicSource: mu index of control point 1 > 0.0. This will generate many warning messages.\n");
200  }
201  int npts = cpts.size();
202  for (int i=0; i<npts; i++) {
203  if (i>0 && cpts[i].mu < cpts[i-1].mu) {
204  egsWarning("EGS_DynamicSource: mu index of control point %i < mu index of control point %i\n",i,i-1);
205  valid = false;
206  }
207  if (cpts[i].mu<0.0) {
208  egsWarning("EGS_DynamicSource: mu index of control point %i < 0.0\n",i);
209  valid = false;
210  }
211  }
212  //normalize mu values
213  for (int i=0; i<npts-1; i++) {
214  cpts[i].mu /= cpts[npts-1].mu;
215  }
216  }
217  setUp();
218  };
219 
222 
223  ~EGS_DynamicSource() {
224  EGS_Object::deleteObject(source);
225  };
226 
227  EGS_I64 getNextParticle(EGS_RandomGenerator *rndm,
228  int &q, int &latch, EGS_Float &E, EGS_Float &wt,
229  EGS_Vector &x, EGS_Vector &u) {
230  int err = 1;
231  EGS_ControlPoint ipt; //the actual rotation coords
232  EGS_I64 c;
233  while (err) {
234  c = source->getNextParticle(rndm,q,latch,E,wt,x,u);
235  if (sync) {
236  pmu = source->getMu();
237  if (pmu<0) {
238  egsWarning("EGS_DynamicSource: You have selected synchronization of dynamic source with %s\n",source->getObjectName().c_str());
239  egsWarning("However, this source does not return mu values for each particle. Will turn off synchronization.\n");
240  sync = false;
241  }
242  }
243  if (!sync) {
244  pmu = rndm->getUniform();
245  }
246  err = getCoord(pmu,ipt);
247  }
248 
249  //translate source in Z
250  x.z=x.z-ipt.dsource;
251  //get the rotation matrices
252  ipt.phicol *= M_PI/180;
253  ipt.theta *= M_PI/180;
254  ipt.phi *= M_PI/180;
256  EGS_RotationMatrix Rtheta(EGS_RotationMatrix::rotY(ipt.theta));
258  //apply rotations in specific order and then translate relative
259  //to the isocentre
260  u=Rphi*Rtheta*Rcol*u;
261  x=Rphi*Rtheta*Rcol*x + ipt.iso;
262  return c;
263  };
264  EGS_Float getEmax() const {
265  return source->getEmax();
266  };
267  EGS_Float getFluence() const {
268  return source->getFluence();
269  };
270  EGS_Float getMu() {
271  return pmu;
272  };
273  bool storeState(ostream &data) const {
274  return source->storeState(data);
275  };
276  bool setState(istream &data) {
277  return source->setState(data);
278  };
279  bool addState(istream &data_in) {
280  return source->addState(data_in);
281  };
282  void resetCounter() {
283  source->resetCounter();
284  };
285 
286  bool isValid() const {
287  return (valid && source != 0);
288  };
289 
290  void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun) {
291  source->setSimulationChunk(nstart, nrun);
292  };
293 
294 protected:
295 
296  EGS_BaseSource *source;
297 
298  vector<EGS_ControlPoint> cpts; //control point
299 
300  int ncpts; //no. of control points
301 
302  bool valid; //is this a valid source
303 
304  bool sync; //set to true if source motion synched with mu read from
305  //iaea phsp or beam simulation source
306 
307  int getCoord(const EGS_Float rand, EGS_ControlPoint &ipt);
308 
309  EGS_Float pmu; //monitor unit index corresponding to particle
310  //could just be a random number.
311 
312  void setUp();
313 
314 };
315 
316 #endif
virtual void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun)
Set the next simulation chunk to start at nstart and to consist of nrun particles.
EGS_BaseSource class header file.
A class for vector rotations.
EGS_Vector methods for the manipulation of 3D vectors in cartesian co-ordinates.
A class representing 3D vectors.
Definition: egs_vector.h:56
virtual bool addState(istream &data_in)
Add data from the stream data_in to the source state.
static void deleteObject(EGS_Object *o)
Delete an object.
virtual void resetCounter()
Reset the source state.
static EGS_RotationMatrix rotY(EGS_Float cphi, EGS_Float sphi)
Returns a rotation around the y-axis by the angle with cphi, sphi = .
A source with time-varying rotations/translations.
virtual bool storeState(ostream &data_out) const
Store the source state into the stream data_out.
Base random number generator class. All random number generators should be derived from this class...
Definition: egs_rndm.h:67
EGS_Float z
z-component
Definition: egs_vector.h:62
static EGS_RotationMatrix rotZ(EGS_Float cphi, EGS_Float sphi)
Returns a rotation around the z-axis by the angle with cphi, sphi = .
EGS_RandomGenerator class header file.
EGS_DynamicSource(EGS_BaseSource *Source, vector< EGS_ControlPoint > cpts, const string &Name="", EGS_ObjectFactory *f=0)
Construct a dynamic source using Source as the source and cpts as the control points. Not sure if this will ever be used but here just in case.
virtual bool setState(istream &data_in)
Set the source state based on data from the stream data_in.
EGS_BaseShape and shape classes header file.
An object factory.
virtual EGS_Float getFluence() const =0
Return the fluence this source has emitted so far.
EGS_Float getUniform()
Returns a random number uniformly distributed between zero (inclusive) and 1 (exclusive).
Definition: egs_rndm.h:103
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
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 EGS_Float getEmax() const =0
Return the maximum energy of this source.
Base source class. All particle sources must be derived from this class.
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.