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";
114 "\n ***************************************************"
118 "\n ***************************************************"
124 if (!geometry && !source) {
128 egsInformation(
"\n\negs_brachy Run Mode Information\n%s\n\n",
string(80,
'=').c_str());
130 egsInformation(
"Single generator (may be overriden later) = %s\n",
single_generator ?
"yes" :
"no");
133 "getCurrentResult phantom/reg = %s %d",
139 egsInformation(
"\n\negs_brachy Geometry Information\n%s\n\n",
string(80,
'=').c_str());
143 egsInformation(
"\n\negs_brachy Phantom Details\n%s\n\n",
string(80,
'=').c_str());
144 egsInformation(
" | | | | Sph (Rmin, Rmax) | | \n");
145 egsInformation(
" | | | Avg Vox Vol | RZ (Rmin, Rmax) | RZ (Zmin, Zmax) | \n");
146 egsInformation(
"Name | Type | Nreg | / cm^3 | XYZ (Xmin, Xmax) | XYZ (Ymin, Ymax) | XYZ (Zmin, Zmax)\n");
147 egsInformation(
"%s\n",
string(145,
'-').c_str());
152 EGS_BaseGeometry *geom = phant->
geometry;
154 string type = geom->getType();
156 if (type ==
"EGS_XYZGeometry") {
162 EGS_Float xmin, xmax, ymin, ymax, zmin, zmax;
171 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | (%8.3F, %8.3F) | (%8.3F, %8.3F)\n",
172 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
173 xmin, xmax, ymin, ymax, zmin, zmax
176 }
else if (type ==
"EGS_RZ") {
178 nr = geom->getNRegDir(EGS_RZGeometry::RDIR);
179 nz = geom->getNRegDir(EGS_RZGeometry::ZDIR);
181 EGS_Float rmin, rmax, zmin, zmax;
182 rmin = geom->getBound(EGS_RZGeometry::RDIR, 0);
183 rmax = geom->getBound(EGS_RZGeometry::RDIR, nr-1);
184 zmin = geom->getBound(EGS_RZGeometry::ZDIR, 0);
185 zmax = geom->getBound(EGS_RZGeometry::ZDIR, nz-1);
188 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | (%8.3F, %8.3F) |\n",
189 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
190 rmin, rmax, zmin, zmax
192 }
else if (type ==
"EGS_cSphericalShell" || type ==
"EGS_cSpheres") {
193 type = (type ==
"EGS_cSphericalShell" ?
"SphSh" :
"Sph");
195 int nr = geom->getNRegDir(0);
197 EGS_Float rmin, rmax;
198 rmin = geom->getBound(EGS_cSpheres::RDIR, 0);
199 rmax = geom->getBound(EGS_cSpheres::RDIR, nr);
202 "%-30s| %20s | %9d | %12.5G | (%8.3F, %8.3F) | | \n",
203 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
208 "%-30s| %20s | %9d | %12.5G | | | \n",
209 geom->getName().c_str(), type.c_str(), geom->regions(), phant->
avgVoxelVol(),
214 if (type ==
"EGS_XYZGeometryT") {
215 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");
220 egsInformation(
"\n\negs_brachy Volume correction details\n%s\n",
string(80,
'-').c_str());
222 egsInformation(
"\nSource specific volume correction details\n%s\n",
string(80,
'-').c_str());
225 egsInformation(
"\nExtra volume correction details\n%s\n",
string(80,
'-').c_str());
228 egsInformation(
"\nFile volume correction details\n%s\n",
string(80,
'-').c_str());
231 egsInformation(
"\n\n");
233 geometry->printInfo();
237 egsInformation(
"\n\negs_brachy Source Information\n%s\n",
string(80,
'=').c_str());
238 egsInformation(
"%s\n\n", source->getSourceDescription());
241 "Applied source coordinate transform to %d source location(s)\n",
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");
320 int err =
ginfo.initializeFromInput(ginput);
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");
337 ginfo.setGeometryIndexes(geometry);
342 if (
ginfo.source_envelope_name ==
"") {
343 egsFatal(
"Missing 'source envelope geometry' input required for superposition mode\n");
348 egsFatal(
"source envelope geometry '%s' can not be found\n",
ginfo.source_envelope_name.c_str());
352 egsFatal(
"You must use an %s source envelope geometry type for superposition mode\n",
"EGS_ASwitchedEnvelope");
356 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
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");
433 EGS_Input *coord_inp = source_inp->takeInputItem(
"source coordinate transform");
435 EGS_AffineTransform *coord_transform = EGS_AffineTransform::getTransformation(coord_inp);
436 if (coord_inp->getInputItem(
"transformation")) {
438 egsFatal(
"EB_Application:: `source coordinate transform` must contain exactly one transformation\n");
441 if (!coord_transform) {
442 egsFatal(
"EB_Application:: invalid `source coordinate transform` input\n");
445 EGS_AffineTransform *composed =
new EGS_AffineTransform(
450 delete coord_transform;
458 EGS_Input *source_overlap_inp = source_inp->takeInputItem(
"source overlap check");
459 if (source_overlap_inp){
462 egsFatal(
"EB_Application:: checkSourceOverlaps detected an error.");
474 vector<string> yn_choices;
475 yn_choices.push_back(
"no");
476 yn_choices.push_back(
"yes");
477 bool check_source_overlap = (bool)inp->getInput(
"check source overlaps", yn_choices, 0);
485 vector<string> mode_choices;
486 mode_choices.push_back(
"warning");
487 mode_choices.push_back(
"fatal");
489 bool fatal = (bool)inp->getInput(
"warning mode", mode_choices, 1);
491 EGS_Input *shape_inp = inp->takeInputItem(
"shape");
493 EGS_BaseShape *bounds = EGS_BaseShape::createShape(shape_inp);
496 egsWarning(
"egs_brachy::checkSourceOverlaps - no `shape` input found.\n");
501 if (bounds_volume < 0){
502 egsWarning(
"egs_brachy::checkSourceOverlaps - Unable to get shape volume.");
506 vector<string> excluded;
507 inp->getInput(
"excluded geometries", excluded);
510 int err = inp->getInput(
"density of random points (cm^-3)", density);
512 egsWarning(
"egs_brachy::checkSourceOverlaps - The volume correction 'density of random points (cm^-3)' input was not found. Using 1E6/cm^3\n");
515 EGS_I64 npoints = (EGS_I64)floor(max(1., density*bounds_volume));
518 EGS_RandomGenerator *rng = EGS_RandomGenerator::defaultRNG();
522 EGS_BaseGeometry *base_source = 0;
523 string base_source_name;
524 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
526 if (find(
ginfo.source_names.begin(),
ginfo.source_names.end(), gr.
name) !=
ginfo.source_names.end()){
527 base_source = EGS_BaseGeometry::getGeometry(gr.
name);
528 base_source_name = gr.
name;
533 egsFatal(
"egs_brachy::checkSourceOverlaps - did not find base source geometry");
538 EGS_AffineTransform inv_base_transform;
539 for (
int gg=0; gg <
ginfo.ngeom; gg++) {
543 if (gr.
type !=
"EGS_AEnvelope" && gr.
type !=
"EGS_ASwitchedEnvelope"){
551 vector<int> overlaps;
553 for (EGS_I64 i=0; i < npoints; i++) {
557 point = bounds->getRandomPoint(rng);
559 if (base_source->isWhere(point) < 0) {
562 inv_base_transform.transform(point);
568 EGS_Vector transformed(point);
576 EGS_Vector inner_transformed(transformed);
581 if (base_source->isWhere(inner_transformed) >= 0) {
583 overlaps.push_back(sa_idx);
584 overlaps.push_back(sb_idx);
601 if (overlaps.size() > 1){
602 string msg =
"Possible overlap of sources: ";
603 for (
int i=0; i < overlaps.size(); i++){
604 msg += to_string(overlaps[i]);
605 if (i != overlaps.size() -1 ){
609 egsInformation((msg+
"\n").c_str());
612 if (overlaps.size() > 1){
613 return fatal ? 1 : 0;
623 EGS_Input *vol_cor_inp = input->takeInputItem(
"volume correction");
625 egsWarning(
"Input item `volume correction` was not found\n");
645 vector<string> user_vols;
647 while ((ij = vol_cor_inp->takeInputItem(
"phantom region volumes")) != 0) {
650 ij->getInput(
"phantom name", phant_name);
653 egsFatal(
"`phanton region volume` specified for phantom `%s` which does not exist.", phant_name.c_str());
655 user_vols.push_back(phant_name);
658 vector<int> phantom_regs;
659 ij->getInput(
"region numbers", phantom_regs);
661 vector<EGS_Float> phantom_vols;
662 ij->getInput(
"region volumes", phantom_vols);
664 if (phantom_regs.size() != phantom_vols.size()){
666 "Mismatched number of inputs for `region numbers` and `region volumes` for phantom `%s`",
669 }
else if (phantom_regs.size() == 0){
671 "Missing `region numbers` or `region volumes` input for `phantom region volumes` block for phantom `%s`",
676 for (
size_t r = 0; r < phantom_regs.size(); r++){
688 string name = phant->
geometry->getName();
689 string type = phant->
geometry->getType();
690 if (phant->
needs_user_geoms && find(user_vols.begin(), user_vols.end(), name) == user_vols.end()){
692 "Missing `phantom region volume` block for phantom `%s`."
693 "Phantoms of type `%s` can not calculate volumes automatically.",
712 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
713 string name =
ginfo.phantom_names[idx];
715 EGS_BaseGeometry *phant_geom = EGS_BaseGeometry::getGeometry(name);
717 egsInformation(
"\n\nUnable to find phantom geometry `%s`.\n\n This is a fatal error\n\n", name.c_str());
722 set<int> global_regions;
724 for (
int reg=0; reg <
ginfo.nreg_total; reg++) {
725 if (
ginfo.phantomFromRegion(reg) == (
int)idx) {
726 global_regions.insert(reg);
730 if (global_regions.size()==0) {
732 "EB_Application::createPhantoms - No phantom regions detected for geometry '%s'.\n"
733 "Are you sure your phantom was included in the final simulation geometry?\n",
734 (phant_geom->getName()).c_str()
750 EGS_Input *source_inp = input->getInputItem(
"source definition");
772 int err = EGS_AdvancedApplication::initSource();
774 egsFatal(
"Failed to initialize source\n");
777 string stype = source->getObjectType();
778 is_phsp_source = stype ==
"EGS_PhspSource" || stype ==
"EB_IAEAPHSPSource";
782 egsInformation(
"Phase space being used. Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
795 int res = EGS_AdvancedApplication::initSimulation();
812 vector<string> format_choices;
813 format_choices.push_back(
"text");
814 format_choices.push_back(
"gzip");
815 EGS_Input *run_control = input->getInputItem(
"run control");
816 int format = run_control->getInput(
"egsdat file format", format_choices, 0);
823 run =
new EGS_RunControl(
this);
825 else if (uniform_run) {
829 run = EGS_RunControl::getRunControlObject(
this);
841 EGS_Input *rm = input->takeInputItem(
"run mode");
847 vector<string> choices;
848 choices.push_back(
"normal");
849 choices.push_back(
"superposition");
850 choices.push_back(
"volume correction only");
856 vector<string> yn_choices;
857 yn_choices.push_back(
"no");
858 yn_choices.push_back(
"yes");
872 EGS_Input *transportp = input->getInputItem(
"MC transport parameter");
874 transportp = input->getInputItem(
"transport parameter");
878 egsFatal(
"Missing `MC transport parameter` input item\n");
882 int err = transportp->getInput(
"fluorescent photon cutoff",
flu_cutoff);
887 int ret = EGS_AdvancedApplication::initCrossSections();
892 err = transportp->getInput(
"source ecut",
source_ecut);
897 err = transportp->getInput(
"source pcut",
source_pcut);
902 egsInformation(
"\negs_brachy transport parameter options:\n%s\n",
string(80,
'-').c_str());
903 egsInformation(
"Fluorescent photon cutoff %.3G\n",
flu_cutoff);
916 EGS_Input *options = input->takeInputItem(
"scoring options");
937 egsFatal(
"\n\nMissing input section 'scoring options'\n\n");
951 vector<string> gcr_inp;
952 int err = inp->getInput(
"current result phantom region", gcr_inp);
953 if (err || gcr_inp.size()==0) {
961 if (gcr_inp.size() >= 1) {
962 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
963 if (
ginfo.phantom_names[idx] == gcr_inp[0]) {
972 "Did not find '%s' phantom for getCurrentResult. Using phantom %s\n",
973 gcr_inp[0].c_str(),
ginfo.phantom_names[0].c_str()
981 if (gcr_inp.size() > 1) {
982 int ireg = atol(gcr_inp[1].c_str());
983 if (ireg > 0 && ireg < gcr_phantom->geometry->regions()) {
991 for (
size_t idx=0; idx <
ginfo.phantom_names.size(); idx++) {
992 if (
ginfo.phantom_names[idx] == name) {
1003 vector<string> yn_choices;
1004 yn_choices.push_back(
"no");
1005 yn_choices.push_back(
"yes");
1006 output_egsphant = (bool)inp->getInput(
"output egsphant files", yn_choices, 0);
1007 output_voxinfo = (bool)inp->getInput(
"output voxel info files", yn_choices, 0);
1010 vector<string> format_choices;
1011 format_choices.push_back(
"text");
1012 format_choices.push_back(
"gzip");
1014 int format = inp->getInput(
"dose file format", format_choices, 0);
1017 format = inp->getInput(
"egsphant file format", format_choices, 0);
1020 format = inp->getInput(
"voxel info file format", format_choices, 0);
1023 format = inp->getInput(
"volume correction file format", format_choices, 0);
1026 inp->getInput(
"record initial particle positions",
record_n_init);
1032 EGS_Input *phsp_inp = inp->takeInputItem(
"phsp scoring");
1043 timing_blocks.addTimer(
"egs_brachy::initVarianceReduction");
1045 egsInformation(
"\n\negs_brachy Variance Reduction Information\n%s\n\n",
string(80,
'=').c_str());
1047 EGS_Input *vr = input->takeInputItem(
"variance reduction");
1061 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1062 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1063 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1064 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1070 EGS_Input *ri = vr->takeInputItem(
"particle recycling");
1073 egsFatal(
"Primary-scatter dose scoring is not available with recycling. Please turn off recycling or disable scatter dose scoring.\n");
1075 egsInformation(
"Particle Recycling\n");
1080 egsInformation(
" Overriding requested 'single generator = no' parameter. Setting to 'yes'\n");
1082 egsInformation(
"\n");
1088 vector<string> yn_choices;
1089 yn_choices.push_back(
"no");
1090 yn_choices.push_back(
"yes");
1092 string old_rr_setting;
1093 int err = vr->getInput(
"range rejection", old_rr_setting);
1096 "'range rejection' is not a valid setting for egs_brachy.\n"
1097 "Please use 'global range rejection' and 'source range rejection' settings instead.\n"
1101 EGS_Float old_rr_max_e;
1102 err = vr->getInput(
"range rejection max energy", old_rr_max_e);
1105 "'range rejection max energy' is not a valid setting for egs_brachy.\n"
1106 "Please use 'global range rejection max energy' and 'source range rejection max energy' settings instead.\n"
1111 global_i_do_rr = vr->getInput(
"global range rejection", yn_choices, 1);
1112 egsInformation(
"Global Range Rejection = %s\n",
global_i_do_rr ?
"Yes" :
"No");
1114 int err = vr->getInput(
"global range rejection max energy",
global_e_max_rr);
1119 egsFatal(
"Global Range Rejection max energy must be at least 0.512MeV\n");
1121 egsInformation(
"Global Range Rejection Maximum Energy = %.3G MeV\n",
global_e_max_rr);
1125 source_i_do_rr = vr->getInput(
"source range rejection", yn_choices, 0);
1126 egsInformation(
"Source Range Rejection = %s\n",
source_i_do_rr ?
"Yes" :
"No");
1128 int err = vr->getInput(
"source range rejection max energy",
source_e_max_rr);
1133 egsFatal(
"Source Range Rejection max energy must be at least 0.512MeV\n");
1135 egsInformation(
"Source Range Rejection Maximum Energy = %.3G MeV\n",
source_e_max_rr);
1145 egsInformation(
"BCSE = %s\n",
do_bcse ?
"Yes" :
"No");
1148 " Brem Cross Section Enhancement medium = %s (%d)\n",
1151 egsInformation(
" Brem Cross Section Enhancement factor = %.3G\n",
bcse_factor);
1156 err = vr->getInput(
"split brem photons",
nbr_split);
1157 egsInformation(
"Brem Splitting = %s\n",
nbr_split > 1?
"Yes" :
"No");
1160 egsInformation(
" Splitting brem photons N times = %d\n",
nbr_split);
1167 egsInformation(
"Charged Particle Russian Roulette = %s\n", the_egsvr->i_play_RR ?
"Yes" :
"No");
1168 if (!err || the_egsvr->i_play_RR) {
1173 " Survival probability (1/nbrsplt*bcse) = 1/(%d*%.3G) (%.3G%%)\n",
1179 " Survival probability (1/nbrsplt) = 1/%d (%.3G%%)\n",
1194 vector<string> yn_choices;
1195 yn_choices.push_back(
"no");
1196 yn_choices.push_back(
"yes");
1198 int play_rr = scoring_options->getInput(
"russian roulette", yn_choices, 0);
1203 the_egsvr->i_play_RR = 1;
1205 AusgabCall rr_calls[] = {
1206 BeforeBrems, AfterBrems,
1207 BeforeAnnihFlight, AfterAnnihFlight,
1208 BeforeAnnihRest, AfterAnnihRest,
1212 int ncalls =
sizeof(rr_calls)/
sizeof(rr_calls[0]);
1220 vector<string> bcse_inp;
1221 int err = inp->getInput(
"bcse medium", bcse_inp);
1222 if (err || bcse_inp.size()==0) {
1226 bcse_med_num = EGS_BaseGeometry::getMediumIndex(bcse_inp[0]);
1228 egsWarning(
"Requested an unknown medium `%s` for BCSE\n",bcse_inp[0].c_str());
1233 if (bcse_inp.size() == 1) {
1244 the_egsvr->i_play_RR = 1;
1246 AusgabCall bcse_calls[] = {BeforeBrems, AfterBrems, FluorescentEvent};
1257 bool header_printed =
false;
1259 while (EGS_Input *spec_inp=scoring_input->takeInputItem(
"spectrum scoring")) {
1261 if (!header_printed) {
1262 egsInformation(
"\n\negs_brachy Spectrum Scoring Information\n%s\n\n",
string(80,
'=').c_str());
1263 header_printed =
true;
1270 egsInformation(
"Added scorer with title: %s\n", scorer->
getInfo().c_str());
1277 for (
size_t call=BeforeTransport; call <= UnknownCall; call++) {
1278 setAusgabCall((AusgabCall)call,
false);
1288 AusgabCall always_call[] = {BeforeTransport, AfterTransport, FluorescentEvent};
1297 vector<string> choices;
1298 choices.push_back(
"no");
1299 choices.push_back(
"yes");
1301 score_tlen = scoring_options->getInput(
"score tracklength dose", choices, 1);
1314 map<string, string> muen_for_med;
1316 vector<string> muen_meds;
1317 scoring_options->getInput(
"muen for media", muen_meds);
1319 for (
size_t i=0; i < muen_meds.size(); i++) {
1320 string med_name = muen_meds[i];
1321 muen_for_med[med_name] = med_name;
1324 EGS_Input *muen_inp;
1325 while ((muen_inp = scoring_options->takeInputItem(
"muen for medium"))) {
1326 string scoring, transport;
1327 int err = muen_inp->getInput(
"transport medium", transport);
1329 egsFatal(
"Missing 'transport medium' key in 'muen for medium' block\n");
1332 err = muen_inp->getInput(
"scoring medium", scoring);
1334 egsFatal(
"Missing 'scoring medium' key in 'muen for medium' block\n");
1338 muen_for_med[transport] = scoring;
1343 return muen_for_med;
1349 egsInformation(
"\n\negs_brachy Muen Data Information\n%s\n\n",
string(80,
'=').c_str());
1352 bool missing_muen = scoring_options->getInput(
"muen file", muen_file) != 0;
1354 egsFatal(
"\n\nMissing input scoring options: muen file\n\n This is a fatal error\n\n");
1356 muen_file = egsExpandPath(muen_file);
1363 "EB_Application:: missing or invalid 'muen for media' input item or 'muen substitution' block(s).\n"
1364 " No muen data has been read.\n"
1372 egsFatal(
"Failed to read muen data from %s\n",muen_file.c_str());
1375 egsInformation(
"Read muen data from %s\n", muen_file.c_str());
1380 string transport_med = mit->first;
1381 string scoring_med = mit->second;
1384 egsFatal(
"EB_Application::Failed to get muen interpolator for %s\n", scoring_med.c_str());
1387 int med_idx = EGS_BaseGeometry::getMediumIndex(transport_med);
1390 "EB_Application:: You requested scoring medium %s for transport medium %s but %s"
1391 " is not present in the geometry\n", scoring_med.c_str(), transport_med.c_str(), transport_med.c_str()
1397 "Set medium %d (%s) to use muen data: %s\n",
1398 med_idx, transport_med.c_str(), scoring_med.c_str()
1406 for (
int i= 0; i < ncalls; i++) {
1407 setAusgabCall(calls[i],
true);
1415 vector<string> choices;
1416 choices.push_back(
"no");
1417 choices.push_back(
"yes");
1419 score_edep = scoring_options->getInput(
"score energy deposition", choices, 0);
1426 AusgabCall edep_calls[] = {ExtraEnergy, UserDiscard, PegsCut, EgsCut};
1434 vector<string> choices;
1435 choices.push_back(
"no");
1436 choices.push_back(
"yes");
1438 score_scat = scoring_options->getInput(
"score scatter dose", choices, 0);
1440 egsFatal(
"\nPrimary-scatter dose scoring requires tracklength scoring. Please enable tracklength scoring or disable scatter dose scoring.\n");
1444 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");
1448 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");
1457 AusgabCall photon_scat_calls[] = {
1458 AfterAnnihFlight, AfterAnnihRest,
1459 AfterPair, AfterCompton, AfterPhoto, AfterRayleigh,
1463 int ncalls =
sizeof(photon_scat_calls)/
sizeof(photon_scat_calls[0]);
1470 EGS_Float scale = 1.;
1472 int err = scoring_options->getInput(
"dose scaling factor", scale);
1474 if (!err && scale > 0) {
1485 while ((scale = scoring_options->takeInputItem(
"scale xcc"))) {
1487 int err = scale->getInput(
"scale xcc",tmp);
1489 if (!err && tmp.size() == 2) {
1490 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1492 EGS_Float fac = atof(tmp[1].c_str());
1493 egsInformation(
"\n ***** Scaling xcc of medium %d with %G\n",imed,fac);
1494 F77_OBJ_(egs_scale_xcc,EGS_SCALE_XCC)(&imed,&fac);
1500 while ((scale = scoring_options->takeInputItem(
"scale bc"))) {
1502 int err = scale->getInput(
"scale bc",tmp);
1504 if (!err && tmp.size() == 2) {
1505 int imed = EGS_BaseGeometry::getMediumIndex(tmp[0]) + 1;
1507 EGS_Float fac = atof(tmp[1].c_str());
1508 egsInformation(
"\n ***** Scaling bc of medium %d with %G\n",imed,fac);
1509 F77_OBJ_(egs_scale_bc,EGS_SCALE_BC)(&imed,&fac);
1521 EGS_Vector new_loc(p->x);
1522 EGS_Vector new_dir(p->u);
1529 double angle = 2*M_PI*rndm->getUniform();
1530 EGS_RotationMatrix rot = EGS_RotationMatrix::rotZ(angle);
1540 int new_reg = geometry->isWhere(new_loc);
1541 int new_med = geometry->medium(new_reg);
1545 int cur_np = the_stack->np;
1546 int new_np = the_stack->np+1;
1547 int np_idx = new_np-1;
1549 the_stack->ir[np_idx] = new_reg + 2;
1550 the_stack->latch[np_idx] = p->latch;
1551 the_stack->E[np_idx] = p->E;
1552 the_stack->wt[np_idx] = new_wt;;
1553 the_stack->iq[np_idx] = p->q;
1554 the_stack->x[np_idx] = new_loc.x;
1555 the_stack->y[np_idx] = new_loc.y;
1556 the_stack->z[np_idx] = new_loc.z;
1557 the_stack->u[np_idx] = new_dir.x;
1558 the_stack->v[np_idx] = new_dir.y;
1559 the_stack->w[np_idx] = new_dir.z;
1560 the_stack->dnear[np_idx] = 0;
1563 the_stack->npold = cur_np;
1565 the_epcont->irnew = new_reg+2;
1566 the_useful->medium_new = new_med+1;
1571 the_stack->wt[np_idx-1] = 0;
1578 EGS_AdvancedApplication::startNewParticle();
1580 int ireg = the_stack->ir[the_stack->np-1] - 2;
1581 if (
ginfo.isSource(ireg)) {
1593 EGS_AdvancedApplication::enterNewRegion();
1595 int ireg = the_epcont->irnew-2;
1596 if (
ginfo.isSource(ireg)) {
1613 the_stack->wt[the_stack->np-1] = 0;
1614 the_epcont->idisc = idisc;
1626 for (
int recycle_idx=0; recycle_idx <
recycle_opts->nrecycle; recycle_idx++) {
1628 int start_loc, stop_loc;
1632 stop_loc = start_loc + 1;
1638 for (
int source_loc = start_loc; source_loc < stop_loc; source_loc++) {
1641 bool kill = source_loc == start_loc && recycle_idx == 0 && !new_hist;
1654 bool same_particle = the_stack->npold == the_stack->np;
1655 if (!same_particle){
1660 cur_R = top_p.x.length2();
1669 egsWarning(
"Particle hasn't moved in %d steps. Discarding particle\n",
NUM_STUCK_STEPS);
1682 bool is_photon = top_p.q == 0;
1683 bool is_before_transport = iarg == BeforeTransport;
1684 bool is_after_transport = iarg == AfterTransport;
1686 if (is_after_transport &&
isStuck()) {
1687 the_stack->latch[the_stack->np - 1] = top_p.latch;
1691 int global_ir = top_p.ir;
1692 int irnew = the_epcont->irnew-2;
1693 int irold = the_epcont->irold-2;
1695 bool in_phantom =
ginfo.isPhantom(global_ir);
1696 bool in_source =
ginfo.isSource(global_ir);
1698 bool is_extra_scoring_reg =
false;
1699 string local_geom_name =
"";
1700 int local_geom_ir = -1;
1701 int extra_reg_dose_index = -1;
1707 local_geom_ir = local.second;
1708 local_geom_name = local.first->getName();
1711 map<string, vector<int> >::iterator i =
extra_scoring_reg.find(local_geom_name);
1713 vector<int>::iterator it = find(i->second.begin(), i->second.end(), local_geom_ir);
1714 if (it != i->second.end()){
1715 is_extra_scoring_reg =
true;
1716 extra_reg_dose_index = distance(i->second.begin(), it);
1722 if (is_before_transport) {
1725 }
else if (in_phantom) {
1733 bool discard_fluorescent = iarg == FluorescentEvent && top_p.E <=
flu_cutoff;
1734 if (discard_fluorescent) {
1736 the_stack->latch[the_stack->np - 1] = top_p.latch;
1741 if (
score_scat && (iarg > AfterTransport) && !in_source) {
1743 for (
int ip=the_stack->npold-1; ip < the_stack->np; ip++) {
1748 bool next_is_source =
ginfo.isSource(irnew);
1749 bool last_was_source =
ginfo.isSource(irold);
1753 bool leaving_source = is_before_transport && in_source && !next_is_source;
1754 bool escaping_source = leaving_source && !
latch_control.hasEscaped(&top_p);
1757 bool left_source = is_after_transport && !in_source && last_was_source;
1758 bool escaped_source = left_source && !
latch_control.hasEscaped(&top_p);
1760 bool escaping_geom = is_before_transport && irnew < 0;
1761 bool escaped_geom = global_ir < 0;
1774 int nmesg =
sizeof(send_messages)/
sizeof(send_messages[0]);
1775 for (
int m=0; m < nmesg; m++) {
1776 if (send_messages[m].first) {
1777 pevent_pub.notify(send_messages[m].second, &top_p);
1783 the_stack->latch[the_stack->np - 1] = top_p.latch;
1790 if (escaped_source && is_after_transport) {
1792 EGS_Float wt = top_p.wt;
1813 bool in_vaccuum = the_useful->medium <= 0;
1814 bool score_tracklength =
score_tlen && is_photon && is_before_transport;
1815 bool score_interaction =
score_edep && iarg <= ExtraEnergy;
1816 bool dose_scoring_not_needed = !is_extra_scoring_reg && (!in_phantom || in_vaccuum || !(score_tracklength || score_interaction));
1818 if (dose_scoring_not_needed) {
1824 int phant_idx =
ginfo.phantomFromRegion(global_ir);
1825 int phant_ir =
ginfo.globalToLocalReg(global_ir);
1832 if (score_tracklength) {
1834 EGS_Interpolator *interp =
media_muen[the_useful->medium-1];
1835 EGS_Float muen_val = interp ? interp->interpolateFast(the_epcont->gle) : 0;
1836 EGS_Float tracklength_edep = the_epcont->tvstep*top_p.E*muen_val*top_p.wt;
1841 if (needs_vol_cor) {
1848 phant->
scoreTlen(phant_ir, tracklength_edep / vol, &top_p);
1852 if (is_extra_scoring_reg){
1854 extra_scoring_doses[local_geom_name]->score(extra_reg_dose_index, tracklength_edep / vol);
1858 if (score_interaction) {
1862 EGS_Float edep = getEdep()*top_p.wt;
1873 phant->
scoreEdep(phant_ir, edep / mass);
1877 if (is_extra_scoring_reg){
1888 bool is_phat = fabs(top_p.wt - 1.) <
EB_EPSILON;
1892 bool in_bcse_med = the_useful->medium - 1 ==
bcse_med_num;
1894 if (iarg == BeforeBrems) {
1900 }
else if (iarg == AfterBrems) {
1904 for (
int ip=the_stack->npold; ip < the_stack->np; ip++) {
1907 EGS_Float rnd = rndm->getUniform();
1909 the_stack->E[the_stack->npold-1] += top_p.E;
1913 the_egsvr->nbr_split = 1;
1916 }
else if (iarg == FluorescentEvent && is_phat) {
1924 the_stack->npold = the_stack->np;
1925 F77_OBJ_(egs_uniform_photons, EGS_UNIFORM_PHOTONS)(&nsplit, &top_p.E);
1929 }
else if (
do_brem_split && iarg == FluorescentEvent && is_phat) {
1932 the_stack->npold = the_stack->np;
1962 string sep(80,
'=');
1964 "\n\nResults for egs_brachy run\n%s\n",
1965 string(80,
'-').c_str()
1969 egsInformation(
"\n\nHistory Information\n%s\n",sep.c_str());
1970 egsInformation(
"Last case = %llu\n", last_case);
1971 egsInformation(
"current case = %llu\n", current_case);
1972 egsInformation(
"run->getNcase() = %llu\n", run->getNcase());
1973 egsInformation(
"source->getFluence() = %f\n", source->getFluence());
1975 egsInformation(
"Particles recycled = %d\n",
recycle_opts->nrecycle);
1980 egsInformation(
"\n\nGeometry Errors\n%s\n", sep.c_str());
1981 egsInformation(
"Number of geometry errors (/max allowed) = %d / %d\n", run->geomErrorCount, run->geomErrorMax);
1982 egsInformation(
"Number of 'stuck' particles discarded = %llu\n",
n_stuck);
1987 EGS_I64 hist_norm = run->getNdone();
1992 "Warning: Stats about energy escaping source may not be accurate when "
1993 "not using a single source generator\n"
1998 phsp->finish(current_case);
1999 phsp->outputResults();
2000 phsp->destroySource();
2008 egsInformation(
"\nSpectrum scoring results\n%s\n",sep.c_str());
2009 string root = constructIOFileName(
"",
true);
2013 (*it)->outputResults(root);
2019 string fname = constructIOFileName(
"",
true)+
".pinit";
2021 out.open(fname.c_str());
2022 out << std::fixed << std::showpoint << std::setprecision(6);
2024 out << (*it).x <<
"\t" << (*it).y <<
"\t" << (*it).z <<
"\n";
2027 egsInformation(
"\nInitial Particle Positions\n%s\n",sep.c_str());
2028 egsInformation(
"%d Initial particle positions written to .pinit file\n",
p_init_locs.size());
2040 (*p)->outputResults(20, dd_format, ep_format, vi_format, vc_format);
2045 egsInformation(
"\nStep Counts\n%s\n", sep.c_str());
2046 EGS_Float total_steps = 0;
2048 for (
int i=-1; i < 2; i++) {
2054 egsInformation(
"Total particle steps : %20llu\n", (EGS_I64)total_steps);
2055 for (
int i=-1; i < 2; i++) {
2057 egsInformation(
"q=%2d Steps taken in sources : %20llu (%.2f%%)\n", i,
steps_in_sources[i],
2061 egsInformation(
"q=%2d Steps taken in phantoms : %20llu (%.2f%%)\n", i,
steps_in_phantoms[i],
2065 egsInformation(
"q=%2d Steps taken in other objects : %20llu (%.2f%%)\n", i,
steps_in_other[i],
2079 count = current_case;
2089 int result = EGS_Application::runSimulation();
2097 last_case = current_case;
2099 current_case = source->getNextParticle(rndm, p.q, p.latch, p.E, p.wt, p.x, p.u);
2118 p.ir = geometry->isWhere(p.x);
2121 egsWarning(
"EB_Application::simulateSingleShower() - particle initiated at (x, y, z) = (%.2g, %.2g, %.2g)\n", p.x.x, p.x.y, p.x.z);
2122 egsFatal(
"EB_Application::simulateSingleShower() - Particle initiated outside "
2123 "the geometry! Please check your source locations.\n");
2134 }
else if (!
ginfo.isSource(p.ir)) {
2140 "Particle started in region %d (%s reg %d) which is outside a source geometry. Please check your geometry\n",
2142 r.first->getName().c_str(),
2152 cur_R = p.x.length2();
2176 return err || finishShower();
2187 int err = EGS_Application::startNewShower();
2194 if (current_case != last_case) {
2198 last_case = current_case;
2208 if (!run->storeState(*out)) {
2211 if (!egsStoreI64(*out,current_case)) {
2215 if (!rndm->storeState(*out)) {
2218 if (!source->storeState(*out)) {
2221 for (
size_t j=0; j<a_objects_list.size(); ++j) {
2222 if (!a_objects_list[j]->storeState(*out)) {
2237 if (np > 10000000) {
2238 egsWarning(
"EGS_AdvancedApplication::outputData(): egsGetRNGPointers"
2239 " returns a huge number? (%d)\n",np);
2242 EGS_Float *array =
new EGS_Float [np];
2244 (*out) <<
" " << np <<
" " << ip <<
"\n";
2245 for (
int j=0; j<np; j++) {
2246 (*out) << array[j] <<
" ";
2249 double ch_steps, all_steps;
2251 (*out) << ch_steps <<
" " << all_steps <<
"\n";
2253 return out->good() ? 0 : 13;
2261 (*out) << std::setprecision(9);
2263 for (
int i=-1; i < 2; i++) {
2278 err = (*spec_it)->outputData(out);
2284 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2286 err = (*phant_it)->outputData(out);
2315 string extension(
".egsdat");
2316 extension += (use_gz ?
".gz" :
"");
2317 string ofile = constructIOFileName(extension.c_str(),
true);
2327 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2338 data_out =
new ofstream(ofile.c_str());
2340 egsWarning(
"EGS_Application::outputData: failed to open %s for writing\n",ofile.c_str());
2354 if (!run->setState(*in)) {
2357 if (!egsGetI64(*in,current_case)) {
2360 last_case = current_case;
2361 if (!rndm->setState(*in)) {
2364 if (!source->setState(*in)) {
2367 for (
int j=0; j<a_objects_list.size(); ++j) {
2368 if (!a_objects_list[j]->setState(*in)) {
2382 if (np > 10000000) {
2383 egsWarning(
"EB_Application::egsAdvApplicationReadData(): got huge size "
2384 "for the mortran random array? (%d)\n",np);
2387 EGS_Float *array =
new EGS_Float [np];
2388 for (
int j=0; j<np; j++) {
2396 double ch_steps, all_steps;
2397 (*in) >> ch_steps >> all_steps;
2399 return in->good() ? 0 : 13;
2406 for (
int i=-1; i < 2; i++) {
2421 err = (*spec_it)->readData(in);
2427 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2429 err = (*phant_it)->readData(in);
2458 string extension(
".egsdat");
2459 extension += (use_gz ?
".gz" :
"");
2460 string ifile = constructIOFileName(extension.c_str(),
false);
2470 egsWarning(
"EGS_Application::readData: failed to open %s for reading\n", ifile.c_str());
2480 data_in =
new ifstream(ifile.c_str());
2482 egsWarning(
"EGS_Application::readData: failed to open %s for writing\n",ifile.c_str());
2498 "\n Suming the following .egsdat files:\n"
2499 "=======================================================================\n");
2502 EGS_Float last_cpu = 0;
2503 EGS_I64 last_ncase = 0;
2506 for (
int j=1; j<500; j++) {
2509 string name(
"%s_w%d.egsdat");
2510 name += (use_gz ?
".gz" :
"");
2512 sprintf(buf, name.c_str(), output_file.c_str(), j);
2513 string dfile = egsJoinPath(app_dir,buf);
2517 bool opened =
false;
2519 gzin.
open(dfile.c_str());
2523 in.open(dfile.c_str());
2524 opened = in.is_open();
2532 EGS_I64 ncase = run->getNdone();
2533 EGS_Float cpu = run->getCPUTime();
2534 egsInformation(
"%2d %-30s ncase=%-14lld cpu=%-11.2f\n",
2535 ndat,buf,ncase-last_ncase,cpu-last_cpu);
2540 egsWarning(
"%2d %-30s error %d\n",ndat,buf,err);
2546 "=======================================================================\n");
2547 egsInformation(
"%40s%-14lld cpu=%-11.2f\n\n",
"Total ncase=",last_ncase,
2559 EGS_AdvancedApplication::resetCounter();
2562 for (
int i=-1; i < 2; i++) {
2574 (*spec_it)->resetCounter();
2577 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2579 (*phant_it)->resetCounter();
2587 int err = EGS_AdvancedApplication::addState(data);
2592 for (
int i=-1; i < 2; i++) {
2593 EGS_I64 steps_in_sources_tmp;
2594 EGS_I64 steps_in_phantoms_tmp;
2595 EGS_I64 steps_in_other_tmp;
2597 data >> steps_in_sources_tmp;
2598 data >> steps_in_phantoms_tmp;
2599 data >> steps_in_other_tmp;
2615 err = (*spec_it)->addState(data);
2621 vector<EB_Phantom *>::iterator phant_it =
phantom_geoms.begin();
2623 err = (*phant_it)->addState(data);
2636 return (stat(name.c_str(), &buffer) == 0);
2642 int n_of_egsdat = 0;
2645 string name(
"%s_w%d.egsdat");
2646 name += (use_gz ?
".gz" :
"");
2648 for (
int i = first_parallel; i < first_parallel + n_parallel; i++) {
2649 sprintf(buf,name.c_str(),final_output_file.c_str(),i);
2650 string dfile = egsJoinPath(app_dir,buf);
2670 int err = input->getInput(
"interval wait time", dummy);
2676 err = input->getInput(
"number of intervals", dummy);
2683 err = input->getInput(
"watcher jobs", w_jobs);
2685 for (
int i = 0; i < w_jobs.size(); i++) {
2686 if (
ipar == w_jobs[i]) {
2703 vector<string> check_options;
2704 check_options.push_back(
"yes");
2705 check_options.push_back(
"no");
2706 int ichk = input->getInput(
"check jobs completed",check_options,0);
2727 string name(
"%s_w%d.egsdat");
2728 name += (use_gz ?
".gz" :
"");
2732 sprintf(buf,name.c_str(),
app->getFinalOutputFile().c_str(),
ipar);
2733 string datFile = egsJoinPath(
app->getOutputDir(),buf);
2734 if (remove(datFile.c_str()) == 0) {
2735 egsWarning(
"EB_UniformRunControl: %s deleted\n",
2740 return EGS_RunControl::startSimulation();
2745 EGS_RunControl::describeRCO();
2750 " Watcher job: remains running after completion checking\n"
2751 " for other jobs finishing every %d s for %d s!\n",
2756 " Option to check for finishing jobs is OFF!\n\n");
2766 usleep(mscnds * 1000);
2771 int err = EGS_RunControl::finishSimulation();
2777 int interval = 0, njobs_done = 0, njobs_done_old= 0;
2781 njobs_done =
app->howManyJobsDone();
2783 if (njobs_done ==
npar - 1) {
2788 if (njobs_done_old < njobs_done) {
2789 egsInformation(
"=> Combining %d jobs ...\n",njobs_done);
2790 app->combinePartialResults();
2792 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
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