54#include "egs_ausgab_object.h"
56#include "egs_run_control.h"
62#define egsGetRNGPointers F77_OBJ_(egs_get_rng_pointers,EGS_GET_RNG_POINTERS)
64#define egsGetRNGArray F77_OBJ_(egs_get_rng_array,EGS_GET_RNG_ARRAY)
66#define egsSetRNGState F77_OBJ_(egs_set_rng_state,EGS_SET_RNG_STATE)
68#define egsGetSteps F77_OBJ_(egs_get_steps,EGS_GET_STEPS)
70#define egsSetSteps F77_OBJ_(egs_set_steps,EGS_SET_STEPS)
71extern __extc__
void egsSetSteps(
const double *,
const double *);
72#define egsOpenUnits F77_OBJ_(egs_open_units,EGS_OPEN_UNITS)
74#define egsGetElectronData F77_OBJ_(egs_get_electron_data,EGS_GET_ELECTRON_DATA)
76 EGS_Float *,EGS_Float *,EGS_Float *),
const EGS_I32 *,
const EGS_I32 *);
77#define egsGetPhotonData F77_OBJ_(egs_get_photon_data,EGS_GET_PHOTON_DATA)
79 EGS_Float *,EGS_Float *,EGS_Float *),
const EGS_I32 *,
const EGS_I32 *);
82extern "C" void F77_OBJ_(egs_scale_xcc,EGS_SCALE_XCC)(
const int *,
const EGS_Float *);
83extern "C" void F77_OBJ_(egs_scale_bc,EGS_SCALE_BC)(
const int *,
const EGS_Float *);
84extern "C" void F77_OBJ_(egs_bcse,EGS_BCSE)(
const int *,
const EGS_Float *);
85extern "C" void F77_OBJ_(egs_uniform_photons,EGS_UNIFORM_PHOTONS)(
const int *,
const EGS_Float *);
88 EGS_Float x,y,z, r, R, theta, phi;
95 R = sqrt(x*x + y*y + z*z);
96 theta = acos(z/R)*180/M_PI;
97 phi = atan2(y, x)*180/M_PI;
100 cout <<
" R = " << R <<
"\n";
101 cout <<
" r = " << r <<
"\n";
102 cout <<
" z = " << z <<
"\n";
103 cout <<
" theta (deg) = " << theta <<
"\n";
104 cout <<
" phi (deg) = " << phi <<
"\n";
116 "\n ***************************************************"
120 "\n ***************************************************"
122 egsInformation(
"This is EB_Application %s based on\n"
123 " EGS_AdvancedApplication %s\n\n",
124 egsSimplifyCVSKey(
revision).c_str(),
125 egsSimplifyCVSKey(base_revision).c_str());
130 if (!geometry && !source) {
134 egsInformation(
"\n\negs_brachy Run Mode Information\n%s\n\n",
string(80,
'=').c_str());
136 egsInformation(
"Single generator (may be overriden later) = %s\n",
single_generator ?
"yes" :
"no");
139 "getCurrentResult phantom/reg = %s %d",
145 egsInformation(
"\n\negs_brachy Geometry Information\n%s\n\n",
string(80,
'=').c_str());
149 egsInformation(
"\n\negs_brachy Phantom Details\n%s\n\n",
string(80,
'=').c_str());
150 egsInformation(
" | | | | Sph (Rmin, Rmax) | | \n");
151 egsInformation(
" | | | Avg Vox Vol | RZ (Rmin, Rmax) | RZ (Zmin, Zmax) | \n");
152 egsInformation(
"Name | Type | Nreg | / cm^3 | XYZ (Xmin, Xmax) | XYZ (Ymin, Ymax) | XYZ (Zmin, Zmax)\n");
153 egsInformation(
"%s\n",
string(145,
'-').c_str());
158 EGS_BaseGeometry *geom = phant->
geometry;
160 string type = geom->getType();
162 if (type ==
"EGS_XYZGeometry") {
168 EGS_Float xmin, xmax, ymin, ymax, zmin, zmax;
177 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | (%8.3F, %8.3F) | (%8.3F, %8.3F)\n",
178 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
179 xmin, xmax, ymin, ymax, zmin, zmax
182 }
else if (type ==
"EGS_RZ") {
184 nr = geom->getNRegDir(EGS_RZGeometry::RDIR);
185 nz = geom->getNRegDir(EGS_RZGeometry::ZDIR);
187 EGS_Float rmin, rmax, zmin, zmax;
188 rmin = geom->getBound(EGS_RZGeometry::RDIR, 0);
189 rmax = geom->getBound(EGS_RZGeometry::RDIR, nr-1);
190 zmin = geom->getBound(EGS_RZGeometry::ZDIR, 0);
191 zmax = geom->getBound(EGS_RZGeometry::ZDIR, nz-1);
194 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | (%8.3F, %8.3F) |\n",
195 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
196 rmin, rmax, zmin, zmax
198 }
else if (type ==
"EGS_cSphericalShell" || type ==
"EGS_cSpheres") {
199 type = (type ==
"EGS_cSphericalShell" ?
"SphSh" :
"Sph");
201 int nr = geom->getNRegDir(0);
203 EGS_Float rmin, rmax;
204 rmin = geom->getBound(EGS_cSpheres::RDIR, 0);
205 rmax = geom->getBound(EGS_cSpheres::RDIR, nr);
208 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | | \n",
209 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
214 "%-30s| %20s | %9d | %12.5G | | | \n",
215 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
220 if (type ==
"EGS_XYZGeometryT") {
221 egsWarning(
"\n***WARNING***\nPhantom of type transformed XYZ geometry used. The number of voxels in each direction and their bounds in the egslog, 3ddose, and egsphant files will be incorrect due to current limitations of the egs++ geometry library.\n***WARNING***\n");
226 egsInformation(
"\n\negs_brachy Volume correction details\n%s\n",
string(80,
'-').c_str());
228 egsInformation(
"\nSource specific volume correction details\n%s\n",
string(80,
'-').c_str());
231 egsInformation(
"\nExtra volume correction details\n%s\n",
string(80,
'-').c_str());
234 egsInformation(
"\nFile volume correction details\n%s\n",
string(80,
'-').c_str());
237 egsInformation(
"\n\n");
239 geometry->printInfo();
243 egsInformation(
"\n\negs_brachy Source Information\n%s\n",
string(80,
'=').c_str());
244 egsInformation(
"%s\n\n", source->getSourceDescription());
247 "Applied source coordinate transform to %d source location(s)\n",
252 egsInformation(
"Single source generator = %s\n", (
single_generator ?
"yes" :
"no"));
253 egsInformation(
"Source | Location (x cm, y cm, z cm) | Rotated | Weight\n%s\n",
string(80,
'-').c_str());
257 "%6d | ( % 7.3F, % 7.3F, % 7.3F) | %5s | % 7.2G\n",
258 tt+1, trans.x, trans.y, trans.z,
266 egsInformation(
"\n\n");
270 if (a_objects_list.size() > 0) {
271 egsInformation(
"The following ausgab objects are included in the simulation\n");
272 egsInformation(
"===========================================================\n\n");
273 for (
size_t j=0; j<a_objects_list.size(); ++j) {
274 egsInformation(
"%s",a_objects_list[j]->getObjectDescription());
276 egsInformation(
"\n\n");
287 string::iterator end_pos = std::remove(str.begin(), str.end(),
' ');
288 str.erase(end_pos, str.end());
289 size_t found = str.find(
"includefile");
290 return found != string::npos;
296 string fname = constructIOFileName(
".egsinp",
false);
297 egsInformation(
"\n\nIncluded Files\n%s\n",
string(80,
'=').c_str());
298 egsInformation(
"Input file:\n\t%s\n", fname.c_str());
299 egsInformation(
"The following files were included in this simulation:\n");
300 ifstream inf(fname.c_str());
306 egsInformation(
"\t%s\n", muen::trim(line).c_str());
319 EGS_Input *ginput = input->getInputItem(
"geometry definition");
322 egsWarning(
"EB_Application::createGeometry: no geometry specification in this input\n");
323 egsFatal(
"Simulation stopped\n");
326 int err =
ginfo.initializeFromInput(ginput);
328 egsWarning(
"EB_Application::createGeometry: incomplete or incorrect geometry specification\n");
330 egsFatal(
"Simulation stopped\n");
333 err = EGS_AdvancedApplication::initGeometry();
336 egsWarning(
"Failed to create a geometry from input file\n");
338 egsFatal(
"Simulation stopped\n");
343 ginfo.setGeometryIndexes(geometry);
348 if (
ginfo.source_envelope_name ==
"") {
349 egsFatal(
"Missing 'source envelope geometry' input required for superposition mode\n");
354 egsFatal(
"source envelope geometry '%s' can not be found\n",
ginfo.source_envelope_name.c_str());
358 egsFatal(
"You must use an %s source envelope geometry type for superposition mode\n",
"EGS_ASwitchedEnvelope");
362 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
364 if (gr.
type ==
"EGS_ASwitchedEnvelope"){
365 egsFatal(
"EGS_ASwitchedEnvelope should not be used when not using 'run mode = superposition\n");
373 egsFatal(
"Failed to initiate source locations\n");
380 egsWarning(
"Failed to create phantom objects\n");
381 egsFatal(
"Simulation stopped\n");
393 vector<EGS_AffineTransform *> transforms;
395 EGS_Input *trans_inp;
397 while ((trans_inp = input->takeInputItem(
"transformation"))) {
398 EGS_AffineTransform *transform = EGS_AffineTransform::getTransformation(trans_inp);
400 egsWarning(
"Invalid transform input given\n");
403 transforms.push_back(transform);
419 EGS_Input *source_inp = input->getInputItem(
"source definition");
426 EGS_Input *source_loc_inp = source_inp->takeInputItem(
"transformations");
428 if (source_loc_inp) {
430 delete source_loc_inp;
434 EGS_AffineTransform *unity_trans =
new EGS_AffineTransform();
436 egsWarning(
"EB_Application:: missing or invalid source `transformations` input item. Assuming single source at origin\n");
439 EGS_Input *coord_inp = source_inp->takeInputItem(
"source coordinate transform");
441 EGS_AffineTransform *coord_transform = EGS_AffineTransform::getTransformation(coord_inp);
442 if (coord_inp->getInputItem(
"transformation")) {
444 egsFatal(
"EB_Application:: `source coordinate transform` must contain exactly one transformation\n");
447 if (!coord_transform) {
448 egsFatal(
"EB_Application:: invalid `source coordinate transform` input\n");
451 EGS_AffineTransform *composed =
new EGS_AffineTransform(
456 delete coord_transform;
464 EGS_Input *source_overlap_inp = source_inp->takeInputItem(
"source overlap check");
465 if (source_overlap_inp){
468 egsFatal(
"EB_Application:: checkSourceOverlaps detected an error.");
480 vector<string> yn_choices;
481 yn_choices.push_back(
"no");
482 yn_choices.push_back(
"yes");
483 bool check_source_overlap = (bool)inp->getInput(
"check source overlaps", yn_choices, 0);
491 vector<string> mode_choices;
492 mode_choices.push_back(
"warning");
493 mode_choices.push_back(
"fatal");
495 bool fatal = (bool)inp->getInput(
"warning mode", mode_choices, 1);
497 EGS_Input *shape_inp = inp->takeInputItem(
"shape");
499 EGS_BaseShape *bounds = EGS_BaseShape::createShape(shape_inp);
502 egsWarning(
"egs_brachy::checkSourceOverlaps - no `shape` input found.\n");
507 if (bounds_volume < 0){
508 egsWarning(
"egs_brachy::checkSourceOverlaps - Unable to get shape volume.");
512 vector<string> excluded;
513 inp->getInput(
"excluded geometries", excluded);
516 int err = inp->getInput(
"density of random points (cm^-3)", density);
518 egsWarning(
"egs_brachy::checkSourceOverlaps - The volume correction 'density of random points (cm^-3)' input was not found. Using 1E6/cm^3\n");
521 EGS_I64 npoints = (EGS_I64)floor(max(1., density*bounds_volume));
524 EGS_RandomGenerator *rng = EGS_RandomGenerator::defaultRNG();
528 EGS_BaseGeometry *base_source = 0;
529 string base_source_name;
530 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
532 if (find(
ginfo.source_names.begin(),
ginfo.source_names.end(), gr.
name) !=
ginfo.source_names.end()){
533 base_source = EGS_BaseGeometry::getGeometry(gr.
name);
534 base_source_name = gr.
name;
539 egsFatal(
"egs_brachy::checkSourceOverlaps - did not find base source geometry");
544 EGS_AffineTransform inv_base_transform;
545 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
549 if (gr.
type !=
"EGS_AEnvelope" && gr.
type !=
"EGS_ASwitchedEnvelope"){
557 vector<int> overlaps;
559 for (EGS_I64 i=0; i < npoints; i++) {
563 point = bounds->getRandomPoint(rng);
565 if (base_source->isWhere(point) < 0) {
568 inv_base_transform.transform(point);
574 EGS_Vector transformed(point);
582 EGS_Vector inner_transformed(transformed);
587 if (base_source->isWhere(inner_transformed) >= 0) {
589 overlaps.push_back(sa_idx);
590 overlaps.push_back(sb_idx);
607 if (overlaps.size() > 1){
608 string msg =
"Possible overlap of sources: ";
609 for (
int i=0; i < overlaps.size(); i++){
610 msg += to_string(overlaps[i]);
611 if (i != overlaps.size() -1 ){
615 egsInformation((msg+
"\n").c_str());
618 if (overlaps.size() > 1){
619 return fatal ? 1 : 0;
629 EGS_Input *vol_cor_inp = input->takeInputItem(
"volume correction");
631 egsWarning(
"Input item `volume correction` was not found\n");
651 vector<string> user_vols;
653 while ((ij = vol_cor_inp->takeInputItem(
"phantom region volumes")) != 0) {
656 ij->getInput(
"phantom name", phant_name);
659 egsFatal(
"`phanton region volume` specified for phantom `%s` which does not exist.", phant_name.c_str());
661 user_vols.push_back(phant_name);
664 vector<int> phantom_regs;
665 ij->getInput(
"region numbers", phantom_regs);
667 vector<EGS_Float> phantom_vols;
668 ij->getInput(
"region volumes", phantom_vols);
670 if (phantom_regs.size() != phantom_vols.size()){
672 "Mismatched number of inputs for `region numbers` and `region volumes` for phantom `%s`",
675 }
else if (phantom_regs.size() == 0){
677 "Missing `region numbers` or `region volumes` input for `phantom region volumes` block for phantom `%s`",
682 for (
size_t r = 0; r < phantom_regs.size(); r++){
694 string name = phant->
geometry->getName();
695 string type = phant->
geometry->getType();
696 if (phant->
needs_user_geoms && find(user_vols.begin(), user_vols.end(), name) == user_vols.end()){
698 "Missing `phantom region volume` block for phantom `%s`."
699 "Phantoms of type `%s` can not calculate volumes automatically.",
718 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
719 string name =
ginfo.phantom_names[idx];
721 EGS_BaseGeometry *phant_geom = EGS_BaseGeometry::getGeometry(name);
723 egsInformation(
"\n\nUnable to find phantom geometry `%s`.\n\n This is a fatal error\n\n", name.c_str());
728 set<int> global_regions;
730 for (
int reg=0; reg <
ginfo.nreg_total; reg++) {
731 if (
ginfo.phantomFromRegion(reg) == (
int)idx) {
732 global_regions.insert(reg);
736 if (global_regions.size()==0) {
738 "EB_Application::createPhantoms - No phantom regions detected for geometry '%s'.\n"
739 "Are you sure your phantom was included in the final simulation geometry?\n",
740 (phant_geom->getName()).c_str()
756 EGS_Input *source_inp = input->getInputItem(
"source definition");
778 int err = EGS_AdvancedApplication::initSource();
780 egsFatal(
"Failed to initialize source\n");
783 string stype = source->getObjectType();
784 is_phsp_source = stype ==
"EGS_PhspSource" || stype ==
"EB_IAEAPHSPSource";
788 egsInformation(
"Phase space being used. Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
801 int res = EGS_AdvancedApplication::initSimulation();
818 vector<string> format_choices;
819 format_choices.push_back(
"text");
820 format_choices.push_back(
"gzip");
821 EGS_Input *run_control = input->getInputItem(
"run control");
822 int format = run_control->getInput(
"egsdat file format", format_choices, 0);
829 run =
new EGS_RunControl(
this);
831 else if (uniform_run) {
835 run = EGS_RunControl::getRunControlObject(
this);
847 EGS_Input *rm = input->takeInputItem(
"run mode");
853 vector<string> choices;
854 choices.push_back(
"normal");
855 choices.push_back(
"superposition");
856 choices.push_back(
"volume correction only");
862 vector<string> yn_choices;
863 yn_choices.push_back(
"no");
864 yn_choices.push_back(
"yes");
878 EGS_Input *transportp = input->getInputItem(
"MC transport parameter");
880 transportp = input->getInputItem(
"transport parameter");
884 egsFatal(
"Missing `MC transport parameter` input item\n");
888 int err = transportp->getInput(
"fluorescent photon cutoff",
flu_cutoff);
893 int ret = EGS_AdvancedApplication::initCrossSections();
898 err = transportp->getInput(
"source ecut",
source_ecut);
903 err = transportp->getInput(
"source pcut",
source_pcut);
908 egsInformation(
"\negs_brachy transport parameter options:\n%s\n",
string(80,
'-').c_str());
909 egsInformation(
"Fluorescent photon cutoff %.3G\n",
flu_cutoff);
922 EGS_Input *options = input->takeInputItem(
"scoring options");
943 egsFatal(
"\n\nMissing input section 'scoring options'\n\n");
957 vector<string> gcr_inp;
958 int err = inp->getInput(
"current result phantom region", gcr_inp);
959 if (err || gcr_inp.size()==0) {
967 if (gcr_inp.size() >= 1) {
968 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
969 if (
ginfo.phantom_names[idx] == gcr_inp[0]) {
978 "Did not find '%s' phantom for getCurrentResult. Using phantom %s\n",
979 gcr_inp[0].c_str(),
ginfo.phantom_names[0].c_str()
987 if (gcr_inp.size() > 1) {
988 int ireg = atol(gcr_inp[1].c_str());
989 if (ireg > 0 && ireg < gcr_phantom->geometry->regions()) {
997 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
998 if (
ginfo.phantom_names[idx] == name) {
1009 vector<string> yn_choices;
1010 yn_choices.push_back(
"no");
1011 yn_choices.push_back(
"yes");
1012 output_egsphant = (bool)inp->getInput(
"output egsphant files", yn_choices, 0);
1013 output_voxinfo = (bool)inp->getInput(
"output voxel info files", yn_choices, 0);
1016 vector<string> format_choices;
1017 format_choices.push_back(
"text");
1018 format_choices.push_back(
"gzip");
1020 int format = inp->getInput(
"dose file format", format_choices, 0);
1023 format = inp->getInput(
"egsphant file format", format_choices, 0);
1026 format = inp->getInput(
"voxel info file format", format_choices, 0);
1029 format = inp->getInput(
"volume correction file format", format_choices, 0);
1032 inp->getInput(
"record initial particle positions",
record_n_init);
1038 EGS_Input *phsp_inp = inp->takeInputItem(
"phsp scoring");
1049 timing_blocks.addTimer(
"egs_brachy::initVarianceReduction");
1051 egsInformation(
"\n\negs_brachy Variance Reduction Information\n%s\n\n",
string(80,
'=').c_str());
1053 EGS_Input *vr = input->takeInputItem(
"variance reduction");
1067 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1068 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1069 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1070 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1076 EGS_Input *ri = vr->takeInputItem(
"particle recycling");
1079 egsFatal(
"Primary-scatter dose scoring is not available with recycling. Please turn off recycling or disable scatter dose scoring.\n");
1081 egsInformation(
"Particle Recycling\n");
1086 egsInformation(
" Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
1088 egsInformation(
"\n");
1094 vector<string> yn_choices;
1095 yn_choices.push_back(
"no");
1096 yn_choices.push_back(
"yes");
1098 string old_rr_setting;
1099 int err = vr->getInput(
"range rejection", old_rr_setting);
1102 "'range rejection' is not a valid setting for egs_brachy.\n"
1103 "Please use 'global range rejection' and 'source range rejection' settings instead.\n"
1107 EGS_Float old_rr_max_e;
1108 err = vr->getInput(
"range rejection max energy", old_rr_max_e);
1111 "'range rejection max energy' is not a valid setting for egs_brachy.\n"
1112 "Please use 'global range rejection max energy' and 'source range rejection max energy' settings instead.\n"
1117 global_i_do_rr = vr->getInput(
"global range rejection", yn_choices, 1);
1118 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1120 int err = vr->getInput(
"global range rejection max energy",
global_e_max_rr);
1125 egsFatal(
"Global Range Rejection max energy must be at least 0.512MeV\n");
1127 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1131 source_i_do_rr = vr->getInput(
"source range rejection", yn_choices, 0);
1132 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1134 int err = vr->getInput(
"source range rejection max energy",
source_e_max_rr);
1139 egsFatal(
"Source Range Rejection max energy must be at least 0.512MeV\n");
1141 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1151 egsInformation(
"BCSE = %s\n",
do_bcse ?
"Yes" :
"No");
1154 " Brem Cross Section Enhancement medium = %s (%d)\n",
1157 egsInformation(
" Brem Cross Section Enhancement factor = %.3G\n",
bcse_factor);
1162 err = vr->getInput(
"split brem photons",
nbr_split);
1163 egsInformation(
"Brem Splitting = %s\n",
nbr_split > 1?
"Yes" :
"No");
1166 egsInformation(
" Splitting brem photons N times = %d\n",
nbr_split);
1173 egsInformation(
"Charged Particle Russian Roulette = %s\n", the_egsvr->i_play_RR ?
"Yes" :
"No");
1174 if (!err || the_egsvr->i_play_RR) {
1179 " Survival probability (1/nbrsplt*bcse) = 1/(%d*%.3G) (%.3G%%)\n",
1185 " Survival probability (1/nbrsplt) = 1/%d (%.3G%%)\n",
1200 vector<string> yn_choices;
1201 yn_choices.push_back(
"no");
1202 yn_choices.push_back(
"yes");
1204 int play_rr = scoring_options->getInput(
"russian roulette", yn_choices, 0);
1209 the_egsvr->i_play_RR = 1;
1211 AusgabCall rr_calls[] = {
1212 BeforeBrems, AfterBrems,
1213 BeforeAnnihFlight, AfterAnnihFlight,
1214 BeforeAnnihRest, AfterAnnihRest,
1218 int ncalls =
sizeof(rr_calls)/
sizeof(rr_calls[0]);
1226 vector<string> bcse_inp;
1227 int err = inp->getInput(
"bcse medium", bcse_inp);
1228 if (err || bcse_inp.size()==0) {
1232 bcse_med_num = EGS_BaseGeometry::getMediumIndex(bcse_inp[0]);
1234 egsWarning(
"Requested an unknown medium `%s` for BCSE\n",bcse_inp[0].c_str());
1239 if (bcse_inp.size() == 1) {
1250 the_egsvr->i_play_RR = 1;
1252 AusgabCall bcse_calls[] = {BeforeBrems, AfterBrems, FluorescentEvent};
1263 bool header_printed =
false;
1265 while (EGS_Input *spec_inp=scoring_input->takeInputItem(
"spectrum scoring")) {
1267 if (!header_printed) {
1268 egsInformation(
"\n\negs_brachy Spectrum Scoring Information\n%s\n\n",
string(80,
'=').c_str());
1269 header_printed =
true;
1276 egsInformation(
"Added scorer with title: %s\n", scorer->
getInfo().c_str());
1283 for (
size_t call=BeforeTransport; call <= UnknownCall; call++) {
1284 setAusgabCall((AusgabCall)call,
false);
1294 AusgabCall always_call[] = {BeforeTransport, AfterTransport, FluorescentEvent};
1303 vector<string> choices;
1304 choices.push_back(
"no");
1305 choices.push_back(
"yes");
1307 score_tlen = scoring_options->getInput(
"score tracklength dose", choices, 1);
1320 map<string, string> muen_for_med;
1322 vector<string> muen_meds;
1323 scoring_options->getInput(
"muen for media", muen_meds);
1325 for (
size_t i=0; i < muen_meds.size(); i++) {
1326 string med_name = muen_meds[i];
1327 muen_for_med[med_name] = med_name;
1330 EGS_Input *muen_inp;
1331 while ((muen_inp = scoring_options->takeInputItem(
"muen for medium"))) {
1332 string scoring, transport;
1333 int err = muen_inp->getInput(
"transport medium", transport);
1335 egsFatal(
"Missing 'transport medium' key in 'muen for medium' block\n");
1338 err = muen_inp->getInput(
"scoring medium", scoring);
1340 egsFatal(
"Missing 'scoring medium' key in 'muen for medium' block\n");
1344 muen_for_med[transport] = scoring;
1349 return muen_for_med;
1355 egsInformation(
"\n\negs_brachy Muen Data Information\n%s\n\n",
string(80,
'=').c_str());
1358 bool missing_muen = scoring_options->getInput(
"muen file", muen_file) != 0;
1360 egsFatal(
"\n\nMissing input scoring options: muen file\n\n This is a fatal error\n\n");
1368 "EB_Application:: missing or invalid 'muen for media' input item or 'muen substitution' block(s).\n"
1369 " No muen data has been read.\n"
1377 egsFatal(
"Failed to read muen data from %s\n",muen_file.c_str());
1380 egsInformation(
"Read muen data from %s\n", muen_file.c_str());
1385 string transport_med = mit->first;
1386 string scoring_med = mit->second;
1389 egsFatal(
"EB_Application::Failed to get muen interpolator for %s\n", scoring_med.c_str());
1392 int med_idx = EGS_BaseGeometry::getMediumIndex(transport_med);
1395 "EB_Application:: You requested scoring medium %s for transport medium %s but %s"
1396 " is not present in the geometry\n", scoring_med.c_str(), transport_med.c_str(), transport_med.c_str()
1402 "Set medium %d (%s) to use muen data: %s\n",
1403 med_idx, transport_med.c_str(), scoring_med.c_str()
1411 for (
int i= 0; i < ncalls; i++) {
1412 setAusgabCall(calls[i],
true);
1420 vector<string> choices;
1421 choices.push_back(
"no");
1422 choices.push_back(
"yes");
1424 score_edep = scoring_options->getInput(
"score energy deposition", choices, 0);
1431 AusgabCall edep_calls[] = {ExtraEnergy, UserDiscard, PegsCut, EgsCut};
1439 vector<string> choices;
1440 choices.push_back(
"no");
1441 choices.push_back(
"yes");
1443 score_scat = scoring_options->getInput(
"score scatter dose", choices, 0);
1445 egsFatal(
"\nPrimary-scatter dose scoring requires tracklength scoring. Please enable tracklength scoring or disable scatter dose scoring.\n");
1449 egsFatal(
"\nPrimary-scatter dose scoring is only available in simulations with a single source. Please simulate a single source or disable scatter dose scoring.\n");
1453 egsFatal(
"\nPrimary-scatter dose scoring is not available with phase-space sources. Please do not use a phase-space source or disable scatter dose scoring.\n");
1462 AusgabCall photon_scat_calls[] = {
1463 AfterAnnihFlight, AfterAnnihRest,
1464 AfterPair, AfterCompton, AfterPhoto, AfterRayleigh,
1468 int ncalls =
sizeof(photon_scat_calls)/
sizeof(photon_scat_calls[0]);
1475 EGS_Float scale = 1.;
1477 int err = scoring_options->getInput(
"dose scaling factor", scale);
1479 if (!err && scale > 0) {
1490 while ((scale = scoring_options->takeInputItem(
"scale xcc"))) {
1492 int err = scale->getInput(
"scale xcc",tmp);
1494 if (!err && tmp.size() == 2) {
1495 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1497 EGS_Float fac = atof(tmp[1].c_str());
1498 egsInformation(
"\n ***** Scaling xcc of medium %d with %G\n",imed,fac);
1499 F77_OBJ_(egs_scale_xcc,EGS_SCALE_XCC)(&imed,&fac);
1505 while ((scale = scoring_options->takeInputItem(
"scale bc"))) {
1507 int err = scale->getInput(
"scale bc",tmp);
1509 if (!err && tmp.size() == 2) {
1510 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1512 EGS_Float fac = atof(tmp[1].c_str());
1513 egsInformation(
"\n ***** Scaling bc of medium %d with %G\n",imed,fac);
1514 F77_OBJ_(egs_scale_bc,EGS_SCALE_BC)(&imed,&fac);
1526 EGS_Vector new_loc(p->x);
1527 EGS_Vector new_dir(p->u);
1534 double angle = 2*M_PI*rndm->getUniform();
1535 EGS_RotationMatrix rot = EGS_RotationMatrix::rotZ(angle);
1545 int new_reg = geometry->isWhere(new_loc);
1546 int new_med = geometry->medium(new_reg);
1550 int cur_np = the_stack->np;
1551 int new_np = the_stack->np+1;
1552 int np_idx = new_np-1;
1554 the_stack->ir[np_idx] = new_reg + 2;
1555 the_stack->latch[np_idx] = p->latch;
1556 the_stack->E[np_idx] = p->E;
1557 the_stack->wt[np_idx] = new_wt;;
1558 the_stack->iq[np_idx] = p->q;
1559 the_stack->x[np_idx] = new_loc.x;
1560 the_stack->y[np_idx] = new_loc.y;
1561 the_stack->z[np_idx] = new_loc.z;
1562 the_stack->u[np_idx] = new_dir.x;
1563 the_stack->v[np_idx] = new_dir.y;
1564 the_stack->w[np_idx] = new_dir.z;
1565 the_stack->dnear[np_idx] = 0;
1568 the_stack->npold = cur_np;
1570 the_epcont->irnew = new_reg+2;
1571 the_useful->medium_new = new_med+1;
1576 the_stack->wt[np_idx-1] = 0;
1583 EGS_AdvancedApplication::startNewParticle();
1585 int ireg = the_stack->ir[the_stack->np-1] - 2;
1586 if (
ginfo.isSource(ireg)) {
1598 EGS_AdvancedApplication::enterNewRegion();
1600 int ireg = the_epcont->irnew-2;
1601 if (
ginfo.isSource(ireg)) {
1618 the_stack->wt[the_stack->np-1] = 0;
1619 the_epcont->idisc = idisc;
1631 for (
int recycle_idx=0; recycle_idx <
recycle_opts->nrecycle; recycle_idx++) {
1633 int start_loc, stop_loc;
1637 stop_loc = start_loc + 1;
1643 for (
int source_loc = start_loc; source_loc < stop_loc; source_loc++) {
1646 bool kill = source_loc == start_loc && recycle_idx == 0 && !new_hist;
1659 bool same_particle = the_stack->npold == the_stack->np;
1660 if (!same_particle){
1665 cur_R = top_p.x.length2();
1674 egsWarning(
"Particle hasn't moved in %d steps. Discarding particle\n",
NUM_STUCK_STEPS);
1687 bool is_photon = top_p.q == 0;
1688 bool is_before_transport = iarg == BeforeTransport;
1689 bool is_after_transport = iarg == AfterTransport;
1691 if (is_after_transport &&
isStuck()) {
1692 the_stack->latch[the_stack->np - 1] = top_p.latch;
1696 int global_ir = top_p.ir;
1697 int irnew = the_epcont->irnew-2;
1698 int irold = the_epcont->irold-2;
1700 bool in_phantom =
ginfo.isPhantom(global_ir);
1701 bool in_source =
ginfo.isSource(global_ir);
1703 bool is_extra_scoring_reg =
false;
1704 string local_geom_name =
"";
1705 int local_geom_ir = -1;
1706 int extra_reg_dose_index = -1;
1712 local_geom_ir = local.second;
1713 local_geom_name = local.first->getName();
1716 map<string, vector<int> >::iterator i =
extra_scoring_reg.find(local_geom_name);
1718 vector<int>::iterator it = find(i->second.begin(), i->second.end(), local_geom_ir);
1719 if (it != i->second.end()){
1720 is_extra_scoring_reg =
true;
1721 extra_reg_dose_index = distance(i->second.begin(), it);
1727 if (is_before_transport) {
1730 }
else if (in_phantom) {
1738 bool discard_fluorescent = iarg == FluorescentEvent && top_p.E <=
flu_cutoff;
1739 if (discard_fluorescent) {
1741 the_stack->latch[the_stack->np - 1] = top_p.latch;
1746 if (
score_scat && (iarg > AfterTransport) && !in_source) {
1748 for (
int ip=the_stack->npold-1; ip < the_stack->np; ip++) {
1753 bool next_is_source =
ginfo.isSource(irnew);
1754 bool last_was_source =
ginfo.isSource(irold);
1758 bool leaving_source = is_before_transport && in_source && !next_is_source;
1759 bool escaping_source = leaving_source && !
latch_control.hasEscaped(&top_p);
1762 bool left_source = is_after_transport && !in_source && last_was_source;
1763 bool escaped_source = left_source && !
latch_control.hasEscaped(&top_p);
1765 bool escaping_geom = is_before_transport && irnew < 0;
1766 bool escaped_geom = global_ir < 0;
1779 int nmesg =
sizeof(send_messages)/
sizeof(send_messages[0]);
1780 for (
int m=0; m < nmesg; m++) {
1781 if (send_messages[m].first) {
1782 pevent_pub.notify(send_messages[m].second, &top_p);
1788 the_stack->latch[the_stack->np - 1] = top_p.latch;
1795 if (escaped_source && is_after_transport) {
1797 EGS_Float wt = top_p.wt;
1818 bool in_vaccuum = the_useful->medium <= 0;
1819 bool score_tracklength =
score_tlen && is_photon && is_before_transport;
1820 bool score_interaction =
score_edep && iarg <= ExtraEnergy;
1821 bool dose_scoring_not_needed = !is_extra_scoring_reg && (!in_phantom || in_vaccuum || !(score_tracklength || score_interaction));
1823 if (dose_scoring_not_needed) {
1829 int phant_idx =
ginfo.phantomFromRegion(global_ir);
1830 int phant_ir =
ginfo.globalToLocalReg(global_ir);
1837 if (score_tracklength) {
1839 EGS_Interpolator *interp =
media_muen[the_useful->medium-1];
1840 EGS_Float muen_val = interp ? interp->interpolateFast(the_epcont->gle) : 0;
1841 EGS_Float tracklength_edep = the_epcont->tvstep*top_p.E*muen_val*top_p.wt;
1846 if (needs_vol_cor) {
1853 phant->
scoreTlen(phant_ir, tracklength_edep / vol, &top_p);
1857 if (is_extra_scoring_reg){
1859 extra_scoring_doses[local_geom_name]->score(extra_reg_dose_index, tracklength_edep / vol);
1863 if (score_interaction) {
1867 EGS_Float edep = getEdep()*top_p.wt;
1878 phant->
scoreEdep(phant_ir, edep / mass);
1882 if (is_extra_scoring_reg){
1893 bool is_phat = fabs(top_p.wt - 1.) <
EB_EPSILON;
1897 bool in_bcse_med = the_useful->medium - 1 ==
bcse_med_num;
1899 if (iarg == BeforeBrems) {
1905 }
else if (iarg == AfterBrems) {
1909 for (
int ip=the_stack->npold; ip < the_stack->np; ip++) {
1912 EGS_Float rnd = rndm->getUniform();
1914 the_stack->E[the_stack->npold-1] += top_p.E;
1918 the_egsvr->nbr_split = 1;
1921 }
else if (iarg == FluorescentEvent && is_phat) {
1929 the_stack->npold = the_stack->np;
1930 F77_OBJ_(egs_uniform_photons, EGS_UNIFORM_PHOTONS)(&nsplit, &top_p.E);
1934 }
else if (
do_brem_split && iarg == FluorescentEvent && is_phat) {
1937 the_stack->npold = the_stack->np;
1967 string sep(80,
'=');
1969 "\n\nResults for egs_brachy run\n%s\n",
1970 string(80,
'-').c_str()
1974 egsInformation(
"\n\nHistory Information\n%s\n",sep.c_str());
1975 egsInformation(
"Last case = %llu\n", last_case);
1976 egsInformation(
"current case = %llu\n", current_case);
1977 egsInformation(
"run->getNcase() = %llu\n", run->getNcase());
1978 egsInformation(
"source->getFluence() = %f\n", source->getFluence());
1980 egsInformation(
"Particles recycled = %d\n",
recycle_opts->nrecycle);
1985 egsInformation(
"\n\nGeometry Errors\n%s\n", sep.c_str());
1986 egsInformation(
"Number of geometry errors (/max allowed) = %d / %d\n", run->geomErrorCount, run->geomErrorMax);
1987 egsInformation(
"Number of 'stuck' particles discarded = %llu\n",
n_stuck);
1992 EGS_I64 hist_norm = run->getNdone();
1997 "Warning: Stats about energy escaping source may not be accurate when "
1998 "not using a single source generator\n"
2003 phsp->finish(current_case);
2004 phsp->outputResults();
2005 phsp->destroySource();
2013 egsInformation(
"\nSpectrum scoring results\n%s\n",sep.c_str());
2014 string root = constructIOFileName(
"",
true);
2018 (*it)->outputResults(root);
2024 string fname = constructIOFileName(
"",
true)+
".pinit";
2026 out.open(fname.c_str());
2027 out << std::fixed << std::showpoint << std::setprecision(6);
2029 out << (*it).x <<
"\t" << (*it).y <<
"\t" << (*it).z <<
"\n";
2032 egsInformation(
"\nInitial Particle Positions\n%s\n",sep.c_str());
2033 egsInformation(
"%d Initial particle positions written to .pinit file\n",
p_init_locs.size());
2045 (*p)->outputResults(20, dd_format, ep_format, vi_format, vc_format);
2050 egsInformation(
"\nStep Counts\n%s\n", sep.c_str());
2051 EGS_Float total_steps = 0;
2053 for (
int i=-1; i < 2; i++) {
2059 egsInformation(
"Total particle steps : %20llu\n", (EGS_I64)total_steps);
2060 for (
int i=-1; i < 2; i++) {
2062 egsInformation(
"q=%2d Steps taken in sources : %20llu (%.2f%%)\n", i,
steps_in_sources[i],
2066 egsInformation(
"q=%2d Steps taken in phantoms : %20llu (%.2f%%)\n", i,
steps_in_phantoms[i],
2070 egsInformation(
"q=%2d Steps taken in other objects : %20llu (%.2f%%)\n", i,
steps_in_other[i],
2084 count = current_case;
2094 int result = EGS_Application::runSimulation();
2102 last_case = current_case;
2104 current_case = source->getNextParticle(rndm, p.q, p.latch, p.E, p.wt, p.x, p.u);
2123 p.ir = geometry->isWhere(p.x);
2126 egsWarning(
"EB_Application::simulateSingleShower() - particle initiated at (x, y, z) = (%.2g, %.2g, %.2g)\n", p.x.x, p.x.y, p.x.z);
2127 egsFatal(
"EB_Application::simulateSingleShower() - Particle initiated outside "
2128 "the geometry! Please check your source locations.\n");
2139 }
else if (!
ginfo.isSource(p.ir)) {
2145 "Particle started in region %d (%s reg %d) which is outside a source geometry. Please check your geometry\n",
2147 r.first->getName().c_str(),
2157 cur_R = p.x.length2();
2181 return err || finishShower();
2192 int err = EGS_Application::startNewShower();
2199 if (current_case != last_case) {
2203 last_case = current_case;
2213 if (!run->storeState(*out)) {
2216 if (!egsStoreI64(*out,current_case)) {
2220 if (!rndm->storeState(*out)) {
2223 if (!source->storeState(*out)) {
2226 for (
size_t j=0; j<a_objects_list.size(); ++j) {
2227 if (!a_objects_list[j]->storeState(*out)) {
2242 if (np > 10000000) {
2243 egsWarning(
"EGS_AdvancedApplication::outputData(): egsGetRNGPointers"
2244 " returns a huge number? (%d)\n",np);
2247 EGS_Float *array =
new EGS_Float [np];
2249 (*out) <<
" " << np <<
" " << ip <<
"\n";
2250 for (
int j=0; j<np; j++) {
2251 (*out) << array[j] <<
" ";
2254 double ch_steps, all_steps;
2256 (*out) << ch_steps <<
" " << all_steps <<
"\n";
2258 return out->good() ? 0 : 13;
2266 (*out) << std::setprecision(9);
2268 for (
int i=-1; i < 2; i++) {
2283 err = (*spec_it)->outputData(out);
2289 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2291 err = (*phant_it)->outputData(out);
2320 string extension(
".egsdat");
2321 extension += (use_gz ?
".gz" :
"");
2322 string ofile = constructIOFileName(extension.c_str(),
true);
2332 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2343 data_out =
new ofstream(ofile.c_str());
2345 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2359 if (!run->setState(*in)) {
2362 if (!egsGetI64(*in,current_case)) {
2365 last_case = current_case;
2366 if (!rndm->setState(*in)) {
2369 if (!source->setState(*in)) {
2372 for (
int j=0; j<a_objects_list.size(); ++j) {
2373 if (!a_objects_list[j]->setState(*in)) {
2387 if (np > 10000000) {
2388 egsWarning(
"EB_Application::egsAdvApplicationReadData(): got huge size "
2389 "for the mortran random array? (%d)\n",np);
2392 EGS_Float *array =
new EGS_Float [np];
2393 for (
int j=0; j<np; j++) {
2401 double ch_steps, all_steps;
2402 (*in) >> ch_steps >> all_steps;
2404 return in->good() ? 0 : 13;
2411 for (
int i=-1; i < 2; i++) {
2426 err = (*spec_it)->readData(in);
2432 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2434 err = (*phant_it)->readData(in);
2463 string extension(
".egsdat");
2464 extension += (use_gz ?
".gz" :
"");
2465 string ifile = constructIOFileName(extension.c_str(),
false);
2475 egsWarning(
"EGS_Application::readData: failed to open %s for reading\n", ifile.c_str());
2485 data_in =
new ifstream(ifile.c_str());
2487 egsWarning(
"EGS_Application::readData: failed to open %s for writing\n",ifile.c_str());
2503 "\n Suming the following .egsdat files:\n"
2504 "=======================================================================\n");
2507 EGS_Float last_cpu = 0;
2508 EGS_I64 last_ncase = 0;
2511 for (
int j=1; j<500; j++) {
2514 string name(
"%s_w%d.egsdat");
2515 name += (use_gz ?
".gz" :
"");
2517 sprintf(buf, name.c_str(), output_file.c_str(), j);
2518 string dfile = egsJoinPath(app_dir,buf);
2522 bool opened =
false;
2524 gzin.
open(dfile.c_str());
2528 in.open(dfile.c_str());
2529 opened = in.is_open();
2537 EGS_I64 ncase = run->getNdone();
2538 EGS_Float cpu = run->getCPUTime();
2539 egsInformation(
"%2d %-30s ncase=%-14lld cpu=%-11.2f\n",
2540 ndat,buf,ncase-last_ncase,cpu-last_cpu);
2545 egsWarning(
"%2d %-30s error %d\n",ndat,buf,err);
2551 "=======================================================================\n");
2552 egsInformation(
"%40s%-14lld cpu=%-11.2f\n\n",
"Total ncase=",last_ncase,
2564 EGS_AdvancedApplication::resetCounter();
2567 for (
int i=-1; i < 2; i++) {
2579 (*spec_it)->resetCounter();
2582 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2584 (*phant_it)->resetCounter();
2592 int err = EGS_AdvancedApplication::addState(data);
2597 for (
int i=-1; i < 2; i++) {
2598 EGS_I64 steps_in_sources_tmp;
2599 EGS_I64 steps_in_phantoms_tmp;
2600 EGS_I64 steps_in_other_tmp;
2602 data >> steps_in_sources_tmp;
2603 data >> steps_in_phantoms_tmp;
2604 data >> steps_in_other_tmp;
2620 err = (*spec_it)->addState(data);
2626 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2628 err = (*phant_it)->addState(data);
2641 return (stat(name.c_str(), &buffer) == 0);
2647 int n_of_egsdat = 0;
2650 string name(
"%s_w%d.egsdat");
2651 name += (use_gz ?
".gz" :
"");
2653 for (
int i = first_parallel; i < first_parallel + n_parallel; i++) {
2654 sprintf(buf,name.c_str(),final_output_file.c_str(),i);
2655 string dfile = egsJoinPath(app_dir,buf);
2675 int err = input->getInput(
"interval wait time", dummy);
2681 err = input->getInput(
"number of intervals", dummy);
2688 err = input->getInput(
"watcher jobs", w_jobs);
2690 for (
int i = 0; i < w_jobs.size(); i++) {
2691 if (
ipar == w_jobs[i]) {
2708 vector<string> check_options;
2709 check_options.push_back(
"yes");
2710 check_options.push_back(
"no");
2711 int ichk = input->getInput(
"check jobs completed",check_options,0);
2732 string name(
"%s_w%d.egsdat");
2733 name += (use_gz ?
".gz" :
"");
2737 sprintf(buf,name.c_str(),
app->getFinalOutputFile().c_str(),
ipar);
2738 string datFile = egsJoinPath(
app->getAppDir(),buf);
2739 if (remove(datFile.c_str()) == 0) {
2740 egsWarning(
"EB_UniformRunControl: %s deleted\n",
2745 return EGS_RunControl::startSimulation();
2750 EGS_RunControl::describeRCO();
2755 " Watcher job: remains running after completion checking\n"
2756 " for other jobs finishing every %d s for %d s!\n",
2761 " Option to check for finishing jobs is OFF!\n\n");
2771 usleep(mscnds * 1000);
2776 int err = EGS_RunControl::finishSimulation();
2782 int interval = 0, njobs_done = 0, njobs_done_old= 0;
2786 njobs_done =
app->howManyJobsDone();
2788 if (njobs_done ==
npar - 1) {
2793 if (njobs_done_old < njobs_done) {
2794 egsInformation(
"=> Combining %d jobs ...\n",njobs_done);
2795 app->combinePartialResults();
2797 njobs_done_old = njobs_done;
abstract base class for scoring spectrum information
static BaseSpectrumScorer * getSpectrumScorer(EGS_Input *inp, EGS_BaseSource *source, GeomInfo *ginfo, Publisher *publisher)
factory method for creating one of the derived spectrum scoring classes
virtual string getInfo() const
The main egs_brachy application class. See the Main Page for full documentation.
vector< BaseSpectrumScorer * > spectrum_scorers
map< string, vector< EGS_Float > > extra_scoring_mass
int initRunControl()
egs_brachy specific run control initialization
void initPHSPScoring(EGS_Input *)
set up phsp scoring
int checkSourceOverlaps(EGS_Input *)
EnergyScoringStats * escoring
Energy related scoring/stats.
int initSimulation()
set the run mode and then call EGS_AdvancedApplication::initSimulation
void initEDepScoring(EGS_Input *)
energy deposition scoring initialization
void copyParticleToSourceLoc(EGS_Particle *p, int source, bool kill_orig, bool rotate, EGS_Float new_wt)
void doPhotonSplitting(int)
int outputData()
Output intermediate results. The egs_brachy version outputs the standard egs++ data along with egs_br...
vector< EGS_AffineTransform * > source_transforms
transforms to locations of all sources
map< string, vector< int > > extra_scoring_reg
void initDoseScaling(EGS_Input *)
Initialize dose scaling factor if requested.
map< int, EGS_I64 > steps_in_phantoms
int initSourceTransforms()
read in the location of all particle sources and optionally apply a source coordinate transform mappi...
int outputDataHelper(ostream *)
helper function for outputData
EB_TimingTree timing_blocks
Track CPU times of various functions.
int initRussianRoulette(EGS_Input *)
Initialize Russian roulette variance reduction if requested.
map< string, EGS_ScoringArray * > extra_scoring_doses
string output_volcor_format
text or gzip
int createPhantoms()
set up Phantom objects for any geometries that user has requested scoring for
Publisher pevent_pub
Particle event publisher.
virtual void startNewParticle()
Set source ecut/pcut if different from global ecut/pcut.
void describeUserCode() const
Print information about the egs_brachy user code.
int initRunMode()
Get run mode from the input file.
void describeSimulation()
Describe the simulation.
void enableAusgabCalls(int ncalls, AusgabCall calls[])
enable an array of ausgab calls
void initAusgabCalls()
setup any required ausgab calls
void initMuenData(EGS_Input *)
load muen data for requested media
string output_egsdat_format
text or gzip
vector< string > output_volcor_phantoms
vector of phantom names to output volume correctino files for
string output_voxinfo_format
text or gzip
igzstream * gz_data_in
GZip file for outputing egsdat.
EGS_Float global_e_max_rr
max range rejection energy globally
int egsAdvApplicationOutputData(ostream *)
helper function for outputData
void discardTopParticle(int idisc=1)
int gcr_phantom_reg
region of phantom to use for getCurrentResult (default to 0)
EGS_Float effective_histories
int initBCSE(EGS_Input *)
Initialize BCSE variance reduction if requested.
bool source_i_do_rr
enable range rejection in sources
bool output_egsphant
true if user requests egsphant ouput
void printIncludedFiles()
bool global_i_do_rr
enable range rejection outside of sources
EGS_Float source_pcut
pcut for source objects
int egsBrachyReadData(istream *)
helper function for outputData
void initTrackLengthScoring(EGS_Input *)
track length scoring initialization
static string revision
the usercode revision number
EGS_Float global_pcut
pcut for source objects
void getCurrentResult(double &sum, double &sum2, double &norm, double &count)
Reports the current results for this batch of the simulation.
int correctVolumes()
run the volume correction routines
bool output_3ddose_files
false if run mode is 'volume correction only'
void initSpectrumScoring(EGS_Input *)
Initialize all spectrum scoring objects.
EB_Phantom * gcr_phantom
phantom object to use in getCurrentResult (defaults to 1st phantom)
EB_Phantom * getPhantomByName(string name)
takes a phantom geometry name and returns the EB_Phantom object
void addRecycledParticlesToStack(EGS_Particle *p, bool new_hist=false)
static const EGS_Float DEFAULT_BCSE_FACTOR
map< string, string > media_muen_names
int readDataHelper(istream *)
helper function for outputData
void initScatScoring(EGS_Input *)
energy deposition scoring initialization
EGS_ASwitchedEnvelope * superpos_geom
an ASwitchedEnv cast of simulation geometry.
string output_dose_format
text or gzip
vector< EGS_Float > source_weights
vector< EGS_AffineTransform * > createTransforms(EGS_Input *input)
virtual void enterNewRegion()
map< string, vector< EGS_Float > > extra_scoring_vols
void resetCounter()
Reset the application to a 'pristine' state. Adapted from egs_application.cpp to allow combining in t...
EGS_AffineTransform * base_transform
same as source_transforms[0]
EGS_BaseGeometry * source_envelope_geom
geometry that the sources are embedded in
vector< EB_Phantom * > phantom_geoms
pointers to all of the phantom objects
void calcEffectiveHistories()
bool score_scat
true when scatter scoring is enabled
string output_egsphant_format
text or gzip
int egsBrachyOutputData(ostream *)
helper function for outputData
ogzstream * gz_data_out
GZip file for outputing egsdat.
int nbr_split
Number of times to split bremstrahlung phtons.
map< int, EGS_Interpolator * > media_muen
Map from medium index to muen interpolator for that medium.
ebvolcor::Results gen_vc_results
results from general volume correction
EGS_AffineTransform * base_transform_inv
same as source_transforms[0].inverse()
map< int, EGS_I64 > steps_in_sources
bool output_voxinfo
true if user requests voxel info file
bool applied_source_coord_transform
true if a source coordinate transform was composed in
map< int, EGS_I64 > steps_in_other
int ausgab(int iarg)
user scoring of dose, spectra etc
int readData()
Read data required for restarting simulations.
int egsApplicationReadData(istream *)
helper function for outputData
int nsources
total number of particle sources in current simulation
EGS_Float flu_cutoff
fluorescent photon cutoff energy
@ RM_VC_ONLY
Run volume correction routines then quit.
@ RM_SUPERPOSITION
Superposition mode for intersource effects.
@ RM_NORMAL
Standard running mode.
int egsAdvApplicationReadData(istream *)
helper function for outputData
int egsApplicationOutputData(ostream *)
helper function for outputData
GeomInfo ginfo
meta data about the geometries
void clearAusgabCalls()
disable all ausgab calls
ebvolcor::Results source_vc_results
results from source volume correctio box phantom
void initXCCScaling(EGS_Input *)
Initialize cross section scaling if requested.
int simulateSingleShower()
EGS_Float source_ecut
ecut for source objects
bool score_edep
true when energy deposition is enabled
void initGCRScoring(EGS_Input *)
setup which phantom/region will be used for getCurrentResult
EGS_Float source_e_max_rr
max range rejection energy for source objects
int initScoring()
initialze all scoring and variance reduction parameters
int addState(istream &data)
Add data from a parallel job. Add standard egs++ data as well as egs_brachy specific scoring informat...
EGS_Float global_ecut
ecut for source objects
int initGeometry()
override default initGeometry so we can manually create our own geometry.
void initOutputFiles(EGS_Input *)
set up whether to output extra info files
int initVarianceReduction()
initialze all variance reduction parameters
vector< EGS_Vector > p_init_locs
bool score_tlen
true when tracklength estimator is enabled
RunMode run_mode
Which run mode are we using (RM_NORMAL, RM_SUPERPOSITION or RM_VC_ONLY */.
RecycleOpts * recycle_opts
int record_n_init
if > 0 write initial pos of record_n_init particles to {input_file}.pinit
ebvolcor::FileResults file_vc_results
results from precomputed volume correction
virtual int runSimulation()
A class to represent a single phantom for scoring dose in egs_brachy.
@ YDIR
YDIR=1 y dir for rectilinear, r dir for cylindrical.
@ XDIR
XDIR=0 x dir for rectilinear, r dir for spherical, z dir for cylindrical.
@ ZDIR
ZDIR=2 z dir for rectilinear.
void scoreTlen(int ir, EGS_Float dose, EGS_Particle *p)
add tracklength dose to region ir
EGS_Float getUncorrectedVolume(int ireg)
get corrected volume for a given region
EGS_BaseGeometry * geometry
the phantom geometry object
bool needs_user_geoms
this phantom requires user specified geometries
void scoreEdep(int ir, EGS_Float dose)
add energy deposition dose to region ir
EGS_Float getRealMass(int ireg)
return (corrected) real mass for region
void setCorrectedVolume(int ir, double fraction, double unc=0)
Allow user to tell phantom what the actual volume of a region is.
EGS_Float getCorrectedVolume(int ireg)
get uncorrected volume for a given region
EGS_Float getUncorrectedMass(int ireg)
return uncorrected for region
EGS_Float avgVoxelVol()
return average voxel volume
a class to use for scoring information about total energy initialzed, escaping sources etc
An object for controlling the volume correction routine.
Results runSourceCorrection(EB_TimingTree &timer)
Results runGeneralCorrection(EB_TimingTree &timer)
FileResults runFileCorrection(EB_TimingTree &timer)
void open(const char *name, int open_mode=std::ios::in)
class for parsing muen data from a file.
int setMuenFile(string filename)
EGS_Interpolator * getMuenInterpolator(string med_name)
Create a new EGS_Interpolator of muen data for the requested medium and return pointer to it....
void F77_OBJ_(egs_scale_xcc, EGS_SCALE_XCC)(const int *
map< string, string > getMuenForMedia(EGS_Input *scoring_options)
void rco_sleep(const int &mscnds)
bool fileExists(const string &name)
bool containsInclude(string str)
#define egsGetRNGPointers
void const EGS_Float *void const EGS_Float *void const EGS_Float *void const EGS_Float *void printParticleWithSpherical(EGS_Particle p)
#define egsGetElectronData
the main egs_brachy application header file
#define PRINT_PARTICLE_WITH_DIR(P)
#define SAME_POSITION_TOLERANCE
pair< EGS_BaseGeometry *, int > GeomRegT
pair of geometry and local region number
EGS_Float getShapeVolume(EGS_Input *shape_inp)
get shape volume from a shape input item
pair< bool, EB_Message > EBSendMessage
@ PARTICLE_ESCAPING_SOURCE
@ PARTICLE_ESCAPED_SOURCE
a struct to contain elementary information aboud a geometry
vector< string > children