44 static bool EGS_FLUENCE_SCORING_LOCAL inputSet =
false;
46 #define REGIONS_ENTRIES 100
47 #define REGIONS_PER_LINE 25
51 scoring_charge(photon), source_charge(unknown),
52 n_scoring_regions(0), n_source_regions(0),
53 max_reg(-1), active_region(-1),
54 flu_s(0), flu_nbin(128), flu_xmin(0.001), flu_xmax(1.0),
55 norm_u(1.0), flu(0), fluT(0), flu_p(0), fluT_p(0), current_ncase(0),
56 verbose(false), score_primaries(false), score_spe(false),
57 m_primary(0.0), m_tot(0.0) {
58 otype =
"EGS_FluenceScoring";
60 flu_a /= (flu_xmax - flu_xmin);
61 flu_b = -flu_xmin*flu_a;
80 void EGS_FluenceScoring::initScoring(
EGS_Input *inp) {
88 int the_selection = 0;
89 name.push_back(
"photon");
90 name.push_back(
"electron");
91 name.push_back(
"positron");
92 name.push_back(
"undefined");
93 the_selection = inp->getInput(
"scoring particle",
name, 3);
94 switch (the_selection) {
96 particle_name=
"photon";
97 scoring_charge = photon;
100 particle_name=
"electron";
101 scoring_charge = electron;
104 particle_name=
"positron";
105 scoring_charge = positron;
108 egsFatal(
"\n******* ERROR *******\n"
109 " Undefined scoring charge!\n"
111 "************************\n");
114 the_selection = inp->getInput(
"source particle",
name, 3);
115 switch (the_selection) {
117 source_charge = photon;
120 source_charge = electron;
123 source_charge = positron;
126 source_charge = unknown;
129 vector<string> choice;
130 choice.push_back(
"no");
131 choice.push_back(
"yes");
132 verbose = inp->getInput(
"verbose", choice,0);
133 score_primaries = inp->getInput(
"score primaries",choice,0);
134 score_spe = inp->getInput(
"score spectrum", choice,0);
137 int err_norm = inp->getInput(
"normalization",norma);
146 EGS_Float flu_Emin, flu_Emax;
147 EGS_Input *eGrid = inp->takeInputItem(
"energy grid");
149 int err_n = eGrid->
getInput(
"number of bins",flu_nbin);
150 int err_i = eGrid->
getInput(
"minimum kinetic energy",flu_Emin);
151 int err_f = eGrid->
getInput(
"maximum kinetic energy",flu_Emax);
152 if (err_n)
egsFatal(
"\n**** EGS_FluenceScoring::initScoring"
153 " Missing input: number of bins.\n"
155 if (err_i)
egsFatal(
"\n**** EGS_FluenceScoring::initScoring"
156 " Missing input: minimum kinetic energy.\n"
158 if (err_f)
egsFatal(
"\n**** EGS_FluenceScoring::initScoring"
159 " Missing input: maximum kinetic energy.\n"
163 vector<string> scale;
164 scale.push_back(
"linear");
165 scale.push_back(
"logarithmic");
166 flu_s = eGrid->
getInput(
"scale",scale,0);
172 flu_xmin = log(flu_Emin);
173 flu_xmax = log(flu_Emax);
176 flu_a /= (flu_xmax - flu_xmin);
177 flu_b = -flu_xmin*flu_a;
192 vector <int> s_start, s_stop;
199 if (inp->getInput(
"source regions",s_regionsString) || s_regionsString.length()<=0) {
200 int err1 = inp->getInput(
"start source region",s_start);
201 int err2 = inp->getInput(
"stop source region",s_stop);
202 if (!err1 && !err2) {
203 if (s_start.size() == s_stop.size()) {
204 for (
int i=0; i<s_start.size(); i++) {
205 int ir = s_start[i], fr = s_stop[i];
207 egsFatal(
"\nEGS_FluenceScoring::initScoring: \n"
208 " Decreasing start (%d) / stop %d region in source region group %d\n"
209 " Aborting!\n\n", ir, fr, i);
210 for (
int ireg=ir; ireg<=fr; ireg++) {
211 s_region.push_back(ireg);
216 "\nEGS_FluenceScoring::initScoring: \n"
217 " Mismatch in number of start (%d) and stop (%d)\n"
218 " source region groups. Aborting!\n",
219 s_start.size(),s_stop.size());
225 void EGS_FluenceScoring::getSensitiveRegions(
EGS_Input *inp) {
227 string listLabel, startLabel, stopLabel;
229 if (
otype ==
"EGS_PlanarFluence") {
230 listLabel =
"contributing regions";
231 startLabel =
"start contributing region";
232 stopLabel =
"stop contributing region";
234 else if (
otype ==
"EGS_VolumetricFluence") {
235 listLabel =
"scoring regions";
236 startLabel =
"start region";
237 stopLabel =
"stop region";
240 egsFatal(
"\n*** Unknown fluence scoriung type! Aborting!\n\n");
244 if (!inp->getInput(listLabel,f_regionsString) && f_regionsString.length()>0) {
246 if (f_regionsString ==
"ALL") {
247 score_in_all_regions =
true;
250 score_in_all_regions =
false;
254 int err1 = inp->getInput(startLabel,f_start);
255 int err2 = inp->getInput(stopLabel, f_stop);
256 if (!err1 && !err2) {
257 if (f_start.size() == f_stop.size()) {
258 for (
int i=0; i<f_start.size(); i++) {
259 int ir = f_start[i], fr = f_stop[i];
261 egsFatal(
"\nEGS_FluenceScoring::initScoring: \n"
262 " Decreasing start (%d) / stop (%d) in region group %d\n"
263 " Aborting!\n\n", ir, fr, i);
264 for (
int ireg=ir; ireg<=fr; ireg++) {
265 f_region.push_back(ireg);
268 score_in_all_regions =
false;
271 "\nEGS_FluenceScoring::initScoring: \n"
272 " Mismatch in number of start (%d) and stop (%d)\n"
273 " region groups. Aborting!\n",
274 f_start.size(),f_stop.size());
279 void EGS_FluenceScoring::getNumberRegions(
const string &str, vector<int> ®s) {
281 egsFatal(
"EGS_FluenceScoring::getNumberRegions\n"
282 " Undefined parent application! Aborting!\n");
287 void EGS_FluenceScoring::getLabelRegions(
const string &str, vector<int> ®s) {
289 egsFatal(
"EGS_FluenceScoring::getLabelRegions\n"
290 " Undefined parent application! Aborting!\n");
295 void EGS_FluenceScoring::setUpRegionFlags() {
297 if (s_regionsString.length() > 0 && !s_region.size()) {
298 getNumberRegions(s_regionsString, s_region);
299 getLabelRegions(s_regionsString, s_region);
302 n_source_regions = s_region.size() < nreg ? s_region.size() : nreg;
304 if (!score_in_all_regions) {
305 if (f_regionsString.length() > 0 && !f_region.size()) {
306 getNumberRegions(f_regionsString, f_region);
307 getLabelRegions(f_regionsString, f_region);
310 n_scoring_regions = f_region.size() < nreg ? f_region.size() : nreg;
312 else if (score_in_all_regions) {
313 n_scoring_regions = nreg;
314 for (
int j=0; j<nreg; j++) {
315 f_region.push_back(j);
319 if (n_source_regions == nreg && score_primaries)
320 egsWarning(
"=> Warning: Setting n_source_regions = nreg \n"
321 " effectively supresses classification\n"
322 " of primaries and secondaries!");
323 for (
int i = 0; i < n_source_regions; i++) {
324 is_source[s_region[i]] =
true;
327 for (
int i = 0; i < n_scoring_regions; i++) {
328 is_sensitive[f_region[i]] =
true;
329 if (f_region[i] > max_reg) {
330 max_reg = f_region[i];
335 void EGS_FluenceScoring::describeMe() {
340 if (n_scoring_regions == nreg) {
344 int start = 0, stop = 0, k = 0, entries = 0;
347 while (k < nreg && entries < REGIONS_ENTRIES) {
349 if (is_sensitive[k]) {
352 while (is_sensitive[k] && k < nreg) {
357 sprintf(buf,
"%d-%d",start,stop);
359 else if (k % REGIONS_PER_LINE) {
360 sprintf(buf,
" %d",start);
363 sprintf(buf,
" %d\n",start);
366 if (entries == REGIONS_ENTRIES) {
367 sprintf(buf,
"... %d\n",max_reg);
379 if (score_primaries) {
380 if (source_charge == unknown) {
381 source_charge = scoring_charge;
382 description +=
" - Unknown source charge due to multi-particle source\n";
383 description +=
" and no user input defining source particle type!\n";
389 sprintf(buf,
"%d\n",source_charge);
395 EGS_Float Emin = flu_s ? exp(flu_xmin):flu_xmin,
396 Emax = flu_s ? exp(flu_xmax):flu_xmax;
397 sprintf(buf,
"%g MeV and %g MeV energy range",Emin,Emax);
414 otype =
"EGS_PlanarFluence";
421 m_d = m_normal*m_midpoint;
428 for (
int j=0; j<Nx*Ny; j++) {
433 for (
int j=0; j<Nx*Ny; j++) {
453 if (source_charge == unknown) {
459 nreg =
app->getnRegions();
462 for (
int j=0; j<nreg; j++) {
464 if (!score_in_all_regions) {
465 is_sensitive.push_back(
false);
468 is_sensitive.push_back(
true);
471 is_source.push_back(
false);
481 for (
int j = 0; j < Nx*Ny; j++) {
486 if (score_primaries) {
490 for (
int j = 0; j < Nx*Ny; j++) {
499 void EGS_PlanarFluence::initScoring(
EGS_Input *inp) {
508 pScoringInput = inp->takeInputItem(
"planar scoring");
509 if (! pScoringInput) {
510 egsFatal(
"AO type %s: Missing planar scoring input?\n",
otype.c_str());
515 EGS_FluenceScoring::initScoring(inp);
518 score_in_all_regions =
true;
519 EGS_FluenceScoring::getSensitiveRegions(pScoringInput);
522 vector<EGS_Float> tmp_field;
523 int err2 = pScoringInput->
getInput(
"scoring circle",tmp_field);
525 int err3 = pScoringInput->
getInput(
"scoring rectangle",tmp_field);
526 if (err3 || tmp_field.size() != 4) {
528 "\n\n*** Wrong/missing 'scoring rectangle' input "
529 "setting it to 10 cm X 10 cm field at origin!\n\n");
533 field_type = rectangle;
537 EGS_Float xmin = tmp_field[0],xmax = tmp_field[1],
538 ymin = tmp_field[2],ymax = tmp_field[3];
540 m_midpoint =
EGS_Vector((xmax+xmin)/2.,(ymax+ymin)/2.,0);
558 int err4 = pScoringInput->
getInput(
"resolution",screen);
563 "\n\n*** Missing/wrong 'resolution' input "
564 " Scoring in the whole field\n\n");
567 else if (screen.size()==1) {
571 else if (screen.size()==2) {
575 else if (screen.size()> 2) {
579 "\n\n*** Too many 'resolution' inputs\n"
580 " Using first two entries\n\n");
588 field_type = rectangle;
592 else if (tmp_field.size() != 4) {
594 "\n\n*** Wrong/missing 'scoring circle' input "
595 "setting it to 10 cm diameter field at origin!\n\n");
603 vector<EGS_Float> tmp_normal;
604 int err1 = pScoringInput->
getInput(
"scoring plane normal",tmp_normal);
605 if (err1 || tmp_normal.size() != 3) {
607 "\n\n*** Wrong/missing 'scoring plane normal' input. "
608 "Set along positive z-axis\n\n");
612 m_normal =
EGS_Vector(tmp_normal[0],tmp_normal[1],
614 m_normal.normalize();
616 m_midpoint =
EGS_Vector(tmp_field[0],tmp_field[1],
619 m_R2 = tmp_field[3]*tmp_field[3];
624 m_d = m_normal*m_midpoint;
629 sprintf(buf,
"\nPlanar %s fluence scoring\n",particle_name.c_str());
631 description +=
"================================\n";
634 sprintf(buf,
"(%g %g %g)\n",m_normal.
x,m_normal.
y,m_normal.
z);
637 sprintf(buf,
"(%g %g %g)\n",m_midpoint.
x,m_midpoint.
y,m_midpoint.
z);
639 if (field_type == circle) {
641 sprintf(buf,
"%g cm\n",m_R);
644 else if (field_type == rectangle) {
646 sprintf(buf,
"%g cm X %g cm\n",ax,ay);
649 sprintf(buf,
"%d X %d\n",Nx,Ny);
652 description +=
" - scoring field distance from origin = ";
653 sprintf(buf,
"%g cm\n",m_d);
658 EGS_FluenceScoring::describeMe();
662 void EGS_PlanarFluence::score(
const EGS_Particle &p,
const int &ivoxel) {
663 EGS_Float up = p.
u*m_normal, aup = fabs(up);
670 EGS_Float e = p.
q ? p.
E -
app->getRM() : p.
E;
676 EGS_Float auxp = p.
wt/aup;
678 fluT->
score(ivoxel,auxp);
679 if (score_primaries && !p.
latch) {
680 fluT_p->
score(ivoxel,auxp);
683 if (score_spe && e > flu_xmin && e <= flu_xmax) {
684 ae = flu_a*e + flu_b;
691 je = min((
int)ae,flu_nbin-1);
693 if (ivoxel < 0 || ivoxel > Nx*Ny) {
694 egsFatal(
"\n-> Scoring out of bounds, ivoxel = %d\n",ivoxel);
697 if (je < 0 || je >= flu_nbin) {
698 egsFatal(
"\n-> Scoring out of bounds, ibin = %d ae = %g E = %g MeV\n",je,ae,e);
701 if (score_primaries && !p.
latch) {
702 flu_p[ivoxel]->
score(je,auxp);
707 int EGS_PlanarFluence::hitsField(
const EGS_Particle &p, EGS_Float *dist) {
708 if (field_type==circle) {
709 EGS_Float xp = p.
x*m_normal, up = p.
u*m_normal;
710 if ((up > 0 && m_d > xp) ||
711 (up < 0 && m_d < xp)) {
712 EGS_Float t = (m_d - xp)/up;
717 return x1.length2() < m_R*m_R ? 0:-1;
721 else if (field_type == rectangle) {
722 EGS_Float xp = p.
x*m_normal, up = p.
u*m_normal;
723 if ((up > 0 && m_d > xp) || (up < 0 && m_d < xp)) {
724 EGS_Float t = (m_d - xp)/up;
726 EGS_Float xcomp = x1*ux;
727 EGS_Float ycomp = x1*uy;
728 xcomp = 2*xcomp + ax;
729 ycomp = 2*ycomp + ay;
730 if (xcomp > 0 && xcomp < 2*ax &&
731 ycomp > 0 && ycomp < 2*ay) {
732 int i = int(xcomp/(2*vx)),
733 j = int(ycomp/(2*vy)),
748 void EGS_PlanarFluence::ouputPlanarFluence(
EGS_ScoringArray *fT,
const double &norma) {
751 int ix_digits = getDigits(Nx);
752 int iy_digits = getDigits(Ny);
753 int xy_digits = getDigits(Nx*Ny);
755 if (field_type == circle) {
757 "-----------------------------------------------------\n");
761 "-----------------------------------------------------\n",
762 iy_digits,
"iy",ix_digits,
"ix",&count);
764 if (field_type == circle) {
774 egsInformation(
" %10.4le +/- %10.4le [%-7.3lf\%]\n",fe*norma,dfe*norma,dfer);
777 for (
int j=0; j<Ny; j++) {
778 for (
int i=0; i<Nx; i++) {
780 egsInformation(
" %*d %*d %*d ",iy_digits,j,ix_digits,i,xy_digits,k);
788 egsInformation(
" %10.4le +/- %10.4le [%-7.3lf\%]\n",fe*norma,dfe*norma,dfer);
794 void EGS_PlanarFluence::ouputResults() {
796 EGS_Float src_norm = 1.0,
797 Fsrc =
app->getFluence();
798 egsInformation(
"\n\n last case = %lld source particles or fluence = %g\n\n",
799 current_ncase, Fsrc);
802 src_norm = Fsrc/current_ncase;
805 string normLabel = src_norm == 1 ?
"history" :
"MeV-1 cm-2";
806 string src_type =
app->sourceType();
807 if (src_type ==
"EGS_BeamSource") {
808 normLabel =
"primary history";
809 egsInformation(
"\n\n %s normalization = %g (primary histories per particle)\n\n",
810 src_type.c_str(), src_norm);
812 else if (src_type ==
"EGS_CollimatedSource" ||
813 (src_type ==
"EGS_ParallelBeam" && src_norm != 1)) {
814 egsInformation(
"\n\n %s normalization = %g (fluence per particle)\n\n",
815 src_type.c_str(), src_norm);
818 egsInformation(
"\n\n %s normalization = %g (histories per particle)\n\n",
819 src_type.c_str(), src_norm);
824 double norm = 1.0/src_norm;
831 " ================\n\n");
834 ouputPlanarFluence(fluT, norm);
836 if (score_primaries) {
838 ouputPlanarFluence(fluT_p, norm);
843 string suffix =
"_" + particle_name +
".agr";
845 ofstream spe_output(spe_name.c_str(),ios::out);
847 egsFatal(
"\n EGS_PlanarFluence: Error: Failed to open file %s\n",spe_name.c_str());
851 spe_output <<
"# " << particle_name.c_str() <<
" fluence \n";
852 spe_output <<
"# \n";
853 spe_output <<
"@ legend 0.2, 0.8\n";
854 spe_output <<
"@ legend box linestyle 0\n";
855 spe_output <<
"@ legend font 4\n";
856 spe_output <<
"@ xaxis label \"energy / MeV\"\n";
857 spe_output <<
"@ xaxis label char size 1.560000\n";
858 spe_output <<
"@ xaxis label font 4\n";
859 spe_output <<
"@ xaxis ticklabel font 4\n";
860 spe_output <<
"@ yaxis label \"fluence / MeV\\S-1\\Ncm\\S-2\"\n";
861 spe_output <<
"@ yaxis label char size 1.560000\n";
862 spe_output <<
"@ yaxis label font 4\n";
863 spe_output <<
"@ yaxis ticklabel font 4\n";
864 spe_output <<
"@ title \""<< particle_name.c_str() <<
" fluence" <<
"\"\n";
865 spe_output <<
"@ title font 4\n";
866 spe_output <<
"@ title size 1.500000\n";
867 spe_output <<
"@ subtitle \"for each scoring region\"\n";
868 spe_output <<
"@ subtitle font 4\n";
869 spe_output <<
"@ subtitle size 1.000000\n";
872 " ====================\n\n");
876 for (
int j=0; j<Ny; j++) {
877 for (
int i=0; i<Nx; i++) {
882 spe_output<<
"@ s" << i_graph <<
" errorbar linestyle 0\n";
883 spe_output<<
"@ s" << i_graph <<
" legend \""<<
884 "Voxel # " << k <<
"\"\n";
885 spe_output<<
"@target G0.S"<< i_graph <<
"\n";
886 spe_output<<
"@type xydy\n";
890 "---------------------------------------------\n");
892 for (
int l=0; l<flu_nbin; l++) {
894 EGS_Float e = (l+0.5-flu_b)/flu_a;
898 spe_output<<e<<
" "<<fe *norm<<
" "<<dfe *norm<<
"\n";
904 if (score_primaries) {
908 "---------------------------------------------\n");
910 spe_output<<
"@ s" << ++i_graph <<
" errorbar linestyle 0\n";
911 spe_output<<
"@ s" << i_graph <<
" legend \""<<
912 "Voxel # " << k <<
" (primary)\"\n";
913 spe_output<<
"@target G0.S"<< i_graph <<
"\n";
914 spe_output<<
"@type xydy\n";
915 for (
int l=0; l<flu_nbin; l++) {
917 EGS_Float e = (l+0.5-flu_b)/flu_a;
921 spe_output<<e<<
" "<<fe *norm<<
" "<<dfe *norm<<
"\n";
935 void EGS_PlanarFluence::reportResults() {
938 egsInformation(
"======================================================\n");
939 egsInformation(
" Total %ss reaching field: %g\n",particle_name.c_str(),m_tot);
940 egsInformation(
" Primary %ss reaching field: %g\n",particle_name.c_str(),m_primary);
942 egsInformation(
"======================================================\n");
948 bool EGS_PlanarFluence::storeState(ostream &data)
const {
954 data << m_tot <<
" " << m_primary;
965 for (
int j=0; j<Nx*Ny; j++) {
966 if (!flu[j]->storeState(data)) {
972 if (score_primaries) {
977 for (
int j=0; j<Nx*Ny; j++) {
978 if (!flu_p[j]->storeState(data)) {
988 bool EGS_PlanarFluence::setState(istream &data) {
993 data >> m_tot >> m_primary;
1003 for (
int j=0; j<Nx*Ny; j++) {
1004 if (!flu[j]->setState(data)) {
1010 if (score_primaries) {
1017 for (
int j=0; j<Nx*Ny; j++) {
1018 if (!flu_p[j]->setState(data)) {
1028 bool EGS_PlanarFluence::addState(istream &data) {
1033 current_ncase += tmp_case;
1037 EGS_Float tmp_tot, tmp_primary;
1038 data >> tmp_tot >> tmp_primary;
1042 m_primary += tmp_primary;
1049 if (!tgT.setState(data)) {
1056 for (
int j=0; j<Nx*Ny; j++) {
1057 if (!tg.setState(data)) {
1064 if (score_primaries) {
1067 if (!tgT_p.setState(data)) {
1074 for (
int j=0; j<Nx*Ny; j++) {
1075 if (!tg_p.setState(data)) {
1078 (*flu_p[j]) += tg_p;
1095 ,one_bin(0), multi_bin(0), max_step(-100.0), n_step_bins(10000)
1098 otype =
"EGS_VolumetricFluence";
1105 for (
int j=0; j<n_scoring_regions; j++) {
1110 for (
int j=0; j<n_scoring_regions; j++) {
1119 if (scoring_charge) {
1141 if (source_charge == unknown) {
1146 nreg =
app->getnRegions();
1149 for (
int j=0; j<nreg; j++) {
1150 is_sensitive.push_back(
false);
1151 is_source.push_back(
false);
1152 volume.push_back(vol_list[0]);
1159 for (
int i = 0; i < n_scoring_regions; i++) {
1160 if (i < vol_list.size()) {
1161 volume[f_region[i]] = vol_list[i];
1169 for (
int j = 0; j < nreg; j++) {
1170 if (is_sensitive[j]) {
1175 if (score_primaries) {
1179 for (
int j = 0; j < nreg; j++) {
1180 if (is_sensitive[j]) {
1191 EGS_Float flu_Emin = flu_s ? exp(flu_xmin) : flu_xmin,
1192 flu_Emax = flu_s ? exp(flu_xmax) : flu_xmax;
1193 EGS_Float bw = flu_s ?(log(flu_Emax / flu_Emin))/flu_nbin :
1194 (flu_Emax - flu_Emin) /flu_nbin;
1199 if (scoring_charge) {
1204 r_const = 1/(expbw-1);
1205 DE =
new EGS_Float [flu_nbin];
1206 a_const =
new EGS_Float [flu_nbin];
1207 for (
int i = 0; i < flu_nbin; i++) {
1208 DE[i] = flu_Emin*pow(expbw,i)*(expbw-1);
1209 a_const[i] = 1/flu_Emin*pow(1/expbw,i);
1213 if (flu_Emin < app->getEcut() -
app->getRM()) {
1214 flu_Emin =
app->getEcut() -
app->getRM() ;
1217 ceil((log(flu_Emax / flu_Emin))/bw) :
1218 ceil((flu_Emax - flu_Emin) /bw);
1224 int n_media =
app->getnMedia();
1226 EGS_Float lnE, lnEmin, lnEmax, lnEmid;
1230 for (
int j = 0; j < n_media; j++) {
1232 i_dedx[j] = *(
app->getDEDX(j, scoring_charge));
1233 EGS_Float Emin = i_dedx[j].
getXmin();
1234 EGS_Float Emax = i_dedx[j].
getXmax();
1235 int n = 1 + i_dedx[j].
getIndex(Emax);
1236 EGS_Float bwidth = (Emax - Emin)/n;
1238 egsInformation(
"---> stpwr in %s : Emin=%g Emax=%g n=%d bw=%g\n",
1239 app->getMediumName(j), exp(Emin), exp(Emax), n, bwidth);
1242 EGS_Float spwr_i[nbins];
1243 for (
int k = 0; k < nbins; k++) {
1244 spwr_i[k] = 1.0 / i_dedx[j].
interpolate(Emin+k*bwidth);
1246 dedx_i[j].
initialize(nbins, Emin, Emax, spwr_i);
1251 bwidth = (Emax - Emin)/n;
1252 egsInformation(
"---> 1/stpwr in %s : lnEmin=%g lnEmax=%g n=%d bw=%g index(Emax)=%d\n",
1253 app->getMediumName(j), Emin, Emax, n, bwidth, dedx_i[j].getIndexFast(Emax));
1254 for (
int k = 0; k < nbins; k++) {
1257 i_dedx[j].interpolate(Emin + k*bwidth),
1258 dedx_i[j].interpolate(Emin + k*bwidth));
1264 lnEmin = flu_s ? log(0.5*flu_Emin*(expbw+1)) : 0;
1265 Lmid_i =
new EGS_Float [flu_nbin*n_media];
1266 for (
int j = 0; j < n_media; j++) {
1268 EGS_Float med_max_step = 0, logEmax, logEmin;
1270 for (
int i = 0; i < flu_nbin; i++) {
1271 lnEmid = flu_s ? lnEmin + i*bw : log(flu_Emin+bw*(i+0.5));
1272 Lmid_i[i+j*flu_nbin] = 1/i_dedx[j].
interpolate(lnEmid);
1277 logEmin = flu_s ? lnEmin + (i-1)*bw : log(flu_Emin+bw*(i-1));
1278 logEmax = flu_s ? lnEmin + i*bw : log(flu_Emin+bw*i);
1279 if (i_dedx[j].interpolate(logEmax) < i_dedx[j].interpolate(logEmin)) {
1280 med_max_step += 1.02*(exp(logEmax) - exp(logEmin))/i_dedx[j].interpolate(logEmax);
1283 med_max_step += 1.02*(exp(logEmax) - exp(logEmin))*i_dedx[j].interpolate(logEmin);
1289 if (med_max_step > max_step) {
1290 max_step = med_max_step;
1299 EGS_Float RCSDA = max_step;
1303 step_a = n_step_bins/max_step;
1308 egsInformation(
"\n===> RCSDA(%s) = %g cm for Emax = %g MeV, max_step = %g cm bin width = %g cm\n",
1309 app->getMediumName(imed_max_range), RCSDA,
1310 flu_s ? exp(flu_Emax) : flu_Emax, max_step, 1.0/step_a);
1319 void EGS_VolumetricFluence::initScoring(
EGS_Input *inp) {
1328 vScoringInput = inp->takeInputItem(
"volumetric scoring");
1329 if (! vScoringInput) {
1330 egsFatal(
"AO type %s: Missing volumetric scoring input?\n",
otype.c_str());
1335 EGS_FluenceScoring::initScoring(inp);
1338 score_in_all_regions =
false;
1339 EGS_FluenceScoring::getSensitiveRegions(vScoringInput);
1342 vector <EGS_Float> v_in;
1343 vScoringInput->
getInput(
"volumes",v_in);
1351 if (! score_in_all_regions && v_in.size() == f_start.size()) {
1353 for (
int i=0; i<f_start.size(); i++) {
1354 int i_r = f_start[i], f_r = f_stop[i];
1355 for (
int ireg=i_r; ireg<=f_r; ireg++) {
1356 vol_list.push_back(v_in[i]);
1360 else if (v_in.size()) {
1364 vol_list.push_back(1.0);
1368 if (scoring_charge) {
1369 vector<string> method;
1370 method.push_back(
"flurz");
1371 method.push_back(
"stpwr");
1372 method.push_back(
"stpwrO5");
1381 sprintf(buf,
"\nVolumetric %s fluence scoring\n",particle_name.c_str());
1383 description +=
"===================================\n";
1387 EGS_FluenceScoring::describeMe();
1389 if (scoring_charge) {
1391 if (flu_stpwr == stpwr) {
1392 description +=
" O(eps^3) approach: accounts for change in stpwr\n";
1393 description +=
" along the step with eps=edep/Emid\n";
1395 else if (flu_stpwr == stpwrO5) {
1396 description +=
" O(eps^5) approach: accounts for change in stpwr\n";
1397 description +=
" along the step with eps=edep/Emid\n";
1401 description +=
" Fluence calculated a-la-FLURZ using Lave=EDEP/TVSTEP.\n";
1405 if (norm_u != 1.0) {
1406 description +=
"\n - Non-unity user-requested normalization = ";
1407 sprintf(buf,
"%g\n",norm_u);
1413 void EGS_VolumetricFluence::ouputVolumetricFluence(
EGS_ScoringArray *fT,
const double &norma) {
1416 int ir_digits = getDigits(nreg);
1421 "-----------------------------------------------------\n");
1422 for (
int k=0; k<nreg; k++) {
1423 if (!is_sensitive[k]) {
1426 double norm = norma/volume[k];
1436 egsInformation(
" %10.4le +/- %10.4le [%-7.3lf%]\n",fe*norm,dfe*norm,dfer);
1440 void EGS_VolumetricFluence::ouputResults() {
1443 EGS_Float src_norm = 1.0,
1444 Fsrc =
app->getFluence();
1445 egsInformation(
"\n\n last case = %lld source particles or fluence = %g\n\n",
1446 current_ncase, Fsrc);
1449 src_norm = Fsrc/current_ncase;
1452 string normLabel = src_norm == 1 ?
"history" :
"MeV-1 cm-2";
1453 string src_type =
app->sourceType();
1454 if (src_type ==
"EGS_BeamSource") {
1455 normLabel =
"primary history";
1456 egsInformation(
"\n\n %s normalization = %g (primary histories per particle)\n\n",
1457 src_type.c_str(), src_norm);
1459 else if (src_type ==
"EGS_CollimatedSource" ||
1460 (src_type ==
"EGS_ParallelBeam" && src_norm != 1)) {
1461 egsInformation(
"\n\n %s normalization = %g (fluence per particle)\n\n",
1462 src_type.c_str(), src_norm);
1465 egsInformation(
"\n\n %s normalization = %g (histories per particle)\n\n",
1466 src_type.c_str(), src_norm);
1470 EGS_Float fbins, d_fbins;
1472 "--------------------------------------\n");
1474 int tot_bins = one_bin + multi_bin;
1475 egsInformation(
"\none_bin = %d [%-7.3lf\%] multi_bin = %d [%-7.3lf\%]\n",
1476 one_bin, 100.0*one_bin/tot_bins, multi_bin,100.0*multi_bin/tot_bins);
1479 int bdigits = getDigits(flu_nbin);
1480 for (
int i=0; i<flu_nbin; i++) {
1481 binDist->currentResult(i,fbins, d_fbins);
1483 d_fbins = 100.0*d_fbins/fbins;
1484 fbins = current_ncase*fbins;
1486 bdigits, i+1, fbins, d_fbins, 100.*fbins/tot_bins);
1490 if (scoring_charge) {
1491 egsInformation(
"\nDistribution of ratio between computed and taken steps\n"
1492 "------------------------------------------------------\n"
1493 " (Omitted bins with differences less than 0.01\%)\n");
1499 EGS_Float step_diff, step_diff_std, step_diff_err, stepMid;
1500 EGS_Float f_scores, f_scores_std;
1501 int idigits = getDigits(eCases);
1503 "---------------------------------------------------------\n");
1504 for (
int i=0; i < n_step_bins; i++) {
1505 stepDist->currentResult(i, f_scores, f_scores_std);
1507 stepMid = (i + 0.5 - step_b)/step_a;
1508 relStepDiff->currentResult(i, step_diff, step_diff_std);
1509 if (step_diff > 0) {
1510 step_diff_err = 100*step_diff_std/step_diff;
1513 step_diff_err = 100;
1515 if (abs(step_diff/f_scores - 1.0) > 0.0001D+0)
1517 stepMid, idigits,
int(f_scores*current_ncase), step_diff/f_scores, step_diff_err);
1525 EGS_Float norm = 1.0/src_norm;
1529 " =======================\n\n");
1531 egsInformation(
"\n\n Total %s fluence\n", particle_name.c_str());
1532 ouputVolumetricFluence(fluT, norm);
1534 if (score_primaries) {
1536 ouputVolumetricFluence(fluT_p, norm);
1544 string suffix =
"_" + particle_name +
".agr";
1546 ofstream spe_output(spe_name.c_str(),ios::out);
1548 egsFatal(
"\n EGS_VolumetricFluence: Error: Failed to open file %s\n",spe_name.c_str());
1552 spe_output <<
"# Volumetric " << particle_name.c_str() <<
" fluence \n";
1553 spe_output <<
"# \n";
1554 spe_output <<
"@ legend 0.2, 0.8\n";
1555 spe_output <<
"@ legend box linestyle 0\n";
1556 spe_output <<
"@ legend font 4\n";
1557 spe_output <<
"@ xaxis label \"energy / MeV\"\n";
1558 spe_output <<
"@ xaxis label char size 1.560000\n";
1559 spe_output <<
"@ xaxis label font 4\n";
1560 spe_output <<
"@ xaxis ticklabel font 4\n";
1561 if (src_norm == 1 || normLabel ==
"primary history") {
1562 spe_output <<
"@ yaxis label \"fluence / MeV\\S-1\\Ncm\\S-2\"\n";
1565 spe_output <<
"@ yaxis label \"fluence / MeV\\S-1\"\n";
1567 spe_output <<
"@ yaxis label char size 1.560000\n";
1568 spe_output <<
"@ yaxis label font 4\n";
1569 spe_output <<
"@ yaxis ticklabel font 4\n";
1570 spe_output <<
"@ title \""<< particle_name.c_str() <<
" fluence" <<
"\"\n";
1571 spe_output <<
"@ title font 4\n";
1572 spe_output <<
"@ title size 1.500000\n";
1573 spe_output <<
"@ subtitle \"for each scoring region\"\n";
1574 spe_output <<
"@ subtitle font 4\n";
1575 spe_output <<
"@ subtitle size 1.000000\n";
1579 " =============================\n\n");
1582 norm *= scoring_charge ? 1 : flu_a;
1584 for (
int j = 0; j < nreg; j++) {
1586 if (!is_sensitive[j]) {
1590 double norma = norm/volume[j];
1605 spe_output<<
"@ s"<< i_graph <<
" errorbar linestyle 0\n";
1606 spe_output<<
"@ s"<< i_graph <<
" legend \""<<
"total (ir # " << j <<
")\"\n";
1607 spe_output<<
"@target G0.S"<< i_graph <<
"\n";
1608 spe_output<<
"@type xydy\n";
1609 if (verbose)
egsInformation(
"\n Emid/MeV Flu/(MeV-1*cm-2) DFlu/(MeV-1*cm-2)\n"
1610 "---------------------------------------------------\n");
1611 for (
int i=0; i<flu_nbin; i++) {
1613 EGS_Float e = (i+0.5-flu_b)/flu_a;
1617 spe_output << e <<
" "<< fe *norma <<
" "<< dfe *norma <<
"\n";
1619 e, fe*norma, dfe*norma);
1621 spe_output <<
"&\n";
1623 if (score_primaries) {
1627 spe_output<<
"@ s"<< ++i_graph <<
" errorbar linestyle 0\n";
1628 spe_output<<
"@ s"<< i_graph <<
" legend \""<<
"primary (ir # " << j <<
")\"\n";
1629 spe_output<<
"@target G0.S"<< i_graph <<
"\n";
1630 spe_output<<
"@type xydy\n";
1631 if (verbose)
egsInformation(
"\n Emid/MeV Flu/(MeV-1*cm-2) DFlu/(MeV-1*cm-2)\n"
1632 "---------------------------------------------------\n");
1633 for (
int i=0; i<flu_nbin; i++) {
1635 EGS_Float e = (i+0.5-flu_b)/flu_a;
1639 spe_output << e <<
" "<< fe *norma <<
" "<< dfe *norma <<
"\n";
1641 e, fe*norma, dfe*norma);
1643 spe_output <<
"&\n";
1654 void EGS_VolumetricFluence::reportResults() {
1657 egsInformation(
"======================================================\n");
1663 bool EGS_VolumetricFluence::storeState(ostream &data)
const {
1674 if (scoring_charge) {
1675 if (!relStepDiff->storeState(data)) {
1678 if (!stepDist->storeState(data)) {
1688 for (
int j = 0; j < nreg; j++) {
1689 if (is_sensitive[j]) {
1690 if (!flu[j]->storeState(data)) {
1697 if (score_primaries) {
1702 for (
int j=0; j < nreg; j++) {
1703 if (is_sensitive[j]) {
1704 if (!flu_p[j]->storeState(data)) {
1715 bool EGS_VolumetricFluence::setState(istream &data) {
1726 if (scoring_charge) {
1727 if (!relStepDiff->setState(data)) {
1730 if (!stepDist->setState(data)) {
1740 for (
int j=0; j<nreg; j++) {
1741 if (is_sensitive[j]) {
1742 if (!flu[j]->setState(data)) {
1749 if (score_primaries) {
1754 for (
int j=0; j < nreg; j++) {
1755 if (is_sensitive[j]) {
1756 if (!flu_p[j]->setState(data)) {
1767 bool EGS_VolumetricFluence::addState(istream &data) {
1772 current_ncase += tmp_case;
1779 if (scoring_charge) {
1781 if (!tmpRelStepDiff.setState(data)) {
1784 (*relStepDiff) += tmpRelStepDiff;
1790 if (!tgT.setState(data)) {
1797 for (
int j = 0; j < nreg; j++) {
1798 if (is_sensitive[j]) {
1799 if (!tg.setState(data)) {
1807 if (score_primaries) {
1809 if (!tgT_p.setState(data)) {
1815 for (
int j=0; j < nreg; j++) {
1816 if (is_sensitive[j]) {
1817 if (!tg_p.setState(data)) {
1820 (*flu_p[j]) += tg_p;
1831 static void setInputs() {
1834 setBaseAusgabObjectInputs();
1836 ausBlockInput->getSingleInput(
"library")->setValues({
"egs_fluence_scoring"});
1839 auto typePtr = ausBlockInput->addSingleInput(
"type",
true,
"Whether to score volumetric or planar fluence", {
"planar",
"volumetric"});
1840 ausBlockInput->addSingleInput(
"scoring particle",
true,
"Which type of particle we are scoring the fluence for", {
"photon",
"electron",
"positron"});
1841 ausBlockInput->addSingleInput(
"source particle",
false,
"Optional, only required to score primary fluence. Defaults to source particles if all the same, or if mixed, defaults to scoring particle.", {
"photon",
"electron",
"positron"});
1842 ausBlockInput->addSingleInput(
"score primaries",
false,
"Whether to score primary fluence as well as differential fluence. Defaults to no.", {
"no",
"yes"});
1843 auto specPtr = ausBlockInput->addSingleInput(
"score spectrum",
false,
"Whether to score a spectrum. If so, add an 'energy grid' input block. Defaults to no.", {
"no",
"yes"});
1844 ausBlockInput->addSingleInput(
"verbose",
false,
"Print extra information about the fluence scoring. Defaults to no.", {
"no",
"yes"});
1845 ausBlockInput->addSingleInput(
"normalization",
false,
"Perform a multiplicative normalization to the results. Defaults to 1.");
1847 auto blockPtr = ausBlockInput->addBlockInput(
"energy grid");
1848 blockPtr->addDependency(specPtr,
"yes");
1849 blockPtr->addSingleInput(
"number of bins",
true,
"The number of energy bins in the spectrum");
1850 blockPtr->addSingleInput(
"minimum kinetic energy",
true,
"The minimum energy to score in the spectrum");
1851 blockPtr->addSingleInput(
"maximum kinetic energy",
true,
"The maximum energy to score in the spectrum");
1852 blockPtr->addSingleInput(
"scale",
false,
"Whether to score on a linear or logarithmic scale. Default is linear.", {
"linear",
"logarithmic"});
1854 blockPtr = ausBlockInput->addBlockInput(
"volumetric scoring");
1855 blockPtr->addDependency(typePtr,
"volumetric");
1856 auto regionPtr = blockPtr->addSingleInput(
"scoring regions",
false,
"A list of regions to score fluence in");
1857 auto startPtr = blockPtr->addSingleInput(
"start region",
false,
"For a series of region ranges, list the 'starting region' for each range here (inclusive)");
1858 auto stopPtr = blockPtr->addSingleInput(
"stop region",
false,
"For a series of region ranges, list the 'ending region' for each range here (inclusive)");
1859 blockPtr->addSingleInput(
"volumes",
false,
"Either a single volume, which will be the same for all regions or a list of individual volumes for each region or region group. Default is 1 cm^3");
1860 blockPtr->addSingleInput(
"method",
false,
"The algorithm to use for charged particle scoring (ignored for photon scoring). See documentation for full explanation. Defaults to 'stpwr'.", {
"flurz",
"stpwr",
"stpwrO5"});
1862 regionPtr->addDependency(startPtr,
"",
true);
1863 regionPtr->addDependency(stopPtr,
"",
true);
1864 startPtr->addDependency(regionPtr,
"",
true);
1865 stopPtr->addDependency(regionPtr,
"",
true);
1867 blockPtr = ausBlockInput->addBlockInput(
"planar scoring");
1868 blockPtr->addDependency(typePtr,
"planar");
1869 regionPtr = blockPtr->addSingleInput(
"contributing regions",
false,
"A list of regions to score fluence in");
1870 startPtr = blockPtr->addSingleInput(
"start contributing region",
false,
"For a series of region ranges, list the 'starting region' for each range here (inclusive)");
1871 stopPtr = blockPtr->addSingleInput(
"stop contributing region",
false,
"For a series of region ranges, list the 'ending region' for each range here (inclusive)");
1872 auto circlePtr = blockPtr->addSingleInput(
"scoring circle",
false,
"The center point and radius of the circle: x y z R");
1873 auto circleNormPtr = blockPtr->addSingleInput(
"scoring plane normal",
false,
"The unit vector for the normal of the scoring circle: ux uy uz");
1874 auto rectPtr = blockPtr->addSingleInput(
"scoring rectangle",
false,
"The x and y ranges for the rectangle edges, initially defined in the x-y plane. Use a transformation input block to rotate. Format is: xmin xmax ymin ymax");
1876 regionPtr->addDependency(startPtr,
"",
true);
1877 regionPtr->addDependency(stopPtr,
"",
true);
1878 startPtr->addDependency(regionPtr,
"",
true);
1879 stopPtr->addDependency(regionPtr,
"",
true);
1881 circlePtr->addDependency(rectPtr,
"",
true);
1882 circleNormPtr->addDependency(rectPtr,
"",
true);
1883 rectPtr->addDependency(circlePtr,
"",
true);
1885 addTransformationBlock(blockPtr);
1888 EGS_FLUENCE_SCORING_EXPORT
string getExample() {
1892 # Example of egs_fluence_scoring for planar fluence
1893 #:start ausgab object:
1894 name = id-string # Arbitrary identifying string
1895 library = egs_fluence_scoring # Library name
1896 type = planar # Score on circular or square field
1897 scoring particle = photon, or electron, or positron
1898 source particle = photon, or electron, or positron
1899 # Optional. Only required to score primary fluence.
1900 # Defaults to source particles if all the same.
1901 # In the case of multiple particles,
1902 # defaults to scoring particle. Useful for
1903 # bremsstrahlung targets and radioactive sources.
1904 score primaries = yes or no # Defaults to `no`.
1905 score spectrum = yes or no # Defaults to `no`.
1906 verbose = yes or no # Defaults to `no`.
1907 normalization = norm # User-requested normalization. Defaults to 1.
1909 # If scoring spectrum, define energy grid
1910 # Default: 128 linear energy bins between 1 keV and 1 MeV
1913 number of bins = nbins
1914 minimum kinetic energy = Emin
1915 maximum kinetic energy = Emax
1916 scale = linear or logarithmic # Defaults to `linear`.
1919 # Define scoring based on type
1921 :start planar scoring:
1922 # Define contributing regions
1923 contributing regions = ir1 ir2 ... irn
1925 # start contributing region = iri_1, iri_2, ..., iri_n
1926 # stop contributing region = irf_1, irf_2, ..., irf_n
1928 ################################
1929 # If a circular field desired:
1930 ################################
1931 scoring circle = x y z R
1932 scoring plane normal = ux uy uz
1933 ########################################################
1934 # If a rectangular field desired:
1936 #scoring rectangle = xmin xmax ymin ymax
1938 # See documentation for EGS_AffineTransform
1940 #:start transformation:
1941 # rotation = 2, 3 or 9 floating point numbers
1942 # translation = tx, ty, tz
1943 #:stop transformation:
1944 ##########################################################
1945 :stop planar scoring:
1946 :stop ausgab object:
1948 # Example of egs_fluence_scoring for volumetric fluence
1949 #:start ausgab object:
1950 name = id-string # Arbitrary identifying string
1951 library = egs_fluence_scoring # Library name
1952 type = volumetric # Score in a volume
1953 scoring particle = photon, or electron, or positron
1954 source particle = photon, or electron, or positron
1955 # Optional. Only required to score primary fluence.
1956 # Defaults to source particles if all the same.
1957 # In the case of multiple particles,
1958 # defaults to scoring particle. Useful for
1959 # bremsstrahlung targets and radioactive sources.
1960 score primaries = yes or no # Defaults to `no`.
1961 score spectrum = yes or no # Defaults to `no`.
1962 verbose = yes or no # Defaults to `no`.
1963 normalization = norm # User-requested normalization. Defaults to 1.
1964 # If scoring spectrum, define energy grid
1965 # Default: 128 linear energy bins between 1 keV and 1 MeV
1967 number of bins = nbins
1968 minimum kinetic energy = Emin
1969 maximum kinetic energy = Emax
1970 scale = linear or logarithmic # Defaults to `linear`.
1972 :start volumetric scoring:
1973 scoring regions = ir1 ir2 ... irn
1975 #start region = iri_1, iri_2, ..., iri_n
1976 #stop region = irf_1, irf_2, ..., irf_n
1978 volumes = V1, V2, ..., VN # Enter as many as scoring regions. If same number
1979 # of entries as group of regions, assumes groups of
1980 # equal volume regions. If only one entry, assumes
1981 # equal volumes in all regions. Defaults to 1.
1982 method = flurz or stpwr or stpwrO5 # For charged particle scoring.
1984 # flurz => FLURZnrc algorithm
1986 # Path length at each energy interval from energy
1987 # deposited EDEP and total particle step TVSTEP.
1988 # Assumes stopping power constancy along the particle's
1989 # step. It might introduce artifacts if ESTEPE or the
1990 # scoring bin width are too large.
1992 # stpwr => Accounts for stopping power variation
1993 # along the particle's step. More accurate
1994 # than method used in FLURZnrc albeit about
1995 # about 10% slower in electron beam cases.
1997 # Uses an O(3) series expansion of the integral of the
1998 # inverse of the stopping power with respect to energy.
1999 # Stopping power is represented as a linear interpolation
2000 # over a log energy grid.
2002 # stpwrO5 => Uses an O(5) series expansion. Slightly slower.
2004 # Defaults to `stpwr`.
2005 :stop volumetric scoring:
2006 :stop ausgab object:
2011 EGS_FLUENCE_SCORING_EXPORT shared_ptr<EGS_BlockInput> getInputs() {
2015 return ausBlockInput;
2020 const static char *func =
"createAusgabObject(fluence_scoring)";
2027 int error = input->
getInput(
"type",type);
2028 if (!error && input->
compare(
"planar",type)) {
2031 result->initScoring(input);
2034 else if (!error && input->
compare(
"volumetric",type)) {
2037 result->initScoring(input);
2041 egsFatal(
"Invalid fluence type input?\n\n\n");
Base class for advanced EGSnrc C++ applications.
void getLabelRegions(const string &str, vector< int > ®s)
Gets the regions for the labels in str and pushes onto regs.
void getNumberRegions(const string &str, vector< int > ®s)
Gets numbers out of str and pushes them onto regs.
string constructIOFileName(const char *extension, bool with_run_dir) const
Constructs and returns the name of an input/output file.
virtual void setApplication(EGS_Application *App)
Set the application this object belongs to.
string description
A short ausgab object description.
EGS_Application * app
The application this object belongs to.
Base class for fluence scoring.
EGS_FluenceScoring(const string &Name="", EGS_ObjectFactory *f=0)
A class for fast run-time interpolations.
int getIndex(EGS_Float x) const
Get the interpolation index corresponding to x.
void initialize(int nbin, EGS_Float Xmin, EGS_Float Xmax, const EGS_Float *values)
Initialize the interpolator.
EGS_Float interpolate(EGS_Float x) const
Interpolate the function value at x.
EGS_Float getXmax() const
Get the upper interpolation interval limit.
EGS_Float getXmin() const
Get the lower interpolation interval limit.
void setName(EGS_Input *inp)
Set the name of the object from the information provided by inp.
string otype
The object type.
string name
The object name.
Ausgab object for scoring fluence at circular or rectangular fields.
EGS_PlanarFluence(const string &Name="", EGS_ObjectFactory *f=0)
void describeMe()
Sets fluence scoring object description.
A class for scoring an array of quantities (e.g. a dose distribution) in a Monte Carlo simulation.
bool storeState(ostream &data)
Stores the state of the scoring array object into the data stream data.
void score(int ireg, EGS_Float f)
Add f to the score in the element ireg.
void currentResult(int ireg, double &r, double &dr)
Sets r to the result in region ireg and dr to its statistical uncertainty.
bool setState(istream &data)
Sets the state fof the scoring array object from the data in the input stream data.
A class representing 3D vectors.
Ausgab object for scoring fluence in arbitrary geometry regions.
void describeMe()
Sets fluence scoring object description.
EGS_VolumetricFluence(const string &Name="", EGS_ObjectFactory *f=0)
A fluence scoring object : header.
Global egspp functions header file.
EGS_RADIATIVE_SPLITTING_EXPORT EGS_AusgabObject * createAusgabObject(EGS_Input *input, EGS_ObjectFactory *f)
bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n)
Writes the 64 bit integer n to the output stream data and returns true on success,...
EGS_InfoFunction EGS_EXPORT egsInformation
Always use this function for reporting the progress of a simulation and any other type of information...
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n)
Reads a 64 bit integer from the stream data and assigns it to n. Returns true on success,...
EGS_InfoFunction EGS_EXPORT egsWarning
Always use this function for reporting warnings.
A structure holding the information of one particle.
EGS_Float E
particle energy in MeV
int latch
latch variable (useful as a flag on many occasions)
EGS_Float wt
statistical weight