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());
246 egsInformation(
"Single source generator = %s\n", (
single_generator ?
"yes" :
"no"));
247 egsInformation(
"Source | Location (x cm, y cm, z cm) | Rotated | Weight\n%s\n",
string(80,
'-').c_str());
251 "%6d | ( % 7.3F, % 7.3F, % 7.3F) | %5s | % 7.2G\n",
252 tt+1, trans.x, trans.y, trans.z,
260 egsInformation(
"\n\n");
264 if (a_objects_list.size() > 0) {
265 egsInformation(
"The following ausgab objects are included in the simulation\n");
266 egsInformation(
"===========================================================\n\n");
267 for (
size_t j=0; j<a_objects_list.size(); ++j) {
268 egsInformation(
"%s",a_objects_list[j]->getObjectDescription());
270 egsInformation(
"\n\n");
281 string::iterator end_pos = std::remove(str.begin(), str.end(),
' ');
282 str.erase(end_pos, str.end());
283 size_t found = str.find(
"includefile");
284 return found != string::npos;
290 string fname = constructIOFileName(
".egsinp",
false);
291 egsInformation(
"\n\nIncluded Files\n%s\n",
string(80,
'=').c_str());
292 egsInformation(
"Input file:\n\t%s\n", fname.c_str());
293 egsInformation(
"The following files were included in this simulation:\n");
294 ifstream inf(fname.c_str());
300 egsInformation(
"\t%s\n", muen::trim(line).c_str());
313 EGS_Input *ginput = input->getInputItem(
"geometry definition");
316 egsWarning(
"EB_Application::createGeometry: no geometry specification in this input\n");
317 egsFatal(
"Simulation stopped\n");
322 egsWarning(
"EB_Application::createGeometry: incomplete or incorrect geometry specification\n");
324 egsFatal(
"Simulation stopped\n");
327 err = EGS_AdvancedApplication::initGeometry();
330 egsWarning(
"Failed to create a geometry from input file\n");
332 egsFatal(
"Simulation stopped\n");
343 egsFatal(
"Missing 'source envelope geometry' input required for superposition mode\n");
352 egsFatal(
"You must use an %s source envelope geometry type for superposition mode\n",
"EGS_ASwitchedEnvelope");
358 if (gr.
type ==
"EGS_ASwitchedEnvelope"){
359 egsFatal(
"EGS_ASwitchedEnvelope should not be used when not using 'run mode = superposition\n");
367 egsFatal(
"Failed to initiate source locations\n");
374 egsWarning(
"Failed to create phantom objects\n");
375 egsFatal(
"Simulation stopped\n");
387 vector<EGS_AffineTransform *> transforms;
389 EGS_Input *trans_inp;
391 while ((trans_inp = input->takeInputItem(
"transformation"))) {
392 EGS_AffineTransform *transform = EGS_AffineTransform::getTransformation(trans_inp);
394 egsWarning(
"Invalid transform input given\n");
397 transforms.push_back(transform);
413 EGS_Input *source_inp = input->getInputItem(
"source definition");
420 EGS_Input *source_loc_inp = source_inp->takeInputItem(
"transformations");
422 if (source_loc_inp) {
424 delete source_loc_inp;
428 EGS_AffineTransform *unity_trans =
new EGS_AffineTransform();
430 egsWarning(
"EB_Application:: missing or invalid source `transformations` input item. Assuming single source at origin\n");
436 EGS_Input *source_overlap_inp = source_inp->takeInputItem(
"source overlap check");
437 if (source_overlap_inp){
440 egsFatal(
"EB_Application:: checkSourceOverlaps detected an error.");
452 vector<string> yn_choices;
453 yn_choices.push_back(
"no");
454 yn_choices.push_back(
"yes");
455 bool check_source_overlap = (bool)inp->getInput(
"check source overlaps", yn_choices, 0);
463 vector<string> mode_choices;
464 mode_choices.push_back(
"warning");
465 mode_choices.push_back(
"fatal");
467 bool fatal = (bool)inp->getInput(
"warning mode", mode_choices, 1);
469 EGS_Input *shape_inp = inp->takeInputItem(
"shape");
471 EGS_BaseShape *bounds = EGS_BaseShape::createShape(shape_inp);
474 egsWarning(
"egs_brachy::checkSourceOverlaps - no `shape` input found.\n");
479 if (bounds_volume < 0){
480 egsWarning(
"egs_brachy::checkSourceOverlaps - Unable to get shape volume.");
484 vector<string> excluded;
485 inp->getInput(
"excluded geometries", excluded);
488 int err = inp->getInput(
"density of random points (cm^-3)", density);
490 egsWarning(
"egs_brachy::checkSourceOverlaps - The volume correction 'density of random points (cm^-3)' input was not found. Using 1E6/cm^3\n");
493 EGS_I64 npoints = (EGS_I64)floor(max(1., density*bounds_volume));
496 EGS_RandomGenerator *rng = EGS_RandomGenerator::defaultRNG();
500 EGS_BaseGeometry *base_source = 0;
501 string base_source_name;
505 base_source = EGS_BaseGeometry::getGeometry(gr.
name);
506 base_source_name = gr.
name;
511 egsFatal(
"egs_brachy::checkSourceOverlaps - did not find base source geometry");
516 EGS_AffineTransform inv_base_transform;
521 if (gr.
type !=
"EGS_AEnvelope" && gr.
type !=
"EGS_ASwitchedEnvelope"){
529 vector<int> overlaps;
531 for (EGS_I64 i=0; i < npoints; i++) {
535 point = bounds->getRandomPoint(rng);
537 if (base_source->isWhere(point) < 0) {
540 inv_base_transform.transform(point);
546 EGS_Vector transformed(point);
554 EGS_Vector inner_transformed(transformed);
559 if (base_source->isWhere(inner_transformed) >= 0) {
561 overlaps.push_back(sa_idx);
562 overlaps.push_back(sb_idx);
579 if (overlaps.size() > 1){
580 string msg =
"Possible overlap of sources: ";
581 for (
int i=0; i < overlaps.size(); i++){
582 msg += to_string(overlaps[i]);
583 if (i != overlaps.size() -1 ){
587 egsInformation((msg+
"\n").c_str());
590 if (overlaps.size() > 1){
591 return fatal ? 1 : 0;
601 EGS_Input *vol_cor_inp = input->takeInputItem(
"volume correction");
603 egsWarning(
"Input item `volume correction` was not found\n");
623 vector<string> user_vols;
625 while ((ij = vol_cor_inp->takeInputItem(
"phantom region volumes")) != 0) {
628 ij->getInput(
"phantom name", phant_name);
631 egsFatal(
"`phanton region volume` specified for phantom `%s` which does not exist.", phant_name.c_str());
633 user_vols.push_back(phant_name);
636 vector<int> phantom_regs;
637 ij->getInput(
"region numbers", phantom_regs);
639 vector<EGS_Float> phantom_vols;
640 ij->getInput(
"region volumes", phantom_vols);
642 if (phantom_regs.size() != phantom_vols.size()){
644 "Mismatched number of inputs for `region numbers` and `region volumes` for phantom `%s`",
647 }
else if (phantom_regs.size() == 0){
649 "Missing `region numbers` or `region volumes` input for `phantom region volumes` block for phantom `%s`",
654 for (
size_t r = 0; r < phantom_regs.size(); r++){
666 string name = phant->
geometry->getName();
667 string type = phant->
geometry->getType();
668 if (phant->
needs_user_geoms && find(user_vols.begin(), user_vols.end(), name) == user_vols.end()){
670 "Missing `phantom region volume` block for phantom `%s`."
671 "Phantoms of type `%s` can not calculate volumes automatically.",
693 EGS_BaseGeometry *phant_geom = EGS_BaseGeometry::getGeometry(name);
695 egsInformation(
"\n\nUnable to find phantom geometry `%s`.\n\n This is a fatal error\n\n", name.c_str());
700 set<int> global_regions;
704 global_regions.insert(reg);
708 if (global_regions.size()==0) {
710 "EB_Application::createPhantoms - No phantom regions detected for geometry '%s'.\n"
711 "Are you sure your phantom was included in the final simulation geometry?\n",
712 (phant_geom->getName()).c_str()
728 EGS_Input *source_inp = input->getInputItem(
"source definition");
750 int err = EGS_AdvancedApplication::initSource();
752 egsFatal(
"Failed to initialize source\n");
755 string stype = source->getObjectType();
756 is_phsp_source = stype ==
"EGS_PhspSource" || stype ==
"EB_IAEAPHSPSource";
760 egsInformation(
"Phase space being used. Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
773 int res = EGS_AdvancedApplication::initSimulation();
790 vector<string> format_choices;
791 format_choices.push_back(
"text");
792 format_choices.push_back(
"gzip");
793 EGS_Input *run_control = input->getInputItem(
"run control");
794 int format = run_control->getInput(
"egsdat file format", format_choices, 0);
801 run =
new EGS_RunControl(
this);
803 else if (uniform_run) {
807 run = EGS_RunControl::getRunControlObject(
this);
819 EGS_Input *rm = input->takeInputItem(
"run mode");
825 vector<string> choices;
826 choices.push_back(
"normal");
827 choices.push_back(
"superposition");
828 choices.push_back(
"volume correction only");
834 vector<string> yn_choices;
835 yn_choices.push_back(
"no");
836 yn_choices.push_back(
"yes");
850 EGS_Input *transportp = input->getInputItem(
"MC transport parameter");
852 transportp = input->getInputItem(
"transport parameter");
856 egsFatal(
"Missing `MC transport parameter` input item\n");
860 int err = transportp->getInput(
"fluorescent photon cutoff",
flu_cutoff);
865 int ret = EGS_AdvancedApplication::initCrossSections();
870 err = transportp->getInput(
"source ecut",
source_ecut);
875 err = transportp->getInput(
"source pcut",
source_pcut);
880 egsInformation(
"\negs_brachy transport parameter options:\n%s\n",
string(80,
'-').c_str());
881 egsInformation(
"Fluorescent photon cutoff %.3G\n",
flu_cutoff);
894 EGS_Input *options = input->takeInputItem(
"scoring options");
915 egsFatal(
"\n\nMissing input section 'scoring options'\n\n");
929 vector<string> gcr_inp;
930 int err = inp->getInput(
"current result phantom region", gcr_inp);
931 if (err || gcr_inp.size()==0) {
939 if (gcr_inp.size() >= 1) {
950 "Did not find '%s' phantom for getCurrentResult. Using phantom %s\n",
959 if (gcr_inp.size() > 1) {
960 int ireg = atol(gcr_inp[1].c_str());
961 if (ireg > 0 && ireg < gcr_phantom->geometry->regions()) {
981 vector<string> yn_choices;
982 yn_choices.push_back(
"no");
983 yn_choices.push_back(
"yes");
984 output_egsphant = (bool)inp->getInput(
"output egsphant files", yn_choices, 0);
985 output_voxinfo = (bool)inp->getInput(
"output voxel info files", yn_choices, 0);
988 vector<string> format_choices;
989 format_choices.push_back(
"text");
990 format_choices.push_back(
"gzip");
992 int format = inp->getInput(
"dose file format", format_choices, 0);
995 format = inp->getInput(
"egsphant file format", format_choices, 0);
998 format = inp->getInput(
"voxel info file format", format_choices, 0);
1001 format = inp->getInput(
"volume correction file format", format_choices, 0);
1004 inp->getInput(
"record initial particle positions",
record_n_init);
1010 EGS_Input *phsp_inp = inp->takeInputItem(
"phsp scoring");
1023 egsInformation(
"\n\negs_brachy Variance Reduction Information\n%s\n\n",
string(80,
'=').c_str());
1025 EGS_Input *vr = input->takeInputItem(
"variance reduction");
1039 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1040 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1041 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1042 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1048 EGS_Input *ri = vr->takeInputItem(
"particle recycling");
1051 egsFatal(
"Primary-scatter dose scoring is not available with recycling. Please turn off recycling or disable scatter dose scoring.\n");
1053 egsInformation(
"Particle Recycling\n");
1058 egsInformation(
" Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
1060 egsInformation(
"\n");
1066 vector<string> yn_choices;
1067 yn_choices.push_back(
"no");
1068 yn_choices.push_back(
"yes");
1070 string old_rr_setting;
1071 int err = vr->getInput(
"range rejection", old_rr_setting);
1074 "'range rejection' is not a valid setting for egs_brachy.\n"
1075 "Please use 'global range rejection' and 'source range rejection' settings instead.\n"
1079 EGS_Float old_rr_max_e;
1080 err = vr->getInput(
"range rejection max energy", old_rr_max_e);
1083 "'range rejection max energy' is not a valid setting for egs_brachy.\n"
1084 "Please use 'global range rejection max energy' and 'source range rejection max energy' settings instead.\n"
1089 global_i_do_rr = vr->getInput(
"global range rejection", yn_choices, 1);
1090 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1092 int err = vr->getInput(
"global range rejection max energy",
global_e_max_rr);
1097 egsFatal(
"Global Range Rejection max energy must be at least 0.512MeV\n");
1099 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1103 source_i_do_rr = vr->getInput(
"source range rejection", yn_choices, 0);
1104 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1106 int err = vr->getInput(
"source range rejection max energy",
source_e_max_rr);
1111 egsFatal(
"Source Range Rejection max energy must be at least 0.512MeV\n");
1113 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1123 egsInformation(
"BCSE = %s\n",
do_bcse ?
"Yes" :
"No");
1126 " Brem Cross Section Enhancement medium = %s (%d)\n",
1129 egsInformation(
" Brem Cross Section Enhancement factor = %.3G\n",
bcse_factor);
1134 err = vr->getInput(
"split brem photons",
nbr_split);
1135 egsInformation(
"Brem Splitting = %s\n",
nbr_split > 1?
"Yes" :
"No");
1138 egsInformation(
" Splitting brem photons N times = %d\n",
nbr_split);
1145 egsInformation(
"Charged Particle Russian Roulette = %s\n", the_egsvr->i_play_RR ?
"Yes" :
"No");
1146 if (!err || the_egsvr->i_play_RR) {
1151 " Survival probability (1/nbrsplt*bcse) = 1/(%d*%.3G) (%.3G%%)\n",
1157 " Survival probability (1/nbrsplt) = 1/%d (%.3G%%)\n",
1172 vector<string> yn_choices;
1173 yn_choices.push_back(
"no");
1174 yn_choices.push_back(
"yes");
1176 int play_rr = scoring_options->getInput(
"russian roulette", yn_choices, 0);
1181 the_egsvr->i_play_RR = 1;
1183 AusgabCall rr_calls[] = {
1184 BeforeBrems, AfterBrems,
1185 BeforeAnnihFlight, AfterAnnihFlight,
1186 BeforeAnnihRest, AfterAnnihRest,
1190 int ncalls =
sizeof(rr_calls)/
sizeof(rr_calls[0]);
1198 vector<string> bcse_inp;
1199 int err = inp->getInput(
"bcse medium", bcse_inp);
1200 if (err || bcse_inp.size()==0) {
1204 bcse_med_num = EGS_BaseGeometry::getMediumIndex(bcse_inp[0]);
1206 egsWarning(
"Requested an unknown medium `%s` for BCSE\n",bcse_inp[0].c_str());
1211 if (bcse_inp.size() == 1) {
1222 the_egsvr->i_play_RR = 1;
1224 AusgabCall bcse_calls[] = {BeforeBrems, AfterBrems, FluorescentEvent};
1235 bool header_printed =
false;
1237 while (EGS_Input *spec_inp=scoring_input->takeInputItem(
"spectrum scoring")) {
1239 if (!header_printed) {
1240 egsInformation(
"\n\negs_brachy Spectrum Scoring Information\n%s\n\n",
string(80,
'=').c_str());
1241 header_printed =
true;
1248 egsInformation(
"Added scorer with title: %s\n", scorer->
getInfo().c_str());
1255 for (
size_t call=BeforeTransport; call <= UnknownCall; call++) {
1256 setAusgabCall((AusgabCall)call,
false);
1266 AusgabCall always_call[] = {BeforeTransport, AfterTransport, FluorescentEvent};
1275 vector<string> choices;
1276 choices.push_back(
"no");
1277 choices.push_back(
"yes");
1279 score_tlen = scoring_options->getInput(
"score tracklength dose", choices, 1);
1292 map<string, string> muen_for_med;
1294 vector<string> muen_meds;
1295 scoring_options->getInput(
"muen for media", muen_meds);
1297 for (
size_t i=0; i < muen_meds.size(); i++) {
1298 string med_name = muen_meds[i];
1299 muen_for_med[med_name] = med_name;
1302 EGS_Input *muen_inp;
1303 while ((muen_inp = scoring_options->takeInputItem(
"muen for medium"))) {
1304 string scoring, transport;
1305 int err = muen_inp->getInput(
"transport medium", transport);
1307 egsFatal(
"Missing 'transport medium' key in 'muen for medium' block\n");
1310 err = muen_inp->getInput(
"scoring medium", scoring);
1312 egsFatal(
"Missing 'scoring medium' key in 'muen for medium' block\n");
1316 muen_for_med[transport] = scoring;
1321 return muen_for_med;
1327 egsInformation(
"\n\negs_brachy Muen Data Information\n%s\n\n",
string(80,
'=').c_str());
1330 bool missing_muen = scoring_options->getInput(
"muen file", muen_file) != 0;
1332 egsFatal(
"\n\nMissing input scoring options: muen file\n\n This is a fatal error\n\n");
1340 "EB_Application:: missing or invalid 'muen for media' input item or 'muen substitution' block(s).\n"
1341 " No muen data has been read.\n"
1349 egsFatal(
"Failed to read muen data from %s\n",muen_file.c_str());
1352 egsInformation(
"Read muen data from %s\n", muen_file.c_str());
1357 string transport_med = mit->first;
1358 string scoring_med = mit->second;
1361 egsFatal(
"EB_Application::Failed to get muen interpolator for %s\n", scoring_med.c_str());
1364 int med_idx = EGS_BaseGeometry::getMediumIndex(transport_med);
1367 "EB_Application:: You requested scoring medium %s for transport medium %s but %s"
1368 " is not present in the geometry\n", scoring_med.c_str(), transport_med.c_str(), transport_med.c_str()
1374 "Set medium %d (%s) to use muen data: %s\n",
1375 med_idx, transport_med.c_str(), scoring_med.c_str()
1383 for (
int i= 0; i < ncalls; i++) {
1384 setAusgabCall(calls[i],
true);
1392 vector<string> choices;
1393 choices.push_back(
"no");
1394 choices.push_back(
"yes");
1396 score_edep = scoring_options->getInput(
"score energy deposition", choices, 0);
1403 AusgabCall edep_calls[] = {ExtraEnergy, UserDiscard, PegsCut, EgsCut};
1411 vector<string> choices;
1412 choices.push_back(
"no");
1413 choices.push_back(
"yes");
1415 score_scat = scoring_options->getInput(
"score scatter dose", choices, 0);
1417 egsFatal(
"\nPrimary-scatter dose scoring requires tracklength scoring. Please enable tracklength scoring or disable scatter dose scoring.\n");
1421 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");
1425 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");
1434 AusgabCall photon_scat_calls[] = {
1435 AfterAnnihFlight, AfterAnnihRest,
1436 AfterPair, AfterCompton, AfterPhoto, AfterRayleigh,
1440 int ncalls =
sizeof(photon_scat_calls)/
sizeof(photon_scat_calls[0]);
1447 EGS_Float scale = 1.;
1449 int err = scoring_options->getInput(
"dose scaling factor", scale);
1451 if (!err && scale > 0) {
1462 while ((scale = scoring_options->takeInputItem(
"scale xcc"))) {
1464 int err = scale->getInput(
"scale xcc",tmp);
1466 if (!err && tmp.size() == 2) {
1467 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1469 EGS_Float fac = atof(tmp[1].c_str());
1470 egsInformation(
"\n ***** Scaling xcc of medium %d with %G\n",imed,fac);
1471 F77_OBJ_(egs_scale_xcc,EGS_SCALE_XCC)(&imed,&fac);
1477 while ((scale = scoring_options->takeInputItem(
"scale bc"))) {
1479 int err = scale->getInput(
"scale bc",tmp);
1481 if (!err && tmp.size() == 2) {
1482 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1484 EGS_Float fac = atof(tmp[1].c_str());
1485 egsInformation(
"\n ***** Scaling bc of medium %d with %G\n",imed,fac);
1486 F77_OBJ_(egs_scale_bc,EGS_SCALE_BC)(&imed,&fac);
1498 EGS_Vector new_loc(p->x);
1499 EGS_Vector new_dir(p->u);
1506 double angle = 2*M_PI*rndm->getUniform();
1507 EGS_RotationMatrix rot = EGS_RotationMatrix::rotZ(angle);
1517 int new_reg = geometry->isWhere(new_loc);
1518 int new_med = geometry->medium(new_reg);
1522 int cur_np = the_stack->np;
1523 int new_np = the_stack->np+1;
1524 int np_idx = new_np-1;
1526 the_stack->ir[np_idx] = new_reg + 2;
1527 the_stack->latch[np_idx] = p->latch;
1528 the_stack->E[np_idx] = p->E;
1529 the_stack->wt[np_idx] = new_wt;;
1530 the_stack->iq[np_idx] = p->q;
1531 the_stack->x[np_idx] = new_loc.x;
1532 the_stack->y[np_idx] = new_loc.y;
1533 the_stack->z[np_idx] = new_loc.z;
1534 the_stack->u[np_idx] = new_dir.x;
1535 the_stack->v[np_idx] = new_dir.y;
1536 the_stack->w[np_idx] = new_dir.z;
1537 the_stack->dnear[np_idx] = 0;
1540 the_stack->npold = cur_np;
1542 the_epcont->irnew = new_reg+2;
1543 the_useful->medium_new = new_med+1;
1548 the_stack->wt[np_idx-1] = 0;
1555 EGS_AdvancedApplication::startNewParticle();
1557 int ireg = the_stack->ir[the_stack->np-1] - 2;
1570 EGS_AdvancedApplication::enterNewRegion();
1572 int ireg = the_epcont->irnew-2;
1590 the_stack->wt[the_stack->np-1] = 0;
1591 the_epcont->idisc = idisc;
1605 int start_loc, stop_loc;
1609 stop_loc = start_loc + 1;
1615 for (
int source_loc = start_loc; source_loc < stop_loc; source_loc++) {
1618 bool kill = source_loc == start_loc && recycle_idx == 0 && !new_hist;
1631 bool same_particle = the_stack->npold == the_stack->np;
1632 if (!same_particle){
1637 cur_R = top_p.x.length2();
1646 egsWarning(
"Particle hasn't moved in %d steps. Discarding particle\n",
NUM_STUCK_STEPS);
1659 bool is_photon = top_p.q == 0;
1660 bool is_before_transport = iarg == BeforeTransport;
1661 bool is_after_transport = iarg == AfterTransport;
1663 if (is_after_transport &&
isStuck()) {
1664 the_stack->latch[the_stack->np - 1] = top_p.latch;
1668 int global_ir = top_p.ir;
1669 int irnew = the_epcont->irnew-2;
1670 int irold = the_epcont->irold-2;
1675 bool is_extra_scoring_reg =
false;
1676 string local_geom_name =
"";
1677 int local_geom_ir = -1;
1678 int extra_reg_dose_index = -1;
1684 local_geom_ir = local.second;
1685 local_geom_name = local.first->getName();
1688 map<string, vector<int> >::iterator i =
extra_scoring_reg.find(local_geom_name);
1690 vector<int>::iterator it = find(i->second.begin(), i->second.end(), local_geom_ir);
1691 if (it != i->second.end()){
1692 is_extra_scoring_reg =
true;
1693 extra_reg_dose_index = distance(i->second.begin(), it);
1699 if (is_before_transport) {
1702 }
else if (in_phantom) {
1710 bool discard_fluorescent = iarg == FluorescentEvent && top_p.E <=
flu_cutoff;
1711 if (discard_fluorescent) {
1713 the_stack->latch[the_stack->np - 1] = top_p.latch;
1718 if (
score_scat && (iarg > AfterTransport) && !in_source) {
1720 for (
int ip=the_stack->npold-1; ip < the_stack->np; ip++) {
1730 bool leaving_source = is_before_transport && in_source && !next_is_source;
1734 bool left_source = is_after_transport && !in_source && last_was_source;
1737 bool escaping_geom = is_before_transport && irnew < 0;
1738 bool escaped_geom = global_ir < 0;
1751 int nmesg =
sizeof(send_messages)/
sizeof(send_messages[0]);
1752 for (
int m=0; m < nmesg; m++) {
1753 if (send_messages[m].first) {
1760 the_stack->latch[the_stack->np - 1] = top_p.latch;
1767 if (escaped_source && is_after_transport) {
1769 EGS_Float wt = top_p.wt;
1790 bool in_vaccuum = the_useful->medium <= 0;
1791 bool score_tracklength =
score_tlen && is_photon && is_before_transport;
1792 bool score_interaction =
score_edep && iarg <= ExtraEnergy;
1793 bool dose_scoring_not_needed = !is_extra_scoring_reg && (!in_phantom || in_vaccuum || !(score_tracklength || score_interaction));
1795 if (dose_scoring_not_needed) {
1809 if (score_tracklength) {
1811 EGS_Interpolator *interp =
media_muen[the_useful->medium-1];
1812 EGS_Float muen_val = interp ? interp->interpolateFast(the_epcont->gle) : 0;
1813 EGS_Float tracklength_edep = the_epcont->tvstep*top_p.E*muen_val*top_p.wt;
1818 if (needs_vol_cor) {
1825 phant->
scoreTlen(phant_ir, tracklength_edep / vol, &top_p);
1829 if (is_extra_scoring_reg){
1831 extra_scoring_doses[local_geom_name]->score(extra_reg_dose_index, tracklength_edep / vol);
1835 if (score_interaction) {
1839 EGS_Float edep = getEdep()*top_p.wt;
1850 phant->
scoreEdep(phant_ir, edep / mass);
1854 if (is_extra_scoring_reg){
1865 bool is_phat = fabs(top_p.wt - 1.) <
EB_EPSILON;
1869 bool in_bcse_med = the_useful->medium - 1 ==
bcse_med_num;
1871 if (iarg == BeforeBrems) {
1877 }
else if (iarg == AfterBrems) {
1881 for (
int ip=the_stack->npold; ip < the_stack->np; ip++) {
1884 EGS_Float rnd = rndm->getUniform();
1886 the_stack->E[the_stack->npold-1] += top_p.E;
1890 the_egsvr->nbr_split = 1;
1893 }
else if (iarg == FluorescentEvent && is_phat) {
1901 the_stack->npold = the_stack->np;
1902 F77_OBJ_(egs_uniform_photons, EGS_UNIFORM_PHOTONS)(&nsplit, &top_p.E);
1906 }
else if (
do_brem_split && iarg == FluorescentEvent && is_phat) {
1909 the_stack->npold = the_stack->np;
1939 string sep(80,
'=');
1941 "\n\nResults for egs_brachy run\n%s\n",
1942 string(80,
'-').c_str()
1946 egsInformation(
"\n\nHistory Information\n%s\n",sep.c_str());
1947 egsInformation(
"Last case = %llu\n", last_case);
1948 egsInformation(
"current case = %llu\n", current_case);
1949 egsInformation(
"run->getNcase() = %llu\n", run->getNcase());
1950 egsInformation(
"source->getFluence() = %f\n", source->getFluence());
1957 egsInformation(
"\n\nGeometry Errors\n%s\n", sep.c_str());
1958 egsInformation(
"Number of geometry errors (/max allowed) = %d / %d\n", run->geomErrorCount, run->geomErrorMax);
1959 egsInformation(
"Number of 'stuck' particles discarded = %llu\n",
n_stuck);
1964 EGS_I64 hist_norm = run->getNdone();
1969 "Warning: Stats about energy escaping source may not be accurate when "
1970 "not using a single source generator\n"
1985 egsInformation(
"\nSpectrum scoring results\n%s\n",sep.c_str());
1986 string root = constructIOFileName(
"",
true);
1990 (*it)->outputResults(root);
1996 string fname = constructIOFileName(
"",
true)+
".pinit";
1998 out.open(fname.c_str());
1999 out << std::fixed << std::showpoint << std::setprecision(6);
2001 out << (*it).x <<
"\t" << (*it).y <<
"\t" << (*it).z <<
"\n";
2004 egsInformation(
"\nInitial Particle Positions\n%s\n",sep.c_str());
2005 egsInformation(
"%d Initial particle positions written to .pinit file\n",
p_init_locs.size());
2017 (*p)->outputResults(20, dd_format, ep_format, vi_format, vc_format);
2022 egsInformation(
"\nStep Counts\n%s\n", sep.c_str());
2023 EGS_Float total_steps = 0;
2025 for (
int i=-1; i < 2; i++) {
2031 egsInformation(
"Total particle steps : %20llu\n", (EGS_I64)total_steps);
2032 for (
int i=-1; i < 2; i++) {
2034 egsInformation(
"q=%2d Steps taken in sources : %20llu (%.2f%%)\n", i,
steps_in_sources[i],
2038 egsInformation(
"q=%2d Steps taken in phantoms : %20llu (%.2f%%)\n", i,
steps_in_phantoms[i],
2042 egsInformation(
"q=%2d Steps taken in other objects : %20llu (%.2f%%)\n", i,
steps_in_other[i],
2056 count = current_case;
2066 int result = EGS_Application::runSimulation();
2074 last_case = current_case;
2076 current_case = source->getNextParticle(rndm, p.q, p.latch, p.E, p.wt, p.x, p.u);
2095 p.ir = geometry->isWhere(p.x);
2098 egsWarning(
"EB_Application::simulateSingleShower() - particle initiated at (x, y, z) = (%.2g, %.2g, %.2g)\n", p.x.x, p.x.y, p.x.z);
2099 egsFatal(
"EB_Application::simulateSingleShower() - Particle initiated outside "
2100 "the geometry! Please check your source locations.\n");
2117 "Particle started in region %d (%s reg %d) which is outside a source geometry. Please check your geometry\n",
2119 r.first->getName().c_str(),
2129 cur_R = p.x.length2();
2153 return err || finishShower();
2164 int err = EGS_Application::startNewShower();
2171 if (current_case != last_case) {
2175 last_case = current_case;
2185 if (!run->storeState(*out)) {
2188 if (!egsStoreI64(*out,current_case)) {
2192 if (!rndm->storeState(*out)) {
2195 if (!source->storeState(*out)) {
2198 for (
size_t j=0; j<a_objects_list.size(); ++j) {
2199 if (!a_objects_list[j]->storeState(*out)) {
2214 if (np > 10000000) {
2215 egsWarning(
"EGS_AdvancedApplication::outputData(): egsGetRNGPointers"
2216 " returns a huge number? (%d)\n",np);
2219 EGS_Float *array =
new EGS_Float [np];
2221 (*out) <<
" " << np <<
" " << ip <<
"\n";
2222 for (
int j=0; j<np; j++) {
2223 (*out) << array[j] <<
" ";
2226 double ch_steps, all_steps;
2228 (*out) << ch_steps <<
" " << all_steps <<
"\n";
2230 return out->good() ? 0 : 13;
2238 (*out) << std::setprecision(9);
2240 for (
int i=-1; i < 2; i++) {
2255 err = (*spec_it)->outputData(out);
2261 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2263 err = (*phant_it)->outputData(out);
2292 string extension(
".egsdat");
2293 extension += (use_gz ?
".gz" :
"");
2294 string ofile = constructIOFileName(extension.c_str(),
true);
2304 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2315 data_out =
new ofstream(ofile.c_str());
2317 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2331 if (!run->setState(*in)) {
2334 if (!egsGetI64(*in,current_case)) {
2337 last_case = current_case;
2338 if (!rndm->setState(*in)) {
2341 if (!source->setState(*in)) {
2344 for (
int j=0; j<a_objects_list.size(); ++j) {
2345 if (!a_objects_list[j]->setState(*in)) {
2359 if (np > 10000000) {
2360 egsWarning(
"EB_Application::egsAdvApplicationReadData(): got huge size "
2361 "for the mortran random array? (%d)\n",np);
2364 EGS_Float *array =
new EGS_Float [np];
2365 for (
int j=0; j<np; j++) {
2373 double ch_steps, all_steps;
2374 (*in) >> ch_steps >> all_steps;
2376 return in->good() ? 0 : 13;
2383 for (
int i=-1; i < 2; i++) {
2398 err = (*spec_it)->readData(in);
2404 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2406 err = (*phant_it)->readData(in);
2435 string extension(
".egsdat");
2436 extension += (use_gz ?
".gz" :
"");
2437 string ifile = constructIOFileName(extension.c_str(),
false);
2447 egsWarning(
"EGS_Application::readData: failed to open %s for reading\n", ifile.c_str());
2457 data_in =
new ifstream(ifile.c_str());
2459 egsWarning(
"EGS_Application::readData: failed to open %s for writing\n",ifile.c_str());
2475 "\n Suming the following .egsdat files:\n"
2476 "=======================================================================\n");
2479 EGS_Float last_cpu = 0;
2480 EGS_I64 last_ncase = 0;
2483 for (
int j=1; j<500; j++) {
2486 string name(
"%s_w%d.egsdat");
2487 name += (use_gz ?
".gz" :
"");
2489 sprintf(buf, name.c_str(), output_file.c_str(), j);
2490 string dfile = egsJoinPath(app_dir,buf);
2494 bool opened =
false;
2496 gzin.
open(dfile.c_str());
2500 in.
open(dfile.c_str());
2501 opened = in.is_open();
2509 EGS_I64 ncase = run->getNdone();
2510 EGS_Float cpu = run->getCPUTime();
2511 egsInformation(
"%2d %-30s ncase=%-14lld cpu=%-11.2f\n",
2512 ndat,buf,ncase-last_ncase,cpu-last_cpu);
2517 egsWarning(
"%2d %-30s error %d\n",ndat,buf,err);
2523 "=======================================================================\n");
2524 egsInformation(
"%40s%-14lld cpu=%-11.2f\n\n",
"Total ncase=",last_ncase,
2536 EGS_AdvancedApplication::resetCounter();
2539 for (
int i=-1; i < 2; i++) {
2551 (*spec_it)->resetCounter();
2554 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2556 (*phant_it)->resetCounter();
2564 int err = EGS_AdvancedApplication::addState(data);
2569 for (
int i=-1; i < 2; i++) {
2570 EGS_I64 steps_in_sources_tmp;
2571 EGS_I64 steps_in_phantoms_tmp;
2572 EGS_I64 steps_in_other_tmp;
2574 data >> steps_in_sources_tmp;
2575 data >> steps_in_phantoms_tmp;
2576 data >> steps_in_other_tmp;
2592 err = (*spec_it)->addState(data);
2598 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2600 err = (*phant_it)->addState(data);
2613 return (stat(name.c_str(), &buffer) == 0);
2619 int n_of_egsdat = 0;
2622 string name(
"%s_w%d.egsdat");
2623 name += (use_gz ?
".gz" :
"");
2625 for (
int i = first_parallel; i < first_parallel + n_parallel; i++) {
2626 sprintf(buf,name.c_str(),final_output_file.c_str(),i);
2627 string dfile = egsJoinPath(app_dir,buf);
2637 EGS_RunControl(a), app(a), output_egsdat_format(egsdat_format), milliseconds(1000), check_intervals(5),
2638 njob(0), npar(app->getNparallel()), ipar(app->getIparallel()), ifirst(app->getFirstParallel()),
2639 check_egsdat(true), watcher_job(false) {
2647 int err = input->getInput(
"interval wait time", dummy);
2653 err = input->getInput(
"number of intervals", dummy);
2660 err = input->getInput(
"watcher jobs", w_jobs);
2662 for (
int i = 0; i < w_jobs.size(); i++) {
2663 if (
ipar == w_jobs[i]) {
2680 vector<string> check_options;
2681 check_options.push_back(
"yes");
2682 check_options.push_back(
"no");
2683 int ichk = input->getInput(
"check jobs completed",check_options,0);
2704 string name(
"%s_w%d.egsdat");
2705 name += (use_gz ?
".gz" :
"");
2709 sprintf(buf,name.c_str(),
app->getFinalOutputFile().c_str(),
ipar);
2710 string datFile = egsJoinPath(
app->getAppDir(),buf);
2711 if (remove(datFile.c_str()) == 0) {
2712 egsWarning(
"EB_UniformRunControl: %s deleted\n",
2717 return EGS_RunControl::startSimulation();
2722 EGS_RunControl::describeRCO();
2727 " Watcher job: remains running after completion checking\n"
2728 " for other jobs finishing every %d s for %d s!\n",
2733 " Option to check for finishing jobs is OFF!\n\n");
2743 usleep(mscnds * 1000);
2748 int err = EGS_RunControl::finishSimulation();
2754 int interval = 0, njobs_done = 0, njobs_done_old= 0;
2760 if (njobs_done ==
npar - 1) {
2765 if (njobs_done_old < njobs_done) {
2766 egsInformation(
"=> Combining %d jobs ...\n",njobs_done);
2767 app->combinePartialResults();
2769 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
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
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
void getCurrentScore(int ireg, double &sum, double &sum2)
get current tlen score for region
double getTlenNorm(int ireg)
void setEffectiveHistories(EGS_Float current_case)
set number of effective histories for normalizing scoring arrays
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
void addTimer(string name)
a class to use for scoring information about total energy initialzed, escaping sources etc
int readData(istream *ifile)
int outputData(ostream *ofile)
int addState(istream &data)
void outputResults()
write results to console
string source_envelope_name
vector< GeomRegionInfo > ordered_geom_data
int phantomFromRegion(int ir)
return the phantom index for this region number or -1 if region is not in a phantom
int initializeFromInput(EGS_Input *input)
Initialize the GeomInfo structure (ginfo) This function reads the geometry input block,...
int ngeom
total number of geometries created
void setGeometryIndexes(EGS_BaseGeometry *sim_geom)
Setup all arrays required to decide which geometry/phantom a region is in and whether or not we are s...
GeomRegT globalToLocal(int ir)
convert global region number to (EGS_BaseGeometry, local_reg_num) pair
int nreg_total
total number of regions in the simulation geometry
int globalToLocalReg(int ir)
convert global region number to local_reg_num
vector< string > source_names
vector< string > phantom_names
static bool hasEscaped(EGS_Particle *p)
True if particle is currently in a source.
static void addScatter(EGS_Particle *p)
void outputResults()
output file name and number of particles written
void finish(EGS_I64 n_orig_particles)
set final number of particles written and destroy source
void destroySource()
destroy the source
void notify(EB_Message message, void *what=0, Subscriber *s=0)
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
void outputResults(string extra="")