EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_dose_scoring.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ dose scoring object 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: Ernesto Mainegra-Hing, 2012
25 #
26 # Contributors: Reid Townson
27 # Blake Walters
28 # Max Orok
29 # Martin Martinov
30 #
31 ###############################################################################
32 #
33 # A general dose calculation tool. Since it is outside the scope of the
34 # EGS_Application class, a few utility methods are needed in EGS_Application
35 # to retrieve information regarding media, geometry and source.
36 #
37 # Dose is output for each dose region without any spacial information. For a
38 # more detailed dose scoring grid it is better to create a user code which
39 # could produce 3D dose distributions and graph data.
40 #
41 # Can be used in any C++ user code by entering the proper input block in
42 # the ausgab object definition block.
43 #
44 # Prints out dose in each dose scoring region.
45 #
46 # Dose scoring regions can be defined by input using one the following
47 # syntax for individual regions:
48 #
49 # :start ausgab object definition:
50 # :start ausgab object:
51 # library = egs_dose_scoring
52 # name = some_name
53 # volume = V0 V1 ... Vn
54 # dose regions = IR0 IR1 ... IRn
55 # :stop ausgab object:
56 # :stop ausgab object definition:
57 #
58 # or by groups of consecutive regions:
59 #
60 # :start ausgab object definition:
61 # :start ausgab object:
62 # library = egs_dose_scoring
63 # name = some_name
64 # volume = V0 V1 ... Vn
65 # dose start region = IRI_0 ... IRI_N
66 # dose stop region = IRE_0 ... IRE_N
67 # :stop ausgab object:
68 # :stop ausgab object definition:
69 #
70 # where one can have same number of volume entries as group of regions (n=N)
71 # or same number of volume entries as number of individual regions. If there
72 # are more dose scoring regions than volume entries, a default volume is use for
73 # those regions without volume information. This default can be either the first
74 # volume entry or 1 g/cm3.
75 #
76 # TODO:
77 #
78 # - Classify dose as contributed by primary or scattered particles
79 # - Custom classification using latch
80 # - Dose to medium calculation
81 #
82 ###############################################################################
83 */
84 
85 
91 #ifndef EGS_DOSE_SCORING_
92 #define EGS_DOSE_SCORING_
93 
94 #include "egs_ausgab_object.h"
95 #include "egs_application.h"
96 #include "egs_scoring.h"
97 #include "egs_base_geometry.h"
98 
99 #ifdef WIN32
100 
101  #ifdef BUILD_DOSE_SCORING_DLL
102  #define EGS_DOSE_SCORING_EXPORT __declspec(dllexport)
103  #else
104  #define EGS_DOSE_SCORING_EXPORT __declspec(dllimport)
105  #endif
106  #define EGS_DOSE_SCORING_LOCAL
107 
108 #else
109 
110  #ifdef HAVE_VISIBILITY
111  #define EGS_DOSE_SCORING_EXPORT __attribute__ ((visibility ("default")))
112  #define EGS_DOSE_SCORING_LOCAL __attribute__ ((visibility ("hidden")))
113  #else
114  #define EGS_DOSE_SCORING_EXPORT
115  #define EGS_DOSE_SCORING_LOCAL
116  #endif
117 
118 #endif
119 
195 class EGS_DOSE_SCORING_EXPORT EGS_DoseScoring : public EGS_AusgabObject {
196 
197 public:
198 
199  EGS_DoseScoring(const string &Name="", EGS_ObjectFactory *f = 0);
200 
201  ~EGS_DoseScoring();
202 
204 
205  int ir = app->top_p.ir, imed = ir>=0 ? app->getMedium(ir):-1;
206  EGS_Float edep = app->getEdep();
207 
208  /**** energy deposition in a medium ***/
209  if (iarg <= 4 && imed >= 0 && edep > 0 && doseM) {
210  doseM->score(imed, edep*app->top_p.wt);
211  }
212 
213  //score in file array if requested
214  if (ir >=0 && doseF && iarg <=4 && df_reg[ir] >= 0 && edep) {
215  doseF->score(df_reg[ir], edep*app->top_p.wt);
216  }
217 
218  /*** Check if scoring in current region ***/
219  if (ir >= 0 && dose) {
220  if (d_reg_index[ir]<0) {
221  return 0;
222  }
223  }
224 
225  /**** energy deposition in current region ***/
226  if (iarg <= 4 && ir >= 0 && edep > 0 && dose) {
227  dose->score(d_reg_index[ir], edep*app->top_p.wt);
228  }
229  return 0;
230  };
231 
232  int processEvent(EGS_Application::AusgabCall iarg, int ir) {
233 
234  if (ir == -1) {
235  ir = app->top_p.ir;
236  }
237 
238  int imed = ir>=0 ? app->getMedium(ir):-1;
239  EGS_Float edep = app->getEdep();
240 
241  /**** energy deposition in a medium ***/
242  if (iarg <= 4 && imed >= 0 && edep > 0 && doseM) {
243  doseM->score(imed, edep*app->top_p.wt);
244  }
245 
246  //score in file array if requested
247  if (ir >= 0 && doseF && iarg <=4 && df_reg[ir] >= 0 && edep) {
248  doseF->score(df_reg[ir], edep*app->top_p.wt);
249  }
250 
251  /*** Check if scoring in current region ***/
252  if (ir >= 0 && dose) {
253  if (d_reg_index[ir]<0) {
254  return 0;
255  }
256  }
257 
258  /**** energy deposition in current region ***/
259  if (iarg <= 4 && ir >= 0 && edep > 0 && dose) {
260  dose->score(d_reg_index[ir], edep*app->top_p.wt);
261  }
262  return 0;
263  };
264 
265  bool needsCall(EGS_Application::AusgabCall iarg) const {
266  if (iarg <= 4) {
267  return true;
268  }
269  else {
270  return false;
271  }
272  };
273 
274  void setApplication(EGS_Application *App);
275 
276  void getNumberRegions(const string &str, vector<int> &regs);
277 
278  void getLabelRegions(const string &str, vector<int> &regs);
279 
280  void reportResults();
281 
282  void setCurrentCase(EGS_I64 ncase) {
283  if (ncase != m_lastCase) {
284  m_lastCase = ncase;
285  if (dose) {
286  dose->setHistory(ncase);
287  }
288  if (doseM) {
289  doseM->setHistory(ncase);
290  }
291  if (doseF) {
292  doseF->setHistory(ncase);
293  }
294  }
295  };
296  int getDigits(int i) {
297  int imax = 10;
298  while (i>=imax) {
299  imax*=10;
300  }
301  return (int)log10((float)imax);
302  };
303 
304  EGS_Float getRealRho(int ireg) {
305  int med = dose_geom->medium(ireg);
306  return dose_geom->getRelativeRho(ireg)*app->getMediumRho(med);
307  }
308 
309  void setVol(const vector<EGS_Float> volin) {
310  vol_list=volin;
311  };
312  void setVol(const EGS_Float volin) {
313  vol_list.push_back(volin);
314  };
315  void setDoseRegions(const vector <int> d_reg) {
316  d_region=d_reg;
317  };
318  void setDoseRegions(const string d_reg) {
319  d_regionString=d_reg;
320  };
321  void setMediumScoring(bool flag) {
322  score_medium_dose=flag;
323  };
324  void setRegionScoring(bool flag) {
325  score_region_dose=flag;
326  };
327  void setOutputFile(bool flag, EGS_BaseGeometry *dgeom, int ftype) {
328  output_dose_file=flag;
329  dose_geom= dgeom;
330  file_type = ftype;
331  };
332  bool getOutputFile(EGS_BaseGeometry *&dgeom, int &ftype) {
333  dgeom = dose_geom;
334  ftype = file_type;
335  return output_dose_file;
336  };
337  void setUserNorm(const EGS_Float &normi) {
338  norm_u=normi;
339  };
340  void outputDoseFile(const EGS_Float &normD);
341 
342  bool storeState(ostream &data) const;
343  bool setState(istream &data);
344  void resetCounter();
345  bool addState(istream &data);
346  int addTheStates(istream &data);
347 
348 protected:
349 
352  vector <EGS_Float> vol_list; // Input list of region volumes
353  vector <int> d_region; // Input list of dose scoring regions d_reg[i] = ir
354  string d_regionString;
355  vector <int> d_reg_index; // list index for dose scoring regions d_reg_index[ir]= 0..d_reg.size()-1
356  vector <EGS_Float> vol; // geometrical region volumes
357  EGS_Float norm_u;
358  int nreg, // number of regions in the geometry
359  nmedia; // number of media in the input file
360  int max_dreg, // maximum dose region number
361  max_medl; // maximum medium name length
362  EGS_I64 m_lastCase;
363  bool score_medium_dose,
364  score_region_dose;
365 
366  EGS_BaseGeometry *dose_geom; //EGS_XYZGeometry for which to output dose to file
368  vector<int> df_reg; //array mapping global reg. no. onto reg. no. in EGS_XYZGeometry
369  bool output_dose_file; //set to true if outputting a dose file
370  int file_type; //output file type--currently only .3ddose (file_type=0) supported
371  string df_name; //output file name--put here for convenience sake
372 };
373 
374 #endif
Base class for advanced EGSnrc C++ applications.
AusgabCall
Possible calls to the user scoring function ausgab().
virtual void resetCounter()
Reset the ausgab object state.
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
virtual int processEvent(EGS_Application::AusgabCall iarg)=0
Process an ausgab call for event iarg.
virtual bool setState(istream &data_in)
Set the ausgab object state based on data from the stream data_in.
virtual void reportResults()
Report results.
virtual bool storeState(ostream &data_out) const
Store the source state into the stream data_out.
virtual void setCurrentCase(EGS_I64 ncase)
Set the current event.
virtual bool addState(istream &data_in)
Add data from the stream data_in to the ausgab object state.
virtual bool needsCall(EGS_Application::AusgabCall iarg) const
Is the ausgab call iarg relevant for this object?
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
A dose scoring object: header.
EGS_ScoringArray * doseF
Scoring dose in each voxel in EGS_XYZGeometry.
EGS_ScoringArray * doseM
Scoring dose in each medium.
EGS_I64 m_lastCase
The event set via setCurrentCase()
EGS_ScoringArray * dose
Scoring in each dose scoring region.
An object factory.
A class for scoring an array of quantities (e.g. a dose distribution) in a Monte Carlo simulation.
Definition: egs_scoring.h:219
EGS_Application class header file.
EGS_AusgabObject interface class header file.
EGS_BaseGeometry class header file.
EGS_ScoringSingle and EGS_ScoringArray class header file.