EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_dose_scoring.cpp
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ dose scoring object
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: Frederic Tessier
27 # Reid Townson
28 # Hubert Ho
29 # Blake Walters
30 # Max Orok
31 # Martin Martinov
32 #
33 ###############################################################################
34 #
35 # A general dose calculation tool. Since it is outside the scope of the
36 # EGS_Application class, a few utility methods are needed in EGS_Application
37 # to retrieve information regarding media, geometry and source.
38 #
39 # Dose is output for each dose region without any spacial information. For a
40 # more detailed dose scoring grid it is better to create a user code which
41 # could produce 3D dose distributions and graph data.
42 #
43 # Can be used in any C++ user code by entering the proper input block in
44 # the ausgab object definition block.
45 #
46 # Prints out dose in each dose scoring region.
47 #
48 # Dose scoring regions can be defined by input using one the following
49 # syntax for individual regions:
50 #
51 # :start ausgab object definition:
52 # :start ausgab object:
53 # library = egs_dose_scoring
54 # name = some_name
55 # volume = V0 V1 ... Vn
56 # dose regions = IR0 IR1 ... IRn
57 # :stop ausgab object:
58 # :stop ausgab object definition:
59 #
60 # or by groups of consecutive regions:
61 #
62 # :start ausgab object definition:
63 # :start ausgab object:
64 # library = egs_dose_scoring
65 # name = some_name
66 # volume = V0 V1 ... Vn
67 # dose start region = IRI_0 ... IRI_N
68 # dose stop region = IRE_0 ... IRE_N
69 # :stop ausgab object:
70 # :stop ausgab object definition:
71 #
72 # where one can have same number of volume entries as group of regions (n=N)
73 # or same number of volume entries as number of individual regions. If there
74 # are more dose scoring regions than volume entries, a default volume is use for
75 # those regions without volume information. This default can be either the first
76 # volume entry or 1 g/cm3.
77 #
78 # TODO:
79 #
80 # - Classify dose as contributed by primary or scattered particles
81 # - Custom classification using latch
82 # - Dose to medium calculation
83 #
84 ###############################################################################
85 */
86 
87 
93 #include <fstream>
94 #include <string>
95 #include <cstdlib>
96 
97 #include "egs_dose_scoring.h"
98 #include "egs_input.h"
99 #include "egs_functions.h"
100 
101 EGS_DoseScoring::EGS_DoseScoring(const string &Name,
102  EGS_ObjectFactory *f) :
103  EGS_AusgabObject(Name,f), dose(0), doseM(0), doseF(0),
104  norm_u(1.0), nreg(0), nmedia(0), max_dreg(-1), max_medl(0),
105  m_lastCase(-1),score_medium_dose(false), score_region_dose(false), output_dose_file(false) {
106  otype = "EGS_DoseScoring";
107 }
108 
109 EGS_DoseScoring::~EGS_DoseScoring() {
110  if (dose) {
111  delete dose;
112  }
113  if (doseM) {
114  delete doseM;
115  }
116  if (doseF) {
117  delete doseF;
118  }
119 }
120 
121 void EGS_DoseScoring::setApplication(EGS_Application *App) {
123  if (!app) {
124  return;
125  }
126 
127  if (d_regionString.length() > 0 && d_region.size() < 1) {
128  getNumberRegions(d_regionString, d_region);
129  getLabelRegions(d_regionString, d_region);
130  }
131 
132  // Get the number of regions in the geometry.
133  nreg = app->getnRegions();
134  // Get the number of media in the input file
135  nmedia = app->getnMedia();
136  // determine maximum medium name length
137  char buf[64];
138  int count = 0;
139  int imed=0;
140  max_medl = 6; // length of the string "medium" is the minimum
141  for (imed=0; imed < nmedia; imed++) {
142  sprintf(buf,"%s%n",app->getMediumName(imed),&count);
143  if (count > max_medl) {
144  max_medl = count;
145  }
146  }
147  if (d_region.size()>nreg)
148  egsWarning("\n*********************************************"
149  "\n WARNING:"
150  "\nRequesting %d dose scoring regions, but there"
151  "\nare only %d geometrical regions!"
152  "\nscoring will be done in all regions!"
153  "\n*********************************************",
154  d_region.size(),nreg);
155  // Flag dose scoring regions in geometry
156  // and set their volume.
157  if (score_region_dose) {
158  if (d_region.size() && d_region.size() < nreg) { // specific dose regions provided
159  // Get maximum dose scoring region
160  for (vector<int>::iterator it = d_region.begin(); it < d_region.end(); it++) {
161  if (*it > max_dreg) {
162  max_dreg = *it;
163  }
164  }
165  for (int j=0; j<nreg; j++) {
166  d_reg_index.push_back(-1);
167  vol.push_back(vol_list[0]);// set to either 1.0 or first volume entered
168  }
169  for (int i=0; i<d_region.size(); i++) {
170  d_reg_index[d_region[i]]=i;
171  if (i < vol_list.size()) {
172  vol[d_region[i]] = vol_list[i];
173  }
174  }
175  if (score_region_dose) {
176  dose = new EGS_ScoringArray(d_region.size());
177  }
178  }
179  else { // scoring in all regions
180  max_dreg = nreg-1;
181  for (int j=0; j<nreg; j++) {
182  d_reg_index.push_back(j);
183  if (j < vol_list.size()) {
184  vol.push_back(vol_list[j]);
185  }
186  else { // more regions than volumes, use default 1 g/cm3 or first volume entered
187  vol.push_back(vol_list[0]);
188  }
189  }
190  if (score_region_dose) {
191  dose = new EGS_ScoringArray(nreg);
192  }
193  }
194  }
195  // If requested request memory for medium dose
196  if (score_medium_dose) {
197  doseM = new EGS_ScoringArray(nmedia);
198  }
199  if (!score_region_dose) { // setup volumes
200  if (vol_list.size() == 1) {
201  vol.push_back(vol_list[0]);
202  }
203  else {
204  for (int j=0; j<nreg; j++) {
205  if (j < vol_list.size()) {
206  vol.push_back(vol_list[j]);
207  }
208  else { // more regions than volumes, use default 1 g/cm3 or first volume entered
209  vol.push_back(vol_list[0]);
210  }
211  }
212  }
213  }
214 
215  if (output_dose_file) {
216  //set df_reg to default (non-scoring) values
217  for (int i=0; i<nreg; i++) {
218  df_reg.push_back(-1);
219  }
220  //determine the region no. in the EGS_XYZGeometry and corresponding
221  //global reg. no.
222  EGS_Vector tp;
223  int nx=dose_geom->getNRegDir(0);
224  int ny=dose_geom->getNRegDir(1);
225  int nz=dose_geom->getNRegDir(2);
226  EGS_Float minx,maxx,miny,maxy,minz,maxz;
227  for (int k=0; k<nz; k++) {
228  for (int j=0; j<ny; j++) {
229  for (int i=0; i<nx; i++) {
230  minx=dose_geom->getBound(0,i);
231  maxx=dose_geom->getBound(0,i+1);
232  miny=dose_geom->getBound(1,j);
233  maxy=dose_geom->getBound(1,j+1);
234  minz=dose_geom->getBound(2,k);
235  maxz=dose_geom->getBound(2,k+1);
236  tp.x=(minx+maxx)/2.;
237  tp.y=(miny+maxy)/2.;
238  tp.z=(minz+maxz)/2.;
239  int g_reg = app->isWhere(tp);
240  df_reg[g_reg]=i+j*nx+k*nx*ny;
241  }
242  }
243  }
244  //create an egs_scoring_array of the appropriate size
245  doseF = new EGS_ScoringArray(nx*ny*nz);
246  }
247 
248  description = "\n*******************************************\n";
249  description += "Dose Scoring Object (";
250  description += name;
251  description += ")\n";
252  description += "*******************************************\n";
253  if (dose) {
254  description +="\n - Regions in dose calculator :";
255  sprintf(buf,"%d\n\n",dose->regions());
256  description += buf;
257  }
258  if (doseM) {
259  description += " - Medium dose will be calculated\n";
260  }
261  description += "\n--------------------------------------\n";
262  sprintf(buf,"%*s %*s rho/(g/cm^3)\n",max_medl/2,"medium",max_medl/2," ");
263  description += buf;
264  description += "--------------------------------------\n";
265  for (imed=0; imed < nmedia; imed++) {
266  sprintf(buf,"%-*s",max_medl,app->getMediumName(imed));
267  description += buf;
268  description += " ";
269  sprintf(buf,"%11.8f",app->getMediumRho(imed));
270  description += buf;
271  description += "\n";
272  }
273  description += "--------------------------------------\n";
274  if (norm_u != 1.0) {
275  description += " Non-unity user-requested normalization = ";
276  sprintf(buf,"%g\n",norm_u);
277  description += buf;
278  }
279  description += "\n*******************************************\n\n";
280  vol_list.clear();
281  if (d_region.size()) {
282  d_region.clear();
283  }
284  if (doseF) {
285  description += "\n Will output dose to file:\n";
286  description += " EGS_XYZGeometry: " + dose_geom->getName();
287  description += "\n file format: ";
288  if (file_type==0) {
289  //only type supported so far
290  description += " 3ddose";
291  }
292  description += "\n file name: ";
293  if (file_type==0) {
294  df_name=getObjectName() + ".3ddose";
295  df_name=egsJoinPath(app->getAppDir(),df_name);
296  }
297  description += df_name;
298  }
299 }
300 
301 void EGS_DoseScoring::getNumberRegions(const string &str, vector<int> &regs) {
302  app->getNumberRegions(str, regs);
303 }
304 
305 void EGS_DoseScoring::getLabelRegions(const string &str, vector<int> &regs) {
306  app->getLabelRegions(str, regs);
307 }
308 
309 void EGS_DoseScoring::reportResults() {
310  egsInformation("\n======================================================\n");
311  egsInformation("Dose Scoring Object(%s)\n",name.c_str());
312  egsInformation("======================================================\n");
313  EGS_Float normD = 1., normE=1.;
314  int count = 0;
315  EGS_Float F = app->getFluence();
316  egsInformation("=> last case = %lld fluence = %g\n", m_lastCase, F);
317  /* Normalize to actual source fluence */
318  normE = m_lastCase/F*norm_u;
319  normD = 1.602e-10*normE;
320  int irmax_digits = getDigits(max_dreg);
321  if (irmax_digits < 2) {
322  irmax_digits = 2;
323  }
324  string line;
325  double r,dr;
326  if (dose) {
327  if (normE==1) {
328  egsInformation("\n\n==> Summary of region dosimetry (per particle)\n\n");
330  "%*s %*s %12s %12s Edep (MeV) D (Gy) %n\n",
331  irmax_digits,"ir",max_medl,"medium","rho (g/cm^3)","Volume (cm^3)",&count);
332  }
333  else {
334  egsInformation("\n==> Summary of region dosimetry (per fluence)\n");
336  "%*s %*s %12s %12s Edep (MeV*cm^2) D (Gy*cm^2) %n\n",
337  irmax_digits,"ir",max_medl,"medium","rho (g/cm^3)","Volume (cm^3)",&count);
338  }
339  line.append(count,'-');
340  egsInformation("%s\n",line.c_str());
341 
342  /* Compute deposited energy and dose */
343  for (int ireg = 0; ireg < nreg; ireg++) {
344  if (d_reg_index[ireg]>=0) {
345  if (!(app->isRealRegion(ireg))) {
346  continue;
347  }
348  int imed = app->getMedium(ireg);
349  EGS_Float rho = app->getMediumRho(imed);
350  EGS_Float mass = vol[ireg]*rho;
351  dose->currentResult(d_reg_index[ireg],r,dr);
352  if (r > 0) {
353  dr = dr/r;
354  }
355  else {
356  dr=1;
357  }
358  egsInformation("%*d %-*s %11.8f %13.6f %12.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n",
359  irmax_digits,ireg,max_medl,app->getMediumName(imed),rho,vol[ireg],r*normE,dr*100.,r*normD/mass,dr*100.);
360  }
361  }
362  egsInformation("%s\n",line.c_str());
363  }
364  if (doseM) {
365  vector<EGS_Float> massM(nmedia,0);
366  int imed = 0;
367  for (int ir=0; ir<nreg; ir++) {
368  if (app->isRealRegion(ir)) {
369  imed = app->getMedium(ir);
370  // skip vacuum regions
371  if (imed == -1) {
372  continue;
373  }
374  EGS_Float volume = vol.size() > 1 ? vol[ir]:vol[0];
375  massM[imed] += app->getMediumRho(imed)*volume;
376  }
377  }
378  if (normE==1) {
379  egsInformation("\n\n==> Summary of media dosimetry (per particle)\n");
381  "%*s %*s Edep/[MeV] D/[Gy] %n\n",
382  max_medl/2,"medium",max_medl/2," ",&count);
383  }
384  else {
385  egsInformation("\n\n==> Summary of media dosimetry (per fluence)\n");
387  "%*s %*s Edep/[MeV*cm2] D/[Gy*cm2] %n\n",
388  max_medl/2,"medium",max_medl/2," ",&count);
389  }
390  line="";
391  line.append(count,'-');
392  egsInformation("%s\n",line.c_str());
393  /* Compute deposited energy in medium (MeV)*/
394  for (int im=0; im<nmedia; im++) {
395  doseM->currentResult(im,r,dr);
396  if (r > 0) {
397  dr = dr/r;
399  "%-*s %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n",
400  max_medl,app->getMediumName(im),r*normE,dr*100.,r*normD/massM[im],dr*100.);
401  }
402  }
403  egsInformation("%s\n",line.c_str());
404  }
405  if (doseF) {
406  if (app->getIparallel()>0) {
407  egsInformation("\n EGS_DoseScoring: This is one of a number of parallel jobs. Will only output dose file on combining results.\n");
408  }
409  else {
410  outputDoseFile(normD);
411  }
412  }
413  egsInformation("\n======================================================\n");
414 }
415 
416 void EGS_DoseScoring::outputDoseFile(const EGS_Float &normD) {
417  double r,dr;
418  ofstream df_out;
419  egsInformation("\n EGS_DoseScoring: Writing dose data for EGS_XYZGeometry %s... \n",dose_geom->getName().c_str());
420  egsInformation(" Output file name: %s\n",df_name.c_str());
421  //idea is to add new file_types as they become available
422  if (file_type==0) {
423  //open file
424  df_out.open(df_name.c_str());
425  if (!df_out) {
426  egsFatal("\n EGS_DoseScoring: Error: Failed to open file %s\n",df_name.c_str());
427  exit(1);
428  }
429  //output data
430  int nx=dose_geom->getNRegDir(0);
431  int ny=dose_geom->getNRegDir(1);
432  int nz=dose_geom->getNRegDir(2);
433  //output no. of voxels in x,y,z
434  df_out << nx << " " << ny << " " << nz << "\n";
435  //use single precision real for output
436  float bound, dose, doseun;
437  //output voxel boundaries
438  for (int i=0; i<=nx; i++) {
439  bound=dose_geom->getBound(0,i);
440  df_out << bound << " ";
441  }
442  df_out << "\n";
443  for (int j=0; j<=ny; j++) {
444  bound=dose_geom->getBound(1,j);
445  df_out << bound << " ";
446  }
447  df_out << "\n";
448  for (int k=0; k<=nz; k++) {
449  bound=dose_geom->getBound(2,k);
450  df_out << bound << " ";
451  }
452  df_out << "\n";
453  //divide dose by mass and output
454  for (int i=0; i<nx*ny*nz; i++) {
455  doseF->currentResult(i,r,dr);
456  EGS_Float mass = dose_geom->getVolume(i)*getRealRho(i); //local reg.
457  dose=r*normD/mass;
458  df_out << dose << " ";
459  }
460  df_out << "\n";
461  //output uncertainties
462  for (int i=0; i<nx*ny*nz; i++) {
463  doseF->currentResult(i,r,dr);
464  if (r > 0) {
465  dr = dr/r;
466  }
467  else {
468  dr=1;
469  }
470  doseun=dr;
471  df_out << doseun << " ";
472  }
473  df_out << "\n";
474  df_out.close();
475  }
476  else {
477  egsFatal("\n EGS_DoseScoring: Warning: Dose output file type not recognized.\n");
478  }
479 }
480 
481 bool EGS_DoseScoring::storeState(ostream &data) const {
482  //egsInformation("Storing EGS_DoseScoring...\n");
483  if (!egsStoreI64(data,m_lastCase)) {
484  return false;
485  }
486  data << endl;
487  if (dose && !dose->storeState(data)) {
488  return false;
489  }
490  if (doseM && !doseM->storeState(data)) {
491  return false;
492  }
493  if (doseF && !doseF->storeState(data)) {
494  return false;
495  }
496  return true;
497 }
498 
499 bool EGS_DoseScoring::setState(istream &data) {
500  if (!egsGetI64(data,m_lastCase)) {
501  return false;
502  }
503  if (dose && !dose->setState(data)) {
504  return false;
505  }
506  if (doseM && !doseM->setState(data)) {
507  return false;
508  }
509  if (doseF && !doseF->setState(data)) {
510  return false;
511  }
512  return true;
513 }
514 
515 bool EGS_DoseScoring::addState(istream &data) {
516  int err = addTheStates(data);
517  if (err) {
518  egsInformation("Error code: %d",err);
519  return false;
520  }
521  return true;
522 }
523 int EGS_DoseScoring::addTheStates(istream &data) {
524  EGS_I64 tmp_case;
525  if (!egsGetI64(data,tmp_case)) {
526  return 4401;
527  }
528  m_lastCase += tmp_case;
529  if (dose) {
530  EGS_ScoringArray tmp(nreg);
531  if (!tmp.setState(data)) {
532  return 4402;
533  }
534  (*dose) += tmp;
535  }
536  if (doseM) {
537  EGS_ScoringArray tmpM(nmedia);
538  if (!tmpM.setState(data)) {
539  return 4403;
540  }
541  (*doseM) += tmpM;
542  }
543  if (doseF) {
544  int nx=dose_geom->getNRegDir(0);
545  int ny=dose_geom->getNRegDir(1);
546  int nz=dose_geom->getNRegDir(2);
547  EGS_ScoringArray tmpF(nx*ny*nz);
548  if (!tmpF.setState(data)) {
549  return 4404;
550  }
551  (*doseF) += tmpF;
552  }
553  return 0;
554 }
555 
556 void EGS_DoseScoring::resetCounter() {
557  m_lastCase = 0;
558  if (dose) {
559  dose->reset();
560  }
561  if (doseM) {
562  doseM->reset();
563  }
564  if (doseF) {
565  doseF->reset();
566  }
567 }
568 
569 //*********************************************************************
570 // Process input for this ausgab object
571 //
572 // volume: Set to 1 cm3 by default
573 // One entry => same size dose scoring regions
574 // Several entries => volume for each dose region
575 // SAME as dose region number
576 // or else default value used
577 //
578 // dose scoring regions: Defaults to all regions in geometry
579 // dose regions => Individual regions
580 // dose start/stop region => Groups of consecutive
581 // dose regions
582 //
583 // If there is a mismatch between number of regions and volumes
584 // default volume values will be used. Default volume will be either
585 // the first volume entry or 1 g/cm3 if no volume entry found.
586 //
587 // TODO:
588 // - Classify in primary, scattered and total dose
589 // - Specify for wich media to score or not the dose
590 //
591 //**********************************************************************
592 extern "C" {
593 
594  EGS_DOSE_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input,
595  EGS_ObjectFactory *f) {
596  const static char *func = "createAusgabObject(dose_scoring)";
597  if (!input) {
598  egsWarning("%s: null input?\n",func);
599  return 0;
600  }
601  vector <EGS_Float> v_in;// voxel volume[s] in g/cm3
602  /* get voxel volume */
603  input->getInput("volume",v_in);
604  /* get dose scoring mode: region dose, medium dose or both */
605  vector<string> allowed_mode;
606  allowed_mode.push_back("no");
607  allowed_mode.push_back("yes");
608  int d_in_medium = input->getInput("medium dose",allowed_mode,0);
609  int d_in_region = input->getInput("region dose",allowed_mode,1);
610 
611  /* get dose regions */
612  string d_regionsString;
613  vector <int> d_regions;
614  bool using_all_regions=true;
615  vector <int> d_start, d_stop;
616  if (!input->getInput("dose regions",d_regionsString)&& d_regionsString.length()>0) {
617  using_all_regions = false; // individual regions
618  }
619  else {
620  int err1 = input->getInput("dose start region",d_start);
621  int err2 = input->getInput("dose stop region",d_stop);
622  if (!err1 && !err2) {
623  if (d_start.size()==d_stop.size()) { // group of dose regions
624  for (int i=0; i<d_start.size(); i++) {
625  int ir = d_start[i], fr = d_stop[i];
626  for (int ireg=ir; ireg<=fr; ireg++) {
627  d_regions.push_back(ireg);
628  }
629  }
630  using_all_regions = false;
631  }
632  else egsWarning(
633  "%s: Mismatch in start and stop dose region groups !!!\n"
634  " Calculating dose in ALL regions.\n",func);
635  }
636  }
637  EGS_Float norma = 1.0;
638  int err04 = input->getInput("normalization",norma);
639 
640  //================================================
641  // Check if one volume for each group requested.
642  // If not just pass the volumes read and if there
643  // is a mismatch, then the first volume element
644  // or 1 g/cm3 will be used.
645  //=================================================
646  vector <EGS_Float> volin;
647  // groups of regions with same volume
648  if (! using_all_regions && v_in.size()== d_start.size()) {
649  for (int i=0; i<d_start.size(); i++) {
650  int ir = d_start[i], fr = d_stop[i];
651  for (int ireg=ir; ireg<=fr; ireg++) {
652  volin.push_back(v_in[i]);
653  }
654  }
655  }
656  else { // all other possibilities handled here
657  volin = v_in;
658  }
659 
660  //see if the user wants to output the dose to a file for an EGS_XYZGeometry
661  bool outputdosefile=false;
662  EGS_Input *fileinp = input->takeInputItem("output dose file");
663  EGS_BaseGeometry *dgeom;
664  int ftype;
665  if (fileinp) {
666  //get geometry name and filename and do some checks
667  string gname;
668  int err05 = fileinp->getInput("geometry name",gname);
669  if (err05) {
670  egsFatal("EGS_DoseScoring: Output dose file: missing/incorrect input for name of geometry.\n");
671  }
672  else {
673  dgeom = EGS_BaseGeometry::getGeometry(gname);
674  if (!dgeom) {
675  egsFatal("EGS_DoseScoring: Output dose file: %s does not name an existing geometry\n",gname.c_str());
676  }
677  else if (dgeom->getType()!="EGS_XYZGeometry") {
678  egsFatal("EGS_DoseScoring: Output dose file: %s is not an EGS_XYZGeometry.\n",gname.c_str());
679  }
680  else {
681  string str;
682  if (fileinp->getInput("file type", str) < 0) {
683  ftype = 0;
684  }
685  else {
686  vector<string> allowed_ftype;
687  allowed_ftype.push_back("3ddose");
688  ftype = fileinp->getInput("file type", allowed_ftype, -1);
689  if (ftype < 0) {
690  egsFatal("EGS_DoseScoring: Output dose file: Invalid file type. Currently only 3ddose is supported.\n");
691  }
692  }
693  outputdosefile=true;
694  }
695  }
696  }
697 
698 
699  //=================================================
700 
701  /* Setup dose scoring object with input parameters */
702  EGS_DoseScoring *result = new EGS_DoseScoring("",f);
703  if (volin.size()==1) {
704  result->setVol(volin[0]); // one size for all regions
705  }
706  else if (volin.size()) {
707  result->setVol(volin); // regions with their volumes
708  }
709  else {
710  result->setVol(1.0); // default value if no entry
711  }
712  if (!using_all_regions) {
713  if (d_regions.size() > 0) {
714  result->setDoseRegions(d_regions);
715  }
716  else {
717  result->setDoseRegions(d_regionsString);
718  }
719  }
720  if (d_in_medium) {
721  result->setMediumScoring(true);
722  }
723  if (d_in_region) {
724  result->setRegionScoring(true);
725  }
726  if (outputdosefile) {
727  result->setOutputFile(true,dgeom,ftype);
728  }
729  result->setName(input);
730  if (!err04) {
731  result->setUserNorm(norma);
732  }
733  return result;
734  }
735 }
Base class for advanced EGSnrc C++ applications.
void getLabelRegions(const string &str, vector< int > &regs)
Gets the regions for the labels in str and pushes onto regs.
int getMedium(int ireg)
Returns the medium index in region ireg using C-style indexing.
bool isRealRegion(int ireg)
Returns true if ireg is a real region, false otherwise.
const string & getAppDir() const
Returns the absolute path to the user code directory.
void getNumberRegions(const string &str, vector< int > &regs)
Gets numbers out of str and pushes them onto regs.
int getIparallel() const
Returns the job number in a parallel run.
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
string description
A short ausgab object description.
EGS_Application * app
The application this object belongs to.
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
virtual const string & getType() const =0
Get the geometry type.
virtual EGS_Float getVolume(int ireg)
Calculates the volume of region ireg.
const string & getName() const
Get the name of this geometry.
virtual int getNRegDir(int idir)
virtual EGS_Float getBound(int idir, int ind)
Returns region boundaries in direction determined by idir.
static EGS_BaseGeometry * getGeometry(const string &Name)
Get a pointer to the geometry named Name.
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.
A class for storing information in a tree-like structure of key-value pairs. This class is used throu...
Definition: egs_input.h:182
EGS_Input * takeInputItem(const string &key, bool self=true)
Get the property named key.
Definition: egs_input.cpp:226
int getInput(const string &key, vector< string > &values) const
Assign values to an array of strings from an input identified by key.
Definition: egs_input.cpp:338
An object factory.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
const string & getObjectName() const
Get the object name.
string name
The object name.
A class for scoring an array of quantities (e.g. a dose distribution) in a Monte Carlo simulation.
Definition: egs_scoring.h:219
int regions() const
Returns the number of regions (or elements or bins, the most appropriate term depending on the way th...
Definition: egs_scoring.h:406
bool storeState(ostream &data)
Stores the state of the scoring array object into the data stream data.
Definition: egs_scoring.h:316
void currentResult(int ireg, double &r, double &dr)
Sets r to the result in region ireg and dr to its statistical uncertainty.
Definition: egs_scoring.h:280
void reset()
Reset the scoring array to a pristine state.
Definition: egs_scoring.h:368
bool setState(istream &data)
Sets the state fof the scoring array object from the data in the input stream data.
Definition: egs_scoring.h:340
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_Float y
y-component
Definition: egs_vector.h:62
EGS_Float z
z-component
Definition: egs_vector.h:63
EGS_Float x
x-component
Definition: egs_vector.h:61
A dose scoring ausgab object.
Global egspp functions header file.
EGS_Input class header file.
EGS_RADIATIVE_SPLITTING_EXPORT EGS_AusgabObject * createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f)
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...
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
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...
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.