diff --git a/.gitignore b/.gitignore index f2eaefea6..0ddaa8dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ mortjob.mortran HEN_HOUSE/bin/ HEN_HOUSE/lib/ HEN_HOUSE/log/ +HEN_HOUSE/distribution/ HEN_HOUSE/egs++/dso/ HEN_HOUSE/mortran3/mortran3_*.f HEN_HOUSE/omega/beamnrc/tools/beam_build_*.f diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cs_all.pdf b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cs_all.pdf index 79b49252c..4b8e42f31 100644 Binary files a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cs_all.pdf and b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cs_all.pdf differ diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cse_all.pdf b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cse_all.pdf index 3c41a74b3..7fa521f83 100644 Binary files a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cse_all.pdf and b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/cse_all.pdf differ diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cs_all.all b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cs_all.all index a65df72e6..80b8b3009 100644 --- a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cs_all.all +++ b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cs_all.all @@ -1,33 +1,60 @@ -# ACE/gr parameter file +# Grace project file # -@version 40102 -@page layout free -@ps linewidth begin 1 -@ps linewidth increment 2 -@hardcopy device 1 -@page 5 -@page inout 5 +@version 50122 +@page size 792, 612 +@page scroll 5% +@page inout 5% @link page off +@map font 0 to "Times-Roman", "Times-Roman" +@map font 2 to "Times-Italic", "Times-Italic" +@map font 1 to "Times-Bold", "Times-Bold" +@map font 3 to "Times-BoldItalic", "Times-BoldItalic" +@map font 4 to "Helvetica", "Helvetica" +@map font 6 to "Helvetica-Oblique", "Helvetica-Oblique" +@map font 5 to "Helvetica-Bold", "Helvetica-Bold" +@map font 7 to "Helvetica-BoldOblique", "Helvetica-BoldOblique" +@map font 8 to "Symbol", "Symbol" +@map font 9 to "ZapfDingbats", "ZapfDingbats" +@map color 0 to (255, 255, 255), "white" +@map color 1 to (0, 0, 0), "black" +@map color 2 to (255, 0, 0), "red" +@map color 3 to (0, 255, 0), "green" +@map color 4 to (0, 0, 255), "blue" +@map color 5 to (255, 255, 0), "yellow" +@map color 6 to (188, 143, 143), "brown" +@map color 7 to (220, 220, 220), "grey" +@map color 8 to (148, 0, 211), "violet" +@map color 9 to (0, 255, 255), "cyan" +@map color 10 to (255, 0, 255), "magenta" +@map color 11 to (255, 165, 0), "orange" +@map color 12 to (114, 33, 188), "indigo" +@map color 13 to (103, 7, 72), "maroon" +@map color 14 to (64, 224, 208), "turquoise" +@map color 15 to (0, 139, 0), "green4" +@reference date 0 +@date wrap on +@date wrap year 1900 +@default linewidth 1.0 @default linestyle 1 -@default linewidth 1 @default color 1 -@default char size 1.000000 +@default pattern 1 @default font 4 -@default font source 0 +@default char size 1.000000 @default symbol size 1.000000 +@default sformat "%.8g" +@background color 0 +@page background fill on @timestamp off @timestamp 0.03, 0.03 -@timestamp linewidth 1 @timestamp color 1 @timestamp rot 0 @timestamp font 4 @timestamp char size 1.000000 -@timestamp def "Tue Feb 22 08:58:05 2000" +@timestamp def "Mon Dec 14 18:52:53 2015" @with string @ string on @ string loctype view -@ string 0.446428571429, 0.785831960461 -@ string linewidth 1 +@ string 0.63509029308, 0.834159098007 @ string color 1 @ string rot 0 @ string font 4 @@ -37,118 +64,117 @@ @with string @ string on @ string loctype view -@ string 0.174450549451, 0.754530477759 -@ string linewidth 1 +@ string 0.229616887037, 0.806575087424 @ string color 1 @ string rot 0 @ string font 4 @ string just 0 @ string char size 1.000000 @ string def "T\sc\N=1 keV" -@with g0 +@r0 off +@link r0 to g0 +@r0 type above +@r0 linestyle 1 +@r0 linewidth 1.0 +@r0 color 1 +@r0 line 0, 0, 0, 0 +@r1 off +@link r1 to g0 +@r1 type above +@r1 linestyle 1 +@r1 linewidth 1.0 +@r1 color 1 +@r1 line 0, 0, 0, 0 +@r2 off +@link r2 to g0 +@r2 type above +@r2 linestyle 1 +@r2 linewidth 1.0 +@r2 color 1 +@r2 line 0, 0, 0, 0 +@r3 off +@link r3 to g0 +@r3 type above +@r3 linestyle 1 +@r3 linewidth 1.0 +@r3 color 1 +@r3 line 0, 0, 0, 0 +@r4 off +@link r4 to g0 +@r4 type above +@r4 linestyle 1 +@r4 linewidth 1.0 +@r4 color 1 +@r4 line 0, 0, 0, 0 @g0 on -@g0 label off @g0 hidden false -@g0 type logx -@g0 autoscale type AUTO +@g0 type XY +@g0 stacked false +@g0 bar hgap 0.000000 @g0 fixedpoint off @g0 fixedpoint type 0 @g0 fixedpoint xy 0.000000, 0.000000 @g0 fixedpoint format general general @g0 fixedpoint prec 6, 6 -@ world xmin 0.001 -@ world xmax 20 -@ world ymin 0 -@ world ymax 4000 -@ stack world 0, 0, 0, 0 tick 0, 0, 0, 0 -@ view xmin 0.150000 -@ view xmax 0.850000 -@ view ymin 0.150000 -@ view ymax 0.850000 +@with g0 +@ world 0.001, 0, 20, 4000 +@ stack world 0, 0, 0, 0 +@ znorm 1 +@ view 0.194238, 0.150000, 1.215613, 0.904585 @ title "" @ title font 4 @ title size 1.500000 @ title color 1 -@ title linewidth 1 @ subtitle "" @ subtitle font 4 @ subtitle size 1.000000 @ subtitle color 1 -@ subtitle linewidth 1 -@ s0 symbol 0 -@ s0 symbol size 1.000000 -@ s0 symbol fill 0 -@ s0 symbol color 1 -@ s0 symbol linewidth 1 -@ s0 symbol linestyle 1 -@ s0 symbol center false -@ s0 symbol char 0 -@ s0 skip 0 -@ s0 linestyle 1 -@ s0 linewidth 1 -@ s0 color 1 -@ s0 fill 0 -@ s0 fill with color -@ s0 fill color 1 -@ s0 fill pattern 0 -@ s0 errorbar type BOTH -@ s0 errorbar length 1.000000 -@ s0 errorbar linewidth 1 -@ s0 errorbar linestyle 1 -@ s0 errorbar riser on -@ s0 errorbar riser linewidth 1 -@ s0 errorbar riser linestyle 1 -@ s0 xyz 0.000000, 0.000000 -@ s0 comment "c512.out" -@ s1 symbol 0 -@ s1 symbol size 1.000000 -@ s1 symbol fill 0 -@ s1 symbol color 1 -@ s1 symbol linewidth 1 -@ s1 symbol linestyle 1 -@ s1 symbol center false -@ s1 symbol char 0 -@ s1 skip 0 -@ s1 linestyle 1 -@ s1 linewidth 1 -@ s1 color 1 -@ s1 fill 0 -@ s1 fill with color -@ s1 fill color 1 -@ s1 fill pattern 0 -@ s1 errorbar type BOTH -@ s1 errorbar length 1.000000 -@ s1 errorbar linewidth 1 -@ s1 errorbar linestyle 1 -@ s1 errorbar riser on -@ s1 errorbar riser linewidth 1 -@ s1 errorbar riser linestyle 1 -@ s1 xyz 0.000000, 0.000000 -@ s1 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cs2s.dat" -@ xaxis tick on -@ xaxis tick major 1 -@ xaxis tick minor 1 -@ xaxis tick offsetx 0.000000 -@ xaxis tick offsety 0.000000 +@ xaxes scale Logarithmic +@ yaxes scale Normal +@ xaxes invert off +@ yaxes invert off +@ xaxis on +@ xaxis type zero false +@ xaxis offset 0.000000 , 0.000000 +@ xaxis bar off +@ xaxis bar color 1 +@ xaxis bar linestyle 1 +@ xaxis bar linewidth 1.0 @ xaxis label "E (MeV)" @ xaxis label layout para @ xaxis label place auto @ xaxis label char size 1.490000 @ xaxis label font 4 @ xaxis label color 1 -@ xaxis label linewidth 1 +@ xaxis label place normal +@ xaxis tick on +@ xaxis tick major 10 +@ xaxis tick minor ticks 0 +@ xaxis tick default 6 +@ xaxis tick place rounded true +@ xaxis tick in +@ xaxis tick major size 1.000000 +@ xaxis tick major color 1 +@ xaxis tick major linewidth 1.0 +@ xaxis tick major linestyle 1 +@ xaxis tick major grid off +@ xaxis tick minor color 1 +@ xaxis tick minor linewidth 1.0 +@ xaxis tick minor linestyle 1 +@ xaxis tick minor grid off +@ xaxis tick minor size 0.500000 @ xaxis ticklabel on -@ xaxis ticklabel type auto -@ xaxis ticklabel prec 0 @ xaxis ticklabel format power +@ xaxis ticklabel prec 0 +@ xaxis ticklabel formula "" @ xaxis ticklabel append "" @ xaxis ticklabel prepend "" -@ xaxis ticklabel layout horizontal -@ xaxis ticklabel place on ticks +@ xaxis ticklabel angle 0 @ xaxis ticklabel skip 0 @ xaxis ticklabel stagger 0 -@ xaxis ticklabel op bottom -@ xaxis ticklabel sign normal +@ xaxis ticklabel place normal +@ xaxis ticklabel offset auto +@ xaxis ticklabel offset 0.000000 , 0.010000 @ xaxis ticklabel start type auto @ xaxis ticklabel start 0.000000 @ xaxis ticklabel stop type auto @@ -156,53 +182,50 @@ @ xaxis ticklabel char size 1.000000 @ xaxis ticklabel font 4 @ xaxis ticklabel color 1 -@ xaxis ticklabel linewidth 1 -@ xaxis tick major on -@ xaxis tick minor on -@ xaxis tick default 6 -@ xaxis tick in -@ xaxis tick major color 1 -@ xaxis tick major linewidth 1 -@ xaxis tick major linestyle 1 -@ xaxis tick minor color 1 -@ xaxis tick minor linewidth 1 -@ xaxis tick minor linestyle 1 -@ xaxis tick log off -@ xaxis tick size 1.000000 -@ xaxis tick minor size 0.500000 -@ xaxis bar off -@ xaxis bar color 1 -@ xaxis bar linestyle 1 -@ xaxis bar linewidth 1 -@ xaxis tick major grid off -@ xaxis tick minor grid off -@ xaxis tick op both -@ xaxis tick type auto -@ xaxis tick spec 0 -@ yaxis tick on -@ yaxis tick major 1000 -@ yaxis tick minor 500 -@ yaxis tick offsetx 0.000000 -@ yaxis tick offsety 0.000000 +@ xaxis tick place both +@ xaxis tick spec type none +@ yaxis on +@ yaxis type zero false +@ yaxis offset 0.000000 , 0.000000 +@ yaxis bar off +@ yaxis bar color 1 +@ yaxis bar linestyle 1 +@ yaxis bar linewidth 1.0 @ yaxis label "\8S\4\S(tot)\N (cm\S-1\N)" @ yaxis label layout para @ yaxis label place auto @ yaxis label char size 1.490000 @ yaxis label font 4 @ yaxis label color 1 -@ yaxis label linewidth 1 +@ yaxis label place normal +@ yaxis tick on +@ yaxis tick major 1000 +@ yaxis tick minor ticks 1 +@ yaxis tick default 6 +@ yaxis tick place rounded true +@ yaxis tick in +@ yaxis tick major size 1.000000 +@ yaxis tick major color 1 +@ yaxis tick major linewidth 1.0 +@ yaxis tick major linestyle 1 +@ yaxis tick major grid off +@ yaxis tick minor color 1 +@ yaxis tick minor linewidth 1.0 +@ yaxis tick minor linestyle 1 +@ yaxis tick minor grid off +@ yaxis tick minor size 0.500000 @ yaxis ticklabel on -@ yaxis ticklabel type auto -@ yaxis ticklabel prec 5 @ yaxis ticklabel format general +@ yaxis ticklabel prec 5 +@ yaxis ticklabel formula "" @ yaxis ticklabel append "" @ yaxis ticklabel prepend "" -@ yaxis ticklabel layout horizontal -@ yaxis ticklabel place on ticks +@ yaxis ticklabel angle 0 @ yaxis ticklabel skip 0 @ yaxis ticklabel stagger 0 -@ yaxis ticklabel op left -@ yaxis ticklabel sign normal +@ yaxis ticklabel place normal +@ yaxis ticklabel offset auto +@ yaxis ticklabel offset 0.000000 , 0.010000 @ yaxis ticklabel start type auto @ yaxis ticklabel start 0.000000 @ yaxis ticklabel stop type auto @@ -210,872 +233,836 @@ @ yaxis ticklabel char size 1.000000 @ yaxis ticklabel font 4 @ yaxis ticklabel color 1 -@ yaxis ticklabel linewidth 1 -@ yaxis tick major on -@ yaxis tick minor on -@ yaxis tick default 6 -@ yaxis tick in -@ yaxis tick major color 1 -@ yaxis tick major linewidth 1 -@ yaxis tick major linestyle 1 -@ yaxis tick minor color 1 -@ yaxis tick minor linewidth 1 -@ yaxis tick minor linestyle 1 -@ yaxis tick log off -@ yaxis tick size 1.000000 -@ yaxis tick minor size 0.500000 -@ yaxis bar off -@ yaxis bar color 1 -@ yaxis bar linestyle 1 -@ yaxis bar linewidth 1 -@ yaxis tick major grid off -@ yaxis tick minor grid off -@ yaxis tick op both -@ yaxis tick type auto -@ yaxis tick spec 0 -@ zeroxaxis tick on -@ zeroxaxis tick major 1 -@ zeroxaxis tick minor 1 -@ zeroxaxis tick offsetx 0.000000 -@ zeroxaxis tick offsety 0.000000 -@ zeroxaxis label "" -@ zeroxaxis label layout para -@ zeroxaxis label place auto -@ zeroxaxis label char size 1.000000 -@ zeroxaxis label font 4 -@ zeroxaxis label color 1 -@ zeroxaxis label linewidth 1 -@ zeroxaxis ticklabel off -@ zeroxaxis ticklabel type auto -@ zeroxaxis ticklabel prec 0 -@ zeroxaxis ticklabel format decimal -@ zeroxaxis ticklabel append "" -@ zeroxaxis ticklabel prepend "" -@ zeroxaxis ticklabel layout horizontal -@ zeroxaxis ticklabel place on ticks -@ zeroxaxis ticklabel skip 0 -@ zeroxaxis ticklabel stagger 0 -@ zeroxaxis ticklabel op bottom -@ zeroxaxis ticklabel sign normal -@ zeroxaxis ticklabel start type auto -@ zeroxaxis ticklabel start 0.000000 -@ zeroxaxis ticklabel stop type auto -@ zeroxaxis ticklabel stop 0.000000 -@ zeroxaxis ticklabel char size 1.000000 -@ zeroxaxis ticklabel font 4 -@ zeroxaxis ticklabel color 1 -@ zeroxaxis ticklabel linewidth 1 -@ zeroxaxis tick major off -@ zeroxaxis tick minor on -@ zeroxaxis tick default 6 -@ zeroxaxis tick in -@ zeroxaxis tick major color 1 -@ zeroxaxis tick major linewidth 1 -@ zeroxaxis tick major linestyle 1 -@ zeroxaxis tick minor color 1 -@ zeroxaxis tick minor linewidth 1 -@ zeroxaxis tick minor linestyle 1 -@ zeroxaxis tick log off -@ zeroxaxis tick size 1.000000 -@ zeroxaxis tick minor size 0.500000 -@ zeroxaxis bar off -@ zeroxaxis bar color 1 -@ zeroxaxis bar linestyle 1 -@ zeroxaxis bar linewidth 1 -@ zeroxaxis tick major grid off -@ zeroxaxis tick minor grid off -@ zeroxaxis tick op both -@ zeroxaxis tick type auto -@ zeroxaxis tick spec 0 -@ zeroyaxis tick on -@ zeroyaxis tick major 1000 -@ zeroyaxis tick minor 500 -@ zeroyaxis tick offsetx 0.000000 -@ zeroyaxis tick offsety 0.000000 -@ zeroyaxis label "" -@ zeroyaxis label layout para -@ zeroyaxis label place auto -@ zeroyaxis label char size 1.000000 -@ zeroyaxis label font 4 -@ zeroyaxis label color 1 -@ zeroyaxis label linewidth 1 -@ zeroyaxis ticklabel off -@ zeroyaxis ticklabel type auto -@ zeroyaxis ticklabel prec 5 -@ zeroyaxis ticklabel format general -@ zeroyaxis ticklabel append "" -@ zeroyaxis ticklabel prepend "" -@ zeroyaxis ticklabel layout horizontal -@ zeroyaxis ticklabel place on ticks -@ zeroyaxis ticklabel skip 0 -@ zeroyaxis ticklabel stagger 0 -@ zeroyaxis ticklabel op left -@ zeroyaxis ticklabel sign normal -@ zeroyaxis ticklabel start type auto -@ zeroyaxis ticklabel start 0.000000 -@ zeroyaxis ticklabel stop type auto -@ zeroyaxis ticklabel stop 0.000000 -@ zeroyaxis ticklabel char size 1.000000 -@ zeroyaxis ticklabel font 4 -@ zeroyaxis ticklabel color 1 -@ zeroyaxis ticklabel linewidth 1 -@ zeroyaxis tick major off -@ zeroyaxis tick minor on -@ zeroyaxis tick default 6 -@ zeroyaxis tick in -@ zeroyaxis tick major color 1 -@ zeroyaxis tick major linewidth 1 -@ zeroyaxis tick major linestyle 1 -@ zeroyaxis tick minor color 1 -@ zeroyaxis tick minor linewidth 1 -@ zeroyaxis tick minor linestyle 1 -@ zeroyaxis tick log off -@ zeroyaxis tick size 1.000000 -@ zeroyaxis tick minor size 0.500000 -@ zeroyaxis bar off -@ zeroyaxis bar color 1 -@ zeroyaxis bar linestyle 1 -@ zeroyaxis bar linewidth 1 -@ zeroyaxis tick major grid off -@ zeroyaxis tick minor grid off -@ zeroyaxis tick op both -@ zeroyaxis tick type auto -@ zeroyaxis tick spec 0 +@ yaxis tick place both +@ yaxis tick spec type none +@ altxaxis off +@ altyaxis off @ legend off @ legend loctype view -@ legend layout 0 -@ legend vgap 2 -@ legend hgap 1 -@ legend length 4 -@ legend box off -@ legend box fill off -@ legend box fill with color -@ legend box fill color 0 -@ legend box fill pattern 1 +@ legend 1.03593558463, 0.8 @ legend box color 1 -@ legend box linewidth 1 +@ legend box pattern 0 +@ legend box linewidth 1.0 @ legend box linestyle 1 -@ legend x1 0.8 -@ legend y1 0.8 +@ legend box fill color 0 +@ legend box fill pattern 1 @ legend font 4 @ legend char size 1.000000 -@ legend linestyle 1 -@ legend linewidth 1 @ legend color 1 -@ frame on +@ legend length 4 +@ legend vgap 1 +@ legend hgap 1 +@ legend invert false @ frame type 0 @ frame linestyle 1 -@ frame linewidth 1 +@ frame linewidth 1.0 @ frame color 1 -@ frame fill off +@ frame pattern 1 @ frame background color 0 -@WITH G0 -@G0 ON -@TARGET S0 -@TYPE xy - 0.001 0.0256408 - 0.00101532 0.0768815 - 0.00103087 0.128122 - 0.00104666 0.184626 - 0.00106269 0.243225 - 0.00107897 0.301824 - 0.0010955 0.359687 - 0.00111228 0.41323 - 0.00112932 0.466772 - 0.00114661 0.520315 - 0.00116418 0.5707 - 0.00118201 0.61878 - 0.00120012 0.66686 - 0.0012185 0.714902 - 0.00123716 0.758925 - 0.00125611 0.802949 - 0.00127536 0.846972 - 0.00129489 0.889529 - 0.00131473 0.930184 - 0.00133486 0.97084 - 0.00135531 1.01149 - 0.00137607 1.04773 - 0.00139715 1.08334 - 0.00141855 1.11896 - 0.00144028 1.15312 - 0.00146234 1.1841 - 0.00148474 1.21508 - 0.00150748 1.24606 - 0.00153058 1.27606 - 0.00155402 1.30567 - 0.00157782 1.33528 - 0.00160199 1.36408 - 0.00162653 1.38893 - 0.00165145 1.41379 - 0.00167674 1.43865 - 0.00170243 1.46133 - 0.0017285 1.48262 - 0.00175498 1.50391 - 0.00178186 1.52516 - 0.00180916 1.54498 - 0.00183687 1.56481 - 0.00186501 1.58463 - 0.00189357 1.60223 - 0.00192258 1.61742 - 0.00195203 1.6326 - 0.00198193 1.64779 - 0.00201229 206.644 - 0.00204311 433.652 - 0.00207441 660.659 - 0.00210618 870.222 - 0.00213844 1045 - 0.0021712 1219.77 - 0.00220446 1394.55 - 0.00223822 1539.39 - 0.00227251 1675.13 - 0.00230732 1810.86 - 0.00234266 1940.26 - 0.00237855 2046.07 - 0.00241498 2151.88 - 0.00245197 2257.68 - 0.00248953 2348.85 - 0.00252766 2431.25 - 0.00256638 2513.65 - 0.00260569 2594.87 - 0.00264561 2658.75 - 0.00268613 2722.64 - 0.00272728 2786.53 - 0.00276905 2842.89 - 0.00281147 2891.83 - 0.00285453 2940.76 - 0.00289826 2989.7 - 0.00294265 3027.41 - 0.00298773 3064.32 - 0.00303349 3101.22 - 0.00307996 3134.5 - 0.00312714 3161.47 - 0.00317504 3188.45 - 0.00322367 3215.43 - 0.00327305 3235.84 - 0.00332319 3254.59 - 0.00337409 3273.34 - 0.00342577 3290.5 - 0.00347825 3302.31 - 0.00353153 3314.13 - 0.00358562 3325.94 - 0.00364054 3333.83 - 0.00369631 3339.77 - 0.00375293 3345.71 - 0.00381041 3351.21 - 0.00386878 3352.29 - 0.00392804 3353.37 - 0.00398821 3354.44 - 0.0040493 3353.29 - 0.00411133 3350.15 - 0.0041743 3347 - 0.00423824 3343.86 - 0.00430316 3337.31 - 0.00436908 3330.64 - 0.004436 3323.97 - 0.00450395 3316.1 - 0.00457294 3306.4 - 0.00464299 3296.7 - 0.00471411 3287 - 0.00478632 3275.2 - 0.00485963 3262.96 - 0.00493407 3250.71 - 0.00500965 3237.88 - 0.00508639 3223.47 - 0.0051643 3209.06 - 0.0052434 3194.64 - 0.00532372 3178.98 - 0.00540527 3162.75 - 0.00548806 3146.53 - 0.00557213 3130.12 - 0.00565748 3112.4 - 0.00574414 3094.68 - 0.00583213 3076.95 - 0.00592146 3058.56 - 0.00601217 3039.6 - 0.00610426 3020.64 - 0.00619776 3001.69 - 0.0062927 2981.71 - 0.00638909 2961.74 - 0.00648695 2941.78 - 0.00658632 2921.49 - 0.0066872 2900.74 - 0.00678964 2879.99 - 0.00689364 2859.24 - 0.00699923 2837.98 - 0.00710645 2816.62 - 0.0072153 2795.26 - 0.00732582 2773.76 - 0.00743804 2751.95 - 0.00755197 2730.15 - 0.00766765 2708.34 - 0.0077851 2686.33 - 0.00790435 2664.23 - 0.00802543 2642.12 - 0.00814836 2619.96 - 0.00827317 2597.7 - 0.0083999 2575.43 - 0.00852857 2553.16 - 0.0086592 2530.88 - 0.00879184 2508.55 - 0.00892651 2486.21 - 0.00906325 2463.89 - 0.00920207 2441.61 - 0.00934303 2419.33 - 0.00948614 2397.04 - 0.00963145 2374.8 - 0.00977898 2352.64 - 0.00992877 2330.49 - 0.0100809 2308.33 - 0.0102353 2286.38 - 0.0103921 2264.43 - 0.0105512 2242.47 - 0.0107129 2220.59 - 0.010877 2198.91 - 0.0110436 2177.22 - 0.0112127 2155.54 - 0.0113845 2134.11 - 0.0115589 2112.74 - 0.0117359 2091.38 - 0.0119157 2070.07 - 0.0120982 2049.08 - 0.0122835 2028.09 - 0.0124717 2007.11 - 0.0126627 1986.38 - 0.0128567 1965.8 - 0.0130536 1945.23 - 0.0132536 1924.69 - 0.0134566 1904.57 - 0.0136627 1884.45 - 0.013872 1864.33 - 0.0140845 1844.44 - 0.0143002 1824.79 - 0.0145193 1805.14 - 0.0147417 1785.5 - 0.0149675 1766.32 - 0.0151967 1747.17 - 0.0154295 1728.02 - 0.0156659 1709.05 - 0.0159058 1690.42 - 0.0161495 1671.79 - 0.0163968 1653.16 - 0.016648 1634.95 - 0.016903 1616.85 - 0.0171619 1598.74 - 0.0174248 1580.76 - 0.0176917 1563.2 - 0.0179627 1545.64 - 0.0182379 1528.09 - 0.0185172 1510.87 - 0.0188009 1493.86 - 0.0190889 1476.84 - 0.0193813 1459.88 - 0.0196781 1443.41 - 0.0199796 1426.95 - 0.0202856 1410.48 - 0.0205964 1394.28 - 0.0209118 1378.37 - 0.0212322 1362.46 - 0.0215574 1346.54 - 0.0218876 1331.14 - 0.0222229 1315.77 - 0.0225633 1300.4 - 0.0229089 1285.25 - 0.0232598 1270.42 - 0.0236161 1255.6 - 0.0239779 1240.77 - 0.0243452 1226.37 - 0.0247181 1212.08 - 0.0250967 1197.79 - 0.0254812 1183.64 - 0.0258715 1169.89 - 0.0262678 1156.13 - 0.0266701 1142.38 - 0.0270787 1128.97 - 0.0274935 1115.74 - 0.0279146 1102.5 - 0.0283422 1089.32 - 0.0287763 1076.6 - 0.0292171 1063.88 - 0.0296647 1051.15 - 0.0301191 1038.69 - 0.0305805 1026.47 - 0.0310489 1014.25 - 0.0315245 1002.03 - 0.0320074 990.296 - 0.0324977 978.564 - 0.0329955 966.832 - 0.0335009 955.283 - 0.034014 944.028 - 0.0345351 932.773 - 0.0350641 921.518 - 0.0356012 910.658 - 0.0361465 899.869 - 0.0367002 889.081 - 0.0372624 878.412 - 0.0378332 868.075 - 0.0384127 857.738 - 0.0390011 847.401 - 0.0395985 837.372 - 0.0402051 827.474 - 0.0408209 817.575 - 0.0414462 807.734 - 0.0420811 798.26 - 0.0427257 788.787 - 0.0433802 779.314 - 0.0440447 770.082 - 0.0447193 761.02 - 0.0454044 751.959 - 0.0460999 742.897 - 0.046806 734.233 - 0.047523 725.569 - 0.0482509 716.906 - 0.04899 708.403 - 0.0497405 700.124 - 0.0505024 691.845 - 0.051276 683.565 - 0.0520614 675.612 - 0.0528589 667.703 - 0.0536686 659.795 - 0.0544907 651.998 - 0.0553254 644.447 - 0.0561728 636.897 - 0.0570333 629.346 - 0.0579069 622.047 - 0.0587939 614.841 - 0.0596945 607.634 - 0.0606089 600.482 - 0.0615373 593.608 - 0.06248 586.733 - 0.063437 579.859 - 0.0644087 573.177 - 0.0653954 566.621 - 0.0663971 560.065 - 0.0674142 553.513 - 0.0684468 547.263 - 0.0694953 541.013 - 0.0705598 534.763 - 0.0716406 528.652 - 0.072738 522.697 - 0.0738522 516.742 - 0.0749835 510.786 - 0.0761321 505.084 - 0.0772982 499.41 - 0.0784823 493.736 - 0.0796845 488.151 - 0.0809051 482.748 - 0.0821444 477.346 - 0.0834027 471.943 - 0.0846802 466.737 - 0.0859773 461.593 - 0.0872943 456.45 - 0.0886315 451.357 - 0.0899892 446.462 - 0.0913676 441.567 - 0.0927672 436.673 - 0.0941882 431.927 - 0.0956309 427.27 - 0.0970958 422.613 - 0.0985831 417.97 - 0.100093 413.541 - 0.101626 409.113 - 0.103183 404.685 - 0.104764 400.364 - 0.106368 396.153 - 0.107998 391.943 - 0.109652 387.732 - 0.111332 383.715 - 0.113037 379.712 - 0.114769 375.71 - 0.116527 371.779 - 0.118312 367.976 - 0.120124 364.172 - 0.121964 360.369 - 0.123832 356.716 - 0.125729 353.103 - 0.127655 349.491 - 0.12961 345.92 - 0.131596 342.49 - 0.133611 339.059 - 0.135658 335.629 - 0.137736 332.311 - 0.139846 329.054 - 0.141988 325.797 - 0.144163 322.555 - 0.146371 319.464 - 0.148613 316.373 - 0.15089 313.281 - 0.153201 310.272 - 0.155548 307.34 - 0.157931 304.407 - 0.16035 301.474 - 0.162806 298.686 - 0.1653 295.905 - 0.167832 293.123 - 0.170403 290.397 - 0.173013 287.759 - 0.175663 285.122 - 0.178354 282.484 - 0.181086 279.959 - 0.18386 277.459 - 0.186676 274.959 - 0.189536 272.493 - 0.192439 270.124 - 0.195387 267.755 - 0.19838 265.385 - 0.201419 263.102 - 0.204504 260.859 - 0.207636 258.615 - 0.210817 256.385 - 0.214046 254.261 - 0.217325 252.136 - 0.220654 250.011 - 0.224034 247.948 - 0.227466 245.937 - 0.23095 243.925 - 0.234488 241.914 - 0.23808 240.009 - 0.241726 238.105 - 0.245429 236.201 - 0.249189 234.341 - 0.253006 232.541 - 0.256881 230.74 - 0.260816 228.94 - 0.264811 227.224 - 0.268868 225.522 - 0.272986 223.82 - 0.277168 222.144 - 0.281413 220.535 - 0.285724 218.926 - 0.290101 217.317 - 0.294545 215.772 - 0.299056 214.253 - 0.303637 212.733 - 0.308288 211.225 - 0.313011 209.79 - 0.317805 208.355 - 0.322674 206.92 - 0.327616 205.532 - 0.332635 204.177 - 0.33773 202.823 - 0.342903 201.469 - 0.348156 200.191 - 0.353489 198.913 - 0.358904 197.635 - 0.364401 196.39 - 0.369983 195.185 - 0.37565 193.98 - 0.381405 192.775 - 0.387247 191.631 - 0.393179 190.495 - 0.399202 189.36 - 0.405316 188.244 - 0.411525 187.175 - 0.417829 186.105 - 0.424229 185.036 - 0.430727 184.013 - 0.437325 183.006 - 0.444024 181.999 - 0.450826 181.002 - 0.457731 180.054 - 0.464743 179.107 - 0.471862 178.16 - 0.47909 177.247 - 0.486428 176.356 - 0.49388 175.465 - 0.501445 174.576 - 0.509126 173.739 - 0.516925 172.902 - 0.524843 172.065 - 0.532882 171.252 - 0.541045 170.466 - 0.549333 169.679 - 0.557747 168.893 - 0.566291 168.15 - 0.574965 167.413 - 0.583773 166.675 - 0.592715 165.953 - 0.601794 165.261 - 0.611012 164.569 - 0.620372 163.877 - 0.629874 163.218 - 0.639523 162.57 - 0.649319 161.921 - 0.659265 161.281 - 0.669364 160.674 - 0.679617 160.066 - 0.690027 159.459 - 0.700597 158.876 - 0.711329 158.308 - 0.722225 157.74 - 0.733288 157.174 - 0.744521 156.642 - 0.755925 156.111 - 0.767504 155.579 - 0.779261 155.065 - 0.791198 154.569 - 0.803317 154.072 - 0.815622 153.575 - 0.828116 153.11 - 0.840801 152.646 - 0.85368 152.183 - 0.866757 151.731 - 0.880034 151.298 - 0.893514 150.865 - 0.907201 150.433 - 0.921097 150.024 - 0.935207 149.621 - 0.949532 149.218 - 0.964077 148.821 - 0.978845 148.446 - 0.993839 148.071 - 1.00906 147.695 - 1.02452 147.337 - 1.04021 146.988 - 1.05615 146.639 - 1.07232 146.292 - 1.08875 145.967 - 1.10543 145.642 - 1.12236 145.318 - 1.13955 145.005 - 1.15701 144.704 - 1.17473 144.402 - 1.19273 144.101 - 1.211 143.82 - 1.22955 143.54 - 1.24838 143.26 - 1.2675 142.989 - 1.28692 142.729 - 1.30663 142.47 - 1.32665 142.21 - 1.34697 141.967 - 1.3676 141.726 - 1.38855 141.486 - 1.40982 141.25 - 1.43141 141.028 - 1.45334 140.806 - 1.4756 140.583 - 1.49821 140.372 - 1.52116 140.167 - 1.54446 139.961 - 1.56811 139.758 - 1.59213 139.568 - 1.61652 139.378 - 1.64128 139.188 - 1.66643 139.006 - 1.69195 138.831 - 1.71787 138.655 - 1.74418 138.48 - 1.7709 138.318 - 1.79803 138.157 - 1.82557 137.995 - 1.85353 137.839 - 1.88193 137.69 - 1.91075 137.541 - 1.94002 137.392 - 1.96974 137.254 - 1.99991 137.117 +@ frame background pattern 0 +@ s0 hidden false +@ s0 type xy +@ s0 symbol 0 +@ s0 symbol size 1.000000 +@ s0 symbol color 1 +@ s0 symbol pattern 1 +@ s0 symbol fill color 1 +@ s0 symbol fill pattern 0 +@ s0 symbol linewidth 1.0 +@ s0 symbol linestyle 1 +@ s0 symbol char 0 +@ s0 symbol char font 4 +@ s0 symbol skip 0 +@ s0 line type 1 +@ s0 line linestyle 1 +@ s0 line linewidth 1.0 +@ s0 line color 1 +@ s0 line pattern 1 +@ s0 baseline type 0 +@ s0 baseline off +@ s0 dropline off +@ s0 fill type 0 +@ s0 fill rule 0 +@ s0 fill color 1 +@ s0 fill pattern 1 +@ s0 avalue off +@ s0 avalue type 2 +@ s0 avalue char size 1.000000 +@ s0 avalue font 4 +@ s0 avalue color 1 +@ s0 avalue rot 0 +@ s0 avalue format general +@ s0 avalue prec 3 +@ s0 avalue prepend "" +@ s0 avalue append "" +@ s0 avalue offset 0.000000 , 0.000000 +@ s0 errorbar on +@ s0 errorbar place both +@ s0 errorbar color 1 +@ s0 errorbar pattern 1 +@ s0 errorbar size 2.000000 +@ s0 errorbar linewidth 1.0 +@ s0 errorbar linestyle 1 +@ s0 errorbar riser linewidth 1.0 +@ s0 errorbar riser linestyle 1 +@ s0 errorbar riser clip off +@ s0 errorbar riser clip length 0.100000 +@ s0 comment "c512.out" +@ s0 legend "" +@ s1 hidden false +@ s1 type xy +@ s1 symbol 0 +@ s1 symbol size 1.000000 +@ s1 symbol color 1 +@ s1 symbol pattern 1 +@ s1 symbol fill color 1 +@ s1 symbol fill pattern 0 +@ s1 symbol linewidth 1.0 +@ s1 symbol linestyle 1 +@ s1 symbol char 0 +@ s1 symbol char font 4 +@ s1 symbol skip 0 +@ s1 line type 1 +@ s1 line linestyle 1 +@ s1 line linewidth 1.0 +@ s1 line color 1 +@ s1 line pattern 1 +@ s1 baseline type 0 +@ s1 baseline off +@ s1 dropline off +@ s1 fill type 0 +@ s1 fill rule 0 +@ s1 fill color 1 +@ s1 fill pattern 1 +@ s1 avalue off +@ s1 avalue type 2 +@ s1 avalue char size 1.000000 +@ s1 avalue font 4 +@ s1 avalue color 1 +@ s1 avalue rot 0 +@ s1 avalue format general +@ s1 avalue prec 3 +@ s1 avalue prepend "" +@ s1 avalue append "" +@ s1 avalue offset 0.000000 , 0.000000 +@ s1 errorbar on +@ s1 errorbar place both +@ s1 errorbar color 1 +@ s1 errorbar pattern 1 +@ s1 errorbar size 2.000000 +@ s1 errorbar linewidth 1.0 +@ s1 errorbar linestyle 1 +@ s1 errorbar riser linewidth 1.0 +@ s1 errorbar riser linestyle 1 +@ s1 errorbar riser clip off +@ s1 errorbar riser clip length 0.100000 +@ s1 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cs2s.dat" +@ s1 legend "" +@target G0.S0 +@type xy +0.001 0.0256408 +0.00101532 0.0768815 +0.00103087 0.128122 +0.00104666 0.184626 +0.00106269 0.243225 +0.00107897 0.301824 +0.0010955 0.359687 +0.00111228 0.41323 +0.00112932 0.466772 +0.00114661 0.520315 +0.00116418 0.5707 +0.00118201 0.61878 +0.00120012 0.66686 +0.0012185 0.714902 +0.00123716 0.758925 +0.00125611 0.802949 +0.00127536 0.846972 +0.00129489 0.889529 +0.00131473 0.930184 +0.00133486 0.97084 +0.00135531 1.01149 +0.00137607 1.04773 +0.00139715 1.08334 +0.00141855 1.11896 +0.00144028 1.15312 +0.00146234 1.1841 +0.00148474 1.21508 +0.00150748 1.24606 +0.00153058 1.27606 +0.00155402 1.30567 +0.00157782 1.33528 +0.00160199 1.36408 +0.00162653 1.38893 +0.00165145 1.41379 +0.00167674 1.43865 +0.00170243 1.46133 +0.0017285 1.48262 +0.00175498 1.50391 +0.00178186 1.52516 +0.00180916 1.54498 +0.00183687 1.56481 +0.00186501 1.58463 +0.00189357 1.60223 +0.00192258 1.61742 +0.00195203 1.6326 +0.00198193 1.64779 +0.00201229 206.644 +0.00204311 433.652 +0.00207441 660.659 +0.00210618 870.222 +0.00213844 1045 +0.0021712 1219.77 +0.00220446 1394.55 +0.00223822 1539.39 +0.00227251 1675.13 +0.00230732 1810.86 +0.00234266 1940.26 +0.00237855 2046.07 +0.00241498 2151.88 +0.00245197 2257.68 +0.00248953 2348.85 +0.00252766 2431.25 +0.00256638 2513.65 +0.00260569 2594.87 +0.00264561 2658.75 +0.00268613 2722.64 +0.00272728 2786.53 +0.00276905 2842.89 +0.00281147 2891.83 +0.00285453 2940.76 +0.00289826 2989.7 +0.00294265 3027.41 +0.00298773 3064.32 +0.00303349 3101.22 +0.00307996 3134.5 +0.00312714 3161.47 +0.00317504 3188.45 +0.00322367 3215.43 +0.00327305 3235.84 +0.00332319 3254.59 +0.00337409 3273.34 +0.00342577 3290.5 +0.00347825 3302.31 +0.00353153 3314.13 +0.00358562 3325.94 +0.00364054 3333.83 +0.00369631 3339.77 +0.00375293 3345.71 +0.00381041 3351.21 +0.00386878 3352.29 +0.00392804 3353.37 +0.00398821 3354.44 +0.0040493 3353.29 +0.00411133 3350.15 +0.0041743 3347 +0.00423824 3343.86 +0.00430316 3337.31 +0.00436908 3330.64 +0.004436 3323.97 +0.00450395 3316.1 +0.00457294 3306.4 +0.00464299 3296.7 +0.00471411 3287 +0.00478632 3275.2 +0.00485963 3262.96 +0.00493407 3250.71 +0.00500965 3237.88 +0.00508639 3223.47 +0.0051643 3209.06 +0.0052434 3194.64 +0.00532372 3178.98 +0.00540527 3162.75 +0.00548806 3146.53 +0.00557213 3130.12 +0.00565748 3112.4 +0.00574414 3094.68 +0.00583213 3076.95 +0.00592146 3058.56 +0.00601217 3039.6 +0.00610426 3020.64 +0.00619776 3001.69 +0.0062927 2981.71 +0.00638909 2961.74 +0.00648695 2941.78 +0.00658632 2921.49 +0.0066872 2900.74 +0.00678964 2879.99 +0.00689364 2859.24 +0.00699923 2837.98 +0.00710645 2816.62 +0.0072153 2795.26 +0.00732582 2773.76 +0.00743804 2751.95 +0.00755197 2730.15 +0.00766765 2708.34 +0.0077851 2686.33 +0.00790435 2664.23 +0.00802543 2642.12 +0.00814836 2619.96 +0.00827317 2597.7 +0.0083999 2575.43 +0.00852857 2553.16 +0.0086592 2530.88 +0.00879184 2508.55 +0.00892651 2486.21 +0.00906325 2463.89 +0.00920207 2441.61 +0.00934303 2419.33 +0.00948614 2397.04 +0.00963145 2374.8 +0.00977898 2352.64 +0.00992877 2330.49 +0.0100809 2308.33 +0.0102353 2286.38 +0.0103921 2264.43 +0.0105512 2242.47 +0.0107129 2220.59 +0.010877 2198.91 +0.0110436 2177.22 +0.0112127 2155.54 +0.0113845 2134.11 +0.0115589 2112.74 +0.0117359 2091.38 +0.0119157 2070.07 +0.0120982 2049.08 +0.0122835 2028.09 +0.0124717 2007.11 +0.0126627 1986.38 +0.0128567 1965.8 +0.0130536 1945.23 +0.0132536 1924.69 +0.0134566 1904.57 +0.0136627 1884.45 +0.013872 1864.33 +0.0140845 1844.44 +0.0143002 1824.79 +0.0145193 1805.14 +0.0147417 1785.5 +0.0149675 1766.32 +0.0151967 1747.17 +0.0154295 1728.02 +0.0156659 1709.05 +0.0159058 1690.42 +0.0161495 1671.79 +0.0163968 1653.16 +0.016648 1634.95 +0.016903 1616.85 +0.0171619 1598.74 +0.0174248 1580.76 +0.0176917 1563.2 +0.0179627 1545.64 +0.0182379 1528.09 +0.0185172 1510.87 +0.0188009 1493.86 +0.0190889 1476.84 +0.0193813 1459.88 +0.0196781 1443.41 +0.0199796 1426.95 +0.0202856 1410.48 +0.0205964 1394.28 +0.0209118 1378.37 +0.0212322 1362.46 +0.0215574 1346.54 +0.0218876 1331.14 +0.0222229 1315.77 +0.0225633 1300.4 +0.0229089 1285.25 +0.0232598 1270.42 +0.0236161 1255.6 +0.0239779 1240.77 +0.0243452 1226.37 +0.0247181 1212.08 +0.0250967 1197.79 +0.0254812 1183.64 +0.0258715 1169.89 +0.0262678 1156.13 +0.0266701 1142.38 +0.0270787 1128.97 +0.0274935 1115.74 +0.0279146 1102.5 +0.0283422 1089.32 +0.0287763 1076.6 +0.0292171 1063.88 +0.0296647 1051.15 +0.0301191 1038.69 +0.0305805 1026.47 +0.0310489 1014.25 +0.0315245 1002.03 +0.0320074 990.296 +0.0324977 978.564 +0.0329955 966.832 +0.0335009 955.283 +0.034014 944.028 +0.0345351 932.773 +0.0350641 921.518 +0.0356012 910.658 +0.0361465 899.869 +0.0367002 889.081 +0.0372624 878.412 +0.0378332 868.075 +0.0384127 857.738 +0.0390011 847.401 +0.0395985 837.372 +0.0402051 827.474 +0.0408209 817.575 +0.0414462 807.734 +0.0420811 798.26 +0.0427257 788.787 +0.0433802 779.314 +0.0440447 770.082 +0.0447193 761.02 +0.0454044 751.959 +0.0460999 742.897 +0.046806 734.233 +0.047523 725.569 +0.0482509 716.906 +0.04899 708.403 +0.0497405 700.124 +0.0505024 691.845 +0.051276 683.565 +0.0520614 675.612 +0.0528589 667.703 +0.0536686 659.795 +0.0544907 651.998 +0.0553254 644.447 +0.0561728 636.897 +0.0570333 629.346 +0.0579069 622.047 +0.0587939 614.841 +0.0596945 607.634 +0.0606089 600.482 +0.0615373 593.608 +0.06248 586.733 +0.063437 579.859 +0.0644087 573.177 +0.0653954 566.621 +0.0663971 560.065 +0.0674142 553.513 +0.0684468 547.263 +0.0694953 541.013 +0.0705598 534.763 +0.0716406 528.652 +0.072738 522.697 +0.0738522 516.742 +0.0749835 510.786 +0.0761321 505.084 +0.0772982 499.41 +0.0784823 493.736 +0.0796845 488.151 +0.0809051 482.748 +0.0821444 477.346 +0.0834027 471.943 +0.0846802 466.737 +0.0859773 461.593 +0.0872943 456.45 +0.0886315 451.357 +0.0899892 446.462 +0.0913676 441.567 +0.0927672 436.673 +0.0941882 431.927 +0.0956309 427.27 +0.0970958 422.613 +0.0985831 417.97 +0.100093 413.541 +0.101626 409.113 +0.103183 404.685 +0.104764 400.364 +0.106368 396.153 +0.107998 391.943 +0.109652 387.732 +0.111332 383.715 +0.113037 379.712 +0.114769 375.71 +0.116527 371.779 +0.118312 367.976 +0.120124 364.172 +0.121964 360.369 +0.123832 356.716 +0.125729 353.103 +0.127655 349.491 +0.12961 345.92 +0.131596 342.49 +0.133611 339.059 +0.135658 335.629 +0.137736 332.311 +0.139846 329.054 +0.141988 325.797 +0.144163 322.555 +0.146371 319.464 +0.148613 316.373 +0.15089 313.281 +0.153201 310.272 +0.155548 307.34 +0.157931 304.407 +0.16035 301.474 +0.162806 298.686 +0.1653 295.905 +0.167832 293.123 +0.170403 290.397 +0.173013 287.759 +0.175663 285.122 +0.178354 282.484 +0.181086 279.959 +0.18386 277.459 +0.186676 274.959 +0.189536 272.493 +0.192439 270.124 +0.195387 267.755 +0.19838 265.385 +0.201419 263.102 +0.204504 260.859 +0.207636 258.615 +0.210817 256.385 +0.214046 254.261 +0.217325 252.136 +0.220654 250.011 +0.224034 247.948 +0.227466 245.937 +0.23095 243.925 +0.234488 241.914 +0.23808 240.009 +0.241726 238.105 +0.245429 236.201 +0.249189 234.341 +0.253006 232.541 +0.256881 230.74 +0.260816 228.94 +0.264811 227.224 +0.268868 225.522 +0.272986 223.82 +0.277168 222.144 +0.281413 220.535 +0.285724 218.926 +0.290101 217.317 +0.294545 215.772 +0.299056 214.253 +0.303637 212.733 +0.308288 211.225 +0.313011 209.79 +0.317805 208.355 +0.322674 206.92 +0.327616 205.532 +0.332635 204.177 +0.33773 202.823 +0.342903 201.469 +0.348156 200.191 +0.353489 198.913 +0.358904 197.635 +0.364401 196.39 +0.369983 195.185 +0.37565 193.98 +0.381405 192.775 +0.387247 191.631 +0.393179 190.495 +0.399202 189.36 +0.405316 188.244 +0.411525 187.175 +0.417829 186.105 +0.424229 185.036 +0.430727 184.013 +0.437325 183.006 +0.444024 181.999 +0.450826 181.002 +0.457731 180.054 +0.464743 179.107 +0.471862 178.16 +0.47909 177.247 +0.486428 176.356 +0.49388 175.465 +0.501445 174.576 +0.509126 173.739 +0.516925 172.902 +0.524843 172.065 +0.532882 171.252 +0.541045 170.466 +0.549333 169.679 +0.557747 168.893 +0.566291 168.15 +0.574965 167.413 +0.583773 166.675 +0.592715 165.953 +0.601794 165.261 +0.611012 164.569 +0.620372 163.877 +0.629874 163.218 +0.639523 162.57 +0.649319 161.921 +0.659265 161.281 +0.669364 160.674 +0.679617 160.066 +0.690027 159.459 +0.700597 158.876 +0.711329 158.308 +0.722225 157.74 +0.733288 157.174 +0.744521 156.642 +0.755925 156.111 +0.767504 155.579 +0.779261 155.065 +0.791198 154.569 +0.803317 154.072 +0.815622 153.575 +0.828116 153.11 +0.840801 152.646 +0.85368 152.183 +0.866757 151.731 +0.880034 151.298 +0.893514 150.865 +0.907201 150.433 +0.921097 150.024 +0.935207 149.621 +0.949532 149.218 +0.964077 148.821 +0.978845 148.446 +0.993839 148.071 +1.00906 147.695 +1.02452 147.337 +1.04021 146.988 +1.05615 146.639 +1.07232 146.292 +1.08875 145.967 +1.10543 145.642 +1.12236 145.318 +1.13955 145.005 +1.15701 144.704 +1.17473 144.402 +1.19273 144.101 +1.211 143.82 +1.22955 143.54 +1.24838 143.26 +1.2675 142.989 +1.28692 142.729 +1.30663 142.47 +1.32665 142.21 +1.34697 141.967 +1.3676 141.726 +1.38855 141.486 +1.40982 141.25 +1.43141 141.028 +1.45334 140.806 +1.4756 140.583 +1.49821 140.372 +1.52116 140.167 +1.54446 139.961 +1.56811 139.758 +1.59213 139.568 +1.61652 139.378 +1.64128 139.188 +1.66643 139.006 +1.69195 138.831 +1.71787 138.655 +1.74418 138.48 +1.7709 138.318 +1.79803 138.157 +1.82557 137.995 +1.85353 137.839 +1.88193 137.69 +1.91075 137.541 +1.94002 137.392 +1.96974 137.254 +1.99991 137.117 & -@TARGET S1 -@TYPE xy - 0.01 0.0345166 - 0.0103514 1.59809 - 0.0107152 3.0957 - 0.0110917 4.52753 - 0.0114815 5.81698 - 0.011885 7.05077 - 0.0123027 8.12776 - 0.012735 9.17549 - 0.0131826 10.186 - 0.0136458 11.0847 - 0.0141254 11.9357 - 0.0146218 12.6402 - 0.0151356 13.3338 - 0.0156675 14.009 - 0.0162181 14.5977 - 0.016788 15.1478 - 0.017378 15.5955 - 0.0179887 16.0331 - 0.0186209 16.4493 - 0.0192752 16.7861 - 0.0199526 17.0786 - 0.0206538 525.61 - 0.0213796 1025.29 - 0.0221309 1431.97 - 0.0229087 1784.42 - 0.0237137 2097.53 - 0.0245471 2347.42 - 0.0254097 2578.7 - 0.0263027 2767.09 - 0.027227 2933.2 - 0.0281838 3079.15 - 0.0291742 3196.9 - 0.0301995 3305.01 - 0.0312608 3390.13 - 0.0323593 3464.97 - 0.0334965 3527.85 - 0.0346736 3576.49 - 0.0358922 3619.72 - 0.0371535 3649.16 - 0.0384591 3673.41 - 0.0398107 3690.09 - 0.0412097 3699.14 - 0.0426579 3704.88 - 0.044157 3701.88 - 0.0457088 3696.26 - 0.0473151 3685.73 - 0.0489778 3670.97 - 0.050699 3654.04 - 0.0524807 3631.9 - 0.0543249 3608.31 - 0.056234 3581.57 - 0.0582102 3552.63 - 0.0602559 3522.2 - 0.0623734 3489.02 - 0.0645653 3455.03 - 0.0668343 3419.15 - 0.069183 3382.24 - 0.0716142 3344.45 - 0.0741309 3305.43 - 0.076736 3266.01 - 0.0794327 3225.7 - 0.0822241 3185.06 - 0.0851136 3144.07 - 0.0881047 3102.75 - 0.0912009 3061.31 - 0.0944059 3019.78 - 0.0977235 2978.29 - 0.101158 2936.85 - 0.104713 2895.66 - 0.108392 2854.58 - 0.112202 2813.91 - 0.116145 2773.46 - 0.120226 2733.37 - 0.124451 2693.82 - 0.128825 2654.5 - 0.133352 2616.07 - 0.138038 2577.91 - 0.142889 2540.38 - 0.14791 2503.49 - 0.153108 2466.98 - 0.158489 2431.5 - 0.164059 2396.36 - 0.169824 2362.03 - 0.175792 2328.38 - 0.18197 2295.22 - 0.188364 2263.1 - 0.194984 2231.35 - 0.201836 2200.56 - 0.208929 2170.4 - 0.216271 2140.82 - 0.223871 2112.22 - 0.231739 2083.99 - 0.239883 2056.77 - 0.248313 2030.09 - 0.257039 2004.08 - 0.266072 1978.97 - 0.275422 1954.23 - 0.285101 1930.53 - 0.29512 1907.28 - 0.305491 1884.71 - 0.316227 1862.95 - 0.32734 1841.52 - 0.338843 1821.13 - 0.350751 1801.11 - 0.363077 1781.8 - 0.375836 1763.14 - 0.389044 1744.84 - 0.402716 1727.5 - 0.416868 1710.46 - 0.431518 1694.11 - 0.446682 1678.31 - 0.462379 1662.89 - 0.478628 1648.27 - 0.495448 1633.93 - 0.51286 1620.26 - 0.530883 1607.03 - 0.549539 1594.18 - 0.568851 1582.01 - 0.588842 1570.08 - 0.609535 1558.79 - 0.630955 1547.84 - 0.653128 1537.27 - 0.676081 1527.24 - 0.699839 1517.42 - 0.724433 1508.21 - 0.749891 1499.25 - 0.776244 1490.66 - 0.803523 1482.51 - 0.831761 1474.54 - 0.860991 1467.11 - 0.891248 1459.88 - 0.922568 1452.99 - 0.954989 1446.44 - 0.988549 1440.06 - 1.02329 1434.16 - 1.05925 1428.4 - 1.09647 1422.95 - 1.13501 1417.76 - 1.17489 1412.74 - 1.21618 1408.08 - 1.25892 1403.55 - 1.30316 1399.31 - 1.34896 1395.26 - 1.39636 1391.37 - 1.44543 1387.77 - 1.49623 1384.26 - 1.54881 1381.01 - 1.60324 1377.9 - 1.65958 1374.94 - 1.7179 1372.19 - 1.77827 1369.53 - 1.84077 1367.08 - 1.90545 1364.74 - 1.97242 1362.52 - 2.04173 1360.47 - 2.11348 1358.48 - 2.18775 1356.68 - 2.26464 1354.95 - 2.34422 1353.33 - 2.4266 1351.83 - 2.51188 1350.38 - 2.60015 1349.08 - 2.69152 1347.84 - 2.78611 1346.68 - 2.88402 1345.61 - 2.98537 1344.59 - 3.09028 1343.68 - 3.19888 1342.81 - 3.3113 1342.02 - 3.42766 1341.29 - 3.54812 1340.6 - 3.67281 1339.99 - 3.80188 1339.41 - 3.93548 1338.9 - 4.07378 1338.42 - 4.21695 1337.98 - 4.36514 1337.6 - 4.51854 1337.24 - 4.67733 1336.94 - 4.8417 1336.66 - 5.01185 1336.41 - 5.18798 1336.2 - 5.37029 1336.01 - 5.55902 1335.86 - 5.75437 1335.72 - 5.95659 1335.61 - 6.16592 1335.53 - 6.3826 1335.45 - 6.6069 1335.42 - 6.83908 1335.39 - 7.07942 1335.39 - 7.32821 1335.4 - 7.58574 1335.42 - 7.85232 1335.47 - 8.12826 1335.52 - 8.41391 1335.59 - 8.70959 1335.67 - 9.01567 1335.76 - 9.33249 1335.86 - 9.66046 1335.97 - 9.99995 1336.09 +@target G0.S1 +@type xy +0.01 0.0345166 +0.0103514 1.59809 +0.0107152 3.0957 +0.0110917 4.52753 +0.0114815 5.81698 +0.011885 7.05077 +0.0123027 8.12776 +0.012735 9.17549 +0.0131826 10.186 +0.0136458 11.0847 +0.0141254 11.9357 +0.0146218 12.6402 +0.0151356 13.3338 +0.0156675 14.009 +0.0162181 14.5977 +0.016788 15.1478 +0.017378 15.5955 +0.0179887 16.0331 +0.0186209 16.4493 +0.0192752 16.7861 +0.0199526 17.0786 +0.0206538 525.61 +0.0213796 1025.29 +0.0221309 1431.97 +0.0229087 1784.42 +0.0237137 2097.53 +0.0245471 2347.42 +0.0254097 2578.7 +0.0263027 2767.09 +0.027227 2933.2 +0.0281838 3079.15 +0.0291742 3196.9 +0.0301995 3305.01 +0.0312608 3390.13 +0.0323593 3464.97 +0.0334965 3527.85 +0.0346736 3576.49 +0.0358922 3619.72 +0.0371535 3649.16 +0.0384591 3673.41 +0.0398107 3690.09 +0.0412097 3699.14 +0.0426579 3704.88 +0.044157 3701.88 +0.0457088 3696.26 +0.0473151 3685.73 +0.0489778 3670.97 +0.050699 3654.04 +0.0524807 3631.9 +0.0543249 3608.31 +0.056234 3581.57 +0.0582102 3552.63 +0.0602559 3522.2 +0.0623734 3489.02 +0.0645653 3455.03 +0.0668343 3419.15 +0.069183 3382.24 +0.0716142 3344.45 +0.0741309 3305.43 +0.076736 3266.01 +0.0794327 3225.7 +0.0822241 3185.06 +0.0851136 3144.07 +0.0881047 3102.75 +0.0912009 3061.31 +0.0944059 3019.78 +0.0977235 2978.29 +0.101158 2936.85 +0.104713 2895.66 +0.108392 2854.58 +0.112202 2813.91 +0.116145 2773.46 +0.120226 2733.37 +0.124451 2693.82 +0.128825 2654.5 +0.133352 2616.07 +0.138038 2577.91 +0.142889 2540.38 +0.14791 2503.49 +0.153108 2466.98 +0.158489 2431.5 +0.164059 2396.36 +0.169824 2362.03 +0.175792 2328.38 +0.18197 2295.22 +0.188364 2263.1 +0.194984 2231.35 +0.201836 2200.56 +0.208929 2170.4 +0.216271 2140.82 +0.223871 2112.22 +0.231739 2083.99 +0.239883 2056.77 +0.248313 2030.09 +0.257039 2004.08 +0.266072 1978.97 +0.275422 1954.23 +0.285101 1930.53 +0.29512 1907.28 +0.305491 1884.71 +0.316227 1862.95 +0.32734 1841.52 +0.338843 1821.13 +0.350751 1801.11 +0.363077 1781.8 +0.375836 1763.14 +0.389044 1744.84 +0.402716 1727.5 +0.416868 1710.46 +0.431518 1694.11 +0.446682 1678.31 +0.462379 1662.89 +0.478628 1648.27 +0.495448 1633.93 +0.51286 1620.26 +0.530883 1607.03 +0.549539 1594.18 +0.568851 1582.01 +0.588842 1570.08 +0.609535 1558.79 +0.630955 1547.84 +0.653128 1537.27 +0.676081 1527.24 +0.699839 1517.42 +0.724433 1508.21 +0.749891 1499.25 +0.776244 1490.66 +0.803523 1482.51 +0.831761 1474.54 +0.860991 1467.11 +0.891248 1459.88 +0.922568 1452.99 +0.954989 1446.44 +0.988549 1440.06 +1.02329 1434.16 +1.05925 1428.4 +1.09647 1422.95 +1.13501 1417.76 +1.17489 1412.74 +1.21618 1408.08 +1.25892 1403.55 +1.30316 1399.31 +1.34896 1395.26 +1.39636 1391.37 +1.44543 1387.77 +1.49623 1384.26 +1.54881 1381.01 +1.60324 1377.9 +1.65958 1374.94 +1.7179 1372.19 +1.77827 1369.53 +1.84077 1367.08 +1.90545 1364.74 +1.97242 1362.52 +2.04173 1360.47 +2.11348 1358.48 +2.18775 1356.68 +2.26464 1354.95 +2.34422 1353.33 +2.4266 1351.83 +2.51188 1350.38 +2.60015 1349.08 +2.69152 1347.84 +2.78611 1346.68 +2.88402 1345.61 +2.98537 1344.59 +3.09028 1343.68 +3.19888 1342.81 +3.3113 1342.02 +3.42766 1341.29 +3.54812 1340.6 +3.67281 1339.99 +3.80188 1339.41 +3.93548 1338.9 +4.07378 1338.42 +4.21695 1337.98 +4.36514 1337.6 +4.51854 1337.24 +4.67733 1336.94 +4.8417 1336.66 +5.01185 1336.41 +5.18798 1336.2 +5.37029 1336.01 +5.55902 1335.86 +5.75437 1335.72 +5.95659 1335.61 +6.16592 1335.53 +6.3826 1335.45 +6.6069 1335.42 +6.83908 1335.39 +7.07942 1335.39 +7.32821 1335.4 +7.58574 1335.42 +7.85232 1335.47 +8.12826 1335.52 +8.41391 1335.59 +8.70959 1335.67 +9.01567 1335.76 +9.33249 1335.86 +9.66046 1335.97 +9.99995 1336.09 & diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cse_all.all b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cse_all.all index c3c3b2071..2fff7078a 100644 --- a/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cse_all.all +++ b/HEN_HOUSE/doc/src/pirs701-egsnrc/figures/grace/cse_all.all @@ -1,33 +1,60 @@ -# ACE/gr parameter file +# Grace project file # -@version 40102 -@page layout free -@ps linewidth begin 1 -@ps linewidth increment 2 -@hardcopy device 1 -@page 5 -@page inout 5 +@version 50122 +@page size 792, 612 +@page scroll 5% +@page inout 5% @link page off +@map font 0 to "Times-Roman", "Times-Roman" +@map font 2 to "Times-Italic", "Times-Italic" +@map font 1 to "Times-Bold", "Times-Bold" +@map font 3 to "Times-BoldItalic", "Times-BoldItalic" +@map font 4 to "Helvetica", "Helvetica" +@map font 6 to "Helvetica-Oblique", "Helvetica-Oblique" +@map font 5 to "Helvetica-Bold", "Helvetica-Bold" +@map font 7 to "Helvetica-BoldOblique", "Helvetica-BoldOblique" +@map font 8 to "Symbol", "Symbol" +@map font 9 to "ZapfDingbats", "ZapfDingbats" +@map color 0 to (255, 255, 255), "white" +@map color 1 to (0, 0, 0), "black" +@map color 2 to (255, 0, 0), "red" +@map color 3 to (0, 255, 0), "green" +@map color 4 to (0, 0, 255), "blue" +@map color 5 to (255, 255, 0), "yellow" +@map color 6 to (188, 143, 143), "brown" +@map color 7 to (220, 220, 220), "grey" +@map color 8 to (148, 0, 211), "violet" +@map color 9 to (0, 255, 255), "cyan" +@map color 10 to (255, 0, 255), "magenta" +@map color 11 to (255, 165, 0), "orange" +@map color 12 to (114, 33, 188), "indigo" +@map color 13 to (103, 7, 72), "maroon" +@map color 14 to (64, 224, 208), "turquoise" +@map color 15 to (0, 139, 0), "green4" +@reference date 0 +@date wrap on +@date wrap year 1900 +@default linewidth 1.0 @default linestyle 1 -@default linewidth 1 @default color 1 -@default char size 1.000000 +@default pattern 1 @default font 4 -@default font source 0 +@default char size 1.000000 @default symbol size 1.000000 +@default sformat "%.8g" +@background color 0 +@page background fill on @timestamp off @timestamp 0.03, 0.03 -@timestamp linewidth 1 @timestamp color 1 @timestamp rot 0 @timestamp font 4 @timestamp char size 1.000000 -@timestamp def "Tue Feb 22 08:38:59 2000" +@timestamp def "Mon Dec 14 19:06:29 2015" @with string @ string on @ string loctype view -@ string 0.493131868132, 0.698517298188 -@ string linewidth 1 +@ string 0.639805220013, 0.759236009464 @ string color 1 @ string rot 0 @ string font 4 @@ -37,168 +64,117 @@ @with string @ string on @ string loctype view -@ string 0.479395604396, 0.477759472817 -@ string linewidth 1 +@ string 0.622017864508, 0.498825148158 @ string color 1 @ string rot 0 @ string font 4 @ string just 0 @ string char size 1.500000 @ string def "C" -@with g0 +@r0 off +@link r0 to g0 +@r0 type above +@r0 linestyle 1 +@r0 linewidth 1.0 +@r0 color 1 +@r0 line 0, 0, 0, 0 +@r1 off +@link r1 to g0 +@r1 type above +@r1 linestyle 1 +@r1 linewidth 1.0 +@r1 color 1 +@r1 line 0, 0, 0, 0 +@r2 off +@link r2 to g0 +@r2 type above +@r2 linestyle 1 +@r2 linewidth 1.0 +@r2 color 1 +@r2 line 0, 0, 0, 0 +@r3 off +@link r3 to g0 +@r3 type above +@r3 linestyle 1 +@r3 linewidth 1.0 +@r3 color 1 +@r3 line 0, 0, 0, 0 +@r4 off +@link r4 to g0 +@r4 type above +@r4 linestyle 1 +@r4 linewidth 1.0 +@r4 color 1 +@r4 line 0, 0, 0, 0 @g0 on -@g0 label off @g0 hidden false -@g0 type logx -@g0 autoscale type AUTO +@g0 type XY +@g0 stacked false +@g0 bar hgap 0.000000 @g0 fixedpoint off @g0 fixedpoint type 0 @g0 fixedpoint xy 0.000000, 0.000000 @g0 fixedpoint format general general @g0 fixedpoint prec 6, 6 -@ world xmin 0.001 -@ world xmax 50 -@ world ymin 0 -@ world ymax 200 -@ stack world 0, 0, 0, 0 tick 0, 0, 0, 0 -@ view xmin 0.150000 -@ view xmax 0.850000 -@ view ymin 0.150000 -@ view ymax 0.850000 +@with g0 +@ world 0.001, 0, 50, 200 +@ stack world 0, 0, 0, 0 +@ znorm 1 +@ view 0.194238, 0.150000, 1.185874, 0.898389 @ title "" @ title font 4 @ title size 1.500000 @ title color 1 -@ title linewidth 1 @ subtitle "" @ subtitle font 4 @ subtitle size 1.000000 @ subtitle color 1 -@ subtitle linewidth 1 -@ s0 symbol 0 -@ s0 symbol size 1.000000 -@ s0 symbol fill 0 -@ s0 symbol color 1 -@ s0 symbol linewidth 1 -@ s0 symbol linestyle 1 -@ s0 symbol center false -@ s0 symbol char 0 -@ s0 skip 0 -@ s0 linestyle 1 -@ s0 linewidth 1 -@ s0 color 1 -@ s0 fill 0 -@ s0 fill with color -@ s0 fill color 1 -@ s0 fill pattern 0 -@ s0 errorbar type BOTH -@ s0 errorbar length 1.000000 -@ s0 errorbar linewidth 1 -@ s0 errorbar linestyle 1 -@ s0 errorbar riser on -@ s0 errorbar riser linewidth 1 -@ s0 errorbar riser linestyle 1 -@ s0 xyz 0.000000, 0.000000 -@ s0 comment "/a/irs29/home/irs29b6/iwan/photong/rad_yields/au512.out:2" -@ s1 symbol 0 -@ s1 symbol size 1.000000 -@ s1 symbol fill 0 -@ s1 symbol color 1 -@ s1 symbol linewidth 1 -@ s1 symbol linestyle 1 -@ s1 symbol center false -@ s1 symbol char 0 -@ s1 skip 0 -@ s1 linestyle 1 -@ s1 linewidth 1 -@ s1 color 1 -@ s1 fill 0 -@ s1 fill with color -@ s1 fill color 1 -@ s1 fill pattern 0 -@ s1 errorbar type BOTH -@ s1 errorbar length 1.000000 -@ s1 errorbar linewidth 1 -@ s1 errorbar linestyle 1 -@ s1 errorbar riser on -@ s1 errorbar riser linewidth 1 -@ s1 errorbar riser linestyle 1 -@ s1 xyz 0.000000, 0.000000 -@ s1 comment "/a/irs29/home/irs29b6/iwan/photong/rad_yields/c512.out:2" -@ s2 symbol 0 -@ s2 symbol size 1.000000 -@ s2 symbol fill 0 -@ s2 symbol color 1 -@ s2 symbol linewidth 1 -@ s2 symbol linestyle 1 -@ s2 symbol center false -@ s2 symbol char 0 -@ s2 skip 0 -@ s2 linestyle 3 -@ s2 linewidth 1 -@ s2 color 1 -@ s2 fill 0 -@ s2 fill with color -@ s2 fill color 1 -@ s2 fill pattern 0 -@ s2 errorbar type BOTH -@ s2 errorbar length 1.000000 -@ s2 errorbar linewidth 1 -@ s2 errorbar linestyle 1 -@ s2 errorbar riser on -@ s2 errorbar riser linewidth 1 -@ s2 errorbar riser linestyle 1 -@ s2 xyz 0.000000, 0.000000 -@ s2 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cse2s.dat" -@ s3 symbol 0 -@ s3 symbol size 1.000000 -@ s3 symbol fill 0 -@ s3 symbol color 1 -@ s3 symbol linewidth 1 -@ s3 symbol linestyle 1 -@ s3 symbol center false -@ s3 symbol char 0 -@ s3 skip 0 -@ s3 linestyle 3 -@ s3 linewidth 1 -@ s3 color 1 -@ s3 fill 0 -@ s3 fill with color -@ s3 fill color 1 -@ s3 fill pattern 0 -@ s3 errorbar type BOTH -@ s3 errorbar length 1.000000 -@ s3 errorbar linewidth 1 -@ s3 errorbar linestyle 1 -@ s3 errorbar riser on -@ s3 errorbar riser linewidth 1 -@ s3 errorbar riser linestyle 1 -@ s3 xyz 0.000000, 0.000000 -@ s3 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cse2s.dat" -@ xaxis tick on -@ xaxis tick major 1 -@ xaxis tick minor 1 -@ xaxis tick offsetx 0.000000 -@ xaxis tick offsety 0.000000 +@ xaxes scale Logarithmic +@ yaxes scale Normal +@ xaxes invert off +@ yaxes invert off +@ xaxis on +@ xaxis type zero false +@ xaxis offset 0.000000 , 0.000000 +@ xaxis bar off +@ xaxis bar color 1 +@ xaxis bar linestyle 1 +@ xaxis bar linewidth 1.0 @ xaxis label "E (MeV)" @ xaxis label layout para @ xaxis label place auto @ xaxis label char size 1.490000 @ xaxis label font 4 @ xaxis label color 1 -@ xaxis label linewidth 1 +@ xaxis label place normal +@ xaxis tick on +@ xaxis tick major 10 +@ xaxis tick minor ticks 0 +@ xaxis tick default 6 +@ xaxis tick place rounded true +@ xaxis tick in +@ xaxis tick major size 1.000000 +@ xaxis tick major color 1 +@ xaxis tick major linewidth 1.0 +@ xaxis tick major linestyle 1 +@ xaxis tick major grid off +@ xaxis tick minor color 1 +@ xaxis tick minor linewidth 1.0 +@ xaxis tick minor linestyle 1 +@ xaxis tick minor grid off +@ xaxis tick minor size 0.500000 @ xaxis ticklabel on -@ xaxis ticklabel type auto -@ xaxis ticklabel prec 0 @ xaxis ticklabel format power +@ xaxis ticklabel prec 0 +@ xaxis ticklabel formula "" @ xaxis ticklabel append "" @ xaxis ticklabel prepend "" -@ xaxis ticklabel layout horizontal -@ xaxis ticklabel place on ticks +@ xaxis ticklabel angle 0 @ xaxis ticklabel skip 0 @ xaxis ticklabel stagger 0 -@ xaxis ticklabel op bottom -@ xaxis ticklabel sign normal +@ xaxis ticklabel place normal +@ xaxis ticklabel offset auto +@ xaxis ticklabel offset 0.000000 , 0.010000 @ xaxis ticklabel start type auto @ xaxis ticklabel start 0.000000 @ xaxis ticklabel stop type auto @@ -206,53 +182,50 @@ @ xaxis ticklabel char size 1.000000 @ xaxis ticklabel font 4 @ xaxis ticklabel color 1 -@ xaxis ticklabel linewidth 1 -@ xaxis tick major on -@ xaxis tick minor on -@ xaxis tick default 6 -@ xaxis tick in -@ xaxis tick major color 1 -@ xaxis tick major linewidth 1 -@ xaxis tick major linestyle 1 -@ xaxis tick minor color 1 -@ xaxis tick minor linewidth 1 -@ xaxis tick minor linestyle 1 -@ xaxis tick log off -@ xaxis tick size 1.000000 -@ xaxis tick minor size 0.500000 -@ xaxis bar off -@ xaxis bar color 1 -@ xaxis bar linestyle 1 -@ xaxis bar linewidth 1 -@ xaxis tick major grid off -@ xaxis tick minor grid off -@ xaxis tick op both -@ xaxis tick type auto -@ xaxis tick spec 0 -@ yaxis tick on -@ yaxis tick major 50 -@ yaxis tick minor 10 -@ yaxis tick offsetx 0.000000 -@ yaxis tick offsety 0.000000 +@ xaxis tick place both +@ xaxis tick spec type none +@ yaxis on +@ yaxis type zero false +@ yaxis offset 0.000000 , 0.000000 +@ yaxis bar off +@ yaxis bar color 1 +@ yaxis bar linestyle 1 +@ yaxis bar linewidth 1.0 @ yaxis label "\8S\4\sE\N (MeV\S-1\N)" @ yaxis label layout para @ yaxis label place auto @ yaxis label char size 1.500000 @ yaxis label font 4 @ yaxis label color 1 -@ yaxis label linewidth 1 +@ yaxis label place normal +@ yaxis tick on +@ yaxis tick major 50 +@ yaxis tick minor ticks 4 +@ yaxis tick default 6 +@ yaxis tick place rounded true +@ yaxis tick in +@ yaxis tick major size 1.000000 +@ yaxis tick major color 1 +@ yaxis tick major linewidth 1.0 +@ yaxis tick major linestyle 1 +@ yaxis tick major grid off +@ yaxis tick minor color 1 +@ yaxis tick minor linewidth 1.0 +@ yaxis tick minor linestyle 1 +@ yaxis tick minor grid off +@ yaxis tick minor size 0.500000 @ yaxis ticklabel on -@ yaxis ticklabel type auto -@ yaxis ticklabel prec 5 @ yaxis ticklabel format general +@ yaxis ticklabel prec 5 +@ yaxis ticklabel formula "" @ yaxis ticklabel append "" @ yaxis ticklabel prepend "" -@ yaxis ticklabel layout horizontal -@ yaxis ticklabel place on ticks +@ yaxis ticklabel angle 0 @ yaxis ticklabel skip 0 @ yaxis ticklabel stagger 0 -@ yaxis ticklabel op left -@ yaxis ticklabel sign normal +@ yaxis ticklabel place normal +@ yaxis ticklabel offset auto +@ yaxis ticklabel offset 0.000000 , 0.010000 @ yaxis ticklabel start type auto @ yaxis ticklabel start 0.000000 @ yaxis ticklabel stop type auto @@ -260,982 +233,1042 @@ @ yaxis ticklabel char size 1.000000 @ yaxis ticklabel font 4 @ yaxis ticklabel color 1 -@ yaxis ticklabel linewidth 1 -@ yaxis tick major on -@ yaxis tick minor on -@ yaxis tick default 6 -@ yaxis tick in -@ yaxis tick major color 1 -@ yaxis tick major linewidth 1 -@ yaxis tick major linestyle 1 -@ yaxis tick minor color 1 -@ yaxis tick minor linewidth 1 -@ yaxis tick minor linestyle 1 -@ yaxis tick log off -@ yaxis tick size 1.000000 -@ yaxis tick minor size 0.500000 -@ yaxis bar off -@ yaxis bar color 1 -@ yaxis bar linestyle 1 -@ yaxis bar linewidth 1 -@ yaxis tick major grid off -@ yaxis tick minor grid off -@ yaxis tick op both -@ yaxis tick type auto -@ yaxis tick spec 0 -@ zeroxaxis tick on -@ zeroxaxis tick major 1 -@ zeroxaxis tick minor 1 -@ zeroxaxis tick offsetx 0.000000 -@ zeroxaxis tick offsety 0.000000 -@ zeroxaxis label "" -@ zeroxaxis label layout para -@ zeroxaxis label place auto -@ zeroxaxis label char size 1.000000 -@ zeroxaxis label font 4 -@ zeroxaxis label color 1 -@ zeroxaxis label linewidth 1 -@ zeroxaxis ticklabel off -@ zeroxaxis ticklabel type auto -@ zeroxaxis ticklabel prec 0 -@ zeroxaxis ticklabel format decimal -@ zeroxaxis ticklabel append "" -@ zeroxaxis ticklabel prepend "" -@ zeroxaxis ticklabel layout horizontal -@ zeroxaxis ticklabel place on ticks -@ zeroxaxis ticklabel skip 0 -@ zeroxaxis ticklabel stagger 0 -@ zeroxaxis ticklabel op bottom -@ zeroxaxis ticklabel sign normal -@ zeroxaxis ticklabel start type auto -@ zeroxaxis ticklabel start 0.000000 -@ zeroxaxis ticklabel stop type auto -@ zeroxaxis ticklabel stop 0.000000 -@ zeroxaxis ticklabel char size 1.000000 -@ zeroxaxis ticklabel font 4 -@ zeroxaxis ticklabel color 1 -@ zeroxaxis ticklabel linewidth 1 -@ zeroxaxis tick major off -@ zeroxaxis tick minor on -@ zeroxaxis tick default 6 -@ zeroxaxis tick in -@ zeroxaxis tick major color 1 -@ zeroxaxis tick major linewidth 1 -@ zeroxaxis tick major linestyle 1 -@ zeroxaxis tick minor color 1 -@ zeroxaxis tick minor linewidth 1 -@ zeroxaxis tick minor linestyle 1 -@ zeroxaxis tick log off -@ zeroxaxis tick size 1.000000 -@ zeroxaxis tick minor size 0.500000 -@ zeroxaxis bar off -@ zeroxaxis bar color 1 -@ zeroxaxis bar linestyle 1 -@ zeroxaxis bar linewidth 1 -@ zeroxaxis tick major grid off -@ zeroxaxis tick minor grid off -@ zeroxaxis tick op both -@ zeroxaxis tick type auto -@ zeroxaxis tick spec 0 -@ zeroyaxis tick on -@ zeroyaxis tick major 2 -@ zeroyaxis tick minor 1 -@ zeroyaxis tick offsetx 0.000000 -@ zeroyaxis tick offsety 0.000000 -@ zeroyaxis label "" -@ zeroyaxis label layout para -@ zeroyaxis label place auto -@ zeroyaxis label char size 1.000000 -@ zeroyaxis label font 4 -@ zeroyaxis label color 1 -@ zeroyaxis label linewidth 1 -@ zeroyaxis ticklabel off -@ zeroyaxis ticklabel type auto -@ zeroyaxis ticklabel prec 5 -@ zeroyaxis ticklabel format general -@ zeroyaxis ticklabel append "" -@ zeroyaxis ticklabel prepend "" -@ zeroyaxis ticklabel layout horizontal -@ zeroyaxis ticklabel place on ticks -@ zeroyaxis ticklabel skip 0 -@ zeroyaxis ticklabel stagger 0 -@ zeroyaxis ticklabel op left -@ zeroyaxis ticklabel sign normal -@ zeroyaxis ticklabel start type auto -@ zeroyaxis ticklabel start 0.000000 -@ zeroyaxis ticklabel stop type auto -@ zeroyaxis ticklabel stop 0.000000 -@ zeroyaxis ticklabel char size 1.000000 -@ zeroyaxis ticklabel font 4 -@ zeroyaxis ticklabel color 1 -@ zeroyaxis ticklabel linewidth 1 -@ zeroyaxis tick major off -@ zeroyaxis tick minor on -@ zeroyaxis tick default 6 -@ zeroyaxis tick in -@ zeroyaxis tick major color 1 -@ zeroyaxis tick major linewidth 1 -@ zeroyaxis tick major linestyle 1 -@ zeroyaxis tick minor color 1 -@ zeroyaxis tick minor linewidth 1 -@ zeroyaxis tick minor linestyle 1 -@ zeroyaxis tick log off -@ zeroyaxis tick size 1.000000 -@ zeroyaxis tick minor size 0.500000 -@ zeroyaxis bar off -@ zeroyaxis bar color 1 -@ zeroyaxis bar linestyle 1 -@ zeroyaxis bar linewidth 1 -@ zeroyaxis tick major grid off -@ zeroyaxis tick minor grid off -@ zeroyaxis tick op both -@ zeroyaxis tick type auto -@ zeroyaxis tick spec 0 +@ yaxis tick place both +@ yaxis tick spec type none +@ altxaxis off +@ altyaxis off @ legend on @ legend loctype view -@ legend layout 0 -@ legend vgap 2 -@ legend hgap 1 -@ legend length 4 -@ legend box off -@ legend box fill off -@ legend box fill with color -@ legend box fill color 0 -@ legend box fill pattern 1 +@ legend 0.55, 0.3 @ legend box color 1 -@ legend box linewidth 1 +@ legend box pattern 0 +@ legend box linewidth 1.0 @ legend box linestyle 1 -@ legend x1 0.395604 -@ legend y1 0.252059 +@ legend box fill color 0 +@ legend box fill pattern 1 @ legend font 4 @ legend char size 1.000000 -@ legend linestyle 1 -@ legend linewidth 1 @ legend color 1 -@ legend string 0 "T\sc\N = k\sc\N = 1 keV" -@ legend string 2 "T\sc\N = k\sc\N = 10 keV (times 14)" -@ frame on +@ legend length 4 +@ legend vgap 1 +@ legend hgap 1 +@ legend invert false @ frame type 0 @ frame linestyle 1 -@ frame linewidth 1 +@ frame linewidth 1.0 @ frame color 1 -@ frame fill off +@ frame pattern 1 @ frame background color 0 -@WITH G0 -@G0 ON -@TARGET S0 -@TYPE xy - 0.001 0.00219221 - 0.00104084 0.0132213 - 0.00108336 0.0248731 - 0.0011276 0.035298 - 0.00117366 0.0447967 - 0.0012216 0.0535773 - 0.00127149 0.0619394 - 0.00132343 0.0700684 - 0.00137748 0.0779561 - 0.00143374 0.0856154 - 0.0014923 0.0931584 - 0.00155325 0.100754 - 0.00161669 0.108352 - 0.00168273 0.115926 - 0.00175145 0.123566 - 0.00182299 0.131276 - 0.00189745 0.139095 - 0.00197495 0.146982 - 0.00205561 14.8701 - 0.00213957 30.2881 - 0.00222696 43.8683 - 0.00231792 55.4021 - 0.00241259 65.4277 - 0.00251113 74.4878 - 0.0026137 82.678 - 0.00272045 89.7714 - 0.00283156 96.1748 - 0.00294722 102.087 - 0.00306759 107.541 - 0.00319289 112.338 - 0.0033233 116.804 - 0.00345903 120.983 - 0.00360031 124.88 - 0.00374736 128.353 - 0.00390042 131.641 - 0.00405973 134.746 - 0.00422555 137.635 - 0.00439814 140.269 - 0.00457777 142.766 - 0.00476475 145.135 - 0.00495936 147.329 - 0.00516192 149.35 - 0.00537275 151.269 - 0.0055922 153.089 - 0.0058206 154.759 - 0.00605834 156.311 - 0.00630579 157.785 - 0.00656334 159.177 - 0.00683141 160.435 - 0.00711044 161.607 - 0.00740085 162.716 - 0.00770313 163.759 - 0.00801776 164.68 - 0.00834524 165.542 - 0.00868609 166.351 - 0.00904087 167.095 - 0.00941013 167.747 - 0.00979448 168.352 - 0.0101945 168.909 - 0.0106109 169.406 - 0.0110443 169.834 - 0.0114954 170.222 - 0.0119649 170.567 - 0.0124536 170.855 - 0.0129623 171.092 - 0.0134917 171.299 - 0.0140427 171.467 - 0.0146163 171.584 - 0.0152133 171.665 - 0.0158347 171.716 - 0.0164814 171.736 - 0.0171546 171.712 - 0.0178552 171.66 - 0.0185845 171.586 - 0.0193436 171.482 - 0.0201337 171.343 - 0.020956 171.188 - 0.0218119 171.007 - 0.0227028 170.802 - 0.0236301 170.57 - 0.0245952 170.319 - 0.0255998 170.051 - 0.0266454 169.767 - 0.0277337 169.465 - 0.0288665 169.142 - 0.0300455 168.804 - 0.0312727 168.456 - 0.03255 168.095 - 0.0338794 167.717 - 0.0352632 167.323 - 0.0367035 166.926 - 0.0382026 166.518 - 0.039763 166.098 - 0.041387 165.667 - 0.0430774 165.232 - 0.0448369 164.788 - 0.0466682 164.334 - 0.0485743 163.873 - 0.0505583 163.411 - 0.0526233 162.939 - 0.0547726 162.466 - 0.0570098 161.986 - 0.0593383 161.505 - 0.0617619 161.021 - 0.0642845 160.53 - 0.0669101 160.038 - 0.069643 159.545 - 0.0724875 159.049 - 0.0754482 158.549 - 0.0785298 158.05 - 0.0817373 157.553 - 0.0850757 157.055 - 0.0885506 156.548 - 0.0921673 156.052 - 0.0959318 155.554 - 0.0998501 155.055 - 0.103928 154.557 - 0.108173 154.068 - 0.112591 153.573 - 0.11719 153.075 - 0.121977 152.572 - 0.126959 152.082 - 0.132144 151.591 - 0.137541 151.099 - 0.143159 150.606 - 0.149006 150.115 - 0.155092 149.624 - 0.161427 149.132 - 0.16802 148.641 - 0.174883 148.151 - 0.182026 147.658 - 0.18946 147.163 - 0.197198 146.669 - 0.205253 146.177 - 0.213636 145.682 - 0.222362 145.182 - 0.231444 144.682 - 0.240897 144.178 - 0.250736 143.67 - 0.260977 143.162 - 0.271637 142.655 - 0.282731 142.141 - 0.294279 141.623 - 0.306299 141.103 - 0.318809 140.584 - 0.33183 140.059 - 0.345384 139.529 - 0.35949 138.999 - 0.374173 138.465 - 0.389456 137.927 - 0.405363 137.384 - 0.42192 136.841 - 0.439153 136.293 - 0.457089 135.741 - 0.475759 135.187 - 0.49519 134.629 - 0.515416 134.069 - 0.536468 133.505 - 0.558379 132.938 - 0.581185 132.37 - 0.604923 131.799 - 0.629631 131.225 - 0.655347 130.649 - 0.682114 130.07 - 0.709975 129.49 - 0.738973 128.908 - 0.769155 128.326 - 0.800571 127.742 - 0.833269 127.159 - 0.867303 126.574 - 0.902727 125.989 - 0.939598 125.406 - 0.977975 124.823 - 1.01792 124.241 - 1.05949 123.663 - 1.10277 123.086 - 1.14781 122.51 - 1.19469 121.936 - 1.24349 121.364 - 1.29428 120.796 - 1.34714 120.232 - 1.40216 119.671 - 1.45943 119.115 - 1.51904 118.561 - 1.58108 118.013 - 1.64566 117.469 - 1.71288 116.931 - 1.78284 116.397 - 1.85566 115.865 - 1.93145 115.341 - 2.01034 114.82 - 2.09245 114.303 - 2.17791 113.79 - 2.26686 113.286 - 2.35945 112.791 - 2.45582 112.301 - 2.55613 111.815 - 2.66053 111.328 - 2.76919 110.852 - 2.8823 110.384 - 3.00002 109.927 +@ frame background pattern 0 +@ s0 hidden false +@ s0 type xy +@ s0 symbol 0 +@ s0 symbol size 1.000000 +@ s0 symbol color 1 +@ s0 symbol pattern 1 +@ s0 symbol fill color 1 +@ s0 symbol fill pattern 0 +@ s0 symbol linewidth 1.0 +@ s0 symbol linestyle 1 +@ s0 symbol char 0 +@ s0 symbol char font 4 +@ s0 symbol skip 0 +@ s0 line type 1 +@ s0 line linestyle 1 +@ s0 line linewidth 1.0 +@ s0 line color 1 +@ s0 line pattern 1 +@ s0 baseline type 0 +@ s0 baseline off +@ s0 dropline off +@ s0 fill type 0 +@ s0 fill rule 0 +@ s0 fill color 1 +@ s0 fill pattern 1 +@ s0 avalue off +@ s0 avalue type 2 +@ s0 avalue char size 1.000000 +@ s0 avalue font 4 +@ s0 avalue color 1 +@ s0 avalue rot 0 +@ s0 avalue format general +@ s0 avalue prec 3 +@ s0 avalue prepend "" +@ s0 avalue append "" +@ s0 avalue offset 0.000000 , 0.000000 +@ s0 errorbar on +@ s0 errorbar place both +@ s0 errorbar color 1 +@ s0 errorbar pattern 1 +@ s0 errorbar size 2.000000 +@ s0 errorbar linewidth 1.0 +@ s0 errorbar linestyle 1 +@ s0 errorbar riser linewidth 1.0 +@ s0 errorbar riser linestyle 1 +@ s0 errorbar riser clip off +@ s0 errorbar riser clip length 0.100000 +@ s0 comment "/a/irs29/home/irs29b6/iwan/photong/rad_yields/au512.out:2" +@ s0 legend "T\sc\N = k\sc\N = 1 keV" +@ s1 hidden false +@ s1 type xy +@ s1 symbol 0 +@ s1 symbol size 1.000000 +@ s1 symbol color 1 +@ s1 symbol pattern 1 +@ s1 symbol fill color 1 +@ s1 symbol fill pattern 0 +@ s1 symbol linewidth 1.0 +@ s1 symbol linestyle 1 +@ s1 symbol char 0 +@ s1 symbol char font 4 +@ s1 symbol skip 0 +@ s1 line type 1 +@ s1 line linestyle 1 +@ s1 line linewidth 1.0 +@ s1 line color 1 +@ s1 line pattern 1 +@ s1 baseline type 0 +@ s1 baseline off +@ s1 dropline off +@ s1 fill type 0 +@ s1 fill rule 0 +@ s1 fill color 1 +@ s1 fill pattern 1 +@ s1 avalue off +@ s1 avalue type 2 +@ s1 avalue char size 1.000000 +@ s1 avalue font 4 +@ s1 avalue color 1 +@ s1 avalue rot 0 +@ s1 avalue format general +@ s1 avalue prec 3 +@ s1 avalue prepend "" +@ s1 avalue append "" +@ s1 avalue offset 0.000000 , 0.000000 +@ s1 errorbar on +@ s1 errorbar place both +@ s1 errorbar color 1 +@ s1 errorbar pattern 1 +@ s1 errorbar size 2.000000 +@ s1 errorbar linewidth 1.0 +@ s1 errorbar linestyle 1 +@ s1 errorbar riser linewidth 1.0 +@ s1 errorbar riser linestyle 1 +@ s1 errorbar riser clip off +@ s1 errorbar riser clip length 0.100000 +@ s1 comment "/a/irs29/home/irs29b6/iwan/photong/rad_yields/c512.out:2" +@ s1 legend "" +@ s2 hidden false +@ s2 type xy +@ s2 symbol 0 +@ s2 symbol size 1.000000 +@ s2 symbol color 1 +@ s2 symbol pattern 1 +@ s2 symbol fill color 1 +@ s2 symbol fill pattern 0 +@ s2 symbol linewidth 1.0 +@ s2 symbol linestyle 1 +@ s2 symbol char 0 +@ s2 symbol char font 4 +@ s2 symbol skip 0 +@ s2 line type 1 +@ s2 line linestyle 3 +@ s2 line linewidth 1.0 +@ s2 line color 1 +@ s2 line pattern 1 +@ s2 baseline type 0 +@ s2 baseline off +@ s2 dropline off +@ s2 fill type 0 +@ s2 fill rule 0 +@ s2 fill color 1 +@ s2 fill pattern 1 +@ s2 avalue off +@ s2 avalue type 2 +@ s2 avalue char size 1.000000 +@ s2 avalue font 4 +@ s2 avalue color 1 +@ s2 avalue rot 0 +@ s2 avalue format general +@ s2 avalue prec 3 +@ s2 avalue prepend "" +@ s2 avalue append "" +@ s2 avalue offset 0.000000 , 0.000000 +@ s2 errorbar on +@ s2 errorbar place both +@ s2 errorbar color 1 +@ s2 errorbar pattern 1 +@ s2 errorbar size 2.000000 +@ s2 errorbar linewidth 1.0 +@ s2 errorbar linestyle 1 +@ s2 errorbar riser linewidth 1.0 +@ s2 errorbar riser linestyle 1 +@ s2 errorbar riser clip off +@ s2 errorbar riser clip length 0.100000 +@ s2 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cse2s.dat" +@ s2 legend "T\sc\N = k\sc\N = 10 keV (times 14)" +@ s3 hidden false +@ s3 type xy +@ s3 symbol 0 +@ s3 symbol size 1.000000 +@ s3 symbol color 1 +@ s3 symbol pattern 1 +@ s3 symbol fill color 1 +@ s3 symbol fill pattern 0 +@ s3 symbol linewidth 1.0 +@ s3 symbol linestyle 1 +@ s3 symbol char 0 +@ s3 symbol char font 4 +@ s3 symbol skip 0 +@ s3 line type 1 +@ s3 line linestyle 3 +@ s3 line linewidth 1.0 +@ s3 line color 1 +@ s3 line pattern 1 +@ s3 baseline type 0 +@ s3 baseline off +@ s3 dropline off +@ s3 fill type 0 +@ s3 fill rule 0 +@ s3 fill color 1 +@ s3 fill pattern 1 +@ s3 avalue off +@ s3 avalue type 2 +@ s3 avalue char size 1.000000 +@ s3 avalue font 4 +@ s3 avalue color 1 +@ s3 avalue rot 0 +@ s3 avalue format general +@ s3 avalue prec 3 +@ s3 avalue prepend "" +@ s3 avalue append "" +@ s3 avalue offset 0.000000 , 0.000000 +@ s3 errorbar on +@ s3 errorbar place both +@ s3 errorbar color 1 +@ s3 errorbar pattern 1 +@ s3 errorbar size 2.000000 +@ s3 errorbar linewidth 1.0 +@ s3 errorbar linestyle 1 +@ s3 errorbar riser linewidth 1.0 +@ s3 errorbar riser linestyle 1 +@ s3 errorbar riser clip off +@ s3 errorbar riser clip length 0.100000 +@ s3 comment "/a/irs29/home/irs29b6/iwan_scr/tex/papers/ionc/figures/cse2s.dat" +@ s3 legend "" +@target G0.S0 +@type xy +0.001 0.00219221 +0.00104084 0.0132213 +0.00108336 0.0248731 +0.0011276 0.035298 +0.00117366 0.0447967 +0.0012216 0.0535773 +0.00127149 0.0619394 +0.00132343 0.0700684 +0.00137748 0.0779561 +0.00143374 0.0856154 +0.0014923 0.0931584 +0.00155325 0.100754 +0.00161669 0.108352 +0.00168273 0.115926 +0.00175145 0.123566 +0.00182299 0.131276 +0.00189745 0.139095 +0.00197495 0.146982 +0.00205561 14.8701 +0.00213957 30.2881 +0.00222696 43.8683 +0.00231792 55.4021 +0.00241259 65.4277 +0.00251113 74.4878 +0.0026137 82.678 +0.00272045 89.7714 +0.00283156 96.1748 +0.00294722 102.087 +0.00306759 107.541 +0.00319289 112.338 +0.0033233 116.804 +0.00345903 120.983 +0.00360031 124.88 +0.00374736 128.353 +0.00390042 131.641 +0.00405973 134.746 +0.00422555 137.635 +0.00439814 140.269 +0.00457777 142.766 +0.00476475 145.135 +0.00495936 147.329 +0.00516192 149.35 +0.00537275 151.269 +0.0055922 153.089 +0.0058206 154.759 +0.00605834 156.311 +0.00630579 157.785 +0.00656334 159.177 +0.00683141 160.435 +0.00711044 161.607 +0.00740085 162.716 +0.00770313 163.759 +0.00801776 164.68 +0.00834524 165.542 +0.00868609 166.351 +0.00904087 167.095 +0.00941013 167.747 +0.00979448 168.352 +0.0101945 168.909 +0.0106109 169.406 +0.0110443 169.834 +0.0114954 170.222 +0.0119649 170.567 +0.0124536 170.855 +0.0129623 171.092 +0.0134917 171.299 +0.0140427 171.467 +0.0146163 171.584 +0.0152133 171.665 +0.0158347 171.716 +0.0164814 171.736 +0.0171546 171.712 +0.0178552 171.66 +0.0185845 171.586 +0.0193436 171.482 +0.0201337 171.343 +0.020956 171.188 +0.0218119 171.007 +0.0227028 170.802 +0.0236301 170.57 +0.0245952 170.319 +0.0255998 170.051 +0.0266454 169.767 +0.0277337 169.465 +0.0288665 169.142 +0.0300455 168.804 +0.0312727 168.456 +0.03255 168.095 +0.0338794 167.717 +0.0352632 167.323 +0.0367035 166.926 +0.0382026 166.518 +0.039763 166.098 +0.041387 165.667 +0.0430774 165.232 +0.0448369 164.788 +0.0466682 164.334 +0.0485743 163.873 +0.0505583 163.411 +0.0526233 162.939 +0.0547726 162.466 +0.0570098 161.986 +0.0593383 161.505 +0.0617619 161.021 +0.0642845 160.53 +0.0669101 160.038 +0.069643 159.545 +0.0724875 159.049 +0.0754482 158.549 +0.0785298 158.05 +0.0817373 157.553 +0.0850757 157.055 +0.0885506 156.548 +0.0921673 156.052 +0.0959318 155.554 +0.0998501 155.055 +0.103928 154.557 +0.108173 154.068 +0.112591 153.573 +0.11719 153.075 +0.121977 152.572 +0.126959 152.082 +0.132144 151.591 +0.137541 151.099 +0.143159 150.606 +0.149006 150.115 +0.155092 149.624 +0.161427 149.132 +0.16802 148.641 +0.174883 148.151 +0.182026 147.658 +0.18946 147.163 +0.197198 146.669 +0.205253 146.177 +0.213636 145.682 +0.222362 145.182 +0.231444 144.682 +0.240897 144.178 +0.250736 143.67 +0.260977 143.162 +0.271637 142.655 +0.282731 142.141 +0.294279 141.623 +0.306299 141.103 +0.318809 140.584 +0.33183 140.059 +0.345384 139.529 +0.35949 138.999 +0.374173 138.465 +0.389456 137.927 +0.405363 137.384 +0.42192 136.841 +0.439153 136.293 +0.457089 135.741 +0.475759 135.187 +0.49519 134.629 +0.515416 134.069 +0.536468 133.505 +0.558379 132.938 +0.581185 132.37 +0.604923 131.799 +0.629631 131.225 +0.655347 130.649 +0.682114 130.07 +0.709975 129.49 +0.738973 128.908 +0.769155 128.326 +0.800571 127.742 +0.833269 127.159 +0.867303 126.574 +0.902727 125.989 +0.939598 125.406 +0.977975 124.823 +1.01792 124.241 +1.05949 123.663 +1.10277 123.086 +1.14781 122.51 +1.19469 121.936 +1.24349 121.364 +1.29428 120.796 +1.34714 120.232 +1.40216 119.671 +1.45943 119.115 +1.51904 118.561 +1.58108 118.013 +1.64566 117.469 +1.71288 116.931 +1.78284 116.397 +1.85566 115.865 +1.93145 115.341 +2.01034 114.82 +2.09245 114.303 +2.17791 113.79 +2.26686 113.286 +2.35945 112.791 +2.45582 112.301 +2.55613 111.815 +2.66053 111.328 +2.76919 110.852 +2.8823 110.384 +3.00002 109.927 & -@TARGET S1 -@TYPE xy - 0.001 0.000141949 - 0.00104084 0.00092631 - 0.00108336 0.00184888 - 0.0011276 0.00275704 - 0.00117366 0.0036566 - 0.0012216 0.00454583 - 0.00127149 0.00541524 - 0.00132343 0.00628677 - 0.00137748 0.00715311 - 0.00143374 0.00800352 - 0.0014923 0.0088074 - 0.00155325 0.00963423 - 0.00161669 0.010464 - 0.00168273 0.0112653 - 0.00175145 0.0120323 - 0.00182299 0.0128129 - 0.00189745 0.0135939 - 0.00197495 0.014328 - 0.00205561 4.72492 - 0.00213957 9.78602 - 0.00222696 14.3851 - 0.00231792 18.424 - 0.00241259 22.0546 - 0.00251113 25.4521 - 0.0026137 28.6334 - 0.00272045 31.4939 - 0.00283156 34.1682 - 0.00294722 36.7191 - 0.00306759 39.1557 - 0.00319289 41.378 - 0.0033233 43.5126 - 0.00345903 45.5743 - 0.00360031 47.5568 - 0.00374736 49.3848 - 0.00390042 51.1638 - 0.00405973 52.8929 - 0.00422555 54.5513 - 0.00439814 56.1103 - 0.00457777 57.6289 - 0.00476475 59.1084 - 0.00495936 60.5203 - 0.00516192 61.8606 - 0.00537275 63.1694 - 0.0055922 64.4459 - 0.0058206 65.6531 - 0.00605834 66.8075 - 0.00630579 67.936 - 0.00656334 69.035 - 0.00683141 70.0655 - 0.00711044 71.061 - 0.00740085 72.031 - 0.00770313 72.975 - 0.00801776 73.849 - 0.00834524 74.7004 - 0.00868609 75.5278 - 0.00904087 76.3256 - 0.00941013 77.0677 - 0.00979448 77.7898 - 0.0101945 78.4901 - 0.0106109 79.157 - 0.0110443 79.7811 - 0.0114954 80.3867 - 0.0119649 80.9698 - 0.0124536 81.5199 - 0.0129623 82.0405 - 0.0134917 82.541 - 0.0140427 83.0238 - 0.0146163 83.4709 - 0.0152133 83.8948 - 0.0158347 84.3029 - 0.0164814 84.6952 - 0.0171546 85.0515 - 0.0178552 85.3909 - 0.0185845 85.7166 - 0.0193436 86.0258 - 0.0201337 86.303 - 0.020956 86.569 - 0.0218119 86.82 - 0.0227028 87.0554 - 0.0236301 87.268 - 0.0245952 87.4667 - 0.0255998 87.6555 - 0.0266454 87.827 - 0.0277337 87.9818 - 0.0288665 88.1239 - 0.0300455 88.2558 - 0.0312727 88.3725 - 0.03255 88.4762 - 0.0338794 88.5701 - 0.0352632 88.6547 - 0.0367035 88.7246 - 0.0382026 88.7853 - 0.039763 88.8363 - 0.041387 88.8792 - 0.0430774 88.9096 - 0.0448369 88.9334 - 0.0466682 88.9491 - 0.0485743 88.9571 - 0.0505583 88.9564 - 0.0526233 88.9474 - 0.0547726 88.9326 - 0.0570098 88.911 - 0.0593383 88.881 - 0.0617619 88.8482 - 0.0642845 88.8074 - 0.0669101 88.7614 - 0.069643 88.709 - 0.0724875 88.6551 - 0.0754482 88.5947 - 0.0785298 88.5288 - 0.0817373 88.458 - 0.0850757 88.3841 - 0.0885506 88.306 - 0.0921673 88.2247 - 0.0959318 88.1398 - 0.0998501 88.052 - 0.103928 87.9609 - 0.108173 87.8674 - 0.112591 87.7707 - 0.11719 87.6704 - 0.121977 87.5671 - 0.126959 87.463 - 0.132144 87.3565 - 0.137541 87.2479 - 0.143159 87.1366 - 0.149006 87.0233 - 0.155092 86.9083 - 0.161427 86.7925 - 0.16802 86.6744 - 0.174883 86.5552 - 0.182026 86.4343 - 0.18946 86.3113 - 0.197198 86.1876 - 0.205253 86.0639 - 0.213636 85.9388 - 0.222362 85.8111 - 0.231444 85.6831 - 0.240897 85.5531 - 0.250736 85.4218 - 0.260977 85.2904 - 0.271637 85.159 - 0.282731 85.0254 - 0.294279 84.8907 - 0.306299 84.7552 - 0.318809 84.6199 - 0.33183 84.4834 - 0.345384 84.3454 - 0.35949 84.2072 - 0.374173 84.0687 - 0.389456 83.9289 - 0.405363 83.7881 - 0.42192 83.6476 - 0.439153 83.5065 - 0.457089 83.3643 - 0.475759 83.2214 - 0.49519 83.0789 - 0.515416 82.9359 - 0.536468 82.7921 - 0.558379 82.6476 - 0.581185 82.5034 - 0.604923 82.3585 - 0.629631 82.2128 - 0.655347 82.0669 - 0.682114 81.9223 - 0.709975 81.7766 - 0.738973 81.63 - 0.769155 81.4843 - 0.800571 81.339 - 0.833269 81.1931 - 0.867303 81.0468 - 0.902727 80.9021 - 0.939598 80.7564 - 0.977975 80.6103 - 1.01792 80.4637 - 1.05949 80.3135 - 1.10277 80.1664 - 1.14781 80.022 - 1.19469 79.8803 - 1.24349 79.7417 - 1.29428 79.5964 - 1.34714 79.4498 - 1.40216 79.3069 - 1.45943 79.1704 - 1.51904 79.0286 - 1.58108 78.8843 - 1.64566 78.7418 - 1.71288 78.6064 - 1.78284 78.4661 - 1.85566 78.3229 - 1.93145 78.1854 - 2.01034 78.0443 - 2.09245 77.8991 - 2.17791 77.752 - 2.26686 77.6129 - 2.35945 77.4813 - 2.45582 77.3513 - 2.55613 77.2195 - 2.66053 77.0764 - 2.76919 76.9404 - 2.8823 76.8122 - 3.00002 76.6909 +@target G0.S1 +@type xy +0.001 0.000141949 +0.00104084 0.00092631 +0.00108336 0.00184888 +0.0011276 0.00275704 +0.00117366 0.0036566 +0.0012216 0.00454583 +0.00127149 0.00541524 +0.00132343 0.00628677 +0.00137748 0.00715311 +0.00143374 0.00800352 +0.0014923 0.0088074 +0.00155325 0.00963423 +0.00161669 0.010464 +0.00168273 0.0112653 +0.00175145 0.0120323 +0.00182299 0.0128129 +0.00189745 0.0135939 +0.00197495 0.014328 +0.00205561 4.72492 +0.00213957 9.78602 +0.00222696 14.3851 +0.00231792 18.424 +0.00241259 22.0546 +0.00251113 25.4521 +0.0026137 28.6334 +0.00272045 31.4939 +0.00283156 34.1682 +0.00294722 36.7191 +0.00306759 39.1557 +0.00319289 41.378 +0.0033233 43.5126 +0.00345903 45.5743 +0.00360031 47.5568 +0.00374736 49.3848 +0.00390042 51.1638 +0.00405973 52.8929 +0.00422555 54.5513 +0.00439814 56.1103 +0.00457777 57.6289 +0.00476475 59.1084 +0.00495936 60.5203 +0.00516192 61.8606 +0.00537275 63.1694 +0.0055922 64.4459 +0.0058206 65.6531 +0.00605834 66.8075 +0.00630579 67.936 +0.00656334 69.035 +0.00683141 70.0655 +0.00711044 71.061 +0.00740085 72.031 +0.00770313 72.975 +0.00801776 73.849 +0.00834524 74.7004 +0.00868609 75.5278 +0.00904087 76.3256 +0.00941013 77.0677 +0.00979448 77.7898 +0.0101945 78.4901 +0.0106109 79.157 +0.0110443 79.7811 +0.0114954 80.3867 +0.0119649 80.9698 +0.0124536 81.5199 +0.0129623 82.0405 +0.0134917 82.541 +0.0140427 83.0238 +0.0146163 83.4709 +0.0152133 83.8948 +0.0158347 84.3029 +0.0164814 84.6952 +0.0171546 85.0515 +0.0178552 85.3909 +0.0185845 85.7166 +0.0193436 86.0258 +0.0201337 86.303 +0.020956 86.569 +0.0218119 86.82 +0.0227028 87.0554 +0.0236301 87.268 +0.0245952 87.4667 +0.0255998 87.6555 +0.0266454 87.827 +0.0277337 87.9818 +0.0288665 88.1239 +0.0300455 88.2558 +0.0312727 88.3725 +0.03255 88.4762 +0.0338794 88.5701 +0.0352632 88.6547 +0.0367035 88.7246 +0.0382026 88.7853 +0.039763 88.8363 +0.041387 88.8792 +0.0430774 88.9096 +0.0448369 88.9334 +0.0466682 88.9491 +0.0485743 88.9571 +0.0505583 88.9564 +0.0526233 88.9474 +0.0547726 88.9326 +0.0570098 88.911 +0.0593383 88.881 +0.0617619 88.8482 +0.0642845 88.8074 +0.0669101 88.7614 +0.069643 88.709 +0.0724875 88.6551 +0.0754482 88.5947 +0.0785298 88.5288 +0.0817373 88.458 +0.0850757 88.3841 +0.0885506 88.306 +0.0921673 88.2247 +0.0959318 88.1398 +0.0998501 88.052 +0.103928 87.9609 +0.108173 87.8674 +0.112591 87.7707 +0.11719 87.6704 +0.121977 87.5671 +0.126959 87.463 +0.132144 87.3565 +0.137541 87.2479 +0.143159 87.1366 +0.149006 87.0233 +0.155092 86.9083 +0.161427 86.7925 +0.16802 86.6744 +0.174883 86.5552 +0.182026 86.4343 +0.18946 86.3113 +0.197198 86.1876 +0.205253 86.0639 +0.213636 85.9388 +0.222362 85.8111 +0.231444 85.6831 +0.240897 85.5531 +0.250736 85.4218 +0.260977 85.2904 +0.271637 85.159 +0.282731 85.0254 +0.294279 84.8907 +0.306299 84.7552 +0.318809 84.6199 +0.33183 84.4834 +0.345384 84.3454 +0.35949 84.2072 +0.374173 84.0687 +0.389456 83.9289 +0.405363 83.7881 +0.42192 83.6476 +0.439153 83.5065 +0.457089 83.3643 +0.475759 83.2214 +0.49519 83.0789 +0.515416 82.9359 +0.536468 82.7921 +0.558379 82.6476 +0.581185 82.5034 +0.604923 82.3585 +0.629631 82.2128 +0.655347 82.0669 +0.682114 81.9223 +0.709975 81.7766 +0.738973 81.63 +0.769155 81.4843 +0.800571 81.339 +0.833269 81.1931 +0.867303 81.0468 +0.902727 80.9021 +0.939598 80.7564 +0.977975 80.6103 +1.01792 80.4637 +1.05949 80.3135 +1.10277 80.1664 +1.14781 80.022 +1.19469 79.8803 +1.24349 79.7417 +1.29428 79.5964 +1.34714 79.4498 +1.40216 79.3069 +1.45943 79.1704 +1.51904 79.0286 +1.58108 78.8843 +1.64566 78.7418 +1.71288 78.6064 +1.78284 78.4661 +1.85566 78.3229 +1.93145 78.1854 +2.01034 78.0443 +2.09245 77.8991 +2.17791 77.752 +2.26686 77.6129 +2.35945 77.4813 +2.45582 77.3513 +2.55613 77.2195 +2.66053 77.0764 +2.76919 76.9404 +2.8823 76.8122 +3.00002 76.6909 & -@TARGET S2 -@TYPE xy - 0.01 0.00014111 - 0.0104351 0.00829056 - 0.010889 0.0164284 - 0.0113628 0.0245419 - 0.0118571 0.0325494 - 0.012373 0.0400393 - 0.0129113 0.0477198 - 0.013473 0.0554494 - 0.0140591 0.0629817 - 0.0146708 0.0699212 - 0.015309 0.0770897 - 0.0159751 0.0843909 - 0.0166701 0.0913569 - 0.0173953 0.0979987 - 0.0181521 0.104748 - 0.0189418 0.111602 - 0.0197659 0.117826 - 0.0206258 3.6241 - 0.0215232 8.2216 - 0.0224596 12.392 - 0.0234367 15.9281 - 0.0244563 19.2422 - 0.0255203 22.351 - 0.0266306 25.2223 - 0.0277891 27.8222 - 0.0289981 30.3173 - 0.0302597 32.7099 - 0.0315762 34.9402 - 0.0329499 37.0469 - 0.0343834 39.093 - 0.0358793 41.0816 - 0.0374403 42.9356 - 0.0390691 44.7331 - 0.0407688 46.4919 - 0.0425425 48.2033 - 0.0443934 49.8049 - 0.0463247 51.3786 - 0.0483401 52.9239 - 0.0504432 54.411 - 0.0526377 55.8291 - 0.0549278 57.2235 - 0.0573174 58.5935 - 0.0598111 59.8962 - 0.0624132 61.1569 - 0.0651285 62.3962 - 0.067962 63.6118 - 0.0709187 64.7545 - 0.0740041 65.8756 - 0.0772237 66.9764 - 0.0805833 68.0445 - 0.0840891 69.0554 - 0.0877475 70.0494 - 0.091565 71.0237 - 0.0955486 71.9578 - 0.0997055 72.8529 - 0.104043 73.732 - 0.10857 74.593 - 0.113293 75.4062 - 0.118222 76.1944 - 0.123365 76.9661 - 0.128732 77.7193 - 0.134333 78.4269 - 0.140177 79.1186 - 0.146276 79.794 - 0.15264 80.444 - 0.15928 81.0618 - 0.16621 81.6648 - 0.173441 82.2522 - 0.180987 82.811 - 0.188861 83.3465 - 0.197077 83.8685 - 0.205651 84.377 - 0.214598 84.8541 - 0.223934 85.3154 - 0.233677 85.7622 - 0.243843 86.1914 - 0.254452 86.5953 - 0.265522 86.9877 - 0.277074 87.3673 - 0.289128 87.7262 - 0.301707 88.0662 - 0.314833 88.3947 - 0.32853 88.7116 - 0.342823 89.0063 - 0.357737 89.2875 - 0.373301 89.5583 - 0.389542 89.8169 - 0.406489 90.0539 - 0.424174 90.281 - 0.442628 90.4978 - 0.461885 90.7014 - 0.481979 90.8886 - 0.502948 91.0661 - 0.524829 91.2339 - 0.547662 91.3878 - 0.571489 91.5295 - 0.596352 91.6618 - 0.622297 91.785 - 0.64937 91.8942 - 0.677621 91.9947 - 0.707102 92.0865 - 0.737865 92.169 - 0.769966 92.2401 - 0.803464 92.3038 - 0.838419 92.3595 - 0.874896 92.407 - 0.912959 92.4447 - 0.952677 92.476 - 0.994124 92.5009 - 1.03737 92.5126 - 1.08251 92.5184 - 1.1296 92.5207 - 1.17875 92.52 - 1.23003 92.5161 - 1.28354 92.4998 - 1.33938 92.4756 - 1.39765 92.4503 - 1.45846 92.4244 - 1.52191 92.3894 - 1.58812 92.3461 - 1.65722 92.3013 - 1.72931 92.2552 - 1.80455 92.2032 - 1.88306 92.1444 - 1.96498 92.0892 - 2.05047 92.0181 - 2.13968 91.9416 - 2.23276 91.8662 - 2.3299 91.7969 - 2.43127 91.7307 - 2.53704 91.6598 - 2.64742 91.5691 - 2.76259 91.4857 - 2.88278 91.4075 - 3.0082 91.3312 - 3.13908 91.2332 - 3.27564 91.1417 - 3.41815 91.0526 - 3.56686 90.9649 - 3.72204 90.8677 - 3.88397 90.7788 - 4.05295 90.6878 - 4.22927 90.5853 - 4.41327 90.4952 - 4.60527 90.3981 - 4.80563 90.2978 - 5.0147 90.2044 - 5.23287 90.1058 - 5.46053 90.0082 - 5.69809 89.9121 - 5.94599 89.8194 - 6.20468 89.7162 - 6.47462 89.6148 - 6.7563 89.5237 - 7.05024 89.4342 - 7.35697 89.341 - 7.67704 89.2486 - 8.01103 89.1666 - 8.35956 89.0751 - 8.72324 88.991 - 9.10275 88.9125 - 9.49877 88.8275 - 9.91202 88.7474 - 10.3433 88.6638 - 10.7932 88.5731 - 11.2628 88.4997 - 11.7528 88.44 - 12.2641 88.3844 - 12.7977 88.3266 - 13.3544 88.2578 - 13.9354 88.2 - 14.5417 88.1527 - 15.1744 88.1097 - 15.8345 88.0562 - 16.5234 88.0106 - 17.2423 87.9763 - 17.9924 87.936 - 18.7752 87.9008 - 19.592 87.8682 - 20.4444 87.8366 - 21.3338 87.7899 - 22.262 87.7579 - 23.2305 87.7395 - 24.2411 87.7384 - 25.2958 87.7248 - 26.3963 87.705 - 27.5447 87.6849 - 28.743 87.6841 - 29.9935 87.6826 - 31.2984 87.6751 - 32.66 87.6627 - 34.0809 87.6726 - 35.5637 87.6687 - 37.1109 87.6631 - 38.7254 87.6644 - 40.4102 87.6687 - 42.1682 87.6725 - 44.0028 87.6768 - 45.9172 87.6847 - 47.9148 87.6914 - 49.9994 87.6971 +@target G0.S2 +@type xy +0.01 0.00014111 +0.0104351 0.00829056 +0.010889 0.0164284 +0.0113628 0.0245419 +0.0118571 0.0325494 +0.012373 0.0400393 +0.0129113 0.0477198 +0.013473 0.0554494 +0.0140591 0.0629817 +0.0146708 0.0699212 +0.015309 0.0770897 +0.0159751 0.0843909 +0.0166701 0.0913569 +0.0173953 0.0979987 +0.0181521 0.104748 +0.0189418 0.111602 +0.0197659 0.117826 +0.0206258 3.6241 +0.0215232 8.2216 +0.0224596 12.392 +0.0234367 15.9281 +0.0244563 19.2422 +0.0255203 22.351 +0.0266306 25.2223 +0.0277891 27.8222 +0.0289981 30.3173 +0.0302597 32.7099 +0.0315762 34.9402 +0.0329499 37.0469 +0.0343834 39.093 +0.0358793 41.0816 +0.0374403 42.9356 +0.0390691 44.7331 +0.0407688 46.4919 +0.0425425 48.2033 +0.0443934 49.8049 +0.0463247 51.3786 +0.0483401 52.9239 +0.0504432 54.411 +0.0526377 55.8291 +0.0549278 57.2235 +0.0573174 58.5935 +0.0598111 59.8962 +0.0624132 61.1569 +0.0651285 62.3962 +0.067962 63.6118 +0.0709187 64.7545 +0.0740041 65.8756 +0.0772237 66.9764 +0.0805833 68.0445 +0.0840891 69.0554 +0.0877475 70.0494 +0.091565 71.0237 +0.0955486 71.9578 +0.0997055 72.8529 +0.104043 73.732 +0.10857 74.593 +0.113293 75.4062 +0.118222 76.1944 +0.123365 76.9661 +0.128732 77.7193 +0.134333 78.4269 +0.140177 79.1186 +0.146276 79.794 +0.15264 80.444 +0.15928 81.0618 +0.16621 81.6648 +0.173441 82.2522 +0.180987 82.811 +0.188861 83.3465 +0.197077 83.8685 +0.205651 84.377 +0.214598 84.8541 +0.223934 85.3154 +0.233677 85.7622 +0.243843 86.1914 +0.254452 86.5953 +0.265522 86.9877 +0.277074 87.3673 +0.289128 87.7262 +0.301707 88.0662 +0.314833 88.3947 +0.32853 88.7116 +0.342823 89.0063 +0.357737 89.2875 +0.373301 89.5583 +0.389542 89.8169 +0.406489 90.0539 +0.424174 90.281 +0.442628 90.4978 +0.461885 90.7014 +0.481979 90.8886 +0.502948 91.0661 +0.524829 91.2339 +0.547662 91.3878 +0.571489 91.5295 +0.596352 91.6618 +0.622297 91.785 +0.64937 91.8942 +0.677621 91.9947 +0.707102 92.0865 +0.737865 92.169 +0.769966 92.2401 +0.803464 92.3038 +0.838419 92.3595 +0.874896 92.407 +0.912959 92.4447 +0.952677 92.476 +0.994124 92.5009 +1.03737 92.5126 +1.08251 92.5184 +1.1296 92.5207 +1.17875 92.52 +1.23003 92.5161 +1.28354 92.4998 +1.33938 92.4756 +1.39765 92.4503 +1.45846 92.4244 +1.52191 92.3894 +1.58812 92.3461 +1.65722 92.3013 +1.72931 92.2552 +1.80455 92.2032 +1.88306 92.1444 +1.96498 92.0892 +2.05047 92.0181 +2.13968 91.9416 +2.23276 91.8662 +2.3299 91.7969 +2.43127 91.7307 +2.53704 91.6598 +2.64742 91.5691 +2.76259 91.4857 +2.88278 91.4075 +3.0082 91.3312 +3.13908 91.2332 +3.27564 91.1417 +3.41815 91.0526 +3.56686 90.9649 +3.72204 90.8677 +3.88397 90.7788 +4.05295 90.6878 +4.22927 90.5853 +4.41327 90.4952 +4.60527 90.3981 +4.80563 90.2978 +5.0147 90.2044 +5.23287 90.1058 +5.46053 90.0082 +5.69809 89.9121 +5.94599 89.8194 +6.20468 89.7162 +6.47462 89.6148 +6.7563 89.5237 +7.05024 89.4342 +7.35697 89.341 +7.67704 89.2486 +8.01103 89.1666 +8.35956 89.0751 +8.72324 88.991 +9.10275 88.9125 +9.49877 88.8275 +9.91202 88.7474 +10.3433 88.6638 +10.7932 88.5731 +11.2628 88.4997 +11.7528 88.44 +12.2641 88.3844 +12.7977 88.3266 +13.3544 88.2578 +13.9354 88.2 +14.5417 88.1527 +15.1744 88.1097 +15.8345 88.0562 +16.5234 88.0106 +17.2423 87.9763 +17.9924 87.936 +18.7752 87.9008 +19.592 87.8682 +20.4444 87.8366 +21.3338 87.7899 +22.262 87.7579 +23.2305 87.7395 +24.2411 87.7384 +25.2958 87.7248 +26.3963 87.705 +27.5447 87.6849 +28.743 87.6841 +29.9935 87.6826 +31.2984 87.6751 +32.66 87.6627 +34.0809 87.6726 +35.5637 87.6687 +37.1109 87.6631 +38.7254 87.6644 +40.4102 87.6687 +42.1682 87.6725 +44.0028 87.6768 +45.9172 87.6847 +47.9148 87.6914 +49.9994 87.6971 & -@TARGET S3 -@TYPE xy - 0.01 0.00214941 - 0.0104351 0.12936 - 0.010889 0.258724 - 0.0113628 0.389822 - 0.0118571 0.52178 - 0.012373 0.651167 - 0.0129113 0.783196 - 0.013473 0.917066 - 0.0140591 1.051 - 0.0146708 1.1812 - 0.015309 1.31462 - 0.0159751 1.45055 - 0.0166701 1.58494 - 0.0173953 1.71786 - 0.0181521 1.85304 - 0.0189418 1.99058 - 0.0197659 2.1231 - 0.0206258 8.15947 - 0.0215232 15.9999 - 0.0224596 23.0812 - 0.0234367 29.0601 - 0.0244563 34.6347 - 0.0255203 39.8405 - 0.0266306 44.6327 - 0.0277891 48.9496 - 0.0289981 53.0669 - 0.0302597 56.9957 - 0.0315762 60.6508 - 0.0329499 64.0823 - 0.0343834 67.401 - 0.0358793 70.61 - 0.0374403 73.596 - 0.0390691 76.4757 - 0.0407688 79.2821 - 0.0425425 82.0092 - 0.0443934 84.5484 - 0.0463247 87.038 - 0.0483401 89.4767 - 0.0504432 91.8128 - 0.0526377 94.0377 - 0.0549278 96.2193 - 0.0573174 98.3562 - 0.0598111 100.384 - 0.0624132 102.351 - 0.0651285 104.277 - 0.067962 106.156 - 0.0709187 107.922 - 0.0740041 109.653 - 0.0772237 111.349 - 0.0805833 112.987 - 0.0840891 114.547 - 0.0877475 116.072 - 0.091565 117.563 - 0.0955486 118.999 - 0.0997055 120.374 - 0.104043 121.728 - 0.10857 123.06 - 0.113293 124.307 - 0.118222 125.503 - 0.123365 126.67 - 0.128732 127.816 - 0.134333 128.903 - 0.140177 129.957 - 0.146276 130.977 - 0.15264 131.957 - 0.15928 132.897 - 0.16621 133.807 - 0.173441 134.684 - 0.180987 135.526 - 0.188861 136.326 - 0.197077 137.103 - 0.205651 137.859 - 0.214598 138.577 - 0.223934 139.256 - 0.233677 139.9 - 0.243843 140.501 - 0.254452 141.075 - 0.265522 141.632 - 0.277074 142.167 - 0.289128 142.652 - 0.301707 143.107 - 0.314833 143.546 - 0.32853 143.966 - 0.342823 144.332 - 0.357737 144.684 - 0.373301 145.016 - 0.389542 145.32 - 0.406489 145.587 - 0.424174 145.834 - 0.442628 146.058 - 0.461885 146.258 - 0.481979 146.425 - 0.502948 146.573 - 0.524829 146.703 - 0.547662 146.798 - 0.571489 146.875 - 0.596352 146.937 - 0.622297 146.98 - 0.64937 146.996 - 0.677621 146.978 - 0.707102 146.944 - 0.737865 146.908 - 0.769966 146.833 - 0.803464 146.747 - 0.838419 146.646 - 0.874896 146.525 - 0.912959 146.39 - 0.952677 146.237 - 0.994124 146.072 - 1.03737 145.909 - 1.08251 145.729 - 1.1296 145.531 - 1.17875 145.314 - 1.23003 145.067 - 1.28354 144.834 - 1.33938 144.603 - 1.39765 144.355 - 1.45846 144.087 - 1.52191 143.821 - 1.58812 143.556 - 1.65722 143.282 - 1.72931 142.996 - 1.80455 142.71 - 1.88306 142.425 - 1.96498 142.128 - 2.05047 141.835 - 2.13968 141.543 - 2.23276 141.246 - 2.3299 140.941 - 2.43127 140.631 - 2.53704 140.323 - 2.64742 140.02 - 2.76259 139.714 - 2.88278 139.407 - 3.0082 139.1 - 3.13908 138.794 - 3.27564 138.49 - 3.41815 138.186 - 3.56686 137.884 - 3.72204 137.584 - 3.88397 137.288 - 4.05295 136.993 - 4.22927 136.696 - 4.41327 136.406 - 4.60527 136.119 - 4.80563 135.836 - 5.0147 135.559 - 5.23287 135.281 - 5.46053 135.008 - 5.69809 134.74 - 5.94599 134.48 - 6.20468 134.217 - 6.47462 133.959 - 6.7563 133.71 - 7.05024 133.468 - 7.35697 133.225 - 7.67704 132.987 - 8.01103 132.759 - 8.35956 132.532 - 8.72324 132.314 - 9.10275 132.103 - 9.49877 131.888 - 9.91202 131.679 - 10.3433 131.47 - 10.7932 131.259 - 11.2628 131.067 - 11.7528 130.891 - 12.2641 130.721 - 12.7977 130.55 - 13.3544 130.37 - 13.9354 130.204 - 14.5417 130.05 - 15.1744 129.904 - 15.8345 129.751 - 16.5234 129.608 - 17.2423 129.479 - 17.9924 129.345 - 18.7752 129.219 - 19.592 129.096 - 20.4444 128.976 - 21.3338 128.843 - 22.262 128.728 - 23.2305 128.63 - 24.2411 128.554 - 25.2958 128.468 - 26.3963 128.377 - 27.5447 128.288 - 28.743 128.223 - 29.9935 128.161 - 31.2984 128.098 - 32.66 128.032 - 34.0809 127.995 - 35.5637 127.948 - 37.1109 127.902 - 38.7254 127.868 - 40.4102 127.843 - 42.1682 127.819 - 44.0028 127.801 - 45.9172 127.789 - 47.9148 127.78 - 49.9994 127.879 +@target G0.S3 +@type xy +0.01 0.00214941 +0.0104351 0.12936 +0.010889 0.258724 +0.0113628 0.389822 +0.0118571 0.52178 +0.012373 0.651167 +0.0129113 0.783196 +0.013473 0.917066 +0.0140591 1.051 +0.0146708 1.1812 +0.015309 1.31462 +0.0159751 1.45055 +0.0166701 1.58494 +0.0173953 1.71786 +0.0181521 1.85304 +0.0189418 1.99058 +0.0197659 2.1231 +0.0206258 8.15947 +0.0215232 15.9999 +0.0224596 23.0812 +0.0234367 29.0601 +0.0244563 34.6347 +0.0255203 39.8405 +0.0266306 44.6327 +0.0277891 48.9496 +0.0289981 53.0669 +0.0302597 56.9957 +0.0315762 60.6508 +0.0329499 64.0823 +0.0343834 67.401 +0.0358793 70.61 +0.0374403 73.596 +0.0390691 76.4757 +0.0407688 79.2821 +0.0425425 82.0092 +0.0443934 84.5484 +0.0463247 87.038 +0.0483401 89.4767 +0.0504432 91.8128 +0.0526377 94.0377 +0.0549278 96.2193 +0.0573174 98.3562 +0.0598111 100.384 +0.0624132 102.351 +0.0651285 104.277 +0.067962 106.156 +0.0709187 107.922 +0.0740041 109.653 +0.0772237 111.349 +0.0805833 112.987 +0.0840891 114.547 +0.0877475 116.072 +0.091565 117.563 +0.0955486 118.999 +0.0997055 120.374 +0.104043 121.728 +0.10857 123.06 +0.113293 124.307 +0.118222 125.503 +0.123365 126.67 +0.128732 127.816 +0.134333 128.903 +0.140177 129.957 +0.146276 130.977 +0.15264 131.957 +0.15928 132.897 +0.16621 133.807 +0.173441 134.684 +0.180987 135.526 +0.188861 136.326 +0.197077 137.103 +0.205651 137.859 +0.214598 138.577 +0.223934 139.256 +0.233677 139.9 +0.243843 140.501 +0.254452 141.075 +0.265522 141.632 +0.277074 142.167 +0.289128 142.652 +0.301707 143.107 +0.314833 143.546 +0.32853 143.966 +0.342823 144.332 +0.357737 144.684 +0.373301 145.016 +0.389542 145.32 +0.406489 145.587 +0.424174 145.834 +0.442628 146.058 +0.461885 146.258 +0.481979 146.425 +0.502948 146.573 +0.524829 146.703 +0.547662 146.798 +0.571489 146.875 +0.596352 146.937 +0.622297 146.98 +0.64937 146.996 +0.677621 146.978 +0.707102 146.944 +0.737865 146.908 +0.769966 146.833 +0.803464 146.747 +0.838419 146.646 +0.874896 146.525 +0.912959 146.39 +0.952677 146.237 +0.994124 146.072 +1.03737 145.909 +1.08251 145.729 +1.1296 145.531 +1.17875 145.314 +1.23003 145.067 +1.28354 144.834 +1.33938 144.603 +1.39765 144.355 +1.45846 144.087 +1.52191 143.821 +1.58812 143.556 +1.65722 143.282 +1.72931 142.996 +1.80455 142.71 +1.88306 142.425 +1.96498 142.128 +2.05047 141.835 +2.13968 141.543 +2.23276 141.246 +2.3299 140.941 +2.43127 140.631 +2.53704 140.323 +2.64742 140.02 +2.76259 139.714 +2.88278 139.407 +3.0082 139.1 +3.13908 138.794 +3.27564 138.49 +3.41815 138.186 +3.56686 137.884 +3.72204 137.584 +3.88397 137.288 +4.05295 136.993 +4.22927 136.696 +4.41327 136.406 +4.60527 136.119 +4.80563 135.836 +5.0147 135.559 +5.23287 135.281 +5.46053 135.008 +5.69809 134.74 +5.94599 134.48 +6.20468 134.217 +6.47462 133.959 +6.7563 133.71 +7.05024 133.468 +7.35697 133.225 +7.67704 132.987 +8.01103 132.759 +8.35956 132.532 +8.72324 132.314 +9.10275 132.103 +9.49877 131.888 +9.91202 131.679 +10.3433 131.47 +10.7932 131.259 +11.2628 131.067 +11.7528 130.891 +12.2641 130.721 +12.7977 130.55 +13.3544 130.37 +13.9354 130.204 +14.5417 130.05 +15.1744 129.904 +15.8345 129.751 +16.5234 129.608 +17.2423 129.479 +17.9924 129.345 +18.7752 129.219 +19.592 129.096 +20.4444 128.976 +21.3338 128.843 +22.262 128.728 +23.2305 128.63 +24.2411 128.554 +25.2958 128.468 +26.3963 128.377 +27.5447 128.288 +28.743 128.223 +29.9935 128.161 +31.2984 128.098 +32.66 128.032 +34.0809 127.995 +35.5637 127.948 +37.1109 127.902 +38.7254 127.868 +40.4102 127.843 +42.1682 127.819 +44.0028 127.801 +45.9172 127.789 +47.9148 127.78 +49.9994 127.879 & diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/chapter2_3.tex b/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/chapter2_3.tex index 7b44ee53c..3d10116cf 100644 --- a/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/chapter2_3.tex +++ b/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/chapter2_3.tex @@ -48,282 +48,282 @@ \subsubsection{General discussion} \setcounter{equation}{0} \index{electron transport!general discussion} -The Condensed History (CH) Technique was introduced by M. Berger in -the early sixties \cite{Be63}. +The Condensed History (CH) Technique was introduced by M. Berger in +the early sixties \cite{Be63}. In this technique, many track segments of the real electron random walk are grouped into a single ``step''. The cumulative effect of elastic and inelastic collisions during the step are taken into account by sampling energy and direction changes from appropriate multiple scattering distributions at the end of the step. This approach is justified by the observation that the changes of -the electron state in a single collision are usually very small and +the electron state in a single collision are usually very small and fails when this condition is not satisfied (at very low energies). -Berger also defined two different implementations of the CH technique, +Berger also defined two different implementations of the CH technique, which he called Class I and Class II schemes. \index{Class I scheme} \index{Class II scheme} -EGSnrc uses a Class II CH scheme -for the simulation of electron transport. -That is to say, bremsstrahlung processes that result in the -creation of photons above an energy threshold $k_c$, and -inelastic collisions that set in motion atomic electrons with +EGSnrc uses a Class II CH scheme +for the simulation of electron transport. +That is to say, bremsstrahlung processes that result in the +creation of photons above an energy threshold $k_c$, and +inelastic collisions that set in motion atomic electrons with kinetic energies above $T_c$, are both simulated explicitly and the -secondaries transported. Such interactions are also referred to as -``catastrophic'' collisions. -Sub-threshold inelastic and radiative events and -elastic collisions are subject to grouping. +secondaries transported. Such interactions are also referred to as +``catastrophic'' collisions. +Sub-threshold inelastic and radiative events and +elastic collisions are subject to grouping. \index{catastrophic collisions} \index{discrete interactions} Every CH scheme must provide rules for selecting -a path-length $\Delta s_n$, an energy loss $\Delta E_n$, +a path-length $\Delta s_n$, an energy loss $\Delta E_n$, a change in direction from $\Omega_n$ to $\Omega_{n+1}$ and a spatial displacement -$\Delta \vec{x}_n$ for each step of the CH random walk. For transport in -heterogeneous geometries a boundary crossing algorithm is +$\Delta \vec{x}_n$ for each step of the CH random walk. For transport in +heterogeneous geometries a boundary crossing algorithm is also required. -In the following we give a brief transport-theoretical -treatment of a Class II CH technique which will help -to establish the motivation and definitions of +In the following we give a brief transport-theoretical +treatment of a Class II CH technique which will help +to establish the motivation and definitions of various quantities used in the CH implementation. \index{transport equation} -The transport equation for the electron fluence -$\Phi(\vec{x},\vec{\Omega},E,t)$ in a medium with a density of -scattering centres (atoms or molecules) $n(\vec{x})$ is given by +The transport equation for the electron fluence +$\Phi(\vec{x},\vec{\Omega},E,t)$ in a medium with a density of +scattering centres (atoms or molecules) $n(\vec{x})$ is given by \begin{equation} \label{transport1} -{{\rm d}\Phi(\vec{x},\vec{\Omega},E,t) \over {\rm d}t} = +{{\rm d}\Phi(\vec{x},\vec{\Omega},E,t) \over {\rm d}t} = \index{electron transport!general discussion} -S(\vec{x},\vec{\Omega},E,t) + v I[\Phi] +S(\vec{x},\vec{\Omega},E,t) + v I[\Phi] \end{equation} -where +where \begin{itemize} \item $S(\vec{x},\vec{\Omega},E,t)$ is the number of electrons with energy $E$ and velocity $\vec{v} = (v,\vec{\Omega})$ at a position $\vec{x}$ per unit -volume, energy and solid angle interval, imparted per unit time +volume, energy and solid angle interval, imparted per unit time by an external source or by photons interacting with the medium at time $t$. This latter part of the -source term causes the coupling of the electron and photon fluences. +source term causes the coupling of the electron and photon fluences. \item -${\rm d}\Phi/{\rm d}t$ is the total time derivative, in the absence -of external force fields it is given by +${\rm d}\Phi/{\rm d}t$ is the total time derivative, in the absence +of external force fields it is given by \begin{equation} -{{\rm d}\Phi(\vec{x},\vec{\Omega},E,t) \over {\rm d}t} = -{\partial \Phi(\vec{x},\vec{\Omega},E,t) \over \partial t} + +{{\rm d}\Phi(\vec{x},\vec{\Omega},E,t) \over {\rm d}t} = +{\partial \Phi(\vec{x},\vec{\Omega},E,t) \over \partial t} + \vec{v} \vec{\nabla} \Phi(\vec{x},\vec{\Omega},E,t)~. \end{equation} \item \index{collision integral} -The collision term $I[\Phi]$ represents the changes of the particle -fluence due to collisions with the atoms or molecules of the +The collision term $I[\Phi]$ represents the changes of the particle +fluence due to collisions with the atoms or molecules of the surrounding medium, \begin{equation} \begin{split} -I[\Phi] = - & - n(\vec{x}) \Phi(\vec{x},\vec{\Omega},E,t) -\int\limits_0^E {\rm d} E' \int\limits_{4 \pi} {\rm d} \vec{\Omega}' -\sigma(E,E',\Omega',\vec{x}) \\ -& + +I[\Phi] = + & - n(\vec{x}) \Phi(\vec{x},\vec{\Omega},E,t) +\int\limits_0^E {\rm d} E' \int\limits_{4 \pi} {\rm d} \vec{\Omega}' +\sigma(E,E',\Omega',\vec{x}) \\ +& + n(\vec{x}) \int\limits_E^\infty {\rm d} E' \int\limits_{4 \pi} {\rm d}\vec{\Omega}' -\Phi(\vec{x},\vec{\Omega}',E',t) +\Phi(\vec{x},\vec{\Omega}',E',t) \sigma(E',E'-E,\vec{\Omega}'\cdot \vec{\Omega},\vec{x}) \end{split} \end{equation} where -$\sigma(E,E',\Omega,\vec{x})$ is the microscopic cross section -at a position $\vec{x}$ for all possible interactions in which -an electron with energy $E$ loses energy $E'$ and changes its direction -by $\vec{\Omega}$. +$\sigma(E,E',\Omega,\vec{x})$ is the microscopic cross section +at a position $\vec{x}$ for all possible interactions in which +an electron with energy $E$ loses energy $E'$ and changes its direction +by $\vec{\Omega}$. \end{itemize} -The collision integral $I[\Phi]$ represents the balance between -particle losses and gains due to interactions described by the -cross section $\sigma(E,E',\Omega,\vec{x})$. +The collision integral $I[\Phi]$ represents the balance between +particle losses and gains due to interactions described by the +cross section $\sigma(E,E',\Omega,\vec{x})$. \index{cross section} -In a Monte Carlo simulation the solution of Eq. \eqref{transport1} -is usually obtained via +In a Monte Carlo simulation the solution of Eq. \eqref{transport1} +is usually obtained via \begin{equation} \label{integrate_green_function} -\Phi(\vec{x},\vec{\Omega},E,t) = \int\limits_0^t {\rm d}t_0 -\int\limits_E^\infty {\rm d}E_0 \int {\rm d}\vec{x}_0 \int\limits_{4 \pi} -{\rm d}\vec{\Omega}_0~ S(\vec{x}_0,\vec{\Omega}_0,E_0,t_0) +\Phi(\vec{x},\vec{\Omega},E,t) = \int\limits_0^t {\rm d}t_0 +\int\limits_E^\infty {\rm d}E_0 \int {\rm d}\vec{x}_0 \int\limits_{4 \pi} +{\rm d}\vec{\Omega}_0~ S(\vec{x}_0,\vec{\Omega}_0,E_0,t_0) \Phi_0(\vec{x},\vec{\Omega},E,t) \end{equation} -where $\Phi_0(\vec{x},\vec{\Omega},E,t)$ is a short hand notation -for $\Phi(\vec{x}_0,\vec{\Omega}_0,E_0,t_0;\vec{x},\vec{\Omega},E,t)$ -which is the solution of +where $\Phi_0(\vec{x},\vec{\Omega},E,t)$ is a short hand notation +for $\Phi(\vec{x}_0,\vec{\Omega}_0,E_0,t_0;\vec{x},\vec{\Omega},E,t)$ +which is the solution of Eq. \eqref{transport1} for a source \begin{equation} -S_0 = \delta^{(3)}(\vec{x} - \vec{x}_0) \delta^{(2)} (\vec{\Omega} - +S_0 = \delta^{(3)}(\vec{x} - \vec{x}_0) \delta^{(2)} (\vec{\Omega} - \vec{\Omega}_0) \delta(E-E_0) \delta(t - t_0) \end{equation} -{\em i.e.} a single particle set in motion at time $t_0$ with -energy $E_0$, direction $\vec{\Omega}_0$ at a position $\vec{x}_0$. -The integration of Eq. (\eqref{integrate_green_function}) +{\em i.e.} a single particle set in motion at time $t_0$ with +energy $E_0$, direction $\vec{\Omega}_0$ at a position $\vec{x}_0$. +The integration of Eq. (\eqref{integrate_green_function}) is of course performed by a Monte Carlo technique: \begin{enumerate} \item -Pick particles from the source $S(\vec{x},\vec{\Omega},E,t)$, -denote their co-ordinates by $E_0, \vec{x_0}, \vec{\Omega_0}, t_0$. +Pick particles from the source $S(\vec{x},\vec{\Omega},E,t)$, +denote their co-ordinates by $E_0, \vec{x_0}, \vec{\Omega_0}, t_0$. \item -Solve the transport equation for these particles by a Monte Carlo -simulation ({\em i.e.} solve the transport equation for +Solve the transport equation for these particles by a Monte Carlo +simulation ({\em i.e.} solve the transport equation for $\Phi_0$) \end{enumerate} -Usually the Monte Carlo simulation is initiated by a single -particle from an external source, which is put on a ``particle -stack''. In EGSnrc this is accomplished by a call to the subroutine -{\tt SHOWER}. Then, at each stage of the Monte Carlo simulation, -the source corresponds to all particles currently on the stack. +Usually the Monte Carlo simulation is initiated by a single +particle from an external source, which is put on a ``particle +stack''. In EGSnrc this is accomplished by a call to the subroutine +{\tt SHOWER}. Then, at each stage of the Monte Carlo simulation, +the source corresponds to all particles currently on the stack. \index{SHOWER} \index{macroscopic cross section} -Sometimes it is customary to use the macroscopic cross section $\Sigma$, +Sometimes it is customary to use the macroscopic cross section $\Sigma$, \begin{equation} \Sigma(E,E',\Omega,\vec{x}) = n(\vec{x}) \sigma(E,E',\Omega,\vec{x}) \end{equation} -which, when integrated over $E'$ and $\Omega'$, represents the number of -interactions per unit length for electrons with energy $E$. -The atom or molecule density $n$ is given by +which, when integrated over $E'$ and $\Omega'$, represents the number of +interactions per unit length for electrons with energy $E$. +The atom or molecule density $n$ is given by \begin{equation} n = \rho \frac{N_A}{M_A} = {\rho \over u A} -\end{equation} -where $N_A = 6.022045\times10^{23}$~mol$^-1$ is -Avogadro constant, $M_A$ the molar mass in mol$^{-1}$, -$u = 1.0665655\times10^{-24}$~g is the atomic mass unit -and $A$ the relative atomic or molecular mass. Macroscopic -cross sections $\Sigma$ are thus obtained from microscopic -cross sections $\sigma$ by multiplication with one of -the above factors. +\end{equation} +where $N_A = 6.022045\times10^{23}$~mol$^-1$ is +Avogadro constant, $M_A$ the molar mass in mol$^{-1}$, +$u = 1.0665655\times10^{-24}$~g is the atomic mass unit +and $A$ the relative atomic or molecular mass. Macroscopic +cross sections $\Sigma$ are thus obtained from microscopic +cross sections $\sigma$ by multiplication with one of +the above factors. \index{cross section!bremsstrahlung} \index{cross section!inelastic collisions} \index{cross section!elastic} \index{cross section!annihilation} -For electrons, $\sigma$ is the sum of the -bremsstrahlung cross section $\sigma_{\rm brem}$, the cross section -for inelastic collisions with atomic electrons, $\sigma_{\rm inel}$, +For electrons, $\sigma$ is the sum of the +bremsstrahlung cross section $\sigma_{\rm brem}$, the cross section +for inelastic collisions with atomic electrons, $\sigma_{\rm inel}$, and the elastic scattering cross section $\sigma_{\rm el}$: \begin{equation} -\sigma(E,E',\Omega,\vec{x}) = \sigma_{\rm brem}(E,E',\Omega,\vec{x}) -+ \sigma_{\rm inel}(E,E',\Omega,\vec{x}) + +\sigma(E,E',\Omega,\vec{x}) = \sigma_{\rm brem}(E,E',\Omega,\vec{x}) ++ \sigma_{\rm inel}(E,E',\Omega,\vec{x}) + \sigma_{\rm el}(E,\Omega,\vec{x}) \delta(0) \end{equation} -where Dirac's $\delta$ function expresses the fact that +where Dirac's $\delta$ function expresses the fact that elastic collisions are zero energy loss events. Positrons -interact in addition via the annihilation process described -by $\sigma_{\rm annih}$, this cross section enters -only the third term of Eq. (\ref{transport1}), however, as annihilation -leads merely to particle loss (at least when looking just at -the electron fluence, the corresponding ``gain'' term appears -as a source term for the photon fluence). +interact in addition via the annihilation process described +by $\sigma_{\rm annih}$, this cross section enters +only the third term of Eq. (\ref{transport1}), however, as annihilation +leads merely to particle loss (at least when looking just at +the electron fluence, the corresponding ``gain'' term appears +as a source term for the photon fluence). \index{Class II scheme} -In a Class II CH implementation the collision integral -is divided into two parts $I_>[\Phi_0]$ and $I_<[\Phi_0]$. -The former includes only interactions -with change in energy larger than $T_c$ (inelastic collisions) -or $k_c$ (bremsstrahlung), the latter only -collision with energy change less than -$T_c$ or $k_c$. Elastic interactions, -being a zero energy loss processes, are included in $I_<[\Phi_0]$. -For brevity we will drop the $\vec{x}$ and time dependence of the -various quantities in the following equations. +In a Class II CH implementation the collision integral +is divided into two parts $I_>[\Phi_0]$ and $I_<[\Phi_0]$. +The former includes only interactions +with change in energy larger than $T_c$ (inelastic collisions) +or $k_c$ (bremsstrahlung), the latter only +collision with energy change less than +$T_c$ or $k_c$. Elastic interactions, +being a zero energy loss processes, are included in $I_<[\Phi_0]$. +For brevity we will drop the $\vec{x}$ and time dependence of the +various quantities in the following equations. We have for $I_>[\Phi_0]$ \begin{equation} \begin{split} I_>[\Phi_0] & = \int\limits_{E+T_c}^\infty {\rm d}E' \int\limits_{4 \pi} -{\rm d} \vec{\Omega}' \Phi_0(\vec{\Omega}',E') +{\rm d} \vec{\Omega}' \Phi_0(\vec{\Omega}',E') \Sigma_{\rm inel}(E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') \\ -& + \int\limits_{E+k_c}^\infty {\rm d}E' \int\limits_{4 \pi} -{\rm d} \vec{\Omega}' \Phi_0(\vec{\Omega}',E') +& + \int\limits_{E+k_c}^\infty {\rm d}E' \int\limits_{4 \pi} +{\rm d} \vec{\Omega}' \Phi_0(\vec{\Omega}',E') \Sigma_{\rm brem}(E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') \\ -& - \Phi_0(\vec{\Omega},E) +& - \Phi_0(\vec{\Omega},E) \left[ \Sigma_{\rm inel}^{\rm (tot)}(E) + \Sigma_{\rm brem}^{\rm (tot)}(E) \right] \end{split} \end{equation} -where $\Sigma_{\rm inel}^{\rm (tot)}(E)$ and -$\Sigma_{\rm breml}^{\rm (tot)}(E)$ are the total macroscopic -cross sections for ``catastrophic'' inelastic or bremsstrahlung +where $\Sigma_{\rm inel}^{\rm (tot)}(E)$ and +$\Sigma_{\rm breml}^{\rm (tot)}(E)$ are the total macroscopic +cross sections for ``catastrophic'' inelastic or bremsstrahlung collisions, respectively: \index{catastrophic collisions} \begin{equation} -\Sigma_{\rm inel,brem}^{\rm (tot)}(E) = \int\limits_{T_c,k_c}^E {\rm d} E' -\int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\Sigma_{\rm inel,brem}^{\rm (tot)}(E) = \int\limits_{T_c,k_c}^E {\rm d} E' +\int\limits_{4 \pi} {\rm d}\vec{\Omega}' \Sigma_{\rm inel,brem}(E,E',\Omega')~. \end{equation} The $I_<[\Phi_0]$ part reads \begin{equation} -I_<[\Phi_0] = \int\limits_{4 \pi} {\rm d}\vec{\Omega}' -\left[ \Phi_0(\vec{\Omega}',E) -\Sigma_{\rm el}(E,\vec{\Omega}\cdot\vec{\Omega}') - -\Phi_0(\vec{\Omega},E) \Sigma_{\rm el}(E,\Omega') \right] + +I_<[\Phi_0] = \int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\left[ \Phi_0(\vec{\Omega}',E) +\Sigma_{\rm el}(E,\vec{\Omega}\cdot\vec{\Omega}') - +\Phi_0(\vec{\Omega},E) \Sigma_{\rm el}(E,\Omega') \right] + I_{\Delta E}[\Phi_0] \end{equation} -where $I_{\Delta E}[\Phi_0]$ is the part of the sub-threshold -collision term that is associated with energy loss: +where $I_{\Delta E}[\Phi_0]$ is the part of the sub-threshold +collision term that is associated with energy loss: \begin{equation} \begin{split} \label{I_deltaE1} -& +& I_{\Delta E}[\Phi_0] = \\ -& - \int\limits_E^{E+T_c} {\rm d}E' \int\limits_{4 \pi} -{\rm d}\vec{\Omega}'\Phi_0(\vec{\Omega}',E') -\Sigma_{\rm inel}(E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') - +& + \int\limits_E^{E+T_c} {\rm d}E' \int\limits_{4 \pi} +{\rm d}\vec{\Omega}'\Phi_0(\vec{\Omega}',E') +\Sigma_{\rm inel}(E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') - \Phi_0(\vec{\Omega},E) -\int\limits_0^{T_c} {\rm d}E' \int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\int\limits_0^{T_c} {\rm d}E' \int\limits_{4 \pi} {\rm d}\vec{\Omega}' \Sigma_{\rm inel}(E,E',\Omega') + \\ -& -\int\limits_E^{E+k_c} {\rm d}E' \int\limits_{4 \pi} -{\rm d}\vec{\Omega}'\Phi_0(\vec{\Omega}',E') -\Sigma_{\rm brem} (E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') - +& +\int\limits_E^{E+k_c} {\rm d}E' \int\limits_{4 \pi} +{\rm d}\vec{\Omega}'\Phi_0(\vec{\Omega}',E') +\Sigma_{\rm brem} (E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') - \Phi_0(\vec{\Omega},E) -\int\limits_0^{k_c} {\rm d}E' \int\limits_{4 \pi} {\rm d}\vec{\Omega}' -\Sigma_{\rm brem}(E,E',\Omega')~. +\int\limits_0^{k_c} {\rm d}E' \int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\Sigma_{\rm brem}(E,E',\Omega')~. \end{split} \end{equation} \index{angular deflections!inelastic collisions} -At this point, the usual approximation made is to assume -that angular deflections in small energy loss collisions are -either negligible -or can be taken into account by modifying the -elastic collision part in an appropriate way. To our knowledge, -this approximation is made, in one way or another, in all -general purpose condensed history codes available. -With this approximation and after a change of the integration variables, +At this point, the usual approximation made is to assume +that angular deflections in small energy loss collisions are +either negligible +or can be taken into account by modifying the +elastic collision part in an appropriate way. To our knowledge, +this approximation is made, in one way or another, in all +general purpose condensed history codes available. +With this approximation and after a change of the integration variables, Eq. (\ref{I_deltaE1}) can be re-written as \begin{equation} \begin{split} \label{I_deltaE2} -I_{\Delta E}[\Phi_0] & = -\int\limits_0^{T_c} {\rm d}E' \left[ \Phi_0(\vec{\Omega},E+E') -\Sigma_{\rm inel}(E+E',E') - \Phi_0(\vec{\Omega},E) \Sigma_{\rm inel}(E,E') -\right] \\ -& + -\int\limits_0^{k_c} {\rm d}E' \left[ \Phi_0(\vec{\Omega},E+E') +I_{\Delta E}[\Phi_0] & = +\int\limits_0^{T_c} {\rm d}E' \left[ \Phi_0(\vec{\Omega},E+E') +\Sigma_{\rm inel}(E+E',E') - \Phi_0(\vec{\Omega},E) \Sigma_{\rm inel}(E,E') +\right] \\ +& + +\int\limits_0^{k_c} {\rm d}E' \left[ \Phi_0(\vec{\Omega},E+E') \Sigma_{\rm brem}(E+E',E') - \Phi_0(\vec{\Omega},E) \Sigma_{\rm brem}(E,E') \right] \end{split} \end{equation} -where the cross sections not depending on $\Omega$ are integrated -over all angles. -If we now use a Taylor series expansions for the first terms in +where the cross sections not depending on $\Omega$ are integrated +over all angles. +If we now use a Taylor series expansions for the first terms in the square brackets, \begin{equation} \label{taylor_exp} \begin{split} -\Phi_0(\vec{\Omega},E+E') \Sigma_{\rm inel,brem}(E+E',E') & \approx +\Phi_0(\vec{\Omega},E+E') \Sigma_{\rm inel,brem}(E+E',E') & \approx \Phi_0(\vec{\Omega},E) \Sigma_{\rm inel,brem}(E,E') \\ -& + -\frac{\partial}{\partial E} \left[ +& + +\frac{\partial}{\partial E} \left[ \Phi_0(\vec{\Omega},E) \Sigma_{\rm inel,brem}(E,E') \right] E' + \cdots \end{split} \end{equation} @@ -332,15 +332,15 @@ \subsubsection{General discussion} I_{\Delta E}[\Phi_0] \approx \frac{\partial}{\partial E} \left[ \Phi_0(\vec{\Omega},E) L(E,T_c,k_c) \right] \end{equation} -where $L(E,T_c,k_c)$ is the restricted stopping power +where $L(E,T_c,k_c)$ is the restricted stopping power for threshold energies $T_c$ and $k_c$, \begin{equation} \begin{split} L(E,T_c,k_c) & = L_{\rm coll}(E,T_c) + L_{\rm rad}(E,k_c) \\ -L_{\rm coll}(E,T_c) & \equiv \int\limits_0^{T_c} {\rm d}E' +L_{\rm coll}(E,T_c) & \equiv \int\limits_0^{T_c} {\rm d}E' \Sigma_{\rm inel}(E,E') E' \\ -L_{\rm radl}(E,k_c) & \equiv \int\limits_0^{k_c} {\rm d}E' -\Sigma_{\rm brem}(E,E') E' +L_{\rm radl}(E,k_c) & \equiv \int\limits_0^{k_c} {\rm d}E' +\Sigma_{\rm brem}(E,E') E' \end{split} \end{equation} \index{restricted stopping power} @@ -349,183 +349,183 @@ \subsubsection{General discussion} \begin{equation} \label{transport2} \begin{split} -\frac{1}{v}~{\partial \Phi_0(\vec{x},\vec{\Omega},E,t) \over -\partial t} & + \vec{\Omega} \vec{\nabla} \Phi_0(\vec{x},\vec{\Omega},E,t) = -S_0 - - \Phi_0(\vec{x},\vec{\Omega},E,t) -\left[ \Sigma_{\rm inel}^{\rm (tot)}(\vec{x},E) + +\frac{1}{v}~{\partial \Phi_0(\vec{x},\vec{\Omega},E,t) \over +\partial t} & + \vec{\Omega} \vec{\nabla} \Phi_0(\vec{x},\vec{\Omega},E,t) = +S_0 + - \Phi_0(\vec{x},\vec{\Omega},E,t) +\left[ \Sigma_{\rm inel}^{\rm (tot)}(\vec{x},E) + \Sigma_{\rm brem}^{\rm (tot)}(\vec{x},E) \right] \\ -& + +& + \int\limits_{E+T_c}^\infty {\rm d}E' \int\limits_{4 \pi} -{\rm d} \vec{\Omega}' \Phi_0(\vec{x},\vec{\Omega}',E',t) +{\rm d} \vec{\Omega}' \Phi_0(\vec{x},\vec{\Omega}',E',t) \Sigma_{\rm inel}(\vec{x},E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') \\ -& + \int\limits_{E+k_c}^\infty {\rm d}E' \int\limits_{4 \pi} -{\rm d} \vec{\Omega}' \Phi_0(\vec{x},\vec{\Omega}',E',t) +& + \int\limits_{E+k_c}^\infty {\rm d}E' \int\limits_{4 \pi} +{\rm d} \vec{\Omega}' \Phi_0(\vec{x},\vec{\Omega}',E',t) \Sigma_{\rm brem}(\vec{x},E',E'-E,\vec{\Omega}\cdot\vec{\Omega}') \\ -& + - \int\limits_{4 \pi} {\rm d}\vec{\Omega}' -\left[ \Phi_0(\vec{x},\vec{\Omega}',E,t) -\Sigma_{\rm el}'(\vec{x},E,\vec{\Omega}\cdot\vec{\Omega}') - +& + + \int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\left[ \Phi_0(\vec{x},\vec{\Omega}',E,t) +\Sigma_{\rm el}'(\vec{x},E,\vec{\Omega}\cdot\vec{\Omega}') - \Phi_0(\vec{x},\vec{\Omega},E,t) \Sigma_{\rm el}'(\vec{x},E,\Omega') \right] \\ & + \frac{\partial}{\partial E} \left[ -\Phi_0(\vec{x},\vec{\Omega},E,t) L(\vec{x},E,T_c,k_c) \right] +\Phi_0(\vec{x},\vec{\Omega},E,t) L(\vec{x},E,T_c,k_c) \right] \end{split} \end{equation} -where we have put back the position dependence of the fluence, -stopping power and cross sections, and the prime on the elastic scattering -cross section means that it includes in some way contributions -from angular deflections due to sub-threshold energy loss processes. +where we have put back the position dependence of the fluence, +stopping power and cross sections, and the prime on the elastic scattering +cross section means that it includes in some way contributions +from angular deflections due to sub-threshold energy loss processes. \index{angular deflections!inelastic collisions} \index{path-length} -We now define the variable $s$, called the path-length, +We now define the variable $s$, called the path-length, which satisfies \begin{equation} \label{s_vs_E} \begin{split} -{{\rm d} t \over {\rm d} s} & = \frac{1}{v} \\ +{{\rm d} t \over {\rm d} s} & = \frac{1}{v} \\ {{\rm d} E \over {\rm d} s} & = -L(E,E_c,k_c)~, \quad \text{or} \\ - s & = \int\limits_E^{E_0} {{\rm d} E' \over L(E,E_c,k_c)} + s & = \int\limits_E^{E_0} {{\rm d} E' \over L(E,E_c,k_c)} \end{split} \end{equation} %which is equivalent to \cite{La92} %\begin{equation} -%\frac{1}{v} -%~{\partial \Phi_0(\vec{x},\vec{\Omega},E,t) \over +%\frac{1}{v} +%~{\partial \Phi_0(\vec{x},\vec{\Omega},E,t) \over %\partial t} = \frac{\partial}{\partial E} \left[ %\Phi_0(\vec{x},\vec{\Omega},E,t) L(\vec{x},E,T_c,k_c) \right] %\end{equation} \index{CSDA} \index{energy loss straggling} \index{Vavilov processes} -The approximation of Eq. (\ref{taylor_exp}), together -with Eq. \eqref{s_vs_E}, is known -as continuous-slowing-down approximation (CSDA). CSDA is used -in EGSnrc (and also in EGS4) to describe sub-threshold -energy loss processes. This is not a necessary -approximation, and one could replace it, for instance, by -the theory of Vavilov \cite{Va57}. We have postponed -the implementation of Vavilov energy loss straggling -into EGSnrc until the implementation of more realistic -small energy loss inelastic scattering cross sections -(which obviously affect the treatment of the integrals in -Eq. (\ref{I_deltaE2})). +The approximation of Eq. (\ref{taylor_exp}), together +with Eq. \eqref{s_vs_E}, is known +as continuous-slowing-down approximation (CSDA). CSDA is used +in EGSnrc (and also in EGS4) to describe sub-threshold +energy loss processes. This is not a necessary +approximation, and one could replace it, for instance, by +the theory of Vavilov \cite{Va57}. We have postponed +the implementation of Vavilov energy loss straggling +into EGSnrc until the implementation of more realistic +small energy loss inelastic scattering cross sections +(which obviously affect the treatment of the integrals in +Eq. (\ref{I_deltaE2})). \index{transport equation!solution by MC simulation} -Equation (\ref{transport2}) can be solved +Equation (\ref{transport2}) can be solved by the following Monte Carlo algorithm: \begin{enumerate} \item -Pick the next electron from the ``particle stack'', we -denote its energy by $E_0$, its direction by $\vec{\Omega}_0$ and -its position by $\vec{x}_0$. +Pick the next electron from the ``particle stack'', we +denote its energy by $E_0$, its direction by $\vec{\Omega}_0$ and +its position by $\vec{x}_0$. \item -Sample the energy $E$ at which the next ``catastrophic'' interaction occurs -from the probability distribution +Sample the energy $E$ at which the next ``catastrophic'' interaction occurs +from the probability distribution \begin{equation} \label{ch_Ps} -P(E) = \exp\left( - \int\limits_{E}^{E_0} {\rm d} E' -\left[\tilde{\Sigma}_{\rm inel}(E') + \tilde{\Sigma}_{\rm brem}(E') \right] +P(E) = \exp\left( - \int\limits_{E}^{E_0} {\rm d} E' +\left[\tilde{\Sigma}_{\rm inel}(E') + \tilde{\Sigma}_{\rm brem}(E') \right] \right) \end{equation} -where we have defined +where we have defined \begin{equation} -\tilde{\Sigma}_{\rm inel, brem}^{\rm (tot)}(E) = -{\Sigma_{\rm inel,brem}^{\rm (tot)}(E) \over +\tilde{\Sigma}_{\rm inel, brem}^{\rm (tot)}(E) = +{\Sigma_{\rm inel,brem}^{\rm (tot)}(E) \over L(E,E_c,k_c)} \end{equation} -which are the total cross sections for bremsstrahlung -or inelastic collisions for discrete interactions per -unit energy loss. +which are the total cross sections for bremsstrahlung +or inelastic collisions for discrete interactions per +unit energy loss. \item -Modify the particles position, direction, and energy, in such a -way as to approximate as closely as possible the +Modify the particles position, direction, and energy, in such a +way as to approximate as closely as possible the exact solution of the transport equation \begin{eqnarray} \label{transport3} -{ \partial \Phi_0(\vec{x},\vec{\Omega},s) \over \partial s} & + & -\vec{\Omega} \vec{\nabla} \Phi_0(\vec{x},\vec{\Omega},s) = +{ \partial \Phi_0(\vec{x},\vec{\Omega},s) \over \partial s} & + & +\vec{\Omega} \vec{\nabla} \Phi_0(\vec{x},\vec{\Omega},s) = \\ -& & -\int\limits_{4 \pi} {\rm d}\vec{\Omega}' -\left[ \Phi_0(\vec{x},\vec{\Omega}',s) -\Sigma_{\rm el}'(\vec{x},s,\vec{\Omega}\cdot\vec{\Omega}') - -\Phi_0(\vec{x},\vec{\Omega},s) \Sigma_{\rm el}'(\vec{x},\Omega',s) \right] -\nonumber +& & +\int\limits_{4 \pi} {\rm d}\vec{\Omega}' +\left[ \Phi_0(\vec{x},\vec{\Omega}',s) +\Sigma_{\rm el}'(\vec{x},s,\vec{\Omega}\cdot\vec{\Omega}') - +\Phi_0(\vec{x},\vec{\Omega},s) \Sigma_{\rm el}'(\vec{x},\Omega',s) \right] +\nonumber \end{eqnarray} -where the $s$ dependence of all quantities is understood -in the sense of Eq. (\ref{s_vs_E}). +where the $s$ dependence of all quantities is understood +in the sense of Eq. (\ref{s_vs_E}). \item -Once at the interaction site, select the interaction type from -the total interaction cross sections at the current position and -for the current energy, sample energy and direction changes -from the appropriate differential cross section, put +Once at the interaction site, select the interaction type from +the total interaction cross sections at the current position and +for the current energy, sample energy and direction changes +from the appropriate differential cross section, put all resulting particles on the stack and go to step 1. \item -Repeat steps 1-4 until the stack is empty or all energies have +Repeat steps 1-4 until the stack is empty or all energies have fallen below the specified threshold. \end{enumerate} -The procedure for positrons is similar but involves the -annihilation cross section in addition to bremsstrahlung -and inelastic collisions with atomic electrons. +The procedure for positrons is similar but involves the +annihilation cross section in addition to bremsstrahlung +and inelastic collisions with atomic electrons. -After this discussion, it is clear that we need the following -quantities and algorithms for a Class II condensed +After this discussion, it is clear that we need the following +quantities and algorithms for a Class II condensed history simulation of electron and positron transport: \begin{enumerate} \item \index{restricted stopping power} -Restricted stopping powers due to sub-threshold processes. -The collision part of the restricted stopping power deserves -an extra paragraph, it is discussed in section \ref{stopping_power}, the -radiative part of the restricted stopping power is -discussed in association with the bremsstrahlung cross section -(section \ref{bremsstrahlung}). +Restricted stopping powers due to sub-threshold processes. +The collision part of the restricted stopping power deserves +an extra paragraph, it is discussed in section \ref{stopping_power}, the +radiative part of the restricted stopping power is +discussed in association with the bremsstrahlung cross section +(section \ref{bremsstrahlung}). \item \index{cross section!total} \index{cross section!differential} -Total and differential cross sections, as well as -the associated sampling technique, for bremsstrahlung -processes with an energy loss greater than $k_c$ -(section \ref{bremsstrahlung}), -inelastic collisions with energy loss larger than $T_c$ -(section \ref{discrete_inel}), and positron annihilation +Total and differential cross sections, as well as +the associated sampling technique, for bremsstrahlung +processes with an energy loss greater than $k_c$ +(section \ref{bremsstrahlung}), +inelastic collisions with energy loss larger than $T_c$ +(section \ref{discrete_inel}), and positron annihilation (section \ref{annihilation}) \item \index{elastic scattering} \index{angular deflections!inelastic collisions} -Elastic scattering cross sections that take into account -angular deflections due to sub-threshold inelastic +Elastic scattering cross sections that take into account +angular deflections due to sub-threshold inelastic collisions (section \ref{elastic}) \item \index{catastrophic collisions} \index{discrete interactions} \index{discrete interactions!distances between} -A procedure to sample the distance between discrete -interactions on the basis of Eq. \eqref{ch_Ps} +A procedure to sample the distance between discrete +interactions on the basis of Eq. \eqref{ch_Ps} (see section \ref{ch_others}) \item \index{path-length} -A procedure to calculate the path-length from a given -change in energy or vice versa according to +A procedure to calculate the path-length from a given +change in energy or vice versa according to Eq. (\ref{s_vs_E}) (section \ref{ch_others}) \item \index{multiple elastic scattering} \index{electron-step algorithm} \index{condensed history technique} \index{Class II scheme} -A procedure for the approximate solution of -Eq. (\ref{transport3}) which describes the -transport process between subsequent discrete events. -This is perhaps the most difficult part of a -Class II condensed history algorithm. It -involves the construction of a multiple elastic scattering -theory, which is necessary for modelling angular deflections, -and an ``electron-step'' algorithm, which relates the -spatial displacement to the path-length (and possibly -multiple elastic scattering angle). These two aspects -of the EGSnrc CH implementation are discussed +A procedure for the approximate solution of +Eq. (\ref{transport3}) which describes the +transport process between subsequent discrete events. +This is perhaps the most difficult part of a +Class II condensed history algorithm. It +involves the construction of a multiple elastic scattering +theory, which is necessary for modelling angular deflections, +and an ``electron-step'' algorithm, which relates the +spatial displacement to the path-length (and possibly +multiple elastic scattering angle). These two aspects +of the EGSnrc CH implementation are discussed in sections \ref{sec_MS} and \ref{es_algorithm}. \end{enumerate} @@ -576,131 +576,131 @@ \subsubsection{Bremsstrahlung} Spline interpolations for 2 to 50 MeV \end{itemize} In addition, a more elaborate procedure for the contribution of -atomic electrons to the bremsstrahlung process is employed. +atomic electrons to the bremsstrahlung process is employed. \noindent -If {\tt ibr\_nist = 2}, a new set of tabulations prepared at the NRC is employed. -This set uses the nuclear bremsstrahlung cross sections from the NIST data base \cite{SB85,SB86a} -but replaces the electron-electron part of the interaction with exact calculations -in the first Born approximation reported in Ref. \cite{TK08}. +If {\tt ibr\_nist = 2}, a new set of tabulations prepared at the NRC is employed. +This set uses the nuclear bremsstrahlung cross sections from the NIST data base \cite{SB85,SB86a} +but replaces the electron-electron part of the interaction with exact calculations +in the first Born approximation reported in Ref. \cite{TK08}. -The default bremsstrahlung cross section for an electron with a -total energy $E$ incident on an atom with atomic number $Z$, +The default bremsstrahlung cross section for an electron with a +total energy $E$ incident on an atom with atomic number $Z$, differential in the photon energy $k$, is \begin{eqnarray} \label{brems_cs} -{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} k} & = & {A'(E,Z) r_0^2 \alpha -Z (Z + \xi(Z)) \over k} \left\{ \left(1 + {E^{' 2} \over E^2} \right) -\left[ \phi_1(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] -\right. \nonumber \\ & - & \left. -\frac{2}{3}~\frac{E'}{E} \left[\phi_2(\delta) - +{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} k} & = & {A'(E,Z) r_0^2 \alpha +Z (Z + \xi(Z)) \over k} \left\{ \left(1 + {E^{' 2} \over E^2} \right) +\left[ \phi_1(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] +\right. \nonumber \\ & - & \left. +\frac{2}{3}~\frac{E'}{E} \left[\phi_2(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] \right\} \end{eqnarray} -where $E' = E-k$ is the electron energy after the emission of the photon, -$r_0$ the classical electron radius, $\alpha$ the fine structure constant, +where $E' = E-k$ is the electron energy after the emission of the photon, +$r_0$ the classical electron radius, $\alpha$ the fine structure constant, \begin{equation} \delta = 136 Z^{-1/3} 2 \Delta~,\quad \quad \Delta = {k m \over 2 E E'}~, \end{equation} -the functions $\phi_1(\delta), \phi_2(\delta), \xi(Z)$ and -$\tilde{f}_c(E,Z)$ have the same definitions as for the +the functions $\phi_1(\delta), \phi_2(\delta), \xi(Z)$ and +$\tilde{f}_c(E,Z)$ have the same definitions as for the pair production process (see section \ref{pair}), -and $A'(E,Z)$ is an empirical correction factor (see below). -For compounds and mixture the the cross section can be -approximated in the same form with the replacements given -by Eq. (\ref{pair_replace}) in section \ref{pair} (page~\pageref{pair}). +and $A'(E,Z)$ is an empirical correction factor (see below). +For compounds and mixture the the cross section can be +approximated in the same form with the replacements given +by Eq. (\ref{pair_replace}) in section \ref{pair} (page~\pageref{pair}). -Also relevant for the condensed history simulation are the +Also relevant for the condensed history simulation are the moments $M_m$, \begin{equation} \label{brems_moments} -M_m(E,Z; k_{\rm min},k_{\rm max}) \equiv -\int\limits_{k_{\rm min}}^{k_{\rm max}} {\rm d}k k^m -{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} k}~. -\end{equation} -$M_0(E,Z;k_c,T)$ is the total cross section for bremsstrahlung -interactions by an electron with energy $E$ (kinetic energy -$T=E-m$) in a medium $Z$ -that produce photons with an energy above the -threshold energy $k_c$. This cross section is required for -sampling distances between subsequent ``catastrophic'' radiative -events. $M_1(E,Z;0,T)$, multiplied with the density of scattering -centres (atoms or molecules), $n$, -is the average energy lost to radiation per unit path-length, -{\em i.e.} the radiative stopping power. $M_1(E,Z;0,k_c) n$ is then -the restricted radiative stopping power corresponding to $k_c$. -With these definitions in place we can turn back to the -discussion of the empirical correction factor $A'(E,Z)$. -In the original EGS4 implementation $A'(E,Z)$ is based on the -data provided in the article by Koch and Motz \cite{KM59}. -In Ref. \cite{Ro89a} a correction factor $A'(E,Z)$ based -on the ICRU-37 radiative stopping powers was implemented -into the EGS4 data preparation package PEGS4, it is defined as +M_m(E,Z; k_{\rm min},k_{\rm max}) \equiv +\int\limits_{k_{\rm min}}^{k_{\rm max}} {\rm d}k k^m +{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} k}~. +\end{equation} +$M_0(E,Z;k_c,T)$ is the total cross section for bremsstrahlung +interactions by an electron with energy $E$ (kinetic energy +$T=E-m$) in a medium $Z$ +that produce photons with an energy above the +threshold energy $k_c$. This cross section is required for +sampling distances between subsequent ``catastrophic'' radiative +events. $M_1(E,Z;0,T)$, multiplied with the density of scattering +centres (atoms or molecules), $n$, +is the average energy lost to radiation per unit path-length, +{\em i.e.} the radiative stopping power. $M_1(E,Z;0,k_c) n$ is then +the restricted radiative stopping power corresponding to $k_c$. +With these definitions in place we can turn back to the +discussion of the empirical correction factor $A'(E,Z)$. +In the original EGS4 implementation $A'(E,Z)$ is based on the +data provided in the article by Koch and Motz \cite{KM59}. +In Ref. \cite{Ro89a} a correction factor $A'(E,Z)$ based +on the ICRU-37 radiative stopping powers was implemented +into the EGS4 data preparation package PEGS4, it is defined as \begin{equation} \label{brems_aprime} A'(E,Z) = {M_1(E,Z;0,T) \over M_1^{\rm NIST}(E,Z;0,T)} \end{equation} -where $M_m^{\rm NIST}$ is defined in the same way as -in Eq. (\ref{brems_moments}) but the cross section is replaced -by the NIST bremsstrahlung cross section. -EGSnrc, having ``inherited'' the use of the PEGS4 package, -has both options available. The selection is made via -the parameter {\tt IAPRIM} when generating the PEGS4 data -set with {\tt IAPRIM=0} corresponding to the original -$A'$ method and {\tt IAPRIM=1} to the approach of Ref. \cite{Ro89a}. -The other two options available in EGSnrc is to use the NIST or NRC cross sections -directly, this is accomplished by setting {\tt ibr\_nist=1} or {\tt ibr\_nist=2}. +where $M_m^{\rm NIST}$ is defined in the same way as +in Eq. (\ref{brems_moments}) but the cross section is replaced +by the NIST bremsstrahlung cross section. +EGSnrc, having ``inherited'' the use of the PEGS4 package, +has both options available. The selection is made via +the parameter {\tt IAPRIM} when generating the PEGS4 data +set with {\tt IAPRIM=0} corresponding to the original +$A'$ method and {\tt IAPRIM=1} to the approach of Ref. \cite{Ro89a}. +The other two options available in EGSnrc is to use the NIST or NRC cross sections +directly, this is accomplished by setting {\tt ibr\_nist=1} or {\tt ibr\_nist=2}. The result of doing so is \index{ibr\_nist} \index{IAPRIM} \begin{enumerate} \item -The total discrete bremsstrahlung cross section is -calculated using 64-point Gauss-Legendre quadrature in -subroutine {\tt init\_nist\_brems} and the cross section -interpolation coefficients coming from the PEGS4 data set +The total discrete bremsstrahlung cross section is +calculated using 64-point Gauss-Legendre quadrature in +subroutine {\tt init\_nist\_brems} and the cross section +interpolation coefficients coming from the PEGS4 data set modified accordingly \item -Alias-sampling tables are prepared from the NIST or NRC cross sections -differential in the photon emission energy $k$ (which are -available only in a numerical form). These tables are then +Alias-sampling tables are prepared from the NIST or NRC cross sections +differential in the photon emission energy $k$ (which are +available only in a numerical form). These tables are then used at run-time to sample the photon energy \item -The contribution from sub-threshold bremsstrahlung processes to -the restricted stopping power is NOT corrected. This introduces -a slight inconsistency in the treatment of of the bremsstrahlung -process which is irrelevant if $k_c \ll T$ or if -the restricted radiative stopping power is small compared to -the restricted collision stopping power, or both. -A self-consistent implementation is left for the next release +The contribution from sub-threshold bremsstrahlung processes to +the restricted stopping power is NOT corrected. This introduces +a slight inconsistency in the treatment of of the bremsstrahlung +process which is irrelevant if $k_c \ll T$ or if +the restricted radiative stopping power is small compared to +the restricted collision stopping power, or both. +A self-consistent implementation is left for the next release of EGSnrc which will not rely on PEGS4 data sets. \end{enumerate} - + \index{bremsstrahlung!cross section} \index{IAPRIM} -Before we discuss the sampling of the photon energy from -Eq. (\ref{brems_cs}), we compare the default EGSnrc -(and also EGS4) differential bremsstrahlung cross section +Before we discuss the sampling of the photon energy from +Eq. (\ref{brems_cs}), we compare the default EGSnrc +(and also EGS4) differential bremsstrahlung cross section (with {\tt IAPRIM=1} which is default with EGSnrc but was an option with -EGS4)) to the NIST data base for gold and -incident electron kinetic energies of 10 keV, 100 keV, -1 MeV, 10 MeV, 50 MeV and 100 MeV in Fig. \ref{brems_fig1}. +EGS4)) to the NIST data base for gold and +incident electron kinetic energies of 10 keV, 100 keV, +1 MeV, 10 MeV, 50 MeV and 100 MeV in Fig. \ref{brems_fig1}. \begin{figure}[htp] \includegraphics[height=15cm,width=15cm]{figures/brem79} -\caption[Bremsstrahlung cross sections]{\label{brems_fig1} -Differential bremsstrahlung cross sections -for gold at various incident electron energies from the NIST data base -\protect\cite{SB85,SB86a} (thick lines) compared to the +\caption[Bremsstrahlung cross sections]{\label{brems_fig1} +Differential bremsstrahlung cross sections +for gold at various incident electron energies from the NIST data base +\protect\cite{SB85,SB86a} (thick lines) compared to the default EGSnrc (and EGS4) cross sections (thin lines). In both cases {\tt -IAPRIM = 1}, which is the default in the EGSnrc system and was an option +IAPRIM = 1}, which is the default in the EGSnrc system and was an option in the EGS4 system.} \index{IAPRIM} \index{ibr\_nist} \end{figure} -The behaviour for other materials is qualitatively similar. -As one can expect, the two cross sections are virtually -identical at high energies, but there are significant differences -at low energies (although the radiative stopping power is the -same due to the use of $A'$ from Eq. (\ref{brems_aprime})). +The behaviour for other materials is qualitatively similar. +As one can expect, the two cross sections are virtually +identical at high energies, but there are significant differences +at low energies (although the radiative stopping power is the +same due to the use of $A'$ from Eq. (\ref{brems_aprime})). \paragraph{Simulation of discrete bremsstrahlung events, photon energy} \hfill @@ -708,72 +708,72 @@ \subsubsection{Bremsstrahlung} \index{discrete interactions!bremsstrahlung} -In the course of the re-work of the EGS4 sampling routines -we have found an error in the sampling algorithm used in -EGS4. The error, which was most likely not discovered before -because it shows up only if the incident electron energy is -not much larger than the threshold energy $k_c$, is -demonstrated in Fig. \ref{brems_fig2}. This figure compares the distribution -sampled by the EGS4 routine {\tt BREMS} (points) for 100 keV -electrons in aluminum, expressed in +In the course of the re-work of the EGS4 sampling routines +we have found an error in the sampling algorithm used in +EGS4. The error, which was most likely not discovered before +because it shows up only if the incident electron energy is +not much larger than the threshold energy $k_c$, is +demonstrated in Fig. \ref{brems_fig2}. This figure compares the distribution +sampled by the EGS4 routine {\tt BREMS} (points) for 100 keV +electrons in aluminum, expressed in terms of $x$, \begin{equation} \label{brems_x} x = {\ln k/k_c \over \ln T/k_c}~, \end{equation} -to the theoretically expected result (solid line). The threshold -energy $k_c$ was 10 keV ($k_c$ is called {\tt AP} in EGS4 and EGSnrc). -%${\rm d}\sigma_{\rm brem}/{\rm d}x = +to the theoretically expected result (solid line). The threshold +energy $k_c$ was 10 keV ($k_c$ is called {\tt AP} in EGS4 and EGSnrc). +%${\rm d}\sigma_{\rm brem}/{\rm d}x = \begin{figure}[htp] \includegraphics[height=12cm,width=12cm]{figures/Al_100keV} -\caption[{\tt BREMS} bug in EGS4]{\label{brems_fig2} -The distribution of photon energies -sampled by the EGS4 routine {\tt BREMS} (points) for 100 keV -electrons in aluminum, expressed in terms of $x$, defined in -Eq. (\protect\ref{brems_x}), compared to the theoretical +\caption[{\tt BREMS} bug in EGS4]{\label{brems_fig2} +The distribution of photon energies +sampled by the EGS4 routine {\tt BREMS} (points) for 100 keV +electrons in aluminum, expressed in terms of $x$, defined in +Eq. (\protect\ref{brems_x}), compared to the theoretical expectation.} \end{figure} -This finding was a sufficient motivation to completely recode +This finding was a sufficient motivation to completely recode the {\tt BREMS} routine. -The most efficient algorithm for sampling photon energies on +The most efficient algorithm for sampling photon energies on the basis of Eq. (\ref{brems_cs}) appears to be the following: after a change of variables from $k$ to $x$, we have \begin{eqnarray} -{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} x} & = & C -\left\{ \left(1 + {E^{' 2} \over E^2} \right) -\left[ \phi_1(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] -\right. \nonumber \\ & - & \left. -\frac{2}{3}~\frac{E'}{E} \left[\phi_2(\delta) - +{{\rm d} \sigma_{\rm brem}(E,Z) \over {\rm d} x} & = & C +\left\{ \left(1 + {E^{' 2} \over E^2} \right) +\left[ \phi_1(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] +\right. \nonumber \\ & - & \left. +\frac{2}{3}~\frac{E'}{E} \left[\phi_2(\delta) - \frac{4}{3} \ln Z - 4 \tilde{f}_c(E,Z) \right] \right\} \end{eqnarray} -where $C$ is a constant combining factors irrelevant for -the sampling algorithm. Apart from a normalization -constant, the function in the curled brackets, to be denoted -in what follows with $R$, is the -quantity $k {\rm d}\sigma_{\tt brem}/{\rm d}k/Z^2$, shown -with the thin lines in Fig. \ref{brems_fig1}. As can be seen, -it is relatively flat and can therefore be employed as a -rejection function in conjunction with a uniform sampling -of $x$. $R$ retains its absolute maximum\footnote{The actual maximum -for a threshold energy -$k_c$ is slightly smaller and obtained for $k=k_c$, the difference between the -two is negligible except at low electron energies.}, $R_{\rm max}$, for +where $C$ is a constant combining factors irrelevant for +the sampling algorithm. Apart from a normalization +constant, the function in the curled brackets, to be denoted +in what follows with $R$, is the +quantity $k {\rm d}\sigma_{\tt brem}/{\rm d}k/Z^2$, shown +with the thin lines in Fig. \ref{brems_fig1}. As can be seen, +it is relatively flat and can therefore be employed as a +rejection function in conjunction with a uniform sampling +of $x$. $R$ retains its absolute maximum\footnote{The actual maximum +for a threshold energy +$k_c$ is slightly smaller and obtained for $k=k_c$, the difference between the +two is negligible except at low electron energies.}, $R_{\rm max}$, for $k = 0$. It is given by \begin{equation} R_{\rm max} = 28.381 - \frac{4}{3} Z_V \end{equation} -where $Z_V$ is defined in Eq. (\ref{pair_replace}) in section \ref{pair} -and we have made use of Eq. (\ref{pair_phi}) for the functions +where $Z_V$ is defined in Eq. (\ref{pair_replace}) in section \ref{pair} +and we have made use of Eq. (\ref{pair_phi}) for the functions $\phi_1(\delta)$ and $\phi_2(\delta)$. The algorithm is then \begin{enumerate} \item -Calculate $b = \ln T/k_c$ \footnote{As the logarithm of the kinetic -energy is known prior to the call to the {\tt BREMS} routine -(because also used for other purposes), the time consuming -evaluation of the logarithm is not necessary if $\ln(k_c)$ is +Calculate $b = \ln T/k_c$ \footnote{As the logarithm of the kinetic +energy is known prior to the call to the {\tt BREMS} routine +(because also used for other purposes), the time consuming +evaluation of the logarithm is not necessary if $\ln(k_c)$ is stored in the computer memory for each medium.} \item Pick two random numbers, $r_1$ and $r_2$ @@ -784,164 +784,164 @@ \subsubsection{Bremsstrahlung} \item Deliver $k$ \end{enumerate} -Figure \ref{brems_times} shows CPU times in $\mu$s necessary to sample one -photon energy on a 500 MHz PIII computer -using the new algorithm (solid line), -the EGS4 algorithm (dotted line) and using the alias sampling technique +Figure \ref{brems_times} shows CPU times in $\mu$s necessary to sample one +photon energy on a 500 MHz PIII computer +using the new algorithm (solid line), +the EGS4 algorithm (dotted line) and using the alias sampling technique in the case {\tt ibr\_nist} is set to 1. \index{ibr\_nist} \begin{figure}[htp] \includegraphics[height=12cm,width=12cm]{figures/brem_times} -\caption[CPU times for bremsstrahlung sampling]{\label{brems_times} -CPU times (in $\mu$s), as function of the incident electron kinetic -energy $T$, necessary to sample one photon energy using various -algorithms} +\caption[CPU times for bremsstrahlung sampling]{\label{brems_times} +CPU times (in $\mu$s), as function of the incident electron kinetic +energy $T$, necessary to sample one photon energy using various +algorithms} \end{figure} -The threshold energy used was $k_c = 10$~keV and the material -was aluminum. The precise -amount of CPU time spent for sampling the photon energy -is somewhat dependent on $k_c$ and $Z$, but the qualitative -behaviour remains the same for other values of $k_c$. -Apart from being more accurate, the new algorithm is also more -efficient. The CPU time for the alias sampling technique is -energy independent, as one can expect. It is faster at lower -energies but slower at high energies and so the use -of the {\tt ibr\_nist=1} option is not meaningful above 50 MeV -(where also the cross sections are identical). The small -``waves'' in the EGS4 curves are due to the technique employed -to sample the distribution $(1-\varepsilon)/\varepsilon$ -(see the EGS4 manual, Ref \cite{Ne85}) which is at the same time -the reason for the error shown in Fig. \ref{brems_fig2}. +The threshold energy used was $k_c = 10$~keV and the material +was aluminum. The precise +amount of CPU time spent for sampling the photon energy +is somewhat dependent on $k_c$ and $Z$, but the qualitative +behaviour remains the same for other values of $k_c$. +Apart from being more accurate, the new algorithm is also more +efficient. The CPU time for the alias sampling technique is +energy independent, as one can expect. It is faster at lower +energies but slower at high energies and so the use +of the {\tt ibr\_nist=1} option is not meaningful above 50 MeV +(where also the cross sections are identical). The small +``waves'' in the EGS4 curves are due to the technique employed +to sample the distribution $(1-\varepsilon)/\varepsilon$ +(see the EGS4 manual, Ref \cite{Ne85}) which is at the same time +the reason for the error shown in Fig. \ref{brems_fig2}. \index{SLAC-265} -\paragraph{Simulation of discrete bremsstrahlung events, +\paragraph{Simulation of discrete bremsstrahlung events, angular distribution} \hfill \index{bremsstrahlung!angular distribution} -In the original EGS4 implementation, the polar angle of bremsstrahlung -emission with respect to the initial electron direction was fixed -and given by $m/E$. In Ref. \cite{Bi89} an improved angle selection -scheme based on equation 2BS in the article by Koch and Motz \cite{KM59} -was implemented for use with EGS4. This implementation -was adopted in EGSnrc with slight modifications. +In the original EGS4 implementation, the polar angle of bremsstrahlung +emission with respect to the initial electron direction was fixed +and given by $m/E$. In Ref. \cite{Bi89} an improved angle selection +scheme based on equation 2BS in the article by Koch and Motz \cite{KM59} +was implemented for use with EGS4. This implementation +was adopted in EGSnrc with slight modifications. \index{Bielajew, Alex} -Equation 2BS, which is the bremsstrahlung cross section, -differential in the photon energy +Equation 2BS, which is the bremsstrahlung cross section, +differential in the photon energy $k$ and the photon emission angle $\theta$, is \cite{KM59} \begin{eqnarray} \label{brems_angle} -{\rm d}\sigma_{\rm brem}(k,\theta) & = & 4 \alpha Z^2 r_0^2 \frac{{\rm d}k}{k} -{y {\rm d} y \over (y^2 + 1)^2} -\left\{ {16 y^2 r \over (y^2 + 1)^2} - (1+r)^2 + \left[ +{\rm d}\sigma_{\rm brem}(k,\theta) & = & 4 \alpha Z^2 r_0^2 \frac{{\rm d}k}{k} +{y {\rm d} y \over (y^2 + 1)^2} +\left\{ {16 y^2 r \over (y^2 + 1)^2} - (1+r)^2 + \left[ 1 + r^2 - {4 y^2 r \over (y^2 + 1)^2} \right] \ln M(y) \right\} \nonumber \\ -r & = & \frac{E'}{E}~, \quad y = \frac{E}{m} \theta~, \quad \frac{1}{M(y)} = +r & = & \frac{E'}{E}~, \quad y = \frac{E}{m} \theta~, \quad \frac{1}{M(y)} = \Delta^2 + \left( {Z^{1/3} \over 111 (y^2 + 1)} \right)^2 \end{eqnarray} where all definitions following Eq. (\ref{brems_cs}) apply. -Eq. (\ref{brems_angle}) is the result of an extreme relativistic, -first Born and small angle approximation, but it includes a -screening correction -based on a Thomas-Fermi potential. The effect of the screening -of the nucleus by atomic electrons is contained by the -expression in the brackets for $1/M(y)$. This can easily be -verified by comparing Eq. (\ref{brems_angle}) to equation -2BN(a) from the article by Koch and Motz which is derived -with the same approximations but using a bare nuclear potential. -In order to investigate the performance of -Eq. (\ref{brems_angle}) at low incident electron energies, -we can compare it to formula -2BN of the article by Koch and Motz which is for a bare -nucleus but does not involve the extreme relativistic -and small angle -approximations. For a ``fair'' comparison, screening corrections +Eq. (\ref{brems_angle}) is the result of an extreme relativistic, +first Born and small angle approximation, but it includes a +screening correction +based on a Thomas-Fermi potential. The effect of the screening +of the nucleus by atomic electrons is contained by the +expression in the brackets for $1/M(y)$. This can easily be +verified by comparing Eq. (\ref{brems_angle}) to equation +2BN(a) from the article by Koch and Motz which is derived +with the same approximations but using a bare nuclear potential. +In order to investigate the performance of +Eq. (\ref{brems_angle}) at low incident electron energies, +we can compare it to formula +2BN of the article by Koch and Motz which is for a bare +nucleus but does not involve the extreme relativistic +and small angle +approximations. For a ``fair'' comparison, screening corrections must be negligible, this is the case if \begin{equation} -\Delta^2 \gg \left( {Z^{1/3} \over 111 (y^2 + 1)} \right)^2 \quad +\Delta^2 \gg \left( {Z^{1/3} \over 111 (y^2 + 1)} \right)^2 \quad \mbox{or} \quad {k m \over E^2} \gg {2 Z^{2/3} \over 111^2}~, \end{equation} -a condition which is satisfied in a wide range of photon/electron -energy combinations. +a condition which is satisfied in a wide range of photon/electron +energy combinations. \begin{figure}[htp] \includegraphics[height=12cm,width=12cm]{figures/bremang1} -\caption[Low energy bremsstrahlung angular distribution]{\label{brems_angle_fig1} -Angular distribution for emission of 10 keV bremsstrahlung photons -by 100 keV electrons in aluminum. Solid line represents -equation 2BS of Koch and Motz (Eq. (\ref{brems_angle}) in this -report), the dotted line equation 2BN of Koch and Motz, the +\caption[Low energy bremsstrahlung angular distribution]{\label{brems_angle_fig1} +Angular distribution for emission of 10 keV bremsstrahlung photons +by 100 keV electrons in aluminum. Solid line represents +equation 2BS of Koch and Motz (Eq. (\ref{brems_angle}) in this +report), the dotted line equation 2BN of Koch and Motz, the dashed line is 2BS with modifications as discussed in the text.} \end{figure} -Figure \ref{brems_angle_fig1} shows a typical result of such -a comparison. The modification to 2BS that we have undertaken, -shown as a dashed line and obviously at a much better -agreement with formula 2BN, -is fairly simple and allows most of the considerations of -Ref.~\cite{Bi89} to be applied for the sampling procedure. -We note that the leading term of the distribution -2BN is $(1 - \beta \cos \theta)^{-2}$ where $\beta$ is the -electron velocity in units of the speed of light. +Figure \ref{brems_angle_fig1} shows a typical result of such +a comparison. The modification to 2BS that we have undertaken, +shown as a dashed line and obviously at a much better +agreement with formula 2BN, +is fairly simple and allows most of the considerations of +Ref.~\cite{Bi89} to be applied for the sampling procedure. +We note that the leading term of the distribution +2BN is $(1 - \beta \cos \theta)^{-2}$ where $\beta$ is the +electron velocity in units of the speed of light. Approximated for -small angles and high energies it is equivalent to -the leading term of 2BS $(1 + y^2)^{-2}$, apart from a +small angles and high energies it is equivalent to +the leading term of 2BS $(1 + y^2)^{-2}$, apart from a normalization constant: \index{Bielajew, Alex} \begin{eqnarray} (1 - \beta \cos \theta)^2 & \approx & -\left[1 - \beta\left(1 - \frac{\theta^2}{2}\right)\right]^2 = -(1 - \beta)^2 \left[ 1 + \theta^2 {\beta \over 1 - \beta} \right]^2 -\nonumber \\ -& = & (1 - \beta)^2 \left(1 + \beta (1 + \beta) \theta^2 \frac{E}{m} \right)^2 +\left[1 - \beta\left(1 - \frac{\theta^2}{2}\right)\right]^2 = +(1 - \beta)^2 \left[ 1 + \theta^2 {\beta \over 1 - \beta} \right]^2 +\nonumber \\ +& = & (1 - \beta)^2 \left(1 + \beta (1 + \beta) \theta^2 \frac{E}{m} \right)^2 \approx (1 - \beta)^2 (1 + y^2)^2 \end{eqnarray} -We then use +We then use \begin{equation} y^2 = \beta (1 + \beta) \frac{E^2}{m^2} (1 - \cos \theta) \end{equation} -in Eq. (\ref{brems_angle})\footnote{One could go one step -further and modify terms containing $y^2$ in the nominator -as they obviously come from expressions with $\sin^2 \theta$ but -this turns out to not improve the agreement to 2BN significantly} -and otherwise apply the results of +in Eq. (\ref{brems_angle})\footnote{One could go one step +further and modify terms containing $y^2$ in the nominator +as they obviously come from expressions with $\sin^2 \theta$ but +this turns out to not improve the agreement to 2BN significantly} +and otherwise apply the results of Ref. \cite{Bi89} so that the sampling algorithm is as follows: \begin{enumerate} \item -Calculate the maximum of the function in the curled brackets (to be -denoted by $f(y)$), -$f_{\rm max}$, -which is obtained for $y^2 = 0, y^2 = 1$ or $y^2 = y_{\rm max}^2 \equiv +Calculate the maximum of the function in the curled brackets (to be +denoted by $f(y)$), +$f_{\rm max}$, +which is obtained for $y^2 = 0, y^2 = 1$ or $y^2 = y_{\rm max}^2 \equiv 2 \beta (1 + \beta) (E/m)^2$ for the current $E$ and $k$ \item Pick two random numbers $r_1$ and $r_2$ \item -Sample $y^2$ from $y {\rm d}y/(1+y^2)^2$ using +Sample $y^2$ from $y {\rm d}y/(1+y^2)^2$ using \begin{equation} y^2 = {r_1 y_{\rm max}^2 \over 1 + y_{\rm max}^2 (1 - r_1)} \end{equation} \item If $r_2 > f(y)/f_{\rm max}$ go to step 2 \item -Deliver $\cos \theta$, +Deliver $\cos \theta$, \begin{equation} \cos \theta = 1 - {y^2 m^2 \over \beta (1 + \beta) E^2} = 1 - \frac{y^2}{2 y_{\rm max}^2} \end{equation} \end{enumerate} \index{IBRDST} -The efficiency of this algorithm is close to unity for low -energies and decreases logarithmically with increasing energy. -In addition, it requires several logarithm evaluations -(3 in step 1, 1 for each repetition of step 4) and is therefore -rather slow. We have therefore implemented a second bremsstrahlung -angle selection scheme which uses only the leading term of -the angular distribution and can be selected by the user +The efficiency of this algorithm is close to unity for low +energies and decreases logarithmically with increasing energy. +In addition, it requires several logarithm evaluations +(3 in step 1, 1 for each repetition of step 4) and is therefore +rather slow. We have therefore implemented a second bremsstrahlung +angle selection scheme which uses only the leading term of +the angular distribution and can be selected by the user by setting the parameter {\tt IBRDST} in {\tt COMMON/BREMPR/} to zero -(the default {\tt IBRDST} value is 1, -{\em i.e.} modified 2BS from Koch and Motz). -We have found that the original -EGS4 fixed angle approach is not faster than using the -leading term of the angular distribution and have +(the default {\tt IBRDST} value is 1, +{\em i.e.} modified 2BS from Koch and Motz). +We have found that the original +EGS4 fixed angle approach is not faster than using the +leading term of the angular distribution and have therefore removed it. \index{Bielajew, Alex} @@ -967,7 +967,7 @@ \subsubsection{Bremsstrahlung} {\tt nbr\_split} times. It is worth noticing that if {\tt nbr\_split} is set -to zero, the bremsstrahlung event will be skipped. +to zero, the bremsstrahlung event will be skipped. This gives the possibility to study, for instance, the influence of the neglect of bremsstrahlung production on calculated quantities\footnote{A similar result @@ -984,27 +984,27 @@ \subsubsection{Discrete inelastic collisions} \index{electron impact ionization} \index{discrete interactions!inelastic collisions} -%At the present stage, binding effects are disregarded -%in the treatment of electron and positron inelastic -%scattering with atomic electrons in EGSnrc -%(and also in the default EGS4 version). -%Namito {\em et al} have implemented various -%electron impact ionization cross sections for -%use with EGS4 \cite{Na98}. We have studied their approach -%but decided to postpone the inclusion -%of binding effects until a more general treatment -%becomes available that can easily be applied -%to ``catastrophic'' {\em and} sub-threshold inelastic -%collisions. - -When the binding of atomic electrons is ignored (default EGSnrc behavior), -electron-electron scattering can be described by the -M{\o}ller cross section \cite{Mo32a} and -positron-electron scattering by the Bhabha cross section -\cite{Bh35}. When binding is taken into account, interactions of -electrons and positrons with atoms can result in the creation of inner -shell vacancies, this process is usually referred to as electron impact -ionization (EII). +%At the present stage, binding effects are disregarded +%in the treatment of electron and positron inelastic +%scattering with atomic electrons in EGSnrc +%(and also in the default EGS4 version). +%Namito {\em et al} have implemented various +%electron impact ionization cross sections for +%use with EGS4 \cite{Na98}. We have studied their approach +%but decided to postpone the inclusion +%of binding effects until a more general treatment +%becomes available that can easily be applied +%to ``catastrophic'' {\em and} sub-threshold inelastic +%collisions. + +When the binding of atomic electrons is ignored (default EGSnrc behavior), +electron-electron scattering can be described by the +M{\o}ller cross section \cite{Mo32a} and +positron-electron scattering by the Bhabha cross section +\cite{Bh35}. When binding is taken into account, interactions of +electrons and positrons with atoms can result in the creation of inner +shell vacancies, this process is usually referred to as electron impact +ionization (EII). \paragraph{M{\o}ller scattering} \hfill \index{M{\o}ller cross section} @@ -1012,67 +1012,67 @@ \subsubsection{Discrete inelastic collisions} \index{discrete interactions!M{\o}ller scattering} \index{cross section!M{\o}ller} -The M{\o}ller cross section, which is the cross section -for electron-electron scattering differential in the kinetic energy +The M{\o}ller cross section, which is the cross section +for electron-electron scattering differential in the kinetic energy $T'$ of the scattered electron which is initially at rest, is -\cite{ICRU37} +\cite{ICRU37} \begin{equation} \label{moller_cs} -{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} = -{2 \pi r_0^2 m \over \beta^2}~\frac{1}{T^{\prime 2}} \left[ +{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} = +{2 \pi r_0^2 m \over \beta^2}~\frac{1}{T^{\prime 2}} \left[ 1 + {T^{' 2} \over (T - T')^2} + {\tau^2 \over (\tau+1)^2}~ -\left(\frac{T'}{T}\right)^2 +\left(\frac{T'}{T}\right)^2 - {2 \tau + 1 \over (\tau + 1)^2}~{T' \over T - T'} \right] \end{equation} -where $\beta$ is the incident electron velocity in units of the -speed of light, $T$ the incident kinetic energy and $\tau = T/m$. -Because the two electrons are indistinguishable, Eq. \eqref{moller_cs} -is symmetric with respect to exchange of the energies of the two scattered -particles. Per definition, the electron with the higher energy -after the collision is considered to be the primary, so that -the total cross section for M{\o}ller interactions is obtained +where $\beta$ is the incident electron velocity in units of the +speed of light, $T$ the incident kinetic energy and $\tau = T/m$. +Because the two electrons are indistinguishable, Eq. \eqref{moller_cs} +is symmetric with respect to exchange of the energies of the two scattered +particles. Per definition, the electron with the higher energy +after the collision is considered to be the primary, so that +the total cross section for M{\o}ller interactions is obtained via integration of Eq. \eqref{moller_cs} from $T_c$ to $T/2$: \begin{equation} \label{moller_cs1} -\sigma_{\rm inel}^- = \int\limits_{T_c}^{T/2} -{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} {\rm d}T' +\sigma_{\rm inel}^- = \int\limits_{T_c}^{T/2} +{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} {\rm d}T' \end{equation} \index{TE} \index{AE} -In EGS4 and EGSnrc $T_c$ is called {\tt TE} and the corresponding +In EGS4 and EGSnrc $T_c$ is called {\tt TE} and the corresponding total energy {\tt AE}. The threshold kinetic energy above which M{\o}ller -events can occur is obviously $2 T_c$. The integration of -Eq. \eqref{moller_cs1} is trivial, and is evaluated by the -PEGS function {\tt AMOLTM}. +events can occur is obviously $2 T_c$. The integration of +Eq. \eqref{moller_cs1} is trivial, and is evaluated by the +PEGS function {\tt AMOLTM}. \index{AMOLTM} \index{PEGS4!AMOLTM} \index{M{\o}ller scattering!sampling of} -To sample the energy of the scattered electron on the basis of -Eq. \eqref{moller_cs}, one makes a change of variables to -$\varepsilon = T'/T$, which can take values between -$\varepsilon_0 = T_c/T$ and $1/2$, and after re-arranging +To sample the energy of the scattered electron on the basis of +Eq. \eqref{moller_cs}, one makes a change of variables to +$\varepsilon = T'/T$, which can take values between +$\varepsilon_0 = T_c/T$ and $1/2$, and after re-arranging obtains \cite{Ne85} \begin{equation} \label{moller_cs2} -{{\rm d} \sigma_{\rm inel}^- \over {\rm d} \varepsilon} = -C \left( {\varepsilon_0 \over 1 - 2 \varepsilon_0}~\frac{1}{\varepsilon^2} -\right) g(\varepsilon) -\end{equation} -where $C$ is a constant irrelevant for the sampling algorithm, -the expression in the brackets is a normalized PDF for $\varepsilon$ -and $g(\varepsilon)$ will be used as a rejection function. -At this point it is worth noticing that there is an error in the EGS4 manual -for the rejection function $g(\varepsilon)$ and the resulting error -in the {\tt MOLLER} sampling routine was not -corrected in EGS4 until 1996 \cite{Bi96b}. The proper rejection function -reads +{{\rm d} \sigma_{\rm inel}^- \over {\rm d} \varepsilon} = +C \left( {\varepsilon_0 \over 1 - 2 \varepsilon_0}~\frac{1}{\varepsilon^2} +\right) g(\varepsilon) +\end{equation} +where $C$ is a constant irrelevant for the sampling algorithm, +the expression in the brackets is a normalized PDF for $\varepsilon$ +and $g(\varepsilon)$ will be used as a rejection function. +At this point it is worth noticing that there is an error in the EGS4 manual +for the rejection function $g(\varepsilon)$ and the resulting error +in the {\tt MOLLER} sampling routine was not +corrected in EGS4 until 1996 \cite{Bi96b}. The proper rejection function +reads \index{SLAC-265} \index{Bielajew, Alex} \begin{equation} \begin{split} -g(\varepsilon) &= {1 + g_2 \varepsilon^2 + r (r - g_3) \over -g_{\rm max} } \\ g_{\rm max} &= 1 + \frac{5}{4} g_2~, \quad +g(\varepsilon) &= {1 + g_2 \varepsilon^2 + r (r - g_3) \over +g_{\rm max} } \\ g_{\rm max} &= 1 + \frac{5}{4} g_2~, \quad g_2 = {\tau^2 \over (\tau + 1)^2}~, \quad g_3 = {2 \tau + 1 \over (\tau+1)^2}~, \quad r = {\varepsilon \over 1 - \varepsilon } ~. \end{split} @@ -1082,10 +1082,10 @@ \subsubsection{Discrete inelastic collisions} \item Calculate quantities dependent only on $T$, namely \begin{displaymath} -\tau,~g_2,~g_3,~g_{\rm max} +\tau,~g_2,~g_3,~g_{\rm max} \end{displaymath} \item Pick two random numbers, $r_1$ and $r_2$ -\item Sample $\varepsilon$ from the expression in the brackets in +\item Sample $\varepsilon$ from the expression in the brackets in Eq. \eqref{moller_cs2} using \begin{equation} \varepsilon = {T_c \over T - (T - 2 T_c) r_1} @@ -1093,55 +1093,55 @@ \subsubsection{Discrete inelastic collisions} \item Calculate $g(\varepsilon)$, if $r_2 > g(\varepsilon)$ go to step 2 \item Deliver $\varepsilon$ \end{enumerate} -The efficiency of this algorithm is close to unity for -low incident energies $T$ but goes to $4/9$ at high energies. -A better approach would be the following: We can rewrite -Eq. \eqref{moller_cs1} as +The efficiency of this algorithm is close to unity for +low incident energies $T$ but goes to $4/9$ at high energies. +A better approach would be the following: We can rewrite +Eq. \eqref{moller_cs1} as \begin{equation} \begin{split} -{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} & = +{{\rm d} \sigma_{\rm inel}^- \over {\rm d}T'} & = {2 \pi r_0^2 m \over \beta^2}~ \left[ F(T') + F(T-T') \right] \\ -F(T') &= \frac{1}{T^{\prime 2}} + {1 \over 2 (T+m)^2} - +F(T') &= \frac{1}{T^{\prime 2}} + {1 \over 2 (T+m)^2} - {2 \tau + 1 \over (\tau+1)^2}~\frac{1}{T T'} ~. \end{split} \end{equation} -If we now extend the range for $T'$ to $T-T_c$, we can drop -$F(T-T')$, and sample $T'$ from $F(T')$ only. At the end -$T'$ will be set to Min$(T',T-T')$. There are several possibilities -to sample $T'$ from $F(T')$. For instance, one can use -$1/T^{\prime 2}$ as a PDF and +If we now extend the range for $T'$ to $T-T_c$, we can drop +$F(T-T')$, and sample $T'$ from $F(T')$ only. At the end +$T'$ will be set to Min$(T',T-T')$. There are several possibilities +to sample $T'$ from $F(T')$. For instance, one can use +$1/T^{\prime 2}$ as a PDF and \begin{equation} -g'(T') = \frac{1}{g'_{\rm max}} \left(1 + {T^{\prime 2} \over 2 (T+m)^2} +g'(T') = \frac{1}{g'_{\rm max}} \left(1 + {T^{\prime 2} \over 2 (T+m)^2} - {2 \tau + 1 \over (\tau + 1)^2}~ \frac{T'}{T} \right) \end{equation} -as a rejection function. Here, +as a rejection function. Here, \begin{equation} g_{\rm max} = \left\{ -\begin{array}{r@{~~, \quad}l} +\begin{array}{r@{~~, \quad}l} 1 & \text{if}~~ \tau \le 2 + \sqrt{6} \\ {3 \tau^2 \over 2 (\tau+1)^2 } & \text{else} \end{array} \right. \end{equation} -The efficiency of such an algorithm is $2/3$ at high energies and -therefore 1.5 times better than the one used in EGS4 and EGSnrc. -Anticipating changes in the treatment of discrete inelastic -scattering, in order to take into account electron binding -effects, in the near future we have not implemented +The efficiency of such an algorithm is $2/3$ at high energies and +therefore 1.5 times better than the one used in EGS4 and EGSnrc. +Anticipating changes in the treatment of discrete inelastic +scattering, in order to take into account electron binding +effects, in the near future we have not implemented this more efficient algorithm. -The polar scattering angles $\theta$ and $\theta'$ -in M{\o}ller events are uniquely -determined by the kinematics. They are given by +The polar scattering angles $\theta$ and $\theta'$ +in M{\o}ller events are uniquely +determined by the kinematics. They are given by \begin{equation} \label{moller_angles} \begin{split} -\cos \theta & = \sqrt{\frac{T-T'}{T}~\frac{T+2 m}{T-T' + 2 m}}~, \quad +\cos \theta & = \sqrt{\frac{T-T'}{T}~\frac{T+2 m}{T-T' + 2 m}}~, \quad \text{for the higher energy electron,} \\ -\cos \theta' & = \sqrt{\frac{T'}{T}~\frac{T+2 m}{T' + 2 m}}~, \quad +\cos \theta' & = \sqrt{\frac{T'}{T}~\frac{T+2 m}{T' + 2 m}}~, \quad \quad \quad \quad \quad \text{for the lower energy electron.} \end{split} \end{equation} -The azimuthal angles are opposite and sample uniformly between +The azimuthal angles are opposite and sample uniformly between zero and $2 \pi$. \paragraph{Bhabha scattering} \hfill @@ -1152,55 +1152,55 @@ \subsubsection{Discrete inelastic collisions} The Bhabha cross section, which is the cross section for positron-electron scattering differential in the kinetic energy -$T'$ of the scattered electron which is initially at rest, is +$T'$ of the scattered electron which is initially at rest, is given by \cite{Ne85} \begin{equation} \label{bhabha_cs} -{{\rm d} \sigma_{\rm inel}^+ \over {\rm d}T'} = -{2 \pi r_0^2 m \over T^2} \left[ \frac{1}{\varepsilon}\left( -{1 \over \varepsilon \beta^2} - B_1 \right) + B_2 + \varepsilon +{{\rm d} \sigma_{\rm inel}^+ \over {\rm d}T'} = +{2 \pi r_0^2 m \over T^2} \left[ \frac{1}{\varepsilon}\left( +{1 \over \varepsilon \beta^2} - B_1 \right) + B_2 + \varepsilon (\varepsilon B_4 - B_3 ) \right] -\end{equation} -where $T$ is the incident positron kinetic energy and +\end{equation} +where $T$ is the incident positron kinetic energy and the following definitions apply: \begin{equation} \label{vhabha_cs1} \begin{split} -\varepsilon & = \frac{T'}{T}, \quad \tau = \frac{T}{m}, -\quad y = {1 \over \tau + 2}, \quad \beta^2 = {\tau (\tau + 2) \over +\varepsilon & = \frac{T'}{T}, \quad \tau = \frac{T}{m}, +\quad y = {1 \over \tau + 2}, \quad \beta^2 = {\tau (\tau + 2) \over (\tau + 1)^2} \\ -B_1 &= 2 - y^2, \quad B_2 = (1 - 2 y)(3 + y^2), \quad B_3 = B_4 + +B_1 &= 2 - y^2, \quad B_2 = (1 - 2 y)(3 + y^2), \quad B_3 = B_4 + (1 - 2 y)^2, \quad B_4 = (1 - 2 y)^3 \end{split} \end{equation} -The range of possible $T'$ values is $T_c \cdots T$ -({\em i.e.} the positron may have energy less then $T_c$ -after Bhabha scattering). -The total discrete Bhabha cross section is then obtained -by integrating Eq. \eqref{bhabha_cs} in the allowed range, -{\em i.e.} +The range of possible $T'$ values is $T_c \cdots T$ +({\em i.e.} the positron may have energy less then $T_c$ +after Bhabha scattering). +The total discrete Bhabha cross section is then obtained +by integrating Eq. \eqref{bhabha_cs} in the allowed range, +{\em i.e.} \begin{equation} -\sigma_{\rm inel}^+ = \int\limits_{T_c}^T {\rm d}T' +\sigma_{\rm inel}^+ = \int\limits_{T_c}^T {\rm d}T' {{\rm d} \sigma_{\rm inel}^+ \over {\rm d}T'}~. \end{equation} -The integration is trivial but the result rather lengthy and therefore not -given here. The total discrete Bhabha cross section is evaluated +The integration is trivial but the result rather lengthy and therefore not +given here. The total discrete Bhabha cross section is evaluated by the PEGS function {\tt BHABTM}. \index{PEGS4!BHABTM} \index{Bhabha scattering!sampling of} -The method employed to sample scattered electron energies on the basis -of Eq. \eqref{bhabha_cs} is similar to the M{\o}ller method. -The electron energy fraction $\varepsilon$ is sampled from -$1/\varepsilon^2$, the rejection function $g(\varepsilon)$ is +The method employed to sample scattered electron energies on the basis +of Eq. \eqref{bhabha_cs} is similar to the M{\o}ller method. +The electron energy fraction $\varepsilon$ is sampled from +$1/\varepsilon^2$, the rejection function $g(\varepsilon)$ is \begin{equation} -g(\varepsilon) = 1 - \beta^2 \varepsilon (B_1 - \varepsilon (B_2 +g(\varepsilon) = 1 - \beta^2 \varepsilon (B_1 - \varepsilon (B_2 - \varepsilon (B_3 - \varepsilon B_4)))~. \end{equation} -As in the case of M{\o}ller scattering, there was an error for -the Bhabha scattering rejection function which was not corrected -until 1996 \cite{Bi96b}. Bhabha polar scattering angles are -given by Eq. \eqref{moller_angles}. +As in the case of M{\o}ller scattering, there was an error for +the Bhabha scattering rejection function which was not corrected +until 1996 \cite{Bi96b}. Bhabha polar scattering angles are +given by Eq. \eqref{moller_angles}. \index{Bielajew, Alex} \subsubsection{Electron Impact Ionization} @@ -1210,32 +1210,32 @@ \subsubsection{Electron Impact Ionization} \index{electron impact ionization} \index{discrete interactions!electron impact ionization} -Since 2003 the EGSnrc system has the ability to explicitely -simulate the creation of inner shell vacancies by electron or positron -impact for all K- and L-shells with binding energies above 1 keV. -This option can be turned on by setting the parameter {\tt eii\_flag} found -in {\tt COMIN/EII-DATA} to one. The differential cross sections used are -based on a semi-empirical theory described in Ref. \cite{Ka02b}. By default, -total EII cross sections are obtained by a numerical integration from these -differential cross sections. However, the user has the option to use +Since 2003 the EGSnrc system has the ability to explicitely +simulate the creation of inner shell vacancies by electron or positron +impact for all K- and L-shells with binding energies above 1 keV. +This option can be turned on by setting the parameter {\tt eii\_flag} found +in {\tt COMIN/EII-DATA} to one. The differential cross sections used are +based on a semi-empirical theory described in Ref. \cite{Ka02b}. By default, +total EII cross sections are obtained by a numerical integration from these +differential cross sections. However, the user has the option to use total EII cross sections from Gryzi\'{n}ski \cite{Gr65a}, Casnati \cite{Ca82} -Kolbenstvedt \cite{Ko67}, or Bote and Salvat \cite{BS08}. -This is accomplished by changing the parameter +Kolbenstvedt \cite{Ko67}, or Bote and Salvat \cite{BS08}. +This is accomplished by changing the parameter {\tt eii\_xfile} found in {\tt COMIN/MEDIA} to {\tt gryzinski, casnati, kolbenstvedt} or {\tt penelope}. Users can also use their own -set of EII cross sections by setting +set of EII cross sections by setting {\tt eii\_xfile} to an arbitrary charater string. -See section \ref{step_2} on page \pageref{eii_xfile_description} +See section \ref{step_2} on page \pageref{eii_xfile_description} for more detials. -When EII is turned on and there are K- or L-shells with -binding energies above {\tt AE} or {\tt AP} in the medium where a discrete -inelastic collision takes place, the probability for the collision being -with the K- or L-shell is computed. If a random number is less than this probability, -the interaction is simulated according to the EII differential cross sections of -Ref. \cite{Ka02b} and an inner shell vacancy is created that is subsequently relaxed +When EII is turned on and there are K- or L-shells with +binding energies above {\tt AE} or {\tt AP} in the medium where a discrete +inelastic collision takes place, the probability for the collision being +with the K- or L-shell is computed. If a random number is less than this probability, +the interaction is simulated according to the EII differential cross sections of +Ref. \cite{Ka02b} and an inner shell vacancy is created that is subsequently relaxed \index{relaxations} -using the subroutine {\tt RELAX} (see section \ref{relax}). Otherwise the -interaction is simulated according to the M{\o}ller or Bhabha cross sections. +using the subroutine {\tt RELAX} (see section \ref{relax}). Otherwise the +interaction is simulated according to the M{\o}ller or Bhabha cross sections. \subsubsection{Two Photon Positron-Electron Annihilation} \setcounter{equation}{0} @@ -1245,88 +1245,88 @@ \subsubsection{Two Photon Positron-Electron Annihilation} \index{discrete interactions!annihilation} \index{cross section!annihilation} -We have adopted the treatment -of the two photon positron annihilation process from -EGS4 without modifications. For completeness -we give below the differential and total annihilation +We have adopted the treatment +of the two photon positron annihilation process from +EGS4 without modifications. For completeness +we give below the differential and total annihilation cross sections as used in EGS4 and EGSnrc. -The cross -section, differential in the energy $k$ of the one -of the annihilation photons, for an incident positron with +The cross +section, differential in the energy $k$ of the one +of the annihilation photons, for an incident positron with a total energy of $E$ is \cite{Ne85} \begin{equation} \label{annih_cs} -{{\rm d} \sigma_{\rm annih} \over {\rm d} k} = {\pi r_0^2 \over \tau +{{\rm d} \sigma_{\rm annih} \over {\rm d} k} = {\pi r_0^2 \over \tau (\tau+2)} \left[ S_1(\kappa) + S_1(\tau + 2 - \kappa) \right] \end{equation} -where $\tau$ and $\kappa$ are the positron kinetic energy and photon -energy in units of $m$ and +where $\tau$ and $\kappa$ are the positron kinetic energy and photon +energy in units of $m$ and \begin{equation} -S_1(x) = \frac{1}{x} \left( \tau + 2 + 2 {\tau + 1 \over \tau + 2} - +S_1(x) = \frac{1}{x} \left( \tau + 2 + 2 {\tau + 1 \over \tau + 2} - \frac{1}{x} \right) - 1~. \end{equation} -Equation (\ref{annih_cs}) is obviously symmetric -under exchange of the annihilation photons, +Equation (\ref{annih_cs}) is obviously symmetric +under exchange of the annihilation photons, the second photon has the energy $E + m - k$. -The polar emission angles of the annihilation photons are uniquely +The polar emission angles of the annihilation photons are uniquely determined by the kinematics and given by \cite{Ne85} \begin{equation} \label{annih_k_theta} -k = { m \over 1 - a \cos \theta}~, +k = { m \over 1 - a \cos \theta}~, \quad a = \sqrt{{\tau \over \tau + 2}} \end{equation} -so that the minimum and maximum possible photon energies are +so that the minimum and maximum possible photon energies are \begin{equation} \label{annih_kminmax} k_{\rm min} = {m \over 1 + a} ~, \quad k_{\rm max} = {m \over 1 - a}~. \end{equation} -The total annihilation cross section -is obtained by integrating Eq. (\ref{annih_cs}) +The total annihilation cross section +is obtained by integrating Eq. (\ref{annih_cs}) over the allowed $k$-range and can be written as \begin{equation} -\sigma_{\rm annih} = {\pi r_0^2 \over \tau + 2} \left[ -{\tau^2 + 6 \tau + 6 \over \tau (\tau + 2)} \ln\left(\tau + 1 -+ \sqrt{\tau (\tau + 2)} \right) - {\tau + 4 \over \sqrt{\tau (\tau + 2)}} +\sigma_{\rm annih} = {\pi r_0^2 \over \tau + 2} \left[ +{\tau^2 + 6 \tau + 6 \over \tau (\tau + 2)} \ln\left(\tau + 1 ++ \sqrt{\tau (\tau + 2)} \right) - {\tau + 4 \over \sqrt{\tau (\tau + 2)}} \right] \end{equation} -At high energies ($\tau \gg 1$) $\sigma_{\rm annih}$ -decreases as $(\ln \tau)/\tau$, for $\tau \to 0$ the cross section -tends to infinity ({\em i.e.} positrons always annihilate at rest -if they have not annihilated before). +At high energies ($\tau \gg 1$) $\sigma_{\rm annih}$ +decreases as $(\ln \tau)/\tau$, for $\tau \to 0$ the cross section +tends to infinity ({\em i.e.} positrons always annihilate at rest +if they have not annihilated before). -The annihilation process is a ``catastrophic'' event and -treated discretely. +The annihilation process is a ``catastrophic'' event and +treated discretely. \index{annihilation!sampling of} -To sample the energy of one of the photons from -Eq. (\ref{annih_cs}), one makes a change in variables -to $\varepsilon = \kappa/(\tau+2)$, drops the second +To sample the energy of one of the photons from +Eq. (\ref{annih_cs}), one makes a change in variables +to $\varepsilon = \kappa/(\tau+2)$, drops the second $S_1$ because of the symmetry, and after re-arranging obtains \begin{eqnarray} -{{\rm d} \sigma_{\rm annih} \over {\rm d}\varepsilon} & = & +{{\rm d} \sigma_{\rm annih} \over {\rm d}\varepsilon} & = & C f(\varepsilon) g(\varepsilon) \\ f(\varepsilon) & = & {1 \over \ln[(1-\varepsilon_0)/\varepsilon_0]}~ -\frac{1}{\varepsilon}~, \quad -%g(\varepsilon) = 1 - \varepsilon + {2 (\tau + 1) \varepsilon - 1 \over +\frac{1}{\varepsilon}~, \quad +%g(\varepsilon) = 1 - \varepsilon + {2 (\tau + 1) \varepsilon - 1 \over %(\tau + 2)^2 } -g(\varepsilon) = 1 - {[\varepsilon (\tau+2) - 1) ]^2 \over \varepsilon +g(\varepsilon) = 1 - {[\varepsilon (\tau+2) - 1) ]^2 \over \varepsilon (\tau^2 + 4 \tau + 2) } \end{eqnarray} -where $C$ is a constant that contains factors irrelevant for -the sampling procedure and $\varepsilon_0$ the minimum +where $C$ is a constant that contains factors irrelevant for +the sampling procedure and $\varepsilon_0$ the minimum possible value for $\varepsilon$, \begin{equation} \varepsilon_0 = {1 \over (\tau+2) (1 + a)}~. \end{equation} -The function $f(\varepsilon)$ is a normalized PDF, $g(\varepsilon)$ -is always positive and +The function $f(\varepsilon)$ is a normalized PDF, $g(\varepsilon)$ +is always positive and has a maximum -of $1$ for $\epsilon = 1/(\tau+2)$ and -thus is a valid rejection function\footnote{Note that our $g(\varepsilon)$ is -the $g(\varepsilon)$ defined in Eq (2.12.26) of the the EGS4 manual +of $1$ for $\epsilon = 1/(\tau+2)$ and +thus is a valid rejection function\footnote{Note that our $g(\varepsilon)$ is +the $g(\varepsilon)$ defined in Eq (2.12.26) of the the EGS4 manual divided by its maximum.}. The sampling algorithm is then as follows: \begin{enumerate} \item @@ -1338,7 +1338,7 @@ \subsubsection{Two Photon Positron-Electron Annihilation} \item Pick two random numbers, $r_1$ and $r_2$ \item -Set +Set \begin{equation} \varepsilon = \varepsilon_0 \exp\left(r_1 b\right) \end{equation} @@ -1351,35 +1351,35 @@ \subsubsection{Two Photon Positron-Electron Annihilation} \index{annihilation!single photon} \index{annihilation!three photon} -At this point -one should perhaps mention that a single photon or three or more -photon annihilation processes in the nuclear field are also -possible. Messel and Crawford \cite{MC70} point out that -the ratio of one to two photon annihilation cross sections is small -until higher energies are reached, at which point the absolute -value of the cross section is small. Thus, the single -photon annihilation process is ignored. Positron annihilation to -three or more photons is even less likely than one photon -annihilation and therefore also ignored. +At this point +one should perhaps mention that a single photon or three or more +photon annihilation processes in the nuclear field are also +possible. Messel and Crawford \cite{MC70} point out that +the ratio of one to two photon annihilation cross sections is small +until higher energies are reached, at which point the absolute +value of the cross section is small. Thus, the single +photon annihilation process is ignored. Positron annihilation to +three or more photons is even less likely than one photon +annihilation and therefore also ignored. \index{annihilation!at rest} -If positrons do not annihilate in flight, they -annihilate at rest producing two photons. As one can easily -verify from Eq. \eqref{annih_k_theta} and \eqref{annih_kminmax}, -the photon energies go to $m$ as $\tau$ goes to zero. -In addition, the cross section differential in the -photon emission angle becomes uniform in the limit $\tau \to 0$. +If positrons do not annihilate in flight, they +annihilate at rest producing two photons. As one can easily +verify from Eq. \eqref{annih_k_theta} and \eqref{annih_kminmax}, +the photon energies go to $m$ as $\tau$ goes to zero. +In addition, the cross section differential in the +photon emission angle becomes uniform in the limit $\tau \to 0$. \index{radiative splitting} \index{variance reduction!radiative splitting} \index{nbr\_split} -If radiative splitting is set ({\tt nbr\_split} $> 1$), -the annihilation process will produce 2 {\tt nbr\_split} photons, -each carrying the fraction 1/{\tt nbr\_split} from the positron weight. -Simultaneous production of {\tt nbr\_split} annihilation -events allows the quantity $b$ (see step 1) as well as -parameter related to angular rotations to be re-used -{\tt nbr\_split} times. +If radiative splitting is set ({\tt nbr\_split} $> 1$), +the annihilation process will produce 2 {\tt nbr\_split} photons, +each carrying the fraction 1/{\tt nbr\_split} from the positron weight. +Simultaneous production of {\tt nbr\_split} annihilation +events allows the quantity $b$ (see step 1) as well as +parameter related to angular rotations to be re-used +{\tt nbr\_split} times. \subsubsection{Collision stopping power} \label{stopping_power} @@ -1390,121 +1390,121 @@ \subsubsection{Collision stopping power} \index{Seltzer, Stephen} \index{Berger, Martin} -EGSnrc ``inherits'' the treatment of restricted collision -stopping powers from EGS4, {\em i.e.} uses the formulas -recommended by Seltzer and Berger \cite{BS64} which are based -on the Bethe-Bloch theory \cite{Be30,Be32,Bl33}. The standard -treatment (see also ICRU report 37 \cite{ICRU37} which was -used as the source of the formulas below) -assumes that there is a certain value for energy -transfer to atomic electrons, $T_{\rm med}$, that is (i) -large compared to the binding energies (ii) corresponds to -an impact parameter that is large compared to the atomic -dimensions. Collision processes that are associated with -energy loss $T'$ less than $T_{\rm med}$ are treated according to +EGSnrc ``inherits'' the treatment of restricted collision +stopping powers from EGS4, {\em i.e.} uses the formulas +recommended by Seltzer and Berger \cite{BS64} which are based +on the Bethe-Bloch theory \cite{Be30,Be32,Bl33}. The standard +treatment (see also ICRU report 37 \cite{ICRU37} which was +used as the source of the formulas below) +assumes that there is a certain value for energy +transfer to atomic electrons, $T_{\rm med}$, that is (i) +large compared to the binding energies (ii) corresponds to +an impact parameter that is large compared to the atomic +dimensions. Collision processes that are associated with +energy loss $T'$ less than $T_{\rm med}$ are treated according to the theory of Bethe, the main result of which is that \begin{equation} -L_{\rm coll}^\pm(T,T' < T_{\rm med}) = {2 \pi r_0^2 m n \over \beta^2} -\left[ \ln \left(2 m \beta^2 T_{\rm med} \over (1 - \beta^2) I^2 \right) +L_{\rm coll}^\pm(T,T' < T_{\rm med}) = {2 \pi r_0^2 m n \over \beta^2} +\left[ \ln \left(2 m \beta^2 T_{\rm med} \over (1 - \beta^2) I^2 \right) - \beta^2 - \delta \right] \end{equation} -where $\beta$ is again the electron velocity in units of -the speed of light, $I$ is the mean ionization energy and -$\delta$ the density effect correction that takes into +where $\beta$ is again the electron velocity in units of +the speed of light, $I$ is the mean ionization energy and +$\delta$ the density effect correction that takes into \index{density effect} -account the polarization of the medium due to the electron field. -As $T_{\rm med}$ is defined being large compared to the binding energies of -the atom, collision processes with energy transfer larger -than $T_{\rm med}$ can be treated using the M{\o}ller \cite{Mo32a} (electrons) -or Bhabha \cite{Bh35} (positron) cross section (see also section +account the polarization of the medium due to the electron field. +As $T_{\rm med}$ is defined being large compared to the binding energies of +the atom, collision processes with energy transfer larger +than $T_{\rm med}$ can be treated using the M{\o}ller \cite{Mo32a} (electrons) +or Bhabha \cite{Bh35} (positron) cross section (see also section \ref{discrete_inel}), {\em i.e.} \index{$T_{\rm med}$} \index{M{\o}ller cross section} \index{Bhabha cross section} \begin{equation} -L_{\rm coll}^\pm(T,T' > T_{\rm med}) = \int\limits_{T_{\rm med}}^{T_c} +L_{\rm coll}^\pm(T,T' > T_{\rm med}) = \int\limits_{T_{\rm med}}^{T_c} {\rm d}T' T' {{\rm d} \sigma_{\rm inel}^\pm \over {\rm d}T'} \end{equation} -Using some additional approximations, $T_{\rm med}$ drops out -in the sum of $L_{\rm coll}^\pm(E,T' < T_{\rm med})$ and +Using some additional approximations, $T_{\rm med}$ drops out +in the sum of $L_{\rm coll}^\pm(E,T' < T_{\rm med})$ and $L_{\rm coll}^\pm(E,T' > T_{\rm med})$ and one obtains \begin{equation} -L_{\rm coll}^\pm(T,T_c) = {2 \pi r_0^2 m n \over \beta^2} +L_{\rm coll}^\pm(T,T_c) = {2 \pi r_0^2 m n \over \beta^2} \left[ \ln {T^2 \over I^2} + \ln(1 + \tau/2) + G^\pm(\tau) - \delta \right] \end{equation} -where $\tau = T/m$ and the functions $G^\pm$ are different for -electrons and positrons due differences in the M{\o}ller and +where $\tau = T/m$ and the functions $G^\pm$ are different for +electrons and positrons due differences in the M{\o}ller and Bhabha cross sections and are given by \index{Bhabha scattering} \begin{equation} \begin{split} -G^-(\tau) & = -1 - \beta^2 + \ln\left[ \eta (1 - \eta) \right] + -{1 \over 1 - \eta} + (1 - \beta^2) \left[ {\tau^2 \eta^2 \over 2} + +G^-(\tau) & = -1 - \beta^2 + \ln\left[ \eta (1 - \eta) \right] + +{1 \over 1 - \eta} + (1 - \beta^2) \left[ {\tau^2 \eta^2 \over 2} + (2 \tau + 1) \ln(1 - \eta) \right] \\ -G^+(\tau) & = \ln(4 \eta) - \beta^2 \left[ 1 + (2 - y^2) \eta - -(3 + y^2) {y \tau \over 2} \eta^2 + (1 + y \tau) {y^2 \tau^2 \over 3} \eta^3 -- {y^3 \tau^3 \over 4} \eta^4 +G^+(\tau) & = \ln(4 \eta) - \beta^2 \left[ 1 + (2 - y^2) \eta - +(3 + y^2) {y \tau \over 2} \eta^2 + (1 + y \tau) {y^2 \tau^2 \over 3} \eta^3 +- {y^3 \tau^3 \over 4} \eta^4 \right] \end{split} \end{equation} -where $\eta = T_c/T$ and $y$ is defined in Eq. \eqref{bhabha_cs}. +where $\eta = T_c/T$ and $y$ is defined in Eq. \eqref{bhabha_cs}. \index{Class II scheme!validity of} -From the above discussion and from the general discussion -of a Class II condensed history implementation in section -\ref{electron_general} it is clear that the formalism -used to treat inelastic collisions with atomic electrons -is only applicable if +From the above discussion and from the general discussion +of a Class II condensed history implementation in section +\ref{electron_general} it is clear that the formalism +used to treat inelastic collisions with atomic electrons +is only applicable if \begin{equation} \label{Tc_condition} -T_c \gg ~~\text{binding energies of the medium of interest}. -\end{equation} -This imposes a rather severe limitation on the use -of Class II condensed history codes in high-$Z$ materials -(the $K$-shell binding energy for lead is, for instance, 88 keV). -We are therefore currently investigating a more realistic approach for -situations when the condition \eqref{Tc_condition} is not -satisfied, but its implementation into EGSnrc is left for the -next release of the system. One should probably also mention -that the many successful studies carried out with the -EGS4 system indicate that the implications of violating -the requirement \eqref{Tc_condition} are perhaps less +T_c \gg ~~\text{binding energies of the medium of interest}. +\end{equation} +This imposes a rather severe limitation on the use +of Class II condensed history codes in high-$Z$ materials +(the $K$-shell binding energy for lead is, for instance, 88 keV). +We are therefore currently investigating a more realistic approach for +situations when the condition \eqref{Tc_condition} is not +satisfied, but its implementation into EGSnrc is left for the +next release of the system. One should probably also mention +that the many successful studies carried out with the +EGS4 system indicate that the implications of violating +the requirement \eqref{Tc_condition} are perhaps less severe than one might expect from purely theoretical arguments. \index{mean ionization energy} \index{density effect} \index{stopping powers} -The only non-trivial parameters of the restricted stopping -power formula are the mean ionization energy $I$ and the -density effect correction $\delta$. The default mean ionization -energies for elements used in PEGS4, along with atomic numbers, -weights, chemical symbols, and mass densities are summarized -in Table \ref{I_values}. Mean ionization energies for +The only non-trivial parameters of the restricted stopping +power formula are the mean ionization energy $I$ and the +density effect correction $\delta$. The default mean ionization +energies for elements used in PEGS4, along with atomic numbers, +weights, chemical symbols, and mass densities are summarized +in Table \ref{I_values}. Mean ionization energies for compounds are derived from \begin{equation} \ln I = \sum p_i Z_i \ln I(Z_i) \end{equation} -where $p_i$ is the stoichiometric index of the $i$'th element -which has atomic number $Z_i$ and a mean ionization energy $I(Z_i)$, -unless the material belongs to a set of pre-defined materials +where $p_i$ is the stoichiometric index of the $i$'th element +which has atomic number $Z_i$ and a mean ionization energy $I(Z_i)$, +unless the material belongs to a set of pre-defined materials to be found in Table 2.13.2 of the EGS4 manual \cite{Ne85} or listed in the -{\tt BLOCK DATA} section of {\tt pegs4.mortran}. +{\tt BLOCK DATA} section of {\tt pegs4.mortran}. \index{pegs4.mortran} \index{SLAC-265} \index{Seltzer, Stephen} \index{Berger, Martin} \index{ISSB} -The density effects correction -has been treated extensively in the literature. +The density effects correction +has been treated extensively in the literature. The default PEGS4 approach is based on the formulation of Sternheimer and Peierls\cite{SP71} which basically parameterizes the density effect in terms of 6 parameters ({\tt AFACT, SK, X0, X1, CBAR}, and {\tt IEV}). This same parameterized approach was used for -the calculations by Berger and Seltzer \cite{BS83} and by +the calculations by Berger and Seltzer \cite{BS83} and by Sternheimer, Berger and Seltzer \cite{St82} who fitted the parameters to the density effect as calculated for the ICRU for increasingly larger numbers of materials. The power of PEGS4 is that it will generate a density effect for any arbitrary material, if need be with no recourse to the fitted -parameters. In this case it will use the Sternheimer and +parameters. In this case it will use the Sternheimer and Peierls\cite{SP71} general formula. There is also an option in PEGS4 which allows the 6 parameters to be read in directly (using the {\tt ISSB=1} option in PEGS4, see section~\ref{issb} page~\pageref{issb}). However, these @@ -1512,15 +1512,15 @@ \subsubsection{Collision stopping power} option was added to PEGS4 in 1989 which allowed the density effect data to be used directly\cite{Du89} and the EGSnrc distribution includes a huge data base of all the density effect values calculated by Seltzer and Berger -for ICRU Report 37\cite{ICRU37}. -To turn this option on the user must +for ICRU Report 37\cite{ICRU37}. +To turn this option on the user must set the flag {\tt EPSTFL} to 1 in the PEGS4 input file. See section~\ref{icru37_csp} (page~\pageref{icru37_csp}) for more details. -In this case the density effect correction is calculated -by interpolation from pre-computed values stored in -a separate file. -Selecting this option has the additional effect that the mean -ionization energy of the material is taken directly from +In this case the density effect correction is calculated +by interpolation from pre-computed values stored in +a separate file. +Selecting this option has the additional effect that the mean +ionization energy of the material is taken directly from the density effect correction file. It should be noted that in general the differences in collision stopping powers between using the default Sternheimer and Peierls density effect, or the fitted parameters or the direct ICRU 37 @@ -1533,15 +1533,15 @@ \subsubsection{Collision stopping power} \begin{longtable}{|rcrrr|} \caption{\label{I_values}Default atomic numbers, symbols, atomic weights, -mass densities, and I values for elements in PEGS4.} \\ +mass densities, and I values for elements in PEGS4.} \\ \hline \hline Z & Symbol & Atomic & Density & I(eV) \\ & & weight & (g/cm$^3$) & \\ \hline -\endfirsthead +\endfirsthead \hline \multicolumn{5}{r}% - {\small\slshape continued from previous page} \\ + {\small\slshape continued from previous page} \\ \hline \hline Z & Symbol & Atomic & Density & I(eV) \\ & & weight & (g/cm$^3$) & \\ @@ -1551,7 +1551,7 @@ \subsubsection{Collision stopping power} \multicolumn{5}{r}% {\small\slshape continued on next page} \\ \hline \endfoot -\hline \hline +\hline \hline \endlastfoot 1 & H & 1.00797 & 0.0808 & 19.2 \\ 2 & HE & 4.00260 & 0.1900 & 41.8 \\ @@ -1659,7 +1659,7 @@ \subsubsection{Collision stopping power} %\end{supertabular} %\end{table} \end{longtable} - + \subsubsection{Elastic scattering cross sections} \label{elastic} \setcounter{equation}{0} @@ -1668,145 +1668,145 @@ \subsubsection{Elastic scattering cross sections} \index{cross section!elastic} \index{SPIN\_EFFECTS} -The treatment of electron and positron elastic -scattering in EGSnrc is determined by the logical parameter -{\tt SPIN\_EFFECTS} which is in {\tt common/ET\_Control/}. -If set to {\tt .true.} (this is the default), -elastic scattering cross sections -that take into account spin effects are employed, they -are discussed in section \ref{spin_elastic}. If {\tt .false.}, -elastic scattering is based on the screened Rutherford cross section. -This is consistent with EGS4, although multiple elastic +The treatment of electron and positron elastic +scattering in EGSnrc is determined by the logical parameter +{\tt SPIN\_EFFECTS} which is in {\tt common/ET\_Control/}. +If set to {\tt .true.} (this is the default), +elastic scattering cross sections +that take into account spin effects are employed, they +are discussed in section \ref{spin_elastic}. If {\tt .false.}, +elastic scattering is based on the screened Rutherford cross section. +This is consistent with EGS4, although multiple elastic \index{multiple elastic scattering} \index{\Mol~theory} -scattering (see section \ref{sec_MS}) -is based on an exact theory rather than the -small-angle theory of \Mol \cite{Mo48} which is used in EGS4. +scattering (see section \ref{sec_MS}) +is based on an exact theory rather than the +small-angle theory of \Mol \cite{Mo48} which is used in EGS4. \index{screened Rutherford cross section} \paragraph{Screened Rutherford elastic scattering} \hfill \index{screened Rutherford cross section} -The screened Rutherford cross section, which is the cross +The screened Rutherford cross section, which is the cross section differential in the cosine $\mu$ of the polar -scattering angle of electrons or positrons incident -on atoms of atomic number $Z$, is +scattering angle of electrons or positrons incident +on atoms of atomic number $Z$, is \begin{equation} \label{SR_1} -{{\rm d} \sigma_{\rm SR} \over {\rm d}\mu} = {2 \pi r_0^2 Z^2 \over -\beta^2 \tau (\tau + 2) }~{1 \over (1 - \mu + 2 \eta)^2} +{{\rm d} \sigma_{\rm SR} \over {\rm d}\mu} = {2 \pi r_0^2 Z^2 \over +\beta^2 \tau (\tau + 2) }~{1 \over (1 - \mu + 2 \eta)^2} \end{equation} -where $\beta$ is the particle velocity in units of the speed of -light, $\tau$ the kinetic energy $T$ in units of $m$ +where $\beta$ is the particle velocity in units of the speed of +light, $\tau$ the kinetic energy $T$ in units of $m$ \index{screening parameter} -and $\eta$ the screening parameter. The total elastic scattering -cross section is obtained from Eq. \eqref{SR_1} by integrating +and $\eta$ the screening parameter. The total elastic scattering +cross section is obtained from Eq. \eqref{SR_1} by integrating over $\mu$ from -1 to 1 and is given by \begin{equation} \label{SR_2} \sigma_{\rm SR} = {\pi r_0^2 Z^2 \over \beta^2 \tau (\tau+2) \eta (1 + \eta)} \end{equation} -In EGS4 the screening parameter $\eta$ is based on the single -elastic scattering theory of \Mol \cite{Mo47}. \Mol~ +In EGS4 the screening parameter $\eta$ is based on the single +elastic scattering theory of \Mol \cite{Mo47}. \Mol~ \index{PWA} -performed a partial-wave analysis (PWA) expansion -of the Klein-Gordon equation ({\em i.e.} he neglected spin effects) -in the nuclear field described by the Thomas-Fermi potential, -used a small-angle approximation ({\em i.e.} replaced the Legendre -Polynomials by zeroth order Bessel functions $J_0$), -and employed a WKB-expansion -of the resulting radial equation up to zeroth order in $\hbar$ +performed a partial-wave analysis (PWA) expansion +of the Klein-Gordon equation ({\em i.e.} he neglected spin effects) +in the nuclear field described by the Thomas-Fermi potential, +used a small-angle approximation ({\em i.e.} replaced the Legendre +Polynomials by zeroth order Bessel functions $J_0$), +and employed a WKB-expansion +of the resulting radial equation up to zeroth order in $\hbar$ to calculate the phase shifts $\phi(z)$ to arrive at \begin{equation} \label{el_mol} -{{\rm d} \sigma_{\rm M} \over \chi {\rm d} \chi} = -2 \pi a^2 \left| \int\limits_0^\infty {\rm d}z z J_0\left(z {\chi \over -2 \sqrt{\eta_0}} \right) \left[ \exp\Big( - 2 i \alpha' -\phi(z) \Big) - 1 \right] +{{\rm d} \sigma_{\rm M} \over \chi {\rm d} \chi} = +2 \pi a^2 \left| \int\limits_0^\infty {\rm d}z z J_0\left(z {\chi \over +2 \sqrt{\eta_0}} \right) \left[ \exp\Big( - 2 i \alpha' +\phi(z) \Big) - 1 \right] \right|^2 \end{equation} -where $\chi$ is the scattering angle, $a$ is the Thomas-Fermi radius, +where $\chi$ is the scattering angle, $a$ is the Thomas-Fermi radius, $\eta_0$ is defined in Eq. \eqref{eta_0} and $\alpha'$ given by \begin{equation} \label{alpha_prime} \alpha' = {\alpha Z \over \beta} \end{equation} ($\alpha \approx 1/137$ is the fine structure constant). In addition -he approximated the Thomas-Fermi potential by the sum of three -exponential functions in which case the phase shifts $\phi(z)$ are -given by zeroth order modified Bessel functions. He then required -that the average scattering angle squared, calculated from a -screened Rutherford cross section is the same as the average -scattering angle squared resulting from Eq. \eqref{el_mol} and, -after studying the limiting cases $\alpha' \to 0$ and -$\alpha' \to \infty$, arrived at the simple formula +he approximated the Thomas-Fermi potential by the sum of three +exponential functions in which case the phase shifts $\phi(z)$ are +given by zeroth order modified Bessel functions. He then required +that the average scattering angle squared, calculated from a +screened Rutherford cross section is the same as the average +scattering angle squared resulting from Eq. \eqref{el_mol} and, +after studying the limiting cases $\alpha' \to 0$ and +$\alpha' \to \infty$, arrived at the simple formula \begin{equation} \label{eta_0} -\eta = \eta_0 (1.13 + 3.76 \alpha^{\prime 2} )~, \quad -\eta_0 = {\alpha^2 Z^{2/3} \over 4 C_{\rm TF}^2 \tau (\tau + 2)}~, +\eta = \eta_0 (1.13 + 3.76 \alpha^{\prime 2} )~, \quad +\eta_0 = {\alpha^2 Z^{2/3} \over 4 C_{\rm TF}^2 \tau (\tau + 2)}~, \quad C_{\rm TF} = \left( {9 \pi^2 \over 128} \right)^{1/3} \end{equation} -for the effective screening parameter $\eta$\footnote{Note that our -$\eta$ is \Mol's $\chi_a^2/4$, $C_{\rm TF}$ is the Thomas-Fermi -constant.}. +for the effective screening parameter $\eta$\footnote{Note that our +$\eta$ is \Mol's $\chi_a^2/4$, $C_{\rm TF}$ is the Thomas-Fermi +constant.}. -The treatment of elastic scattering in EGS4 is intrinsically -associated with \Mol's multiple scattering theory\cite{Mo48}. -In his treatment of multiple scattering \Mol~ uses a small-angle -approximation in which case the moments of the screened Rutherford -cross section (see section \ref{sec_MS}) are given by -first order modified Bessel functions $K_1$. +The treatment of elastic scattering in EGS4 is intrinsically +associated with \Mol's multiple scattering theory\cite{Mo48}. +In his treatment of multiple scattering \Mol~ uses a small-angle +approximation in which case the moments of the screened Rutherford +cross section (see section \ref{sec_MS}) are given by +first order modified Bessel functions $K_1$. %{\em i.e.} %\begin{equation} -%\int\limits_{-1}^1 {\rm d} \mu \Big[1 - P_l(\mu) \Big] -%{{\rm d} -In addition, a small argument expansion of $K_1$ is performed -so that the elastic scattering cross section for -compounds and mixtures can be expressed with two +%\int\limits_{-1}^1 {\rm d} \mu \Big[1 - P_l(\mu) \Big] +%{{\rm d} +In addition, a small argument expansion of $K_1$ is performed +so that the elastic scattering cross section for +compounds and mixtures can be expressed with two parameters, $b_c$ and $\chi_{cc}$, as follows: \begin{equation} \begin{split} -b_c & = {4 \pi r_0^2 C_{\rm TF}^2 \rho \over 1.13 \alpha^2 u} -{Z_S \exp(Z_E/Z_S) \over A \exp(Z_X/Z_S)} = 7821.6~ \mbox{cm}^2/\mbox{g}~\rho +b_c & = {4 \pi r_0^2 C_{\rm TF}^2 \rho \over 1.13 \alpha^2 u} +{Z_S \exp(Z_E/Z_S) \over A \exp(Z_X/Z_S)} = 7821.6~ \mbox{cm}^2/\mbox{g}~\rho { Z_S \exp(Z_E/Z_S) \over A \exp(Z_X/Z_S)} \\ -\chi_{cc}^2 & = {4 \pi r_0^2 m^2 \over u}~\rho~\frac{Z_S}{A} = 0.1569~ +\chi_{cc}^2 & = {4 \pi r_0^2 m^2 \over u}~\rho~\frac{Z_S}{A} = 0.1569~ \mbox{cm}^2 \mbox{MeV}^2 / \mbox{g}~\rho \frac{Z_S}{A} \end{split} \end{equation} -where $A$ is the relative molecular mass and +where $A$ is the relative molecular mass and \begin{equation} \begin{split} Z_S & = \sum p_i Z_i (Z_i + \xi_{\rm MS} ) \\ Z_E & = \sum p_i Z_i (Z_i + \xi_{\rm MS} ) \ln Z_i^{-2/3} \\ -Z_X & = \sum p_i Z_i (Z_i + \xi_{\rm MS} ) \ln \left(1 + 3.34~ \alpha^2 Z_i^2 +Z_X & = \sum p_i Z_i (Z_i + \xi_{\rm MS} ) \ln \left(1 + 3.34~ \alpha^2 Z_i^2 \right) \end{split} \end{equation} \index{angular deflections!inelastic collisions} -Note that in the expression for $Z_X$ $\alpha'$ was replaced -by $\alpha Z_i$ and we have removed the factor 1.167 in the -denominator of the expression for $b_c$ in the EGS4 manual, -this factor is not necessary when multiple scattering is -treated with the exact formulation. The purpose of the -parameter $\xi_{\rm MS}$ is to take into account -contributions from sub-threshold inelastic scattering -with atomic electrons. In PEGS4 a macros {\tt \$FUDGEMS} is -used for $\xi_{\rm MS}$ with the intent to provide -the user with the possibility of implementing a more -realistic treatment of sub-threshold inelastic -contributions. Experience shows that -this capability is rarely used and so, PEGS4 generated -data sets usually have $\xi_{\rm MS}=1$ (the default value). -This leads to double counting of angular deflections due -to sub-threshold inelastic collisions (see {\em e.g.} \cite{LR94a}). -This problem remains present in EGSnrc if the screened -Rutherford cross section is used to model elastic collisions -(parameter {\tt SPIN\_EFFECTS} is set to {\tt .false.}). -We have not attempted a correction in this case as the neglect of spin -effects represents a more severe approximation than the -double counting of inelastic collisions. A more -realistic approach is used when spin effects are turned on, -see next section. +Note that in the expression for $Z_X$ $\alpha'$ was replaced +by $\alpha Z_i$ and we have removed the factor 1.167 in the +denominator of the expression for $b_c$ in the EGS4 manual, +this factor is not necessary when multiple scattering is +treated with the exact formulation. The purpose of the +parameter $\xi_{\rm MS}$ is to take into account +contributions from sub-threshold inelastic scattering +with atomic electrons. In PEGS4 a macros {\tt \$FUDGEMS} is +used for $\xi_{\rm MS}$ with the intent to provide +the user with the possibility of implementing a more +realistic treatment of sub-threshold inelastic +contributions. Experience shows that +this capability is rarely used and so, PEGS4 generated +data sets usually have $\xi_{\rm MS}=1$ (the default value). +This leads to double counting of angular deflections due +to sub-threshold inelastic collisions (see {\em e.g.} \cite{LR94a}). +This problem remains present in EGSnrc if the screened +Rutherford cross section is used to model elastic collisions +(parameter {\tt SPIN\_EFFECTS} is set to {\tt .false.}). +We have not attempted a correction in this case as the neglect of spin +effects represents a more severe approximation than the +double counting of inelastic collisions. A more +realistic approach is used when spin effects are turned on, +see next section. \index{SPIN\_EFFECTS} \index{\$FUDGEMS} \index{PEGS4!\$FUDGEMS} @@ -1815,33 +1815,33 @@ \subsubsection{Elastic scattering cross sections} %\index{{\tt XCC}} \index{BLCC} \index{XCC} -In terms of the parameter $b_c$ and $\chi_{cc}$, -which are called {\tt BLCC} and {\tt XCC}, -the screening parameter is +In terms of the parameter $b_c$ and $\chi_{cc}$, +which are called {\tt BLCC} and {\tt XCC}, +the screening parameter is \begin{equation} \label{calc_eta} \eta = {\chi_{cc}^2 \over 4 b_c m^2 \tau (\tau + 2)} \end{equation} -and the total macroscopic cross section +and the total macroscopic cross section \begin{equation} \label{SR_tot} \Sigma_{\rm SR} = {b_c \over \beta^2} \end{equation} -The latter formula involves the neglect of $1 + \eta$ in the denominator +The latter formula involves the neglect of $1 + \eta$ in the denominator of Eq. \eqref{SR_2}. \index{angular deflections!single elastic scattering} \index{single elastic scattering} -Sampling angular deflections in single elastic scattering events -on the basis of Eq. \eqref{SR_1} is trivial, it is accomplished by +Sampling angular deflections in single elastic scattering events +on the basis of Eq. \eqref{SR_1} is trivial, it is accomplished by \begin{equation} \label{sample_SR} \mu = 1 - {2 \eta r \over 1 - r + \eta} \end{equation} -where $r$ denotes a random number between zero and unity. -Single elastic scattering deflections are necessary when -boundary crossing between different media is modelled exactly, -see section \ref{BCA}. +where $r$ denotes a random number between zero and unity. +Single elastic scattering deflections are necessary when +boundary crossing between different media is modelled exactly, +see section \ref{BCA}. \paragraph{Elastic scattering with spin} \hfill \label{spin_elastic} @@ -1849,261 +1849,261 @@ \subsubsection{Elastic scattering cross sections} \index{PWA} \index{elastic scattering!spin effects} -Potentially the most accurate elastic scattering cross sections -are those obtained from a PWA solution of the Dirac equation -in the nuclear field screened by the atomic electrons. +Potentially the most accurate elastic scattering cross sections +are those obtained from a PWA solution of the Dirac equation +in the nuclear field screened by the atomic electrons. The general expression for the cross section, derived by Mott \cite{Mo29}, is given by (see also the article by Motz, Olsen and Koch, \cite{Mo64}) \begin{equation} \label{mott1} \begin{split} -{{\rm d}\sigma_{\rm PWA} \over {\rm d}\Omega} & = {r_0^2 \over 4 \alpha^2 \tau +{{\rm d}\sigma_{\rm PWA} \over {\rm d}\Omega} & = {r_0^2 \over 4 \alpha^2 \tau (\tau + 2) } \Big[ |f|^2 + |g|^2 \Big] \\ -f & = \sum_{l=0}^\infty \left\{ (l+1) \left[ e^{2 i \phi_l} - 1 \right] +f & = \sum_{l=0}^\infty \left\{ (l+1) \left[ e^{2 i \phi_l} - 1 \right] + l \left[ e^{2 i \phi_{-l-1}} - 1 \right] \right\} P_l(\mu) \\ -g & = \sum_{l=0}^\infty \left\{ e^{2 i \phi_{-l-1}} - e^{2 i \phi_l} \right\} +g & = \sum_{l=0}^\infty \left\{ e^{2 i \phi_{-l-1}} - e^{2 i \phi_l} \right\} P_l^1(\mu) \end{split} \end{equation} -where the definitions from the previous section for $\tau$ and $\alpha$ -apply, $P_l$ and $P_l^m$ are Legendre and associated Legendre polynomials -and $\phi_l$ denotes the phase shifts. They are obtained from -the asymptotic solution of the equation +where the definitions from the previous section for $\tau$ and $\alpha$ +apply, $P_l$ and $P_l^m$ are Legendre and associated Legendre polynomials +and $\phi_l$ denotes the phase shifts. They are obtained from +the asymptotic solution of the equation \begin{equation} \label{mott2} -{{\rm d}^2 F_l \over {\rm d}r^2} + \left[ p r + {l (l+1) \over r^2} +{{\rm d}^2 F_l \over {\rm d}r^2} + \left[ p r + {l (l+1) \over r^2} - U_l \right] F_l = 0 \end{equation} -when written in the form $F_l(r \to \infty) = \sin(p r - l \pi/2 + \phi_l)$. -Here, $p = \sqrt{\tau (\tau+2)}$ is the electron momentum in units -of $m/c$ and the nuclear and/or atomic charge structure +when written in the form $F_l(r \to \infty) = \sin(p r - l \pi/2 + \phi_l)$. +Here, $p = \sqrt{\tau (\tau+2)}$ is the electron momentum in units +of $m/c$ and the nuclear and/or atomic charge structure is contained in the effective Dirac potential $U_l$, \begin{equation} \label{mott3} \begin{split} -U_l & = 2 (\tau + 1) V - V^2 - {l+1 \over r^2}~{D' \over D} + +U_l & = 2 (\tau + 1) V - V^2 - {l+1 \over r^2}~{D' \over D} + \frac{3}{4}~{D^{\prime 2} \over D^2} - \frac{1}{2}~ \frac{D^{\prime \prime}}{D} \\ -D & = \tau + 2 - V, \quad D' = {{\rm d} D \over {\rm d}r}, \quad +D & = \tau + 2 - V, \quad D' = {{\rm d} D \over {\rm d}r}, \quad D^{\prime \prime} = {{\rm d}^2 D \over {\rm d}r^2} \end{split} \end{equation} -where $V$ is a spherically symmetric potential arising from the -charge structure of the nucleus and/or the atom. -Mott has also presented \cite{Mo32} an analytical solution for the -phase shifts for a bare nucleus ({\em i.e.} $V = \pm Z/r$, where -the plus sign is for positrons and the minus +where $V$ is a spherically symmetric potential arising from the +charge structure of the nucleus and/or the atom. +Mott has also presented \cite{Mo32} an analytical solution for the +phase shifts for a bare nucleus ({\em i.e.} $V = \pm Z/r$, where +the plus sign is for positrons and the minus for electrons). His result can be written as \cite{Mo64} \begin{equation} -{{\rm d}\sigma_{el} \over {\rm d}\Omega} = -{r_0^2 Z^2 \over -\beta^2 \tau (\tau + 2) }~{R_{\rm mott}(Z,\tau,\mu) \over (1 - \mu )^2} +{{\rm d}\sigma_{el} \over {\rm d}\Omega} = +{r_0^2 Z^2 \over +\beta^2 \tau (\tau + 2) }~{R_{\rm mott}(Z,\tau,\mu) \over (1 - \mu )^2} \end{equation} \index{Mott correction} -where $R_{\rm mott}$ has become known as the Mott correction +where $R_{\rm mott}$ has become known as the Mott correction and is given by \begin{equation} \begin{split} -R_{\rm mott} & = {1 - \mu \over (\tau + 1)^2} |F_0 + F_1|^2 + -{2 \beta^4 \over \tau (\tau + 2)}~{(1 - \mu)^2 \over 1 + \mu} -{|G_0 + G_1|^2 \over \alpha^2 Z^2} \\ -F_0 & = {i \Gamma(1 - i \alpha') \over 2 \Gamma(1 + i \alpha')} +R_{\rm mott} & = {1 - \mu \over (\tau + 1)^2} |F_0 + F_1|^2 + +{2 \beta^4 \over \tau (\tau + 2)}~{(1 - \mu)^2 \over 1 + \mu} +{|G_0 + G_1|^2 \over \alpha^2 Z^2} \\ +F_0 & = {i \Gamma(1 - i \alpha') \over 2 \Gamma(1 + i \alpha')} \left( {1 - \mu \over 2} \right)^{i \alpha'} \\ G_0 & = -i \alpha' {1 + \mu \over 1 - \mu} F_0 \\ -F_1 & = \frac{i}{2} \sum_{l=0}^\infty \left[ l \phi_l - (l+1) \phi_{l+1} +F_1 & = \frac{i}{2} \sum_{l=0}^\infty \left[ l \phi_l - (l+1) \phi_{l+1} \right] (-1)^l P_l(\mu) \\ -G_1 & = \frac{i}{2} \sum_{l=0}^\infty \left[ l^2 \phi_l - (l+1)^2 \phi_{l+1} +G_1 & = \frac{i}{2} \sum_{l=0}^\infty \left[ l^2 \phi_l - (l+1)^2 \phi_{l+1} \right] (-1)^l P_l(\mu) \\ -\phi_l &= {\exp(-i \pi l) \over l + i \alpha'} ~ {\Gamma(l - i \alpha') -\over \Gamma(l + i \alpha') } - {\exp(-i \pi \rho_l) \over -\rho_l + i \alpha'}~ {\Gamma(\rho_l - i \alpha') \over +\phi_l &= {\exp(-i \pi l) \over l + i \alpha'} ~ {\Gamma(l - i \alpha') +\over \Gamma(l + i \alpha') } - {\exp(-i \pi \rho_l) \over +\rho_l + i \alpha'}~ {\Gamma(\rho_l - i \alpha') \over \Gamma(\rho_l + i \alpha') } \\ \rho_l & = \sqrt{ l^2 - \alpha^2 Z^2 } \end{split} \end{equation} -where $\Gamma$ is the gamma function. The quantity $\alpha'$ is defined -in Eq. \eqref{alpha_prime} but now the atomic number $Z$ is considered -as being $-Z$ for electrons and $+Z$ for positrons. Due to -this fact, the Mott correction is different for electrons and positrons. -$R_{\rm mott}$ must be evaluated numerically, Fig. \ref{fig_mott} gives some -representative examples. +where $\Gamma$ is the gamma function. The quantity $\alpha'$ is defined +in Eq. \eqref{alpha_prime} but now the atomic number $Z$ is considered +as being $-Z$ for electrons and $+Z$ for positrons. Due to +this fact, the Mott correction is different for electrons and positrons. +$R_{\rm mott}$ must be evaluated numerically, Fig. \ref{fig_mott} gives some +representative examples. \begin{figure}[htp] \includegraphics[height=14cm,width=14cm]{figures/mott1} \index{Mott correction} -\caption[The Mott correction]{\label{fig_mott} The Mott correction factor -$R_{\rm mott}$ for gold and aluminum and various incident +\caption[The Mott correction]{\label{fig_mott} The Mott correction factor +$R_{\rm mott}$ for gold and aluminum and various incident electron and positron energies.} -\end{figure} - -Berger and Wang \cite{BW89} have implemented into ETRAN (see {\em e.g.} -Ref. \cite{Se89}) -the treatment of multiple -elastic scattering according to the general Mott PWA cross section, -equations \eqref{mott1} to \eqref{mott3}. They have used the code -by Riley \cite{Ri74} for the numerical solution of Eq. \eqref{mott2} -in a nuclear field screened by an electron density distribution -obtained from the multi-configuration Dirac-Fock program by -Desclaux \cite{De75}. These cross sections were later implemented -also in ITS \cite{ITSV3}. Note that ETRAN and ITS use a Class I -condensed history implementation where electron transport is -performed on a pre-determined step-size grid. This allows -the calculation of the multiple elastic scattering distribution -(see section \ref{sec_MS}) for arbitrary complicated cross -sections for the step-size grid used with a reasonable amount -of pre-calculated data. +\end{figure} + +Berger and Wang \cite{BW89} have implemented into ETRAN (see {\em e.g.} +Ref. \cite{Se89}) +the treatment of multiple +elastic scattering according to the general Mott PWA cross section, +equations \eqref{mott1} to \eqref{mott3}. They have used the code +by Riley \cite{Ri74} for the numerical solution of Eq. \eqref{mott2} +in a nuclear field screened by an electron density distribution +obtained from the multi-configuration Dirac-Fock program by +Desclaux \cite{De75}. These cross sections were later implemented +also in ITS \cite{ITSV3}. Note that ETRAN and ITS use a Class I +condensed history implementation where electron transport is +performed on a pre-determined step-size grid. This allows +the calculation of the multiple elastic scattering distribution +(see section \ref{sec_MS}) for arbitrary complicated cross +sections for the step-size grid used with a reasonable amount +of pre-calculated data. \index{Class II scheme!multiple scattering} \index{Seltzer, Stephen} -The situation in a Class II code is more difficult as step-lengths -are stochastic (see section \ref{electron_general}). -Using Riley's code and Desclaux' electron -density functions, both kindly provided to us by Steve Seltzer of NIST, -we have also generated an elastic scattering data +The situation in a Class II code is more difficult as step-lengths +are stochastic (see section \ref{electron_general}). +Using Riley's code and Desclaux' electron +density functions, both kindly provided to us by Steve Seltzer of NIST, +we have also generated an elastic scattering data base for all elements and energies from 1 keV to 16 MeV\footnote{ -The calculation of the elastic scattering cross section from -equations \eqref{mott1} to \eqref{mott3} becomes increasingly -more difficult with increasing energy as more and more phase -shifts have to be calculated and numerical round-off errors -accumulate in the summations involved. We have modified Riley's -code to perform calculations in double precision, use more dense phase -shifts calculation grid and more accurate interpolations for -the electron density. This allowed calculations up to 16 MeV, for +The calculation of the elastic scattering cross section from +equations \eqref{mott1} to \eqref{mott3} becomes increasingly +more difficult with increasing energy as more and more phase +shifts have to be calculated and numerical round-off errors +accumulate in the summations involved. We have modified Riley's +code to perform calculations in double precision, use more dense phase +shifts calculation grid and more accurate interpolations for +the electron density. This allowed calculations up to 16 MeV, for even higher energies the results become numerically unstable.}. -Using this data base, we have studied the construction of a multiple +Using this data base, we have studied the construction of a multiple \index{multiple elastic scattering} -scattering theory but could not find a satisfactory procedure -to keep the amount of pre-calculated data required at a reasonable level. -We have therefore decided to approximate the elastic scattering +scattering theory but could not find a satisfactory procedure +to keep the amount of pre-calculated data required at a reasonable level. +We have therefore decided to approximate the elastic scattering cross section as \begin{equation} \label{sigma_el} -{{\rm d}\sigma_{el} \over {\rm d}\mu} = {{\rm d}\sigma_{SR} \over {\rm d}\mu} +{{\rm d}\sigma_{el} \over {\rm d}\mu} = {{\rm d}\sigma_{SR} \over {\rm d}\mu} R_{\rm mott}(Z,\tau,\mu) \end{equation} \index{Mott correction} -where ${\rm d}\sigma_{SR}/{\rm d}\mu$ is the screened Rutherford cross -section given in Eq. \eqref{SR_1}. This approximation is known -to be accurate for energies above 1 MeV (high-$Z$ materials) or -100 keV (low-$Z$ materials) as there the spin effect correction -decouples from the screening correction \cite{BW89}. To -reproduce the average scattering at low energies we treat -the screening parameter $\eta$ as a free parameter and determine +where ${\rm d}\sigma_{SR}/{\rm d}\mu$ is the screened Rutherford cross +section given in Eq. \eqref{SR_1}. This approximation is known +to be accurate for energies above 1 MeV (high-$Z$ materials) or +100 keV (low-$Z$ materials) as there the spin effect correction +decouples from the screening correction \cite{BW89}. To +reproduce the average scattering at low energies we treat +the screening parameter $\eta$ as a free parameter and determine it by numerically solving the equation \begin{equation} \label{fix_eta} -\int\limits_{-1}^1 {\rm d} \mu {{\rm d}\sigma_{SR} \over {\rm d}\mu} -R_{\rm mott}(Z,\tau,\mu) (1 - \mu) \equiv -\int\limits_{-1}^1 {\rm d} \mu {{\rm d}\sigma_{\rm PWA} \over {\rm d} \mu} -(1 - \mu) +\int\limits_{-1}^1 {\rm d} \mu {{\rm d}\sigma_{SR} \over {\rm d}\mu} +R_{\rm mott}(Z,\tau,\mu) (1 - \mu) \equiv +\int\limits_{-1}^1 {\rm d} \mu {{\rm d}\sigma_{\rm PWA} \over {\rm d} \mu} +(1 - \mu) \end{equation} \index{screening parameter} -The resulting screening parameter for electrons is shown -as a function of $\beta$ for 4 different elements in -Fig. \ref{fig_eta}. In this figure $\eta$ is expressed in units -of $\eta_{\rm M}$, where +The resulting screening parameter for electrons is shown +as a function of $\beta$ for 4 different elements in +Fig. \ref{fig_eta}. In this figure $\eta$ is expressed in units +of $\eta_{\rm M}$, where \begin{equation} \label{eta_M} \eta_{\rm M} = \eta_0 (1.13 + 3.76 \alpha^2 Z^2) \end{equation} -is the screening parameter used in EGS4. +is the screening parameter used in EGS4. \begin{figure}[htp] \includegraphics[height=12cm,width=12cm]{figures/eta} -\caption[Screening parameter]{\label{fig_eta} The screening parameter $\eta$, -determined from Eq. \protect\eqref{fix_eta}, in units of +\caption[Screening parameter]{\label{fig_eta} The screening parameter $\eta$, +determined from Eq. \protect\eqref{fix_eta}, in units of $\eta_{\rm M}$, defined in Eq. \protect\eqref{eta_M}.} -\end{figure} +\end{figure} -The elastic scattering cross section for compounds and -mixtures is expressed in a similar form as Eq. \eqref{sigma_el} -but now the Mott correction is +The elastic scattering cross section for compounds and +mixtures is expressed in a similar form as Eq. \eqref{sigma_el} +but now the Mott correction is \begin{equation} -R_{\rm mott}(\tau,\mu) = {\sum p_i Z_i^2 R_{\rm mott}(Z_i,\tau,\mu) \over +R_{\rm mott}(\tau,\mu) = {\sum p_i Z_i^2 R_{\rm mott}(Z_i,\tau,\mu) \over \sum p_i Z_i^2} \end{equation} -and the screening parameter is determined from Eq. \eqref{fix_eta} where -the partial-wave analysis cross section for the compound is -calculated from the PWA cross sections of its elements using -the independent atom approximation. +and the screening parameter is determined from Eq. \eqref{fix_eta} where +the partial-wave analysis cross section for the compound is +calculated from the PWA cross sections of its elements using +the independent atom approximation. \index{angular deflections!inelastic collisions} -We can now turn to the discussion of the modifications necessary -to take into account contributions from angular deflections -due to sub-threshold processes. Various studies on this subject -are available in the literature, see {\em e.g.} \cite{Sc63,Fa54,BW89}. -We have not attempted to implement one of them, instead, we -take the simplistic point of view that the contributions -to angular deflections for all inelastic collisions, sub-threshold -and discrete, can be taken into account by replacing -$Z^2$ with $Z (Z + \xi_{0})$ in the screened Rutherford -cross section, Eq. \eqref{SR_1}. Here $\xi_0$ is an appropriate -parameter, we use by default $\xi_0=1$ but this is not a necessary -requirement. If now inelastic collisions with energy transfer -larger than $T_c$ are simulated explicitly, $\xi_0$ must -be replaced with an energy and cut-off dependent parameter $\xi(T,T_c)$ -as follows \cite{Ka96c} +We can now turn to the discussion of the modifications necessary +to take into account contributions from angular deflections +due to sub-threshold processes. Various studies on this subject +are available in the literature, see {\em e.g.} \cite{Sc63,Fa54,BW89}. +We have not attempted to implement one of them, instead, we +take the simplistic point of view that the contributions +to angular deflections for all inelastic collisions, sub-threshold +and discrete, can be taken into account by replacing +$Z^2$ with $Z (Z + \xi_{0})$ in the screened Rutherford +cross section, Eq. \eqref{SR_1}. Here $\xi_0$ is an appropriate +parameter, we use by default $\xi_0=1$ but this is not a necessary +requirement. If now inelastic collisions with energy transfer +larger than $T_c$ are simulated explicitly, $\xi_0$ must +be replaced with an energy and cut-off dependent parameter $\xi(T,T_c)$ +as follows \cite{Ka96c} \begin{equation} \xi(T,T_c) = \xi_0 \left(1 - {1 \over \bar{Z} + \xi_0}~ {g_{\rm M}(\tau,\tau_c) \over g_{\rm R}(\eta) } \right) \end{equation} -where $\bar{Z}$ is the average atomic number of the compound -and %$g_{\rm M}(\tau,\tau_c)$ is the average angle +where $\bar{Z}$ is the average atomic number of the compound +and %$g_{\rm M}(\tau,\tau_c)$ is the average angle \newcommand{\tpr}{\tau^{\prime}} \begin{equation} \begin{split} -g_M(\tau,\tau_c) & = -\ln {\tau \over 2 \tau_c} + \left[1 + -{(\tau + 2)^2 \over (\tau+1)^2} \right] \ln {2 (\tau-\tau_c+2) \over \tau + 4} -\\ &- -\left[{(\tau+2)^2 \over 4} + {(\tau+2) (\tau+1/2) \over (\tau+1)^2} \right] -\ln {(\tau+4) (\tau-\tau_c) \over \tau (\tau-\tau_c+2)} \\ & + -{(\tau-2 \tau_c) (\tau+2) \over 2} +g_M(\tau,\tau_c) & = +\ln {\tau \over 2 \tau_c} + \left[1 + +{(\tau + 2)^2 \over (\tau+1)^2} \right] \ln {2 (\tau-\tau_c+2) \over \tau + 4} +\\ &- +\left[{(\tau+2)^2 \over 4} + {(\tau+2) (\tau+1/2) \over (\tau+1)^2} \right] +\ln {(\tau+4) (\tau-\tau_c) \over \tau (\tau-\tau_c+2)} \\ & + +{(\tau-2 \tau_c) (\tau+2) \over 2} \left[{1 \over \tau-\tau_c} - {1 \over (\tau+1)^2} \right]~. \end{split} \end{equation} -($\tau_c = T_c/m$) and +($\tau_c = T_c/m$) and \begin{equation} g_{\rm R}(\eta) = (1 + 2 \eta) \left[ \ln \left(1 + \frac{1}{\eta} \right) - 2 \right] \end{equation} \index{SPIN\_EFFECTS} -To summarize, when spin effects are turned on in EGSnrc -({\tt SPIN\_EFFECTS = .true.}), the elastic scattering -cross section used is +To summarize, when spin effects are turned on in EGSnrc +({\tt SPIN\_EFFECTS = .true.}), the elastic scattering +cross section used is \begin{equation} \label{sigma_el1} -{{\rm d}\sigma_{\rm el} \over {\rm d}\mu} = -{2 \pi r_0^2 Z (Z + \xi(T,T_c)) \over -\beta^2 \tau (\tau + 2) }~{R_{\rm mott}(Z,T,\mu) \over (1 - \mu + 2 \eta)^2} +{{\rm d}\sigma_{\rm el} \over {\rm d}\mu} = +{2 \pi r_0^2 Z (Z + \xi(T,T_c)) \over +\beta^2 \tau (\tau + 2) }~{R_{\rm mott}(Z,T,\mu) \over (1 - \mu + 2 \eta)^2} \end{equation} where \begin{itemize} \item -The screening parameter $\eta$ is determined from the requirement -that the above cross section reproduces the average scattering -from PWA cross sections obtained via the numerical solution of -equations \eqref{mott1} to \eqref{mott3} using Hartree-Fock -electron densities. This parameter is different for electrons +The screening parameter $\eta$ is determined from the requirement +that the above cross section reproduces the average scattering +from PWA cross sections obtained via the numerical solution of +equations \eqref{mott1} to \eqref{mott3} using Hartree-Fock +electron densities. This parameter is different for electrons and positrons \item -The parameter $\xi(T,T_c)$ takes into account contributions -from sub-threshold inelastic collisions, it depends on energy +The parameter $\xi(T,T_c)$ takes into account contributions +from sub-threshold inelastic collisions, it depends on energy and the threshold energy $T_c$ \item -$R_{\rm mott}$ is the Mott correction that is the result of -the solution of the Dirac equation in the field of a bare nucleus. -\end{itemize} -All parameters necessary for the run-time interpolation -of $\eta$, $\xi$ and $R_{\rm mott}$ are initialized in -the subroutine {\tt init\_spin} which is called from +$R_{\rm mott}$ is the Mott correction that is the result of +the solution of the Dirac equation in the field of a bare nucleus. +\end{itemize} +All parameters necessary for the run-time interpolation +of $\eta$, $\xi$ and $R_{\rm mott}$ are initialized in +the subroutine {\tt init\_spin} which is called from the subroutine {\tt mscati}, executed at the end of {\tt HATCH}. -Sampling of single elastic scattering events on the basis of -Eq. \eqref{sigma_el1} is performed using a rejection technique. -One uses Eq. \eqref{sample_SR} to sample the screened Rutherford -part, the $\mu$ sampled is accepted if a second random number is -less than $R_{\rm mott}/R_{\rm mott,max}$. The efficiency of -this algorithm is close to unity for low-$Z$ materials but +Sampling of single elastic scattering events on the basis of +Eq. \eqref{sigma_el1} is performed using a rejection technique. +One uses Eq. \eqref{sample_SR} to sample the screened Rutherford +part, the $\mu$ sampled is accepted if a second random number is +less than $R_{\rm mott}/R_{\rm mott,max}$. The efficiency of +this algorithm is close to unity for low-$Z$ materials but only close to $1/2$ for high-$Z$ materials. \subsubsection{Multiple elastic scattering} @@ -2112,145 +2112,145 @@ \subsubsection{Multiple elastic scattering} \index{multiple elastic scattering} \index{Goudsmit-Saunderson theory} -The multiple elastic scattering distribution for electron -transport in an infinite, homogeneous medium for a path-length -$s$, which corresponds to an energy loss $E_0 - E$, can be obtained -from Eq. \eqref{transport3} by integrating it over the position, -expanding $\Phi_0$ and the cross sections in Legendre polynomials +The multiple elastic scattering distribution for electron +transport in an infinite, homogeneous medium for a path-length +$s$, which corresponds to an energy loss $E_0 - E$, can be obtained +from Eq. \eqref{transport3} by integrating it over the position, +expanding $\Phi_0$ and the cross sections in Legendre polynomials $P_l$ to arrive at \begin{equation} -\Phi_0(\mu,\phi,E) = \frac{1}{2 \pi} \sum_{l=0}^\infty \left(l + \frac{1}{2} +\Phi_0(\mu,\phi,E) = \frac{1}{2 \pi} \sum_{l=0}^\infty \left(l + \frac{1}{2} \right) \exp( -G_l ) P_l(\mu) \end{equation} -where $\mu$ is the cosine of the polar angle $\theta$ and the process -is considered in a frame where the electron is initially moving -along the $z$ axis. This expression was first obtained by -Goudsmit and Saunderson \cite{GS40,GS40a}. The Goudsmit-Saunderson +where $\mu$ is the cosine of the polar angle $\theta$ and the process +is considered in a frame where the electron is initially moving +along the $z$ axis. This expression was first obtained by +Goudsmit and Saunderson \cite{GS40,GS40a}. The Goudsmit-Saunderson (GS) moments $G_l$ are given by \begin{equation} \label{GS_moments} -G_l = \int\limits_0^s {\rm d}s' \kappa_l(s') = \int\limits_{E}^{E_0} -{{\rm d}E' \over L(E',E_c,k_c)} \kappa_l(E') +G_l = \int\limits_0^s {\rm d}s' \kappa_l(s') = \int\limits_{E}^{E_0} +{{\rm d}E' \over L(E',E_c,k_c)} \kappa_l(E') \end{equation} -where the $\kappa_l$ denote the moments of the elastic scattering +where the $\kappa_l$ denote the moments of the elastic scattering cross section, \index{elastic scattering!moments} \begin{equation} \label{kappa_l} -\kappa_l(E) = 2 \pi -\int\limits_{-1}^1 {\rm d}\mu +\kappa_l(E) = 2 \pi +\int\limits_{-1}^1 {\rm d}\mu \Sigma_{\rm el}'(\mu,E) \left[ 1 - P_l(\mu) \right] ~. \end{equation} -The moments $\kappa_l$ depend on the energy and the material in -which the transport takes place, so that the -multiple elastic distribution is dependent on the energy, -path-length (or corresponding energy loss), material, and -threshold energies for discrete interactions. In a Class I -condensed history implementation one uses the total stopping -power (because discrete interaction are not explicitely modelled). -In addition, possible path-lengths are limited to the -energy-loss grid which is decided upon prior to the simulation. -These two facts allow the MS distributions to be pre-computed -and stored in the memory using a relatively small amount of -data. In a Class II implementation path-lengths are stochastic -and so a straightforward pre-calculation for all possible step-lengths -is not possible. In the past this fact has favoured use of +The moments $\kappa_l$ depend on the energy and the material in +which the transport takes place, so that the +multiple elastic distribution is dependent on the energy, +path-length (or corresponding energy loss), material, and +threshold energies for discrete interactions. In a Class I +condensed history implementation one uses the total stopping +power (because discrete interaction are not explicitely modelled). +In addition, possible path-lengths are limited to the +energy-loss grid which is decided upon prior to the simulation. +These two facts allow the MS distributions to be pre-computed +and stored in the memory using a relatively small amount of +data. In a Class II implementation path-lengths are stochastic +and so a straightforward pre-calculation for all possible step-lengths +is not possible. In the past this fact has favoured use of \index{multiple elastic scattering!small-angle approximation} -small-angle theories for the modelling of multiple elastic -scattering, {\em e.g.} the theory of \Mol~ which is used in EGS4. -The limitations of \Mol's theory have been discussed extensively -in the literature. +small-angle theories for the modelling of multiple elastic +scattering, {\em e.g.} the theory of \Mol~ which is used in EGS4. +The limitations of \Mol's theory have been discussed extensively +in the literature. -In EGSnrc we use an exact formulation, the multiple scattering -distributions employed being dependent on the underlying +In EGSnrc we use an exact formulation, the multiple scattering +distributions employed being dependent on the underlying elastic scattering cross sections (see section \ref{elastic}). -\paragraph{Multiple elastic scattering from the screened Rutherford +\paragraph{Multiple elastic scattering from the screened Rutherford cross section} \hfill \index{screened Rutherford cross section} \index{multiple elastic scattering!based on screened Rutherford} -The multiple elastic scattering theory for the screened -Rutherford cross section employed in EGSnrc was developed -by Kawrakow and Bielajew in Ref. \cite{KB97} and later refined -by Kawrakow in Ref. \cite{Ka99a} to better take into account -energy loss. - -The treatment of Ref. \cite{KB97} starts with the MS distribution -that results from the neglect of energy loss which can be written -as -\begin{equation} -2 \pi \Phi_0(\mu,\phi,E) = e^{-\lambda} \delta(1 - \mu) -+ \lambda e^{-\lambda} {1 \over \sigma_{\rm SR}} -{{\rm d} \sigma_{\rm SR}(\mu) \over {\rm d}\mu} + +The multiple elastic scattering theory for the screened +Rutherford cross section employed in EGSnrc was developed +by Kawrakow and Bielajew in Ref. \cite{KB97} and later refined +by Kawrakow in Ref. \cite{Ka99a} to better take into account +energy loss. + +The treatment of Ref. \cite{KB97} starts with the MS distribution +that results from the neglect of energy loss which can be written +as +\begin{equation} +2 \pi \Phi_0(\mu,\phi,E) = e^{-\lambda} \delta(1 - \mu) ++ \lambda e^{-\lambda} {1 \over \sigma_{\rm SR}} +{{\rm d} \sigma_{\rm SR}(\mu) \over {\rm d}\mu} + \left(1 - e^{-\lambda} - \lambda e^{-\lambda} \right) F^{(2+)}_{\rm SR} (\mu) \end{equation} -where $\lambda$ is the number of elastic free paths corresponding +where $\lambda$ is the number of elastic free paths corresponding to the path-length $s$, \begin{equation} \label{lambda} \lambda = \Sigma_{SR} s~, \end{equation} and the screened Rutherford cross section -is given in Eq. \eqref{SR_1}. -The distribution $F^{(2+)}_{\rm SR}$ is the normalized multiple -scattering distribution -that results from at least two elastic collisions described by -the screened Rutherford cross section, +is given in Eq. \eqref{SR_1}. +The distribution $F^{(2+)}_{\rm SR}$ is the normalized multiple +scattering distribution +that results from at least two elastic collisions described by +the screened Rutherford cross section, \index{screened Rutherford cross section} \begin{equation} \label{F_2plus} \begin{split} -F^{(2+)}_{\rm SR}(\mu) & = \sum_{l=0}^\infty \left(l + \frac{1}{2} \right) +F^{(2+)}_{\rm SR}(\mu) & = \sum_{l=0}^\infty \left(l + \frac{1}{2} \right) P_l(\mu) j_l^{(2+)} \\ -j_l^{(2+)} & = { \exp(-G_{l, {\rm SR}}) + -\left[ 1 + \lambda - G_{l,{\rm SR}} \right] \exp(-\lambda) +j_l^{(2+)} & = { \exp(-G_{l, {\rm SR}}) + +\left[ 1 + \lambda - G_{l,{\rm SR}} \right] \exp(-\lambda) \over 1 - \exp(-\lambda) - \lambda \exp(-\lambda) } \end{split} \end{equation} -Here, we have put the subscript ``SR'' on the moments $G_l$ -to explicitly state that they are calculated -using the screened Rutherford cross section. -Equation \eqref{F_2plus} can be put in a more tractable form +Here, we have put the subscript ``SR'' on the moments $G_l$ +to explicitly state that they are calculated +using the screened Rutherford cross section. +Equation \eqref{F_2plus} can be put in a more tractable form by a variable change, \index{screened Rutherford cross section} \begin{equation} u = (1 + a) \left(1 - {2 a \over 1 - \mu + 2 a} \right) \end{equation} -where the parameter $a$ is chosen such as to make $q^{(2+)}_{\rm SR}$, +where the parameter $a$ is chosen such as to make $q^{(2+)}_{\rm SR}$, \begin{equation} q^{(2+)}_{\rm SR}(u) = F^{(2+)}_{\rm SR}(\mu)~{{\rm d} \mu \over {\rm d} u}~, \end{equation} -``as flat as possible''. After some +``as flat as possible''. After some straightforward manipulations one obtains \cite{KB97} \begin{equation} \label{a-kappa} a = \kappa + \sqrt{\kappa^2 + \kappa} -\end{equation} +\end{equation} with the short hand notation \begin{equation} \label{kappa} \begin{split} -\kappa & = {\langle 0\rangle - 2 \langle 1\rangle + +\kappa & = {\langle 0\rangle - 2 \langle 1\rangle + \langle 2\rangle \over 4 \langle 1\rangle } \\ -\langle n\rangle & = +\langle n\rangle & = \sum_{l=0}^\infty \left( l + {1 \over 2} \right) j_l^{(2+)} \sum_{m=0}^\infty \left( m + {1 \over 2} \right) j_m^{(2+)} \int_{-1}^1 {\rm d} \mu~ \mu^n P_l(\mu) P_m(\mu)~, \end{split} \end{equation} -The quantity $\omega^2 = a/\eta$ ($\eta$ is the screening parameter) -is a function of $\lambda$ and has a slight dependence -on $\eta$. In terms of simulation efficiency, it is better to -ignore the $\eta$ dependence of $\omega$ and use a fit to -the data obtained at run time from Eq. (\ref{a-kappa},\ref{kappa}) for -$\eta \to 0$. We use +The quantity $\omega^2 = a/\eta$ ($\eta$ is the screening parameter) +is a function of $\lambda$ and has a slight dependence +on $\eta$. In terms of simulation efficiency, it is better to +ignore the $\eta$ dependence of $\omega$ and use a fit to +the data obtained at run time from Eq. (\ref{a-kappa},\ref{kappa}) for +$\eta \to 0$. We use \begin{equation} \label{fit_omega2} \begin{split} -{\omega^2 \over \lambda + 4} & = +{\omega^2 \over \lambda + 4} & = \begin{cases} -1.347 + t (0.209364 - t (0.45525 - t (0.50142 - 0.081234 t))) & \text{if}~ +1.347 + t (0.209364 - t (0.45525 - t (0.50142 - 0.081234 t))) & \text{if}~ \lambda < 10, \\ -2.77164 + t (2.94874 - t (0.1535754 - 0.00552888 t)) & \text{else} \end{cases} @@ -2258,103 +2258,103 @@ \subsubsection{Multiple elastic scattering} t & = \ln \lambda \end{split} \end{equation} -The dependence of the distribution $q^{(2+)}_{\rm SR}(u)$ on -$\lambda$ and $\eta$ +The dependence of the distribution $q^{(2+)}_{\rm SR}(u)$ on +$\lambda$ and $\eta$ \begin{figure}[htp] \includegraphics[height=15cm,width=15cm]{figures/q2} -\caption[The $q^{(2+)}$ surface]{\label{fig_q2} -The $q^{(2+)}_{\rm SR}$ distribution for -three step-lengths. The curve labelled ``small-angle'' limit is -the distribution for $\eta \to 0$ (infinite energy), the -curve for the maximum step-size corresponds to the +\caption[The $q^{(2+)}$ surface]{\label{fig_q2} +The $q^{(2+)}_{\rm SR}$ distribution for +three step-lengths. The curve labelled ``small-angle'' limit is +the distribution for $\eta \to 0$ (infinite energy), the +curve for the maximum step-size corresponds to the maximum step-size for condensed history steps for which the data base was generated ($G_1 < 0.5$, see section~\ref{es_algorithm}.)} -\end{figure} -is rather weak, as can be seen in Fig. \ref{fig_q2}. -$q^{(2+)}_{\rm SR}$ can therefore be interpolated -very accurately during run time using -linear interpolation in $\ln \lambda$ and $G_{1,{\rm SR}}$ +\end{figure} +is rather weak, as can be seen in Fig. \ref{fig_q2}. +$q^{(2+)}_{\rm SR}$ can therefore be interpolated +very accurately during run time using +linear interpolation in $\ln \lambda$ and $G_{1,{\rm SR}}$ from a pre-computed table. -Here $G_{1,{\rm SR}}$ denotes the first -GS moment, see Eq. \eqref{GS_moments}, resulting +Here $G_{1,{\rm SR}}$ denotes the first +GS moment, see Eq. \eqref{GS_moments}, resulting from screened Rutherford elastic scattering, \index{screened Rutherford cross section} \begin{equation} \label{G1_SR} -G_{1,{\rm SR}} = +G_{1,{\rm SR}} = 2 \lambda \eta \left[ (1 + \eta) \ln\left(1 + \frac{1}{\eta}\right) - 1 \right] \end{equation} -The $q^{(2+)}_{\rm SR}$ data which are in a form of a 3 dimensional -alias table, are stored in the file {\tt newms.data} and read in +The $q^{(2+)}_{\rm SR}$ data which are in a form of a 3 dimensional +alias table, are stored in the file {\tt newms.data} and read in by subroutine {\tt init\_ms\_SR}. \index{multiple elastic scattering!energy loss} -To take into account energy loss, one uses the multiple scattering -distribution for an ``effective'' step energy which is +To take into account energy loss, one uses the multiple scattering +distribution for an ``effective'' step energy which is determined from the requirement \cite{Ka99a} \begin{equation} -{G_2(E_0,E) \over G_1(E_0,E)} = +{G_2(E_0,E) \over G_1(E_0,E)} = {\kappa_2(E_{\rm eff}) \over \kappa_1(E_{\rm eff})} \end{equation} for a path-length $s_{\rm eff}$, \begin{equation} s_{\rm eff} = {G_1(E_0,E) \over \kappa_1(E_{\rm eff})}~. \end{equation} -These two requirements guarantee that the first two GS moments -are exactly reproduced, and gives at the same time a very accurate -approximation for higher order GS so that the resulting -multiple scattering distribution is virtually -identical to the MS distribution calculated via numerical integration +These two requirements guarantee that the first two GS moments +are exactly reproduced, and gives at the same time a very accurate +approximation for higher order GS so that the resulting +multiple scattering distribution is virtually +identical to the MS distribution calculated via numerical integration of the moments $G_l$, see Fig. 2 of Ref. \cite{Ka99a}. \index{screened Rutherford cross section} -For the screened Rutherford cross section the effective energy and -path-length are given by +For the screened Rutherford cross section the effective energy and +path-length are given by \begin{eqnarray} \label{E-eff} -E_{\rm eff} & = & E_0 \left[ 1 - {\epsilon \over 2} - -{\epsilon^2 \over 12 (2 - \epsilon)} \left( -{5 \tilde{\tau}^2 + 10 \tilde{\tau} + 6 \over (\tilde{\tau} + 1) -(\tilde{\tau} + 2)} + 2 b(\tilde{E}) \right) + O(\epsilon^3) \right] +E_{\rm eff} & = & E_0 \left[ 1 - {\epsilon \over 2} - +{\epsilon^2 \over 12 (2 - \epsilon)} \left( +{5 \tilde{\tau}^2 + 10 \tilde{\tau} + 6 \over (\tilde{\tau} + 1) +(\tilde{\tau} + 2)} + 2 b(\tilde{E}) \right) + O(\epsilon^3) \right] \nonumber \\ -s_{\rm eff} & = & s \left( 1 - {\epsilon^2 \over 3 ( 2 - \epsilon)}~ -{\tilde{\tau}^4 + 4 \tilde{\tau}^3 + 7 \tilde{\tau}^2 + 6 \tilde{\tau} +s_{\rm eff} & = & s \left( 1 - {\epsilon^2 \over 3 ( 2 - \epsilon)}~ +{\tilde{\tau}^4 + 4 \tilde{\tau}^3 + 7 \tilde{\tau}^2 + 6 \tilde{\tau} + 4 \over (\tilde{\tau} + 1)^2 (\tilde{\tau} + 2)^2} + O(\epsilon^4) \right) \end{eqnarray} where we have defined \begin{equation} \label{bE} -b(E) = {E \over C(E)}~ +b(E) = {E \over C(E)}~ {{\rm d} C(E) \over {\rm d}E~}~,\quad \quad C(E) = L(E) \beta^2~, \end{equation} $\beta$ denoting the particle velocity in units of the speed of light. -In the above equations $\epsilon = (E_0 - E)/E$ and $\tilde{\tau} = +In the above equations $\epsilon = (E_0 - E)/E$ and $\tilde{\tau} = 1/2 (E_0 + E)/m$. \index{multiple elastic scattering!sampling of} -With all this, the algorithm for sampling multiple elastic scattering +With all this, the algorithm for sampling multiple elastic scattering angles is as follows: \begin{enumerate} \item Calculate $s_{\rm eff}$ and $E_{\rm eff}$ from Eq. \eqref{E-eff}. \item -Calculate $\lambda$ from Eq. \eqref{lambda} and \eqref{SR_tot}, +Calculate $\lambda$ from Eq. \eqref{lambda} and \eqref{SR_tot}, $t = \ln \lambda$ and $\eta$ from Eq. \eqref{calc_eta} \item -Pick a random number number $r_1$. +Pick a random number number $r_1$. \item -If $r_1 < e^{-\lambda}$, then the scattering angle is zero, return +If $r_1 < e^{-\lambda}$, then the scattering angle is zero, return control to the calling routine \item -Else if $r_1 < e^{-\lambda}(1 + \lambda)$, then sample $\mu$ from -the single scattering distribution according to Eq. \eqref{sample_SR}, +Else if $r_1 < e^{-\lambda}(1 + \lambda)$, then sample $\mu$ from +the single scattering distribution according to Eq. \eqref{sample_SR}, return control to the calling routine \item -Else, we must sample $\mu$ from the $q^{(2+)}_{\rm SR}$ distribution. -Calculate $G_{1,{\rm SR}}$ from Eq. \eqref{G1_SR}, -$\omega^2$ from Eq. \eqref{fit_omega2} and +Else, we must sample $\mu$ from the $q^{(2+)}_{\rm SR}$ distribution. +Calculate $G_{1,{\rm SR}}$ from Eq. \eqref{G1_SR}, +$\omega^2$ from Eq. \eqref{fit_omega2} and $a = \omega^2 \eta$ \item Determine the table look-up indices for $\ln \lambda$ and $G_{1,{\rm SR}}$ @@ -2372,38 +2372,38 @@ \subsubsection{Multiple elastic scattering} \index{multiple elastic scattering!spin effects} \index{screened Rutherford cross section} -In principle, the approach developed in Ref. \cite{KB97} could -be applied to more complicated single elastic scattering cross -sections than the screened Rutherford cross section. -We have found, however, that the direct use of this approach for +In principle, the approach developed in Ref. \cite{KB97} could +be applied to more complicated single elastic scattering cross +sections than the screened Rutherford cross section. +We have found, however, that the direct use of this approach for the cross section with spin effects (see section \ref{spin_elastic}) -does not lead to a satisfactory interpolation accuracy. We have -therefore implemented a rejection technique for the sampling -of multiple scattering angles when {\tt SPIN\_EFFECTS = .true.}. +does not lead to a satisfactory interpolation accuracy. We have +therefore implemented a rejection technique for the sampling +of multiple scattering angles when {\tt SPIN\_EFFECTS = .true.}. \index{SPIN\_EFFECTS} -We can write the multiple scattering distribution -that results from at least 2 elastic scattering processes as +We can write the multiple scattering distribution +that results from at least 2 elastic scattering processes as \index{screened Rutherford cross section} \begin{equation} \label{ms_spin1} -F^{(2+)}(\lambda,\eta,Z,\mu) = F^{(2+)}_{\rm SR}(\lambda,\eta,\mu) +F^{(2+)}(\lambda,\eta,Z,\mu) = F^{(2+)}_{\rm SR}(\lambda,\eta,\mu) R(\lambda,\eta,Z,\mu) \end{equation} -where $F^{(2+)}_{\rm SR}$ is the 2+ distribution from a -screened Rutherford cross section for a path-length corresponding -to $\lambda$ elastic mean-free paths and a screening angle $\eta$ -and $R(\lambda,\eta,Z,\mu)$ is defined as +where $F^{(2+)}_{\rm SR}$ is the 2+ distribution from a +screened Rutherford cross section for a path-length corresponding +to $\lambda$ elastic mean-free paths and a screening angle $\eta$ +and $R(\lambda,\eta,Z,\mu)$ is defined as \begin{equation} - R(\lambda,\eta,Z,\mu) = {F^{(2+)}(\lambda,\eta,Z,\mu) \over + R(\lambda,\eta,Z,\mu) = {F^{(2+)}(\lambda,\eta,Z,\mu) \over F^{(2+)}_{\rm SR}(\lambda,\eta,\mu)} \end{equation} ({\em i.e.} Eq. \eqref{ms_spin1} is the identity $F^{(2+)}=F^{(2+)}$). -The function $R(\lambda,\eta,Z,\mu)$ is a three dimensional -surface for each medium. -Numerical experiments show that the way which requires the minimum -amount of pre-calculated data to interpolate -the function $R(\lambda,\eta,Z,\mu)$ between pre-calculated +The function $R(\lambda,\eta,Z,\mu)$ is a three dimensional +surface for each medium. +Numerical experiments show that the way which requires the minimum +amount of pre-calculated data to interpolate +the function $R(\lambda,\eta,Z,\mu)$ between pre-calculated data is to use for each medium \begin{itemize} \item @@ -2411,59 +2411,59 @@ \subsubsection{Multiple elastic scattering} \begin{equation} q = {2 G_{1,{\rm SR}}(\lambda,\eta) \over 1 + 2 G_{1,{\rm SR}}(\lambda,\eta)}~. \end{equation} -Obviously $q$ can take only values between zero and unity. For -$q \to 0, R(\lambda,\eta,Z,\mu)$ converges to $R_{\rm mott}(E,Z,\mu)$, -see section \ref{spin_elastic}. For $q \to 1, R(\lambda,\eta,Z,\mu)$ -goes to unity for all angles $\mu$. The rate at which the function +Obviously $q$ can take only values between zero and unity. For +$q \to 0, R(\lambda,\eta,Z,\mu)$ converges to $R_{\rm mott}(E,Z,\mu)$, +see section \ref{spin_elastic}. For $q \to 1, R(\lambda,\eta,Z,\mu)$ +goes to unity for all angles $\mu$. The rate at which the function $R$ changes from the one limit to the other depends on the energy. \item -Linear interpolation in $\beta^2$ for energies greater than +Linear interpolation in $\beta^2$ for energies greater than 100 keV, linear interpolation in $\ln E$ for energies less -then 100 keV. +then 100 keV. \item Linear interpolation in $\sin \theta/2 = \sqrt{(1-\mu)/2}$. \end{itemize} -The pre-calculated data are stored in separate files for -all elements in the directory {\tt spinms} and used -in subroutine {\tt init\_spin} to compute $R$ for -the media involved in the actual simulation. {\tt init\_spin} -is called from {\tt mscati} which is called from {\tt HATCH}. - -The sampling algorithm is then similar to the one given at the -and of the previous section but involves an additional rejection -loop in steps 4 and 8 using $R_{\rm mott}$ or $R$ as a -rejection function\footnote{Both, $R_{\rm mott}$ and $R$ are -scaled to their maximum in the routine {\tt init\_spin}.}. -In addition, the calculation of the screening parameter -$\eta$ and the number of mean-free-paths $\lambda$ involve -additional correction factors, because both, $\eta/\eta_0$ and -the parameter $\xi$ which describe the contribution -of sub-threshold inelastic collisions to angular deflections, +The pre-calculated data are stored in separate files for +all elements in the directory {\tt spinms} and used +in subroutine {\tt init\_spin} to compute $R$ for +the media involved in the actual simulation. {\tt init\_spin} +is called from {\tt mscati} which is called from {\tt HATCH}. + +The sampling algorithm is then similar to the one given at the +and of the previous section but involves an additional rejection +loop in steps 4 and 8 using $R_{\rm mott}$ or $R$ as a +rejection function\footnote{Both, $R_{\rm mott}$ and $R$ are +scaled to their maximum in the routine {\tt init\_spin}.}. +In addition, the calculation of the screening parameter +$\eta$ and the number of mean-free-paths $\lambda$ involve +additional correction factors, because both, $\eta/\eta_0$ and +the parameter $\xi$ which describe the contribution +of sub-threshold inelastic collisions to angular deflections, are not constant, see section \ref{spin_elastic}. \index{spin effects!measurements} -It is worth showing an example of the influence of the inclusion -of spin effects in the treatment of elastic scattering as -a conclusion of this section. +It is worth showing an example of the influence of the inclusion +of spin effects in the treatment of elastic scattering as +a conclusion of this section. \begin{figure}[htp] \includegraphics[height=12cm,width=12cm]{figures/dd_1MeV_Be_and_U} -\caption[Depth-dose curves in Beryllium and Uranium]{\label{dd_spin} -Depth-dose curves -for a broad parallel beam of 1 MeV electrons incident -on a Beryllium or Uranium target as a function of the CSDA range. +\caption[Depth-dose curves in Beryllium and Uranium]{\label{dd_spin} +Depth-dose curves +for a broad parallel beam of 1 MeV electrons incident +on a Beryllium or Uranium target as a function of the CSDA range. The experimental data are from \protect\cite{Lo80a}.} -\end{figure} -Figure \ref{dd_spin} shows a comparison of calculated depth-dose curves +\end{figure} +Figure \ref{dd_spin} shows a comparison of calculated depth-dose curves in Beryllium and Uranium to measurements by Lockwood {\em et al} \cite{Lo80a}. -Both, the calculations and the measurements are absolute. -The calculations with ``spin on'' are in much better agreement -with the experiment. The effect of including spin is -to make the effective range of electrons longer for low-$Z$ -materials and shorter for high-$Z$ materials. It is also -present for the energy range relevant for radiation therapy. -The reason for not seeing disagreement between EGS4 calculations -and measurements in this energy range is due to the rarity of -measurements +Both, the calculations and the measurements are absolute. +The calculations with ``spin on'' are in much better agreement +with the experiment. The effect of including spin is +to make the effective range of electrons longer for low-$Z$ +materials and shorter for high-$Z$ materials. It is also +present for the energy range relevant for radiation therapy. +The reason for not seeing disagreement between EGS4 calculations +and measurements in this energy range is due to the rarity of +measurements with precise knowledge of the incident energy. In depth-dose measurements with a known 20 MeV electron beam incident on water, comparisons to EGS4 required using an incident beam energy of 20.3 MeV to get good @@ -2477,46 +2477,46 @@ \subsubsection{Electron-step algorithm} \setcounter{equation}{0} \index{electron-step algorithm} -As mentioned in section \ref{electron_general}, -the transport between -subsequent ``catastrophic'' collisions is described by -Eq. \eqref{transport3} with Eq. \eqref{s_vs_E} providing -the link between energy and path-length. An exact solution -of this equation is not known and so some approximate -methods are required to relate the -energy loss, the path-length, and the spatial displacement. - -The simplest possible -approach one could take is to ignore deflections due -to multiple elastic scattering -during the condensed history step and -to transport the electron on a straight line along the initial -direction of motion. In order for this approach to -be accurate the CH steps must be sufficiently short so -that the straight line approach does not represent to a -severe approximation. Larsen has shown \cite{La92} that -any condensed history algorithm will converge to the correct -answer in the limit of sufficiently small step-sizes, provided -multiple elastic scattering is faithfully simulated. -However, making the step lengths very short may -cause the simulation to become extremely inefficient. -In addition, if the calculated results show step-size -dependencies, one needs to perform a careful step-size -study in order to determine when the result has -converged. - -Many electron-step algorithms that attempt to make -corrections for deflections from the straight-line -approach have been proposed over the years, {\em e.g.} -\cite{Be63,BR87,Fe93,Ka96b}. A detailed discussion of these -algorithms is given in Ref. \cite{KB97a}. In general -none of the algorithms available is accurate enough -to allow the condensed history simulation between -subsequent discrete events to be always done in a single -step. Instead, the distances between discrete collisions -is divided into smaller condensed history steps using -a procedure to determine maximum acceptable -lengths for the steps (step-size restrictions). +As mentioned in section \ref{electron_general}, +the transport between +subsequent ``catastrophic'' collisions is described by +Eq. \eqref{transport3} with Eq. \eqref{s_vs_E} providing +the link between energy and path-length. An exact solution +of this equation is not known and so some approximate +methods are required to relate the +energy loss, the path-length, and the spatial displacement. + +The simplest possible +approach one could take is to ignore deflections due +to multiple elastic scattering +during the condensed history step and +to transport the electron on a straight line along the initial +direction of motion. In order for this approach to +be accurate the CH steps must be sufficiently short so +that the straight line approach does not represent to a +severe approximation. Larsen has shown \cite{La92} that +any condensed history algorithm will converge to the correct +answer in the limit of sufficiently small step-sizes, provided +multiple elastic scattering is faithfully simulated. +However, making the step lengths very short may +cause the simulation to become extremely inefficient. +In addition, if the calculated results show step-size +dependencies, one needs to perform a careful step-size +study in order to determine when the result has +converged. + +Many electron-step algorithms that attempt to make +corrections for deflections from the straight-line +approach have been proposed over the years, {\em e.g.} +\cite{Be63,BR87,Fe93,Ka96b}. A detailed discussion of these +algorithms is given in Ref. \cite{KB97a}. In general +none of the algorithms available is accurate enough +to allow the condensed history simulation between +subsequent discrete events to be always done in a single +step. Instead, the distances between discrete collisions +is divided into smaller condensed history steps using +a procedure to determine maximum acceptable +lengths for the steps (step-size restrictions). \index{step-size restrictions} \index{trans\-port\_algo\-rithm} @@ -2524,44 +2524,44 @@ \subsubsection{Electron-step algorithm} \index{path-length correction} \index{lateral correlation algorithm} \index{PRESTA} -The electron-step algorithm employed in EGSnrc depends -on the parameter {\tt trans\-port\_algo\-rithm} which -is in {\tt COMMON/ET\_Control/}. If set -to one, a slightly modified version of -PRESTA's \cite{BR87} path-length-correction (PLC) -and lateral correlation algorithm (LCA) are employed. -The PRESTA algorithm is known to underestimate -lateral deflections (deflections perpendicular to the -initial direction of motion), to underestimate -longitudinal straggling and to produce a singularity -in the distribution describing the lateral spread of electrons -in a single condensed history step \cite{Ka96b,KB97a}. -The implications on the simulation results depend on -the actual situation under investigation. At high energies, -where elastic scattering is weak, PRESTA is perhaps sufficiently -accurate. Its use for low energy applications is not -recommended. One of us has shown, for instance, that -there is up to 8\% variation of the calculated ion chamber -response subject to a $^{60}Co$ beam when using PRESTA's +The electron-step algorithm employed in EGSnrc depends +on the parameter {\tt trans\-port\_algo\-rithm} which +is in {\tt COMMON/ET\_Control/}. If set +to one, a slightly modified version of +PRESTA's \cite{BR87} path-length-correction (PLC) +and lateral correlation algorithm (LCA) are employed. +The PRESTA algorithm is known to underestimate +lateral deflections (deflections perpendicular to the +initial direction of motion), to underestimate +longitudinal straggling and to produce a singularity +in the distribution describing the lateral spread of electrons +in a single condensed history step \cite{Ka96b,KB97a}. +The implications on the simulation results depend on +the actual situation under investigation. At high energies, +where elastic scattering is weak, PRESTA is perhaps sufficiently +accurate. Its use for low energy applications is not +recommended. One of us has shown, for instance, that +there is up to 8\% variation of the calculated ion chamber +response subject to a $^{60}Co$ beam when using PRESTA's transport algorithm \cite{Ka99b}. -If the parameter {\tt trans\-port\_algo\-rithm} is set to zero -(it's default value), the electron-step algorithm -developed in Ref. \cite{KB97a} and later refined in -\cite{Ka99a} is employed. This algorithm is constructed -in such a way as to reproduce up to second order spatial moments -of the fluence $\Phi_0(\vec{x},\vec{\Omega},E,t)$, which -are known from the theory of Lewis \cite{Le50} for -transport in an infinite, homogeneous medium. This algorithm -was shown to produce step-size independent results for -ion chamber simulations and backscattering \cite{Ka99a,Ka99b}, two of the -most difficult tasks for condensed history Monte Carlo codes. - -For completeness, we give a brief summary of the transport -algorithms available in EGSnrc. Final positions are in a frame -where the electron is initially at the origin and moving -along the positive z-axis. Positions in the actual simulation -co-ordinate system are obtained using the appropriate +If the parameter {\tt trans\-port\_algo\-rithm} is set to zero +(it's default value), the electron-step algorithm +developed in Ref. \cite{KB97a} and later refined in +\cite{Ka99a} is employed. This algorithm is constructed +in such a way as to reproduce up to second order spatial moments +of the fluence $\Phi_0(\vec{x},\vec{\Omega},E,t)$, which +are known from the theory of Lewis \cite{Le50} for +transport in an infinite, homogeneous medium. This algorithm +was shown to produce step-size independent results for +ion chamber simulations and backscattering \cite{Ka99a,Ka99b}, two of the +most difficult tasks for condensed history Monte Carlo codes. + +For completeness, we give a brief summary of the transport +algorithms available in EGSnrc. Final positions are in a frame +where the electron is initially at the origin and moving +along the positive z-axis. Positions in the actual simulation +co-ordinate system are obtained using the appropriate rotations and spatial translations. \begin{itemize} \index{PRESTA} @@ -2573,29 +2573,29 @@ \subsubsection{Electron-step algorithm} x &= r_\perp \sin \theta \cos \phi \\ y &= r_\perp \sin \theta \sin \phi \\ z &= \langle z \rangle \\ -r_\perp &= \mbox{Min}\left({s \over 2},\sqrt{{s^2 - \langle z \rangle^2 \over +r_\perp &= \mbox{Min}\left({s \over 2},\sqrt{{s^2 - \langle z \rangle^2 \over \sin^2 \theta}} \right) \end{split} \end{equation} -where $\theta$ and $\phi$ are the polar and azimuthal scattering -angles and $\langle z \rangle$ the average transport distance -in the initial direction of motion for a path-length of $s$. -In the original PRESTA implementation $\langle z \rangle$ -was calculated from the theory of \Mol, we use in EGSnrc the +where $\theta$ and $\phi$ are the polar and azimuthal scattering +angles and $\langle z \rangle$ the average transport distance +in the initial direction of motion for a path-length of $s$. +In the original PRESTA implementation $\langle z \rangle$ +was calculated from the theory of \Mol, we use in EGSnrc the exact expression of Lewis \cite{Le50}, which is simply \begin{equation} \langle z \rangle = s~{1 - \exp(-G_1) \over G_1} \end{equation} -if one neglects energy loss. A small correction arises -if energy loss is taken into account, it is not included +if one neglects energy loss. A small correction arises +if energy loss is taken into account, it is not included to be consistent with PRESTA where energy loss was also ignored. \item {\tt trans\-port\_algo\-rithm = 0} (EGSnrc default) \hfill \\ -The condensed history step is divided into two sub-steps and -separate multiple elastic scattering angles $\theta_1,\phi_1$ and -$\theta_2,\phi_2$ are sampled. The final scattering angle +The condensed history step is divided into two sub-steps and +separate multiple elastic scattering angles $\theta_1,\phi_1$ and +$\theta_2,\phi_2$ are sampled. The final scattering angle is then determined from $\theta_1,\phi_1$,$\theta_2,\phi_2$, {\em e.g.} \begin{equation} -\cos \theta = \cos \theta_1 \cos \theta_2 - \sin \theta_1 \sin \theta_2 +\cos \theta = \cos \theta_1 \cos \theta_2 - \sin \theta_1 \sin \theta_2 \cos(\phi_1 - \phi_2)~. \end{equation} The final position is calculated as follows: @@ -2603,26 +2603,26 @@ \subsubsection{Electron-step algorithm} \label{egsnrc_algorithm} \begin{split} x & = s \Big[ \eta \delta \sin \theta_1 \cos \phi_1 + -\eta (1 - \delta) \sin \theta_2 ( \cos \phi_1 \cos \phi_2 - -\cos \theta_1 \sin \phi_1 \sin \phi_2 ) + +\eta (1 - \delta) \sin \theta_2 ( \cos \phi_1 \cos \phi_2 - +\cos \theta_1 \sin \phi_1 \sin \phi_2 ) + a_2 \sin \theta \cos \phi \Big] \\ y & = s \Big[ \eta \delta \sin \theta_1 \sin \phi_1 + -\eta (1 - \delta) \sin \theta_2 ( \sin \phi_1 \cos \phi_2 + -\cos \theta_1 \cos \phi_1 \sin \phi_2 ) + +\eta (1 - \delta) \sin \theta_2 ( \sin \phi_1 \cos \phi_2 + +\cos \theta_1 \cos \phi_1 \sin \phi_2 ) + a_2 \sin \theta \sin \phi \Big] \\ z & = s \Big[ a_1 + \eta \delta \cos \theta_1 + \eta (1 - \delta) \cos \theta_2 + a_2 \cos \theta \Big] \\ a_1 & = {1 - \eta \over 2} (1 + \alpha_1) \\ a_2 & = {1 - \eta \over 2} (1 - \alpha_1) \\ -\delta & = {1 \over 2} + {\sqrt{6} \over 6} - -\left( {1 \over 4 \sqrt{6}} - \gamma {4 - \sqrt{6} \over 24 \sqrt{6}} +\delta & = {1 \over 2} + {\sqrt{6} \over 6} - +\left( {1 \over 4 \sqrt{6}} - \gamma {4 - \sqrt{6} \over 24 \sqrt{6}} \right) G_1 + \alpha_2 \\ \gamma & = {G_2 \over G_1} \end{split} \end{equation} -Here, $\eta$ is a random number sampled from $2 \eta {\rm d} \eta$ -(and not the screening parameter) and $\alpha_1$ and $\alpha_2$ +Here, $\eta$ is a random number sampled from $2 \eta {\rm d} \eta$ +(and not the screening parameter) and $\alpha_1$ and $\alpha_2$ are energy loss corrections derived in Ref. \cite{Ka99a}, \begin{equation} \label{eloss_correction} @@ -2630,80 +2630,80 @@ \subsubsection{Electron-step algorithm} \alpha_1 & = - {\kappa_1'(\tilde{E}) \over \kappa_1(\tilde{E})}~ {\Delta E \over 2} + O(\Delta E^2) \\ \alpha_2 & = \left( {\kappa_2'(\tilde{E}) \over \kappa_2(\tilde{E})} -- {\kappa_1'(\tilde{E}) \over \kappa_1(\tilde{E})} \right) {\Delta E \over +- {\kappa_1'(\tilde{E}) \over \kappa_1(\tilde{E})} \right) {\Delta E \over 2 \sqrt{6} } + O(\Delta E^2) \end{split} \end{equation} -where $\Delta E$ is the sub-threshold energy loss associated -with the step, $\tilde{E}$ the average step energy and -$\kappa_1'$ and $\kappa_2'$ derivatives of the -moments $\kappa_1$ and $\kappa_2$ (see Eq. \eqref{kappa_l}) -with respect to $E$. +where $\Delta E$ is the sub-threshold energy loss associated +with the step, $\tilde{E}$ the average step energy and +$\kappa_1'$ and $\kappa_2'$ derivatives of the +moments $\kappa_1$ and $\kappa_2$ (see Eq. \eqref{kappa_l}) +with respect to $E$. \index{ximax} \index{ESTEPE} \index{$G_1$} -If elastic scattering is described by the screened Rutherford -cross section, the energy loss corrections $\alpha_1$ and -$\alpha_2$ are given by +If elastic scattering is described by the screened Rutherford +cross section, the energy loss corrections $\alpha_1$ and +$\alpha_2$ are given by \begin{equation} \label{eloss_correction_SR} \begin{split} -\alpha_1 & \approx \left( {2 + 2 \tilde{\tau} + \tilde{\tau}^2 \over -(1 + \tilde{\tau}) } - {1 + \tilde{\tau} \over -\ln(1 + 1/\tilde{\eta}) (1 + \tilde{\eta}) - 1) } \right) +\alpha_1 & \approx \left( {2 + 2 \tilde{\tau} + \tilde{\tau}^2 \over +(1 + \tilde{\tau}) } - {1 + \tilde{\tau} \over +\ln(1 + 1/\tilde{\eta}) (1 + \tilde{\eta}) - 1) } \right) {\Delta E/\tilde{E} \over (2 + \tilde{\tau})} \\ -\alpha_2 & \approx {\Delta E/\tilde{E} \over \sqrt{6} (1 + \tilde{\tau}) +\alpha_2 & \approx {\Delta E/\tilde{E} \over \sqrt{6} (1 + \tilde{\tau}) (2 + \tilde{\tau}) \Big[ -\ln(1 + 1/\tilde{\eta}) (1 + \tilde{\eta}) - 1) \Big] +\ln(1 + 1/\tilde{\eta}) (1 + \tilde{\eta}) - 1) \Big] \Big[ \ln(1 + 1/\tilde{\eta}) (1 + 2 \tilde{\eta}) - 2) \Big] } \end{split} \end{equation} -where $\tilde{\tau} = \tilde{E}/m$ and -$\tilde{\eta}$ is the screening parameter for -the midpoint energy $\tilde{E}$. -These equations are used in the subroutine {\tt msdist\_pII} -which implements condensed history electron transport according -to the algorithm given in Eq. \eqref{egsnrc_algorithm}. -Strictly speaking, when spin effects are ``turned on'', one -should use the energy loss corrections derived -from the moments resulting from the corresponding elastic scattering -cross section. We have left this refinment for the future because -(i) Given the fact that the corrections involve the calculation -of derivatives and that the cross sections with spin are -available only in numerical form, the implementation is more -difficult (ii) Eq. \eqref{eloss_correction_SR} does take into -account the main energy dependence of the corrections, deviations -from Eq. \eqref{eloss_correction_SR} are either higher order -in $\Delta E$ or have small coefficients. - -The algorithm given in Eq. \eqref{egsnrc_algorithm} reproduces -first and second order spatial moments to better than 0.1\% for +where $\tilde{\tau} = \tilde{E}/m$ and +$\tilde{\eta}$ is the screening parameter for +the midpoint energy $\tilde{E}$. +These equations are used in the subroutine {\tt msdist\_pII} +which implements condensed history electron transport according +to the algorithm given in Eq. \eqref{egsnrc_algorithm}. +Strictly speaking, when spin effects are ``turned on'', one +should use the energy loss corrections derived +from the moments resulting from the corresponding elastic scattering +cross section. We have left this refinment for the future because +(i) Given the fact that the corrections involve the calculation +of derivatives and that the cross sections with spin are +available only in numerical form, the implementation is more +difficult (ii) Eq. \eqref{eloss_correction_SR} does take into +account the main energy dependence of the corrections, deviations +from Eq. \eqref{eloss_correction_SR} are either higher order +in $\Delta E$ or have small coefficients. + +The algorithm given in Eq. \eqref{egsnrc_algorithm} reproduces +first and second order spatial moments to better than 0.1\% for $G_1 \le 0.5$ if energy loss is neglected ($G_1$ is defined by Eq. \eqref{GS_moments} and is a function of pathlength, so this condition -imposes a maximum allowed step size). This accuracy -is maintained when energy loss is taken into account via -the corrections given in \eqref{eloss_correction} if -the maximum fractional energy loss per step is -restricted to 25\%. These two condensed history -step-size restrictions are controlled via the -parameters {\tt ximax} (corresponding to the maximum allowed $G_1$) -and {\tt ESTEPE} which are in {\tt COMMON/ET\_Control} and set by default -to 0.5 and 0.25. - -Due to the use of the energy loss corrections derived from the -screened Rutherford cross section also for elastic scattering -with spin, in this case the deviation from the theoretical expectation -is slightly larger and exceeds 0.1\% for {\tt ESTEPE} between -0.15 and 0.2. If such a high precision is required for -your application, the simplest solution is to use step sizes +imposes a maximum allowed step size). This accuracy +is maintained when energy loss is taken into account via +the corrections given in \eqref{eloss_correction} if +the maximum fractional energy loss per step is +restricted to 25\%. These two condensed history +step-size restrictions are controlled via the +parameters {\tt ximax} (corresponding to the maximum allowed $G_1$) +and {\tt ESTEPE} which are in {\tt COMMON/ET\_Control} and set by default +to 0.5 and 0.25. + +Due to the use of the energy loss corrections derived from the +screened Rutherford cross section also for elastic scattering +with spin, in this case the deviation from the theoretical expectation +is slightly larger and exceeds 0.1\% for {\tt ESTEPE} between +0.15 and 0.2. If such a high precision is required for +your application, the simplest solution is to use step sizes that don't exceed 20\% energy loss per step when spin is on. \end{itemize} -%If one expands +%If one expands %Eq. \eqref{transport3} in spherical harmonics, %\begin{equation} -%\Phi_0(\vec{x},\vec{\Omega},s) = \sum\limits_{l m} +%\Phi_0(\vec{x},\vec{\Omega},s) = \sum\limits_{l m} %f_{l m}(\vec{x},s) Y_{l m}(\vec{\Omega})~, %\end{equation} %the elastic scattering cross section in Legendre polynomials, @@ -2714,68 +2714,68 @@ \subsubsection{Boundary crossing algorithm} \setcounter{equation}{0} \index{boundary crossing algorithm} -The electron-step algorithms discussed in section -\ref{es_algorithm} are valid only for transport in -an infinite, homogeneous medium. In practical -situations one has to deal with interfaces between -different materials. If an electron is close -to an interface with another material, portions -of its curved path may be in this different material and -so the trajectory different than simulated. -In the original EGS4 version, this problem associated -with the condensed history simulation of electron -transport, which has become known as the interface artifact \cite{Bi85}, was -entirely ignored. +The electron-step algorithms discussed in section +\ref{es_algorithm} are valid only for transport in +an infinite, homogeneous medium. In practical +situations one has to deal with interfaces between +different materials. If an electron is close +to an interface with another material, portions +of its curved path may be in this different material and +so the trajectory different than simulated. +In the original EGS4 version, this problem associated +with the condensed history simulation of electron +transport, which has become known as the interface artifact \cite{Bi85}, was +entirely ignored. To address the interface artifact, -a refined boundary crossing algorithm (BCA) was -incorporated into PRESTA. According to this algorithm, the electron -is not allowed to take a step longer than $t_\perp$, $t_\perp$ being -the perpendicular distance to the closest boundary, unless -$t_\perp$ becomes smaller than $t_{min}$, a user defined -minimum step-length for boundary crossing. For $t_\perp < t_{min}$, -lateral deflections are switched off and the particle is transported, -as in the case of standard EGS4, on a straight line to the -boundary. +a refined boundary crossing algorithm (BCA) was +incorporated into PRESTA. According to this algorithm, the electron +is not allowed to take a step longer than $t_\perp$, $t_\perp$ being +the perpendicular distance to the closest boundary, unless +$t_\perp$ becomes smaller than $t_{min}$, a user defined +minimum step-length for boundary crossing. For $t_\perp < t_{min}$, +lateral deflections are switched off and the particle is transported, +as in the case of standard EGS4, on a straight line to the +boundary. \index{PRESTA} \index{boundary crossing algorithm!fluence singularity} -In a more recent paper \cite{FS95}, Foote and Smyth have demonstrated -that the approach of forcing a multiple scattering event at the -boundary causes a singularity in the simulated particle fluence. +In a more recent paper \cite{FS95}, Foote and Smyth have demonstrated +that the approach of forcing a multiple scattering event at the +boundary causes a singularity in the simulated particle fluence. The singularity results from the fact that there is a -non-zero probability for scattering parallel to the boundary. +non-zero probability for scattering parallel to the boundary. Note that in real life, particles moving parallel to the boundary do -not cross it and therefore do not contribute to the planar fluence. +not cross it and therefore do not contribute to the planar fluence. Although the singularity is present in any situation over a distance of the order of $t_{min}$, it will be observed, {\em e.g.} as a dose over-prediction, only if the -size of a scoring region is comparable to $t_{min}$ due to averaging. -One of us has developed an analytical expression for -the effect when (semi)-charged particle equilibrium is -present and has demonstrated that in the case of a small air -cavity surrounded by a dense material (ionization chamber), +size of a scoring region is comparable to $t_{min}$ due to averaging. +One of us has developed an analytical expression for +the effect when (semi)-charged particle equilibrium is +present and has demonstrated that in the case of a small air +cavity surrounded by a dense material (ionization chamber), the dose over-prediction may be up to 3.5\% \cite{Ka99b}. \index{single scattering} \index{boundary crossing algorithm!single scattering} \index{SKINDEPTH\_FOR\_BCA} \index{BCA\_ALGORITHM} -To overcome this problem we have implemented into EGSnrc an -exact boundary crossing algorithm, {\em i.e.} the simulation -goes over into a single elastic scattering mode whenever -an electron comes closer to a -boundary than $t_{min}$. -Whereas in the case of PRESTA one of -the criteria to determine $t_{min}$ was to assure the -applicability of \Mol's MS theory, in EGSnrc the only criterion -for $t_{min}$ is efficiency (because of the multiple scattering theory -employed which is applicable for all step-sizes). It turns out that single +To overcome this problem we have implemented into EGSnrc an +exact boundary crossing algorithm, {\em i.e.} the simulation +goes over into a single elastic scattering mode whenever +an electron comes closer to a +boundary than $t_{min}$. +Whereas in the case of PRESTA one of +the criteria to determine $t_{min}$ was to assure the +applicability of \Mol's MS theory, in EGSnrc the only criterion +for $t_{min}$ is efficiency (because of the multiple scattering theory +employed which is applicable for all step-sizes). It turns out that single scattering simulation becomes more efficient than condensed history -simulation at about -3 elastic mean free paths. This is taken as the default value -for the parameter {\tt \$SKIN\_DEPTH\_FOR\_BCA} which determines -$t_{min}$. Note that {\tt \$SKIN\_DEPTH\_FOR\_BCA} is in -elastic mean free paths and not in length units. +simulation at about +3 elastic mean free paths. This is taken as the default value +for the parameter {\tt \$SKIN\_DEPTH\_FOR\_BCA} which determines +$t_{min}$. Note that {\tt \$SKIN\_DEPTH\_FOR\_BCA} is in +elastic mean free paths and not in length units. {\tt SKINDEPTH\_FOR\_BCA} is in {\tt COMMON/ET\_Control/}. \index{\$SKIN\_DEPTH\_FOR\_BCA} \index{SKINDEPTH\_FOR\_BCA} @@ -2783,31 +2783,31 @@ \subsubsection{Boundary crossing algorithm} \index{ET\_Control} \index{PRESTA} \index{EGS4!mimic} -The investigation of Ref. \cite{Ka99b} shows that the -strength of the effect of the fluence singularity -due to forcing multiple elastic scattering events exactly -at boundaries is proportional to the first GS moment $G_1$. -At high energies $G_1$ is very small for reasonable step-sizes and -so, a single scattering simulation in the vicinity of -boundaries is potentially wasteful. Hence we decided to keep -the original PRESTA boundary crossing algorithm in EGSnrc. The selection -between exact BCA and PRESTA's BCA is made via the parameter +The investigation of Ref. \cite{Ka99b} shows that the +strength of the effect of the fluence singularity +due to forcing multiple elastic scattering events exactly +at boundaries is proportional to the first GS moment $G_1$. +At high energies $G_1$ is very small for reasonable step-sizes and +so, a single scattering simulation in the vicinity of +boundaries is potentially wasteful. Hence we decided to keep +the original PRESTA boundary crossing algorithm in EGSnrc. The selection +between exact BCA and PRESTA's BCA is made via the parameter {\tt BCA\_ALGORITHM} which is in {\tt COMMON/ET\_Control/}. -If set to 0 (the default), exact boundary crossing is employed, -1 means PRESTA's BCA is used. If PRESTA's BCA is selected -and the parameter {\tt SKIN\_DEPTH\_FOR\_BCA} set to 0, -EGSnrc will calculate $t_{min}$ according to the procedure -in the original PRESTA implementation. It is worth noticing -that if {\tt BCA\_ALGORITHM} is set to 1 and the parameter -{\tt SKINDEPTH\_FOR\_BCA} to a very large number, -the entire simulation will run without lateral deflections -in the individual condensed history steps and so -mimic the original EGS4 behaviour. If, on the other side, -{\tt BCA\_ALGORITHM} is set to 0 and {\tt SKINDEPTH\_FOR\_BCA} -to a very large number, the entire simulation will be in -a single scattering mode. These are also the two options -available, if the geometry under investigation is -too complex to allow for the calculation of $t_\perp$. +If set to 0 (the default), exact boundary crossing is employed, +1 means PRESTA's BCA is used. If PRESTA's BCA is selected +and the parameter {\tt SKIN\_DEPTH\_FOR\_BCA} set to 0, +EGSnrc will calculate $t_{min}$ according to the procedure +in the original PRESTA implementation. It is worth noticing +that if {\tt BCA\_ALGORITHM} is set to 1 and the parameter +{\tt SKINDEPTH\_FOR\_BCA} to a very large number, +the entire simulation will run without lateral deflections +in the individual condensed history steps and so +mimic the original EGS4 behaviour. If, on the other side, +{\tt BCA\_ALGORITHM} is set to 0 and {\tt SKINDEPTH\_FOR\_BCA} +to a very large number, the entire simulation will be in +a single scattering mode. These are also the two options +available, if the geometry under investigation is +too complex to allow for the calculation of $t_\perp$. \index{single scattering mode} \index{BCA\_ALGORITHM} \index{SKINDEPTH\_FOR\_BCA} @@ -2818,45 +2818,45 @@ \subsubsection{Other condensed history aspects} \label{ch_others} \setcounter{equation}{0} -There are two additional aspects of the implementation -of the condensed history technique that deserve some -consideration: +There are two additional aspects of the implementation +of the condensed history technique that deserve some +consideration: \begin{enumerate} \item -Calculation of path-lengths corresponding to a given -energy loss and vice versa. The two quantities are -related via Eq. \eqref{s_vs_E}. +Calculation of path-lengths corresponding to a given +energy loss and vice versa. The two quantities are +related via Eq. \eqref{s_vs_E}. \item -Sampling distances between discrete interactions. -Since the cross sections are energy dependent and -the energy changes via sub-threshold (continuous) energy loss, -sampling distances between discrete interactions is slightly +Sampling distances between discrete interactions. +Since the cross sections are energy dependent and +the energy changes via sub-threshold (continuous) energy loss, +sampling distances between discrete interactions is slightly more complicated for electrons than for photons. -\end{enumerate} +\end{enumerate} \paragraph{Energy loss evaluation} \hfill \index{discrete interactions!distances between} \index{energy loss} -The energy loss $\Delta E$ due -to sub-threshold processes for -a condensed history step of length $s$ is +The energy loss $\Delta E$ due +to sub-threshold processes for +a condensed history step of length $s$ is \begin{equation} \label{delta_E} \Delta E = \int\limits_0^s {\rm d}s' L(s') \end{equation} -where the restricted stopping power is a function of $s'$ -in the sense of Eq. \eqref{s_vs_E}. -Equation \eqref{delta_E} must be evaluated ``on the fly'' for -each condensed history step and so a fast and accurate -procedure is needed. -In the original -EGS4 implementation the above integral was approximated with +where the restricted stopping power is a function of $s'$ +in the sense of Eq. \eqref{s_vs_E}. +Equation \eqref{delta_E} must be evaluated ``on the fly'' for +each condensed history step and so a fast and accurate +procedure is needed. +In the original +EGS4 implementation the above integral was approximated with \begin{equation} -\Delta E \approx L(E_0) s +\Delta E \approx L(E_0) s \end{equation} -where $E_0$ is the energy at the beginning of the step. -The PRESTA algorithm made the refinement +where $E_0$ is the energy at the beginning of the step. +The PRESTA algorithm made the refinement \index{PRESTA} \begin{equation} \label{eloss_presta} @@ -2864,81 +2864,81 @@ \subsubsection{Other condensed history aspects} \end{equation} The motivation for this is Euler's integration formula \begin{equation} -\int\limits_{x - \Delta x/2}^{x + \Delta x/2} {\rm d}x' f(x') +\int\limits_{x - \Delta x/2}^{x + \Delta x/2} {\rm d}x' f(x') = f(x) \Delta x + O(\Delta x^3) \end{equation} -and so, one might expect at a first sight an $O(\Delta E^3)$ error due to -the use of Eq. \eqref{eloss_presta}. A more careful examination -of the integral reveals that Eq. \eqref{eloss_presta} still has -an $O(\Delta E^2)$ error as the original EGS4 approach (although -the coefficient of the $O(\Delta E^2)$ term is smaller). -A more accurate approach was -presented in Ref. \cite{Ka99a}, but for the official release of the -system we decided to use another approach which is simpler -but not less accurate. - -In EGS4 (and also EGSnrc), a linear interpolation in $\ln E$ is -used at run time to calculate various quantities, the restricted +and so, one might expect at a first sight an $O(\Delta E^3)$ error due to +the use of Eq. \eqref{eloss_presta}. A more careful examination +of the integral reveals that Eq. \eqref{eloss_presta} still has +an $O(\Delta E^2)$ error as the original EGS4 approach (although +the coefficient of the $O(\Delta E^2)$ term is smaller). +A more accurate approach was +presented in Ref. \cite{Ka99a}, but for the official release of the +system we decided to use another approach which is simpler +but not less accurate. + +In EGS4 (and also EGSnrc), a linear interpolation in $\ln E$ is +used at run time to calculate various quantities, the restricted stopping power among them, {\em i.e.} \begin{equation} \label{L_interpolation} L(E) = a_i + b_i \ln E \quad \text{for}~ E_i \le E < E_{i+1} \end{equation} -where $E_i$ are the bin edge energies. This approach has -proven to be very accurate (and if not accurate enough, -the accuracy can always be increased by increasing the +where $E_i$ are the bin edge energies. This approach has +proven to be very accurate (and if not accurate enough, +the accuracy can always be increased by increasing the number of interpolation bins). We now define $R_i$, \begin{equation} R_i = \int\limits_{E_1}^{E_i} {{\rm d} E' \over L(E')}~, \end{equation} -where $E_1$ is the first energy in the interpolation table -(usually slightly smaller than {\tt TE}). $R_i$ is -the path-length that an electron with energy $E_i$ will -travel until local absorption if losing energy only -via sub-threshold processes (range). +where $E_1$ is the first energy in the interpolation table +(usually slightly smaller than {\tt TE}). $R_i$ is +the path-length that an electron with energy $E_i$ will +travel until local absorption if losing energy only +via sub-threshold processes (range). \index{range} \index{electron range} -In EGSnrc the quantities $R_i$ are stored in the array -{\tt range\_ep} which is in {\tt COMMON/ELECIN/} for each -medium. Using the $R_i$'s we can calculate the range -$R(E)$ for arbitrary energies from +In EGSnrc the quantities $R_i$ are stored in the array +{\tt range\_ep} which is in {\tt COMMON/ELECIN/} for each +medium. Using the $R_i$'s we can calculate the range +$R(E)$ for arbitrary energies from \index{range\_ep} \index{COMMON!ELECIN} \begin{equation} \label{range} -R(E) = R_i + \int\limits_{E_i}^E {{\rm d}E' \over a_i + b_i \ln E'} -\approx R_i + {E - E_i \over L_i} \left(1 - +R(E) = R_i + \int\limits_{E_i}^E {{\rm d}E' \over a_i + b_i \ln E'} +\approx R_i + {E - E_i \over L_i} \left(1 - {b_i \over L_i}~{\epsilon \over 2} + {b_i (2 b_i + L_i) \over L_i^2}~ {\epsilon^2 \over 6} \pm \cdots \right) \end{equation} -where $E_i$ is the lower edge energy of the bin to which $E$ belongs, -$L_i$ is a short hand notation for $L(E_i) = a_i + b \ln E_i$ -and $\epsilon = E/E_i - 1$ is usually very small\footnote{{\em e.g.} for a -data set for the entire energy range of the applicability -of EGSnrc, 1 keV to 10 GeV, $\epsilon < 0.107$ using 150 interpolation -bins. Normally $\epsilon$ is much smaller.}, so that -the expansion up to second order in $\epsilon$ is sufficiently -accurate. The range of electrons is calculated according to Eq. -\eqref{range} at the beginning of each condensed history step in -EGSnrc. If now the decision is made to perform a step with -length $s$, the range of the electron at the end of the step -is $R - s$ and one can use Eq. \eqref{range} to -calculate the corresponding final step energy after finding -the bin to which the new energy belongs using the ranges -$R_i$. If, on the other side, -the step-size is determined via a given energy loss -$\Delta E$, one calculates $R(E - \Delta E)$ from -Eq. \eqref{range} and uses $R(E) - R(E - \Delta E)$ as the -corresponding step-length $s$. - -The appeal of the approach described above lies in its simplicity -and generality. If one day it is decided that our understanding -of restricted stopping powers is incomplete and a change -is required, this approach will be still applicable as long -as a logarithmic interpolation is used. At this point one -should mention that the accurate knowledge of the electron range -is absolutely essential for the accurate calculation of -energy loss. Under no circumstances the variable -{\tt range} (which holds the value of $R$) +where $E_i$ is the lower edge energy of the bin to which $E$ belongs, +$L_i$ is a short hand notation for $L(E_i) = a_i + b \ln E_i$ +and $\epsilon = E/E_i - 1$ is usually very small\footnote{{\em e.g.} for a +data set for the entire energy range of the applicability +of EGSnrc, 1 keV to 10 GeV, $\epsilon < 0.107$ using 150 interpolation +bins. Normally $\epsilon$ is much smaller.}, so that +the expansion up to second order in $\epsilon$ is sufficiently +accurate. The range of electrons is calculated according to Eq. +\eqref{range} at the beginning of each condensed history step in +EGSnrc. If now the decision is made to perform a step with +length $s$, the range of the electron at the end of the step +is $R - s$ and one can use Eq. \eqref{range} to +calculate the corresponding final step energy after finding +the bin to which the new energy belongs using the ranges +$R_i$. If, on the other side, +the step-size is determined via a given energy loss +$\Delta E$, one calculates $R(E - \Delta E)$ from +Eq. \eqref{range} and uses $R(E) - R(E - \Delta E)$ as the +corresponding step-length $s$. + +The appeal of the approach described above lies in its simplicity +and generality. If one day it is decided that our understanding +of restricted stopping powers is incomplete and a change +is required, this approach will be still applicable as long +as a logarithmic interpolation is used. At this point one +should mention that the accurate knowledge of the electron range +is absolutely essential for the accurate calculation of +energy loss. Under no circumstances the variable +{\tt range} (which holds the value of $R$) should be overwritten by the user! \index{range} @@ -2946,57 +2946,57 @@ \subsubsection{Other condensed history aspects} \index{variance reduction!range rejection} \index{i\_do\_rr} \index{e\_max\_rr} -An additional useful feature that results from the knowledge -of the electron range in the current material is that -electron range rejection can be applied. If the parameter -{\tt i\_do\_rr} is set to unity for the current region, -the electron energy is less than {\tt e\_max\_rr} (this -is total energy, including rest energy!) and the electron -range $R$ is less than $t_\perp$ (see section \ref{BCA}), -the simulation of the current electron is terminated and its entire energy -deposited locally. +An additional useful feature that results from the knowledge +of the electron range in the current material is that +electron range rejection can be applied. If the parameter +{\tt i\_do\_rr} is set to unity for the current region, +the electron energy is less than {\tt e\_max\_rr} (this +is total energy, including rest energy!) and the electron +range $R$ is less than $t_\perp$ (see section \ref{BCA}), +the simulation of the current electron is terminated and its entire energy +deposited locally. \paragraph{Distances between discrete interactions} \hfill \label{eloss_evaluation} -If one uses the path-length as the variable to measure -distances between discrete interactions, the path-length -$s$ to the next discrete event must be sampled from +If one uses the path-length as the variable to measure +distances between discrete interactions, the path-length +$s$ to the next discrete event must be sampled from \begin{equation} \int\limits_0^s {\rm d} s' \Sigma^{\rm (tot)}(s') = -\ln r \end{equation} -where $r$ is a uniformly distributed random number between -zero and unity. To avoid the numerically intensive -solution of the above equation, the so called -fictitious cross section method is employed in EGS4: an additional, -fictitious interaction is introduced, its total cross section -$\Sigma_{\rm f}(s')$ is chosen such that +where $r$ is a uniformly distributed random number between +zero and unity. To avoid the numerically intensive +solution of the above equation, the so called +fictitious cross section method is employed in EGS4: an additional, +fictitious interaction is introduced, its total cross section +$\Sigma_{\rm f}(s')$ is chosen such that \begin{equation} \Sigma^{\rm (tot)}(s') + \Sigma_{\rm f}(s') \equiv \Sigma_0 = \text{const}~. -\end{equation} -The path-length to the next interaction, real or fictitious, is then -simply +\end{equation} +The path-length to the next interaction, real or fictitious, is then +simply \begin{equation} s = -{ \ln r \over \Sigma_0 }~. \end{equation} -Once at the interaction site, the interaction is rejected with the -probability $1 - \Sigma^{\rm (tot)}(s)/\Sigma_0$ (or, with other words, -a fictitious interaction takes place with the probability -$1 - \Sigma^{\rm (tot)}(s)/\Sigma_0$). In order this approach to work -properly, $\Sigma_0$ must be greater than $\Sigma^{\rm (tot)}(s)$ for -all $s$. Based on the observation that at high energies the -discrete interaction cross section is a monotonic increasing function -of energy, the cross section for the initial energy is used in EGS4. -This approach fails for threshold energies for delta particle -production less than about $m/7$, as pointed out by Rogers -in 1984 \cite{Ro84}. Although known for a long time, this problem -was never corrected. The modification proposed by Ma and Nahum -in 1992 \cite{MN92} is also biased, as shown in Ref. \cite{Ka99a}. -If one would attempt to employ the fictitious cross section method -using the global cross section maximum as $\Sigma_0$, the -simulation would become extremely inefficient for low values -of $T_c$ and $k_c$. This can easily be understood from -Fig. \ref{sigmas} which shows the total cross section in graphite +Once at the interaction site, the interaction is rejected with the +probability $1 - \Sigma^{\rm (tot)}(s)/\Sigma_0$ (or, with other words, +a fictitious interaction takes place with the probability +$1 - \Sigma^{\rm (tot)}(s)/\Sigma_0$). In order this approach to work +properly, $\Sigma_0$ must be greater than $\Sigma^{\rm (tot)}(s)$ for +all $s$. Based on the observation that at high energies the +discrete interaction cross section is a monotonic increasing function +of energy, the cross section for the initial energy is used in EGS4. +This approach fails for threshold energies for delta particle +production less than about $m/7$, as pointed out by Rogers +in 1984 \cite{Ro84}. Although known for a long time, this problem +was never corrected. The modification proposed by Ma and Nahum +in 1992 \cite{MN92} is also biased, as shown in Ref. \cite{Ka99a}. +If one would attempt to employ the fictitious cross section method +using the global cross section maximum as $\Sigma_0$, the +simulation would become extremely inefficient for low values +of $T_c$ and $k_c$. This can easily be understood from +Fig. \ref{sigmas} which shows the total cross section in graphite for two different cutoff energies. \begin{figure}[htp] \includegraphics[height=9cm,width=9cm]{figures/cs_all} @@ -3007,16 +3007,16 @@ \subsubsection{Other condensed history aspects} (scaled by a factor of 100) as a function of kinetic energy.} \end{figure} -In EGSnrc the distance between discrete interactions is measured -in units of the energy loss due to sub-threshold processes. -The relevant total cross section is then -$\tilde{\Sigma}^{\rm (tot)}(E) = \Sigma^{\rm (tot)}(E)/L(E)$ -(see the general discussion +In EGSnrc the distance between discrete interactions is measured +in units of the energy loss due to sub-threshold processes. +The relevant total cross section is then +$\tilde{\Sigma}^{\rm (tot)}(E) = \Sigma^{\rm (tot)}(E)/L(E)$ +(see the general discussion of the transport equation in section \ref{electron_general}). -This cross section, shown in Fig. \ref{tilde_sigma} for graphite and gold -for two different values of $T_c$ and $k_c$, -is much flatter than $\Sigma^{\rm (tot)}$ -(at least for low cutoff energies) +This cross section, shown in Fig. \ref{tilde_sigma} for graphite and gold +for two different values of $T_c$ and $k_c$, +is much flatter than $\Sigma^{\rm (tot)}$ +(at least for low cutoff energies) \begin{figure}[htp] \includegraphics[height=10cm,width=10cm]{figures/cse_all} \caption[Total cross sections per unit energy loss]{\label{tilde_sigma} @@ -3027,12 +3027,49 @@ \subsubsection{Other condensed history aspects} (scaled with a factor of 14 for better visibility) as a function of kinetic energy.} \end{figure} -and has a single maximum. This maximum is determined after -the PEGS data becomes available and is used at run time to -sample energy losses between discrete interactions. -This saves the necessity of evaluating the cross section -at the beginning of each discrete interaction loop -(the {\tt TSTEP LOOP}) in subroutine {\tt ELECTR}. +and has a single maximum. This maximum is determined after +the PEGS data becomes available and is used at run time to +sample energy losses between discrete interactions. +This saves the necessity of evaluating the cross section +at the beginning of each discrete interaction loop +(the {\tt TSTEP LOOP}) in subroutine {\tt ELECTR}. The procedure described above -is then used to compute the corresponding path-length. +is then used to compute the corresponding path-length. + +\paragraph{Transport in electromagnetic fields} \hfill +\label{EMF_macros_algorithm} + +Transport of charged particles through matter under the influence of electric and magnetic fields is now possible +using the approach proposed by Bielajew\cite{Bi89a}. In this approach, charged particles are forced +to take small enough steps so that the external fields do not change significantly, and energy losses as well +as angular deflections are negligible. Under these assumptions the effect of the electromagnetic field can +be superimposed upon the field-free transport, and the final direction calculated to first order as + +\begin{equation} +\Delta\vec{u} = \Delta\vec{u}_{ms,ret} + \Delta\vec{u}_{em} +\end{equation} +where $\Delta\vec{u}_{ms,ret}$ is the angular deflection due to elastic and inelastic scattering which +can be calculated using EGSnrc's electron transport algorithm, and $\Delta\vec{u}_{em}$ is the angular +deflection due to the electromagnetic field, which, to first order, can be obtained from + +\begin{equation} +\label{uchange_emf} + \Delta\vec{u}_{em} = \frac{q \cdot s}{m_0 \gamma v^2_0} \left[\vec{E}_0 - \vec{u}_0(\vec{u}_0\cdot \vec{E}_0) + \vec{v}_0 \times \vec{B}_0\right] +\end{equation} + + +The final position can be obtained using + +\begin{equation} + \vec{x}_f = \vec{x}_0 + \vec{u}_0 s + \frac{s}{2} \left(\Delta\vec{u}_{ms,ret} + \Delta\vec{u}_{em}\right) +\end{equation} +however, in the current implementation, lateral displacement due to the Lorentz force is ignored, and only a condensed history (CH) step s is taken along $\vec{u}_0$ using EGSnrc's electron transport algorithm. This simplification relies on the assumption that accounting only for the change in direction due to the Lorentz force is accurate enough when using very small steps. + +There are several criteria to restrict the step size based on energy loss, change in the electromagnetic field and change in particle direction. For instance, in the case of a static $\vec{B}$ field ($\vec{E}$ = 0, $\vec{B}$ = $\vec{B}_0$) only the restriction of small changes in the particle direction is relevant. According to Eq.(\ref{uchange_emf}) $\Delta\vec{u}_{em}$ should only be allowed to take a value $\delta \ll 1$ from where the restricted step size follows as +\begin{equation} +\label{uchange_restriction} + s = \delta \cdot \frac{E_o \gamma_0 \beta^2}{q\left(\vec{v}_0 \times \vec{B}_0\right)} = \delta \cdot r_g +\end{equation} +the quantity $r_g$ is the well known radius of gyration of the particle's trajectory. A value of $\delta$ = 0.02 has been recommended by Bielajew for accurately reproducing the analytical trajectory of electrons in vacuum. For more details on the implementation of this algorithm the reader is encouraged to read the very detailed chapter on this topic by Bielajew\cite{Bi89a}. For instructions on how to enable transport under electromagnetic fields please refer to section \ref{EMF_macros_implementation}. + \newpage diff --git a/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/new_um_app2.tex b/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/new_um_app2.tex index 064dd0803..bb37d773a 100644 --- a/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/new_um_app2.tex +++ b/HEN_HOUSE/doc/src/pirs701-egsnrc/inputs/new_um_app2.tex @@ -2881,6 +2881,131 @@ \subsubsection{EXAMIN} % \$HEN\_HOUSE/test\_distribution\_outputs}. % \index{test\_distribution\_outputs} +\subsection{Latest additions} +\subsubsection{Charged particle transport under electromagnetic fields} +\label{EMF_macros_implementation} +Bielajew's EGS4 macros for transport under electromagnetic (EM) fields were adapted for EGSnrc by Amir Keyvanloo and +others from the Cross Cancer Institute in Edmonton. These macros have been included in the current EGSnrc release. +To turn on transport under EM fields, users must add the file {\tt emf\_macros.mortran} to the {\tt MORTRAN} sources to be compiled. The subroutine {\tt ELECTR} in {\tt egsnrc.mortran} contains macro replacements which are empty by default, but which are activated when including the EM macros. + +To include these macros in a MORTRAN user code, append {\tt emf\_macros.mortran} to {\tt SOURCES} variable in file +{\tt user\_code.make} (user\_code can be any MORTRAN user code other than a BEAMnrc user code): +\begin{verbatim} + ... +SOURCES = \ + $(EGS_SOURCEDIR)egsnrc.macros \ + ... + $(EGS_SOURCEDIR)emf_macros.mortran \ + $(USER_CODE).mortran \ + ... + $(EGS_SOURCEDIR)get_inputs.mortran\ + $(EGS_SOURCEDIR)get_media_inputs.mortran\ + ... + $(EGS_SOURCEDIR)pegs4_routines.mortran \ + $(EGS_SOURCEDIR)egsnrc.mortran + ... +\end{verbatim} + +To include these macros in an existing BEAMnrc user code, append {\tt emf\_macros.mortran} to {\tt SOURCES} variable in file +{\tt source.make}: +\begin{verbatim} +SOURCES = $(EGS_SOURCEDIR)egsnrc.macros \ + ... + $(EGS_SOURCEDIR)emf_macros.mortran \ + ... + $(BEAM_HOME)beamnrc_user_macros.mortran \ + ... + $(BEAM_CODE)_macros.mortran \ + $(EGS_SOURCEDIR)egs_utilities.mortran \ + $(BEAM_HOME)beam_main.mortran\ + $(BEAM_HOME)beamnrc.mortran \ + ... + $(EGS_SOURCEDIR)egsnrc.mortran + +\end{verbatim} +In the case of a BEAMnrc source library, append {\tt emf\_macros.mortran} to {\tt LIB\_SOURCES} variable in file +{\tt source.make}: +\begin{verbatim} +LIB_SOURCES = $(BEAM_HOME)beam_lib.macros \ + $(EGS_SOURCEDIR)egsnrc.macros \ + ... + $(EGS_SOURCEDIR)emf_macros.mortran \ + ... + $(BEAM_HOME)beamnrc_user_macros.mortran \ + ... + $(BEAM_CODE)_macros.mortran \ + $(BEAM_HOME)beam_lib.mortran\ + $(BEAM_HOME)beamnrc.mortran \ + ... + $(EGS_SOURCEDIR)egsnrc.mortran +\end{verbatim} + +For C++ user codes one must append {\tt emf\_macros.mortran} to the {\tt EGSPP\_USER\_MACROS} variable in +the {\tt Makefile}: +\begin{verbatim} + ... +# Specify the name of the user code. +# The name of the executable is determined from this variable. +# +USER_CODE = cavity + +# The following can be used to add user macros and mortran subroutines. +# The file(s) specified here are added after egsnrc.macros, machine.macros +# and egs_c_interface2.macros but before any files that have +# executable code. +# +#EGSPP_USER_MACROS = cavity.macros +EGSPP_USER_MACROS = cavity.macros \ + $(EGS_SOURCEDIR)emf_macros.mortran + ... +\end{verbatim} + +Details of the field and the step size restriction are entered by input in the MC transport parameters section: +\begin{itemize} +\item For magnetic fields: +\begin{verbatim} +:start MC transport parameter: + ... + Magnetic Field = 0, 1.5, 0 # magnetic field in T + EM ESTEPE = 0.02 + ... +:stop MC transport parameter: +\end{verbatim} + +\item For electric fields: +\begin{verbatim} +:start MC transport parameter: + ... + Electric Field = 0, 3, 0 # electric field in V/cm + EM ESTEPE = 0.02 + ... +:stop MC transport parameter: +\end{verbatim} +\end{itemize} + +Please note than one can define both, an electric and a magnetic field. The {\tt EM ESTEPE} +entry sets the value for the step size restrictions based on energy loss, field change and +direction change. For instance, in the static $\vec{B}_0$ field case of section \ref{EMF_macros_algorithm}, +{\tt EM ESTEPE} corresponds to the $\delta$ value of Eq(\ref{uchange_restriction}). By default it is set to 0.02. + +\subsubsection{EADL atomic relaxations} +In EGSnrc the relaxation cascade of inner shell vacancies is an independent process that is initiated each time +a vacancy is created +\begin{itemize} + \item In photo-absorption, bound Compton scattering, and electron impact ionization processes. + \item Future: triplet production, electron-electron bremsstrahlung +\end{itemize} + +The default implementation include relaxation events from: +\begin{itemize} +\item All shells with binding energies above 1 keV +\item All radiative and non-radiative transitions to/from K-, LI-, LII and LIII-shells +\item All radiative and non-radiative transitions to/from ``average'' M and N-shells. +\end{itemize} + +An option to remove above limitations by using EADL atomic relaxation data has been available in EGSnrc since 2011. +% User must set macro \$EADL\_RELAX to .true. in file egsnrc.macros. +The way to turn on EADL relaxation is by setting macro \$EADL\_RELAX to .true. in egsnrc.macros or in the user-code. It is currently set to .false. by default. %following may be needed to get next section start on odd page %\newpage diff --git a/HEN_HOUSE/doc/src/pirs898-egs++/figures/i6702.png b/HEN_HOUSE/doc/src/pirs898-egs++/figures/I6702b.png similarity index 100% rename from HEN_HOUSE/doc/src/pirs898-egs++/figures/i6702.png rename to HEN_HOUSE/doc/src/pirs898-egs++/figures/I6702b.png diff --git a/HEN_HOUSE/doc/src/pirs898-egs++/figures/i6702a.png b/HEN_HOUSE/doc/src/pirs898-egs++/figures/I6702c.png similarity index 100% rename from HEN_HOUSE/doc/src/pirs898-egs++/figures/i6702a.png rename to HEN_HOUSE/doc/src/pirs898-egs++/figures/I6702c.png diff --git a/HEN_HOUSE/doc/src/pirs898-egs++/geometry.doxy b/HEN_HOUSE/doc/src/pirs898-egs++/geometry.doxy index 515cbdbab..e141b41fb 100644 --- a/HEN_HOUSE/doc/src/pirs898-egs++/geometry.doxy +++ b/HEN_HOUSE/doc/src/pirs898-egs++/geometry.doxy @@ -914,11 +914,11 @@ planes as a CD-geometry: This is a view of the resulting brachytherapy seed with the titanium and air media made semi-transparent: -\image html i6702.png +\image html I6702b.png and here is an alternative view with 2 clipping planes with normals along the z- and x-axis passing through the origin used to remove 3/4 of the geometry for better viewing the inside: -\image html i6702a.png +\image html I6702c.png This is the complete geometry definition file, which has been created by Ernesto Mainegra (Note the diff --git a/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.cpp index 0e2f1aae3..51ff9e162 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.cpp @@ -49,24 +49,29 @@ #include "egs_functions.h" BEAM_DoseScoring::BEAM_DoseScoring(const string &Name, - EGS_ObjectFactory *f) : + EGS_ObjectFactory *f) : EGS_AusgabObject(Name,f), nreg(0), m_lastCase(-1), nmedia(0), dose(0), doseM(0), max_dreg(-1), max_medl(0), - score_medium_dose(false), score_region_dose(false) -{ + score_medium_dose(false), score_region_dose(false) { otype = "BEAM_DoseScoring"; } BEAM_DoseScoring::~BEAM_DoseScoring() { - if( dose ) delete dose; - if( doseM ) delete doseM; + if (dose) { + delete dose; + } + if (doseM) { + delete doseM; + } } void BEAM_DoseScoring::setApplication(EGS_Application *App) { app=App; - bapp = dynamic_cast(app); - if( !bapp ) return; + bapp = dynamic_cast(app); + if (!bapp) { + return; + } // Get the number of regions in the geometry. nreg = app->getnRegions(); // Get the number of media in the input file @@ -74,82 +79,113 @@ void BEAM_DoseScoring::setApplication(EGS_Application *App) { // Get list of regions for which to score dose; int d_start,d_end; // first, clear the array of media indices in the dose CMs - for(int i=0; i med_ind; - for(int j=0; j med_ind; + for (int j=0; jCM_reg_end(d_cms[i]-1)+1; - d_end = bapp->CM_reg_end(d_cms[i]); - for(int j=d_start; j<=d_end; j++) { - //note we need to use IsRegionReal instead of isRealRegion because - //the latter registers virtual regions as real in beampp - if(bapp->IsRegionReal(j)) { - d_region.push_back(j); - cm_med[i][app->getMedium(j)]=1; + for (int i=0; iCM_reg_end(d_cms[i]-1)+1; + } + d_end = bapp->CM_reg_end(d_cms[i]); + for (int j=d_start; j<=d_end; j++) { + //note we need to use IsRegionReal instead of isRealRegion because + //the latter registers virtual regions as real in beampp + if (bapp->IsRegionReal(j)) { + d_region.push_back(j); + cm_med[i][app->getMedium(j)]=1; + } } - } } // determine maximum medium name length - char buf[32]; int count = 0;int imed=0; - for ( imed=0; imed < nmedia; imed++){ - sprintf(buf,"%s%n",app->getMediumName(imed),&count); - if (count > max_medl) max_medl = count; + char buf[32]; + int count = 0; + int imed=0; + for (imed=0; imed < nmedia; imed++) { + sprintf(buf,"%s%n",app->getMediumName(imed),&count); + if (count > max_medl) { + max_medl = count; + } } // Flag dose scoring regions in geometry // and set their volume. - if (d_region.size()){// specific dose regions provided - // Get maximum dose scoring region - for (vector::iterator it = d_region.begin(); it < d_region.end(); it++){ - if (*it > max_dreg) max_dreg = *it; - } - for (int j=0; jCM_reg_end(d_cms[j])){ - d_reg_cm_ind[d_region[i]]=j; - break; - } - } - } - if (score_region_dose) dose = new EGS_ScoringArray(d_region.size()); + if (d_region.size()) { // specific dose regions provided + // Get maximum dose scoring region + for (vector::iterator it = d_region.begin(); it < d_region.end(); it++) { + if (*it > max_dreg) { + max_dreg = *it; + } + } + for (int j=0; jCM_reg_end(d_cms[j])) { + d_reg_cm_ind[d_region[i]]=j; + break; + } + } + } + if (score_region_dose) { + dose = new EGS_ScoringArray(d_region.size()); + } } // If requested request memory for medium dose in each CM - if (score_medium_dose) doseM = new EGS_ScoringArray(nmedia*d_cms.size()); + if (score_medium_dose) { + doseM = new EGS_ScoringArray(nmedia*d_cms.size()); + } description = "\n*******************************************\n"; description += "BEAM Dose Scoring Object ("; - description += name; description += ")\n"; + description += name; + description += ")\n"; description += "*******************************************\n"; description +="\n Dose will be calculated in CM no.'s (start region - end region):\n"; for (int i=0; iCM_reg_end(d_cms[i])); - else sprintf(buf,"%d (%d - %d)\n",d_cms[i],bapp->CM_reg_end(d_cms[i]-1)+1,bapp->CM_reg_end(d_cms[i])); - description += buf; + if (d_cms[i]==0) { + sprintf(buf,"%d (0 - %d)\n",d_cms[i],bapp->CM_reg_end(d_cms[i])); + } + else { + sprintf(buf,"%d (%d - %d)\n",d_cms[i],bapp->CM_reg_end(d_cms[i]-1)+1,bapp->CM_reg_end(d_cms[i])); + } + description += buf; } description += "\n"; - if (dose) description += " - Region dose will be calculated\n"; - if (doseM) description += " - Medium dose will be calculated\n"; + if (dose) { + description += " - Region dose will be calculated\n"; + } + if (doseM) { + description += " - Medium dose will be calculated\n"; + } description += "\n--------------------------------------\n"; - sprintf(buf,"%*s %*s rho/[g/cm**3]\n",max_medl/2,"medium",max_medl/2," ");description += buf; + sprintf(buf,"%*s %*s rho/[g/cm**3]\n",max_medl/2,"medium",max_medl/2," "); + description += buf; description += "--------------------------------------\n"; - for ( imed=0; imed < nmedia; imed++){ - sprintf(buf,"%-*s",max_medl,app->getMediumName(imed));description += buf;description += " "; - sprintf(buf,"%5.2f",app->getMediumRho(imed));description += buf;description += "\n"; + for (imed=0; imed < nmedia; imed++) { + sprintf(buf,"%-*s",max_medl,app->getMediumName(imed)); + description += buf; + description += " "; + sprintf(buf,"%5.2f",app->getMediumRho(imed)); + description += buf; + description += "\n"; } description += "\n*******************************************\n\n"; - if (d_region.size()) d_region.clear(); + if (d_region.size()) { + d_region.clear(); + } } void BEAM_DoseScoring::reportResults() { @@ -162,195 +198,259 @@ void BEAM_DoseScoring::reportResults() { egsInformation("=> last case = %lld fluence = %g\n", m_lastCase, F); /* Normalize to actual source fluence */ egsInformation("\n Dose output for CM no.'s:\n"); - for(int i=0; i Summary of region dosimetry (per particle)\n"); - egsInformation( - "CM %-*s %-*s %-*s rho/[g/cm3] V/cm3 Edep/[MeV] D/[Gy] %n\n", - irmax_digits,"ir",irmax_digits,"CM reg.",max_medl,"medium",&count); + string line; + double r,dr; + if (dose) { + if (normE==1) { + egsInformation("\n\n==> Summary of region dosimetry (per particle)\n"); + egsInformation( + "CM %-*s %-*s %-*s rho/[g/cm3] V/cm3 Edep/[MeV] D/[Gy] %n\n", + irmax_digits,"ir",irmax_digits,"CM reg.",max_medl,"medium",&count); } - else{ - egsInformation("\n==> Summary of region dosimetry (per fluence)\n"); - egsInformation( - "CM %-*s %-*s %-*s rho/[g/cm3] V/cm3 Edep/[MeV*cm2] D/[Gy*cm2] %n\n", - irmax_digits,"ir",irmax_digits,"CM reg.",max_medl,"medium",&count); + else { + egsInformation("\n==> Summary of region dosimetry (per fluence)\n"); + egsInformation( + "CM %-*s %-*s %-*s rho/[g/cm3] V/cm3 Edep/[MeV*cm2] D/[Gy*cm2] %n\n", + irmax_digits,"ir",irmax_digits,"CM reg.",max_medl,"medium",&count); } - line.append(count,'-'); egsInformation("%s\n",line.c_str()); + line.append(count,'-'); + egsInformation("%s\n",line.c_str()); /* Compute deposited energy and dose */ - int ir_cm,fr_cm; - for(int i=0; iCM_reg_end(d_cms[i]-1)+1; - fr_cm = bapp->CM_reg_end(d_cms[i]); - for (int ireg = ir_cm; ireg <= fr_cm; ireg++) { - if (d_reg_index[ireg]>=0){ - if (!(app->isRealRegion(ireg))) continue; - int imed = app->getMedium(ireg); - EGS_Float rho = app->getMediumRho(imed); - EGS_Float mass = vol[ireg]*rho; - dose->currentResult(d_reg_index[ireg],r,dr);if( r > 0 ) dr = dr/r; else dr=1; - egsInformation("%-2d %-*d %-*d %-*s %7.3f %7.3f %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", - d_cms[i],max(irmax_digits,2),ireg,max(irmax_digits,7),ireg-ir_cm,max_medl,app->getMediumName(imed),rho,vol[ireg],r*normE,dr*100.,r*normD/mass,dr*100.); - } + int ir_cm,fr_cm; + for (int i=0; iCM_reg_end(d_cms[i]-1)+1; + } + fr_cm = bapp->CM_reg_end(d_cms[i]); + for (int ireg = ir_cm; ireg <= fr_cm; ireg++) { + if (d_reg_index[ireg]>=0) { + if (!(app->isRealRegion(ireg))) { + continue; + } + int imed = app->getMedium(ireg); + EGS_Float rho = app->getMediumRho(imed); + EGS_Float mass = vol[ireg]*rho; + dose->currentResult(d_reg_index[ireg],r,dr); + if (r > 0) { + dr = dr/r; + } + else { + dr=1; + } + egsInformation("%-2d %-*d %-*d %-*s %7.3f %7.3f %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", + d_cms[i],max(irmax_digits,2),ireg,max(irmax_digits,7),ireg-ir_cm,max_medl,app->getMediumName(imed),rho,vol[ireg],r*normE,dr*100.,r*normD/mass,dr*100.); + } + } + egsInformation("%s\n",line.c_str()); } - egsInformation("%s\n",line.c_str()); - } } - if (doseM){ - vector massM(d_cms.size()*nmedia,0); int imed = 0; - for (int ir=0; ir=0) { - imed = app->getMedium(ir); - massM[imed+d_reg_cm_ind[ir]*nmedia] += app->getMediumRho(imed)*vol[ir]; - } + if (doseM) { + vector massM(d_cms.size()*nmedia,0); + int imed = 0; + for (int ir=0; ir=0) { + imed = app->getMedium(ir); + massM[imed+d_reg_cm_ind[ir]*nmedia] += app->getMediumRho(imed)*vol[ir]; + } } - if (normE==1){ - egsInformation("\n\n==> Summary of media dosimetry (per particle)\n"); - egsInformation( - "CM %*s %*s Edep/[MeV] D/[Gy] %n\n", - max_medl/2,"medium",max_medl/2," ",&count); + if (normE==1) { + egsInformation("\n\n==> Summary of media dosimetry (per particle)\n"); + egsInformation( + "CM %*s %*s Edep/[MeV] D/[Gy] %n\n", + max_medl/2,"medium",max_medl/2," ",&count); } - else{ - egsInformation("\n\n==> Summary of media dosimetry (per fluence)\n"); - egsInformation( - "CM %*s %*s Edep/[MeV*cm2] D/[Gy*cm2] %n\n", - max_medl/2,"medium",max_medl/2," ",&count); + else { + egsInformation("\n\n==> Summary of media dosimetry (per fluence)\n"); + egsInformation( + "CM %*s %*s Edep/[MeV*cm2] D/[Gy*cm2] %n\n", + max_medl/2,"medium",max_medl/2," ",&count); } - line="";line.append(count,'-'); egsInformation("%s\n",line.c_str()); + line=""; + line.append(count,'-'); + egsInformation("%s\n",line.c_str()); /* Compute deposited energy in medium (MeV)*/ - for(int i=0; icurrentResult(im+i*nmedia,r,dr); - if( cm_med[i][im] >= 0 ){ - if( r > 0) dr = dr/r; else dr=1; - egsInformation( - "%-2d %-*s %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", - d_cms[i],max_medl,app->getMediumName(im),r*normE,dr*100.,r*normD/massM[im+i*nmedia],dr*100.); + for (int i=0; icurrentResult(im+i*nmedia,r,dr); + if (cm_med[i][im] >= 0) { + if (r > 0) { + dr = dr/r; + } + else { + dr=1; + } + egsInformation( + "%-2d %-*s %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", + d_cms[i],max_medl,app->getMediumName(im),r*normE,dr*100.,r*normD/massM[im+i*nmedia],dr*100.); + } } + egsInformation("%s\n",line.c_str()); } - egsInformation("%s\n",line.c_str()); - } } egsInformation("\n======================================================\n"); } bool BEAM_DoseScoring::storeState(ostream &data) const { - //egsInformation("Storing BEAM_DoseScoring...\n"); - if( !egsStoreI64(data,m_lastCase)) return false; - data << endl; - if( dose && !dose->storeState(data)) return false; - if( doseM && !doseM->storeState(data)) return false; - return true; + //egsInformation("Storing BEAM_DoseScoring...\n"); + if (!egsStoreI64(data,m_lastCase)) { + return false; + } + data << endl; + if (dose && !dose->storeState(data)) { + return false; + } + if (doseM && !doseM->storeState(data)) { + return false; + } + return true; } -bool BEAM_DoseScoring::setState(istream &data){ - if( !egsGetI64(data,m_lastCase) ) return false; - if( dose && !dose->setState(data)) return false; - if( doseM && !doseM->setState(data)) return false; - return true; +bool BEAM_DoseScoring::setState(istream &data) { + if (!egsGetI64(data,m_lastCase)) { + return false; + } + if (dose && !dose->setState(data)) { + return false; + } + if (doseM && !doseM->setState(data)) { + return false; + } + return true; } -bool BEAM_DoseScoring::addState(istream &data){ - int err = addTheStates(data); - if (err){ +bool BEAM_DoseScoring::addState(istream &data) { + int err = addTheStates(data); + if (err) { egsInformation("Error code: %d",err); return false; - } - return true; + } + return true; } -int BEAM_DoseScoring::addTheStates(istream &data){ - EGS_I64 tmp_case; if( !egsGetI64(data,tmp_case) ) return 4401; - m_lastCase += tmp_case; - if (dose){ +int BEAM_DoseScoring::addTheStates(istream &data) { + EGS_I64 tmp_case; + if (!egsGetI64(data,tmp_case)) { + return 4401; + } + m_lastCase += tmp_case; + if (dose) { EGS_ScoringArray tmp(nreg); - if( !tmp.setState(data) ) return 4402; + if (!tmp.setState(data)) { + return 4402; + } (*dose) += tmp; - } - if (doseM){ - EGS_ScoringArray tmpM(nmedia); - if( !tmpM.setState(data) ) return 4403; - (*doseM) += tmpM; - } - return 0; + } + if (doseM) { + EGS_ScoringArray tmpM(nmedia); + if (!tmpM.setState(data)) { + return 4403; + } + (*doseM) += tmpM; + } + return 0; } -void BEAM_DoseScoring::resetCounter(){ - m_lastCase = 0; - if (dose) dose->reset(); - if (doseM) doseM->reset(); +void BEAM_DoseScoring::resetCounter() { + m_lastCase = 0; + if (dose) { + dose->reset(); + } + if (doseM) { + doseM->reset(); + } } extern "C" { -BEAM_DOSE_SCORING_EXPORT EGS_AusgabObject* createAusgabObject(EGS_Input *input, - EGS_ObjectFactory *f) { - const static char *func = "createAusgabObject(beam_dose_scoring)"; - if( !input ) { - egsWarning("%s: null input?\n",func); return 0; - } - /* get CMs to score dose in */ - vector d_cms; - int err1=input->getInput("dose CMs",d_cms); - if(err1) { - egsWarning("%s: No CMs input. Dose will not be scored.\n",func); return 0; - } - /* get dose scoring mode: region dose, medium dose or both */ - vector allowed_mode; - allowed_mode.push_back("no");allowed_mode.push_back("yes"); - int d_in_medium = input->getInput("medium dose",allowed_mode,0); - int d_in_region = input->getInput("region dose",allowed_mode,1); - if(d_in_medium == 0 && d_in_region == 0) { - egsWarning("%s: Neither dose in regions nor dose in medium specified. Dose will not be scored.\n",func); return 0; - } - vector vreg_start,vreg_stop; - vector v_in,volin; - //give the user the option to input volumes of regions if they know them - int err2 = input->getInput("start volume region",vreg_start); - int err3 = input->getInput("stop volume region",vreg_stop); - int err4 = input->getInput("volume",v_in); - if(err4) { - egsWarning("%s: No dose zone volumes input. Will assume 1 cm^3 for all regions.\n",func); - } - else { - if(!err2 && !err3) { - if(vreg_start.size()==vreg_stop.size()) { - if(v_in.size() d_cms; + int err1=input->getInput("dose CMs",d_cms); + if (err1) { + egsWarning("%s: No CMs input. Dose will not be scored.\n",func); + return 0; + } + /* get dose scoring mode: region dose, medium dose or both */ + vector allowed_mode; + allowed_mode.push_back("no"); + allowed_mode.push_back("yes"); + int d_in_medium = input->getInput("medium dose",allowed_mode,0); + int d_in_region = input->getInput("region dose",allowed_mode,1); + if (d_in_medium == 0 && d_in_region == 0) { + egsWarning("%s: Neither dose in regions nor dose in medium specified. Dose will not be scored.\n",func); + return 0; + } + vector vreg_start,vreg_stop; + vector v_in,volin; + //give the user the option to input volumes of regions if they know them + int err2 = input->getInput("start volume region",vreg_start); + int err3 = input->getInput("stop volume region",vreg_stop); + int err4 = input->getInput("volume",v_in); + if (err4) { + egsWarning("%s: No dose zone volumes input. Will assume 1 cm^3 for all regions.\n",func); + } + else { + if (!err2 && !err3) { + if (vreg_start.size()==vreg_stop.size()) { + if (v_in.size()setVol(volin); - else result->setVol(1.0); - result->setDoseCMs(d_cms); - if ( d_in_medium ) result->setMediumScoring(true); - if ( d_in_region ) result->setRegionScoring(true); - result->setName(input); - return result; -} + /* Setup dose scoring object with input parameters */ + BEAM_DoseScoring *result = new BEAM_DoseScoring("",f); + if (volin.size()) { + result->setVol(volin); + } + else { + result->setVol(1.0); + } + result->setDoseCMs(d_cms); + if (d_in_medium) { + result->setMediumScoring(true); + } + if (d_in_region) { + result->setRegionScoring(true); + } + result->setName(input); + return result; + } } diff --git a/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.h b/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.h index 8361def59..b3f3d22e8 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.h +++ b/HEN_HOUSE/egs++/ausgab_objects/beam_dose_scoring/beam_dose_scoring.h @@ -52,22 +52,22 @@ #ifdef WIN32 -#ifdef BUILD_DOSE_SCORING_DLL -#define BEAM_DOSE_SCORING_EXPORT __declspec(dllexport) -#else -#define BEAM_DOSE_SCORING_EXPORT __declspec(dllimport) -#endif -#define BEAM_DOSE_SCORING_LOCAL + #ifdef BUILD_DOSE_SCORING_DLL + #define BEAM_DOSE_SCORING_EXPORT __declspec(dllexport) + #else + #define BEAM_DOSE_SCORING_EXPORT __declspec(dllimport) + #endif + #define BEAM_DOSE_SCORING_LOCAL #else -#ifdef HAVE_VISIBILITY -#define BEAM_DOSE_SCORING_EXPORT __attribute__ ((visibility ("default"))) -#define BEAM_DOSE_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define BEAM_DOSE_SCORING_EXPORT -#define BEAM_DOSE_SCORING_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define BEAM_DOSE_SCORING_EXPORT __attribute__ ((visibility ("default"))) + #define BEAM_DOSE_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define BEAM_DOSE_SCORING_EXPORT + #define BEAM_DOSE_SCORING_LOCAL + #endif #endif @@ -86,54 +86,74 @@ class BEAM_DOSE_SCORING_EXPORT BEAM_DoseScoring : public EGS_AusgabObject { public: - BEAM_DoseScoring(const string &Name="", EGS_ObjectFactory *f = 0); + BEAM_DoseScoring(const string &Name="", EGS_ObjectFactory *f = 0); - ~BEAM_DoseScoring(); + ~BEAM_DoseScoring(); - int processEvent(EGS_Application::AusgabCall iarg) { + int processEvent(EGS_Application::AusgabCall iarg) { int ir = app->top_p.ir, imed = ir>=0 ? app->getMedium(ir):-1; EGS_Float edep = app->getEdep(); - if (d_reg_index[ir]<0) return 0; + if (d_reg_index[ir]<0) { + return 0; + } /**** energy deposition in current region ***/ - if( iarg <= 4 && ir >= 0 && edep > 0 && dose) { - dose->score(d_reg_index[ir], edep*app->top_p.wt); + if (iarg <= 4 && ir >= 0 && edep > 0 && dose) { + dose->score(d_reg_index[ir], edep*app->top_p.wt); } /**** energy deposition in a medium ***/ //put it here so it doesn't get scored if this is not a scoring region - if( iarg <= 4 && imed >= 0 && edep > 0 && doseM ) { - doseM->score(imed+nmedia*d_reg_cm_ind[ir], edep*app->top_p.wt); + if (iarg <= 4 && imed >= 0 && edep > 0 && doseM) { + doseM->score(imed+nmedia*d_reg_cm_ind[ir], edep*app->top_p.wt); } return 0; }; - bool needsCall(EGS_Application::AusgabCall iarg) const { return true; }; + bool needsCall(EGS_Application::AusgabCall iarg) const { + return true; + }; void setApplication(EGS_Application *App); void reportResults(); void setCurrentCase(EGS_I64 ncase) { - if( ncase != m_lastCase ) { + if (ncase != m_lastCase) { m_lastCase = ncase; - if (dose) dose->setHistory(ncase); - if (doseM) doseM->setHistory(ncase); + if (dose) { + dose->setHistory(ncase); + } + if (doseM) { + doseM->setHistory(ncase); + } } }; - int getDigits(int i){ + int getDigits(int i) { int imax = 10; - while(i>=imax){imax*=10;} + while (i>=imax) { + imax*=10; + } return (int)log10((float)imax); }; - void setVol(const vector volin){vol_list=volin;}; - void setVol(const EGS_Float volin){vol_list.push_back(volin);}; - void setDoseCMs(const vector dcm){d_cms=dcm;}; - void setMediumScoring(bool flag){score_medium_dose=flag;}; - void setRegionScoring(bool flag){score_region_dose=flag;}; + void setVol(const vector volin) { + vol_list=volin; + }; + void setVol(const EGS_Float volin) { + vol_list.push_back(volin); + }; + void setDoseCMs(const vector dcm) { + d_cms=dcm; + }; + void setMediumScoring(bool flag) { + score_medium_dose=flag; + }; + void setRegionScoring(bool flag) { + score_region_dose=flag; + }; bool storeState(ostream &data) const; bool setState(istream &data); @@ -142,23 +162,23 @@ class BEAM_DOSE_SCORING_EXPORT BEAM_DoseScoring : public EGS_AusgabObject { int addTheStates(istream &data); protected: - BEAMpp_Application* bapp; - EGS_ScoringArray *dose; //!< Scoring in each dose scoring region - EGS_ScoringArray *doseM; //!< Scoring dose in each medium - vector vol_list; // Input list of region volumes - vector d_cms; // List of CMs for which dose is to be output - vector d_region; // Input list of dose scoring regions d_reg[i] = ir - vector d_reg_index; // list index for dose scoring regions d_reg_index[ir]= 0..d_reg.size()-1 - vector d_reg_cm_ind; // dose CM index for each dose region. Allows quick scoring of medium dose. - vector < vector > cm_med; // list of media present in CMs in which dose is scored - vector vol; // geometrical region volumes - int nreg, // number of regions in the geometry - nmedia; // number of media in the input file - int max_dreg, // maximum dose region number - max_medl; // maximum medium name length - EGS_I64 m_lastCase; //!< The event set via setCurrentCase() - bool score_medium_dose, - score_region_dose; + BEAMpp_Application *bapp; + EGS_ScoringArray *dose; //!< Scoring in each dose scoring region + EGS_ScoringArray *doseM; //!< Scoring dose in each medium + vector vol_list; // Input list of region volumes + vector d_cms; // List of CMs for which dose is to be output + vector d_region; // Input list of dose scoring regions d_reg[i] = ir + vector d_reg_index; // list index for dose scoring regions d_reg_index[ir]= 0..d_reg.size()-1 + vector d_reg_cm_ind; // dose CM index for each dose region. Allows quick scoring of medium dose. + vector < vector > cm_med; // list of media present in CMs in which dose is scored + vector vol; // geometrical region volumes + int nreg, // number of regions in the geometry + nmedia; // number of media in the input file + int max_dreg, // maximum dose region number + max_medl; // maximum medium name length + EGS_I64 m_lastCase; //!< The event set via setCurrentCase() + bool score_medium_dose, + score_region_dose; }; #endif diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp index 211632fdf..75061d77e 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.cpp @@ -93,108 +93,145 @@ #include "egs_functions.h" EGS_DoseScoring::EGS_DoseScoring(const string &Name, - EGS_ObjectFactory *f) : + EGS_ObjectFactory *f) : EGS_AusgabObject(Name,f), nreg(0), m_lastCase(-1), nmedia(0), dose(0), doseM(0), max_dreg(-1), max_medl(0), - score_medium_dose(false), score_region_dose(false), norm_u(1.0) -{ + score_medium_dose(false), score_region_dose(false), norm_u(1.0) { otype = "EGS_DoseScoring"; } EGS_DoseScoring::~EGS_DoseScoring() { - if( dose ) delete dose; - if( doseM ) delete doseM; + if (dose) { + delete dose; + } + if (doseM) { + delete doseM; + } } void EGS_DoseScoring::setApplication(EGS_Application *App) { EGS_AusgabObject::setApplication(App); - if( !app ) return; + if (!app) { + return; + } // Get the number of regions in the geometry. nreg = app->getnRegions(); // Get the number of media in the input file nmedia = app->getnMedia(); // determine maximum medium name length - char buf[32]; int count = 0;int imed=0; - for ( imed=0; imed < nmedia; imed++){ - sprintf(buf,"%s%n",app->getMediumName(imed),&count); - if (count > max_medl) max_medl = count; + char buf[32]; + int count = 0; + int imed=0; + for (imed=0; imed < nmedia; imed++) { + sprintf(buf,"%s%n",app->getMediumName(imed),&count); + if (count > max_medl) { + max_medl = count; + } } if (d_region.size()>nreg) - egsWarning("\n*********************************************" - "\n WARNING:" - "\nRequesting %d dose scoring regions, but there" - "\nare only %d geometrical regions!" - "\nscoring will be done in all regions!" - "\n*********************************************", - d_region.size(),nreg); + egsWarning("\n*********************************************" + "\n WARNING:" + "\nRequesting %d dose scoring regions, but there" + "\nare only %d geometrical regions!" + "\nscoring will be done in all regions!" + "\n*********************************************", + d_region.size(),nreg); // Flag dose scoring regions in geometry // and set their volume. - if (score_region_dose){ - if (d_region.size() && d_region.size() < nreg){// specific dose regions provided - // Get maximum dose scoring region - for (vector::iterator it = d_region.begin(); it < d_region.end(); it++){ - if (*it > max_dreg) max_dreg = *it; - } - for (int j=0; j::iterator it = d_region.begin(); it < d_region.end(); it++) { + if (*it > max_dreg) { + max_dreg = *it; + } + } + for (int j=0; jregions());description += buf; + if (dose) { + description +="\n - Regions in dose calculator :"; + sprintf(buf,"%d\n\n",dose->regions()); + description += buf; + } + if (doseM) { + description += " - Medium dose will be calculated\n"; } - if (doseM) description += " - Medium dose will be calculated\n"; description += "\n--------------------------------------\n"; - sprintf(buf,"%*s %*s rho/[g/cm**3]\n",max_medl/2,"medium",max_medl/2," ");description += buf; + sprintf(buf,"%*s %*s rho/[g/cm**3]\n",max_medl/2,"medium",max_medl/2," "); + description += buf; description += "--------------------------------------\n"; - for ( imed=0; imed < nmedia; imed++){ - sprintf(buf,"%-*s",max_medl,app->getMediumName(imed));description += buf;description += " "; - sprintf(buf,"%5.2f",app->getMediumRho(imed));description += buf;description += "\n"; + for (imed=0; imed < nmedia; imed++) { + sprintf(buf,"%-*s",max_medl,app->getMediumName(imed)); + description += buf; + description += " "; + sprintf(buf,"%5.2f",app->getMediumRho(imed)); + description += buf; + description += "\n"; } description += "--------------------------------------\n"; - if (norm_u != 1.0){ - description += " Non-unity user-requested normalization = "; - sprintf(buf,"%g\n",norm_u); description += buf; + if (norm_u != 1.0) { + description += " Non-unity user-requested normalization = "; + sprintf(buf,"%g\n",norm_u); + description += buf; } description += "\n*******************************************\n\n"; - vol_list.clear(); if (d_region.size()) d_region.clear(); + vol_list.clear(); + if (d_region.size()) { + d_region.clear(); + } } void EGS_DoseScoring::reportResults() { @@ -206,66 +243,80 @@ void EGS_DoseScoring::reportResults() { EGS_Float F = app->getFluence(); egsInformation("=> last case = %lld fluence = %g\n", m_lastCase, F); /* Normalize to actual source fluence */ - normE = m_lastCase/F*norm_u; normD = 1.602e-10*normE; + normE = m_lastCase/F*norm_u; + normD = 1.602e-10*normE; int irmax_digits = getDigits(max_dreg); - string line; double r,dr; - if (dose){ - if (normE==1){ - egsInformation("\n\n==> Summary of region dosimetry (per particle)\n"); - egsInformation( - "%*s %*s %*s rho/[g/cm3] V/cm3 Edep/[MeV] D/[Gy] %n\n", - irmax_digits,"ir",max_medl/2,"medium",max_medl/2," ",&count); + string line; + double r,dr; + if (dose) { + if (normE==1) { + egsInformation("\n\n==> Summary of region dosimetry (per particle)\n"); + egsInformation( + "%*s %*s %*s rho/[g/cm3] V/cm3 Edep/[MeV] D/[Gy] %n\n", + irmax_digits,"ir",max_medl/2,"medium",max_medl/2," ",&count); } - else{ - egsInformation("\n==> Summary of region dosimetry (per fluence)\n"); - egsInformation( - "%*s %*s %*s rho/[g/cm3] V/cm3 Edep/[MeV*cm2] D/[Gy*cm2] %n\n", - irmax_digits,"ir",max_medl/2,"medium",max_medl/2," ",&count); + else { + egsInformation("\n==> Summary of region dosimetry (per fluence)\n"); + egsInformation( + "%*s %*s %*s rho/[g/cm3] V/cm3 Edep/[MeV*cm2] D/[Gy*cm2] %n\n", + irmax_digits,"ir",max_medl/2,"medium",max_medl/2," ",&count); } - line.append(count,'-'); egsInformation("%s\n",line.c_str()); + line.append(count,'-'); + egsInformation("%s\n",line.c_str()); /* Compute deposited energy and dose */ for (int ireg = 0; ireg < nreg; ireg++) { - if (d_reg_index[ireg]>=0){ - if (!(app->isRealRegion(ireg))) continue; - int imed = app->getMedium(ireg); - EGS_Float rho = app->getMediumRho(imed); - EGS_Float mass = vol[ireg]*rho; - dose->currentResult(d_reg_index[ireg],r,dr);if( r > 0 ) dr = dr/r; else dr=1; - egsInformation("%*d %-*s %7.3f %8.4f %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", - irmax_digits,ireg,max_medl,app->getMediumName(imed),rho,vol[ireg],r*normE,dr*100.,r*normD/mass,dr*100.); - } + if (d_reg_index[ireg]>=0) { + if (!(app->isRealRegion(ireg))) { + continue; + } + int imed = app->getMedium(ireg); + EGS_Float rho = app->getMediumRho(imed); + EGS_Float mass = vol[ireg]*rho; + dose->currentResult(d_reg_index[ireg],r,dr); + if (r > 0) { + dr = dr/r; + } + else { + dr=1; + } + egsInformation("%*d %-*s %7.3f %8.4f %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", + irmax_digits,ireg,max_medl,app->getMediumName(imed),rho,vol[ireg],r*normE,dr*100.,r*normD/mass,dr*100.); + } } egsInformation("%s\n",line.c_str()); } - if (doseM){ - vector massM(nmedia,0); int imed = 0; - for (int ir=0; irgetMedium(ir); - EGS_Float volume = vol.size() > 1 ? vol[ir]:vol[0]; - massM[imed] += app->getMediumRho(imed)*volume; + if (doseM) { + vector massM(nmedia,0); + int imed = 0; + for (int ir=0; irgetMedium(ir); + EGS_Float volume = vol.size() > 1 ? vol[ir]:vol[0]; + massM[imed] += app->getMediumRho(imed)*volume; } - if (normE==1){ - egsInformation("\n\n==> Summary of media dosimetry (per particle)\n"); - egsInformation( - "%*s %*s Edep/[MeV] D/[Gy] %n\n", - max_medl/2,"medium",max_medl/2," ",&count); + if (normE==1) { + egsInformation("\n\n==> Summary of media dosimetry (per particle)\n"); + egsInformation( + "%*s %*s Edep/[MeV] D/[Gy] %n\n", + max_medl/2,"medium",max_medl/2," ",&count); } - else{ - egsInformation("\n\n==> Summary of media dosimetry (per fluence)\n"); - egsInformation( - "%*s %*s Edep/[MeV*cm2] D/[Gy*cm2] %n\n", - max_medl/2,"medium",max_medl/2," ",&count); + else { + egsInformation("\n\n==> Summary of media dosimetry (per fluence)\n"); + egsInformation( + "%*s %*s Edep/[MeV*cm2] D/[Gy*cm2] %n\n", + max_medl/2,"medium",max_medl/2," ",&count); } - line="";line.append(count,'-'); egsInformation("%s\n",line.c_str()); + line=""; + line.append(count,'-'); + egsInformation("%s\n",line.c_str()); /* Compute deposited energy in medium (MeV)*/ for (int im=0; imcurrentResult(im,r,dr); - if( r > 0 ){ - dr = dr/r; - egsInformation( - "%-*s %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", - max_medl,app->getMediumName(im),r*normE,dr*100.,r*normD/massM[im],dr*100.); + if (r > 0) { + dr = dr/r; + egsInformation( + "%-*s %10.4e +/- %-7.3f%% %10.4e +/- %-7.3f%%\n", + max_medl,app->getMediumName(im),r*normE,dr*100.,r*normD/massM[im],dr*100.); } } egsInformation("%s\n",line.c_str()); @@ -274,49 +325,72 @@ void EGS_DoseScoring::reportResults() { } bool EGS_DoseScoring::storeState(ostream &data) const { - //egsInformation("Storing EGS_DoseScoring...\n"); - if( !egsStoreI64(data,m_lastCase)) return false; - data << endl; - if( dose && !dose->storeState(data)) return false; - if( doseM && !doseM->storeState(data)) return false; - return true; + //egsInformation("Storing EGS_DoseScoring...\n"); + if (!egsStoreI64(data,m_lastCase)) { + return false; + } + data << endl; + if (dose && !dose->storeState(data)) { + return false; + } + if (doseM && !doseM->storeState(data)) { + return false; + } + return true; } -bool EGS_DoseScoring::setState(istream &data){ - if( !egsGetI64(data,m_lastCase) ) return false; - if( dose && !dose->setState(data)) return false; - if( doseM && !doseM->setState(data)) return false; - return true; +bool EGS_DoseScoring::setState(istream &data) { + if (!egsGetI64(data,m_lastCase)) { + return false; + } + if (dose && !dose->setState(data)) { + return false; + } + if (doseM && !doseM->setState(data)) { + return false; + } + return true; } -bool EGS_DoseScoring::addState(istream &data){ - int err = addTheStates(data); - if (err){ +bool EGS_DoseScoring::addState(istream &data) { + int err = addTheStates(data); + if (err) { egsInformation("Error code: %d",err); return false; - } - return true; + } + return true; } -int EGS_DoseScoring::addTheStates(istream &data){ - EGS_I64 tmp_case; if( !egsGetI64(data,tmp_case) ) return 4401; - m_lastCase += tmp_case; - if (dose){ +int EGS_DoseScoring::addTheStates(istream &data) { + EGS_I64 tmp_case; + if (!egsGetI64(data,tmp_case)) { + return 4401; + } + m_lastCase += tmp_case; + if (dose) { EGS_ScoringArray tmp(nreg); - if( !tmp.setState(data) ) return 4402; + if (!tmp.setState(data)) { + return 4402; + } (*dose) += tmp; - } - if (doseM){ - EGS_ScoringArray tmpM(nmedia); - if( !tmpM.setState(data) ) return 4403; - (*doseM) += tmpM; - } - return 0; + } + if (doseM) { + EGS_ScoringArray tmpM(nmedia); + if (!tmpM.setState(data)) { + return 4403; + } + (*doseM) += tmpM; + } + return 0; } -void EGS_DoseScoring::resetCounter(){ - m_lastCase = 0; - if (dose) dose->reset(); - if (doseM) doseM->reset(); +void EGS_DoseScoring::resetCounter() { + m_lastCase = 0; + if (dose) { + dose->reset(); + } + if (doseM) { + doseM->reset(); + } } //********************************************************************* @@ -344,80 +418,97 @@ void EGS_DoseScoring::resetCounter(){ //********************************************************************** extern "C" { -EGS_DOSE_SCORING_EXPORT EGS_AusgabObject* createAusgabObject(EGS_Input *input, - EGS_ObjectFactory *f) { - const static char *func = "createAusgabObject(dose_scoring)"; - if( !input ) { - egsWarning("%s: null input?\n",func); return 0; - } - vector v_in;// voxel volume[s] in g/cm3 - /* get voxel volume */ - input->getInput("volume",v_in); - /* get dose scoring mode: region dose, medium dose or both */ - vector allowed_mode; - allowed_mode.push_back("no");allowed_mode.push_back("yes"); - int d_in_medium = input->getInput("medium dose",allowed_mode,0); - int d_in_region = input->getInput("region dose",allowed_mode,1); + EGS_DOSE_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, + EGS_ObjectFactory *f) { + const static char *func = "createAusgabObject(dose_scoring)"; + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + vector v_in;// voxel volume[s] in g/cm3 + /* get voxel volume */ + input->getInput("volume",v_in); + /* get dose scoring mode: region dose, medium dose or both */ + vector allowed_mode; + allowed_mode.push_back("no"); + allowed_mode.push_back("yes"); + int d_in_medium = input->getInput("medium dose",allowed_mode,0); + int d_in_region = input->getInput("region dose",allowed_mode,1); - /* get dose regions */ - vector d_regions; bool using_all_regions=true; - vector d_start, d_stop; - if (!input->getInput("dose regions",d_regions)&& d_regions.size()>0) - using_all_regions = false;// individual regions - else{ - int err1 = input->getInput("dose start region",d_start); - int err2 = input->getInput("dose stop region",d_stop); - if ( !err1 && !err2 ){ - if (d_start.size()==d_stop.size()){// group of dose regions - for (int i=0; i d_regions; + bool using_all_regions=true; + vector d_start, d_stop; + if (!input->getInput("dose regions",d_regions)&& d_regions.size()>0) { + using_all_regions = false; // individual regions + } + else { + int err1 = input->getInput("dose start region",d_start); + int err2 = input->getInput("dose stop region",d_stop); + if (!err1 && !err2) { + if (d_start.size()==d_stop.size()) { // group of dose regions + for (int i=0; igetInput("normalization",norma); + } + EGS_Float norma = 1.0; + int err04 = input->getInput("normalization",norma); - //================================================ - // Check if one volume for each group requested. - // If not just pass the volumes read and if there - // is a mismatch, then the first volume element - // or 1g/cm3 will be used. - //================================================= - vector volin; - // groups of regions with same volume - if (! using_all_regions && v_in.size()== d_start.size()){ - for (int i=0; i volin; + // groups of regions with same volume + if (! using_all_regions && v_in.size()== d_start.size()) { + for (int i=0; isetVol(volin[0]);// one size for all regions - else if(volin.size()) - result->setVol(volin); // regions with their volumes - else - result->setVol(1.0); // default value if no entry - if (!using_all_regions) - result->setDoseRegions(d_regions); - if ( d_in_medium ) result->setMediumScoring(true); - if ( d_in_region ) result->setRegionScoring(true); - result->setName(input); - if (!err04) result->setUserNorm(norma); - return result; -} + /* Setup dose scoring object with input parameters */ + EGS_DoseScoring *result = new EGS_DoseScoring("",f); + if (volin.size()==1) { + result->setVol(volin[0]); // one size for all regions + } + else if (volin.size()) { + result->setVol(volin); // regions with their volumes + } + else { + result->setVol(1.0); // default value if no entry + } + if (!using_all_regions) { + result->setDoseRegions(d_regions); + } + if (d_in_medium) { + result->setMediumScoring(true); + } + if (d_in_region) { + result->setRegionScoring(true); + } + result->setName(input); + if (!err04) { + result->setUserNorm(norma); + } + return result; + } } diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.h b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.h index b1d489b6f..4584587b3 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.h +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_dose_scoring/egs_dose_scoring.h @@ -94,22 +94,22 @@ #ifdef WIN32 -#ifdef BUILD_DOSE_SCORING_DLL -#define EGS_DOSE_SCORING_EXPORT __declspec(dllexport) -#else -#define EGS_DOSE_SCORING_EXPORT __declspec(dllimport) -#endif -#define EGS_DOSE_SCORING_LOCAL + #ifdef BUILD_DOSE_SCORING_DLL + #define EGS_DOSE_SCORING_EXPORT __declspec(dllexport) + #else + #define EGS_DOSE_SCORING_EXPORT __declspec(dllimport) + #endif + #define EGS_DOSE_SCORING_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_DOSE_SCORING_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_DOSE_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_DOSE_SCORING_EXPORT -#define EGS_DOSE_SCORING_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_DOSE_SCORING_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_DOSE_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_DOSE_SCORING_EXPORT + #define EGS_DOSE_SCORING_LOCAL + #endif #endif @@ -177,25 +177,31 @@ class EGS_DOSE_SCORING_EXPORT EGS_DoseScoring : public EGS_AusgabObject { EGS_Float edep = app->getEdep(); /**** energy deposition in a medium ***/ - if( iarg <= 4 && imed >= 0 && edep > 0 && doseM) { - doseM->score(imed, edep*app->top_p.wt); + if (iarg <= 4 && imed >= 0 && edep > 0 && doseM) { + doseM->score(imed, edep*app->top_p.wt); } /*** Check if scoring in current region ***/ - if (dose){ - if (d_reg_index[ir]<0) return 0; + if (dose) { + if (d_reg_index[ir]<0) { + return 0; + } } /**** energy deposition in current region ***/ - if( iarg <= 4 && ir >= 0 && edep > 0 && dose) { - dose->score(d_reg_index[ir], edep*app->top_p.wt); + if (iarg <= 4 && ir >= 0 && edep > 0 && dose) { + dose->score(d_reg_index[ir], edep*app->top_p.wt); } return 0; }; bool needsCall(EGS_Application::AusgabCall iarg) const { - if( iarg <= 4 ) return true; - else return false; + if (iarg <= 4) { + return true; + } + else { + return false; + } }; void setApplication(EGS_Application *App); @@ -203,24 +209,42 @@ class EGS_DOSE_SCORING_EXPORT EGS_DoseScoring : public EGS_AusgabObject { void reportResults(); void setCurrentCase(EGS_I64 ncase) { - if( ncase != m_lastCase ) { + if (ncase != m_lastCase) { m_lastCase = ncase; - if (dose) dose->setHistory(ncase); - if (doseM) doseM->setHistory(ncase); + if (dose) { + dose->setHistory(ncase); + } + if (doseM) { + doseM->setHistory(ncase); + } } }; - int getDigits(int i){ + int getDigits(int i) { int imax = 10; - while(i>=imax){imax*=10;} + while (i>=imax) { + imax*=10; + } return (int)log10((float)imax); }; - void setVol(const vector volin){vol_list=volin;}; - void setVol(const EGS_Float volin){vol_list.push_back(volin);}; - void setDoseRegions(const vector d_reg){d_region=d_reg;}; - void setMediumScoring(bool flag){score_medium_dose=flag;}; - void setRegionScoring(bool flag){score_region_dose=flag;}; - void setUserNorm(const EGS_Float & normi){norm_u=normi;}; + void setVol(const vector volin) { + vol_list=volin; + }; + void setVol(const EGS_Float volin) { + vol_list.push_back(volin); + }; + void setDoseRegions(const vector d_reg) { + d_region=d_reg; + }; + void setMediumScoring(bool flag) { + score_medium_dose=flag; + }; + void setRegionScoring(bool flag) { + score_region_dose=flag; + }; + void setUserNorm(const EGS_Float &normi) { + norm_u=normi; + }; bool storeState(ostream &data) const; bool setState(istream &data); @@ -230,20 +254,20 @@ class EGS_DOSE_SCORING_EXPORT EGS_DoseScoring : public EGS_AusgabObject { protected: - EGS_ScoringArray *dose; //!< Scoring in each dose scoring region - EGS_ScoringArray *doseM; //!< Scoring dose in each medium - vector vol_list; // Input list of region volumes - vector d_region; // Input list of dose scoring regions d_reg[i] = ir - vector d_reg_index; // list index for dose scoring regions d_reg_index[ir]= 0..d_reg.size()-1 - vector vol; // geometrical region volumes - EGS_Float norm_u; - int nreg, // number of regions in the geometry - nmedia; // number of media in the input file - int max_dreg, // maximum dose region number - max_medl; // maximum medium name length - EGS_I64 m_lastCase; //!< The event set via setCurrentCase() - bool score_medium_dose, - score_region_dose; + EGS_ScoringArray *dose; //!< Scoring in each dose scoring region + EGS_ScoringArray *doseM; //!< Scoring dose in each medium + vector vol_list; // Input list of region volumes + vector d_region; // Input list of dose scoring regions d_reg[i] = ir + vector d_reg_index; // list index for dose scoring regions d_reg_index[ir]= 0..d_reg.size()-1 + vector vol; // geometrical region volumes + EGS_Float norm_u; + int nreg, // number of regions in the geometry + nmedia; // number of media in the input file + int max_dreg, // maximum dose region number + max_medl; // maximum medium name length + EGS_I64 m_lastCase; //!< The event set via setCurrentCase() + bool score_medium_dose, + score_region_dose; }; #endif diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp index debba1219..bfcb82721 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.cpp @@ -46,26 +46,43 @@ EGS_TrackScoring::EGS_TrackScoring(const string &Name, EGS_ObjectFactory *f) : } EGS_TrackScoring::~EGS_TrackScoring() { - if( m_pts ) delete m_pts; + if (m_pts) { + delete m_pts; + } } void EGS_TrackScoring::setApplication(EGS_Application *App) { EGS_AusgabObject::setApplication(App); - if( !app ) return; - if( m_pts ) { delete m_pts; m_pts = 0; } - if( m_bufSize < 1 ) m_bufSize = 1024; - string fname(app->getOutputFile()); fname += m_fnExtra; - if( !egsIsAbsolutePath(fname) ) fname = egsJoinPath(app->getAppDir(),fname); + if (!app) { + return; + } + if (m_pts) { + delete m_pts; + m_pts = 0; + } + if (m_bufSize < 1) { + m_bufSize = 1024; + } + string fname(app->getOutputFile()); + fname += m_fnExtra; + if (!egsIsAbsolutePath(fname)) { + fname = egsJoinPath(app->getAppDir(),fname); + } int i_parallel = -1; - if( app->getNparallel() > 1 ) i_parallel = app->getIparallel(); - if( i_parallel >= 0 ) { - char buf[16]; sprintf(buf,"_w%d",i_parallel); fname += buf; + if (app->getNparallel() > 1) { + i_parallel = app->getIparallel(); + } + if (i_parallel >= 0) { + char buf[16]; + sprintf(buf,"_w%d",i_parallel); + fname += buf; } fname += ".ptracks"; m_pts = new EGS_ParticleTrackContainer(fname.c_str(),m_bufSize); description = "\nParticle Track Scoring ("; - description += name; description += ")\n"; + description += name; + description += ")\n"; description += "======================================================\n"; description += " - Scoring photon tracks = "; description += m_score_photons ? "YES\n" : "NO\n"; @@ -75,12 +92,16 @@ void EGS_TrackScoring::setApplication(EGS_Application *App) { description += m_score_positrons ? "YES\n" : "NO\n"; description += " - First event to score = "; char buf[32]; - sprintf(buf,"%lld\n",m_start); description += buf; + sprintf(buf,"%lld\n",m_start); + description += buf; description += " - Last event to score = "; - sprintf(buf,"%lld\n",m_stop); description += buf; + sprintf(buf,"%lld\n",m_stop); + description += buf; description += " - Track buffer size = "; - sprintf(buf,"%d\n",m_bufSize); description += buf; - description += " - Output file name = "; description += fname; + sprintf(buf,"%d\n",m_bufSize); + description += buf; + description += " - Output file name = "; + description += fname; description += "\n\n"; } @@ -88,37 +109,47 @@ void EGS_TrackScoring::reportResults() { egsInformation("\nParticle Track Scoring (%s)\n",name.c_str()); egsInformation("======================================================\n"); egsInformation(" Total events scored: %lld\n",m_nScore); - if( m_pts ) m_pts->reportResults(false); + if (m_pts) { + m_pts->reportResults(false); + } } extern "C" { -EGS_TRACK_SCORING_EXPORT EGS_AusgabObject* createAusgabObject(EGS_Input *input, - EGS_ObjectFactory *f) { - const static char *func = "createAusgabObject(track_scoring)"; - if( !input ) { - egsWarning("%s: null input?\n",func); return 0; + EGS_TRACK_SCORING_EXPORT EGS_AusgabObject *createAusgabObject(EGS_Input *input, + EGS_ObjectFactory *f) { + const static char *func = "createAusgabObject(track_scoring)"; + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + vector sc_options; + sc_options.push_back("no"); + sc_options.push_back("yes"); + bool scph = input->getInput("score photons",sc_options,true); + bool scel = input->getInput("score electrons",sc_options,true); + bool scpo = input->getInput("score positrons",sc_options,true); + if (!scph && !scel && !scpo) { + return 0; + } + EGS_I64 first = 0, last = 1024; + input->getInput("start scoring",first); + input->getInput("stop scoring",last); + int bufSize = 1024; + input->getInput("buffer size",bufSize); + string fnExtra; + input->getInput("file name addition",fnExtra); + EGS_TrackScoring *result = new EGS_TrackScoring("",f); + result->setScorePhotons(scph); + result->setScoreElectrons(scel); + result->setScorePositrons(scpo); + result->setFirstEvent(first); + result->setLastEvent(last); + result->setBufferSize(bufSize); + result->setFileNameExtra(fnExtra); + result->setName(input); + return result; } - vector sc_options; sc_options.push_back("no"); sc_options.push_back("yes"); - bool scph = input->getInput("score photons",sc_options,true); - bool scel = input->getInput("score electrons",sc_options,true); - bool scpo = input->getInput("score positrons",sc_options,true); - if( !scph && !scel && !scpo ) return 0; - EGS_I64 first = 0, last = 1024; - input->getInput("start scoring",first); input->getInput("stop scoring",last); - int bufSize = 1024; input->getInput("buffer size",bufSize); - string fnExtra; input->getInput("file name addition",fnExtra); - EGS_TrackScoring *result = new EGS_TrackScoring("",f); - result->setScorePhotons(scph); - result->setScoreElectrons(scel); - result->setScorePositrons(scpo); - result->setFirstEvent(first); - result->setLastEvent(last); - result->setBufferSize(bufSize); - result->setFileNameExtra(fnExtra); - result->setName(input); - return result; -} } diff --git a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.h b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.h index 5d7f709a1..d8e3c2a77 100644 --- a/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.h +++ b/HEN_HOUSE/egs++/ausgab_objects/egs_track_scoring/egs_track_scoring.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_TRACK_SCORING_DLL -#define EGS_TRACK_SCORING_EXPORT __declspec(dllexport) -#else -#define EGS_TRACK_SCORING_EXPORT __declspec(dllimport) -#endif -#define EGS_TRACK_SCORING_LOCAL + #ifdef BUILD_TRACK_SCORING_DLL + #define EGS_TRACK_SCORING_EXPORT __declspec(dllexport) + #else + #define EGS_TRACK_SCORING_EXPORT __declspec(dllimport) + #endif + #define EGS_TRACK_SCORING_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_TRACK_SCORING_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_TRACK_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_TRACK_SCORING_EXPORT -#define EGS_TRACK_SCORING_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_TRACK_SCORING_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_TRACK_SCORING_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_TRACK_SCORING_EXPORT + #define EGS_TRACK_SCORING_LOCAL + #endif #endif @@ -100,22 +100,25 @@ class EGS_TRACK_SCORING_EXPORT EGS_TrackScoring : public EGS_AusgabObject { ~EGS_TrackScoring(); int processEvent(EGS_Application::AusgabCall iarg) { - if( m_score ) { - if( !m_didScore ) { - m_didScore = true; ++m_nScore; + if (m_score) { + if (!m_didScore) { + m_didScore = true; + ++m_nScore; } int np = app->Np; - if( m_pts->isScoringParticle(np)) { - if (iarg == EGS_Application::AfterTransport) + if (m_pts->isScoringParticle(np)) { + if (iarg == EGS_Application::AfterTransport) { m_pts->addVertex(np,new EGS_ParticleTrack::Vertex(app->top_p.x,app->top_p.E)); - else if( iarg != EGS_Application::BeforeTransport ) + } + else if (iarg != EGS_Application::BeforeTransport) { m_pts->stopScoringParticle(np); + } } - else if( iarg == EGS_Application::BeforeTransport ) { + else if (iarg == EGS_Application::BeforeTransport) { int q = app->top_p.q; - if( (q == 0 && m_score_photons) || - (q == -1 && m_score_electrons) || - (q == 1 && m_score_positrons) ) { + if ((q == 0 && m_score_photons) || + (q == -1 && m_score_electrons) || + (q == 1 && m_score_positrons)) { m_pts->startNewTrack(np); m_pts->setCurrentParticleInfo(new EGS_ParticleTrack::ParticleInfo(q)); m_pts->addVertex(np,new EGS_ParticleTrack::Vertex(app->top_p.x,app->top_p.E)); @@ -125,26 +128,48 @@ class EGS_TRACK_SCORING_EXPORT EGS_TrackScoring : public EGS_AusgabObject { return 0; }; - bool needsCall(EGS_Application::AusgabCall iarg) const { return true; }; + bool needsCall(EGS_Application::AusgabCall iarg) const { + return true; + }; void setApplication(EGS_Application *App); void reportResults(); void setCurrentCase(EGS_I64 ncase) { - if( ncase != m_lastCase ) { - m_lastCase = ncase; m_didScore = false; + if (ncase != m_lastCase) { + m_lastCase = ncase; + m_didScore = false; + } + if (ncase < m_start || ncase > m_stop) { + m_score = false; + } + else { + m_score = true; } - if( ncase < m_start || ncase > m_stop ) m_score = false; else m_score = true; }; - void setScorePhotons(bool score) { m_score_photons = score; }; - void setScoreElectrons(bool score) { m_score_electrons = score; }; - void setScorePositrons(bool score) { m_score_positrons = score; }; - void setFirstEvent(EGS_I64 first) { m_start = first; }; - void setLastEvent(EGS_I64 last) { m_stop = last; }; - void setBufferSize(int size) { m_bufSize = size; }; - void setFileNameExtra(const string &extra) { m_fnExtra = extra; }; + void setScorePhotons(bool score) { + m_score_photons = score; + }; + void setScoreElectrons(bool score) { + m_score_electrons = score; + }; + void setScorePositrons(bool score) { + m_score_positrons = score; + }; + void setFirstEvent(EGS_I64 first) { + m_start = first; + }; + void setLastEvent(EGS_I64 last) { + m_stop = last; + }; + void setBufferSize(int size) { + m_bufSize = size; + }; + void setFileNameExtra(const string &extra) { + m_fnExtra = extra; + }; protected: diff --git a/HEN_HOUSE/egs++/egs_advanced_application.cpp b/HEN_HOUSE/egs++/egs_advanced_application.cpp index f85e8b631..58b578826 100644 --- a/HEN_HOUSE/egs++/egs_advanced_application.cpp +++ b/HEN_HOUSE/egs++/egs_advanced_application.cpp @@ -106,56 +106,74 @@ extern __extc__ void egsSetSteps(const double *, const double *); extern __extc__ void egsOpenUnits(const EGS_I32 *); #define egsGetElectronData F77_OBJ_(egs_get_electron_data,EGS_GET_ELECTRON_DATA) extern __extc__ void egsGetElectronData(void (*func)(EGS_I32 *,EGS_Float *, - EGS_Float *,EGS_Float *,EGS_Float *),const EGS_I32 *,const EGS_I32 *); + EGS_Float *,EGS_Float *,EGS_Float *),const EGS_I32 *,const EGS_I32 *); #define egsGetPhotonData F77_OBJ_(egs_get_photon_data,EGS_GET_PHOTON_DATA) extern __extc__ void egsGetPhotonData(void (*func)(EGS_I32 *,EGS_Float *, - EGS_Float *,EGS_Float *,EGS_Float *),const EGS_I32 *,const EGS_I32 *); + EGS_Float *,EGS_Float *,EGS_Float *),const EGS_I32 *,const EGS_I32 *); static EGS_Float *__help1, *__help2, *__help3, *__help4; static EGS_I32 *__ihelp; static void __help_get_data(EGS_I32 *nbin,EGS_Float *emin, EGS_Float *emax, EGS_Float *a, EGS_Float *b) { - __ihelp = nbin; __help1 = emin; __help2 = emax; __help3 = a; __help4 = b; + __ihelp = nbin; + __help1 = emin; + __help2 = emax; + __help3 = a; + __help4 = b; } static void __init_interpolator(int q, int imed, int type, EGS_Interpolator &i) { - if( q ) egsGetElectronData(__help_get_data,&imed,&type); - else egsGetPhotonData(__help_get_data,&imed,&type); + if (q) { + egsGetElectronData(__help_get_data,&imed,&type); + } + else { + egsGetPhotonData(__help_get_data,&imed,&type); + } i.initialize(*__ihelp,*__help1,*__help2,__help3,__help4); } -void EGS_AdvancedApplication::setAusgabCall(AusgabCall call, bool on_or_off) {\ +void EGS_AdvancedApplication::setAusgabCall(AusgabCall call, bool on_or_off) { + \ EGS_Application::setAusgabCall(call,on_or_off); the_epcont->iausfl[call] = (int) on_or_off; } static EGS_LOCAL void __egs_iovar(int nio, int ns, - const char *source, char *var) { - if( ns > nio-1 ) + const char *source, char *var) { + if (ns > nio-1) { egsFatal("Mortran variable is not long enough to hold %s\n",source); + } int j; - for(j=0; ji_log; F77_OBJ_(egs_write_string,EGS_WRITE_STRING)(&ounit,__write_buf, - strlen(__write_buf)); + strlen(__write_buf)); } void EGS_LOCAL __write_to_fortran_file_and_exit(const char *msg, ...) { - va_list ap; va_start( ap, msg ); - vsprintf(__write_buf,msg,ap); va_end(ap); + va_list ap; + va_start(ap, msg); + vsprintf(__write_buf,msg,ap); + va_end(ap); int ounit=the_egsio->i_log; F77_OBJ_(egs_write_string,EGS_WRITE_STRING)(&ounit,__write_buf, - strlen(__write_buf)); + strlen(__write_buf)); exit(1); } @@ -168,12 +186,14 @@ int EGS_AdvancedApplication::initEGSnrcBackEnd() { __egs_iovar(128,egs_home.size(),egs_home.c_str(),the_egsio->egs_home); __egs_iovar(256,input_file.size(),input_file.c_str(),the_egsio->input_file); __egs_iovar(256,final_output_file.size(),final_output_file.c_str(), - the_egsio->output_file); + the_egsio->output_file); __egs_iovar(256,pegs_file.size(),pegs_file.c_str(),the_egsio->pegs_file); the_egsio->i_parallel = i_parallel; the_egsio->n_parallel = n_parallel; the_egsio->is_pegsless = is_pegsless; - if( run ) the_egsio->n_chunk = run->getNchunk(); + if (run) { + the_egsio->n_chunk = run->getNchunk(); + } the_egsio->is_batch = (int) batch_run; F77_OBJ_(egs_init1,EGS_INIT1)(); /* @@ -251,76 +271,123 @@ class EGS_LOCAL EGS_TransportProperty { name(Name), type(5), f_v(f), nitem(N) {}; /* Integer input with allowed values => type = 2 */ void addOption(const char *opt) { - options.push_back(opt); type = 2; + options.push_back(opt); + type = 2; }; void getInput(EGS_Input *input) { - if( type == 1 ) { - EGS_Float aux; int err = input->getInput(name,aux); - if( !err ) *float_input = aux; + if (type == 1) { + EGS_Float aux; + int err = input->getInput(name,aux); + if (!err) { + *float_input = aux; + } } - else if( type == 0 ) { - EGS_I32 aux; int err = input->getInput(name,aux); - if( !err ) *int_input = aux; + else if (type == 0) { + EGS_I32 aux; + int err = input->getInput(name,aux); + if (!err) { + *int_input = aux; + } } - else if( type == 3 ) { + else if (type == 3) { int err = input->getInput(name,charinp); - if( !err ) { - int l = charinp.size(); if( l > len ) l = len; int j; - for(j=0; j len) { + l = len; + } + int j; + for (j=0; jgetInput(name,*str_v); - if( !err ) { - vector str = *str_v;str_v->clear(); - int number = str.size(); - if(number>nitem){ - str.erase(str.begin()+nitem,str.end());number=nitem; - } - for(int i=0; ilen) str[i] = str[i].substr(0,len); - } - *str_v = str; + if (!err) { + vector str = *str_v; + str_v->clear(); + int number = str.size(); + if (number>nitem) { + str.erase(str.begin()+nitem,str.end()); + number=nitem; + } + for (int i=0; ilen) { + str[i] = str[i].substr(0,len); + } + } + *str_v = str; } } - else if( type == 5 ) { + else if (type == 5) { int err = input->getInput(name,*f_v); - if( !err ) { - vector fv = *f_v;f_v->clear(); - int number = fv.size(); - if(number>nitem){ - fv.erase(fv.begin()+nitem,fv.end());number=nitem; - } - *f_v = fv; + if (!err) { + vector fv = *f_v; + f_v->clear(); + int number = fv.size(); + if (number>nitem) { + fv.erase(fv.begin()+nitem,fv.end()); + number=nitem; + } + *f_v = fv; } } else { - bool is_ok; EGS_I32 iaux = input->getInput(name,options,0,&is_ok); - if( is_ok ) *int_input = iaux; + bool is_ok; + EGS_I32 iaux = input->getInput(name,options,0,&is_ok); + if (is_ok) { + *int_input = iaux; + } egsWarning("Property %s: %d\n",name.c_str(),*int_input); } }; void info(int nc) { egsInformation("%s",name.c_str()); - for(int j=name.size(); j::iterator it = f_v->begin() ; it != f_v->end(); ++it) + for (int j=name.size(); j::iterator it = f_v->begin() ; it != f_v->end(); ++it) { egsInformation("%g ",*it); - egsInformation("\n"); + } + egsInformation("\n"); + } + else { + egsInformation("%s\n",options[*int_input].c_str()); } - else egsInformation("%s\n",options[*int_input].c_str()); }; int size() { - if( type == 1 ) return sizeof(EGS_Float); - else if( type == 3 ) return len; - else if( type == 4 ) return nitem; - else if( type == 5 ) return f_v->size(); - else return sizeof(EGS_I32); + if (type == 1) { + return sizeof(EGS_Float); + } + else if (type == 3) { + return len; + } + else if (type == 4) { + return nitem; + } + else if (type == 5) { + return f_v->size(); + } + else { + return sizeof(EGS_I32); + } }; }; @@ -330,49 +397,61 @@ EGS_AdvancedApplication::EGS_AdvancedApplication(int argc, char **argv) : EGS_Application(argc,argv), n_rng_buffer(0), final_job(false), nmed(0), io_flag(0) { } EGS_AdvancedApplication::~EGS_AdvancedApplication() { - if( n_rng_buffer > 0 ) delete [] rng_buffer; + if (n_rng_buffer > 0) { + delete [] rng_buffer; + } } void EGS_AdvancedApplication::describeSimulation() { EGS_Application::describeSimulation(); - if( final_job ) helpInit(0,false); + if (final_job) { + helpInit(0,false); + } } int EGS_AdvancedApplication::initCrossSections() { egsWarning("In initCrossSections(): spin effects = %d\n", - the_xoptions->spin_effects); + the_xoptions->spin_effects); EGS_Input *transportp = input->getInputItem("MC transport parameter"); - if( !transportp ) transportp = input->getInputItem("transport parameter"); + if (!transportp) { + transportp = input->getInputItem("transport parameter"); + } return helpInit(transportp,true); } extern "C" void F77_OBJ_(set_elastic_parameter,SET_ELASTIC_PARAMETER)(); int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { - if( !geometry ) { - egsWarning("initCrossSections(): no geometry?\n"); return 1; + if (!geometry) { + egsWarning("initCrossSections(): no geometry?\n"); + return 1; } EGS_BaseGeometry::setActiveGeometryList(app_index); int nmed_new = EGS_BaseGeometry::nMedia(), j; - if( nmed_new < 1 ) { + if (nmed_new < 1) { egsWarning("initCrossSections(): no media in this geometry?\n"); return 2; } - int nmed_old = nmed; nmed = nmed_new; + int nmed_old = nmed; + nmed = nmed_new; int *ind = new int [nmed]; - for(j=0; jgetMediumName(j); - int len = strlen(medname); ind[j] = egsAddMedium(medname, len); + int len = strlen(medname); + ind[j] = egsAddMedium(medname, len); } - vector ff_media, ff_names; string eii_xsect; + vector ff_media, ff_names; + string eii_xsect; vector efield_v, bfield_v; // // The Intel compiler uses -1 for .true. => all logical // variables don't work! // This is a fix for this // - if( the_xoptions->spin_effects != 0 ) the_xoptions->spin_effects=1; + if (the_xoptions->spin_effects != 0) { + the_xoptions->spin_effects=1; + } //if( the_xoptions->exact_bca != 0 ) the_xoptions->exact_bca=1; // @@ -387,54 +466,75 @@ int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { EGS_TransportProperty estep("ESTEPE",&the_etcontrol->estepe); EGS_TransportProperty ximax("Ximax",&the_etcontrol->ximax); EGS_TransportProperty skind("Skin depth for BCA", - &the_etcontrol->skindepth_for_bca); + &the_etcontrol->skindepth_for_bca); EGS_TransportProperty pxsec("Photon cross sections",16,the_media->pxsec); EGS_TransportProperty pxsec_out("Photon cross-sections output",&the_egsio->xsec_out); - pxsec_out.addOption("Off"); pxsec_out.addOption("On"); + pxsec_out.addOption("Off"); + pxsec_out.addOption("On"); EGS_TransportProperty cxsec("Compton cross sections",16,the_media->compxsec); EGS_TransportProperty bc("Bound Compton scattering",&the_xoptions->ibcmp); - bc.addOption("Off"); bc.addOption("On"); bc.addOption("Simple"); + bc.addOption("Off"); + bc.addOption("On"); + bc.addOption("Simple"); bc.addOption("norej"); EGS_TransportProperty radc("Radiative Compton corrections", - &the_xoptions->radc_flag); - radc.addOption("Off"); radc.addOption("On"); + &the_xoptions->radc_flag); + radc.addOption("Off"); + radc.addOption("On"); /* Photonuclear input parameters */ EGS_TransportProperty photonucxsec("Photonuclear cross sections",16,the_media->photonucxsec); EGS_TransportProperty photonuc("Photonuclear attenuation",&the_xoptions->iphotonuc); - photonuc.addOption("Off"); photonuc.addOption("On"); + photonuc.addOption("Off"); + photonuc.addOption("On"); EGS_TransportProperty rayl("Rayleigh scattering",&the_xoptions->iraylr); - rayl.addOption("Off"); rayl.addOption("On"); rayl.addOption("custom"); + rayl.addOption("Off"); + rayl.addOption("On"); + rayl.addOption("custom"); EGS_TransportProperty ff_med("ff media names",24,MXMED,&ff_media); EGS_TransportProperty ff_files("ff file names",128,MXMED, &ff_names); EGS_TransportProperty relax("Atomic relaxations",&the_xoptions->iedgfl); - relax.addOption("Off"); relax.addOption("On"); + relax.addOption("Off"); + relax.addOption("On"); EGS_TransportProperty iphter("Photoelectron angular sampling", - &the_xoptions->iphter); - iphter.addOption("Off"); iphter.addOption("On"); + &the_xoptions->iphter); + iphter.addOption("Off"); + iphter.addOption("On"); EGS_TransportProperty spin("Spin effects",&the_xoptions->spin_effects); - spin.addOption("Off"); spin.addOption("On"); + spin.addOption("Off"); + spin.addOption("On"); EGS_TransportProperty trip("Triplet production",&the_xoptions->itriplet); - trip.addOption("Off"); trip.addOption("On"); + trip.addOption("Off"); + trip.addOption("On"); EGS_TransportProperty eii("Electron Impact Ionization",16,the_media->eiixsec); EGS_TransportProperty brem("Brems cross sections",&the_xoptions->ibr_nist); - brem.addOption("BH"); brem.addOption("NIST"); brem.addOption("NRC"); + brem.addOption("BH"); + brem.addOption("NIST"); + brem.addOption("NRC"); EGS_TransportProperty bang("Brems angular sampling",&the_xoptions->ibrdst); - bang.addOption("Simple"); bang.addOption("KM"); + bang.addOption("Simple"); + bang.addOption("KM"); EGS_TransportProperty pair("Pair cross sections",&the_xoptions->pair_nrc); - pair.addOption("BH"); pair.addOption("NRC"); + pair.addOption("BH"); + pair.addOption("NRC"); EGS_TransportProperty pang("Pair angular sampling",&the_xoptions->iprdst); - pang.addOption("Off"); pang.addOption("Simple"); pang.addOption("KM"); - pang.addOption("Uniform"); pang.addOption("Blend"); + pang.addOption("Off"); + pang.addOption("Simple"); + pang.addOption("KM"); + pang.addOption("Uniform"); + pang.addOption("Blend"); EGS_TransportProperty tran("Electron-step algorithm", - &the_etcontrol->transport_algorithm); - tran.addOption("EGSnrc"); tran.addOption("PRESTA-I"); - tran.addOption("PRESTA-II"); tran.addOption("default"); + &the_etcontrol->transport_algorithm); + tran.addOption("EGSnrc"); + tran.addOption("PRESTA-I"); + tran.addOption("PRESTA-II"); + tran.addOption("default"); EGS_TransportProperty bca("Boundary crossing algorithm", - &the_etcontrol->bca_algorithm); - bca.addOption("Exact"); bca.addOption("PRESTA-I"); + &the_etcontrol->bca_algorithm); + bca.addOption("Exact"); + bca.addOption("PRESTA-I"); - if( transportp ) { + if (transportp) { efield.getInput(transportp); bfield.getInput(transportp); estepem.getInput(transportp); @@ -453,27 +553,29 @@ int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { bc.getInput(transportp); radc.getInput(transportp); rayl.getInput(transportp); - if(the_xoptions->iraylr>1){ - ff_med.getInput(transportp); - ff_files.getInput(transportp); - setRayleighData(ff_media,ff_names); + if (the_xoptions->iraylr>1) { + ff_med.getInput(transportp); + ff_files.getInput(transportp); + setRayleighData(ff_media,ff_names); } relax.getInput(transportp); iphter.getInput(transportp); spin.getInput(transportp); trip.getInput(transportp); - eii.getInput(transportp);setEIIData(eii.size()); + eii.getInput(transportp); + setEIIData(eii.size()); brem.getInput(transportp); bang.getInput(transportp); pair.getInput(transportp); pang.getInput(transportp); tran.getInput(transportp); - if( the_etcontrol->transport_algorithm > 1 ) + if (the_etcontrol->transport_algorithm > 1) { the_etcontrol->transport_algorithm = 0; + } bca.getInput(transportp); } - if( do_hatch ) { + if (do_hatch) { egsHatch(); F77_OBJ_(set_elastic_parameter,SET_ELASTIC_PARAMETER)(); @@ -481,14 +583,20 @@ int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { the_bounds->ecut_new = the_bounds->ecut; the_bounds->pcut_new = the_bounds->pcut; - if( nmed_old > 0 ) { - delete [] i_ededx; delete [] i_pdedx; delete [] i_esig; - delete [] i_psig; delete [] i_ebr1; delete [] i_pbr1; + if (nmed_old > 0) { + delete [] i_ededx; + delete [] i_pdedx; + delete [] i_esig; + delete [] i_psig; + delete [] i_ebr1; + delete [] i_pbr1; delete [] i_pbr2; - delete [] i_gmfp; delete [] i_gbr1; delete [] i_gbr2; + delete [] i_gmfp; + delete [] i_gbr1; + delete [] i_gbr2; delete [] i_cohe; } - if( nmed > 0 ) { + if (nmed > 0) { i_ededx = new EGS_Interpolator [nmed]; i_pdedx = new EGS_Interpolator [nmed]; i_esig = new EGS_Interpolator [nmed]; @@ -501,64 +609,106 @@ int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { i_gbr2 = new EGS_Interpolator [nmed]; i_cohe = new EGS_Interpolator [nmed]; i_photonuc = new EGS_Interpolator [nmed]; - for(int imed=0; imedgetEmax() : 0; bool data_ok = true; - for(j=0; jgetMediumName(j),the_thresh->ae[imed], - the_thresh->ap[imed],imed); - if( Emax > the_thresh->ue[imed]-0.511 || - Emax > the_thresh->up[imed] ) { + geometry->getMediumName(j),the_thresh->ae[imed], + the_thresh->ap[imed],imed); + if (Emax > the_thresh->ue[imed]-0.511 || + Emax > the_thresh->up[imed]) { egsInformation(" upper limits (UE=%g UP=%g) not enough for " - "maximum source energy (%g)\n",the_thresh->ue[imed], - the_thresh->up[imed],Emax); + "maximum source energy (%g)\n",the_thresh->ue[imed], + the_thresh->up[imed],Emax); data_ok = false; } } - if( !data_ok ) { delete [] ind; return 3; } + if (!data_ok) { + delete [] ind; + return 3; + } egsInformation("\n\nTransport parameter and cross section options:\n" - "==============================================\n"); + "==============================================\n"); int nc = 50; - if( !isspace(the_media->pxsec[0]) ) pxsec.info(nc); - if( !isspace(the_media->compxsec[0]) ) cxsec.info(nc); - pcut.info(nc); pair.info(nc); pang.info(nc); trip.info(nc); - bc.info(nc); radc.info(nc); rayl.info(nc); relax.info(nc); iphter.info(nc); - photonuc.info(nc);photonucxsec.info(nc); + if (!isspace(the_media->pxsec[0])) { + pxsec.info(nc); + } + if (!isspace(the_media->compxsec[0])) { + cxsec.info(nc); + } + pcut.info(nc); + pair.info(nc); + pang.info(nc); + trip.info(nc); + bc.info(nc); + radc.info(nc); + rayl.info(nc); + relax.info(nc); + iphter.info(nc); + photonuc.info(nc); + photonucxsec.info(nc); egsInformation("\n"); - ecut.info(nc); brem.info(nc); bang.info(nc); spin.info(nc); - eii.info(nc); smax.info(nc); estep.info(nc); ximax.info(nc); - bca.info(nc); skind.info(nc); tran.info(nc); - if(efield.size()==3){ - efield.info(nc); - the_emf->ExIN=efield_v[0];the_emf->EyIN=efield_v[1];the_emf->EzIN=efield_v[2]; + ecut.info(nc); + brem.info(nc); + bang.info(nc); + spin.info(nc); + eii.info(nc); + smax.info(nc); + estep.info(nc); + ximax.info(nc); + bca.info(nc); + skind.info(nc); + tran.info(nc); + if (efield.size()==3) { + efield.info(nc); + the_emf->ExIN=efield_v[0]; + the_emf->EyIN=efield_v[1]; + the_emf->EzIN=efield_v[2]; + } + if (bfield.size()==3) { + bfield.info(nc); + the_emf->BxIN=bfield_v[0]; + the_emf->ByIN=bfield_v[1]; + the_emf->BzIN=bfield_v[2]; } - if(bfield.size()==3){ - bfield.info(nc); - the_emf->BxIN=bfield_v[0];the_emf->ByIN=bfield_v[1];the_emf->BzIN=bfield_v[2]; + if (efield.size()==3 || bfield.size()==3) { + estepem.info(nc); } - if(efield.size()==3 || bfield.size()==3) estepem.info(nc); egsInformation("==============================================\n\n"); @@ -577,19 +727,19 @@ int EGS_AdvancedApplication::helpInit(EGS_Input *transportp, bool do_hatch) { EMH April 6th 2011 **********************************************************************/ void EGS_AdvancedApplication::setRayleighData( - const vector &str_medium, - const vector &str_file ) -{ - the_xoptions->iraylr=1; int i,k; - for(i=0;iff_media[i][k]= str_medium[i][k]; - } + const vector &str_medium, + const vector &str_file) { + the_xoptions->iraylr=1; + int i,k; + for (i=0; iff_media[i][k]= str_medium[i][k]; + } } - for(i=0;iff_file[i][k]=str_file[i][k]; - } + for (i=0; iff_file[i][k]=str_file[i][k]; + } } } @@ -602,34 +752,53 @@ void EGS_AdvancedApplication::setRayleighData( xsections with EGSnrc. EMH April 6th 2011 **********************************************************************/ -void EGS_AdvancedApplication::setEIIData(EGS_I32 len) -{ - string str_eii,off,on; the_xoptions->eii_flag = 1;string ik="ik"; - for (int i=0; ieiixsec[i]); - off+=' '; on+=' '; +void EGS_AdvancedApplication::setEIIData(EGS_I32 len) { + string str_eii,off,on; + the_xoptions->eii_flag = 1; + string ik="ik"; + for (int i=0; ieiixsec[i]); + off+=' '; + on+=' '; + } + off[0]='O'; + off[1]='F'; + off[2]='F'; + on[0]='O'; + on[1]='N'; + if (str_eii == off) { + the_xoptions->eii_flag = 0; + } + else if (str_eii == on) { + strcpy(the_media->eiixsec,ik.c_str()); } - off[0]='O';off[1]='F';off[2]='F'; on[0]='O'; on[1]='N'; - if (str_eii == off) the_xoptions->eii_flag = 0; - else if (str_eii == on) strcpy(the_media->eiixsec,ik.c_str()); } #ifdef GDEBUG -#define MAX_STEP 100000 -EGS_Vector steps_x[MAX_STEP], steps_u[MAX_STEP]; -int steps_ireg[MAX_STEP], steps_inew[MAX_STEP]; -EGS_Float steps_ustepi[MAX_STEP], steps_ustepf[MAX_STEP]; -int steps_n = 0; + #define MAX_STEP 100000 + EGS_Vector steps_x[MAX_STEP], steps_u[MAX_STEP]; + int steps_ireg[MAX_STEP], steps_inew[MAX_STEP]; + EGS_Float steps_ustepi[MAX_STEP], steps_ustepf[MAX_STEP]; + int steps_n = 0; #endif int EGS_AdvancedApplication::shower() { - if( !p.wt ) return 0; + if (!p.wt) { + return 0; + } the_stack->E[0] = (p.q) ? p.E + the_useful->rm : p.E; - the_stack->x[0] = p.x.x; the_stack->y[0] = p.x.y; the_stack->z[0] = p.x.z; - the_stack->u[0] = p.u.x; the_stack->v[0] = p.u.y; the_stack->w[0] = p.u.z; - the_stack->dnear[0] = 0; the_stack->wt[0] = p.wt; - the_stack->ir[0] = p.ir + 2; the_stack->iq[0] = p.q; - the_stack->latch[0] = p.latch; the_stack->np = 1; + the_stack->x[0] = p.x.x; + the_stack->y[0] = p.x.y; + the_stack->z[0] = p.x.z; + the_stack->u[0] = p.u.x; + the_stack->v[0] = p.u.y; + the_stack->w[0] = p.u.z; + the_stack->dnear[0] = 0; + the_stack->wt[0] = p.wt; + the_stack->ir[0] = p.ir + 2; + the_stack->iq[0] = p.q; + the_stack->latch[0] = p.latch; + the_stack->np = 1; #ifdef GDEBUG steps_n = 0; #endif @@ -641,15 +810,17 @@ void EGS_AdvancedApplication::finishRun() { egsFinish(); //egsSetDefaultIOFunctions(); io_flag = 0; - // so that if extra output is being produced somewhere, it does not - // go to fort.6 as it would without this as all fortran units are - // closed after egsFinish(). + // so that if extra output is being produced somewhere, it does not + // go to fort.6 as it would without this as all fortran units are + // closed after egsFinish(). } int EGS_AdvancedApplication::finishSimulation() { int err = EGS_Application::finishSimulation(); egsInformation("finishSimulation(%s) %d\n",app_name.c_str(),err); - if( err <= 0 ) return err; + if (err <= 0) { + return err; + } //egsInformation("\n\n********** I'm last job! **********\n\n"); //return 0; // if err is positive, this is the last job in a parallel run @@ -659,8 +830,10 @@ int EGS_AdvancedApplication::finishSimulation() { // moved to the user code directory and the working directory has been // reset to be the user code directory. We must now reset the // output_file name and re-open units. - output_file = final_output_file; the_egsio->i_parallel = 0; - int flag = 0; egsOpenUnits(&flag); + output_file = final_output_file; + the_egsio->i_parallel = 0; + int flag = 0; + egsOpenUnits(&flag); // The following is necessary because finishRun() was called from // EGS_Application::finishSimulation() and this resets I/O // to stdout and stderr. But if we are here, we are combining @@ -671,12 +844,16 @@ int EGS_AdvancedApplication::finishSimulation() { //egsSetInfoFunction(Fatal,__write_to_fortran_file_and_exit); io_flag = 1; final_job = true; - describeUserCode(); describeSimulation(); + describeUserCode(); + describeSimulation(); err = combineResults(); - if( err ) return err; + if (err) { + return err; + } run->finishSimulation(); - for(int j=0; jreportResults(); + } outputResults(); finishRun(); return 0; @@ -684,19 +861,28 @@ int EGS_AdvancedApplication::finishSimulation() { int EGS_AdvancedApplication::outputData() { int err = EGS_Application::outputData(); - if( err ) return err; - EGS_I32 np, ip; egsGetRNGPointers(&np,&ip); - if( np < 1 ) return 11; - if( np > 10000000 ) { + if (err) { + return err; + } + EGS_I32 np, ip; + egsGetRNGPointers(&np,&ip); + if (np < 1) { + return 11; + } + if (np > 10000000) { egsWarning("EGS_AdvancedApplication::outputData(): egsGetRNGPointers" - " returns a huge number? (%d)\n",np); return 12; + " returns a huge number? (%d)\n",np); + return 12; } EGS_Float *array = new EGS_Float [np]; egsGetRNGArray(array); (*data_out) << " " << np << " " << ip << endl; - for(int j=0; jgood() ? 0 : 13; @@ -704,16 +890,26 @@ int EGS_AdvancedApplication::outputData() { int EGS_AdvancedApplication::readData() { int err = EGS_Application::readData(); - if( err ) return err; - int np, ip; (*data_in) >> np >> ip; - if( np < 1 ) return 11; - if( np > 10000000 ) { + if (err) { + return err; + } + int np, ip; + (*data_in) >> np >> ip; + if (np < 1) { + return 11; + } + if (np > 10000000) { egsWarning("EGS_AdvancedApplication::readData(): got huge size " - "for the mortran random array? (%d)\n",np); return 12; + "for the mortran random array? (%d)\n",np); + return 12; } EGS_Float *array = new EGS_Float [np]; - for(int j=0; j> array[j]; - if( !data_in->good() ) return 13; + for (int j=0; j> array[j]; + } + if (!data_in->good()) { + return 13; + } egsSetRNGState(&ip,array); delete [] array; double ch_steps, all_steps; @@ -724,26 +920,35 @@ int EGS_AdvancedApplication::readData() { int EGS_AdvancedApplication::addState(istream &data) { int err = EGS_Application::addState(data); - if( err ) return err; - int np, ip; data >> np >> ip; - if( np < 1 ) { + if (err) { + return err; + } + int np, ip; + data >> np >> ip; + if (np < 1) { egsWarning("Got np=%d\n",np); return 11; } - if( np > 10000000 ) { + if (np > 10000000) { egsWarning("EGS_AdvancedApplication::addState(): got huge size " - "for the mortran random array? (%d)\n",np); return 12; + "for the mortran random array? (%d)\n",np); + return 12; } EGS_Float *array = new EGS_Float [np]; - for(int j=0; j> array[j]; - if( !data.good() ) return 13; + for (int j=0; j> array[j]; + } + if (!data.good()) { + return 13; + } egsSetRNGState(&ip,array); delete [] array; double ch_steps, all_steps; data >> ch_steps >> all_steps; double ch_steps_old, all_steps_old; egsGetSteps(&ch_steps_old,&all_steps_old); - ch_steps += ch_steps_old; all_steps += all_steps_old; + ch_steps += ch_steps_old; + all_steps += all_steps_old; egsSetSteps(&ch_steps,&all_steps); return data.good() ? 0 : 13; } @@ -758,13 +963,19 @@ EGS_I64 EGS_AdvancedApplication::randomNumbersUsed() const { EGS_I64 nused = EGS_Application::randomNumbersUsed(); EGS_I32 np, ip; egsGetRNGPointers(&np,&ip); - if( ip <= np ) nused -= (np+1-ip); + if (ip <= np) { + nused -= (np+1-ip); + } return nused; } void EGS_AdvancedApplication::appInformation(const char *msg) { - if( !msg ) return; - if( !io_flag ) EGS_Application::appInformation(msg); + if (!msg) { + return; + } + if (!io_flag) { + EGS_Application::appInformation(msg); + } else { int ounit = the_egsio->i_log; F77_OBJ_(egs_write_string,EGS_WRITE_STRING)(&ounit,msg,strlen(msg)); @@ -773,8 +984,12 @@ void EGS_AdvancedApplication::appInformation(const char *msg) { } void EGS_AdvancedApplication::appWarning(const char *msg) { - if( !msg ) return; - if( !io_flag ) EGS_Application::appWarning(msg); + if (!msg) { + return; + } + if (!io_flag) { + EGS_Application::appWarning(msg); + } else { int ounit = the_egsio->i_log; F77_OBJ_(egs_write_string,EGS_WRITE_STRING)(&ounit,msg,strlen(msg)); @@ -783,9 +998,11 @@ void EGS_AdvancedApplication::appWarning(const char *msg) { } void EGS_AdvancedApplication::appFatal(const char *msg) { - if( !io_flag ) EGS_Application::appFatal(msg); + if (!io_flag) { + EGS_Application::appFatal(msg); + } else { - if( msg ) { + if (msg) { int ounit = the_egsio->i_log; F77_OBJ_(egs_write_string,EGS_WRITE_STRING)(&ounit,msg,strlen(msg)); } @@ -794,38 +1011,48 @@ void EGS_AdvancedApplication::appFatal(const char *msg) { } void EGS_AdvancedApplication::getElectronSteps(double &ch_steps, - double &all_steps) const { egsGetSteps(&ch_steps,&all_steps); } + double &all_steps) const { + egsGetSteps(&ch_steps,&all_steps); +} void EGS_AdvancedApplication::startNewParticle() { - if( geometry->hasRhoScaling() ) { + if (geometry->hasRhoScaling()) { int ireg = the_stack->ir[the_stack->np-1] - 2; EGS_Float rho = geometry->getRelativeRho(ireg); - the_useful->rhor = rho; the_useful->rhor_new = rho; + the_useful->rhor = rho; + the_useful->rhor_new = rho; + } + else { + the_useful->rhor = 1; + the_useful->rhor_new = 1; } - else { the_useful->rhor = 1; the_useful->rhor_new = 1; } } void EGS_AdvancedApplication::enterNewRegion() { - if( geometry->hasRhoScaling() ) { + if (geometry->hasRhoScaling()) { int ireg = the_epcont->irnew-2; - if( ireg >= 0 ) { + if (ireg >= 0) { EGS_Float rho = geometry->getRelativeRho(ireg); the_useful->rhor_new = rho; } } - else the_useful->rhor_new = 1; + else { + the_useful->rhor_new = 1; + } } void EGS_AdvancedApplication::saveRNGState() { rndm->saveState(); - int np,ip; egsGetRNGPointers(&np,&ip); - if( n_rng_buffer > 0 ) { - if( np != n_rng_buffer ) egsFatal("EGS_AdvancedApplication::saveRNGState:\n" - " new buffer size (%d) is not the same as previous size(%d) ?\n", - np,n_rng_buffer); + int np,ip; + egsGetRNGPointers(&np,&ip); + if (n_rng_buffer > 0) { + if (np != n_rng_buffer) egsFatal("EGS_AdvancedApplication::saveRNGState:\n" + " new buffer size (%d) is not the same as previous size(%d) ?\n", + np,n_rng_buffer); } else { - rng_buffer = new EGS_Float [np]; n_rng_buffer = np; + rng_buffer = new EGS_Float [np]; + n_rng_buffer = np; } i_rng_buffer = ip; egsGetRNGArray(rng_buffer); @@ -833,56 +1060,65 @@ void EGS_AdvancedApplication::saveRNGState() { void EGS_AdvancedApplication::resetRNGState() { rndm->resetState(); - if( n_rng_buffer > 0 ) egsSetRNGState(&i_rng_buffer,rng_buffer); + if (n_rng_buffer > 0) { + egsSetRNGState(&i_rng_buffer,rng_buffer); + } } //************************************************************ // Utility functions for use with ausgab dose scoring objects //************************************************************ // Returns density for medium ind -EGS_Float EGS_AdvancedApplication::getMediumRho(int ind){ - return the_media->rho[ind]; +EGS_Float EGS_AdvancedApplication::getMediumRho(int ind) { + return the_media->rho[ind]; } // Returns edep -EGS_Float EGS_AdvancedApplication::getEdep(){ - return the_epcont->edep; +EGS_Float EGS_AdvancedApplication::getEdep() { + return the_epcont->edep; } //************************************************************ extern __extc__ void egsHowfar() { CHECK_GET_APPLICATION(app,"egsHowfar()"); - int np = the_stack->np-1; int ireg = the_stack->ir[np]-2; - if( ireg < 0 || the_stack->wt[np] == 0 ) { the_epcont->idisc = 1; return; } - int newmed; EGS_Float tsave = the_epcont->ustep; + int np = the_stack->np-1; + int ireg = the_stack->ir[np]-2; + if (ireg < 0 || the_stack->wt[np] == 0) { + the_epcont->idisc = 1; + return; + } + int newmed; + EGS_Float tsave = the_epcont->ustep; int inew = app->howfar(ireg, - EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]), - EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]), - the_epcont->ustep,&newmed); + EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]), + EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]), + the_epcont->ustep,&newmed); #ifdef GDEBUG - if( steps_n < MAX_STEP ) { + if (steps_n < MAX_STEP) { steps_x[steps_n] = EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]); steps_u[steps_n] = EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]); - steps_ireg[steps_n] = ireg; steps_inew[steps_n] = inew; + steps_ireg[steps_n] = ireg; + steps_inew[steps_n] = inew; steps_ustepi[steps_n] = tsave; steps_ustepf[steps_n++] = the_epcont->ustep; } - if( the_epcont->ustep < -1e-4 ) { + if (the_epcont->ustep < -1e-4) { egsWarning("Negative step: %g\n",the_epcont->ustep); - for(int j=0; jirnew = inew+2; the_useful->medium_new = newmed+1; + if (inew != ireg) { + the_epcont->irnew = inew+2; + the_useful->medium_new = newmed+1; app->enterNewRegion(); - if( inew < 0 ) { + if (inew < 0) { the_epcont->idisc = -1; // i.e. discard after the step. the_useful->medium_new = 0; } @@ -891,9 +1127,10 @@ extern __extc__ void egsHowfar() { extern __extc__ void egsHownear(EGS_Float *tperp) { CHECK_GET_APPLICATION(app,"egsHownear()"); - int np = the_stack->np-1; int ireg = the_stack->ir[np]-2; + int np = the_stack->np-1; + int ireg = the_stack->ir[np]-2; *tperp = app->hownear(ireg,EGS_Vector(the_stack->x[np],the_stack->y[np], - the_stack->z[np])); + the_stack->z[np])); } extern __extc__ void egsFillRandomArray(const EGS_I32 *n, EGS_Float *rarray) { @@ -909,18 +1146,25 @@ extern __extc__ void egsAusgab(EGS_I32 *iarg) { CHECK_GET_APPLICATION(app,"egsAusgab()"); //*iarg = app->ausgab(*iarg); int np = the_stack->np-1; - app->top_p.E = the_stack->E[np]; app->top_p.wt = the_stack->wt[np]; + app->top_p.E = the_stack->E[np]; + app->top_p.wt = the_stack->wt[np]; app->top_p.x = EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]); app->top_p.u = EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]); - app->top_p.q = the_stack->iq[np]; app->top_p.ir = the_stack->ir[np]-2; - app->top_p.latch = the_stack->latch[np]; app->Np = the_stack->np-1; + app->top_p.q = the_stack->iq[np]; + app->top_p.ir = the_stack->ir[np]-2; + app->top_p.latch = the_stack->latch[np]; + app->Np = the_stack->np-1; *iarg = app->userScoring(*iarg); } extern __extc__ void egsStartParticle() { CHECK_GET_APPLICATION(app,"egsStartParticle()"); - int np = the_stack->np - 1; int ir = the_stack->ir[np]-2; - if( ir < 0 ) { the_epcont->idisc = 1; return; } + int np = the_stack->np - 1; + int ir = the_stack->ir[np]-2; + if (ir < 0) { + the_epcont->idisc = 1; + return; + } the_epcont->idisc = 0; the_useful->medium = app->getMedium(ir)+1; //egsInformation("start particle: ir=%d medium=%d\n",ir,the_useful->medium); diff --git a/HEN_HOUSE/egs++/egs_advanced_application.h b/HEN_HOUSE/egs++/egs_advanced_application.h index 6401ed794..8d4d7f0b3 100644 --- a/HEN_HOUSE/egs++/egs_advanced_application.h +++ b/HEN_HOUSE/egs++/egs_advanced_application.h @@ -190,14 +190,14 @@ class APP_EXPORT EGS_AdvancedApplication : public EGS_Application { Set media and corresponding ff file names for custom Rayleigh data. */ - void setRayleighData( const vector &str_medium, - const vector &str_file ); + void setRayleighData(const vector &str_medium, + const vector &str_file); /*! \brief Set EII flag and xsection file name. - The EII input is of a mixed type, i.e., one should be able to turn - this option on/off, but there is also the possibility of using an - arbitrary EII xsection compilation, including the available EII - xsections with EGSnrc. + The EII input is of a mixed type, i.e., one should be able to turn + this option on/off, but there is also the possibility of using an + arbitrary EII xsection compilation, including the available EII + xsections with EGSnrc. */ void setEIIData(EGS_I32 len); diff --git a/HEN_HOUSE/egs++/egs_alias_table.cpp b/HEN_HOUSE/egs++/egs_alias_table.cpp index 8f84c1558..c10ba4097 100644 --- a/HEN_HOUSE/egs++/egs_alias_table.cpp +++ b/HEN_HOUSE/egs++/egs_alias_table.cpp @@ -40,37 +40,55 @@ #include "egs_functions.h" void EGS_AliasTable::clear() { - if( n > 0 ) { - delete [] fi; delete [] xi; delete [] wi; delete [] bin; n = 0; + if (n > 0) { + delete [] fi; + delete [] xi; + delete [] wi; + delete [] bin; + n = 0; } } void EGS_AliasTable::allocate(int N, int Type) { clear(); - n = N; type = Type; xi = new EGS_Float [n]; - if( type == 0 ) { + n = N; + type = Type; + xi = new EGS_Float [n]; + if (type == 0) { np = n; - fi = new EGS_Float [n]; wi = new EGS_Float [n]; bin = new int [n]; + fi = new EGS_Float [n]; + wi = new EGS_Float [n]; + bin = new int [n]; } else { np = n-1; - wi = new EGS_Float [n-1]; bin = new int [n-1]; - if( type == 1 ) fi = new EGS_Float [n-1]; - else fi = new EGS_Float [n]; + wi = new EGS_Float [n-1]; + bin = new int [n-1]; + if (type == 1) { + fi = new EGS_Float [n-1]; + } + else { + fi = new EGS_Float [n]; + } } } void EGS_AliasTable::copy(const EGS_AliasTable &t) { clear(); - if( t.n > 0 ) { + if (t.n > 0) { allocate(t.n,t.type); - for(int j=0; j sum) break; + for (i=0; i sum) { + break; + } } - for(jl=0; jl accu ) { - is_ok = false; xtemp[++j] = x; ftemp[j] = fe; + if (test > accu) { + is_ok = false; + xtemp[++j] = x; + ftemp[j] = fe; } } j++; } - if( is_ok ) break; - xtemp[j] = xi[n-1]; ftemp[j++] = fi[n-1]; + if (is_ok) { + break; + } + xtemp[j] = xi[n-1]; + ftemp[j++] = fi[n-1]; allocate(j,2); - for(i=0; i= nmax ) { error = 1; break; } - delete [] xtemp; delete [] ftemp; + for (i=0; i= nmax) { + error = 1; + break; + } + delete [] xtemp; + delete [] ftemp; } - delete [] xtemp; delete [] ftemp; + delete [] xtemp; + delete [] ftemp; make(); return error; } int EGS_AliasTable::sampleBin(EGS_RandomGenerator *rndm) const { EGS_Float r1 = rndm->getUniform(); - EGS_Float aj = r1*np; int j = (int) aj; aj -= j; - if( aj > wi[j] ) j = bin[j]; + EGS_Float aj = r1*np; + int j = (int) aj; + aj -= j; + if (aj > wi[j]) { + j = bin[j]; + } return j; } EGS_Float EGS_AliasTable::sample(EGS_RandomGenerator *rndm) const { EGS_Float r1 = rndm->getUniform(); - EGS_Float aj = r1*np; int j = (int) aj; aj -= j; - if( aj > wi[j] ) j = bin[j]; - if( !type ) return xi[j]; - EGS_Float x = xi[j]; EGS_Float dx = xi[j+1] - x; + EGS_Float aj = r1*np; + int j = (int) aj; + aj -= j; + if (aj > wi[j]) { + j = bin[j]; + } + if (!type) { + return xi[j]; + } + EGS_Float x = xi[j]; + EGS_Float dx = xi[j+1] - x; EGS_Float r2 = rndm->getUniform(); - if( type == 1 ) return x + dx*r2; + if (type == 1) { + return x + dx*r2; + } EGS_Float res; - if( fi[j] > 0 ) { + if (fi[j] > 0) { EGS_Float a = fi[j+1]/fi[j]-1; - if( fabs(a) < 0.2 ) { - EGS_Float rnno1 = 0.5*(1-r2)*a; res = x + r2*dx*(1+rnno1*(1-r2*a)); + if (fabs(a) < 0.2) { + EGS_Float rnno1 = 0.5*(1-r2)*a; + res = x + r2*dx*(1+rnno1*(1-r2*a)); + } + else { + res = x - dx/a*(1-sqrt(1+r2*a*(2+a))); } - else res = x - dx/a*(1-sqrt(1+r2*a*(2+a))); } - else res = x + dx*sqrt(r2); + else { + res = x + dx*sqrt(r2); + } return res; } EGS_SimpleAliasTable::EGS_SimpleAliasTable(int N, const EGS_Float *f) : n(0) { - if( N < 1 ) return; + if (N < 1) { + return; + } n = N; - wi = new EGS_Float [n]; bins = new int [n]; int i; - double sum = 0; double *fcum = new double [n]; - for(i=0; i n && fcum[jh] > sum ) break; + for (i=0; i n && fcum[jh] > sum) { + break; + } + } + if (fcum[jh_old] < sum && jh_old < jl_old) { + jl = jh_old; } - if( fcum[jh_old] < sum && jh_old < jl_old ) jl = jh_old; else { - for(jl=jl_old; jl n && fcum[jl] < sum ) break; + for (jl=jl_old; jl n && fcum[jl] < sum) { + break; + } } jl_old = jl; } double aux = sum - fcum[jl]; fcum[jh] -= aux; - wi[jl] = fcum[jl]/sum; bins[jl] = jh; + wi[jl] = fcum[jl]/sum; + bins[jl] = jh; //egsInformation("i=%d jh=%d jl=%d w=%g\n",i,jh,jl,wi[jl]); jh_old = jh; //jl_old = jl; } - for(i=0; i n ) { bins[i] = i; wi[i] = 1; } + for (i=0; i n) { + bins[i] = i; + wi[i] = 1; + } //egsInformation("alias table: %d %d %g\n",i,bins[i],wi[i]); } delete [] fcum; } EGS_SimpleAliasTable::~EGS_SimpleAliasTable() { - if( n > 0 ) { delete [] wi; delete [] bins; } + if (n > 0) { + delete [] wi; + delete [] bins; + } } diff --git a/HEN_HOUSE/egs++/egs_alias_table.h b/HEN_HOUSE/egs++/egs_alias_table.h index 7f7d0cd25..6504657ee 100644 --- a/HEN_HOUSE/egs++/egs_alias_table.h +++ b/HEN_HOUSE/egs++/egs_alias_table.h @@ -40,7 +40,7 @@ #include "egs_libconfig.h" #include "egs_rndm.h" -typedef EGS_Float (*EGS_AtFunction)(EGS_Float,void*); +typedef EGS_Float(*EGS_AtFunction)(EGS_Float,void *); /*! \brief A class for sampling random values from a given probability distribution using the alias table technique. @@ -71,7 +71,9 @@ class EGS_EXPORT EGS_AliasTable { EGS_AliasTable() : n(0) {}; /*! \brief Copy constructor. Performs a deep copy */ - EGS_AliasTable(const EGS_AliasTable &t) : n(0) { copy(t); }; + EGS_AliasTable(const EGS_AliasTable &t) : n(0) { + copy(t); + }; /*! \brief Construct an alias table from the tabulated distribution with \a N bins with probabilities \a f at the bins \a x. @@ -88,7 +90,9 @@ class EGS_EXPORT EGS_AliasTable { \f$x_{i+1},f_{i+1}\f$. */ EGS_AliasTable(int N, const EGS_Float *x, const EGS_Float *f, - int Type = 1) : n(0) { initialize(N,x,f,Type); }; + int Type = 1) : n(0) { + initialize(N,x,f,Type); + }; /*! \brief Construct an alias table for sampling values in the interval @@ -102,7 +106,7 @@ class EGS_EXPORT EGS_AliasTable { Internally the alias table will be set to be of type 2. */ EGS_AliasTable(EGS_Float xmin, EGS_Float xmax, EGS_Float accu, int nmax, - EGS_AtFunction func, void *data) : n(0) { + EGS_AtFunction func, void *data) : n(0) { initialize(xmin,xmax,accu,nmax,func,data); }; @@ -111,7 +115,7 @@ class EGS_EXPORT EGS_AliasTable { See \link EGS_AliasTable::EGS_AliasTable(int,const EGS_Float*,const EGS_Float*,int=1) the constructor \endlink with corresponding arguments. */ void initialize(int N, const EGS_Float *x, const EGS_Float *f, - int Type = 1); + int Type = 1); /*! \brief Initialize the alias table @@ -133,10 +137,14 @@ class EGS_EXPORT EGS_AliasTable { /*! \brief Get the average of the probability distribution represented by this alias table object. */ - EGS_Float getAverage() const { return average; }; + EGS_Float getAverage() const { + return average; + }; /*! \brief Get the maximum abscissa of this alias table object. */ - EGS_Float getMaximum() const { return xi[n-1]; }; + EGS_Float getMaximum() const { + return xi[n-1]; + }; private: @@ -189,7 +197,7 @@ class EGS_EXPORT EGS_SimpleAliasTable { Returns a random bin according to the bin probabilities for this alias table */ int sample(EGS_RandomGenerator *rndm) const { - int bin = (int) (rndm->getUniform()*n); + int bin = (int)(rndm->getUniform()*n); return rndm->getUniform() < wi[bin] ? bin : bins[bin]; }; diff --git a/HEN_HOUSE/egs++/egs_application.cpp b/HEN_HOUSE/egs++/egs_application.cpp index 229fe431a..5f32576fa 100644 --- a/HEN_HOUSE/egs++/egs_application.cpp +++ b/HEN_HOUSE/egs++/egs_application.cpp @@ -58,17 +58,17 @@ using namespace std; #ifdef WIN32 -const char fs = 92; -#define F_OK 0 -#define W_OK 2 -#define R_OK 4 -#include -#define EGS_ACCESS ::_access + const char fs = 92; + #define F_OK 0 + #define W_OK 2 + #define R_OK 4 + #include + #define EGS_ACCESS ::_access #else -const char fs = '/'; -#include -#define EGS_ACCESS ::access -#include + const char fs = '/'; + #include + #define EGS_ACCESS ::access + #include #endif static char __egs_app_msg1[] = "EGS_Application::EGS_Application(int,char**):"; @@ -78,11 +78,14 @@ static char __egs_app_msg3[] = "EGS_Application::runSimulation():"; static EGS_LOCAL bool __egs_find_pegsfile(const vector &paths, const string &pegs_file, string &abs_pegs_file) { string pfile = pegs_file; - if( pfile.find(".pegs4dat") == string::npos ) pfile += ".pegs4dat"; - for(unsigned int j=0; jprocessEvent((AusgabCall)iarg); - if( res < 0 ) return res; - if( res > 0 ) early_return = res; + if (res < 0) { + return res; + } + if (res > 0) { + early_return = res; + } + } + if (early_return > 0) { + return early_return; } - if( early_return > 0 ) return early_return; } return ausgab(iarg); } @@ -116,12 +125,19 @@ int EGS_Application::userScoring(int iarg) { void EGS_Application::checkEnvironmentVar(int &argc, char **argv, const char *n1, const char *n2, const char *env, string &var) { char *aux = getenv(env); - if( aux ) var = aux; else var = ""; + if (aux) { + var = aux; + } + else { + var = ""; + } getArgument(argc,argv,n1,n2,var); - if( !var.size() ) egsFatal("%s\n the environment variable %s is not set" - " and it was not passed as argument\n",__egs_app_msg1,env); + if (!var.size()) egsFatal("%s\n the environment variable %s is not set" + " and it was not passed as argument\n",__egs_app_msg1,env); int n = var.size()-1; - if( var[n] != '/' && var[n] != fs ) var += fs; + if (var[n] != '/' && var[n] != fs) { + var += fs; + } } class EGS_LOCAL EGS_GeometryHistory { @@ -132,30 +148,39 @@ class EGS_LOCAL EGS_GeometryHistory { int ireg, inew; Step() {}; Step(int Ireg, int Inew, const EGS_Vector &X, const EGS_Vector &U, - EGS_Float Twant, EGS_Float T) : x(X), u(U), twant(Twant), t(T), + EGS_Float Twant, EGS_Float T) : x(X), u(U), twant(Twant), t(T), ireg(Ireg), inew(Inew) {}; void show() const { egsWarning("old region=%d, position=(%g,%g,%g), " - "direction=(%g,%g,%g) intended step=%g, new region=%d, " - "step=%g\n",ireg,x.x,x.y,x.z,u.x,u.y,u.z,twant,inew,t); + "direction=(%g,%g,%g) intended step=%g, new region=%d, " + "step=%g\n",ireg,x.x,x.y,x.z,u.x,u.y,u.z,twant,inew,t); }; }; EGS_GeometryHistory(int N=2) : steps(new Step [N]), nsize(N), ns(0), - wrap(false) {}; - ~EGS_GeometryHistory() { delete [] steps; }; + wrap(false) {}; + ~EGS_GeometryHistory() { + delete [] steps; + }; void addStep(int ireg, int inew, const EGS_Vector &x, const EGS_Vector &u, EGS_Float twant, EGS_Float t) { steps[ns++] = Step(ireg,inew,x,u,twant,t); - if( ns >= nsize ) { ns = 0; wrap = true; } + if (ns >= nsize) { + ns = 0; + wrap = true; + } }; void reportHistory() const { int nhave = wrap ? nsize : ns; egsWarning("\n************** Last %d geometry steps:\n",nhave); - if( wrap ) { - for(int j=ns; jaddStep(ireg,inew,x,u,twant,t); } @@ -188,20 +213,28 @@ EGS_Application::EGS_Application(int argc, char **argv) : input(0), geometry(0), app_index = n_apps++; - if( !active_egs_application ) active_egs_application = this; - { for(int call=BeforeTransport; call 0 ) { run_dir += input_file; run_dir += '_'; } - else run_dir += "_noinput_"; + if (input_file.size() > 0) { + run_dir += input_file; + run_dir += '_'; + } + else { + run_dir += "_noinput_"; + } run_dir += egsHostName(); // // *** check if there is a PEGS file specified on the command line // is_pegsless= false; - if(!getArgument(argc,argv,"-p","--pegs-file",pegs_file)) is_pegsless= true; - //gsFatal("%s\n no PEGS file specified\n",__egs_app_msg1); + if (!getArgument(argc,argv,"-p","--pegs-file",pegs_file)) { + is_pegsless= true; + } + //gsFatal("%s\n no PEGS file specified\n",__egs_app_msg1); // // *** check if the pegs file exists. // - if( pegs_file.size() > 0 ) { + if (pegs_file.size() > 0) { string pdirs = egsJoinPath("pegs4","data"); - vector pegs_paths; pegs_paths.push_back(""); + vector pegs_paths; + pegs_paths.push_back(""); pegs_paths.push_back(egsJoinPath(egs_home,pdirs)); pegs_paths.push_back(egsJoinPath(hen_house,pdirs)); - if( !__egs_find_pegsfile(pegs_paths,pegs_file,abs_pegs_file) ) + if (!__egs_find_pegsfile(pegs_paths,pegs_file,abs_pegs_file)) egsFatal("%s\n the pegs file %s does not exist or is not " - "readable\n",__egs_app_msg1,pegs_file.c_str()); + "readable\n",__egs_app_msg1,pegs_file.c_str()); } // // *** check if the input file exists. // string ifile; - if( input_file.size() > 0 ) { + if (input_file.size() > 0) { ifile = egsJoinPath(app_dir,input_file); - if( ifile.find(".egsinp") == string::npos ) ifile += ".egsinp"; - if( EGS_ACCESS(ifile.c_str(),R_OK) ) + if (ifile.find(".egsinp") == string::npos) { + ifile += ".egsinp"; + } + if (EGS_ACCESS(ifile.c_str(),R_OK)) egsFatal("%s\n the input file %s does not exist or is not " - "readable\n",__egs_app_msg1,ifile.c_str()); + "readable\n",__egs_app_msg1,ifile.c_str()); } // // *** set the output file // - if( !getArgument(argc,argv,"-o","--output",output_file) ) - output_file = input_file; - if( !output_file.size() ) output_file = "test"; + if (!getArgument(argc,argv,"-o","--output",output_file)) { + output_file = input_file; + } + if (!output_file.size()) { + output_file = "test"; + } // // *** see if a batch run. // batch_run = false; - for(int j=1; j n_parallel ) { + if (i_parallel > n_parallel) { egsWarning("%s\n job number (%d) can not be larger than number" - " of parallel jobs(%d). Turning off parallel option\n", - __egs_app_msg1,i_parallel,n_parallel); - n_parallel = 0; i_parallel = 0; + " of parallel jobs(%d). Turning off parallel option\n", + __egs_app_msg1,i_parallel,n_parallel); + n_parallel = 0; + i_parallel = 0; } } - else if ( have_np || have_ip ) + else if (have_np || have_ip) egsWarning("%s\n to specify a parallel run you need both," - " the -P and -j command line options\n",__egs_app_msg1); + " the -P and -j command line options\n",__egs_app_msg1); // // *** see if user wants simple job control // { - for(int j=1; j 0 && n_parallel > 0 ) { + if (i_parallel > 0 && n_parallel > 0) { batch_run = true; - char buf[1024]; sprintf(buf,"%s_w%d",output_file.c_str(),i_parallel); + char buf[1024]; + sprintf(buf,"%s_w%d",output_file.c_str(),i_parallel); output_file = buf; } @@ -331,19 +383,19 @@ EGS_Application::EGS_Application(int argc, char **argv) : input(0), geometry(0), // *** read the input // input = new EGS_Input; - if( ifile.size() > 0 ) { - if( input->setContentFromFile(ifile.c_str()) ) + if (ifile.size() > 0) { + if (input->setContentFromFile(ifile.c_str())) egsFatal("%s\n error while reading input file %s\n", - __egs_app_msg1,ifile.c_str()); + __egs_app_msg1,ifile.c_str()); } } bool EGS_Application::getArgument(int &argc, char **argv, - const char *name1, const char *name2, string &arg) { + const char *name1, const char *name2, string &arg) { string n1(name1), n2(name2); - for(int j=1; jstoreState(*data_out)) { + return 2; + } + if (!egsStoreI64(*data_out,current_case)) { + return 3; } - if( !run->storeState(*data_out) ) return 2; - if( !egsStoreI64(*data_out,current_case) ) return 3; (*data_out) << endl; - if( !rndm->storeState(*data_out) ) return 4; - if( !source->storeState(*data_out) ) return 5; - for(int j=0; jstoreState(*data_out)) return 6; + if (!rndm->storeState(*data_out)) { + return 4; + } + if (!source->storeState(*data_out)) { + return 5; + } + for (int j=0; jstoreState(*data_out)) { + return 6; + } } return 0; } int EGS_Application::readData() { - if( data_in ) delete data_in; + if (data_in) { + delete data_in; + } string ifile = constructIOFileName(".egsdat",false); /* string ifile = egsJoinPath(app_dir,output_file); ifile += ".egsdat"; */ data_in = new ifstream(ifile.c_str()); - if( !(*data_in) ) { + if (!(*data_in)) { egsWarning("EGS_Application::readData: failed to open %s " - "for reading\n",ifile.c_str()); return 1; + "for reading\n",ifile.c_str()); + return 1; + } + if (!run->setState(*data_in)) { + return 2; + } + if (!egsGetI64(*data_in,current_case)) { + return 3; } - if( !run->setState(*data_in) ) return 2; - if( !egsGetI64(*data_in,current_case) ) return 3; last_case = current_case; - if( !rndm->setState(*data_in) ) return 4; - if( !source->setState(*data_in) ) return 5; - for(int j=0; jsetState(*data_in)) return 6; + if (!rndm->setState(*data_in)) { + return 4; + } + if (!source->setState(*data_in)) { + return 5; + } + for (int j=0; jsetState(*data_in)) { + return 6; + } } return 0; } void EGS_Application::resetCounter() { - last_case = 0; current_case = 0; + last_case = 0; + current_case = 0; run->resetCounter(); rndm->resetCounter(); source->resetCounter(); - for(int j=0; jresetCounter(); } } int EGS_Application::addState(istream &data) { - if( !run->addState(data) ) return 1; - EGS_I64 tmp_case; if( !egsGetI64(data,tmp_case) ) return 2; - current_case += tmp_case; last_case = current_case; - if( !rndm->addState(data) ) return 3; - if( !source->addState(data) ) return 4; - for(int j=0; jaddState(data)) return 5; + if (!run->addState(data)) { + return 1; + } + EGS_I64 tmp_case; + if (!egsGetI64(data,tmp_case)) { + return 2; + } + current_case += tmp_case; + last_case = current_case; + if (!rndm->addState(data)) { + return 3; + } + if (!source->addState(data)) { + return 4; + } + for (int j=0; jaddState(data)) { + return 5; + } return 0; } int EGS_Application::combineResults() { egsInformation( -"\n Suming the following .egsdat files:\n" -"=======================================================================\n"); - char buf[512]; resetCounter(); - EGS_Float last_cpu = 0; EGS_I64 last_ncase = 0; - int ndat = 0; bool ok = true; - for(int j=1; j<500; j++) { + "\n Suming the following .egsdat files:\n" + "=======================================================================\n"); + char buf[512]; + resetCounter(); + EGS_Float last_cpu = 0; + EGS_I64 last_ncase = 0; + int ndat = 0; + bool ok = true; + for (int j=1; j<500; j++) { sprintf(buf,"%s_w%d.egsdat",output_file.c_str(),j); string dfile = egsJoinPath(app_dir,buf); ifstream data(dfile.c_str()); - if( data ) { - int err = addState(data); ++ndat; - if( !err ) { + if (data) { + int err = addState(data); + ++ndat; + if (!err) { EGS_I64 ncase = run->getNdone(); EGS_Float cpu = run->getCPUTime(); egsInformation("%2d %-30s ncase=%-14lld cpu=%-11.2f\n", - ndat,buf,ncase-last_ncase,cpu-last_cpu); - last_ncase = ncase; last_cpu = cpu; + ndat,buf,ncase-last_ncase,cpu-last_cpu); + last_ncase = ncase; + last_cpu = cpu; } else { - ok = false; egsWarning("%2d %-30s error %d\n",ndat,buf,err); + ok = false; + egsWarning("%2d %-30s error %d\n",ndat,buf,err); } } } - if( ndat > 0 ) { + if (ndat > 0) { egsInformation( -"=======================================================================\n"); + "=======================================================================\n"); egsInformation("%40s%-14lld cpu=%-11.2f\n\n","Total ncase=",last_ncase, - last_cpu); + last_cpu); + } + if (ndat > 0) { + return ok ? 0 : -1; + } + else { + return 1; } - if( ndat > 0 ) return ok ? 0 : -1; else return 1; } EGS_I64 EGS_Application::randomNumbersUsed() const { - if( !rndm ) return 0; + if (!rndm) { + return 0; + } return rndm->numbersUsed(); } int EGS_Application::initGeometry() { - if( !input ) return -1; + if (!input) { + return -1; + } //if( geometry ) { delete geometry; geometry = 0; } EGS_BaseGeometry::setActiveGeometryList(app_index); geometry = EGS_BaseGeometry::createGeometry(input); - if( !geometry ) return 1; + if (!geometry) { + return 1; + } geometry->ref(); return 0; } int EGS_Application::initSource() { - if( !input ) return -1; + if (!input) { + return -1; + } //if( source ) { delete source; source = 0; } source = EGS_BaseSource::createSource(input); - if( !source ) return 1; + if (!source) { + return 1; + } source->ref(); return 0; } int EGS_Application::initRunControl() { - if( run ) delete run; - if( simple_run ) run = new EGS_RunControl(this); - else run = EGS_RunControl::getRunControlObject(this); - if( !run ) return 1; + if (run) { + delete run; + } + if (simple_run) { + run = new EGS_RunControl(this); + } + else { + run = EGS_RunControl::getRunControlObject(this); + } + if (!run) { + return 1; + } return 0; } int EGS_Application::initRNG() { - if( rndm ) delete rndm; + if (rndm) { + delete rndm; + } int sequence = 0; - if( n_parallel > 0 && i_parallel > 0 ) sequence = i_parallel - 1; - if( input ) rndm = EGS_RandomGenerator::createRNG(input,sequence); - if( !rndm ) { + if (n_parallel > 0 && i_parallel > 0) { + sequence = i_parallel - 1; + } + if (input) { + rndm = EGS_RandomGenerator::createRNG(input,sequence); + } + if (!rndm) { egsWarning("EGS_Application::initRNG(): using default RNG\n"); rndm = EGS_RandomGenerator::defaultRNG(sequence); } - if( !rndm ) { + if (!rndm) { egsWarning("EGS_Application::initRNG(): got null RNG?\n"); return 1; } @@ -516,43 +644,46 @@ int EGS_Application::initRNG() { int EGS_Application::initSimulation() { //if( !input ) { egsWarning("%s no input\n",__egs_app_msg2); return -1; } egsInformation("In EGS_Application::initSimulation()\n"); - int err; bool ok = true; + int err; + bool ok = true; err = initGeometry(); - if( err ) { + if (err) { egsWarning("\n\n%s geometry initialization failed\n",__egs_app_msg2); ok = false; } err = initSource(); - if( err ) { + if (err) { egsWarning("\n\n%s source initialization failed\n",__egs_app_msg2); ok = false; } err = initRNG(); - if( err ) { + if (err) { egsWarning("\n\n%s RNG initialization failed\n",__egs_app_msg2); ok = false; } err = initRunControl(); - if( err ) { + if (err) { egsWarning("\n\n%s run control initialization failed\n",__egs_app_msg2); ok = false; } - if( !ok ) return 1; + if (!ok) { + return 1; + } err = initEGSnrcBackEnd(); - if( err ) { + if (err) { egsWarning("\n\n%s back-end initialization failed\n",__egs_app_msg2); return 2; } describeUserCode(); err = initCrossSections(); - if( err ) { + if (err) { egsWarning("\n\n%s cross section initialization failed\n",__egs_app_msg2); return 3; } err = initScoring(); - if( err ) { + if (err) { egsWarning("\n\n%s scoring initialization failed with status %d\n", - __egs_app_msg2,err); + __egs_app_msg2,err); return 4; } initAusgabObjects(); @@ -561,82 +692,108 @@ int EGS_Application::initSimulation() { } void EGS_Application::setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun) { - if( source ) source->setSimulationChunk(nstart,nrun); + if (source) { + source->setSimulationChunk(nstart,nrun); + } } void EGS_Application::describeSimulation() { - if( !geometry && !source ) return; + if (!geometry && !source) { + return; + } egsInformation("\n\n"); - if( geometry ) geometry->printInfo(); - if( source ) egsInformation("\n\nThe simulation uses the following source:" - "\n=========================================" - "\n %s\n\n\n",source->getSourceDescription()); - if( rndm ) { rndm->describeRNG(); egsInformation("\n\n"); } - if( a_objects_list.size() > 0 ) { + if (geometry) { + geometry->printInfo(); + } + if (source) egsInformation("\n\nThe simulation uses the following source:" + "\n=========================================" + "\n %s\n\n\n",source->getSourceDescription()); + if (rndm) { + rndm->describeRNG(); + egsInformation("\n\n"); + } + if (a_objects_list.size() > 0) { egsInformation("The following ausgab objects are included in the simulation\n"); egsInformation("===========================================================\n\n"); - for(int j=0; jgetObjectDescription()); + } egsInformation("\n\n"); } } int EGS_Application::runSimulation() { bool ok = true; - if( !geometry ) { - egsWarning("%s no geometry\n",__egs_app_msg3); ok = false; + if (!geometry) { + egsWarning("%s no geometry\n",__egs_app_msg3); + ok = false; + } + if (!source) { + egsWarning("%s no source\n",__egs_app_msg3); + ok = false; } - if( !source ) { - egsWarning("%s no source\n",__egs_app_msg3); ok = false; + if (!rndm) { + egsWarning("%s no RNG\n",__egs_app_msg3); + ok = false; } - if( !rndm ) { - egsWarning("%s no RNG\n",__egs_app_msg3); ok = false; + if (!run) { + egsWarning("%s no run control object\n",__egs_app_msg3); + ok = false; } - if( !run ) { - egsWarning("%s no run control object\n",__egs_app_msg3); ok = false; + if (!ok) { + return 1; } - if( !ok ) return 1; int start_status = run->startSimulation(); - if( start_status ) { - if( start_status < 0 ) - egsWarning("\n%s failed to start the simulation\n\n",__egs_app_msg3); + if (start_status) { + if (start_status < 0) { + egsWarning("\n%s failed to start the simulation\n\n",__egs_app_msg3); + } return start_status; } - EGS_I64 ncase; bool next_chunk = true; + EGS_I64 ncase; + bool next_chunk = true; - while( next_chunk && (ncase = run->getNextChunk()) > 0 ) { + while (next_chunk && (ncase = run->getNextChunk()) > 0) { egsInformation("\nRunning %lld histories\n",ncase); double f,df; - if( run->getCombinedResult(f,df) ) { + if (run->getCombinedResult(f,df)) { char c = '%'; egsInformation(" combined result from this and other parallel" - " runs: %lg +/- %7.3lf%c\n\n",f,df,c); + " runs: %lg +/- %7.3lf%c\n\n",f,df,c); + } + else { + egsInformation("\n"); } - else egsInformation("\n"); int nbatch = run->getNbatch(); EGS_I64 ncase_per_batch = ncase/nbatch; - if( !ncase_per_batch ) { - ncase_per_batch = 1; nbatch = ncase; + if (!ncase_per_batch) { + ncase_per_batch = 1; + nbatch = ncase; } - for(int ibatch=0; ibatchstartBatch(ibatch,ncase_per_batch) ) { + for (int ibatch=0; ibatchstartBatch(ibatch,ncase_per_batch)) { egsInformation(" startBatch() loop termination\n"); - next_chunk = false; break; + next_chunk = false; + break; } - for(EGS_I64 icase=0; icasefinishBatch() ) { + if (!next_chunk) { + break; + } + if (!run->finishBatch()) { egsInformation(" finishBatch() loop termination\n"); - next_chunk = false; break; + next_chunk = false; + break; } } } @@ -646,43 +803,63 @@ int EGS_Application::runSimulation() { } int EGS_Application::simulateSingleShower() { - int ireg; int ntry = 0; last_case = current_case; + int ireg; + int ntry = 0; + last_case = current_case; do { ntry++; - if( ntry > 100000 ) { + if (ntry > 100000) { egsWarning("EGS_Application::simulateSingleShower(): no particle" - " from the source has entered the geometry after 100000" - " attempts\n"); return 1; + " from the source has entered the geometry after 100000" + " attempts\n"); + return 1; } current_case = source->getNextParticle(rndm,p.q,p.latch,p.E,p.wt,p.x,p.u); ireg = geometry->isWhere(p.x); - if( ireg < 0 ) { - EGS_Float t = 1e30; ireg = geometry->howfar(ireg,p.x,p.u,t); - if( ireg >= 0 ) p.x += p.u*t; + if (ireg < 0) { + EGS_Float t = 1e30; + ireg = geometry->howfar(ireg,p.x,p.u,t); + if (ireg >= 0) { + p.x += p.u*t; + } } - } while ( ireg < 0 ); + } + while (ireg < 0); p.ir = ireg; - int err = startNewShower(); if( err ) return err; - err = shower(); if( err ) return err; + int err = startNewShower(); + if (err) { + return err; + } + err = shower(); + if (err) { + return err; + } return finishShower(); } int EGS_Application::startNewShower() { - if( current_case != last_case ) { - for(int j=0; jsetCurrentCase(current_case); + } } return 0; } EGS_Application::~EGS_Application() { - if( rndm ) delete rndm; - if( run ) delete run; - if( input ) delete input; + if (rndm) { + delete rndm; + } + if (run) { + delete run; + } + if (input) { + delete input; + } EGS_Object::deleteObject(source); - if( geometry ) { - if( !geometry->deref() ) { + if (geometry) { + if (!geometry->deref()) { EGS_Application *app = active_egs_application; active_egs_application = this; EGS_BaseGeometry::setActiveGeometryList(app_index); @@ -698,49 +875,67 @@ EGS_Application::~EGS_Application() { delete [] a_objects; } */ - if( a_objects ) delete [] a_objects; - if( ghistory ) delete ghistory; - if( active_egs_application == this ) active_egs_application = 0; + if (a_objects) { + delete [] a_objects; + } + if (ghistory) { + delete ghistory; + } + if (active_egs_application == this) { + active_egs_application = 0; + } } void EGS_Application::addAusgabObject(EGS_AusgabObject *o) { - if( !o ) return; + if (!o) { + return; + } o->setApplication(this); a_objects_list.add(o); //int ncall = 1 + (int)AugerEvent; int ncall = (int)UnknownCall; - if( !a_objects ) a_objects = new EGS_SimpleContainer [ncall]; - for(int call=(int)BeforeTransport; callneedsCall((AusgabCall)call) ) { - a_objects[call].add(o); setAusgabCall((AusgabCall)call,true); + if (!a_objects) { + a_objects = new EGS_SimpleContainer [ncall]; + } + for (int call=(int)BeforeTransport; callneedsCall((AusgabCall)call)) { + a_objects[call].add(o); + setAusgabCall((AusgabCall)call,true); } } } void EGS_Application::initAusgabObjects() { - if( !input ) return; + if (!input) { + return; + } EGS_AusgabObject::createAusgabObjects(input); - for(int i=0; ifinishSimulation(); - if( err < 0 ) return err; + if (err < 0) { + return err; + } } outputResults(); - for(int j=0; jreportResults(); + } - if( data_out ) { - delete data_out; data_out = 0; + if (data_out) { + delete data_out; + data_out = 0; /* -#ifdef WIN32 + #ifdef WIN32 string dfile = egsJoinPath(app_dir,run_dir); dfile = egsJoinPath(dfile,output_file); dfile += ".egsdat"; @@ -750,12 +945,12 @@ int EGS_Application::finishSimulation() { int istat = system(command.c_str()); if( istat ) egsWarning("Failed to move the .egsdat file from the" " working directory\n"); -#endif + #endif */ } finishRun(); run_dir = ""; // i.e. from now on all output will go to the user code - // directory. + // directory. return err; } @@ -784,7 +979,7 @@ void EGS_Application::checkDeviceFull(FILE *stream) { } void EGS_Application::appInformation(const char *msg) { - if(msg) { + if (msg) { fprintf(stdout,"%s",msg); fflush(stdout); checkDeviceFull(stdout); @@ -792,7 +987,7 @@ void EGS_Application::appInformation(const char *msg) { } void EGS_Application::appWarning(const char *msg) { - if(msg) { + if (msg) { fprintf(stderr,"%s",msg); fflush(stderr); checkDeviceFull(stderr); @@ -800,6 +995,9 @@ void EGS_Application::appWarning(const char *msg) { } void EGS_Application::appFatal(const char *msg) { - if(msg) { fprintf(stderr,"%s",msg); fflush(stderr); } + if (msg) { + fprintf(stderr,"%s",msg); + fflush(stderr); + } exit(1); } diff --git a/HEN_HOUSE/egs++/egs_application.h b/HEN_HOUSE/egs++/egs_application.h index 05e13dcb8..3dc3a95e6 100644 --- a/HEN_HOUSE/egs++/egs_application.h +++ b/HEN_HOUSE/egs++/egs_application.h @@ -382,8 +382,11 @@ class EGS_EXPORT EGS_Application { to report intermediate results during a simulation. */ virtual void getCurrentResult(double &sum, double &sum2, double &norm, - double &count) { - sum = 0; sum2 = 0; norm = 1; count = 0; + double &count) { + sum = 0; + sum2 = 0; + norm = 1; + count = 0; }; /*! \brief Analyze the simulation results. @@ -451,19 +454,29 @@ class EGS_EXPORT EGS_Application { /*! \brief Returns a pointer to the EGS_Input object containing the user input to the application found in the input file. */ - EGS_Input *getInput() { return input; }; + EGS_Input *getInput() { + return input; + }; /*! \brief Returns the application name */ - const string &getAppName() const { return app_name; }; + const string &getAppName() const { + return app_name; + }; /*! \brief Returns the \c EGS_HOME directory */ - const string &getEgsHome() const { return egs_home; }; + const string &getEgsHome() const { + return egs_home; + }; /*! \brief Returns the \c HEN_HOUSE directory */ - const string &getHenHouse() const { return hen_house; }; + const string &getHenHouse() const { + return hen_house; + }; /*! \brief Returns the base name of the output file(s) */ - const string &getOutputFile() const { return output_file; }; + const string &getOutputFile() const { + return output_file; + }; /*! \brief Returns the base name of the final output file(s) @@ -473,7 +486,9 @@ class EGS_EXPORT EGS_Application { getOutputFile() returns xxx_wX with xxx indicating the output file name and X the job number. */ - const string &getFinalOutputFile() const { return final_output_file; }; + const string &getFinalOutputFile() const { + return final_output_file; + }; /*! \brief Constructs and returns the name of an input/output file @@ -485,13 +500,19 @@ class EGS_EXPORT EGS_Application { string constructIOFileName(const char *extension, bool with_run_dir) const; /*! \brief Returns the absolute path to the user code directory */ - const string &getAppDir() const { return app_dir; }; + const string &getAppDir() const { + return app_dir; + }; /*! \brief Returns the name of the working directory */ - const string &getRunDir() const { return run_dir; }; + const string &getRunDir() const { + return run_dir; + }; /*! \brief Returns the name of the working directory */ - const string &getWorkDir() const { return run_dir; }; + const string &getWorkDir() const { + return run_dir; + }; /*! \brief Possible calls to the user scoring function ausgab(). */ enum AusgabCall { @@ -520,7 +541,7 @@ class EGS_EXPORT EGS_Application { AfterPhoto = 20, //!< after a photo-absorption event EnteringUphi = 21, //!< the rotation routine was just entered LeavingUphi = 22, //!< about to leave the rotation routine - //!< I consider the above 2 to be obsolete + //!< I consider the above 2 to be obsolete BeforeRayleigh = 23, //!< before coherent scattering AfterRayleigh = 24, //!< after coherent scattering FluorescentEvent = 25, //!< a fluorescent transition just occured @@ -547,7 +568,9 @@ class EGS_EXPORT EGS_Application { there was no job number specified (see getIparallel()) or the job number was greater than the number of parallel jobs. */ - int getNparallel() const { return n_parallel; }; + int getNparallel() const { + return n_parallel; + }; /*! \brief Returns the job number in a parallel run. @@ -555,20 +578,24 @@ class EGS_EXPORT EGS_Application { -j n or --job n and requires that the number of parallel jobs was also specified using -P n. */ - int getIparallel() const { return i_parallel; }; + int getIparallel() const { + return i_parallel; + }; /*! \brief Calculates distance to a boundary along the current direction. This function implements the EGSnrc howfar geometry specification */ inline int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed) { + EGS_Float &t, int *newmed) { geometry->resetErrorFlag(); EGS_Float twant = t; int inew = geometry->howfar(ireg,x,u,t,newmed); storeGeometryStep(ireg,inew,x,u,twant,t); - if( geometry->getLastError() ) reportGeometryError(); + if (geometry->getLastError()) { + reportGeometryError(); + } return inew; //return geometry->howfar(ireg,x,u,t,newmed); @@ -583,7 +610,9 @@ class EGS_EXPORT EGS_Application { }; /*! \brief Returns the medium index in region ireg using C-style indexing.*/ - inline int getMedium(int ireg) { return geometry->medium(ireg); }; + inline int getMedium(int ireg) { + return geometry->medium(ireg); + }; /*! \brief Returns true if \a ireg is a real region, false otherwise @@ -592,8 +621,12 @@ class EGS_EXPORT EGS_Application { regions than actual regions. This method can be used in such cases to check if a region exists. */ - bool isRealRegion(int ireg) { return geometry->isRealRegion(ireg); } - int isWhere(EGS_Vector &r) { return geometry->isWhere(r); } + bool isRealRegion(int ireg) { + return geometry->isRealRegion(ireg); + } + int isWhere(EGS_Vector &r) { + return geometry->isWhere(r); + } /*! \brief User scoring function for accumulation of results and VRT implementation @@ -608,7 +641,9 @@ class EGS_EXPORT EGS_Application { This function should be re-implemented in derived classes to perform the actual scoring of the quantities of interest. */ - virtual int ausgab(int) { return 0; }; + virtual int ausgab(int) { + return 0; + }; /*! \brief Start the transport of a new particle. @@ -699,7 +734,8 @@ class EGS_EXPORT EGS_Application { steps are counted in the mortran back-end. */ virtual void getElectronSteps(double &ch_steps, double &all_steps) const { - ch_steps = 0; all_steps = 0; + ch_steps = 0; + all_steps = 0; }; /*! \brief Add data from a parallel job. @@ -750,7 +786,7 @@ class EGS_EXPORT EGS_Application { /*! \brief Check if a device holding a given stream is full */ - void checkDeviceFull (FILE *); + void checkDeviceFull(FILE *); /*! \brief Finds a command line argument. @@ -762,7 +798,7 @@ class EGS_EXPORT EGS_Application { \sa checkEnvironmentVar() */ static bool getArgument(int &argc, char **argv, - const char *name1, const char *name2, string &arg); + const char *name1, const char *name2, string &arg); /*! \brief Finds a command line argument. @@ -771,7 +807,7 @@ class EGS_EXPORT EGS_Application { variable \a env (if it is defined). */ static void checkEnvironmentVar(int &argc, char **argv, const char *env, - const char *n1, const char *n2, string &var); + const char *n1, const char *n2, string &var); protected: @@ -819,7 +855,9 @@ class EGS_EXPORT EGS_Application { This function is called from within the default implementation of the initSimulation() function. */ - virtual int initCrossSections() { return 0; }; + virtual int initCrossSections() { + return 0; + }; /*! \brief Initialize the scoring of quantities of interest. @@ -828,7 +866,9 @@ class EGS_EXPORT EGS_Application { the user to do all initializations related to the scoring of quantities of interest. */ - virtual int initScoring() { return 0; }; + virtual int initScoring() { + return 0; + }; /*! \brief Construct the run control object. @@ -874,7 +914,9 @@ class EGS_EXPORT EGS_Application { This function is called from within the default implementation of the initSimulation() function. */ - virtual int initEGSnrcBackEnd() { return 0; }; + virtual int initEGSnrcBackEnd() { + return 0; + }; /*! \brief Initialize ausgab objects. @@ -905,7 +947,9 @@ class EGS_EXPORT EGS_Application { the simulateSingleShower() function and its return value is returned as the return value of simulateSingleShower() */ - virtual int finishShower() { return 0; }; + virtual int finishShower() { + return 0; + }; /*! \brief Simulate a single shower. @@ -916,12 +960,14 @@ class EGS_EXPORT EGS_Application { This function is reimplemented in EGS_AdvancedApplication to call the mortran EGSnrc shower subroutine. */ - virtual int shower() { return 0; }; + virtual int shower() { + return 0; + }; virtual void finishRun() { }; void storeGeometryStep(int ireg, int inew, const EGS_Vector &x, - const EGS_Vector &u, EGS_Float twant, EGS_Float t); + const EGS_Vector &u, EGS_Float twant, EGS_Float t); void reportGeometryError(); @@ -994,12 +1040,24 @@ class EGS_EXPORT EGS_Application { //************************************************************ // Utility functions for use with ausgab dose scoring objects //************************************************************ - EGS_Float getFluence(){ return source->getFluence();}; - int getnRegions(){return geometry->regions();}; - int getnMedia(){return geometry->nMedia();}; - const char* getMediumName(int ind){return geometry->getMediumName(ind);}; - virtual EGS_Float getMediumRho(int ind){return -1.0;}; - virtual EGS_Float getEdep(){return 0.0;}; + EGS_Float getFluence() { + return source->getFluence(); + }; + int getnRegions() { + return geometry->regions(); + }; + int getnMedia() { + return geometry->nMedia(); + }; + const char *getMediumName(int ind) { + return geometry->getMediumName(ind); + }; + virtual EGS_Float getMediumRho(int ind) { + return -1.0; + }; + virtual EGS_Float getEdep() { + return 0.0; + }; }; #define APP_MAIN(app_name) \ diff --git a/HEN_HOUSE/egs++/egs_atomic_relaxations.cpp b/HEN_HOUSE/egs++/egs_atomic_relaxations.cpp index bb4a266ef..4ad2969f7 100644 --- a/HEN_HOUSE/egs++/egs_atomic_relaxations.cpp +++ b/HEN_HOUSE/egs++/egs_atomic_relaxations.cpp @@ -103,11 +103,19 @@ class EGS_LOCAL EGS_ShellData { EGS_SimpleAliasTable *table; //!< for sampling transitions EGS_ShellData() : ntrans(0), table(0) {}; - ~EGS_ShellData() { deleteData(); } + ~EGS_ShellData() { + deleteData(); + } void deleteData() { - if( ntrans > 0 ) { delete [] ttypes; ntrans = 0; } - if( table ) { delete table; table = 0; } + if (ntrans > 0) { + delete [] ttypes; + ntrans = 0; + } + if (table) { + delete table; + table = 0; + } }; bool loadData(istream &data); @@ -120,23 +128,32 @@ class EGS_LOCAL EGS_ShellData { bool EGS_ShellData::loadData(istream &data) { deleteData(); - char t; data.read((char *)&t,sizeof(char)); type = t; + char t; + data.read((char *)&t,sizeof(char)); + type = t; data.read((char *)&ntrans,sizeof(short)); data.read((char *)&be,sizeof(float)); //egsInformation("shell is of type %d, has BE=%g and %d transitions\n",type,be,ntrans); - if( data.fail() || ntrans > 10000 ) { - ntrans = 0; return false; + if (data.fail() || ntrans > 10000) { + ntrans = 0; + return false; + } + if (ntrans == 0) { + return true; } - if( ntrans == 0 ) return true; ttypes = new unsigned short [ntrans]; - EGS_Float *tmp = new EGS_Float [ntrans]; float aux; - for(int i=0; i 0 ) delete [] shells; - Z = 0; nshell = 0; shells = 0; + if (nshell > 0) { + delete [] shells; + } + Z = 0; + nshell = 0; + shells = 0; }; }; int EGS_ElementRelaxData::loadData(int iZ, istream &data) { - if( iZ == Z ) return 0; + if (iZ == Z) { + return 0; + } deleteData(); Z = iZ; int pos = 2 + (Z-1)*sizeof(int); data.seekg(pos,ios::beg); data.read((char *)&pos,sizeof(int)); - if( data.fail() ) { + if (data.fail()) { egsWarning("Failed reading position for element %d\n",Z); - Z = 0; return 5; + Z = 0; + return 5; } data.seekg(pos,ios::beg); data.read((char *)&nshell,sizeof(nshell)); - if( data.fail() || nshell < 1 || nshell > 63 ) { + if (data.fail() || nshell < 1 || nshell > 63) { egsWarning("Failed reading number of shells for Z=%d (got %d shells and fail()=%d\n", - Z,nshell,data.fail()); nshell = 0; return 6; + Z,nshell,data.fail()); + nshell = 0; + return 6; } //egsInformation("element %d has %d shells\n",Z,nshell); shells = new EGS_ShellData [nshell]; - for(int j=0; j 0 ) { - for(int j=0; j 0) { + for (int j=0; j nz ) + if (!elements) + if (loadData(Z)) egsFatal("%s: failed to load data for Z=%d\n", + func_name,Z); + if (Z < 1 || Z > nz) egsFatal("%s: Z=%d is outside of initialized range 1...%d\n", - func_name,Z,nz); - if( shell < 0 || shell >= elements[Z-1]->nshell ) + func_name,Z,nz); + if (shell < 0 || shell >= elements[Z-1]->nshell) egsFatal("%s: element %d has %d shells but you are asking for " - "shell %d\n",func_name,Z,elements[Z-1]->nshell,shell); + "shell %d\n",func_name,Z,elements[Z-1]->nshell,shell); }; void relax(int Z, int sh, EGS_Float ecut, EGS_Float pcut, - EGS_RandomGenerator *rndm, double &edep, - EGS_SimpleContainer &particles) { + EGS_RandomGenerator *rndm, double &edep, + EGS_SimpleContainer &particles) { checkData(Z,sh); EGS_Float minE = pcut < ecut ? pcut : ecut; relax(Z,sh,minE,ecut,pcut,rndm,edep,particles); @@ -251,14 +282,18 @@ class EGS_LOCAL EGS_RelaxImplementation { EGS_Float getMaxGammaEnergy(int Z, int shell) { checkData(Z,shell); int ntrans = elements[Z-1]->shells[shell].ntrans; - if( ntrans < 1 ) return 0; + if (ntrans < 1) { + return 0; + } EGS_Float E = elements[Z-1]->shells[shell].be; EGS_Float emax = 0; - for(int j=0; jshells[shell].ttypes[j]; - if( transition < 64 ) { + if (transition < 64) { EGS_Float Egamma = E - elements[Z-1]->shells[transition].be; - if( Egamma > emax ) emax = Egamma; + if (Egamma > emax) { + emax = Egamma; + } } } return emax; @@ -267,51 +302,62 @@ class EGS_LOCAL EGS_RelaxImplementation { EGS_Float getMaxElectronEnergy(int Z, int shell) { checkData(Z,shell); int ntrans = elements[Z-1]->shells[shell].ntrans; - if( ntrans < 1 ) return 0; + if (ntrans < 1) { + return 0; + } EGS_Float E = elements[Z-1]->shells[shell].be; EGS_Float emax = 0; - for(int j=0; jshells[shell].ttypes[j]; - if( transition >= 64 ) { - int sh1 = (transition >> 6); int sh2 = transition - (sh1 << 6); + if (transition >= 64) { + int sh1 = (transition >> 6); + int sh2 = transition - (sh1 << 6); EGS_Float Eelec = E - (elements[Z-1]->shells[sh1].be + elements[Z-1]->shells[sh2].be); - if( Eelec > emax ) emax = Eelec; + if (Eelec > emax) { + emax = Eelec; + } } } return emax; }; void relax(int Z, int sh, EGS_Float minE, EGS_Float ecut, EGS_Float pcut, - EGS_RandomGenerator *rndm, double &edep, - EGS_SimpleContainer &particles) { + EGS_RandomGenerator *rndm, double &edep, + EGS_SimpleContainer &particles) { EGS_Float E = elements[Z-1]->shells[sh].be; //egsInformation("relax(%d,%d): E=%g minE=%g\n",Z,sh,E,minE); - if( E <= minE || elements[Z-1]->shells[sh].ntrans < 1 ) { + if (E <= minE || elements[Z-1]->shells[sh].ntrans < 1) { //egsInformation("relax: terminating\n"); - edep += E; return; + edep += E; + return; } int transition = elements[Z-1]->shells[sh].sample(rndm); //egsInformation("relax: got transition %d\n",transition); - if( transition < 64 ) { + if (transition < 64) { EGS_Float Egamma = E - elements[Z-1]->shells[transition].be; //egsInformation("->flourescence, Egamma=%g\n",Egamma); - if( Egamma > pcut ) { + if (Egamma > pcut) { EGS_RelaxationParticle p(0,Egamma); particles.add(p); } - else edep += Egamma; + else { + edep += Egamma; + } relax(Z,transition,minE,ecut,pcut,rndm,edep,particles); } else { - int sh1 = (transition >> 6); int sh2 = transition - (sh1 << 6); + int sh1 = (transition >> 6); + int sh2 = transition - (sh1 << 6); EGS_Float Eelec = E - elements[Z-1]->shells[sh1].be - elements[Z-1]->shells[sh2].be; //egsInformation("->Auger, sh1=%d sh2=%d E=%g\n",sh1,sh2,Eelec); - if( Eelec > ecut ) { + if (Eelec > ecut) { EGS_RelaxationParticle p(-1,Eelec); particles.add(p); } - else edep += Eelec; + else { + edep += Eelec; + } relax(Z,sh1,minE,ecut,pcut,rndm,edep,particles); relax(Z,sh2,minE,ecut,pcut,rndm,edep,particles); } @@ -327,22 +373,31 @@ int EGS_RelaxImplementation::openDataFile(istream **the_data) { static const char *func_name = "EGS_RelaxImplementation::openDataFile()"; *the_data = 0; ifstream *data = new ifstream(data_file.c_str(),ios::binary); - if( !(*data) ) { + if (!(*data)) { egsWarning("%s: failed to open data file %s\n", - func_name,data_file.c_str()); return 1; + func_name,data_file.c_str()); + return 1; } - short Nz; data->read((char *)&Nz,sizeof(short)); - if( data->fail() || Nz < 1 || Nz > 200 ) { + short Nz; + data->read((char *)&Nz,sizeof(short)); + if (data->fail() || Nz < 1 || Nz > 200) { egsWarning("%s: failed reading first record from %s\n", - func_name,data_file.c_str()); return 2; + func_name,data_file.c_str()); + return 2; } - if( Nz > nz ) { + if (Nz > nz) { EGS_ElementRelaxData **new_elements = new EGS_ElementRelaxData* [Nz]; - if( nz > 0 ) { - for(int j=0; j 0) { + for (int j=0; j nz ) { + if (Z > nz) { egsWarning("%s: called with Z=%d, but I only have data for Z<=%d.\n", - func_name,Z,nz); return 4; + func_name,Z,nz); + return 4; } res = loadData(Z,data); delete the_data; @@ -371,56 +429,80 @@ int EGS_RelaxImplementation::loadData(int Z) { } int EGS_RelaxImplementation::loadData(int Z, istream &data) { - if( elements[Z-1] ) return 0; + if (elements[Z-1]) { + return 0; + } elements[Z-1] = new EGS_ElementRelaxData; return elements[Z-1]->loadData(Z,data); } int EGS_RelaxImplementation::loadData(int Nz, const int *Zarray) { - istream *the_data; int res = openDataFile(&the_data); - if( res || !the_data ) return res; + istream *the_data; + int res = openDataFile(&the_data); + if (res || !the_data) { + return res; + } istream &data = *the_data; - for(int j=0; jgetHenHouse(),"data"); + } else { char *hen_house = getenv("HEN_HOUSE"); - if( !hen_house ) { + if (!hen_house) { egsWarning("EGS_AtomicRelaxations::EGS_AtomicRelaxations: " - "no active application and HEN_HOUSE not defined.\n" - " assuming local directory for relax data\n"); + "no active application and HEN_HOUSE not defined.\n" + " assuming local directory for relax data\n"); path = "./"; } - else path = egsJoinPath(hen_house,"data"); + else { + path = egsJoinPath(hen_house,"data"); + } } - } else path = data_path; + } + else { + path = data_path; + } p = new EGS_RelaxImplementation(path.c_str()); } -EGS_AtomicRelaxations::~EGS_AtomicRelaxations() { delete p; } +EGS_AtomicRelaxations::~EGS_AtomicRelaxations() { + delete p; +} -int EGS_AtomicRelaxations::loadData(int Z) { return p->loadData(Z); } +int EGS_AtomicRelaxations::loadData(int Z) { + return p->loadData(Z); +} int EGS_AtomicRelaxations::loadData(int nz, const int *Zarray) { return p->loadData(nz,Zarray); @@ -431,8 +513,8 @@ int EGS_AtomicRelaxations::loadAllData() { } void EGS_AtomicRelaxations::relax(int Z, int sh, EGS_Float ecut, EGS_Float pcut, - EGS_RandomGenerator *rndm, double &edep, - EGS_SimpleContainer &particles) { + EGS_RandomGenerator *rndm, double &edep, + EGS_SimpleContainer &particles) { p->relax(Z,sh,ecut,pcut,rndm,edep,particles); } diff --git a/HEN_HOUSE/egs++/egs_ausgab_object.cpp b/HEN_HOUSE/egs++/egs_ausgab_object.cpp index b8203666f..a162ff138 100644 --- a/HEN_HOUSE/egs++/egs_ausgab_object.cpp +++ b/HEN_HOUSE/egs++/egs_ausgab_object.cpp @@ -45,23 +45,27 @@ ausgab_object_creator(string("egs++/dso/")+CONFIG_NAME,"EGS_AusgabObject"); void EGS_AusgabObject::createAusgabObjects(EGS_Input *i) { ausgab_object_creator.createObjects(i,"ausgab object definition", - "ausgab object","__no__key__","createAusgabObject",true); + "ausgab object","__no__key__","createAusgabObject",true); } -EGS_AusgabObject* EGS_AusgabObject::getAusgabObject(const string &Name) { +EGS_AusgabObject *EGS_AusgabObject::getAusgabObject(const string &Name) { EGS_Object *o = ausgab_object_creator.getObject(Name); - if( !o ) return 0; + if (!o) { + return 0; + } EGS_AusgabObject *s = dynamic_cast(o); - if( s ) return s; + if (s) { + return s; + } egsWarning("EGS_AusgabObject::getAusgabObject(): dynamic cast failed?\n" - " Object named %s is of type %s. Trying simple cast\n", - Name.c_str(),o->getObjectType().c_str()); + " Object named %s is of type %s. Trying simple cast\n", + Name.c_str(),o->getObjectType().c_str()); return (EGS_AusgabObject *)o; } void EGS_AusgabObject::addKnownAusgabObject(EGS_AusgabObject *o) { - if(o) egsInformation("Adding known ausgab object of type %s\n", - o->getObjectType().c_str()); + if (o) egsInformation("Adding known ausgab object of type %s\n", + o->getObjectType().c_str()); ausgab_object_creator.addKnownObject(o); } @@ -69,7 +73,10 @@ void EGS_AusgabObject::addKnownTypeId(const char *tid) { ausgab_object_creator.addKnownTypeId(tid); } -int EGS_AusgabObject::nObjects() { return ausgab_object_creator.nObjects(); } +int EGS_AusgabObject::nObjects() { + return ausgab_object_creator.nObjects(); +} -EGS_AusgabObject* EGS_AusgabObject::getObject(int j) { - return (EGS_AusgabObject*) ausgab_object_creator.getObject(j); } +EGS_AusgabObject *EGS_AusgabObject::getObject(int j) { + return (EGS_AusgabObject *) ausgab_object_creator.getObject(j); +} diff --git a/HEN_HOUSE/egs++/egs_ausgab_object.h b/HEN_HOUSE/egs++/egs_ausgab_object.h index ca1aca04e..97cb9be6c 100644 --- a/HEN_HOUSE/egs++/egs_ausgab_object.h +++ b/HEN_HOUSE/egs++/egs_ausgab_object.h @@ -94,10 +94,14 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * Derived classes should re-implement this function to return \a true * for ausgab calls that are of interest to them. */ - virtual bool needsCall(EGS_Application::AusgabCall iarg) const { return false; }; + virtual bool needsCall(EGS_Application::AusgabCall iarg) const { + return false; + }; /*! \brief Set the application this object belongs to */ - virtual void setApplication(EGS_Application *App) { app = App; }; + virtual void setApplication(EGS_Application *App) { + app = App; + }; /*! \brief Set the current event */ virtual void setCurrentCase(EGS_I64 ncase) {}; @@ -107,7 +111,9 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * Derived classes should set #description to a short * string describing the ausgab object. */ - const char *getObjectDescription() const { return description.c_str(); }; + const char *getObjectDescription() const { + return description.c_str(); + }; /*! \brief Store the source state into the stream \a data_out. * @@ -117,7 +123,9 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * calculations. Should return \c true on success, \c false on failure. * \sa setState(), addState(), resetCounter(). */ - virtual bool storeState(ostream &data_out) const { return true; }; + virtual bool storeState(ostream &data_out) const { + return true; + }; /*! \brief Set the ausgab object state based on data from the stream \a data_in. * @@ -128,7 +136,9 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * * \sa addState(), storeState(), resetCounter() */ - virtual bool setState(istream &data_in) { return true; }; + virtual bool setState(istream &data_in) { + return true; + }; /*! \brief Add data from the stream \a data_in to the ausgab object state. * @@ -138,7 +148,9 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * * \sa storeState(), setState(), resetCounter(). */ - virtual bool addState(istream &data_in) { return true; }; + virtual bool addState(istream &data_in) { + return true; + }; /*! \brief Reset the ausgab object state. * @@ -159,7 +171,7 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * accumulated during the simulation. * */ - virtual void reportResults() {}; + virtual void reportResults() {}; /*! \brief Create ausgab objects from the information pointed to by \a input. * @@ -199,23 +211,23 @@ class EGS_EXPORT EGS_AusgabObject : public EGS_Object { * application can define its own ausgab objects (in addition to * the ausgab objects provided by egspp) and use them. */ - static void addKnownAusgabObject(EGS_AusgabObject *o); - - /*! \brief Add a known ausgab object typeid to the ausgab object factory. - * - * For whatever reason dynamic_cast to EGS_AusgabObject* from EGS_Object* - * fails when an application is made into a shared library and - * dynamically loads an ausgab object DSO. I'm therefore adding this method - * so that ausgab object classes can add their typeid to allow for an additional - * check in such cases. - */ - static void addKnownTypeId(const char *name); - - /*! \brief Returns the number of ausgab objects in the internal list */ - static int nObjects(); - - /*! \brief Returns the j'th ausgab object in the internal list */ - static EGS_AusgabObject* getObject(int j); + static void addKnownAusgabObject(EGS_AusgabObject *o); + + /*! \brief Add a known ausgab object typeid to the ausgab object factory. + * + * For whatever reason dynamic_cast to EGS_AusgabObject* from EGS_Object* + * fails when an application is made into a shared library and + * dynamically loads an ausgab object DSO. I'm therefore adding this method + * so that ausgab object classes can add their typeid to allow for an additional + * check in such cases. + */ + static void addKnownTypeId(const char *name); + + /*! \brief Returns the number of ausgab objects in the internal list */ + static int nObjects(); + + /*! \brief Returns the j'th ausgab object in the internal list */ + static EGS_AusgabObject *getObject(int j); protected: diff --git a/HEN_HOUSE/egs++/egs_base_geometry.cpp b/HEN_HOUSE/egs++/egs_base_geometry.cpp index 9dac362c1..a9e083dee 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.cpp +++ b/HEN_HOUSE/egs++/egs_base_geometry.cpp @@ -49,7 +49,7 @@ using namespace std; -typedef EGS_BaseGeometry* (*EGS_GeometryCreationFunction)(EGS_Input *); +typedef EGS_BaseGeometry *(*EGS_GeometryCreationFunction)(EGS_Input *); #ifndef SKIP_DOXYGEN /*! \brief This class implements functionality related to the dynamic @@ -82,42 +82,60 @@ class EGS_LOCAL EGS_GeometryPrivate { void setUp() { char *hhouse = getenv("HEN_HOUSE"); - if( !hhouse ) + if (!hhouse) { egsFatal("Environment variable HEN_HOUSE must be defined\n"); + } dso_path = hhouse; #if defined WIN32 && !defined CYGWIN char c = '\\'; #else char c = '/'; #endif - if( dso_path[dso_path.size()-1] != c ) dso_path += c; + if (dso_path[dso_path.size()-1] != c) { + dso_path += c; + } //dso_path += "geometry"; dso_path += c; - dso_path += "egs++"; dso_path += c; - dso_path += "dso"; dso_path += c; + dso_path += "egs++"; + dso_path += c; + dso_path += "dso"; + dso_path += c; dso_path += CONFIG_NAME; }; ~EGS_GeometryPrivate() { //egsInformation("Destructing EGS_GeometryPrivate at 0x%x, " // "ntot=%d nnow=%d\n",this,ntot,nnow); - if( !ntot ) return; + if (!ntot) { + return; + } clearGeometries(); delete [] geoms; //egsInformation("Deleting geometry libs\n"); - { for(unsigned int j=0; j 0 ) { - if( geoms[j]->deref() == -1 ) delete geoms[j]; - else geoms[j++]->ref(); - if( j >= nnow && nnow ) { - j = 0; ++iloop; - if( iloop > 20 ) egsWarning("~EGS_GeometryPrivate(): failed " - "to delete all geometries after 20 loops!\n"); + while (nnow > 0) { + if (geoms[j]->deref() == -1) { + delete geoms[j]; + } + else { + geoms[j++]->ref(); + } + if (j >= nnow && nnow) { + j = 0; + ++iloop; + if (iloop > 20) egsWarning("~EGS_GeometryPrivate(): failed " + "to delete all geometries after 20 loops!\n"); break; } } @@ -126,49 +144,76 @@ class EGS_LOCAL EGS_GeometryPrivate { void grow(int ngrow) { ntot += ngrow; EGS_BaseGeometry **tmp = new EGS_BaseGeometry* [ntot]; - for(int j=0; jgetName() == g->getName() ) return -1; - if( nnow >= ntot ) grow(10); - geoms[nnow++] = g; return nnow-1; + if (!g) { + return -1; + } + for (int j=0; jgetName() == g->getName()) { + return -1; + } + if (nnow >= ntot) { + grow(10); + } + geoms[nnow++] = g; + return nnow-1; }; void removeGeometry(EGS_BaseGeometry *g) { - for(int j=0; jgetName() == name ) return geoms[j]; + for (int j=0; jgetName() == name) { + return geoms[j]; + } return 0; }; int addMedium(const string &Name) { - if( EGS_Input::compare(Name,"vacuum") ) return -1; - for(unsigned int j=0; j media.size()-1 ) return 0; + if (ind < 0 || ind > media.size()-1) { + return 0; + } return media[ind].c_str(); }; @@ -183,23 +228,34 @@ class EGS_LOCAL EGS_PrivateGeometryLists { }; ~EGS_PrivateGeometryLists() { //egsInformation("Deleting geometry lists\n"); - if( ntot > 0 ) { - for(int j=0; j 0) { + for (int j=0; j= ntot ) { + if (!l) { + return; + } + if (nnow >= ntot) { EGS_GeometryPrivate **tmp = new EGS_GeometryPrivate* [ntot+10]; - for(int j=0; j 0 ) delete [] lists; - lists = tmp; ntot += 10; + for (int j=0; j 0) { + delete [] lists; + } + lists = tmp; + ntot += 10; } lists[nnow++] = l; }; @@ -219,59 +275,63 @@ static char buf_unique[32]; int EGS_BaseGeometry::error_flag = 0; #ifdef SINGLE -EGS_Float EGS_BaseGeometry::epsilon = 1e-5; + EGS_Float EGS_BaseGeometry::epsilon = 1e-5; #else -EGS_Float EGS_BaseGeometry::epsilon = 1e-7; + EGS_Float EGS_BaseGeometry::epsilon = 1e-7; #endif #ifndef SKIP_DOXYGEN EGS_BaseGeometry *EGS_GeometryPrivate::createSingleGeometry(EGS_Input *i) { string libname; - if( !i ) { + if (!i) { egsWarning("createSingleGeometry: null input?\n"); return 0; } int error = i->getInput(EGS_GeometryPrivate::libkey,libname); - if( error ) { + if (error) { egsWarning("createSingleGeometry: input item %s does not define the" - " geometry library\n",i->name()); + " geometry library\n",i->name()); return 0; } EGS_Library *lib = 0; - for(unsigned int j=0; jlibraryName() ) { - lib = glibs[j]; break; + for (unsigned int j=0; jlibraryName()) { + lib = glibs[j]; + break; } } - if( !lib ) { - lib = new EGS_Library(libname.c_str(),dso_path.c_str()); lib->load(); - if( !lib->isLoaded() ) { + if (!lib) { + lib = new EGS_Library(libname.c_str(),dso_path.c_str()); + lib->load(); + if (!lib->isLoaded()) { egsWarning("createSingleGeometry: Failed to load library '%s' from" - " %s\n",libname.c_str(),dso_path.c_str()); + " %s\n",libname.c_str(),dso_path.c_str()); return 0; } glibs.push_back(lib); } EGS_GeometryCreationFunction gcreate = (EGS_GeometryCreationFunction) - lib->resolve(EGS_GeometryPrivate::create_key.c_str()); - if( !gcreate ) { + lib->resolve(EGS_GeometryPrivate::create_key.c_str()); + if (!gcreate) { egsWarning("createSingleGeometry: failed to resolve the %s function\n" - " in geometry library %s\n", - EGS_GeometryPrivate::create_key.c_str(),lib->libraryName()); + " in geometry library %s\n", + EGS_GeometryPrivate::create_key.c_str(),lib->libraryName()); return 0; } EGS_BaseGeometry *g = gcreate(i); - if( !g ) { + if (!g) { egsWarning("createSingleGeometry: got null geometry\n"); egsWarning(" library: %s\n",lib->libraryName()); - egsWarning(" input:\n"); i->print(4,cerr); + egsWarning(" input:\n"); + i->print(4,cerr); return 0; } - if( !addGeometry(g) ) { + if (!addGeometry(g)) { egsWarning("createSingleGeometry: failed to add the geometry %s\n" - " to the list of geometries. This implies that a geometry with" - " this name already exists\n",g->getName().c_str()); - delete g; return 0; + " to the list of geometries. This implies that a geometry with" + " this name already exists\n",g->getName().c_str()); + delete g; + return 0; } return g; @@ -283,12 +343,20 @@ static EGS_LOCAL EGS_PrivateGeometryLists egs_geometries; EGS_Float EGS_BaseGeometry::howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u) { - if( ireg < 0 ) return 0; - EGS_Vector xx(x); EGS_Float ttot = 0; - while(1) { - EGS_Float t = 1e30; int inew = howfar(ireg,xx,u,t); - ttot += t; if( inew < 0 ) break; - xx += u*t; ireg = inew; + if (ireg < 0) { + return 0; + } + EGS_Vector xx(x); + EGS_Float ttot = 0; + while (1) { + EGS_Float t = 1e30; + int inew = howfar(ireg,xx,u,t); + ttot += t; + if (inew < 0) { + break; + } + xx += u*t; + ireg = inew; } return ttot; } @@ -297,9 +365,11 @@ void EGS_BaseGeometry::setActiveGeometryList(int list) { int n = egs_geometries.size(); //egsInformation("EGS_BaseGeometry::setActiveGeometryList: size=%d list=%d\n", // n,list); - for(int j=n; j<=list; j++) + for (int j=n; j<=list; j++) //egs_geometries.push_back(EGS_GeometryPrivate()); + { egs_geometries.addList(new EGS_GeometryPrivate); + } active_glist = list; } @@ -318,18 +388,27 @@ extern "C" void __list_geometries() { EGS_BaseGeometry::EGS_BaseGeometry(const string &Name) : nreg(0), name(Name), med(-1), region_media(0), nref(0), debug(false), is_convex(true), has_rho_scaling(false), rhor(0), bproperty(0), bp_array(0) { - if( !egs_geometries.size() ) + if (!egs_geometries.size()) { egs_geometries.addList(new EGS_GeometryPrivate); - if( !name.size() ) name = getUniqueName(); - if( egs_geometries[active_glist].addGeometry(this) < 0 ) + } + if (!name.size()) { + name = getUniqueName(); + } + if (egs_geometries[active_glist].addGeometry(this) < 0) egsFatal("EGS_BaseGeometry::EGS_BaseGeometry:\n" - " a geometry with name %s alread exists\n",name.c_str()); + " a geometry with name %s alread exists\n",name.c_str()); } EGS_BaseGeometry::~EGS_BaseGeometry() { - if( region_media ) delete [] region_media; - if( rhor && has_rho_scaling ) delete [] rhor; - if( bp_array ) delete [] bp_array; + if (region_media) { + delete [] region_media; + } + if (rhor && has_rho_scaling) { + delete [] rhor; + } + if (bp_array) { + delete [] bp_array; + } //egsInformation("Deleting geometry at 0x%x, list=%d\n",this,active_glist); egs_geometries[active_glist].removeGeometry(this); } @@ -344,8 +423,10 @@ EGS_BaseGeometry *EGS_BaseGeometry::getGeometry(const string &Name) { void EGS_BaseGeometry::setMedium(const string &Name) { med = egs_geometries[active_glist].addMedium(Name); - if( region_media ) - for(int j=0; j nreg-1 ) iend = nreg-1; - if( !region_media ) { + if (nreg <= 1) { + med = imed; + return; + } + if (delta <= 0) { + return; + } + if (istart < 0) { + istart = 0; + } + if (iend > nreg-1) { + iend = nreg-1; + } + if (!region_media) { region_media = new short [nreg]; - for(int j=0; jisA(egs_geometries[active_glist].geom_delimeter) ) { + EGS_Input *ginput = input; + bool delete_it = false; + if (!input->isA(egs_geometries[active_glist].geom_delimeter)) { ginput = input->takeInputItem(egs_geometries[active_glist].geom_delimeter); delete_it = true; } - if( !ginput ) { + if (!ginput) { egsWarning("EGS_BaseGeometry::createGeometry: no geometry specification" - " in this input\n"); + " in this input\n"); return 0; } - EGS_Input *ij; bool error = false; - while( (ij = ginput->takeInputItem("geometry")) != 0 ) { + EGS_Input *ij; + bool error = false; + while ((ij = ginput->takeInputItem("geometry")) != 0) { EGS_BaseGeometry *g = egs_geometries[active_glist].createSingleGeometry(ij); - if( !g ) error = true; + if (!g) { + error = true; + } delete ij; } - if( error ) { + if (error) { egsFatal("EGS_BaseGeometry::createGeometry: errors during geometry" - " definition\n"); return 0; + " definition\n"); + return 0; } string sim_geom; int err = ginput->getInput("simulation geometry",sim_geom); - if( err ) { + if (err) { egsWarning("EGS_BaseGeometry::createGeometry: missing/wrong keyword" - " 'simulation geometry'\n"); + " 'simulation geometry'\n"); return 0; } EGS_BaseGeometry *g = egs_geometries[active_glist].getGeometry(sim_geom); - if( !g ) egsWarning("EGS_BaseGeometry::createGeometry: a geometry with " - "the name %s does not exist\n",sim_geom.c_str()); - if( delete_it ) delete ginput; + if (!g) egsWarning("EGS_BaseGeometry::createGeometry: a geometry with " + "the name %s does not exist\n",sim_geom.c_str()); + if (delete_it) { + delete ginput; + } return g; } string EGS_BaseGeometry::getUniqueName() { sprintf(buf_unique,"geometry%d",egs_geometries[active_glist].nnow); - string result(buf_unique); return result; + string result(buf_unique); + return result; } void EGS_BaseGeometry::setName(EGS_Input *i) { int err = i->getInput("name",name); - if( err ) name = getUniqueName(); - EGS_Input *inp; int irep=0; - while( (inp = i->takeInputItem("replica")) ) { - string typ; int ncopy; + if (err) { + name = getUniqueName(); + } + EGS_Input *inp; + int irep=0; + while ((inp = i->takeInputItem("replica"))) { + string typ; + int ncopy; vector trans, trans_o; vector rot_axis; EGS_Float rot_angle, rot_angle_o; @@ -440,55 +548,61 @@ void EGS_BaseGeometry::setName(EGS_Input *i) { int err4 = inp->getInput("rotation axis",rot_axis); int err5 = inp->getInput("rotation delta",rot_angle); int err5a = inp->getInput("first rotation",rot_angle_o); - bool do_it = true; int ttype; - if( err1 || err2 ) { - if( err1 ) egsWarning("geometry replication: 'type' not defined ->" - " ignoring input\n"); - if( err2 ) egsWarning("geometry replication: 'number of copies' " - "not defined -> ignoring input\n"); + bool do_it = true; + int ttype; + if (err1 || err2) { + if (err1) egsWarning("geometry replication: 'type' not defined ->" + " ignoring input\n"); + if (err2) egsWarning("geometry replication: 'number of copies' " + "not defined -> ignoring input\n"); do_it = false; } else { - if( ncopy < 1 ) { + if (ncopy < 1) { egsWarning("geometry replication: %d copies?\n",ncopy); do_it = false; } - if( typ == "line" ) { - if( trans.size() != 3 ) { + if (typ == "line") { + if (trans.size() != 3) { egsWarning("geometry replication: got %d inputs for " - "'translation', need 3\n",trans.size()); + "'translation', need 3\n",trans.size()); do_it = false; } else { - if( err3a ) { - trans_o.push_back(0); trans_o.push_back(0); + if (err3a) { + trans_o.push_back(0); + trans_o.push_back(0); trans_o.push_back(0); } } ttype = 0; } - else if( typ == "rotation" ) { - if( rot_axis.size() != 3 ) { + else if (typ == "rotation") { + if (rot_axis.size() != 3) { egsWarning("geometry replication: got %d inputs for " - "'rotation axis', need 3\n",rot_axis.size()); + "'rotation axis', need 3\n",rot_axis.size()); do_it = false; } - if( err4 ) { + if (err4) { egsWarning("geometry replication: missing 'rotation delta'" - " input\n"); + " input\n"); do_it = false; } - if( err5a ) rot_angle_o = 0; + if (err5a) { + rot_angle_o = 0; + } ttype = 1; } else { egsWarning("geometry replication: unknown replica type %s\n", - typ.c_str()); do_it = false; + typ.c_str()); + do_it = false; } } - if( do_it ) { - ++irep; char buf[1024]; - for(int icopy=1; icopy<=ncopy; icopy++) { + if (do_it) { + ++irep; + char buf[1024]; + for (int icopy=1; icopy<=ncopy; icopy++) { //string content(":start geometry:\n"); string content; content += " library = egs_gtransformed\n"; @@ -497,23 +611,24 @@ void EGS_BaseGeometry::setName(EGS_Input *i) { sprintf(buf," my geometry = %s\n",name.c_str()); content += buf; content += " :start transformation:\n"; - if( ttype == 0 ) + if (ttype == 0) sprintf(buf," translation = %g %g %g\n", trans_o[0]+trans[0]*icopy, trans_o[1]+trans[1]*icopy, trans_o[2]+trans[2]*icopy); else sprintf(buf," rotation = %g %g %g %g\n", - rot_axis[0],rot_axis[1],rot_axis[2], - rot_angle_o+rot_angle*icopy); + rot_axis[0],rot_axis[1],rot_axis[2], + rot_angle_o+rot_angle*icopy); content += buf; content += " :stop transformation:\n"; //content += ":stop geometry:\n"; - EGS_Input aux; aux.setContentFromString(content); + EGS_Input aux; + aux.setContentFromString(content); EGS_BaseGeometry *g = EGS_BaseGeometry::createSingleGeometry(&aux); - if( !g ) egsWarning("geometry replication: failed to create" - " replica %d of %s\n",icopy,name.c_str()); + if (!g) egsWarning("geometry replication: failed to create" + " replica %d of %s\n",icopy,name.c_str()); //else egsInformation("geometry replication: created replica" // " %s\n",g->getName().c_str()); } @@ -530,88 +645,121 @@ void EGS_BaseGeometry::printInfo() const { void EGS_BaseGeometry::describeGeometries() { egsInformation("\nThe following geometries are defined:\n\n"); - for(int j=0; jprintInfo(); + } } void EGS_BaseGeometry::setMedia(EGS_Input *inp) { - EGS_Input *input = inp; bool delete_it = false; - if( !input->isA("media input") ) { + EGS_Input *input = inp; + bool delete_it = false; + if (!input->isA("media input")) { input = inp->takeInputItem("media input"); - if( !input ) return; + if (!input) { + return; + } // i.e., if there is no media related input for this geometry, // we don't warn as we assume that media will be set from the outside delete_it = true; } vector media_names; int err = input->getInput("media",media_names); - int *med_ind = 0; int nmed = media_names.size(); - if( !err && nmed > 0 ) { + int *med_ind = 0; + int nmed = media_names.size(); + if (!err && nmed > 0) { med_ind = new int [nmed]; - for(int j=0; jtakeInputItem("set medium")) ) { + EGS_Input *i; + med = mind[0]; + while ((i = input->takeInputItem("set medium"))) { vector inp; int err = i->getInput("set medium",inp); delete i; - if( !err ) { + if (!err) { //if( inp.size() == 2 ) setMedium(inp[0],inp[0]+1,mind[inp[1]]); - if( inp.size() == 2 ) setMedium(inp[0],inp[0],mind[inp[1]]); - else if( inp.size() == 3 ) setMedium(inp[0],inp[1],mind[inp[2]]); - else if( inp.size() == 4 ) setMedium(inp[0],inp[1],mind[inp[2]],inp[3]); + if (inp.size() == 2) { + setMedium(inp[0],inp[0],mind[inp[1]]); + } + else if (inp.size() == 3) { + setMedium(inp[0],inp[1],mind[inp[2]]); + } + else if (inp.size() == 4) { + setMedium(inp[0],inp[1],mind[inp[2]],inp[3]); + } else egsWarning("EGS_BaseGeometry::setMedia(): found %d inputs\n" - "in a 'set medium' input. 2 or 3 are allowed\n",inp.size()); + "in a 'set medium' input. 2 or 3 are allowed\n",inp.size()); } else egsWarning("EGS_BaseGeometry::setMedia(): wrong 'set medium'" - " input\n"); + " input\n"); } } void EGS_BaseGeometry::setRelativeRho(int start, int end, EGS_Float rho) { - if( start < 0 ) start = 0; - if( end >= nreg ) end = nreg-1; - if( end >= start ) { + if (start < 0) { + start = 0; + } + if (end >= nreg) { + end = nreg-1; + } + if (end >= start) { int j; - if( !rhor ) { + if (!rhor) { rhor = new EGS_Float [nreg]; - for(j=0; jtakeInputItem("set relative density")) ) { + while ((i = input->takeInputItem("set relative density"))) { vector tmp; int err = i->getInput("set relative density",tmp); - if( !err ) { - if( tmp.size() == 2 ) { - int start = (int) (tmp[0]+0.1); int end = start; + if (!err) { + if (tmp.size() == 2) { + int start = (int)(tmp[0]+0.1); + int end = start; setRelativeRho(start,end,tmp[1]); } - else if( tmp.size() == 3 ) { - int start = (int) (tmp[0]+0.1); int end = (int) (tmp[1]+0.1); + else if (tmp.size() == 3) { + int start = (int)(tmp[0]+0.1); + int end = (int)(tmp[1]+0.1); setRelativeRho(start,end,tmp[2]); } else { egsWarning("EGS_BaseGeometry::setRelativeRho(): found %d " - "inputs in a 'set relative density' input.\n",tmp.size()); + "inputs in a 'set relative density' input.\n",tmp.size()); egsWarning(" 2 or 3 are allowed => input ignored\n"); } } @@ -621,24 +769,44 @@ void EGS_BaseGeometry::setRelativeRho(EGS_Input *input) { int EGS_BaseGeometry::computeIntersections(int ireg, int n, const EGS_Vector &X, const EGS_Vector &u, EGS_GeometryIntersections *isections) { - if( n < 1 ) return -1; - int ifirst = 0; EGS_Float t, ttot = 0; EGS_Vector x(X); int imed; - if( ireg < 0 ) { - t = 1e30; ireg = howfar(ireg,x,u,t,&imed); - if( ireg < 0 ) return 0; - isections[0].t = t; isections[0].rhof = 1; - isections[0].ireg = -1; isections[0].imed = -1; - ttot = t; ++ifirst; x += u*t; - } - else imed = medium(ireg); - - for(int j=ifirst; j= 0 ? -1 : n; @@ -647,55 +815,82 @@ int EGS_BaseGeometry::computeIntersections(int ireg, int n, const EGS_Vector &X, void EGS_BaseGeometry::setBooleanProperty(EGS_BPType prop) { bproperty = prop; - if( bp_array ) { delete [] bp_array; bp_array = 0; } + if (bp_array) { + delete [] bp_array; + bp_array = 0; + } } void EGS_BaseGeometry::addBooleanProperty(int bit) { - if( bit < 0 || bit >= 8*sizeof(EGS_BPType) ) { + if (bit < 0 || bit >= 8*sizeof(EGS_BPType)) { egsWarning("EGS_BaseGeometry::addBooleanProperty: attempt to set the " - "%d'th bith!\n",bit); return; + "%d'th bith!\n",bit); + return; } EGS_BPType prop = 1 << bit; bproperty |= prop; - if( bp_array ) { - for(int j=0; j= nreg ) end = nreg-1; - if( start == 0 && end == nreg-1 && step==1 ) setBooleanProperty(prop); + if (start < 0) { + start = 0; + } + if (end >= nreg) { + end = nreg-1; + } + if (start == 0 && end == nreg-1 && step==1) { + setBooleanProperty(prop); + } else { - if( !bp_array ) { + if (!bp_array) { bp_array = new EGS_BPType [nreg]; - for(int j=0; j= 8*sizeof(EGS_BPType) ) { + if (bit < 0 || bit >= 8*sizeof(EGS_BPType)) { egsWarning("EGS_BaseGeometry::addBooleanProperty: attempt to set the " - "%d'th bith!\n",bit); return; + "%d'th bith!\n",bit); + return; + } + if (start < 0) { + start = 0; + } + if (end >= nreg) { + end = nreg-1; + } + if (start == 0 && end == nreg-1 && step==1) { + addBooleanProperty(bit); } - if( start < 0 ) start = 0; - if( end >= nreg ) end = nreg-1; - if( start == 0 && end == nreg-1 && step==1 ) addBooleanProperty(bit); else { EGS_BPType prop = 1 << bit; - if( !bp_array ) { + if (!bp_array) { bp_array = new EGS_BPType [nreg]; - for(int j=0; j ®s) { +void EGS_BaseGeometry::getLabelRegions(const string &str, vector ®s) { // get all regions lists for this named label for (int i=0; i ®s) { } // sort region list and remove duplicates - sort (regs.begin(), regs.end()); - regs.erase ( unique (regs.begin(), regs.end() ), regs.end()); + sort(regs.begin(), regs.end()); + regs.erase(unique(regs.begin(), regs.end()), regs.end()); } int EGS_BaseGeometry::setLabels(EGS_Input *input) { EGS_Input *i; int labelCount=0; - while( (i = input->takeInputItem("set label")) ) { + while ((i = input->takeInputItem("set label"))) { // get input string string inp; @@ -747,8 +942,9 @@ int EGS_BaseGeometry::setLabels(const string &inp) { while (*ptr != ' ' && *ptr) { ptr++; } - tokens.push_back (string (begin, ptr)); - } while (*ptr++ != '\0'); + tokens.push_back(string(begin, ptr)); + } + while (*ptr++ != '\0'); // bail out if there are no label tokens if (tokens.size() < 1) { @@ -766,16 +962,18 @@ int EGS_BaseGeometry::setLabels(const string &inp) { } else { egsWarning("EGS_BaseGeometry::setLabels(): label \"%s\": region %d is beyond the number " \ - "of regions in this geometry\n", lab.name.c_str(), reg); + "of regions in this geometry\n", lab.name.c_str(), reg); } } // continue if there is no region - if (lab.regions.size() <= 0) return 0; + if (lab.regions.size() <= 0) { + return 0; + } // sort region list and remove duplicates - sort (lab.regions.begin(), lab.regions.end()); - lab.regions.erase ( unique (lab.regions.begin(), lab.regions.end() ), lab.regions.end()); + sort(lab.regions.begin(), lab.regions.end()); + lab.regions.erase(unique(lab.regions.begin(), lab.regions.end()), lab.regions.end()); // push current label onto vector of labels labels.push_back(lab); diff --git a/HEN_HOUSE/egs++/egs_base_geometry.h b/HEN_HOUSE/egs++/egs_base_geometry.h index 6bb45313e..4b49fca77 100644 --- a/HEN_HOUSE/egs++/egs_base_geometry.h +++ b/HEN_HOUSE/egs++/egs_base_geometry.h @@ -50,13 +50,13 @@ class EGS_Input; struct EGS_GeometryIntersections; #ifdef BPROPERTY64 -typedef EGS_I64 EGS_BPType; + typedef EGS_I64 EGS_BPType; #elif defined BPROPERTY32 -typedef unsigned int EGS_BPType; + typedef unsigned int EGS_BPType; #elif defined BPROPERTY16 -typedef unsigned short EGS_BPType; + typedef unsigned short EGS_BPType; #else -typedef unsigned char EGS_BPType; + typedef unsigned char EGS_BPType; #endif /*! \brief Base geometry class. Every geometry class must be derived from @@ -116,7 +116,9 @@ class EGS_EXPORT EGS_BaseGeometry { applies if all dimensions are convex or if there is a single concave dimension, which is also the last dimension. */ - inline bool isConvex() const { return is_convex; }; + inline bool isConvex() const { + return is_convex; + }; /*! \brief Returns the region index, if inside, or -1 if outside (obsolete) @@ -152,9 +154,14 @@ class EGS_EXPORT EGS_BaseGeometry { */ static int findRegion(EGS_Float xp, int np, const EGS_Float *p) { int ml = 0, mu = np; - while( mu - ml > 1 ) { + while (mu - ml > 1) { int mav = (ml+mu)/2; - if( xp <= p[mav] ) mu = mav; else ml = mav; + if (xp <= p[mav]) { + mu = mav; + } + else { + ml = mav; + } } return mu - 1; }; @@ -190,7 +197,7 @@ class EGS_EXPORT EGS_BaseGeometry { simulation). */ virtual int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) = 0; + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) = 0; /*! Calculate the distance to the outer geometry boundary from \a x along the direction \a u. @@ -205,7 +212,7 @@ class EGS_EXPORT EGS_BaseGeometry { */ virtual EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u); + const EGS_Vector &u); /*! \brief Calculate the distance to a boundary for position \a x in any direction. @@ -223,7 +230,9 @@ class EGS_EXPORT EGS_BaseGeometry { Currently only implemented in EGS_XYZGeometry */ - virtual EGS_Float getMass(int ireg) { return 1.0; } + virtual EGS_Float getMass(int ireg) { + return 1.0; + } /*! \brief Returns region boundaries in direction determined by idir @@ -231,7 +240,7 @@ class EGS_EXPORT EGS_BaseGeometry { idir=1--> Y-boundaries, idir=2--> Z-boundaries */ virtual EGS_Float getBound(int idir, int ind) { - return 0.0; + return 0.0; } /*! Returns number of planar slabs/cylinders/etc in direction idir @@ -239,7 +248,9 @@ class EGS_EXPORT EGS_BaseGeometry { Currently only implemented in EGS_XYZGeometry, where idir=0--> X-boundaries, idir=1--> Y-boundaries, idir=2--> Z-boundaries */ - virtual int getNRegDir(int idir) { return 0; } + virtual int getNRegDir(int idir) { + return 0; + } /*! \brief Returns the number of local regions in this geometry. @@ -247,7 +258,9 @@ class EGS_EXPORT EGS_BaseGeometry { geometry classes must set EGS_BaseGeometry::nreg to the number of regions in the geometry. */ - int regions() const { return nreg; }; + int regions() const { + return nreg; + }; /*! \brief Returnes true if \a ireg is a real region, false otherwise @@ -275,7 +288,9 @@ class EGS_EXPORT EGS_BaseGeometry { * This method is handy for detecting when a particle gets stuck * at a boundary */ - virtual int getMaxStep() const { return nreg+1; }; + virtual int getMaxStep() const { + return nreg+1; + }; /*! \brief Calculates intersection distances to region boundaries @@ -290,7 +305,7 @@ class EGS_EXPORT EGS_BaseGeometry { then finds all other intersections as in the case of \a x inside. */ virtual int computeIntersections(int ireg, int n, const EGS_Vector &x, - const EGS_Vector &u, EGS_GeometryIntersections *isections); + const EGS_Vector &u, EGS_GeometryIntersections *isections); /*! \brief Set all regions to a medium with name \a Name @@ -316,7 +331,9 @@ class EGS_EXPORT EGS_BaseGeometry { Note that... */ - void setMedium(int imed) { med = imed; }; + void setMedium(int imed) { + med = imed; + }; /*! \brief Set every delta'th region between \a start and \a end * (inclusive) to \a imed. @@ -353,7 +370,7 @@ class EGS_EXPORT EGS_BaseGeometry { Returns a pointer to the character array holding the name of the medium with index \a ind or \c null if there is no such medium index. */ - static const char* getMediumName(int ind); + static const char *getMediumName(int ind); /*! \brief Add a medium or get the index of an existing medium. @@ -375,7 +392,9 @@ class EGS_EXPORT EGS_BaseGeometry { /*! \brief Does this geometry object have a mass density scaling feature? */ - inline bool hasRhoScaling() const { return has_rho_scaling; }; + inline bool hasRhoScaling() const { + return has_rho_scaling; + }; /*! \brief Get the relative mass density in region \a ireg @@ -407,7 +426,9 @@ class EGS_EXPORT EGS_BaseGeometry { Every geometry must have a name and this method can be used to retrieve the name of a geometry. */ - const string &getName() const { return name; }; + const string &getName() const { + return name; + }; /*! \brief Get the geometry type. @@ -469,7 +490,9 @@ class EGS_EXPORT EGS_BaseGeometry { This is mainly useful in the development process of a new geometry. It sets the protected data member #debug to \a deb. */ - void setDebug(bool deb) { debug = deb; }; + void setDebug(bool deb) { + debug = deb; + }; /*! \brief Get a pointer to the geometry named \a Name. @@ -500,7 +523,9 @@ class EGS_EXPORT EGS_BaseGeometry { /*! \brief Is the boolean property \a prop set for region \a ireg ? */ virtual bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( !bp_array ) return ( prop & bproperty ); + if (!bp_array) { + return (prop & bproperty); + } return ireg >= 0 && ireg < nreg ? prop & bp_array[ireg] : false; }; @@ -527,7 +552,7 @@ class EGS_EXPORT EGS_BaseGeometry { * addBooleanProperty(int,int,int,int) */ virtual void setBooleanProperty(EGS_BPType prop, int start, int end, - int step=1); + int step=1); /*! \brief Add a boolean property to every \a step'th region between * \a start and \a end (inclusive) by setting the bit'th bit @@ -562,7 +587,9 @@ class EGS_EXPORT EGS_BaseGeometry { their reference count using this method. This is needed to prevent a geometry being destructed that is still in use by some other geometry. */ - inline int ref() { return ++nref; }; + inline int ref() { + return ++nref; + }; /*! \brief Decrease the reference count to this geometry @@ -572,29 +599,43 @@ class EGS_EXPORT EGS_BaseGeometry { destructed and delete the geometry, if the return value of this function is 0. */ - inline int deref() { return --nref; }; + inline int deref() { + return --nref; + }; /*! \brief Set the currently active geometry list. */ static void setActiveGeometryList(int list); - static int getLastError() { return error_flag; }; + static int getLastError() { + return error_flag; + }; - static void resetErrorFlag() { error_flag = 0; }; + static void resetErrorFlag() { + error_flag = 0; + }; - static void setBoundaryTolerance(EGS_Float btol) { epsilon = btol; }; + static void setBoundaryTolerance(EGS_Float btol) { + epsilon = btol; + }; - static EGS_Float getBoundaryTolerance() { return epsilon; }; + static EGS_Float getBoundaryTolerance() { + return epsilon; + }; /*! \brief Get the list of all regions labeled with \a str */ - virtual void getLabelRegions (const string &str, vector ®s); + virtual void getLabelRegions(const string &str, vector ®s); /*! \brief Get the name of the i-th explicit label in the geometry */ - virtual const string& getLabelName (const int i) { return labels[i].name; } + virtual const string &getLabelName(const int i) { + return labels[i].name; + } /*! \brief Get the number of explicit labels in the geometry */ - virtual int getLabelCount () { return labels.size(); } + virtual int getLabelCount() { + return labels.size(); + } /*! \brief Set the labels from an input block */ int setLabels(EGS_Input *input); diff --git a/HEN_HOUSE/egs++/egs_base_source.cpp b/HEN_HOUSE/egs++/egs_base_source.cpp index f38e19b8f..6128c899c 100644 --- a/HEN_HOUSE/egs++/egs_base_source.cpp +++ b/HEN_HOUSE/egs++/egs_base_source.cpp @@ -41,38 +41,45 @@ #include "egs_input.h" EGS_BaseSimpleSource::EGS_BaseSimpleSource(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSource(input,f), q(0), s(0), count(0) { - int Q; int err = input->getInput("charge",Q); - if( !err ) q = Q; + EGS_ObjectFactory *f) : EGS_BaseSource(input,f), q(0), s(0), count(0) { + int Q; + int err = input->getInput("charge",Q); + if (!err) { + q = Q; + } s = EGS_BaseSpectrum::createSpectrum(input); - if( !s ) egsWarning("EGS_BaseSimpleSource::EGS_BaseSimpleSource:\n" - " no spectrum was defined\n"); + if (!s) egsWarning("EGS_BaseSimpleSource::EGS_BaseSimpleSource:\n" + " no spectrum was defined\n"); } static EGS_LOCAL EGS_TypedObjectFactory source_creator(string("egs++/dso/")+CONFIG_NAME,"EGS_BaseSource"); -EGS_BaseSource* EGS_BaseSource::createSource(EGS_Input *i) { +EGS_BaseSource *EGS_BaseSource::createSource(EGS_Input *i) { //EGS_Object *o = source_creator.createSingleObject(i,"createSource",true); EGS_Object *o = source_creator.createObjects(i,"source definition", - "source","simulation source","createSource",true); + "source","simulation source","createSource",true); return dynamic_cast(o); } -EGS_BaseSource* EGS_BaseSource::getSource(const string &Name) { +EGS_BaseSource *EGS_BaseSource::getSource(const string &Name) { EGS_Object *o = source_creator.getObject(Name); - if( !o ) return 0; + if (!o) { + return 0; + } EGS_BaseSource *s = dynamic_cast(o); - if( s ) return s; + if (s) { + return s; + } egsWarning("EGS_BaseSource::getSource(): dynamic cast failed?\n" - " Object named %s is of type %s. Trying simple cast\n", - Name.c_str(),o->getObjectType().c_str()); + " Object named %s is of type %s. Trying simple cast\n", + Name.c_str(),o->getObjectType().c_str()); return (EGS_BaseSource *)o; } void EGS_BaseSource::addKnownSource(EGS_BaseSource *o) { - if(o) egsInformation("Adding known source of type %s\n", - o->getObjectType().c_str()); + if (o) egsInformation("Adding known source of type %s\n", + o->getObjectType().c_str()); source_creator.addKnownObject(o); } diff --git a/HEN_HOUSE/egs++/egs_base_source.h b/HEN_HOUSE/egs++/egs_base_source.h index 466881d12..fd1366520 100644 --- a/HEN_HOUSE/egs++/egs_base_source.h +++ b/HEN_HOUSE/egs++/egs_base_source.h @@ -104,7 +104,9 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * Derived source classes should set #description to a short * string describing the source type. */ - const char *getSourceDescription() const { return description.c_str(); }; + const char *getSourceDescription() const { + return description.c_str(); + }; /*! \brief Sample the next source particle from the source probability * distribution. @@ -127,9 +129,9 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * of systematic sampling of the beam area. */ virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, // charge and latch - EGS_Float &E, EGS_Float &wt, // energy and weight - EGS_Vector &x, EGS_Vector &u) = 0; // position and direction + int &q, int &latch, // charge and latch + EGS_Float &E, EGS_Float &wt, // energy and weight + EGS_Vector &x, EGS_Vector &u) = 0; // position and direction /*! \brief Set the next simulation chunk to start at \a nstart and to consist of \a nrun particles. @@ -178,7 +180,9 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * * \sa setState(), addState(), resetCounter(). */ - virtual bool storeState(ostream &data_out) const { return true; }; + virtual bool storeState(ostream &data_out) const { + return true; + }; /*! \brief Set the source state based on data from the stream \a data_in. * @@ -190,7 +194,9 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * * \sa addState(), storeState(), resetCounter() */ - virtual bool setState(istream &data_in) { return true; }; + virtual bool setState(istream &data_in) { + return true; + }; /*! \brief Add data from the stream \a data_in to the source state. * @@ -204,7 +210,9 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * * \sa storeState(), setState(), resetCounter(). */ - virtual bool addState(istream &data_in) { return true; }; + virtual bool addState(istream &data_in) { + return true; + }; /*! \brief Reset the source state. * @@ -264,17 +272,17 @@ class EGS_EXPORT EGS_BaseSource : public EGS_Object { * application can define its own particle sources (in addition to * the sources provided by egspp) and use them. */ - static void addKnownSource(EGS_BaseSource *o); + static void addKnownSource(EGS_BaseSource *o); - /*! \brief Add a known source object typeid to the source factory. - * - * For whatever reason dynamic_cast to EGS_BaseSource* from EGS_Object* - * fails when an application is made into a shared library and - * dynamically loads a source DSO. I'm therefore adding this method - * so that source classes can add their typeid to allow for an additional - * check in such cases. - */ - static void addKnownTypeId(const char *name); + /*! \brief Add a known source object typeid to the source factory. + * + * For whatever reason dynamic_cast to EGS_BaseSource* from EGS_Object* + * fails when an application is made into a shared library and + * dynamically loads a source DSO. I'm therefore adding this method + * so that source classes can add their typeid to allow for an additional + * check in such cases. + */ + static void addKnownTypeId(const char *name); protected: @@ -324,7 +332,9 @@ class EGS_EXPORT EGS_BaseSpectrum { * be set to a short string describing the type of the spectrum by * derived classes. */ - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; /*! \brief Sample a particle energy. * @@ -333,8 +343,11 @@ class EGS_EXPORT EGS_BaseSpectrum { * It also updates the counters #count, #sum_E and #sum_E2. */ inline EGS_Float sampleEnergy(EGS_RandomGenerator *rndm) { - EGS_Float e = sample(rndm); count++; - sum_E += e; sum_E2 += e*e; return e; + EGS_Float e = sample(rndm); + count++; + sum_E += e; + sum_E2 += e*e; + return e; }; /*! \brief Get the maximum energy of this spectrum. @@ -364,9 +377,13 @@ class EGS_EXPORT EGS_BaseSpectrum { * parallel runs. */ virtual bool storeState(ostream &data_out) const { - if( !egsStoreI64(data_out,count) ) return false; + if (!egsStoreI64(data_out,count)) { + return false; + } data_out << " " << sum_E << " " << sum_E2 << endl; - if( !data_out.good() || data_out.fail() ) return false; + if (!data_out.good() || data_out.fail()) { + return false; + } return true; }; @@ -384,9 +401,13 @@ class EGS_EXPORT EGS_BaseSpectrum { * parallel runs. */ virtual bool setState(istream &data_in) { - if( !egsGetI64(data_in,count) ) return false; + if (!egsGetI64(data_in,count)) { + return false; + } data_in >> sum_E >> sum_E2; - if( data_in.eof() || !data_in.good() || data_in.fail() ) return false; + if (data_in.eof() || !data_in.good() || data_in.fail()) { + return false; + } return true; }; @@ -405,8 +426,12 @@ class EGS_EXPORT EGS_BaseSpectrum { virtual bool addState(istream &data_in) { EGS_I64 count_save = count; double sum_E_save = sum_E, sum_E2_save = sum_E2; - if( !setState(data_in) ) return false; - count += count_save; sum_E += sum_E_save; sum_E2 += sum_E2_save; + if (!setState(data_in)) { + return false; + } + count += count_save; + sum_E += sum_E_save; + sum_E2 += sum_E2_save; return true; }; @@ -422,7 +447,9 @@ class EGS_EXPORT EGS_BaseSpectrum { * parallel runs. */ virtual void resetCounter() { - count = 0; sum_E = 0; sum_E2 = 0; + count = 0; + sum_E = 0; + sum_E2 = 0; }; /*! \brief Create and return a pointer to a spectrum object from the @@ -446,9 +473,13 @@ class EGS_EXPORT EGS_BaseSpectrum { * its statistical uncertainty to \a de. */ void getSampledAverage(EGS_Float &e, EGS_Float &de) const { - if( count > 1 ) { - e = sum_E/count; de = sum_E2/count; - de -= e*e; if( de > 0 ) de = sqrt(de/(count-1)); + if (count > 1) { + e = sum_E/count; + de = sum_E2/count; + de -= e*e; + if (de > 0) { + de = sqrt(de/(count-1)); + } } }; @@ -515,7 +546,7 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * spectrum object and will delete it in the destructor. */ EGS_BaseSimpleSource(int Q, EGS_BaseSpectrum *Spec, - const string &Name="", EGS_ObjectFactory *f=0) : + const string &Name="", EGS_ObjectFactory *f=0) : EGS_BaseSource(Name,f), q(Q), s(Spec), count(0) { }; /*! \brief Construct a 'simple' particle source from the information @@ -534,7 +565,11 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * * Deletes the spectrum object of the 'simple' source. */ - ~EGS_BaseSimpleSource() { if(s) delete s; }; + ~EGS_BaseSimpleSource() { + if (s) { + delete s; + } + }; /*! \brief Is this a valid source? * @@ -546,7 +581,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * createSourceTemplate() to check if the input was sufficient to * construct the desired source. */ - virtual bool isValid() const { return (s != 0); }; + virtual bool isValid() const { + return (s != 0); + }; /*! \brief Sample the next source particle from the source probability * distribution. @@ -560,10 +597,12 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * Increments #count by one. */ virtual EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &Q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u) { - Q = q; E = s->sampleEnergy(rndm); - getPositionDirection(rndm,x,u,wt); setLatch(latch); + int &Q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u) { + Q = q; + E = s->sampleEnergy(rndm); + getPositionDirection(rndm,x,u,wt); + setLatch(latch); return ++count; }; @@ -576,14 +615,16 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * of the particle. This function is needed by getNextParticle(). */ virtual void getPositionDirection(EGS_RandomGenerator *rndm, - EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) = 0; + EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) = 0; /*! \brief Get the maximum energy of the source. * * Simply uses the \link EGS_BaseSpectrum::maxEnergy() maxEnergy() \endlink * method of the spectrum object. */ - virtual EGS_Float getEmax() const { return s->maxEnergy(); }; + virtual EGS_Float getEmax() const { + return s->maxEnergy(); + }; /*! \brief Store the fluence state of this source to the data stream * \a data_out. @@ -595,7 +636,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * \sa EGS_BaseSource::storeState(), EGS_BaseSource::setState(), * EGS_BaseSource::addState() and EGS_BaseSource::resetCounter(). */ - virtual bool storeFluenceState(ostream &data_out) const { return true; }; + virtual bool storeFluenceState(ostream &data_out) const { + return true; + }; /*! \brief Store the source state to the data stream \a data_out. * @@ -603,9 +646,15 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * of the spectrum object and the storeFluenceState() virtual function. */ virtual bool storeState(ostream &data_out) const { - if( !egsStoreI64(data_out,count) ) return false; - if( !s->storeState(data_out) ) return false; - if( !storeFluenceState(data_out) ) return false; + if (!egsStoreI64(data_out,count)) { + return false; + } + if (!s->storeState(data_out)) { + return false; + } + if (!storeFluenceState(data_out)) { + return false; + } return true; }; @@ -617,10 +666,17 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { */ virtual bool addState(istream &data) { EGS_I64 count_save = count; - if( !egsGetI64(data,count) ) return false; - if( !s->addState(data) ) return false; - if( !addFluenceData(data) ) return false; - count += count_save; return true; + if (!egsGetI64(data,count)) { + return false; + } + if (!s->addState(data)) { + return false; + } + if (!addFluenceData(data)) { + return false; + } + count += count_save; + return true; }; /*! \brief Reset the source to a state with zero sampled particles. @@ -630,7 +686,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * resetFluenceCounter(). */ virtual void resetCounter() { - count = 0; s->resetCounter(); resetFluenceCounter(); + count = 0; + s->resetCounter(); + resetFluenceCounter(); }; /*! \brief Add fluence data from the stream \a data to the current state. @@ -642,7 +700,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * \sa storeFluenceState(), setFluenceState(), resetFluenceCounter(), * setState(), storeState(), resetCounter() and addState(). */ - virtual bool addFluenceData(istream &data) { return true; } + virtual bool addFluenceData(istream &data) { + return true; + } /*! \brief Reset the data related to the sampling of positions and * directions to a state with zero sampled particles. @@ -666,7 +726,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * \sa storeFluenceState(), addFluenceState(), addFluenceData(), * setState(), storeState(), resetCounter() and addState(). */ - virtual bool setFluenceState(istream &data) { return true; }; + virtual bool setFluenceState(istream &data) { + return true; + }; /*! \brief Set the source state according to the data in the stream \a data. * @@ -675,9 +737,15 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * function. */ virtual bool setState(istream &data) { - if( !egsGetI64(data,count) ) return false; - if( !s->setState(data) ) return false; - if( !setFluenceState(data) ) return false; + if (!egsGetI64(data,count)) { + return false; + } + if (!s->setState(data)) { + return false; + } + if (!setFluenceState(data)) { + return false; + } return true; }; @@ -689,7 +757,9 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { * set the particle latch according to some condition. The default * implementation sets the latch to zero. */ - virtual void setLatch(int &latch) { latch = 0; }; + virtual void setLatch(int &latch) { + latch = 0; + }; /*! \brief The charge of this simple source */ int q; @@ -716,16 +786,18 @@ class EGS_EXPORT EGS_BaseSimpleSource : public EGS_BaseSource { */ template EGS_BaseSource *createSourceTemplate(EGS_Input *input, - EGS_ObjectFactory *f, const char *name) { + EGS_ObjectFactory *f, const char *name) { EGS_BaseSource::addKnownTypeId(typeid(T).name()); - if( !input ) { - egsWarning("createSource(%s): null input?\n",name); return 0; + if (!input) { + egsWarning("createSource(%s): null input?\n",name); + return 0; } T *res = new T(input,f); - if( !res->isValid() ) { + if (!res->isValid()) { egsWarning("createSource(%s): the input is not " - "sufficient to create a valid source\n",name); - delete res; return 0; + "sufficient to create a valid source\n",name); + delete res; + return 0; } return res; }; diff --git a/HEN_HOUSE/egs++/egs_fortran_geometry.cpp b/HEN_HOUSE/egs++/egs_fortran_geometry.cpp index 8ab485b8b..07d122bdd 100644 --- a/HEN_HOUSE/egs++/egs_fortran_geometry.cpp +++ b/HEN_HOUSE/egs++/egs_fortran_geometry.cpp @@ -43,79 +43,89 @@ #include using namespace std; -static EGS_SimpleContainer egspp_f_geoms; +static EGS_SimpleContainer egspp_f_geoms; const static char *egspp_f_error_message = "%s: Invalid geometry index %d\n"; extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_init_geometry,EGSPP_INIT_GEOMETRY)( - EGS_I32 *igeom, const char *file_name, int flength) { + EGS_I32 *igeom, const char *file_name, int flength) { int n = flength-1; - while( isspace(file_name[n]) && n > 0 ) --n; + while (isspace(file_name[n]) && n > 0) { + --n; + } char *fname = new char [n+1]; - for(int j=0; jref(); egspp_f_geoms.add(g); + g->ref(); + egspp_f_geoms.add(g); } else { egsWarning("egspp_init_geometry: failed to create a geometry from " - "the input in file %s\n",fname); + "the input in file %s\n",fname); *igeom = -1; } } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_howfar,EGSPP_HOWFAR)( - const EGS_I32 *igeom, const EGS_I32 *ireg, - const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, - const EGS_Float *u, const EGS_Float *v, const EGS_Float *w, - EGS_I32 *inew, EGS_I32 *newmed, EGS_Float *ustep) { + const EGS_I32 *igeom, const EGS_I32 *ireg, + const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, + const EGS_Float *u, const EGS_Float *v, const EGS_Float *w, + EGS_I32 *inew, EGS_I32 *newmed, EGS_Float *ustep) { int ig = *igeom; - if( ig < 0 || ig >= egspp_f_geoms.size() ) + if (ig < 0 || ig >= egspp_f_geoms.size()) { egsFatal(egspp_f_error_message,"egspp_howfar",ig); + } EGS_Vector xx(*x,*y,*z), uu(*u,*v,*w); *inew = egspp_f_geoms[ig]->howfar(*ireg,xx,uu,*ustep,newmed); } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_hownear,EGSPP_HOWNEAR)( - const EGS_I32 *igeom, const EGS_I32 *ireg, - const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, - EGS_Float *tperp) { + const EGS_I32 *igeom, const EGS_I32 *ireg, + const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, + EGS_Float *tperp) { int ig = *igeom; - if( ig < 0 || ig >= egspp_f_geoms.size() ) + if (ig < 0 || ig >= egspp_f_geoms.size()) { egsFatal(egspp_f_error_message,"egspp_hownear",ig); + } EGS_Vector xx(*x,*y,*z); *tperp = egspp_f_geoms[ig]->hownear(*ireg,xx); } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_is_where,EGSPP_IS_WHERE)( - const EGS_I32 *igeom, - const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, - EGS_I32 *ireg) { + const EGS_I32 *igeom, + const EGS_Float *x, const EGS_Float *y, const EGS_Float *z, + EGS_I32 *ireg) { int ig = *igeom; - if( ig < 0 || ig >= egspp_f_geoms.size() ) + if (ig < 0 || ig >= egspp_f_geoms.size()) { egsFatal(egspp_f_error_message,"egspp_is_where",ig); + } EGS_Vector xx(*x,*y,*z); *ireg = egspp_f_geoms[ig]->isWhere(xx); } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_n_regions,EGSPP_N_REGIONS)( - const EGS_I32 *igeom, EGS_I32 *nreg) { + const EGS_I32 *igeom, EGS_I32 *nreg) { int ig = *igeom; - if( ig < 0 || ig >= egspp_f_geoms.size() ) + if (ig < 0 || ig >= egspp_f_geoms.size()) { egsFatal(egspp_f_error_message,"egspp_n_regions",ig); + } *nreg = egspp_f_geoms[ig]->regions(); } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_describe_geometry,EGSPP_DESCRIBE_GEOMETRY)( - const EGS_I32 *igeom) { + const EGS_I32 *igeom) { int ig = *igeom; - if( ig < 0 || ig >= egspp_f_geoms.size() ) { + if (ig < 0 || ig >= egspp_f_geoms.size()) { egsWarning(egspp_f_error_message,"egspp_describe_geometry",ig); return; } @@ -127,16 +137,25 @@ extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_n_media,EGSPP_N_MEDIA)(EGS_I32 *n } extern __extc__ void EGS_EXPORT F77_OBJ_(egspp_get_medium_name,EGSPP_GET_MEDIUM_NAME)( - const EGS_I32 *imed, char *medname, int mlength) { + const EGS_I32 *imed, char *medname, int mlength) { const static char *vacuum = "VACUUM"; const char *the_medium; int im = *imed - 1; - if( im >= 0 && im < EGS_BaseGeometry::nMedia() ) + if (im >= 0 && im < EGS_BaseGeometry::nMedia()) { the_medium = EGS_BaseGeometry::getMediumName(im); - else the_medium = vacuum; + } + else { + the_medium = vacuum; + } int n = strlen(the_medium); - if( n > mlength ) n = mlength; + if (n > mlength) { + n = mlength; + } int j; - for(j=0; j #ifdef WIN32 -const char __egs_fs = 92; + const char __egs_fs = 92; #else -const char __egs_fs = '/'; + const char __egs_fs = '/'; #endif /* @@ -55,16 +55,25 @@ extern "C" void __attribute__((destructor)) finish_egspp_library() { */ bool EGS_EXPORT egsStoreI64(ostream &data, EGS_I64 n) { - EGS_I64 i1 = n; i1 /= 1000000000; EGS_I64 i2 = n % 1000000000; + EGS_I64 i1 = n; + i1 /= 1000000000; + EGS_I64 i2 = n % 1000000000; data << " " << (int) i1 << " " << (int) i2; - if( data.fail() ) return false; + if (data.fail()) { + return false; + } return true; } bool EGS_EXPORT egsGetI64(istream &data, EGS_I64 &n) { - int i1, i2; data >> i1 >> i2; - if( data.eof() || !data.good() ) return false; - n = i1; n *= 1000000000; n += i2; + int i1, i2; + data >> i1 >> i2; + if (data.eof() || !data.good()) { + return false; + } + n = i1; + n *= 1000000000; + n += i2; return true; } @@ -75,40 +84,50 @@ static FILE *egs_error_fp = stderr; static EGS_LOCAL char __egsf_write_buf[8192]; static void EGS_LOCAL __egs_default_information(const char *msg, ...) { - va_list ap; va_start( ap, msg ); + va_list ap; + va_start(ap, msg); EGS_Application *a = EGS_Application::activeApplication(); - if( a ) { - vsprintf(__egsf_write_buf,msg,ap); a->appInformation(__egsf_write_buf); + if (a) { + vsprintf(__egsf_write_buf,msg,ap); + a->appInformation(__egsf_write_buf); } else { - vfprintf( egs_info_fp, msg, ap ); fflush(egs_info_fp); + vfprintf(egs_info_fp, msg, ap); + fflush(egs_info_fp); } va_end(ap); } static void EGS_LOCAL __egs_default_warning(const char *msg, ...) { - va_list ap; va_start( ap, msg ); + va_list ap; + va_start(ap, msg); EGS_Application *a = EGS_Application::activeApplication(); - if( a ) { - vsprintf(__egsf_write_buf,msg,ap); a->appWarning(__egsf_write_buf); + if (a) { + vsprintf(__egsf_write_buf,msg,ap); + a->appWarning(__egsf_write_buf); } else { - vfprintf( egs_warning_fp, msg, ap ); fflush(egs_warning_fp); + vfprintf(egs_warning_fp, msg, ap); + fflush(egs_warning_fp); } va_end(ap); } static void EGS_LOCAL __egs_default_error(const char *msg, ...) { - va_list ap; va_start( ap, msg ); + va_list ap; + va_start(ap, msg); EGS_Application *a = EGS_Application::activeApplication(); - if( a ) { - vsprintf(__egsf_write_buf,msg,ap); va_end(ap); + if (a) { + vsprintf(__egsf_write_buf,msg,ap); + va_end(ap); a->appFatal(__egsf_write_buf); } else { - vfprintf( egs_error_fp, msg, ap ); fflush(stderr); - va_end(ap); exit(1); + vfprintf(egs_error_fp, msg, ap); + fflush(stderr); + va_end(ap); + exit(1); } } @@ -117,16 +136,27 @@ EGS_InfoFunction EGS_EXPORT egsWarning = __egs_default_warning; EGS_InfoFunction EGS_EXPORT egsFatal = __egs_default_error; EGS_InfoFunction egsSetInfoFunction(EGS_InfoType t, EGS_InfoFunction func) { - if( !func ) { + if (!func) { egsWarning("egsSetInfoFunction: info function can not be NULL!\n"); return 0; } EGS_InfoFunction res; switch (t) { - case Information: res = egsInformation; egsInformation = func; break; - case Warning: res = egsWarning; egsWarning = func; break; - case Fatal: res = egsFatal; egsFatal = func; break; - default: egsWarning("Unknown info function type\n"); res = 0; + case Information: + res = egsInformation; + egsInformation = func; + break; + case Warning: + res = egsWarning; + egsWarning = func; + break; + case Fatal: + res = egsFatal; + egsFatal = func; + break; + default: + egsWarning("Unknown info function type\n"); + res = 0; } return res; } @@ -139,45 +169,67 @@ void egsSetDefaultIOFunctions() { template void __egs_swap_bytes(T *v) { char *c = (char *) v; - char tmp = c[0]; c[0]=c[3]; c[3]=tmp; - tmp = c[1]; c[1]=c[2]; c[2]=tmp; + char tmp = c[0]; + c[0]=c[3]; + c[3]=tmp; + tmp = c[1]; + c[1]=c[2]; + c[2]=tmp; } -void egsSwapBytes(int *n) { __egs_swap_bytes(n); } -void egsSwapBytes(float *n) { __egs_swap_bytes(n); } +void egsSwapBytes(int *n) { + __egs_swap_bytes(n); +} +void egsSwapBytes(float *n) { + __egs_swap_bytes(n); +} void egsSwapBytes(short *n) { char *c = (char *) n; - char tmp=c[0]; c[0]=c[1]; c[1]=tmp; + char tmp=c[0]; + c[0]=c[1]; + c[1]=tmp; } string egsJoinPath(const string &first, const string &second) { - int n = first.size()-1; char c = first[n]; + int n = first.size()-1; + char c = first[n]; string result(first); - if( c == '/' && c != __egs_fs ) result[n] = __egs_fs; - if( result[n] != __egs_fs ) result += __egs_fs; + if (c == '/' && c != __egs_fs) { + result[n] = __egs_fs; + } + if (result[n] != __egs_fs) { + result += __egs_fs; + } result += second; return result; } string egsStripPath(const string &aname) { int j; - for(j=aname.size()-1; j>=0; j--) { - if( aname[j] == '/' || aname[j] == __egs_fs ) { j++; break; } + for (j=aname.size()-1; j>=0; j--) { + if (aname[j] == '/' || aname[j] == __egs_fs) { + j++; + break; + } + } + if (j < 0) { + return aname; } - if( j < 0 ) return aname; string result; - if( j >= 0 ) { - while( j < aname.size() ) result += aname[j++]; + if (j >= 0) { + while (j < aname.size()) { + result += aname[j++]; + } } return result; } #ifdef WIN32 -#include + #include #else -#include -#include + #include + #include #endif string egsHostName() { @@ -187,16 +239,22 @@ string egsHostName() { // ws2_32 DLL. This is pretty stupid as we just want to get the host name => // we try to get the host name from environment variables. char *var = getenv("COMPUTERNAME"); - if( !var ) { + if (!var) { var = getenv("HOSTNAME"); - if( !var ) var = getenv("HOST"); + if (!var) { + var = getenv("HOST"); + } + } + if (!var) { + return "unknown"; } - if( !var ) return "unknown"; return var; #else char buf[1024]; int err = gethostname(buf,1023); - if( err ) return "unknown"; + if (err) { + return "unknown"; + } return buf; #endif } @@ -210,33 +268,63 @@ int egsGetPid() { } string egsSimplifyCVSKey(const string &key) { - if( key.size() < 2 ) return key; - int js; for(js=0; js= key.size() ) return key; - int je; for(je=key.size()-1; je>=0; je--) if( key[je] == '$' ) break; - if( je <= js ) return key; - string result; for(int j=js+1; j= key.size()) { + return key; + } + int je; + for (je=key.size()-1; je>=0; je--) if (key[je] == '$') { + break; + } + if (je <= js) { + return key; + } + string result; + for (int j=js+1; jtestInside(g); } +void EGS_GeometryTester::testInside(EGS_BaseGeometry *g) { + p->testInside(g); +} void EGS_GeometryTester::testInsideTime(EGS_BaseGeometry *g) { p->testInsideTime(g); @@ -149,22 +153,36 @@ void EGS_GeometryTester::printPosition(const EGS_Vector &x) { }; #ifndef SKIP_DOXYGEN -EGS_PrivateTester::EGS_PrivateTester(EGS_GeometryTester *p, EGS_Input *input){ - if( !p ) egsFatal("EGS_PrivateTester::EGS_PrivateTester:\n" - " attempt to construct a tester with a null parent\n"); - parent = p; rndm = 0; n_inside = 0; n_inside_time = 0; - n_hownear = 0; n_hownear_time = 0; n_howfar = 0; n_howfar_time = 0; - inside_shape = 0; inside_time_shape = 0; - hownear_shape = 0; howfar_shape = 0; +EGS_PrivateTester::EGS_PrivateTester(EGS_GeometryTester *p, EGS_Input *input) { + if (!p) egsFatal("EGS_PrivateTester::EGS_PrivateTester:\n" + " attempt to construct a tester with a null parent\n"); + parent = p; + rndm = 0; + n_inside = 0; + n_inside_time = 0; + n_hownear = 0; + n_hownear_time = 0; + n_howfar = 0; + n_howfar_time = 0; + inside_shape = 0; + inside_time_shape = 0; + hownear_shape = 0; + howfar_shape = 0; hownear_time_shape = 0; - howfar_time_shape = 0; hownear_shape = 0; + howfar_time_shape = 0; + hownear_shape = 0; store_steps = true; check_infinity = true; - fp_info = stdout; fp_warn = stderr; - fp_inside = stdout; fp_hownear = stdout; fp_howfar = stdout; + fp_info = stdout; + fp_warn = stderr; + fp_inside = stdout; + fp_hownear = stdout; + fp_howfar = stdout; rndm = EGS_RandomGenerator::createRNG(input); - if ( !rndm ) rndm = EGS_RandomGenerator::defaultRNG(); + if (!rndm) { + rndm = EGS_RandomGenerator::defaultRNG(); + } setTest(input,"inside test",n_inside,&inside_shape); fp_inside = fp_this_test; @@ -184,47 +202,57 @@ EGS_PrivateTester::EGS_PrivateTester(EGS_GeometryTester *p, EGS_Input *input){ } void EGS_PrivateTester::setTest(EGS_Input *input, const char *delim, int &n, - EGS_BaseShape **s) { + EGS_BaseShape **s) { EGS_Input *i = input->takeInputItem(delim); - if( !i ) fprintf(fp_warn,"EGS_PrivateTester::EGS_setTest: \n" - " no '%s' specification\n",delim); + if (!i) fprintf(fp_warn,"EGS_PrivateTester::EGS_setTest: \n" + " no '%s' specification\n",delim); else { string shape_name; int ierr = i->getInput("bounding shape name",shape_name); EGS_BaseShape *shape = 0; - if( !ierr ) shape = EGS_BaseShape::getShape(shape_name); - if( !shape ) { + if (!ierr) { + shape = EGS_BaseShape::getShape(shape_name); + } + if (!shape) { EGS_Input *ishape = i->takeInputItem("bounding shape"); - if( !ishape ) fprintf(fp_warn,"EGS_PrivateTester::EGS_setTest: \n" - " no 'bounding shape' definition for %s\n",delim); + if (!ishape) fprintf(fp_warn,"EGS_PrivateTester::EGS_setTest: \n" + " no 'bounding shape' definition for %s\n",delim); else { shape = EGS_BaseShape::createShape(ishape); delete ishape; } } - if( !shape ) fprintf(fp_warn,"EGS_PrivateTester::EGS_PrivateTester:" - "\n got null shape for %s\n",delim); - else { shape->ref(); *s = shape; } + if (!shape) fprintf(fp_warn,"EGS_PrivateTester::EGS_PrivateTester:" + "\n got null shape for %s\n",delim); + else { + shape->ref(); + *s = shape; + } int err = i->getInput("ntest",n); - if( err ) fprintf(fp_warn,"EGS_PrivateTester::setTest: \n" - " missing/wrong 'ntest' input for %s\n",delim); - string fname; fp_this_test = stdout; + if (err) fprintf(fp_warn,"EGS_PrivateTester::setTest: \n" + " missing/wrong 'ntest' input for %s\n",delim); + string fname; + fp_this_test = stdout; err = i->getInput("file name",fname); - if( !err && fname.size() > 0 ) { + if (!err && fname.size() > 0) { fp_this_test = fopen(fname.c_str(),"w"); - if( !fp_this_test ) { + if (!fp_this_test) { fprintf(fp_warn,"EGS_PrivateTester::setTest: \n" - " failed to open file %s from writing\n",fname.c_str()); + " failed to open file %s from writing\n",fname.c_str()); fp_this_test = stdout; } } - int ci; err = i->getInput("check infinity",ci); - if( !err && ci == 0 ) check_infinity = false; + int ci; + err = i->getInput("check infinity",ci); + if (!err && ci == 0) { + check_infinity = false; + } string delimeter(delim); - if( delimeter == "howfar time test") { - string ss; i->getInput("store steps",ss); - if( ss == "no" || ss == "0" ) { + if (delimeter == "howfar time test") { + string ss; + i->getInput("store steps",ss); + if (ss == "no" || ss == "0") { fprintf(fp_info,"will not store steps in howfar test\n"); store_steps = false; } @@ -235,27 +263,36 @@ void EGS_PrivateTester::setTest(EGS_Input *input, const char *delim, int &n, } void EGS_PrivateTester::testInside(EGS_BaseGeometry *g) { - if( beginTest(n_inside,inside_shape,"testInside()","inside test",g) ) + if (beginTest(n_inside,inside_shape,"testInside()","inside test",g)) { return; - int n_in = 0; fp_this_test = fp_inside; - for(int j=0; jgetRandomPoint(rndm); int ireg = g->inside(x); - if( ireg >= 0 ) { n_in++; parent->printPosition(x); } + if (ireg >= 0) { + n_in++; + parent->printPosition(x); + } } fprintf(fp_info,"finished inside test. Point inside: %d (%g)\n", n_in,((double) n_in)/((double) n_inside)); } void EGS_PrivateTester::testInsideTime(EGS_BaseGeometry *g) { - if( beginTest(n_inside_time,inside_time_shape,"testInsideTime()", - "inside time test",g) ) return; + if (beginTest(n_inside_time,inside_time_shape,"testInsideTime()", + "inside time test",g)) { + return; + } int n_in = 0; EGS_Timer t; - for(int j=0; jgetRandomPoint(rndm); int ireg = g->inside(x); - if( ireg >= 0 ) n_in++; + if (ireg >= 0) { + n_in++; + } } EGS_Float cpu = t.time(); fprintf(fp_info,"finished inside time test.\n"); @@ -265,26 +302,29 @@ void EGS_PrivateTester::testInsideTime(EGS_BaseGeometry *g) { } void EGS_PrivateTester::testHownear(int ntry, EGS_BaseGeometry *g) { - if( ntry < 1 ) { + if (ntry < 1) { fprintf(fp_warn,"EGS_GeometryTester::testHownear(): ntry must be >0\n"); return; } - if( beginTest(n_hownear,hownear_shape,"testHownear()","hownear test",g) ) + if (beginTest(n_hownear,hownear_shape,"testHownear()","hownear test",g)) { return; + } int n_fail = 0; - for(int j=0; jgetRandomPoint(rndm); - int ireg = g->inside(x); EGS_Float tperp = g->hownear(ireg,x); - for(int i=0; iinside(x); + EGS_Float tperp = g->hownear(ireg,x); + for (int i=0; igetUniform()-1; EGS_Float sint = tperp*sqrt(1-cost*cost); - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); EGS_Vector xi(x.x+sint*cphi,x.y+sint*sphi,x.z+tperp*cost); int ireg_i = g->inside(xi); - if( ireg_i != ireg ) { + if (ireg_i != ireg) { n_fail++; fprintf(fp_hownear," point (%g,%g,%g) with tperp=%g fails for " - "(%g,%g,%g): %d %d\n",x.x,x.y,x.z,tperp,xi.x,xi.y,xi.z,ireg,ireg_i); + "(%g,%g,%g): %d %d\n",x.x,x.y,x.z,tperp,xi.x,xi.y,xi.z,ireg,ireg_i); } } } @@ -293,11 +333,13 @@ void EGS_PrivateTester::testHownear(int ntry, EGS_BaseGeometry *g) { } void EGS_PrivateTester::testHownearTime(EGS_BaseGeometry *g) { - if( beginTest(n_hownear_time,hownear_time_shape,"testHownearTime()", - "hownear time test",g) ) return; + if (beginTest(n_hownear_time,hownear_time_shape,"testHownearTime()", + "hownear time test",g)) { + return; + } double sum_tperp = 0; EGS_Timer t; - for(int j=0; jgetRandomPoint(rndm); int ireg = g->inside(x); sum_tperp += g->hownear(ireg,x); @@ -314,13 +356,14 @@ void EGS_PrivateTester::testHownearTime(EGS_BaseGeometry *g) { void EGS_PrivateTester::testHowfar(EGS_BaseGeometry *g, bool time) { EGS_Vector positions[N_MAX_STEP]; int regions[N_MAX_STEP]; - int btest; int ncase; + int btest; + int ncase; EGS_BaseShape *hshape; bool ss; - if( time ) { + if (time) { ncase = n_howfar_time; btest = beginTest(n_howfar_time,howfar_time_shape,"testHowfarTime()", - "howfar time test",g); + "howfar time test",g); hshape = howfar_time_shape; ss = store_steps; fprintf(fp_info,"Store steps: %d\n",ss); @@ -331,17 +374,21 @@ void EGS_PrivateTester::testHowfar(EGS_BaseGeometry *g, bool time) { hshape = howfar_shape; ss = true; } - if (btest) return; + if (btest) { + return; + } const EGS_AffineTransform *T = hshape->getTransform(); egsWarning("has transofrmation: %d\n",(T != 0)); //EGS_BaseGeometry::geometry_error = &__geometry_error; - EGS_Timer timer; fp_this_test = fp_howfar; + EGS_Timer timer; + fp_this_test = fp_howfar; double nstep = 0; - for(int j=0; jgetRandomPoint(rndm); EGS_Float cost = 2*rndm->getUniform()-1; EGS_Float sint = sqrt(1-cost*cost); - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); EGS_Vector u(sint*cphi,sint*sphi,cost); EGS_Vector Xo(x); bool go_back = true; @@ -350,23 +397,30 @@ void EGS_PrivateTester::testHowfar(EGS_BaseGeometry *g, bool time) { //if( !go_back ) egsWarning("Initial position: (%g,%g,%g) direction: " // "(%g,%g,%g)\n",x.x,x.y,x.z,u.x,u.y,u.z); EGS_Float t_step = 1e15; - int ireg = g->inside(x); int ireg_first = ireg; + int ireg = g->inside(x); + int ireg_first = ireg; ireg = g->howfar(ireg,x,u,t_step); - if( ireg < 0 && ireg != ireg_first && !time ) { + if (ireg < 0 && ireg != ireg_first && !time) { EGS_Vector tmp(x + u*t_step); parent->printPosition(tmp); } //egsWarning("ireg: %d new_ireg: %d t = %g\n",ireg_first,ireg,t_step); int n_step = 0; - if( ireg >= 0 ) { - x += u*t_step; - if( ss ) { positions[n_step] = x; regions[n_step++] = ireg; } - if (!time ) parent->printPosition(x); + if (ireg >= 0) { + x += u*t_step; + if (ss) { + positions[n_step] = x; + regions[n_step++] = ireg; + } + if (!time) { + parent->printPosition(x); + } } //if( !go_back && ireg >= 0 ) egsWarning("Starting loop: ireg=%d " // "x=(%g,%g,%g)\n",ireg,x.x,x.y,x.z); - while( ireg >= 0 ) { - t_step = 1e15; int ireg_new = g->howfar(ireg,x,u,t_step); + while (ireg >= 0) { + t_step = 1e15; + int ireg_new = g->howfar(ireg,x,u,t_step); //if( !go_back ) egsWarning("new region=%d step=%g x=(%g,%g,%g)\n", // ireg_new,t_step,x.x,x.y,x.z); //if( __geometry_error ) { @@ -376,52 +430,59 @@ void EGS_PrivateTester::testHowfar(EGS_BaseGeometry *g, bool time) { // go_back = false; x = Xo; goto retry; // } //} - if( ireg_new == ireg ) break; - // if the above condition is true, - // we assume to be in an anfinite geometry with a direction - // such that we never get out. + if (ireg_new == ireg) { + break; + } + // if the above condition is true, + // we assume to be in an anfinite geometry with a direction + // such that we never get out. ireg = ireg_new; - x += u*t_step; nstep += 1; - if( ss ) { - positions[n_step] = x; regions[n_step++] = ireg; - if( n_step >= N_MAX_STEP ) { - if( go_back ) { + x += u*t_step; + nstep += 1; + if (ss) { + positions[n_step] = x; + regions[n_step++] = ireg; + if (n_step >= N_MAX_STEP) { + if (go_back) { egsWarning("testHowfar(): number of steps exceeded %d for" - " case %d:\n",N_MAX_STEP,j+1); + " case %d:\n",N_MAX_STEP,j+1); egsWarning(" direction = (%g,%g,%g)\n",u.x,u.y,u.z); egsWarning(" initial position = (%g,%g,%g) region = %d\n", - Xo.x,Xo.y,Xo.z,ireg_first); - for(int j=0; jsetDebug(true); x = Xo; goto retry; + positions[j].y,positions[j].z,regions[j]); + go_back = false; + g->setDebug(true); + x = Xo; + goto retry; } egsFatal("\nQuiting now\n\n"); } } - if( !time ) { - if( check_infinity && x.length2() > 1e10 ) { + if (!time) { + if (check_infinity && x.length2() > 1e10) { egsWarning("testHowfar(): x -> infinity for case %d?\n", - j+1); + j+1); egsWarning(" direction = (%g,%g,%g)\n",u.x,u.y,u.z); egsWarning(" initial position = (%g,%g,%g) region = %d\n", - Xo.x,Xo.y,Xo.z,ireg_first); - for(int j=0; j= 0 ) { + if (ireg >= 0) { int itest = g->inside(x); - if( itest < 0 ) { + if (itest < 0) { egsWarning("testHowfar(): after howfar step ireg = %d" - " but inside() returns %d\n",ireg,itest); + " but inside() returns %d\n",ireg,itest); egsWarning(" position = (%g,%g,%g)\n",x.x,x.y,x.z); egsWarning(" direction = (%g,%g,%g)\n",u.x,u.y,u.z); egsWarning(" initial position = (%g,%g,%g) " - "region = %d\n",Xo.x,Xo.y,Xo.z,ireg_first); - for(int j=0; jfp_this_test,"%g %g\n",z,r); }; private: @@ -479,7 +547,8 @@ class EGS_LOCAL EGS_SphereTester : public EGS_GeometryTester { xo(Xo), EGS_GeometryTester(i) {}; ~EGS_SphereTester() {}; void printPosition(const EGS_Vector &x) { - EGS_Vector xp(x-xo); EGS_Float r2 = xp.length2(); + EGS_Vector xp(x-xo); + EGS_Float r2 = xp.length2(); fprintf(p->fp_this_test,"%g %g\n",xp.z,sqrt(r2-xp.z*xp.z)); }; private: @@ -489,7 +558,7 @@ class EGS_LOCAL EGS_SphereTester : public EGS_GeometryTester { class EGS_LOCAL EGS_TransformedTester : public EGS_GeometryTester { public: EGS_TransformedTester(const EGS_AffineTransform &t, EGS_Input *i) : - T(t), EGS_GeometryTester(i) {}; + T(t), EGS_GeometryTester(i) {}; ~EGS_TransformedTester() {}; void printPosition(const EGS_Vector &x) { EGS_Vector xp(x*T); @@ -500,64 +569,80 @@ class EGS_LOCAL EGS_TransformedTester : public EGS_GeometryTester { }; #endif -EGS_GeometryTester* EGS_GeometryTester::getGeometryTester(EGS_Input *input) { - if( !input ) { egsWarning("EGS_GeometryTester::getGeometryTester:\n" - " input is null?\n"); return 0; +EGS_GeometryTester *EGS_GeometryTester::getGeometryTester(EGS_Input *input) { + if (!input) { + egsWarning("EGS_GeometryTester::getGeometryTester:\n" + " input is null?\n"); + return 0; + } + bool delete_it = false; + EGS_Input *i; + if (input->isA("geometry tester")) { + i = input; } - bool delete_it = false; EGS_Input *i; - if( input->isA("geometry tester") ) i = input; else { i = input->takeInputItem("geometry tester"); - if( !i ) { + if (!i) { egsWarning("EGS_GeometryTester::getGeometryTester:\n" - " no 'geometry tester' input\n"); return 0; + " no 'geometry tester' input\n"); + return 0; } delete_it = true; } EGS_Input *ishape; - while( (ishape = i->takeInputItem("bounding shape")) ) { + while ((ishape = i->takeInputItem("bounding shape"))) { egsWarning("*** adding shape\n"); - EGS_BaseShape::createShape(ishape); delete ishape; + EGS_BaseShape::createShape(ishape); + delete ishape; } - string type; EGS_GeometryTester *tester; + string type; + EGS_GeometryTester *tester; int err = i->getInput("output type",type); - if( err || i->compare(type,"normal") ) + if (err || i->compare(type,"normal")) { tester = new EGS_GeometryTester(i); - else if( i->compare(type,"cylindrical") ) { + } + else if (i->compare(type,"cylindrical")) { vector axis; int err1 = i->getInput("axis",axis); - if( !err1 && axis.size() == 3 ) + if (!err1 && axis.size() == 3) { tester = new EGS_CylTester(EGS_Vector(axis[0],axis[1],axis[2]),i); + } else { egsWarning("EGS_GeometryTester::getGeometryTester: no 'axis'" - " input for cylindrical output type\n"); + " input for cylindrical output type\n"); tester = new EGS_GeometryTester(i); } } - else if( i->compare(type,"spherical") ) { + else if (i->compare(type,"spherical")) { vector Xo; int err1 = i->getInput("midpoint",Xo); - if( !err1 && Xo.size() == 3 ) + if (!err1 && Xo.size() == 3) { tester = new EGS_SphereTester(EGS_Vector(Xo[0],Xo[1],Xo[2]),i); - else + } + else { tester = new EGS_SphereTester(EGS_Vector(),i); + } } - else if( i->compare(type,"transformed") ) { + else if (i->compare(type,"transformed")) { EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(i); - if( !t ) { + if (!t) { egsWarning("EGS_GeometryTester::getGeometryTester: no " - "transformation defined for a transformed tester\n"); + "transformation defined for a transformed tester\n"); tester = new EGS_GeometryTester(i); - } else { - tester = new EGS_TransformedTester(*t,i); delete t; + } + else { + tester = new EGS_TransformedTester(*t,i); + delete t; } } else { egsWarning("EGS_GeometryTester::getGeometryTester: unknown tester" - " type %s\n",type.c_str()); + " type %s\n",type.c_str()); tester = new EGS_GeometryTester(i); } - if( delete_it ) delete i; + if (delete_it) { + delete i; + } return tester; } diff --git a/HEN_HOUSE/egs++/egs_geometry_tester.h b/HEN_HOUSE/egs++/egs_geometry_tester.h index 47d90a328..5e698bb96 100644 --- a/HEN_HOUSE/egs++/egs_geometry_tester.h +++ b/HEN_HOUSE/egs++/egs_geometry_tester.h @@ -245,7 +245,7 @@ class EGS_EXPORT EGS_GeometryTester { the file. */ - static EGS_GeometryTester* getGeometryTester(EGS_Input *i); + static EGS_GeometryTester *getGeometryTester(EGS_Input *i); protected: diff --git a/HEN_HOUSE/egs++/egs_input.cpp b/HEN_HOUSE/egs++/egs_input.cpp index 4684399af..9bcbd348d 100644 --- a/HEN_HOUSE/egs++/egs_input.cpp +++ b/HEN_HOUSE/egs++/egs_input.cpp @@ -39,11 +39,11 @@ #include "egs_functions.h" #ifdef NO_SSTREAM -#include -#define S_STREAM std::istrstream + #include + #define S_STREAM std::istrstream #else -#include -#define S_STREAM std::istringstream + #include + #define S_STREAM std::istringstream #endif #include @@ -72,12 +72,13 @@ class EGS_LOCAL EGS_InputPrivate { EGS_InputPrivate() : nref(0) {}; EGS_InputPrivate(const string &Key, const string &Val = "") : key(Key), - value(Val), children(), nref(0) { }; + value(Val), children(), nref(0) { }; EGS_InputPrivate(const EGS_InputPrivate &p, bool deep=false) : key(p.key), value(p.value), nref(0), children() { - for(unsigned int j=0; jnref++; @@ -86,8 +87,9 @@ class EGS_LOCAL EGS_InputPrivate { } ~EGS_InputPrivate() { - for(unsigned int j=0; jnref++; children.push_back(p); + p->nref++; + children.push_back(p); }; EGS_InputPrivate *takeInputItem(const string &key, bool self=true) { - if( self && isA(key) ) return this; - for(vector::iterator it=children.begin(); + if (self && isA(key)) { + return this; + } + for (vector::iterator it=children.begin(); it != children.end(); it++) { - if( compareKeys((*it)->key,key) ) { + if (compareKeys((*it)->key,key)) { EGS_InputPrivate *res = *it; - children.erase(it); return res; + children.erase(it); + return res; } //if( (*it)->key == key ) { // EGS_InputPrivate *res = *it; @@ -123,9 +129,13 @@ class EGS_LOCAL EGS_InputPrivate { }; EGS_InputPrivate *getInputItem(const string &Key) { - if( isA(Key) ) return this; - for(unsigned int j=0; jkey,Key) ) return children[j]; + if (isA(Key)) { + return this; + } + for (unsigned int j=0; jkey,Key)) { + return children[j]; + } return 0; }; @@ -134,13 +144,13 @@ class EGS_LOCAL EGS_InputPrivate { }; static void removeComment(const string &start, const string &end, - string &input, bool newline); + string &input, bool newline); static int findStart(int start, int stop, - const string &start_key, const string &end_key, - const string &input, string &what, int &end); + const string &start_key, const string &end_key, + const string &input, string &what, int &end); static int findStop(int start, const string &start_string, - const string &end_string, const string &input, int &ie); + const string &end_string, const string &input, int &ie); static bool compareKeys(const string &s1, const string &s2); @@ -149,109 +159,169 @@ class EGS_LOCAL EGS_InputPrivate { void removeEmptyLines(string &input); static void deleteItem(EGS_InputPrivate *p) { - if( p ) { - if( !p->nref ) delete p; else p->nref--; + if (p) { + if (!p->nref) { + delete p; + } + else { + p->nref--; + } } }; }; #endif -EGS_Input::EGS_Input() { p = 0; } +EGS_Input::EGS_Input() { + p = 0; +} EGS_Input::EGS_Input(const EGS_Input &input) { - if( input.p ) { p = input.p; p->nref++; } - else p = 0; + if (input.p) { + p = input.p; + p->nref++; + } + else { + p = 0; + } } EGS_Input::EGS_Input(const string &name, const string &value) { p = new EGS_InputPrivate(name,value); } -EGS_Input::~EGS_Input() { EGS_InputPrivate::deleteItem(p); } +EGS_Input::~EGS_Input() { + EGS_InputPrivate::deleteItem(p); +} int EGS_Input::setContentFromFile(const char *fname) { EGS_InputPrivate::deleteItem(p); - p = new EGS_InputPrivate; return p->setContentFromFile(fname); + p = new EGS_InputPrivate; + return p->setContentFromFile(fname); } int EGS_Input::setContentFromString(string &input) { EGS_InputPrivate::deleteItem(p); - p = new EGS_InputPrivate; return p->setContentFromString(input); + p = new EGS_InputPrivate; + return p->setContentFromString(input); } int EGS_Input::addContentFromFile(const char *fname) { - if( !p ) p = new EGS_InputPrivate; + if (!p) { + p = new EGS_InputPrivate; + } return p->addContentFromFile(fname); } int EGS_Input::addContentFromString(string &input) { - if( !p ) p = new EGS_InputPrivate; + if (!p) { + p = new EGS_InputPrivate; + } return p->addContentFromString(input); } EGS_Input *EGS_Input::takeInputItem(const string &key, bool self) { - if( !p ) return 0; + if (!p) { + return 0; + } EGS_InputPrivate *item = p->takeInputItem(key,self); - if( !item ) return 0; - if( item == p && !self ) return 0; - EGS_Input *result = new EGS_Input; result->p = item; - if( item == p ) p = 0; + if (!item) { + return 0; + } + if (item == p && !self) { + return 0; + } + EGS_Input *result = new EGS_Input; + result->p = item; + if (item == p) { + p = 0; + } return result; } EGS_Input *EGS_Input::getInputItem(const string &key) const { - if( !p ) return 0; + if (!p) { + return 0; + } EGS_InputPrivate *item = p->getInputItem(key); - if( !item ) return 0; - item->nref++; EGS_Input *result = new EGS_Input; result->p = item; + if (!item) { + return 0; + } + item->nref++; + EGS_Input *result = new EGS_Input; + result->p = item; return result; } void EGS_Input::addInputItem(const EGS_Input &input) { - if( !input.p ) return; - if( !p ) p = new EGS_InputPrivate(*input.p); - else p->addItem(input.p); + if (!input.p) { + return; + } + if (!p) { + p = new EGS_InputPrivate(*input.p); + } + else { + p->addItem(input.p); + } } const char *EGS_Input::name() const { - if( !p ) return 0; + if (!p) { + return 0; + } return p->key.c_str(); } bool EGS_Input::isA(const string &key) const { - if( !p ) return false; + if (!p) { + return false; + } return p->isA(key); } template int EGS_LOCAL get_input(const EGS_InputPrivate *p, const string &key, vector &values) { - if( !p ) return -1; + if (!p) { + return -1; + } const EGS_InputPrivate *p1; - if( !p->children.size() ) { - if( !p->isA(key) ) return -1; + if (!p->children.size()) { + if (!p->isA(key)) { + return -1; + } p1 = p; } else { - for(unsigned int j=0; jchildren.size(); j++) { + for (unsigned int j=0; jchildren.size(); j++) { p1 = p->children[j]; - if( p1->isA(key) ) break; + if (p1->isA(key)) { + break; + } p1 = 0; } - if( !p1 ) return -1; + if (!p1) { + return -1; + } } values.erase(values.begin(),values.end()); S_STREAM in(p1->value.c_str()); int error = 0; - while ( 1 ) { - T tmp; in >> tmp; - if( !in.fail() ) values.push_back(tmp); - if( in.eof() ) { - if( values.size() <= 0) error = 1; + while (1) { + T tmp; + in >> tmp; + if (!in.fail()) { + values.push_back(tmp); + } + if (in.eof()) { + if (values.size() <= 0) { + error = 1; + } break; } - if( !in.good() ) { - if( values.size() <= 0) error = 2; + if (!in.good()) { + if (values.size() <= 0) { + error = 2; + } break; } } @@ -272,23 +342,35 @@ int EGS_Input::getInput(const string &key, vector &values) const { template int EGS_LOCAL get_input(const EGS_InputPrivate *p, const string &key, T &value) { - if( !p ) return -1; + if (!p) { + return -1; + } const EGS_InputPrivate *p1; - if( !p->children.size() ) { - if( !p->isA(key) ) return -1; + if (!p->children.size()) { + if (!p->isA(key)) { + return -1; + } p1 = p; } else { - for(unsigned int j=0; jchildren.size(); j++) { + for (unsigned int j=0; jchildren.size(); j++) { p1 = p->children[j]; - if( p1->isA(key) ) break; + if (p1->isA(key)) { + break; + } p1 = 0; } - if( !p1 ) return -1; + if (!p1) { + return -1; + } } S_STREAM in(p1->value.c_str()); - T tmp; in >> tmp; - if( !in.fail() ) { value = tmp; return 0; } + T tmp; + in >> tmp; + if (!in.fail()) { + value = tmp; + return 0; + } return 1; } @@ -296,10 +378,13 @@ int EGS_Input::getInput(const string &key, string &value) const { vector v; //int err = get_input(p,key,v); int err = getInput(key,v); - if( err ) return err; + if (err) { + return err; + } value = v[0]; - for(unsigned int j=1; j aux; - int err = getInput(key,aux); if( err ) return err; - if( aux.size() > 1 ) return 1; - if( aux[0].size() < 10 ) { + int err = getInput(key,aux); + if (err) { + return err; + } + if (aux.size() > 1) { + return 1; + } + if (aux[0].size() < 10) { // if it is less than 10 chars long, it is guaranteed to be // less then 1e9 => will fit into a 32 bit integer. - int n; err = getInput(key,n); if( err ) return err; - value = n; return 0; + int n; + err = getInput(key,n); + if (err) { + return err; + } + value = n; + return 0; } - int nfirst = 0; bool neg = false; - if( aux[0][0] == '+' ) nfirst = 1; - else if( aux[0][0] == '-' ) { nfirst = 1; neg = true; }; + int nfirst = 0; + bool neg = false; + if (aux[0][0] == '+') { + nfirst = 1; + } + else if (aux[0][0] == '-') { + nfirst = 1; + neg = true; + }; EGS_I64 fac=1, res = 0; - for(int j=aux[0].size()-1; j>=nfirst; j--) { - if( !isdigit(aux[0][j]) ) return 2; - EGS_I64 c = aux[0][j]-48; res += c*fac; fac *= 10; + for (int j=aux[0].size()-1; j>=nfirst; j--) { + if (!isdigit(aux[0][j])) { + return 2; + } + EGS_I64 c = aux[0][j]-48; + res += c*fac; + fac *= 10; + } + if (neg) { + res *= (-1); } - if( neg ) res *= (-1); value = res; return 0; + value = res; + return 0; } int EGS_Input::getInput(const string &key, const vector &allowed, - int def, bool *found) const { - string res; int err = getInput(key,res); - if( !err ) { - for(unsigned int j=0; j + #include #endif int EGS_InputPrivate::replace(const string &replace_what, - const string &replace_with) { - string::size_type pos = 0; int nr = 0; - while( (pos = key.find(replace_what,pos)) < key.size() ) { - key.replace(pos,replace_what.size(),replace_with); ++nr; + const string &replace_with) { + string::size_type pos = 0; + int nr = 0; + while ((pos = key.find(replace_what,pos)) < key.size()) { + key.replace(pos,replace_what.size(),replace_with); + ++nr; } pos = 0; - while( (pos = value.find(replace_what,pos)) < value.size() ) { - value.replace(pos,replace_what.size(),replace_with); ++nr; + while ((pos = value.find(replace_what,pos)) < value.size()) { + value.replace(pos,replace_what.size(),replace_with); + ++nr; } - for(int j=0; jreplace(replace_what,replace_with); + } return nr; } #endif @@ -526,11 +665,17 @@ class EGS_LOCAL EGS_InputLoopVariable { vr; //!< Loop variable replacement string. char buf[128]; EGS_InputLoopVariable(const string &var) : vname(var), is_list(false) { - vr = "$("; vr += vname; vr += ")"; + vr = "$("; + vr += vname; + vr += ")"; }; virtual ~EGS_InputLoopVariable() {}; - const char* getVarNameReplacement() const { return vr.c_str(); }; - const char* getVarReplacement() const { return buf; }; + const char *getVarNameReplacement() const { + return vr.c_str(); + }; + const char *getVarReplacement() const { + return buf; + }; virtual void setVarReplacement(int) = 0; static EGS_InputLoopVariable *getInputLoopVariable(const char *input); }; @@ -569,60 +714,83 @@ class EGS_LOCAL EGS_ListInputLoopVariable : public EGS_InputLoopVariable { public: vector list; EGS_ListInputLoopVariable(vector List, const string &var) : - EGS_InputLoopVariable(var), list(List) {is_list = true;}; + EGS_InputLoopVariable(var), list(List) { + is_list = true; + }; void setVarReplacement(int i) { string str = list[i]; sprintf(buf,"%s",str.c_str()); }; - int list_size(){return list.size();} + int list_size() { + return list.size(); + } }; -EGS_InputLoopVariable* EGS_InputLoopVariable::getInputLoopVariable( - const char *input) { - if( !input ) return 0; +EGS_InputLoopVariable *EGS_InputLoopVariable::getInputLoopVariable( + const char *input) { + if (!input) { + return 0; + } S_STREAM in(input); - string name; int type; in >> type >> name; - if( in.fail() || !in.good() ) { - egsWarning("Failed reading type and name from %s\n",input); return 0; + string name; + int type; + in >> type >> name; + if (in.fail() || !in.good()) { + egsWarning("Failed reading type and name from %s\n",input); + return 0; } - if( type < 0 || type > 2 ) { + if (type < 0 || type > 2) { egsFatal("Invalid loop type in input: %s\n" "Only integer [0], float [1] and list [2] are valid types!\n", input); } EGS_InputLoopVariable *result; - if( type == 0 ) { - int vmin, vdelta; in >> vmin >> vdelta; + if (type == 0) { + int vmin, vdelta; + in >> vmin >> vdelta; result = new EGS_IntegerInputLoopVariable(vmin,vdelta,name); } - else if( type == 1 ){ - double vmin, vdelta; in >> vmin >> vdelta; - string format; in >> format; + else if (type == 1) { + double vmin, vdelta; + in >> vmin >> vdelta; + string format; + in >> format; if (format.empty()) { format = "%lg"; - if (in.fail()) in.clear(); + if (in.fail()) { + in.clear(); + } } result = new EGS_FloatInputLoopVariable(vmin,vdelta,name,format); } - else if( type == 2 ){ - vector vstr; string str, s_tmp; - while(!in.eof()){in >> s_tmp; if (!in.fail()) vstr.push_back(s_tmp);} + else if (type == 2) { + vector vstr; + string str, s_tmp; + while (!in.eof()) { + in >> s_tmp; + if (!in.fail()) { + vstr.push_back(s_tmp); + } + } result = new EGS_ListInputLoopVariable(vstr,name); - if( in.fail() && in.eof() ) {// possibly white spaces at end of line - if (!vstr.size()){// end-of-line reached and no list-item found - delete result; result = 0; - egsFatal("No list-items found reading loop-input: %s\n",input); - } - //Found white spaces at the end of loop-input list which is ok. - return result; + if (in.fail() && in.eof()) { // possibly white spaces at end of line + if (!vstr.size()) { // end-of-line reached and no list-item found + delete result; + result = 0; + egsFatal("No list-items found reading loop-input: %s\n",input); + } + //Found white spaces at the end of loop-input list which is ok. + return result; } - if( in.bad() ) { - delete result; result = 0; - egsFatal("Fatal error reading loop input list from %s\n",input); + if (in.bad()) { + delete result; + result = 0; + egsFatal("Fatal error reading loop input list from %s\n",input); } } - if( in.fail() ) { + if (in.fail()) { egsWarning("Failed reading vmin vdelta from %s\n",input); - delete result; result = 0; + delete result; + result = 0; } return result; } @@ -631,35 +799,43 @@ EGS_InputLoopVariable* EGS_InputLoopVariable::getInputLoopVariable( void EGS_InputPrivate::processInputLoop(EGS_InputPrivate *p) { egsWarning("Processing input loop\n"); EGS_InputPrivate *ic = p->takeInputItem("loop count"); - if( !ic ) { - egsWarning("processInputLoop: no 'loop count' input\n"); return; + if (!ic) { + egsWarning("processInputLoop: no 'loop count' input\n"); + return; } - int nloop = -1; int err = get_input(ic,"loop count",nloop); + int nloop = -1; + int err = get_input(ic,"loop count",nloop); delete ic; - if( err || nloop < 1 ) { + if (err || nloop < 1) { egsWarning("processInputLoop: got %d for loop count, expecting 1 or " - "more\n",nloop); return; + "more\n",nloop); + return; } - EGS_InputPrivate *iv; vector ivars; - while( (iv = p->takeInputItem("loop variable")) != 0 ) { + EGS_InputPrivate *iv; + vector ivars; + while ((iv = p->takeInputItem("loop variable")) != 0) { EGS_InputLoopVariable *v = EGS_InputLoopVariable::getInputLoopVariable(iv->value.c_str()); - if (v->is_list){ - if (((EGS_ListInputLoopVariable*)v)->list_size()list_size()); - } - } - if( !v ) egsWarning("processInputLoop: failed to create loop variable" - " based on the input %s\n",iv->value.c_str()); - else ivars.push_back(v); + if (v->is_list) { + if (((EGS_ListInputLoopVariable *)v)->list_size()list_size()); + } + } + if (!v) egsWarning("processInputLoop: failed to create loop variable" + " based on the input %s\n",iv->value.c_str()); + else { + ivars.push_back(v); + } delete iv; } - if( !ivars.size() ) { - egsWarning("processInputLoop: no loop variables\n"); return; + if (!ivars.size()) { + egsWarning("processInputLoop: no loop variables\n"); + return; } - int nvar = ivars.size(); int j; + int nvar = ivars.size(); + int j; /* for(j=0; jchildren.size(); j++) { for(int iloop=0; iloopchildren.size(); j++) { + for (int iloop=0; iloopchildren.size(); j++) { EGS_InputPrivate *pnew = new EGS_InputPrivate(*p->children[j],true); - for(int ivar=0; ivarsetVarReplacement(iloop); pnew->replace(ivars[ivar]->getVarNameReplacement(), ivars[ivar]->getVarReplacement()); @@ -685,20 +861,33 @@ void EGS_InputPrivate::processInputLoop(EGS_InputPrivate *p) { } } - for(j=0; j start_keys, stop_keys; - int p = 0; int ep = input.size(); string what; int ie; - while( (p=findStart(p,ep,start_key_begin,start_key_end,input,what,ie))>=0 ){ - string the_start = start_key_begin; string the_end = stop_key_begin; - for(int j=0; j=0) { + string the_start = start_key_begin; + string the_end = stop_key_begin; + for (int j=0; j ie+1 ) { + if (ep > ie+1) { EGS_InputPrivate *ip = new EGS_InputPrivate(what); string content; content.assign(input,ie+1,p1-ie-1); input.erase(p,ep-p); ip->setContentFromString(content); - if( ip->isA("input loop") ) { - processInputLoop(ip); delete ip; + if (ip->isA("input loop")) { + processInputLoop(ip); + delete ip; + } + else { + children.push_back(ip); } - else children.push_back(ip); } else { egsWarning("No matching stop delimeter for %s\n",what.c_str()); return -1; } } - p = 0; string::size_type p1; - while( (p1=input.find('\n',p)) < input.size() ) { + p = 0; + string::size_type p1; + while ((p1=input.find('\n',p)) < input.size()) { int j=p1; - while( --j > p && isspace(input[j]) ); - if( j > p ) { - if( input[j] == ',' || input[j] == '\\' ) { - input[p1] = ' '; input[j] = ' '; + while (--j > p && isspace(input[j])); + if (j > p) { + if (input[j] == ',' || input[j] == '\\') { + input[p1] = ' '; + input[j] = ' '; } } p = p1+1; } p=0; - while( (p1=input.find('\n',p)) < input.size() ) { + while ((p1=input.find('\n',p)) < input.size()) { string::size_type p2 = input.find('=',p); - if( p2 < p1 ) { - string what; what.assign(input,p,p2-p); - string value; value.assign(input,p2+1,p1-p2-1); - for(int j=0; j= stop ) return -1; + string::size_type pos = start; + unsigned int ns=0; + while (1) { + if (pos >= stop) { + return -1; + } char c = ::toupper(input[pos++]); - if( start_key[ns] == c ) ns++; + if (start_key[ns] == c) { + ns++; + } else { - ns=0; if( start_key[ns] == c ) ns++; + ns=0; + if (start_key[ns] == c) { + ns++; + } + } + if (ns == start_key.size()) { + break; } - if( ns == start_key.size() ) break; } string::size_type epos = input.find(end_key,pos); - if( epos < stop ) { + if (epos < stop) { what.assign(input,pos,epos-pos); end = epos + end_key.size(); return pos-start_key.size(); @@ -829,37 +1061,53 @@ int EGS_InputPrivate::findStart(int start, int stop, const string &start_key, } void EGS_InputPrivate::print(int indent, ostream &out) const { - if( children.size() > 0 ) { - if( key.size() > 0 ) { - for(int j=0; j 0) { + if (key.size() > 0) { + for (int j=0; jprint(indent,out); + for (int i=0; iprint(indent,out); + } indent -= 1; - if( key.size() > 0 ) { - for(int j=0; j 0) { + for (int j=0; j= Xmax ) egsFatal("EGS_Interpolator::initialize: \n" - " Xmin must be > Xmax, I got Xmin=%g Xmax=%g\n",Xmin,Xmax); + if (nbin < 2) egsFatal("EGS_Interpolator::initialize: \n" + " attempt to initialize the interpolator with %d bins\n",nbin); + if (Xmin >= Xmax) egsFatal("EGS_Interpolator::initialize: \n" + " Xmin must be > Xmax, I got Xmin=%g Xmax=%g\n",Xmin,Xmax); } void EGS_Interpolator::initialize(int nbin, EGS_Float Xmin, EGS_Float Xmax, - const EGS_Float *values) { - check(nbin,Xmin,Xmax); clear(); + const EGS_Float *values) { + check(nbin,Xmin,Xmax); + clear(); own_data = true; n = nbin - 1; a = new EGS_Float [n], b = new EGS_Float [n]; - xmin = Xmin; xmax = Xmax; - fmin = values[0]; fmax = values[n]; + xmin = Xmin; + xmax = Xmax; + fmin = values[0]; + fmax = values[n]; EGS_Float dx = (xmax-xmin)/n; - bx = 1/dx; ax = -xmin*bx; - for(int j=0; j accu ) { ok = false; break; } + if (err > accu) { + ok = false; + break; + } } - if( ok ) { - initialize(nnow,Xmin,Xmax,tmp); delete [] tmp; delete [] tmp1; + if (ok) { + initialize(nnow,Xmin,Xmax,tmp); + delete [] tmp; + delete [] tmp1; return; } - if( 2*nnow-1 > nmax ) { delete [] tmp; delete [] tmp1; break; } + if (2*nnow-1 > nmax) { + delete [] tmp; + delete [] tmp1; + break; + } EGS_Float *aux = new EGS_Float [2*nnow-1]; - aux[0] = tmp[0]; int i = 1; - for(j=1; j xmin && x < xmax ) { - int i = (int) (ax + bx*x); if(i < 0) i=0; return a[i] + b[i]*x; + if (x > xmin && x < xmax) { + int i = (int)(ax + bx*x); + if (i < 0) { + i=0; + } + return a[i] + b[i]*x; + } + else if (x <= xmin) { + return fmin; + } + else { + return fmax; } - else if( x <= xmin ) return fmin; else return fmax; }; /*! \brief Interpolate the function value at \a x. @@ -162,7 +171,8 @@ class EGS_EXPORT EGS_Interpolator { \sa interpolate(). */ inline EGS_Float interpolateFast(EGS_Float x) const { - int i = (int) (ax + bx*x); return a[i] + b[i]*x; + int i = (int)(ax + bx*x); + return a[i] + b[i]*x; }; /*! \brief Get the interpolation index corresponding to \a x. @@ -170,8 +180,15 @@ class EGS_EXPORT EGS_Interpolator { \sa getIndexFast() */ inline int getIndex(EGS_Float x) const { - if( x > xmin && x < xmax ) return (int) (ax + bx*x); - else if( x <= xmin ) return 0; else return n-1; + if (x > xmin && x < xmax) { + return (int)(ax + bx*x); + } + else if (x <= xmin) { + return 0; + } + else { + return n-1; + } }; /*! \brief Get the interpolation index corresponding to \a x. @@ -181,7 +198,9 @@ class EGS_EXPORT EGS_Interpolator { \sa getIndex() */ - inline int getIndexFast(EGS_Float x) const { return (int) (ax + bx*x); }; + inline int getIndexFast(EGS_Float x) const { + return (int)(ax + bx*x); + }; /*! \brief Interpolate the function value at \a x assuming that \a belongs to the interpolation interval \a i. @@ -204,9 +223,13 @@ class EGS_EXPORT EGS_Interpolator { }; /*! \brief Get the lower interpolation interval limit. */ - EGS_Float getXmin() const { return xmin; }; + EGS_Float getXmin() const { + return xmin; + }; /*! \brief Get the upper interpolation interval limit. */ - EGS_Float getXmax() const { return xmax; }; + EGS_Float getXmax() const { + return xmax; + }; private: @@ -216,7 +239,7 @@ class EGS_EXPORT EGS_Interpolator { EGS_Float xmin,xmax; //!< interpolation interval. EGS_Float fmin,fmax; //!< function values at interval boundaries. bool own_data; - //!< true if the interpolator owns the data pointed to by a and b. + //!< true if the interpolator owns the data pointed to by a and b. void clear(); void check(int nbin, EGS_Float Xmin, EGS_Float Xmax); }; diff --git a/HEN_HOUSE/egs++/egs_libconfig.h b/HEN_HOUSE/egs++/egs_libconfig.h index 723fb0fa4..b58761fd7 100644 --- a/HEN_HOUSE/egs++/egs_libconfig.h +++ b/HEN_HOUSE/egs++/egs_libconfig.h @@ -48,7 +48,7 @@ */ #ifdef MISSING -#include "missing.h" + #include "missing.h" #endif #include "egs_config1.h" @@ -60,37 +60,37 @@ #ifdef WIN32 -#ifdef BUILD_APP_LIB -#define APP_EXPORT __declspec(dllexport) -#else -#define APP_EXPORT -#endif + #ifdef BUILD_APP_LIB + #define APP_EXPORT __declspec(dllexport) + #else + #define APP_EXPORT + #endif -#ifdef BUILD_DLL -#define EGS_EXPORT __declspec(dllexport) -#else -#define EGS_EXPORT __declspec(dllimport) -#endif -#define EGS_LOCAL -#define APP_LOCAL + #ifdef BUILD_DLL + #define EGS_EXPORT __declspec(dllexport) + #else + #define EGS_EXPORT __declspec(dllimport) + #endif + #define EGS_LOCAL + #define APP_LOCAL #else -#ifdef HAVE_VISIBILITY -#ifdef BUILD_APP_LIB -#define APP_EXPORT __attribute__ ((visibility ("default"))) -#else -#define APP_EXPORT -#endif -#define EGS_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_LOCAL __attribute__ ((visibility ("hidden"))) -#define APP_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define APP_EXPORT -#define EGS_EXPORT -#define EGS_LOCAL -#define APP_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #ifdef BUILD_APP_LIB + #define APP_EXPORT __attribute__ ((visibility ("default"))) + #else + #define APP_EXPORT + #endif + #define EGS_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_LOCAL __attribute__ ((visibility ("hidden"))) + #define APP_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define APP_EXPORT + #define EGS_EXPORT + #define EGS_LOCAL + #define APP_LOCAL + #endif #endif diff --git a/HEN_HOUSE/egs++/egs_library.cpp b/HEN_HOUSE/egs++/egs_library.cpp index 6b9e119cf..f0a50f6ed 100644 --- a/HEN_HOUSE/egs++/egs_library.cpp +++ b/HEN_HOUSE/egs++/egs_library.cpp @@ -39,21 +39,21 @@ #ifdef WIN32 -#include + #include -#define DLL_HANDLE HMODULE -#define LOAD_LIBRARY(fname) LoadLibrary(fname) -#define FREE_LIBRARY(lib) FreeLibrary(lib); -#define RESOLVE_SYMBOL(lib,symb) (void *) GetProcAddress(lib,symb) + #define DLL_HANDLE HMODULE + #define LOAD_LIBRARY(fname) LoadLibrary(fname) + #define FREE_LIBRARY(lib) FreeLibrary(lib); + #define RESOLVE_SYMBOL(lib,symb) (void *) GetProcAddress(lib,symb) #else -#include + #include -#define DLL_HANDLE void* -#define LOAD_LIBRARY(fname) dlopen(fname,RTLD_LAZY) -#define FREE_LIBRARY(lib) !dlclose(lib) -#define RESOLVE_SYMBOL(lib,symb) dlsym(lib,symb) + #define DLL_HANDLE void* + #define LOAD_LIBRARY(fname) dlopen(fname,RTLD_LAZY) + #define FREE_LIBRARY(lib) !dlclose(lib) + #define RESOLVE_SYMBOL(lib,symb) dlsym(lib,symb) #endif @@ -68,93 +68,113 @@ using namespace std; */ class EGS_LOCAL EGS_PrivateLibrary { public: - DLL_HANDLE lib; - string name, fname; bool au; - EGS_PrivateLibrary(const char *lib_name, const char *path = 0); - ~EGS_PrivateLibrary(); - bool load(); - void *resolve(const char *symb); - bool unload(); - static char fs; - static const char *lib_prefix; - static const char *lib_suffix; + DLL_HANDLE lib; + string name, fname; + bool au; + EGS_PrivateLibrary(const char *lib_name, const char *path = 0); + ~EGS_PrivateLibrary(); + bool load(); + void *resolve(const char *symb); + bool unload(); + static char fs; + static const char *lib_prefix; + static const char *lib_suffix; }; #ifdef WIN32 -#ifdef CYGWIN -char EGS_PrivateLibrary::fs = '/'; + #ifdef CYGWIN + char EGS_PrivateLibrary::fs = '/'; + #else + char EGS_PrivateLibrary::fs = '\\'; + #endif + const char *EGS_PrivateLibrary::lib_prefix = ""; + const char *EGS_PrivateLibrary::lib_suffix = ".dll"; #else -char EGS_PrivateLibrary::fs = '\\'; -#endif -const char *EGS_PrivateLibrary::lib_prefix = ""; -const char *EGS_PrivateLibrary::lib_suffix = ".dll"; -#else -char EGS_PrivateLibrary::fs = '/'; -const char *EGS_PrivateLibrary::lib_prefix = "lib"; -const char *EGS_PrivateLibrary::lib_suffix = ".so"; + char EGS_PrivateLibrary::fs = '/'; + const char *EGS_PrivateLibrary::lib_prefix = "lib"; + const char *EGS_PrivateLibrary::lib_suffix = ".so"; #endif EGS_PrivateLibrary::EGS_PrivateLibrary(const char *lib_name, const char *path) { - au = true; lib = 0; - if( !lib_name ) { - egsWarning("EGS_Library::EGS_Library: null library name?\n"); - return; - } - name = lib_name; - if(path) { - fname = path; - if( fname[fname.size()-1] != fs ) fname += fs; - } - fname += lib_prefix; fname += lib_name; fname += lib_suffix; + au = true; + lib = 0; + if (!lib_name) { + egsWarning("EGS_Library::EGS_Library: null library name?\n"); + return; + } + name = lib_name; + if (path) { + fname = path; + if (fname[fname.size()-1] != fs) { + fname += fs; + } + } + fname += lib_prefix; + fname += lib_name; + fname += lib_suffix; #ifdef LIB_DEBUG - egsInformation("EGS_Library::EGS_Library: file name is <%s>\n",fname.c_str()); + egsInformation("EGS_Library::EGS_Library: file name is <%s>\n",fname.c_str()); #endif } EGS_PrivateLibrary::~EGS_PrivateLibrary() { - if( au ) unload(); + if (au) { + unload(); + } } bool EGS_PrivateLibrary::load() { - if( lib ) return true; - lib = LOAD_LIBRARY(fname.c_str()); - /* - if (!lib ) { - const char *tmp = dlerror(); egsWarning("load library: %s\n",tmp); - } - */ + if (lib) { + return true; + } + lib = LOAD_LIBRARY(fname.c_str()); + /* + if (!lib ) { + const char *tmp = dlerror(); egsWarning("load library: %s\n",tmp); + } + */ #ifdef DLL_DEBUG - egsInformation("In EGS_PrivateLibrary::load(): name = %s lib = 0x%x\n", - name.c_str(),lib); + egsInformation("In EGS_PrivateLibrary::load(): name = %s lib = 0x%x\n", + name.c_str(),lib); #endif - if( lib ) return true; - else { - egsWarning("EGS_Library::load(): failed to load library %s\n", - fname.c_str()); + if (lib) { + return true; + } + else { + egsWarning("EGS_Library::load(): failed to load library %s\n", + fname.c_str()); #ifdef WIN32 - egsWarning(" error was: %d\n",GetLastError()); + egsWarning(" error was: %d\n",GetLastError()); #else - egsWarning(" error was: %s\n",dlerror()); + egsWarning(" error was: %s\n",dlerror()); #endif - return false; - } + return false; + } } void *EGS_PrivateLibrary::resolve(const char *symb) { - if( !lib ) { if( !load() ) return 0; } - void *result = RESOLVE_SYMBOL(lib,symb); + if (!lib) { + if (!load()) { + return 0; + } + } + void *result = RESOLVE_SYMBOL(lib,symb); #ifdef DLL_DEBUG - egsInformation("In EGS_PrivateLibrary::resolve: symbol = %s result = 0x%x\n", - symb,result); + egsInformation("In EGS_PrivateLibrary::resolve: symbol = %s result = 0x%x\n", + symb,result); #endif - return result; + return result; } bool EGS_PrivateLibrary::unload() { - if( !lib ) return true; + if (!lib) { + return true; + } bool result = FREE_LIBRARY(lib); - if( result ) lib = 0; + if (result) { + lib = 0; + } return result; } #endif @@ -163,27 +183,48 @@ EGS_Library::EGS_Library(const char *lib_name, const char *path) { pl = new EGS_PrivateLibrary(lib_name,path); } -EGS_Library::~EGS_Library() { delete pl; } +EGS_Library::~EGS_Library() { + delete pl; +} -bool EGS_Library::load() { return pl->load(); } +bool EGS_Library::load() { + return pl->load(); +} -void *EGS_Library::resolve(const char *symb) { return pl->resolve(symb); } +void *EGS_Library::resolve(const char *symb) { + return pl->resolve(symb); +} -bool EGS_Library::unload() { return pl->unload(); } +bool EGS_Library::unload() { + return pl->unload(); +} -bool EGS_Library::isLoaded() const { return (bool) pl->lib; } +bool EGS_Library::isLoaded() const { + return (bool) pl->lib; +} -bool EGS_Library::autoUnload() const { return pl->au; } +bool EGS_Library::autoUnload() const { + return pl->au; +} -void EGS_Library::setUnload(bool u) { pl->au = u; } +void EGS_Library::setUnload(bool u) { + pl->au = u; +} -const char *EGS_Library::libraryName() const { return pl->name.c_str(); } +const char *EGS_Library::libraryName() const { + return pl->name.c_str(); +} -const char *EGS_Library::libraryFile() const { return pl->fname.c_str(); } +const char *EGS_Library::libraryFile() const { + return pl->fname.c_str(); +} void *EGS_Library::resolve(const char *lname, const char *func, - const char *path) { - EGS_PrivateLibrary p(lname,path); p.au = false; - if( !p.load() ) return 0; + const char *path) { + EGS_PrivateLibrary p(lname,path); + p.au = false; + if (!p.load()) { + return 0; + } return p.resolve(func); } diff --git a/HEN_HOUSE/egs++/egs_library.h b/HEN_HOUSE/egs++/egs_library.h index 028a9cb25..f7fb25874 100644 --- a/HEN_HOUSE/egs++/egs_library.h +++ b/HEN_HOUSE/egs++/egs_library.h @@ -51,90 +51,90 @@ class EGS_PrivateLibrary; */ class EGS_EXPORT EGS_Library { - //! Pointer to the private class implementing the functionality. - EGS_PrivateLibrary *pl; + //! Pointer to the private class implementing the functionality. + EGS_PrivateLibrary *pl; public: - /*! \brief Constructs the library object and sets the DSO name to \a lib_name. - - \a lib_name should not contain platform specific prefixes or extensions, - this will be handled by the library object (\em i.e. - lib_name = mylib - will result in \c mylib.dll under Windows and \c libmylib.so under Unix.) - If \a path is \c null, the library must be in the standard search - path for DSOs. If path contains a valid path specification, - the library name will be constracted from \a path and \a lib_name. - */ - EGS_Library(const char *lib_name, const char *path = 0); - - /*! \brief Destructs the library object. - - The library will be unloaded - unless the \a auto_unload flag is set to \c false using setUnload(). - */ - ~EGS_Library(); - - /*! \brief Loads the library. - - It is not necessary to call this function - before using resolve(). Will return \c true on success and - \c false otherwise. - */ - bool load(); - - /*! \brief Returns the address of the exported symbol \a func. - - Calls the load() function if necessary. Returns the address of - the symbol on success or \c null if the symbol could not - be resolved or the library could not be loaded. - */ - void *resolve(const char *func); - - /*! \brief Unloads the library. - - Returns \c true on success, \c false otherwise. - This function is called by the destructor if the library object - was set to automatically unload the library with setUnload(). - */ - bool unload(); - - /*! \brief Returns \c true if the library is loaded, \c false otherwise - */ - bool isLoaded() const; - - /*! \brief Returns \c true if the library automatically unloads when - the object is destructed, \c false otherwise. - - \sa setUnload(). - */ - bool autoUnload() const; - - /*! \brief Set automatic unloading to \a u. */ - void setUnload(bool u); - - /*! \brief Returns the name of the library object as given in the - constructor. */ - const char *libraryName() const; - - /*! \brief Returns the name of the DSO, including full path and - platform-specific prefix and extension. */ - const char *libraryFile() const; - - /*! \brief Resolve the address of the symbol \a func from the DSO \a lname. - - This static function is provided for convenience. It loads the library - \a lname - and returns the address of the symbol \a func on success, \c null if - the library could not be loaded or if it does not export a symbol named - \a func. If \a path is null, the library will be searched for in the - standard set of library search paths, otherwise the library file name - will be constructed from \a path and \a lname. - - \sa EGS_Library::EGS_Library(), load(), resolve(). - */ - static void *resolve(const char *lname, const char *func, - const char *path = 0); + /*! \brief Constructs the library object and sets the DSO name to \a lib_name. + + \a lib_name should not contain platform specific prefixes or extensions, + this will be handled by the library object (\em i.e. + lib_name = mylib + will result in \c mylib.dll under Windows and \c libmylib.so under Unix.) + If \a path is \c null, the library must be in the standard search + path for DSOs. If path contains a valid path specification, + the library name will be constracted from \a path and \a lib_name. + */ + EGS_Library(const char *lib_name, const char *path = 0); + + /*! \brief Destructs the library object. + + The library will be unloaded + unless the \a auto_unload flag is set to \c false using setUnload(). + */ + ~EGS_Library(); + + /*! \brief Loads the library. + + It is not necessary to call this function + before using resolve(). Will return \c true on success and + \c false otherwise. + */ + bool load(); + + /*! \brief Returns the address of the exported symbol \a func. + + Calls the load() function if necessary. Returns the address of + the symbol on success or \c null if the symbol could not + be resolved or the library could not be loaded. + */ + void *resolve(const char *func); + + /*! \brief Unloads the library. + + Returns \c true on success, \c false otherwise. + This function is called by the destructor if the library object + was set to automatically unload the library with setUnload(). + */ + bool unload(); + + /*! \brief Returns \c true if the library is loaded, \c false otherwise + */ + bool isLoaded() const; + + /*! \brief Returns \c true if the library automatically unloads when + the object is destructed, \c false otherwise. + + \sa setUnload(). + */ + bool autoUnload() const; + + /*! \brief Set automatic unloading to \a u. */ + void setUnload(bool u); + + /*! \brief Returns the name of the library object as given in the + constructor. */ + const char *libraryName() const; + + /*! \brief Returns the name of the DSO, including full path and + platform-specific prefix and extension. */ + const char *libraryFile() const; + + /*! \brief Resolve the address of the symbol \a func from the DSO \a lname. + + This static function is provided for convenience. It loads the library + \a lname + and returns the address of the symbol \a func on success, \c null if + the library could not be loaded or if it does not export a symbol named + \a func. If \a path is null, the library will be searched for in the + standard set of library search paths, otherwise the library file name + will be constructed from \a path and \a lname. + + \sa EGS_Library::EGS_Library(), load(), resolve(). + */ + static void *resolve(const char *lname, const char *func, + const char *path = 0); }; #endif diff --git a/HEN_HOUSE/egs++/egs_math.h b/HEN_HOUSE/egs++/egs_math.h index 9c48b23a9..4c908d4cf 100644 --- a/HEN_HOUSE/egs++/egs_math.h +++ b/HEN_HOUSE/egs++/egs_math.h @@ -38,45 +38,45 @@ #define EGS_MATH_ #ifdef MISSING -#include "missing.h" + #include "missing.h" #endif #ifdef NO_CMATH -#include + #include #else -#include + #include #endif // M_PI is not defined after including cmath for the MS visual studio compiler? #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif // Some C++ compilers don't have a proper implementation of abs() for // all types => use a macro instead. #ifdef DONT_HAVE_ABS -#ifdef abs -#undef abs -#endif -#define abs(a) ((a) >= 0 ? (a) : -(a)) + #ifdef abs + #undef abs + #endif + #define abs(a) ((a) >= 0 ? (a) : -(a)) #endif // Some C++ compilers don't know anything about min/max after including // cmath. #ifdef DONT_HAVE_MINMAX -#ifdef min -#undef min -#endif -#ifdef max -#undef max -#endif -#define max(a, b) ((a) > (b) ? (a) : (b)) -#define min(a, b) ((a) < (b) ? (a) : (b)) + #ifdef min + #undef min + #endif + #ifdef max + #undef max + #endif + #define max(a, b) ((a) > (b) ? (a) : (b)) + #define min(a, b) ((a) < (b) ? (a) : (b)) #endif // this one is needed for the SGI C++ compiler. #ifdef STD_SQRT -#define sqrt(a) std::sqrt(a) + #define sqrt(a) std::sqrt(a) #endif #endif diff --git a/HEN_HOUSE/egs++/egs_object_factory.cpp b/HEN_HOUSE/egs++/egs_object_factory.cpp index 9cfbbbc05..4358fd8f8 100644 --- a/HEN_HOUSE/egs++/egs_object_factory.cpp +++ b/HEN_HOUSE/egs++/egs_object_factory.cpp @@ -46,7 +46,9 @@ static unsigned int object_count = 0; EGS_Object::EGS_Object(const string &Name, EGS_ObjectFactory *f) : nref(0), otype("EGS_Object"), name(Name), factory(f) { object_count++; - if( !name.size() ) name = getUniqueName(this); + if (!name.size()) { + name = getUniqueName(this); + } //if( factory ) factory->addObject(this); } @@ -60,39 +62,55 @@ EGS_Object::EGS_Object(EGS_Input *input, EGS_ObjectFactory *f) : EGS_Object::~EGS_Object() { //egsWarning("Destruncting object of type %s with name %s\n", // otype.c_str(),name.c_str()); - if( factory ) factory->removeObject(this); + if (factory) { + factory->removeObject(this); + } } void EGS_Object::setFactory(EGS_ObjectFactory *f) { - if( f && f != factory ) { - if( factory ) factory->removeObject(this); - factory = f; factory->addObject(this); + if (f && f != factory) { + if (factory) { + factory->removeObject(this); + } + factory = f; + factory->addObject(this); } } string EGS_Object::getUniqueName(const EGS_Object *o) { char buf[256]; - if( o ) sprintf(buf,"%s_%d",o->getObjectType().c_str(),object_count); - else sprintf(buf,"object_%d",object_count); - string result(buf); return result; + if (o) { + sprintf(buf,"%s_%d",o->getObjectType().c_str(),object_count); + } + else { + sprintf(buf,"object_%d",object_count); + } + string result(buf); + return result; } void EGS_Object::setName(EGS_Input *input) { int err = 1; - if( input ) err = input->getInput("name",name); - if( err ) name = getUniqueName(this); + if (input) { + err = input->getInput("name",name); + } + if (err) { + name = getUniqueName(this); + } } EGS_ObjectFactory::EGS_ObjectFactory(const string &dsoPath, int where) { //egsWarning("Creating object factory at 0x%x\n",this); - if( egsIsAbsolutePath(dsoPath) ) dso_path = dsoPath; + if (egsIsAbsolutePath(dsoPath)) { + dso_path = dsoPath; + } else { - static const char* locations[] = {"HEN_HOUSE","EGS_HOME"}; + static const char *locations[] = {"HEN_HOUSE","EGS_HOME"}; int i = !where ? 0 : 1; char *loc = getenv(locations[i]); - if( !loc ) + if (!loc) egsFatal("EGS_ObjectFactory: the environment variable " - "%s must be defined\n",locations[i]); + "%s must be defined\n",locations[i]); dso_path = egsJoinPath(loc,dsoPath); } } @@ -101,24 +119,27 @@ EGS_ObjectFactory::~EGS_ObjectFactory() { unsigned int j; //egsWarning("Destructing object factory at 0x%x\n",this); //egsWarning(" - destructing known objects\n"); - for(j=0; jgetObjectType().c_str(),o->getObjectName().c_str()); EGS_Object::deleteObject(o); } //egsWarning(" - unloading libraries\n"); - for(j=0; j::iterator i = objects.begin(); + for (vector::iterator i = objects.begin(); i != objects.end(); i++) { - if( o == *i ) { + if (o == *i) { // why not calling o->deref() here ? objects.erase(i); break; @@ -126,84 +147,96 @@ void EGS_ObjectFactory::removeObject(EGS_Object *o) { } } -typedef EGS_Object* (*EGS_ObjectCreationFunction)(EGS_Input *, - EGS_ObjectFactory *); +typedef EGS_Object *(*EGS_ObjectCreationFunction)(EGS_Input *, + EGS_ObjectFactory *); -EGS_Object* EGS_ObjectFactory::createObjects(EGS_Input *i, +EGS_Object *EGS_ObjectFactory::createObjects(EGS_Input *i, const string §ion_delimeter, const string &object_delimeter, const string &select_key, const char *funcname, bool unique) { - if( !i ) { + if (!i) { egsWarning("EGS_ObjectFactory::createObjects(): null input?\n"); return 0; } EGS_Input *input = i; - if( !i->isA(section_delimeter) ) { + if (!i->isA(section_delimeter)) { input = i->takeInputItem(section_delimeter); - if( !input ) { + if (!input) { egsWarning("EGS_ObjectFactory::createObjects(): the input is" - " not of type %s and also does not have items of this type\n", - section_delimeter.c_str()); return 0; + " not of type %s and also does not have items of this type\n", + section_delimeter.c_str()); + return 0; } } - EGS_Input *ij; int errors = 0; - while( (ij = input->takeInputItem(object_delimeter)) != 0 ) { + EGS_Input *ij; + int errors = 0; + while ((ij = input->takeInputItem(object_delimeter)) != 0) { EGS_Object *o = createSingleObject(ij,funcname,unique); - if( !o ) errors++; + if (!o) { + errors++; + } delete ij; } - if( errors ) egsWarning("EGS_ObjectFactory::createObjects(): %d errors" - " occured while creating objects\n",errors); - string sought_object; EGS_Object *o = 0; - if( objects.size() > 0 ) o = objects[objects.size()-1]; + if (errors) egsWarning("EGS_ObjectFactory::createObjects(): %d errors" + " occured while creating objects\n",errors); + string sought_object; + EGS_Object *o = 0; + if (objects.size() > 0) { + o = objects[objects.size()-1]; + } int err = input->getInput(select_key,sought_object); - if( !err ) { + if (!err) { o = getObject(sought_object); - if( !o ) egsWarning("EGS_ObjectFactory::createObjects(): an object " - "with the name %s does not exist\n",sought_object.c_str()); + if (!o) egsWarning("EGS_ObjectFactory::createObjects(): an object " + "with the name %s does not exist\n",sought_object.c_str()); } return o; } -EGS_Object* EGS_ObjectFactory::createSingleObject(EGS_Input *i, +EGS_Object *EGS_ObjectFactory::createSingleObject(EGS_Input *i, const char *funcname, bool unique) { - if( !i ) { + if (!i) { egsWarning("EGS_ObjectFactory::createSingleObject(): null input?\n"); return 0; } - string type; int err = i->getInput("type",type); - if( !err ) { - for(unsigned int j=0; jcompare(type,known_objects[j]->getObjectType()) ) { + string type; + int err = i->getInput("type",type); + if (!err) { + for (unsigned int j=0; jcompare(type,known_objects[j]->getObjectType())) { EGS_Object *o = known_objects[j]->createObject(i); - if( addObject(o,unique) ) return o; - EGS_Object::deleteObject(o); return 0; + if (addObject(o,unique)) { + return o; + } + EGS_Object::deleteObject(o); + return 0; } } } string libname; int error = i->getInput("library",libname); - if( error ) { - if( err ) egsWarning("EGS_ObjectFactory::createObject(): \n" - " input item %s does not define an object type or an object " - "library\n",i->name()); + if (error) { + if (err) egsWarning("EGS_ObjectFactory::createObject(): \n" + " input item %s does not define an object type or an object " + "library\n",i->name()); else egsWarning("EGS_ObjectFactory::createObject(): input item %s\n" - " don't know anything about object type %s and no object" - "library defined\n",i->name(),type.c_str()); + " don't know anything about object type %s and no object" + "library defined\n",i->name(),type.c_str()); return 0; } EGS_Library *lib = 0; - for(unsigned int j=0; jlibraryName() ) { - lib = libs[j]; break; + for (unsigned int j=0; jlibraryName()) { + lib = libs[j]; + break; } } - if( !lib ) { + if (!lib) { lib = new EGS_Library(libname.c_str(),dso_path.c_str()); lib->load(); - if( !lib->isLoaded() ) { + if (!lib->isLoaded()) { egsWarning("EGS_ObjectFactory::createObject(): " - "failed to load the library %s from %s\n", - libname.c_str(),dso_path.c_str()); + "failed to load the library %s from %s\n", + libname.c_str(),dso_path.c_str()); return 0; } libs.push_back(lib); @@ -211,30 +244,36 @@ EGS_Object* EGS_ObjectFactory::createSingleObject(EGS_Input *i, EGS_ObjectCreationFunction create; const char *fname = funcname ? funcname : "createObject"; create = (EGS_ObjectCreationFunction) lib->resolve(fname); - if( !create ) { + if (!create) { egsWarning("EGS_ObjectFactory::createObject():\n" - " failed to resolve the '%s' function in the library %s\n", - fname,lib->libraryName()); + " failed to resolve the '%s' function in the library %s\n", + fname,lib->libraryName()); return 0; } EGS_Object *o = create(i,this); - if( addObject(o,unique) ) return o; - EGS_Object::deleteObject(o); return 0; + if (addObject(o,unique)) { + return o; + } + EGS_Object::deleteObject(o); + return 0; } bool EGS_ObjectFactory::addObject(EGS_Object *o, bool unique) { - if( !o ) { + if (!o) { egsWarning("EGS_ObjectFactory::addObject(): attempt to add a null" - " object\n"); return false; + " object\n"); + return false; } - for(unsigned int j=0; jgetObjectName() == objects[j]->getObjectName() ) { + if (unique) { + for (unsigned int j=0; jgetObjectName() == objects[j]->getObjectName()) { egsWarning("EGS_ObjectFactory::addObject(): an object with " - "the name %s already exists\n",o->getObjectName().c_str()); + "the name %s already exists\n",o->getObjectName().c_str()); //if( o->deref() == -1 ) delete o; return false; } @@ -242,37 +281,48 @@ bool EGS_ObjectFactory::addObject(EGS_Object *o, bool unique) { } //egsWarning("adding an object with name '%s' of type '%s' at 0x%x\n", // o->getObjectName().c_str(),o->getObjectType().c_str(),o); - objects.push_back(o); o->setFactory(this); return true; + objects.push_back(o); + o->setFactory(this); + return true; } bool EGS_ObjectFactory::haveObject(const EGS_Object *o) const { - for(unsigned int j=0; jgetObjectName() ) +EGS_Object *EGS_ObjectFactory::getObject(const string &name) { + for (unsigned int j=0; jgetObjectName()) { return objects[j]; + } } return 0; } -EGS_Object* EGS_ObjectFactory::takeObject(const string &name) { - for(vector::iterator i = objects.begin(); +EGS_Object *EGS_ObjectFactory::takeObject(const string &name) { + for (vector::iterator i = objects.begin(); i != objects.end(); i++) { - if( (*i)->getObjectName() == name ) { - (*i)->deref(); objects.erase(i); return *i; + if ((*i)->getObjectName() == name) { + (*i)->deref(); + objects.erase(i); + return *i; } } return 0; } void EGS_ObjectFactory::addKnownTypeId(const char *typeid_name) { - if( !typeid_name ) return; - for(int j=0; jderef() ) delete o; + if (!o) { + return; + } + if (!o->deref()) { + delete o; + } }; protected: @@ -221,8 +237,9 @@ class EGS_EXPORT EGS_ObjectFactory { when constructing objects with createSingleObject(). */ virtual void addKnownObject(EGS_Object *o) { - if( o ) { - o->ref(); known_objects.push_back(o); + if (o) { + o->ref(); + known_objects.push_back(o); } }; @@ -249,7 +266,7 @@ class EGS_EXPORT EGS_ObjectFactory { to the newly created object. In all other cases \c null is returned. */ virtual EGS_Object *createSingleObject(EGS_Input *inp, - const char *funcname = 0, bool unique = true); + const char *funcname = 0, bool unique = true); /*! \brief Create all objects specified by the information \a inp. @@ -279,8 +296,8 @@ class EGS_EXPORT EGS_ObjectFactory { as in createSingleObject(). */ EGS_Object *createObjects(EGS_Input *inp, const string §ion_delimeter, - const string &object_delimeter, const string &select_key, - const char *funcname = 0, bool unique = true); + const string &object_delimeter, const string &select_key, + const char *funcname = 0, bool unique = true); /*! \brief Does the factory own the object pointed to by \a o? @@ -331,10 +348,14 @@ class EGS_EXPORT EGS_ObjectFactory { void addKnownTypeId(const char *typeid_name); /*! \brief Get the number of objects this factory has created so far */ - int nObjects() const { return objects.size(); }; + int nObjects() const { + return objects.size(); + }; /*! \brief Get the \a j'th object */ - EGS_Object* getObject(int j) { return (j>=0 && j=0 && j(o); bool res; - if( t ) res = true; - else res = isKnownTypeId(o); - if( !res && func ) egsWarning("EGS_TypedObjectFactory::%s:\n" - " dynamic_cast to %s fails for object of type %s\n" - " This object's typeid is also not in the list of know typeids\n", - func,otype.c_str(),o->getObjectType().c_str()); + if (t) { + res = true; + } + else { + res = isKnownTypeId(o); + } + if (!res && func) egsWarning("EGS_TypedObjectFactory::%s:\n" + " dynamic_cast to %s fails for object of type %s\n" + " This object's typeid is also not in the list of know typeids\n", + func,otype.c_str(),o->getObjectType().c_str()); return res; }; void addKnownObject(EGS_Object *o) { - if( isMyObjectType(o,"addKnownObject()") ) + if (isMyObjectType(o,"addKnownObject()")) { EGS_ObjectFactory::addKnownObject(o); + } EGS_ObjectFactory::addKnownObject(o); }; EGS_Object *createSingleObject(EGS_Input *i, - const char *fname = 0, bool u = true) { + const char *fname = 0, bool u = true) { EGS_Object *o = EGS_ObjectFactory::createSingleObject(i,fname,u); - if( o ) { - if( !isMyObjectType(o,"createSingleObject()") ) { - delete o; o = 0; + if (o) { + if (!isMyObjectType(o,"createSingleObject()")) { + delete o; + o = 0; } } return o; }; bool addObject(EGS_Object *o, bool unique = true) { - if( !isMyObjectType(o,"addObject()") ) return false; + if (!isMyObjectType(o,"addObject()")) { + return false; + } return EGS_ObjectFactory::addObject(o,unique); }; diff --git a/HEN_HOUSE/egs++/egs_particle_track.cpp b/HEN_HOUSE/egs++/egs_particle_track.cpp index ee92dba23..c29ad38f0 100644 --- a/HEN_HOUSE/egs++/egs_particle_track.cpp +++ b/HEN_HOUSE/egs++/egs_particle_track.cpp @@ -35,29 +35,41 @@ void EGS_ParticleTrack::grow() { // calculate the new size of the vertex array int new_size = m_size > 0 ? m_size*2 : 16; // not enough ?? then allocate more - if (m_nVertices > new_size) new_size = m_nVertices; + if (m_nVertices > new_size) { + new_size = m_nVertices; + } Vertex **tmp = new Vertex* [new_size]; if (m_track) { for (int i = 0; i < m_nVertices; ++i) { tmp[i] = m_track[i]; } - delete [] m_track; m_track = NULL; + delete [] m_track; + m_track = NULL; } - m_track = tmp; m_size = new_size; + m_track = tmp; + m_size = new_size; } void EGS_ParticleTrack::clearTrack() { - if (m_pInfo) delete m_pInfo; m_pInfo = NULL; + if (m_pInfo) { + delete m_pInfo; + } + m_pInfo = NULL; if (m_track) for (int i = 0; i < m_nVertices; i++) { - if (m_track[i]) delete m_track[i]; m_track[i] = NULL; + if (m_track[i]) { + delete m_track[i]; + } + m_track[i] = NULL; } m_nVertices = 0; } int EGS_ParticleTrack::writeTrack(ofstream *trsp) { // no need to write the track if it has less than 2 vertices ... - if (m_nVertices < 2) return 1; + if (m_nVertices < 2) { + return 1; + } trsp->write((char *)&m_nVertices, sizeof(int)); trsp->write((char *)m_pInfo, sizeof(ParticleInfo)); for (int i = 0; i < m_nVertices; i++) { @@ -66,8 +78,10 @@ int EGS_ParticleTrack::writeTrack(ofstream *trsp) { return 0; } -EGS_ParticleTrack::Vertex* EGS_ParticleTrack::getVertex(int v) { - if ((v < 0) || (v >= m_nVertices)) return NULL; +EGS_ParticleTrack::Vertex *EGS_ParticleTrack::getVertex(int v) { + if ((v < 0) || (v >= m_nVertices)) { + return NULL; + } return (m_track[v]); } @@ -75,14 +89,18 @@ void EGS_ParticleTrack::addVertex(Vertex *x) { m_track[m_nVertices] = x; m_nVertices++; // resize the vertex array if necessary - if (m_nVertices >= m_size) grow(); + if (m_nVertices >= m_size) { + grow(); + } } ///////////////////////// EGS_ParticleTrackContainer //////////////////////// void EGS_ParticleTrackContainer::startNewTrack() { // buffer full ? flush it - if (m_nTracks >= m_bufferSize) flushBuffer(); + if (m_nTracks >= m_bufferSize) { + flushBuffer(); + } m_nTracks++; // mark the track as being scored @@ -90,7 +108,9 @@ void EGS_ParticleTrackContainer::startNewTrack() { } void EGS_ParticleTrackContainer::startNewTrack(int stackIndex) { - if (m_nTracks >= m_bufferSize) flushBuffer(); + if (m_nTracks >= m_bufferSize) { + flushBuffer(); + } m_nTracks++; // map the track on the stack @@ -99,7 +119,9 @@ void EGS_ParticleTrackContainer::startNewTrack(int stackIndex) { } void EGS_ParticleTrackContainer::startNewTrack(EGS_ParticleTrack::ParticleInfo *p) { - if (m_nTracks >= m_bufferSize) flushBuffer(); + if (m_nTracks >= m_bufferSize) { + flushBuffer(); + } m_nTracks++; m_isScoring[m_nTracks-1] = true; m_buffer[m_nTracks-1]->setParticleInfo(p); @@ -107,14 +129,17 @@ void EGS_ParticleTrackContainer::startNewTrack(EGS_ParticleTrack::ParticleInfo * void EGS_ParticleTrackContainer::flushBuffer() { int save = 0; - if ( m_trspFile ) { + if (m_trspFile) { for (int i = 0; i < m_nTracks; i++) { // if the particle is not being scored anymore if (!m_isScoring[i]) { // output it to the file and free memory - if (!m_buffer[i]->writeTrack(m_trspFile)) m_totalTracks++; + if (!m_buffer[i]->writeTrack(m_trspFile)) { + m_totalTracks++; + } m_buffer[i]->clearTrack(); - } else { + } + else { // still scoring it -> save the particle m_buffer[save] = m_buffer[i]; m_isScoring[i] = false; @@ -142,18 +167,24 @@ void EGS_ParticleTrackContainer::updateHeader() { } } -EGS_ParticleTrack::Vertex* EGS_ParticleTrackContainer::getTrackVertex(int tr, int v) { - if ((tr < 0) || (tr >= m_nTracks)) return NULL; +EGS_ParticleTrack::Vertex *EGS_ParticleTrackContainer::getTrackVertex(int tr, int v) { + if ((tr < 0) || (tr >= m_nTracks)) { + return NULL; + } return (m_buffer[tr]->getVertex(v)); } void EGS_ParticleTrackContainer::addVertex(EGS_ParticleTrack::Vertex *x) { - if ( !m_isScoring[m_nTracks-1] ) return; + if (!m_isScoring[m_nTracks-1]) { + return; + } m_buffer[m_nTracks-1]->addVertex(x); } void EGS_ParticleTrackContainer::addVertex(int stackIndex, EGS_ParticleTrack::Vertex *x) { - if ( !m_isScoring[m_stackMap[stackIndex]] ) return; + if (!m_isScoring[m_stackMap[stackIndex]]) { + return; + } m_buffer[m_stackMap[stackIndex]]->addVertex(x); } @@ -162,7 +193,7 @@ int EGS_ParticleTrackContainer::readDataFile(const char *filename) { ifstream *data = new ifstream(filename, ios::binary); if (!data || data->fail() || !data->good()) { egsWarning("%s: Unable to open track space file '%s'! No tracks loaded\n", - func_name, filename); + func_name, filename); return -1; } data->read((char *)&m_totalTracks, sizeof(int)); @@ -184,7 +215,7 @@ int EGS_ParticleTrackContainer::readDataFile(const char *filename) { data->read((char *)pinfo,sizeof(EGS_ParticleTrack::ParticleInfo)); startNewTrack(pinfo); for (int j = 0; j < nvertices; j++) { - EGS_ParticleTrack::Vertex* v = new EGS_ParticleTrack::Vertex(); + EGS_ParticleTrack::Vertex *v = new EGS_ParticleTrack::Vertex(); data->read((char *)v,sizeof(EGS_ParticleTrack::Vertex)); addVertex(v); } @@ -203,11 +234,13 @@ void EGS_ParticleTrackContainer::reportResults(bool with_header) { if (m_isScoring) { scoring = 0; for (int i = 0; i < m_bufferSize; i++) { - if (m_isScoring[i]) scoring++; + if (m_isScoring[i]) { + scoring++; + } } } - if( with_header ) { + if (with_header) { egsInformation("\nParticle track scoring results:\n"); egsInformation("=================================\n"); egsInformation(" Total events scored: %d\n", m_nEvents); @@ -216,7 +249,8 @@ void EGS_ParticleTrackContainer::reportResults(bool with_header) { egsInformation(" Still being scored: "); if (scoring == -1) { egsInformation("Unknown!?\n"); - } else { + } + else { egsInformation("%d\n", scoring); if (scoring > 0) { egsWarning(" *** There are particles still being tracked. This" diff --git a/HEN_HOUSE/egs++/egs_particle_track.h b/HEN_HOUSE/egs++/egs_particle_track.h index 78c321871..5c1626156 100644 --- a/HEN_HOUSE/egs++/egs_particle_track.h +++ b/HEN_HOUSE/egs++/egs_particle_track.h @@ -67,16 +67,26 @@ class EGS_EXPORT EGS_ParticleTrack { Vertex() : x(0,0,0), e(0) {}; Vertex(EGS_Float px, EGS_Float py, EGS_Float pz) { - x.x = px; x.y = py; x.z = pz; e = 1;}; + x.x = px; + x.y = py; + x.z = pz; + e = 1; + }; Vertex(EGS_Float px, EGS_Float py, EGS_Float pz, EGS_Float pe) { - x.x = px; x.y = py; x.z = pz; e = pe;}; + x.x = px; + x.y = py; + x.z = pz; + e = pe; + }; Vertex(const EGS_Vector &px, EGS_Float pe) : x(px), e(pe) {}; }; /*! \brief Structure describing the particle being tracked. */ struct ParticleInfo { EGS_I32 q; //!< particle charge - ParticleInfo(EGS_I32 pq) { q = pq; }; + ParticleInfo(EGS_I32 pq) { + q = pq; + }; ~ParticleInfo() { }; }; @@ -88,7 +98,10 @@ class EGS_EXPORT EGS_ParticleTrack { /*! \brief The destructor. Deallocate all memory. */ ~EGS_ParticleTrack() { clearTrack(); - if (m_track) delete [] m_track; m_track = NULL; + if (m_track) { + delete [] m_track; + } + m_track = NULL; }; /*! \brief Deallocate particle information and vertex data. @@ -113,16 +126,22 @@ class EGS_EXPORT EGS_ParticleTrack { If \a v is less than 0 or greater than m_nVertices - 1 the return value is \c NULL . */ - Vertex* getVertex(int v); + Vertex *getVertex(int v); /*! \brief Get number of vertices currently in the track. */ - int getNumVertices() { return m_nVertices; }; + int getNumVertices() { + return m_nVertices; + }; /*! \brief Define the type of the particle being tracked. */ - void setParticleInfo(ParticleInfo *p) { m_pInfo = p; }; + void setParticleInfo(ParticleInfo *p) { + m_pInfo = p; + }; /*! \brief Get the type of the particle being tracked. */ - ParticleInfo* getParticleInfo() { return m_pInfo; }; + ParticleInfo *getParticleInfo() { + return m_pInfo; + }; protected: @@ -152,8 +171,8 @@ class EGS_EXPORT EGS_ParticleTrackContainer { /*! \brief Basic Constructor. Initializes all variables. */ EGS_ParticleTrackContainer() : m_nEvents(0), m_nTracks(0), - m_totalTracks(0), m_stackMap(NULL), m_isScoring(NULL), m_bufferSize(0), - m_buffer(NULL), m_trspFile(NULL) {}; + m_totalTracks(0), m_stackMap(NULL), m_isScoring(NULL), m_bufferSize(0), + m_buffer(NULL), m_trspFile(NULL) {}; /*! \brief Constructor. @@ -162,9 +181,9 @@ class EGS_EXPORT EGS_ParticleTrackContainer { \a buf_size which defines how many tracks the container will store before flushing them to the output file. */ - EGS_ParticleTrackContainer(const char* fname, int buf_size) : m_nEvents(0), - m_nTracks(0), m_totalTracks(0), m_isScoring(NULL), m_bufferSize(0), m_buffer(0), - m_trspFile(NULL) { + EGS_ParticleTrackContainer(const char *fname, int buf_size) : m_nEvents(0), + m_nTracks(0), m_totalTracks(0), m_isScoring(NULL), m_bufferSize(0), m_buffer(0), + m_trspFile(NULL) { m_bufferSize = buf_size; // initialize the arrays @@ -188,25 +207,41 @@ class EGS_EXPORT EGS_ParticleTrackContainer { /*! \brief The Destructor. Deallocate all allocated memory. */ ~EGS_ParticleTrackContainer() { // if any particles are left in memory -> flush them to the file - if (m_nTracks > 0) flushBuffer(); + if (m_nTracks > 0) { + flushBuffer(); + } if (m_buffer) { for (int i = 0; i < m_bufferSize; i++) { - if (m_buffer[i]) - delete m_buffer[i]; m_buffer[i] = NULL; + if (m_buffer[i]) { + delete m_buffer[i]; + } + m_buffer[i] = NULL; } - delete [] m_buffer; m_buffer = NULL; + delete [] m_buffer; + m_buffer = NULL; + } + if (m_stackMap) { + delete [] m_stackMap; } - if (m_stackMap) delete [] m_stackMap; - if (m_isScoring) delete [] m_isScoring; - if (m_trspFile) delete m_trspFile; m_trspFile = NULL; + if (m_isScoring) { + delete [] m_isScoring; + } + if (m_trspFile) { + delete m_trspFile; + } + m_trspFile = NULL; }; /*! \brief Save the number of events (for example, decays) tracked so far. */ - void setEvents(int e) { m_nEvents = e; } + void setEvents(int e) { + m_nEvents = e; + } /*! \brief Get the number of events tracked so far. */ - int getEvents() { return m_nEvents; } + int getEvents() { + return m_nEvents; + } /*! \brief Get the number of vertices in the track currently being scorred */ int getCurrentNumVertices() { @@ -227,10 +262,12 @@ class EGS_EXPORT EGS_ParticleTrackContainer { /*! \brief Get the \a v vertex from the \a tr track. \todo Have to test this method. */ - EGS_ParticleTrack::Vertex* getTrackVertex(int tr, int v); + EGS_ParticleTrack::Vertex *getTrackVertex(int tr, int v); /*! \brief Are we still scoring the current particle? */ - bool isScoringParticle() { return m_isScoring[m_nTracks-1]; } + bool isScoringParticle() { + return m_isScoring[m_nTracks-1]; + } /*! \brief Are we still scoring the particle mapped by the stack? */ bool isScoringParticle(int stackIndex) { @@ -238,7 +275,9 @@ class EGS_EXPORT EGS_ParticleTrackContainer { } /*! \brief Stop scoring the current particle. */ - void stopScoringParticle() { m_isScoring[m_nTracks-1] = false; } + void stopScoringParticle() { + m_isScoring[m_nTracks-1] = false; + } /*! \brief Stop scoring the particle mapped by the stack. */ void stopScoringParticle(int stackIndex) { diff --git a/HEN_HOUSE/egs++/egs_polygon.cpp b/HEN_HOUSE/egs++/egs_polygon.cpp index 0d8ab2c9e..2bc3446bf 100644 --- a/HEN_HOUSE/egs++/egs_polygon.cpp +++ b/HEN_HOUSE/egs++/egs_polygon.cpp @@ -38,93 +38,151 @@ bool EGS_2DPolygon::checkCCW(const vector &points) { double A = 0; - for(int j=0; j 0 ) return true; else return false; + } + if (A > 0) { + return true; + } + else { + return false; + } } EGS_2DPolygon::~EGS_2DPolygon() { - delete [] a; delete [] p; delete [] d; delete [] pc; delete [] uj; - if( !is_convex ) { + delete [] a; + delete [] p; + delete [] d; + delete [] pc; + delete [] uj; + if (!is_convex) { delete cpol; - for(int j=0; j &points, bool Open) { - int n = points.size(); open = Open; + int n = points.size(); + open = Open; EGS_2DVector test(points[0]-points[n-1]); - if( test.length2() > 1e-8 ) { - points.push_back(points[0]); n++; + if (test.length2() > 1e-8) { + points.push_back(points[0]); + n++; } bool ccw = checkCCW(points); // Remove points that are too close to each other. EGS_2DVector *pp = new EGS_2DVector [n]; - pp[0] = points[0]; int jj=1; int j; - for(j=1; j 1e-8 ) pp[jj++] = points[j]; + if (aux.length2() > 1e-8) { + pp[jj++] = points[j]; + } } n = jj; // now check for points on a line - for(j=0; j xmax ) xmax = p[j].x; - if( p[j].y < ymin ) ymin = p[j].y; - if( p[j].y > ymax ) ymax = p[j].y; + if (p[j].x < xmin) { + xmin = p[j].x; + } + if (p[j].x > xmax) { + xmax = p[j].x; + } + if (p[j].y < ymin) { + ymin = p[j].y; + } + if (p[j].y > ymax) { + ymax = p[j].y; + } uj[j] = p[j+1]-p[j]; - if( ccw ) a[j] = EGS_2DVector(-uj[j].y,uj[j].x); - else a[j] = EGS_2DVector(uj[j].y,-uj[j].x); + if (ccw) { + a[j] = EGS_2DVector(-uj[j].y,uj[j].x); + } + else { + a[j] = EGS_2DVector(uj[j].y,-uj[j].x); + } a[j].normalize(); d[j] = a[j]*p[j]; } // now see if the polygon is convex is_convex = true; - if( np == 4 ) return; // triangles are always convex. + if (np == 4) { + return; // triangles are always convex. + } open = false; // we can not have open polygons - for(j=0; j j+1 ) if( !inside(j,p[i]) ) { is_ok=false; break; } + for (int i=0; i j+1) if (!inside(j,p[i])) { + is_ok=false; + break; + } } - if( is_ok ) { // found the point + if (is_ok) { // found the point jstart = j; - pp = new EGS_2DVector [np]; int jj=0; int i; - for(i=j; i &points, bool Open) { vector chull; vector ipol; vector tmp_pol; - chull.push_back(pp[0]); chull.push_back(pp[1]); int nc=2; - j=2; bool doing_chull=true; - while(1) { + chull.push_back(pp[0]); + chull.push_back(pp[1]); + int nc=2; + j=2; + bool doing_chull=true; + while (1) { EGS_2DVector s(pp[j]-chull[nc-1]); EGS_2DVector sperp(-s.y,s.x); - if( !ccw ) sperp *= (-1.); + if (!ccw) { + sperp *= (-1.); + } EGS_Float ds = sperp*chull[nc-1]; bool all_inside=true; - for(int i=j+1; i= n ) break; + j++; + if (j >= n) { + break; + } } cpol = new EGS_2DPolygon(chull); ncut = tmp_pol.size(); cut = new EGS_2DPolygon* [ncut]; - for(j=0; j= 0 && j < np-1 ) return a[j]; else return EGS_2DVector(); + if (j >= 0 && j < np-1) { + return a[j]; + } + else { + return EGS_2DVector(); + } }; /*! \brief Get the nearest distance from \a x to the polygon. @@ -87,50 +96,80 @@ class EGS_EXPORT EGS_2DPolygon { inside the polygon, \a false otherwise. */ EGS_Float hownear(bool in, const EGS_2DVector &x) const { - if( !open ) { - EGS_Float tperp = 1e30; bool do_it = true; - for(int j=0; j= 0 && lam <= uj[j].length2() ) { - do_it = false; EGS_Float t = fabs(d[j] - x*a[j]); - if( t < tperp ) tperp = t; + if (lam >= 0 && lam <= uj[j].length2()) { + do_it = false; + EGS_Float t = fabs(d[j] - x*a[j]); + if (t < tperp) { + tperp = t; + } + } + else if (lam < 0 && do_it) { + EGS_Float t = v.length(); + if (t < tperp) { + tperp = t; + } } - else if( lam < 0 && do_it ) { - EGS_Float t = v.length(); if( t < tperp ) tperp = t; + else { + do_it = true; } - else do_it = true; } return tperp; } - EGS_2DVector v(x - p[0]); EGS_Float lam = uj[0]*v; - EGS_Float tperp; bool do_it; - if( lam <= uj[0].length2() ) { - do_it = false; tperp = fabs(d[0] - x*a[0]); - } else { do_it = true; tperp = 1e30; } - v = x - p[1]; lam = uj[1]*v; - if( lam >= 0 ) { + EGS_2DVector v(x - p[0]); + EGS_Float lam = uj[0]*v; + EGS_Float tperp; + bool do_it; + if (lam <= uj[0].length2()) { + do_it = false; + tperp = fabs(d[0] - x*a[0]); + } + else { + do_it = true; + tperp = 1e30; + } + v = x - p[1]; + lam = uj[1]*v; + if (lam >= 0) { EGS_Float t = fabs(d[1] - x*a[1]); - if( t < tperp ) tperp = t; + if (t < tperp) { + tperp = t; + } } - else if( do_it ) { - EGS_Float t = v.length(); if( t < tperp ) tperp = t; + else if (do_it) { + EGS_Float t = v.length(); + if (t < tperp) { + tperp = t; + } } return tperp; }; /*! \brief Is the 2D point \a x inside the polygon ? */ bool isInside(const EGS_2DVector &x) const { - if( !open && - (x.xxmax || x.yymax) ) return false; - if( is_convex ) { + if (!open && + (x.xxmax || x.yymax)) { + return false; + } + if (is_convex) { int nn = open ? np-2 : np-1; - for(int j=0; jisInside(x) ) return false; - for(int j=0; jisInside(x) ) return false; + if (!cpol->isInside(x)) { + return false; + } + for (int j=0; jisInside(x)) { + return false; + } return true; }; @@ -147,73 +186,93 @@ class EGS_EXPORT EGS_2DPolygon { */ bool howfar(bool in, const EGS_2DVector &x, const EGS_2DVector &u, EGS_Float &t, EGS_2DVector *normal = 0) { - EGS_Float xp, up; bool res = false; + EGS_Float xp, up; + bool res = false; int nn = open ? np-2 : np-1; - if( in ) { + if (in) { int jhit; - for(int j=0; j d[j] ) { + for (int j=0; j d[j]) { EGS_Float tt = d[j] - xp; - if( tt >= t*up ) { + if (tt >= t*up) { tt /= up; bool ok = is_convex || pc[j]; - if( !ok ) { + if (!ok) { EGS_Float lam = uj[j]*(x-p[j]+u*tt); - if( lam >= 0 && lam < uj[j].length2() ) ok = true; + if (lam >= 0 && lam < uj[j].length2()) { + ok = true; + } } - if( ok ) { - t = tt; res = true; jhit = j; + if (ok) { + t = tt; + res = true; + jhit = j; //if( normal ) *normal = a[j]; } } } } - if( res && normal ) *normal = a[jhit]; + if (res && normal) { + *normal = a[jhit]; + } } else { int jhit; - if( open ) { - if( (up = u*a[0]) > 0 && (xp = x*a[0]) < d[0] ) { + if (open) { + if ((up = u*a[0]) > 0 && (xp = x*a[0]) < d[0]) { EGS_Float tt = (d[0] - xp)/up; - if( tt <= t ) { + if (tt <= t) { EGS_Float lam = uj[0]*(x-p[0]+u*tt); - if( lam < uj[0].length2() ) { - t = tt; res = true; jhit = 0; + if (lam < uj[0].length2()) { + t = tt; + res = true; + jhit = 0; } } } - if( (up = u*a[1]) > 0 && (xp = x*a[1]) < d[1] ) { + if ((up = u*a[1]) > 0 && (xp = x*a[1]) < d[1]) { EGS_Float tt = (d[1] - xp)/up; - if( tt <= t ) { + if (tt <= t) { EGS_Float lam = uj[1]*(x-p[1]+u*tt); - if( lam > 0 ) { - t = tt; res = true; jhit = 1; + if (lam > 0) { + t = tt; + res = true; + jhit = 1; } } } } else { - for(int j=0; j 0 && (xp = x*a[j]) < d[j] ) { + for (int j=0; j 0 && (xp = x*a[j]) < d[j]) { EGS_Float tt = (d[j] - xp)/up; - if( tt <= t ) { + if (tt <= t) { EGS_Float lam = uj[j]*(x-p[j]+u*tt); - if( lam >= 0 && lam < uj[j].length2() ) { - t = tt; res = true; jhit = j; + if (lam >= 0 && lam < uj[j].length2()) { + t = tt; + res = true; + jhit = j; //if( normal ) *normal = a[j]*(-1); } } } } } - if( res && normal ) *normal = a[jhit]*(-1); + if (res && normal) { + *normal = a[jhit]*(-1); + } } return res; }; /*! \brief Get the \a j'th point of this polygon. */ EGS_2DVector getPoint(int j) const { - if( j >= 0 && j < np ) return p[j]; else return EGS_2DVector(); + if (j >= 0 && j < np) { + return p[j]; + } + else { + return EGS_2DVector(); + } }; @@ -241,7 +300,12 @@ class EGS_EXPORT EGS_2DPolygon { static bool checkCCW(const vector &points); /*! \brief Is the point \a x inside the \a j'th edge ? */ bool inside(int j, const EGS_2DVector &x) const { - if( x*a[j] >= d[j] ) return true; else return false; + if (x*a[j] >= d[j]) { + return true; + } + else { + return false; + } }; }; @@ -272,16 +336,22 @@ class EGS_EXPORT EGS_PolygonT { EGS_2DPolygon::EGS_2DPolygon(). */ EGS_PolygonT(vector &points, const T &projector, - bool Open=false) : p(new EGS_2DPolygon(points,Open)), a(projector) {}; + bool Open=false) : p(new EGS_2DPolygon(points,Open)), a(projector) {}; /*! \brief Destructor */ - ~EGS_PolygonT() { delete p; }; + ~EGS_PolygonT() { + delete p; + }; /*! \brief Is this polygon convex ? */ - inline bool isConvex() const { return p->isConvex(); }; + inline bool isConvex() const { + return p->isConvex(); + }; /*! \brief Get the number of polygon points */ - inline int getN() const { return p->getN(); }; + inline int getN() const { + return p->getN(); + }; /*! \brief Get the \a j'th point */ inline EGS_Vector getPoint(int j) const { @@ -289,7 +359,9 @@ class EGS_EXPORT EGS_PolygonT { }; /*! \brief Get the normal to the polygon plane */ - inline EGS_Vector getNormal() const { return a.normal(); }; + inline EGS_Vector getNormal() const { + return a.normal(); + }; /*! ? */ inline EGS_Vector getNormal(const EGS_2DVector &x) const { @@ -339,7 +411,9 @@ class EGS_EXPORT EGS_PolygonT { inline EGS_Float hownear(bool in, const EGS_Vector &x) const { EGS_2DVector pos(a.getProjection(x)); EGS_Float t1 = fabs(a.distance(x)); - if( p->isInside(pos) ) return t1; + if (p->isInside(pos)) { + return t1; + } EGS_Float t2 = p->hownear(true,pos); return sqrt(t1*t1+t2*t2); }; @@ -350,9 +424,11 @@ class EGS_EXPORT EGS_PolygonT { \sa EGS_2DPolygon::howfar() */ inline bool howfar2D(bool in, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, EGS_2DVector *normal = 0) const { + EGS_Float &t, EGS_2DVector *normal = 0) const { EGS_2DVector dir(a.getProjection(u)); - if( u.length2() < 1e-8 ) return false; + if (u.length2() < 1e-8) { + return false; + } return p->howfar(in,a.getProjection(x),dir,t,normal); }; @@ -365,17 +441,24 @@ class EGS_EXPORT EGS_PolygonT { inline bool howfar(bool in, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t) const { EGS_Float up = a*u; - if( in && up >= 0 || !in && up <= 0 ) return false; + if (in && up >= 0 || !in && up <= 0) { + return false; + } EGS_Float tt = -a.distance(x)/up; - if( tt <= t ) { + if (tt <= t) { EGS_Vector xp(x + u*tt); - if( p->isInside(a.getProjection(xp)) ) { t = tt; return true; } + if (p->isInside(a.getProjection(xp))) { + t = tt; + return true; + } } return false; }; /*! \brief Get the polygon type */ - const string &getType() const { return a.getType(); }; + const string &getType() const { + return a.getType(); + }; private: @@ -394,6 +477,6 @@ typedef EGS_PolygonT EGS_PolygonXY; typedef EGS_PolygonT EGS_Polygon; /*! \brief Make a polygon from the 3D points \a points */ -EGS_EXPORT EGS_Polygon* makePolygon(const vector &points); +EGS_EXPORT EGS_Polygon *makePolygon(const vector &points); #endif diff --git a/HEN_HOUSE/egs++/egs_projectors.cpp b/HEN_HOUSE/egs++/egs_projectors.cpp index ec95b2849..9ccd48282 100644 --- a/HEN_HOUSE/egs++/egs_projectors.cpp +++ b/HEN_HOUSE/egs++/egs_projectors.cpp @@ -39,21 +39,31 @@ EGS_Projector::EGS_Projector(const EGS_Vector &A, const string &Type) : a(A), xo(EGS_Vector()), d(0), type(Type) { - norm = a.length(); a.normalize(); - if( a.x*a.x + a.y*a.y > 0 ) { - v1 = EGS_Vector(-a.y,a.x,0); v1.normalize(); + norm = a.length(); + a.normalize(); + if (a.x*a.x + a.y*a.y > 0) { + v1 = EGS_Vector(-a.y,a.x,0); + v1.normalize(); + } + else { + v1 = EGS_Vector(1,0,0); } - else v1 = EGS_Vector(1,0,0); v2 = a%v1; } EGS_Projector::EGS_Projector(const EGS_Vector &x1, const EGS_Vector &x2, - const EGS_Vector &x3, const string &T) : type(T) { - v1 = x2-x1; v2 = x3-x1; a = v1%v2; xo = x1; - if( a.length2() < 1e-10 ) egsFatal("EGS_Projector::EGS_Projector: " - " the vectors are co-linear\n"); - a.normalize(); norm = 1; - v1.normalize(); v2 = a%v1; d = a*x1; + const EGS_Vector &x3, const string &T) : type(T) { + v1 = x2-x1; + v2 = x3-x1; + a = v1%v2; + xo = x1; + if (a.length2() < 1e-10) egsFatal("EGS_Projector::EGS_Projector: " + " the vectors are co-linear\n"); + a.normalize(); + norm = 1; + v1.normalize(); + v2 = a%v1; + d = a*x1; } void EGS_Projector::printInfo() const { diff --git a/HEN_HOUSE/egs++/egs_projectors.h b/HEN_HOUSE/egs++/egs_projectors.h index 4b0b7f2dd..1ffa6fe1d 100644 --- a/HEN_HOUSE/egs++/egs_projectors.h +++ b/HEN_HOUSE/egs++/egs_projectors.h @@ -58,36 +58,54 @@ class EGS_EXPORT EGS_2DVector { EGS_2DVector(EGS_Float X, EGS_Float Y) : x(X), y(Y) {}; EGS_2DVector(const EGS_2DVector &v) : x(v.x), y(v.y) {}; EGS_2DVector &operator=(const EGS_Vector &v) { - x = v.x; y = v.y; return *this; + x = v.x; + y = v.y; + return *this; }; EGS_2DVector operator+(const EGS_2DVector &v) const { return EGS_2DVector(x+v.x, y+v.y); }; EGS_2DVector &operator+=(const EGS_2DVector &v) { - x += v.x; y += v.y; return *this; + x += v.x; + y += v.y; + return *this; }; EGS_2DVector operator-(const EGS_2DVector &v) const { return EGS_2DVector(x-v.x, y-v.y); }; EGS_2DVector &operator-=(const EGS_2DVector &v) { - x -= v.x; y -= v.y; return *this; + x -= v.x; + y -= v.y; + return *this; }; EGS_2DVector operator*(const EGS_Float f) const { return EGS_2DVector(x*f,y*f); }; EGS_2DVector &operator*=(const EGS_Float f) { - x*=f; y*=f; return *this; + x*=f; + y*=f; + return *this; + }; + EGS_Float operator*(const EGS_2DVector &v) const { + return x*v.x + y*v.y; }; - EGS_Float operator*(const EGS_2DVector &v) const { return x*v.x + y*v.y; }; EGS_Float operator%(const EGS_2DVector &v) const { return x*v.y - y*v.x; }; EGS_Vector crossProduct(const EGS_2DVector &v) const { return EGS_Vector(0,0,x*v.y - y*v.x); }; - EGS_Float length() const { return sqrt(x*x+y*y); }; - EGS_Float length2() const { return x*x+y*y; }; - void normalize() { EGS_Float tmp=1./length(); x*=tmp; y*=tmp; }; + EGS_Float length() const { + return sqrt(x*x+y*y); + }; + EGS_Float length2() const { + return x*x+y*y; + }; + void normalize() { + EGS_Float tmp=1./length(); + x*=tmp; + y*=tmp; + }; }; @@ -101,20 +119,34 @@ class EGS_EXPORT EGS_2DVector { class EGS_EXPORT EGS_XProjector { public: EGS_XProjector(const string &Type) : type(Type) {}; - EGS_Float operator*(const EGS_Vector &x) const { return x.x; }; - EGS_Vector operator*(EGS_Float t) const { return EGS_Vector(t,0,0); }; - EGS_Float length() const { return 1; }; + EGS_Float operator*(const EGS_Vector &x) const { + return x.x; + }; + EGS_Vector operator*(EGS_Float t) const { + return EGS_Vector(t,0,0); + }; + EGS_Float length() const { + return 1; + }; EGS_2DVector getProjection(const EGS_Vector &x) const { return EGS_2DVector(x.y,x.z); }; - EGS_Float distance(const EGS_Vector &x) const { return x.x; } - const string &getType() const { return type; }; + EGS_Float distance(const EGS_Vector &x) const { + return x.x; + } + const string &getType() const { + return type; + }; void printInfo() const {}; - EGS_Vector normal() const { return EGS_Vector(1,0,0); }; + EGS_Vector normal() const { + return EGS_Vector(1,0,0); + }; EGS_Vector normal(const EGS_2DVector &x) const { return EGS_Vector(0,x.x,x.y); }; - EGS_Vector getPoint(const EGS_2DVector &x) const { return normal(x); }; + EGS_Vector getPoint(const EGS_2DVector &x) const { + return normal(x); + }; private: string type; }; @@ -129,20 +161,34 @@ class EGS_EXPORT EGS_XProjector { class EGS_EXPORT EGS_YProjector { public: EGS_YProjector(const string &Type) : type(Type) {}; - EGS_Float operator*(const EGS_Vector &x) const { return x.y; }; - EGS_Vector operator*(EGS_Float t) const { return EGS_Vector(0,t,0); }; - EGS_Float length() const { return 1; }; + EGS_Float operator*(const EGS_Vector &x) const { + return x.y; + }; + EGS_Vector operator*(EGS_Float t) const { + return EGS_Vector(0,t,0); + }; + EGS_Float length() const { + return 1; + }; EGS_2DVector getProjection(const EGS_Vector &x) const { return EGS_2DVector(x.x,x.z); }; - EGS_Float distance(const EGS_Vector &x) const { return x.y; } - const string &getType() const { return type; }; + EGS_Float distance(const EGS_Vector &x) const { + return x.y; + } + const string &getType() const { + return type; + }; void printInfo() const {}; - EGS_Vector normal() const { return EGS_Vector(0,1,0); }; + EGS_Vector normal() const { + return EGS_Vector(0,1,0); + }; EGS_Vector normal(const EGS_2DVector &x) const { return EGS_Vector(x.x,0,x.y); }; - EGS_Vector getPoint(const EGS_2DVector &x) const { return normal(x); }; + EGS_Vector getPoint(const EGS_2DVector &x) const { + return normal(x); + }; private: string type; }; @@ -157,20 +203,34 @@ class EGS_EXPORT EGS_YProjector { class EGS_EXPORT EGS_ZProjector { public: EGS_ZProjector(const string &Type) : type(Type) {}; - EGS_Float operator*(const EGS_Vector &x) const { return x.z; }; - EGS_Vector operator*(EGS_Float t) const { return EGS_Vector(0,0,t); }; - EGS_Float length() const { return 1; }; + EGS_Float operator*(const EGS_Vector &x) const { + return x.z; + }; + EGS_Vector operator*(EGS_Float t) const { + return EGS_Vector(0,0,t); + }; + EGS_Float length() const { + return 1; + }; EGS_2DVector getProjection(const EGS_Vector &x) const { return EGS_2DVector(x.x,x.y); }; - EGS_Float distance(const EGS_Vector &x) const { return x.z; } - const string &getType() const { return type; }; + EGS_Float distance(const EGS_Vector &x) const { + return x.z; + } + const string &getType() const { + return type; + }; void printInfo() const {}; - EGS_Vector normal() const { return EGS_Vector(0,0,1); }; + EGS_Vector normal() const { + return EGS_Vector(0,0,1); + }; EGS_Vector normal(const EGS_2DVector &x) const { return EGS_Vector(x.x,x.y,0); }; - EGS_Vector getPoint(const EGS_2DVector &x) const { return normal(x); }; + EGS_Vector getPoint(const EGS_2DVector &x) const { + return normal(x); + }; private: string type; }; @@ -191,13 +251,19 @@ class EGS_EXPORT EGS_Projector { const EGS_Vector &x3, const string &Type); /*! \brief Get the scalar product between \a x and the plane normal */ - EGS_Float operator*(const EGS_Vector &x) const { return a*x; }; + EGS_Float operator*(const EGS_Vector &x) const { + return a*x; + }; /*! \brief Get the plane normal scaled by \a t */ - EGS_Vector operator*(EGS_Float t) const { return a*t; }; + EGS_Vector operator*(EGS_Float t) const { + return a*t; + }; /*! \brief Get the length of the plane normal */ - EGS_Float length() const { return norm; }; + EGS_Float length() const { + return norm; + }; /*! \brief Get the 2D projection of the vector \a x onto the plane */ EGS_2DVector getProjection(const EGS_Vector &x) const { @@ -206,16 +272,22 @@ class EGS_EXPORT EGS_Projector { /*! \brief Get the distance from \a x to the plane (positive, negative or zero, depending on which side of the plane the position \a x is). */ - EGS_Float distance(const EGS_Vector &x) const { return x*a-d; } + EGS_Float distance(const EGS_Vector &x) const { + return x*a-d; + } /*! \brief Get the name (type) of this projector */ - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; /*! \brief Print some info about this projector using egsInformation */ void printInfo() const; /*! \brief Get the normal to the projection plane */ - EGS_Vector normal() const { return a; }; + EGS_Vector normal() const { + return a; + }; /*! \brief ? */ EGS_Vector normal(const EGS_2DVector &x) const { diff --git a/HEN_HOUSE/egs++/egs_rndm.cpp b/HEN_HOUSE/egs++/egs_rndm.cpp index 4876f0c95..e4e11c9b7 100644 --- a/HEN_HOUSE/egs++/egs_rndm.cpp +++ b/HEN_HOUSE/egs++/egs_rndm.cpp @@ -46,52 +46,85 @@ using namespace std; void EGS_RandomGenerator::allocate(int n) { - if( n < 1 ) egsFatal("Attempt to construct a RNG with n < 1\n"); - rarray = new EGS_Float[n]; np = n; ip = np; + if (n < 1) { + egsFatal("Attempt to construct a RNG with n < 1\n"); + } + rarray = new EGS_Float[n]; + np = n; + ip = np; } void EGS_RandomGenerator::copyBaseState(const EGS_RandomGenerator &r) { - if( np > 0 && np != r.np ) { - delete [] rarray; np = 0; + if (np > 0 && np != r.np) { + delete [] rarray; + np = 0; + } + if (np <= 0) { + allocate(r.np); + } + ip = r.ip; + have_x = r.have_x; + the_x = r.the_x; + count = r.count; + for (int j=ip; j> np1 >> ip; - if( !data.good() || data.fail() || data.eof() ) return false; - if( np1 < 1 ) return false; - if( np1 != np && np > 0 ) { - delete [] rarray; rarray = new EGS_Float [np1]; + if (!data.good() || data.fail() || data.eof()) { + return false; + } + if (np1 < 1) { + return false; + } + if (np1 != np && np > 0) { + delete [] rarray; + rarray = new EGS_Float [np1]; } np = np1; - for(int j=0; j> rarray[j]; - if( !data.good() ) return false; + for (int j=0; j> rarray[j]; + } + if (!data.good()) { + return false; + } return setPrivateState(data); } bool EGS_RandomGenerator::addState(istream &data) { EGS_I64 count_save = count; - if( !setState(data) ) return false; + if (!setState(data)) { + return false; + } count += count_save; return true; } @@ -109,16 +142,22 @@ class EGS_LOCAL EGS_Ranmar : public EGS_RandomGenerator { * initial seeds. */ EGS_Ranmar(int ixx=1802, int jxx=9373, int n=128) : - EGS_RandomGenerator(n), copy(0), high_res(false) { setState(ixx,jxx); }; + EGS_RandomGenerator(n), copy(0), high_res(false) { + setState(ixx,jxx); + }; EGS_Ranmar(const EGS_Ranmar &r) : EGS_RandomGenerator(r), ix(r.ix), jx(r.jx), c(r.c), iseed1(r.iseed1), iseed2(r.iseed2), high_res(r.high_res) { - for(int j=0; j<97; j++) u[j] = r.u[j]; + for (int j=0; j<97; j++) { + u[j] = r.u[j]; + } }; ~EGS_Ranmar() { - if( copy ) delete copy; + if (copy) { + delete copy; + } }; /*! \brief Fill the array pointed to by \a array with random numbers @@ -128,16 +167,20 @@ class EGS_LOCAL EGS_Ranmar : public EGS_RandomGenerator { /*! \brief Output information about this RNG using egsInformation() */ void describeRNG() const; - EGS_RandomGenerator* getCopy(); + EGS_RandomGenerator *getCopy(); void setState(EGS_RandomGenerator *r); void saveState(); void resetState(); - int rngSize() const { return baseSize() + 102*sizeof(int); }; + int rngSize() const { + return baseSize() + 102*sizeof(int); + }; - void setHighResolution(bool hr) { high_res = hr; }; + void setHighResolution(bool hr) { + high_res = hr; + }; protected: @@ -150,9 +193,14 @@ class EGS_LOCAL EGS_Ranmar : public EGS_RandomGenerator { void set(const EGS_Ranmar &r) { copyBaseState(r); - ix = r.ix; jx = r.jx; c = r.c; - iseed1 = r.iseed1; iseed2 = r.iseed2; - for(int j=0; j<97; j++) u[j] = r.u[j]; + ix = r.ix; + jx = r.jx; + c = r.c; + iseed1 = r.iseed1; + iseed2 = r.iseed2; + for (int j=0; j<97; j++) { + u[j] = r.u[j]; + } }; private: @@ -172,44 +220,62 @@ class EGS_LOCAL EGS_Ranmar : public EGS_RandomGenerator { }; void EGS_Ranmar::saveState() { - if( copy ) copy->set(*this); - else copy = new EGS_Ranmar(*this); + if (copy) { + copy->set(*this); + } + else { + copy = new EGS_Ranmar(*this); + } copy->copy = 0; } void EGS_Ranmar::resetState() { - if( copy ) { + if (copy) { EGS_Ranmar *tmp = copy; - set(*copy); copy = tmp; + set(*copy); + copy = tmp; } } -EGS_RandomGenerator* EGS_Ranmar::getCopy() { +EGS_RandomGenerator *EGS_Ranmar::getCopy() { EGS_Ranmar *c = new EGS_Ranmar(*this); - c->np = 0; c->copy = 0; c->copyBaseState(*this); + c->np = 0; + c->copy = 0; + c->copyBaseState(*this); return c; } void EGS_Ranmar::setState(EGS_RandomGenerator *r) { copyBaseState(*r); EGS_Ranmar *r1 = dynamic_cast(r); - if( !r1 ) egsFatal("EGS_Ranmar::setState: attampt to set my state by a non EGS_Ranmar RNG!\n"); - ix = r1->ix; jx = r1->jx; c = r1->c; - iseed1 = r1->iseed1; iseed2 = r1->iseed2; - for(int j=0; j<97; j++) u[j] = r1->u[j]; + if (!r1) { + egsFatal("EGS_Ranmar::setState: attampt to set my state by a non EGS_Ranmar RNG!\n"); + } + ix = r1->ix; + jx = r1->jx; + c = r1->c; + iseed1 = r1->iseed1; + iseed2 = r1->iseed2; + for (int j=0; j<97; j++) { + u[j] = r1->u[j]; + } } bool EGS_Ranmar::storePrivateState(ostream &data) { data << ix << " " << jx << " " << c << " " << iseed1 << " " << iseed2 << " " << high_res << endl; - for(int j=0; j<97; j++) data << u[j] << " "; + for (int j=0; j<97; j++) { + data << u[j] << " "; + } data << endl; return data.good(); } bool EGS_Ranmar::setPrivateState(istream &data) { data >> ix >> jx >> c >> iseed1 >> iseed2 >> high_res; - for(int j=0; j<97; j++) data >> u[j]; + for (int j=0; j<97; j++) { + data >> u[j]; + } return data.good(); } @@ -223,65 +289,114 @@ void EGS_Ranmar::describeRNG() const { "============================================\n"); egsInformation(" type = ranmar\n"); egsInformation(" high resolution = "); - if( high_res ) egsInformation("yes\n"); else egsInformation("no\n"); + if (high_res) { + egsInformation("yes\n"); + } + else { + egsInformation("no\n"); + } egsInformation(" initial seeds = %d %d\n",iseed1,iseed2); egsInformation(" numbers used so far = %lld\n",count); } void EGS_Ranmar::setState(int ixx, int jxx) { - if( ixx <= 0 || ixx >= 31328) ixx = 1802; - if( jxx <= 0 || jxx >= 30081) jxx = 9373; - iseed1 = ixx; iseed2 = jxx; + if (ixx <= 0 || ixx >= 31328) { + ixx = 1802; + } + if (jxx <= 0 || jxx >= 30081) { + jxx = 9373; + } + iseed1 = ixx; + iseed2 = jxx; int i = (ixx/177)%177 + 2; int j = ixx%177 + 2; int k = (jxx/169)%178 + 1; int l = jxx%169; - for(int ii=0; ii<97; ii++) { - int s = 0; int t = 8388608; - for(int jj=0; jj<24; jj++) { + for (int ii=0; ii<97; ii++) { + int s = 0; + int t = 8388608; + for (int jj=0; jj<24; jj++) { int m = (((i*j)%179)*k)%179; - i = j; j = k; k = m; + i = j; + j = k; + k = m; l = (53*l+1)%169; - if( (l*m)%64 >= 32 ) s += t; + if ((l*m)%64 >= 32) { + s += t; + } t /= 2; } u[ii] = s; } - c = 362436; ix = 96; jx = 32; + c = 362436; + ix = 96; + jx = 32; } void EGS_Ranmar::fillArray(int n, EGS_Float *array) { - for(int ii=0; ii 16777219 ) egsWarning("r = %d\n",r); + if (r > 16777219) { + egsWarning("r = %d\n",r); + } #endif - if( r < 0 ) r += 16777216; + if (r < 0) { + r += 16777216; + } u[ix--] = r; - if(ix < 0) ix = 96; - if(jx < 0) jx = 96; - c -= cd; if( c < 0 ) c+=cm; - r -= c; if( r < 0 ) r+=16777216; + if (ix < 0) { + ix = 96; + } + if (jx < 0) { + jx = 96; + } + c -= cd; + if (c < 0) { + c+=cm; + } + r -= c; + if (r < 0) { + r+=16777216; + } #ifdef MSVC - if( r > 16777219 ) egsWarning("r = %d\n",r); + if (r > 16777219) { + egsWarning("r = %d\n",r); + } #endif array[ii] = twom24*r; } - if( high_res ) { - for(int ii=0; ii 16777219 ) egsWarning("r = %d\n",r); + if (r > 16777219) { + egsWarning("r = %d\n",r); + } #endif - if( r < 0 ) r += 16777216; + if (r < 0) { + r += 16777216; + } u[ix--] = r; - if(ix < 0) ix = 96; - if(jx < 0) jx = 96; - c -= cd; if( c < 0 ) c+=cm; - r -= c; if( r < 0 ) r+=16777216; + if (ix < 0) { + ix = 96; + } + if (jx < 0) { + jx = 96; + } + c -= cd; + if (c < 0) { + c+=cm; + } + r -= c; + if (r < 0) { + r+=16777216; + } #ifdef MSVC - if( r > 16777219 ) egsWarning("r = %d\n",r); + if (r > 16777219) { + egsWarning("r = %d\n",r); + } #endif array[ii] += twom24*twom24*r; } @@ -290,61 +405,71 @@ void EGS_Ranmar::fillArray(int n, EGS_Float *array) { } -EGS_RandomGenerator* EGS_RandomGenerator::createRNG(EGS_Input *input, +EGS_RandomGenerator *EGS_RandomGenerator::createRNG(EGS_Input *input, int sequence) { - if( !input ) { + if (!input) { egsWarning("EGS_RandomGenerator::createRNG: null input?\n"); return 0; } - EGS_Input *i; bool delete_it = false; - if( input->isA("rng definition") ) i = input; + EGS_Input *i; + bool delete_it = false; + if (input->isA("rng definition")) { + i = input; + } else { i = input->takeInputItem("rng definition"); - if( !i ) { + if (!i) { egsWarning("EGS_RandomGenerator::createRNG: no 'RNG definition'" - " input\n"); + " input\n"); return 0; } delete_it = true; } string type; int err = i->getInput("type",type); - if( err ) { + if (err) { egsWarning("EGS_RandomGenerator::createRNG: no RNG type specified\n" - " Assuming ranmar.\n"); + " Assuming ranmar.\n"); type = "ranmar"; } EGS_RandomGenerator *result; - if( i->compare(type,"ranmar") ) { + if (i->compare(type,"ranmar")) { vector seeds; err = i->getInput("initial seeds",seeds); EGS_Ranmar *res; - if( !err && seeds.size() == 2 ) + if (!err && seeds.size() == 2) { res = new EGS_Ranmar(seeds[0],seeds[1] + sequence); - else res = new EGS_Ranmar(1802,9373+sequence); + } + else { + res = new EGS_Ranmar(1802,9373+sequence); + } vector hr_options; - hr_options.push_back("no"); hr_options.push_back("yes"); + hr_options.push_back("no"); + hr_options.push_back("yes"); bool hr = i->getInput("high resolution",hr_options,0); res->setHighResolution(hr); result = res; } else { egsWarning("EGS_RandomGenerator::createRNG: unknown RNG type %s\n", - type.c_str()); + type.c_str()); result = 0; } - if( delete_it ) delete i; + if (delete_it) { + delete i; + } return result; } -EGS_RandomGenerator* EGS_RandomGenerator::defaultRNG(int sequence) { +EGS_RandomGenerator *EGS_RandomGenerator::defaultRNG(int sequence) { sequence += 97; - int ixx = 33; int iaux = sequence/30081; + int ixx = 33; + int iaux = sequence/30081; int jxx = sequence - iaux*30081; - if( iaux > 0 ) { + if (iaux > 0) { ixx += iaux; - if( iaux > 31328 ) egsFatal("EGS_RandomGenerator::defaultRNG: " - "sequence %d is outside of allowed range\n",sequence); + if (iaux > 31328) egsFatal("EGS_RandomGenerator::defaultRNG: " + "sequence %d is outside of allowed range\n",sequence); } return new EGS_Ranmar(ixx,jxx); } diff --git a/HEN_HOUSE/egs++/egs_rndm.h b/HEN_HOUSE/egs++/egs_rndm.h index 19733af1d..66aa0b774 100644 --- a/HEN_HOUSE/egs++/egs_rndm.h +++ b/HEN_HOUSE/egs++/egs_rndm.h @@ -90,7 +90,9 @@ class EGS_EXPORT EGS_RandomGenerator { * * Deallocates the memory pointed to by #rarray. */ - virtual ~EGS_RandomGenerator() { delete [] rarray; }; + virtual ~EGS_RandomGenerator() { + delete [] rarray; + }; /*! \brief Returns a random number uniformly distributed between * zero (inclusive) and 1 (exclusive). @@ -99,7 +101,10 @@ class EGS_EXPORT EGS_RandomGenerator { * if the pointer #ip points beyond the last element of #rarray. */ inline EGS_Float getUniform() { - if( ip >= np ) { fillArray(np,rarray); ip = 0; } + if (ip >= np) { + fillArray(np,rarray); + ip = 0; + } return rarray[ip++]; }; @@ -108,14 +113,18 @@ class EGS_EXPORT EGS_RandomGenerator { * This is useful for simulation diagnostics purposes. * \sa numbersUsed() */ - EGS_I64 numbersGenerated() const { return count; }; + EGS_I64 numbersGenerated() const { + return count; + }; /*! \brief Returns the number of random numbers used so far. * * This is normally different than numbersGenerated() as some of the * numbers in the array #rarray may not have been used yet. */ - EGS_I64 numbersUsed() const { return ip 1 ); + } + while (rhophi > 1); cphi = (xphi2 - yphi2)/rhophi; sphi = 2*xphi*yphi/rhophi; #else EGS_Float phi = 2*M_PI*getUniform(); - cphi = cos(phi); sphi = sin(phi); + cphi = cos(phi); + sphi = sin(phi); #endif }; @@ -146,10 +159,16 @@ class EGS_EXPORT EGS_RandomGenerator { * and standard deviation 1. */ inline EGS_Float getGaussian() { - if( have_x ) { have_x = false; return the_x; } + if (have_x) { + have_x = false; + return the_x; + } EGS_Float r = sqrt(-2*log(1-getUniform())); - EGS_Float cphi, sphi; getAzimuth(cphi,sphi); - have_x = true; the_x = r*sphi; return r*cphi; + EGS_Float cphi, sphi; + getAzimuth(cphi,sphi); + have_x = true; + the_x = r*sphi; + return r*cphi; }; /*! \brief Create a RNG object from the information pointed to by @@ -166,7 +185,7 @@ class EGS_EXPORT EGS_RandomGenerator { * but this functionality is not there yet. For now, the only RNG * type available is a ranmar RNG. */ - static EGS_RandomGenerator* createRNG(EGS_Input *inp, int sequence=0); + static EGS_RandomGenerator *createRNG(EGS_Input *inp, int sequence=0); /*! \brief Returns a pointer to the default egspp RNG. * @@ -174,7 +193,7 @@ class EGS_EXPORT EGS_RandomGenerator { * by increasing the second ranmar default initial seed by * \a sequence. */ - static EGS_RandomGenerator* defaultRNG(int sequence=0); + static EGS_RandomGenerator *defaultRNG(int sequence=0); /*! \brief Fill the array of \a n elements pointed to by \a array with * random numbers. @@ -208,11 +227,13 @@ class EGS_EXPORT EGS_RandomGenerator { bool storeState(ostream &data); bool setState(istream &data); bool addState(istream &data); - void resetCounter() { count = 0; }; + void resetCounter() { + count = 0; + }; //@} /*! \brief Get a copy of the RNG */ - virtual EGS_RandomGenerator* getCopy() = 0; + virtual EGS_RandomGenerator *getCopy() = 0; /*! \brief Set the state of the RNG from another RNG */ virtual void setState(EGS_RandomGenerator *r) = 0; diff --git a/HEN_HOUSE/egs++/egs_run_control.cpp b/HEN_HOUSE/egs++/egs_run_control.cpp index 7708ae462..b0404cf78 100644 --- a/HEN_HOUSE/egs++/egs_run_control.cpp +++ b/HEN_HOUSE/egs++/egs_run_control.cpp @@ -52,87 +52,114 @@ EGS_RunControl::EGS_RunControl(EGS_Application *a) : app(a), input(0), ncase(0), ndone(0), nbatch(10), maxt(-1), accu(-1), restart(0), nchunk(1), cpu_time(0), previous_cpu_time(0), geomErrorCount(0), geomErrorMax(0) { n_run_controls++; - if( !app ) egsFatal("EGS_RunControl::EGS_RunControl: it is not allowed\n" - " to construct a run control object on a NULL application\n"); + if (!app) egsFatal("EGS_RunControl::EGS_RunControl: it is not allowed\n" + " to construct a run control object on a NULL application\n"); input = app->getInput(); - if( !input ) { + if (!input) { egsWarning("EGS_RunControl::EGS_RunControl: the application has no" - " input\n"); return; + " input\n"); + return; } input = input->takeInputItem("run control"); - if( !input ) { + if (!input) { egsWarning("EGS_RunControl::EGS_RunControl: no 'run control' " - "input\n"); return; + "input\n"); + return; } double ncase_double; int err = input->getInput("number of histories", ncase_double); - if( err ) { + if (err) { err = input->getInput("ncase", ncase_double); - if( err ) + if (err) egsWarning("EGS_RunControl: missing/wrong 'ncase' or " - "'number of histories' input\n"); + "'number of histories' input\n"); } ncase = EGS_I64(ncase_double); err = input->getInput("nbatch",nbatch); - if( err ) nbatch = 10; + if (err) { + nbatch = 10; + } err = input->getInput("max cpu hours allowed",maxt); - if( err ) maxt = -1; + if (err) { + maxt = -1; + } err = input->getInput("statistical accuracy sought",accu); - if( err ) accu = -1; + if (err) { + accu = -1; + } err = input->getInput("geometry error limit", geomErrorMax); - if( err ) geomErrorMax = 0; + if (err) { + geomErrorMax = 0; + } vector ctype; - ctype.push_back("first"); ctype.push_back("restart"); - ctype.push_back("analyze"); ctype.push_back("combine"); + ctype.push_back("first"); + ctype.push_back("restart"); + ctype.push_back("analyze"); + ctype.push_back("combine"); restart = input->getInput("calculation",ctype,0); } EGS_RunControl::~EGS_RunControl() { - if( input ) delete input; + if (input) { + delete input; + } n_run_controls--; - if( !n_run_controls ) { - while( rc_libs.size() > 0 ) { - delete rc_libs[rc_libs.size()-1]; rc_libs.pop_back(); + if (!n_run_controls) { + while (rc_libs.size() > 0) { + delete rc_libs[rc_libs.size()-1]; + rc_libs.pop_back(); } } } bool EGS_RunControl::storeState(ostream &data) { - if( !egsStoreI64(data,ndone) ) return false; + if (!egsStoreI64(data,ndone)) { + return false; + } data << " " << (cpu_time+previous_cpu_time) << endl; return data.good(); } bool EGS_RunControl::setState(istream &data) { EGS_I64 ndone1; - if( !egsGetI64(data,ndone1) ) return false; - ndone += ndone1; ncase += ndone1; + if (!egsGetI64(data,ndone1)) { + return false; + } + ndone += ndone1; + ncase += ndone1; data >> previous_cpu_time; return data.good(); } bool EGS_RunControl::addState(istream &data) { EGS_Float previous_cpu_time_save = previous_cpu_time; - if( !setState(data) ) return false; + if (!setState(data)) { + return false; + } previous_cpu_time += previous_cpu_time_save; return true; } void EGS_RunControl::resetCounter() { - previous_cpu_time = 0; cpu_time = 0; timer.start(); - ncase = 0; ndone = 0; + previous_cpu_time = 0; + cpu_time = 0; + timer.start(); + ncase = 0; + ndone = 0; } int EGS_RunControl::startSimulation() { - if( restart == 1 || restart == 2 ) { - if( app->readData() ) return -1; - if( restart == 2 ) { + if (restart == 1 || restart == 2) { + if (app->readData()) { + return -1; + } + if (restart == 2) { ncase = ndone; egsInformation("\n\nResult analysis only\n\n"); return 1; } } - else if( restart == 3 ) { + else if (restart == 3) { app->describeSimulation(); egsInformation("\n\nCombine results only\n\n"); egsInformation("calling combineResults()\n"); @@ -143,27 +170,28 @@ int EGS_RunControl::startSimulation() { app->describeSimulation(); time_t tinfo = time(0); egsInformation("\n\nStarting simulation on %s\n", - asctime(localtime(&tinfo))); - if( restart == 0 ) + asctime(localtime(&tinfo))); + if (restart == 0) { egsInformation(" Fresh simulation of %lld histories\n\n\n",ncase); + } else { egsInformation(" Restarted simulation with %lld old and %lld" - " new histories\n\n\n",ndone,ncase-ndone); + " new histories\n\n\n",ndone,ncase-ndone); } timer.start(); return 0; } bool EGS_RunControl::startBatch(int ibatch, EGS_I64 ncase_per_batch) { - if( !ibatch ) egsInformation( -" Batch CPU time Result Uncertainty(%c)\n" -"==========================================================\n",'%'); - if( maxt > 0 && ndone > 0 ) { + if (!ibatch) egsInformation( + " Batch CPU time Result Uncertainty(%c)\n" + "==========================================================\n",'%'); + if (maxt > 0 && ndone > 0) { EGS_Float time_per_shower = (cpu_time + previous_cpu_time)/ndone; EGS_Float extra_time = time_per_shower*ncase_per_batch; - if( cpu_time + extra_time > maxt*3600 ) { + if (cpu_time + extra_time > maxt*3600) { egsWarning("\n\n*** Not enough time to finish another batch\n" - " => terminating simulation.\n\n"); + " => terminating simulation.\n\n"); return false; } } @@ -175,20 +203,31 @@ bool EGS_RunControl::startBatch(int ibatch, EGS_I64 ncase_per_batch) { bool EGS_RunControl::finishBatch() { cpu_time = timer.time(); int out = app->outputData(); - if( out ) egsWarning("\n\noutputData() returned error code %d ?\n",out); + if (out) { + egsWarning("\n\noutputData() returned error code %d ?\n",out); + } double sum, sum2, norm, count; app->getCurrentResult(sum,sum2,norm,count); double f, df; - if( sum > 0 && sum2 > 0 && norm > 0 && count > 1 ) { + if (sum > 0 && sum2 > 0 && norm > 0 && count > 1) { f = sum*norm/count; df = count*sum2/(sum*sum)-1; - if( df > 0 ) df = 100*sqrt(df/(count-1)); else df = 100; - } else { f = 0; df = 100; } + if (df > 0) { + df = 100*sqrt(df/(count-1)); + } + else { + df = 100; + } + } + else { + f = 0; + df = 100; + } egsInformation(" %12.2f %14g %14.2f\n",cpu_time,f,df); - if( df < 100 && accu > 0 && df < accu ) { + if (df < 100 && accu > 0 && df < accu) { char c = '%'; egsWarning("\n\n*** Reached the requested uncertainty of %g%c\n" - " => terminating simulation.\n\n",accu,c); + " => terminating simulation.\n\n",accu,c); return false; } return true; @@ -196,38 +235,38 @@ bool EGS_RunControl::finishBatch() { #ifdef WIN32 -#include -#include -#include -#include -#include -#include - -#define OPEN_FILE _open -#define CLOSE_FILE _close -#define CREATE_FLAGS _O_CREAT | _O_EXCL | _O_RDWR, _S_IREAD | _S_IWRITE -#define OPEN_FLAGS _O_RDWR,_S_IREAD | _S_IWRITE -#define WAIT_FOR_FILE _sleep(1000) -#define WRITE_FILE _write -#define READ_FILE _read + #include + #include + #include + #include + #include + #include + + #define OPEN_FILE _open + #define CLOSE_FILE _close + #define CREATE_FLAGS _O_CREAT | _O_EXCL | _O_RDWR, _S_IREAD | _S_IWRITE + #define OPEN_FLAGS _O_RDWR,_S_IREAD | _S_IWRITE + #define WAIT_FOR_FILE _sleep(1000) + #define WRITE_FILE _write + #define READ_FILE _read #else -#include -#include -#include -#include -#include -#include -#include - -#define OPEN_FILE open -#define CLOSE_FILE close -#define CREATE_FLAGS O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR -#define OPEN_FLAGS O_RDWR -#define WAIT_FOR_FILE sleep(1) -#define WRITE_FILE write -#define READ_FILE read + #include + #include + #include + #include + #include + #include + #include + + #define OPEN_FILE open + #define CLOSE_FILE close + #define CREATE_FLAGS O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR + #define OPEN_FLAGS O_RDWR + #define WAIT_FOR_FILE sleep(1) + #define WRITE_FILE write + #define READ_FILE read #endif @@ -247,19 +286,29 @@ class EGS_LOCAL EGS_FileLocking { #endif EGS_FileLocking() : fd(-1), is_locked(false), ntry(15) { #ifndef WIN32 - fl_write.l_type = F_WRLCK; fl_write.l_whence = SEEK_SET; - fl_write.l_start = 0; fl_write.l_len = 0; - fl_unlock.l_type = F_UNLCK; fl_unlock.l_whence = SEEK_SET; - fl_unlock.l_start = 0; fl_unlock.l_len = 0; + fl_write.l_type = F_WRLCK; + fl_write.l_whence = SEEK_SET; + fl_write.l_start = 0; + fl_write.l_len = 0; + fl_unlock.l_type = F_UNLCK; + fl_unlock.l_whence = SEEK_SET; + fl_unlock.l_start = 0; + fl_unlock.l_len = 0; #endif }; - ~EGS_FileLocking() { if( fd > 0 ) CLOSE_FILE(fd); }; + ~EGS_FileLocking() { + if (fd > 0) { + CLOSE_FILE(fd); + } + }; bool createControlFile(const char *fname) { is_locked = false; - if( fd > 0 ) CLOSE_FILE(fd); + if (fd > 0) { + CLOSE_FILE(fd); + } fd = OPEN_FILE(fname,CREATE_FLAGS); egsWarning("createControlFile: file=%s fd=%d\n",fname,fd); - if( fd < 0 ) { + if (fd < 0) { egsWarning("createControlFile(): open failed! (fd=%d)\n",fd); #ifndef WIN32 perror("System error was"); @@ -269,50 +318,71 @@ class EGS_LOCAL EGS_FileLocking { }; bool openControlFile(const char *fname) { is_locked = false; - if( fd > 0 ) CLOSE_FILE(fd); - for(int t=0; t 0 ) break; + if (fd > 0) { + CLOSE_FILE(fd); + } + for (int t=0; t 0) { + break; + } WAIT_FOR_FILE; } - return ( fd > 0 ); + return (fd > 0); }; bool closeControlFile() { - if( fd > 0 ) { - int res = CLOSE_FILE(fd); fd = -1; return !res; + if (fd > 0) { + int res = CLOSE_FILE(fd); + fd = -1; + return !res; } return true; }; bool lockControlFile() { - if( is_locked ) return true; - if( fd < 0 ) return false; + if (is_locked) { + return true; + } + if (fd < 0) { + return false; + } #ifdef WIN32 long np = _lseek(fd,0L,SEEK_SET); - if( np ) { + if (np) { egsWarning("lockControlFile: _lseek returned %d?\n",np); return false; } int res = _locking(fd,_LK_LOCK,1000000L); - if( !res ) { is_locked = true; return true; } + if (!res) { + is_locked = true; + return true; + } return false; #else - for(int i1=0; i1<5; i1++) { - for(int i2=0; i2<12; i2++) { + for (int i1=0; i1<5; i1++) { + for (int i2=0; i2<12; i2++) { int res = fcntl(fd,F_SETLK,&fl_write); - if( !res ) { is_locked = true; return true; } + if (!res) { + is_locked = true; + return true; + } WAIT_FOR_FILE ; } egsWarning("lockControlFile: failed to lock file for " - "12 seconds...\n"); + "12 seconds...\n"); } return false; #endif }; bool unlockControlFile() { - if( !is_locked ) return true; - if( fd < 0 ) return false; + if (!is_locked) { + return true; + } + if (fd < 0) { + return false; + } #ifdef WIN32 int np = _lseek(fd,0L,SEEK_SET); - if( np ) { + if (np) { egsWarning("unlockControlFile: _lseek returned %d?\n",np); return false; } @@ -320,13 +390,20 @@ class EGS_LOCAL EGS_FileLocking { #else int res = fcntl(fd,F_SETLKW,&fl_unlock); #endif - if( !res ) { is_locked = false; return true; } + if (!res) { + is_locked = false; + return true; + } return false; }; bool rewindControlFile() { - if( fd < 0 ) return false; - if( !is_locked ) { - if( !lockControlFile() ) return false; + if (fd < 0) { + return false; + } + if (!is_locked) { + if (!lockControlFile()) { + return false; + } } #ifdef WIN32 return !_lseek(fd,0,SEEK_SET); @@ -343,12 +420,21 @@ EGS_JCFControl::EGS_JCFControl(EGS_Application *a, int Nbuf) : npar(app->getNparallel()), ipar(app->getIparallel()), first_time(true), nbuf(Nbuf), njob(0), tsum(0), tsum2(0), tcount(0), norm(1), last_sum(0), last_sum2(0), last_count(0), removed_jcf(false) { - if( input ) { + if (input) { int err = input->getInput("nchunk",nchunk); - if( err ) nchunk = 10; - } else nchunk = 10; - if( nbuf < 0 ) nbuf = 1024; buf = new char [nbuf]; - nleft = ncase; ntot = 0; + if (err) { + nchunk = 10; + } + } + else { + nchunk = 10; + } + if (nbuf < 0) { + nbuf = 1024; + } + buf = new char [nbuf]; + nleft = ncase; + ntot = 0; //egsInformation("EGS_JCFControl::EGS_JCFControl:\n"); //egsInformation(" ncase = %lld nleft = %lld nchunk = %d\n", // nleft,ncase,nchunk); @@ -357,43 +443,49 @@ EGS_JCFControl::EGS_JCFControl(EGS_Application *a, int Nbuf) : bool EGS_JCFControl::createControlFile() { string cfile = egsJoinPath(app->getAppDir(),app->getFinalOutputFile()); cfile += ".lock"; - if( !p->createControlFile(cfile.c_str()) ) { + if (!p->createControlFile(cfile.c_str())) { egsWarning("EGS_JCFControl: failed to create or lock the " - " job control file %s\n\n",cfile.c_str()); + " job control file %s\n\n",cfile.c_str()); + return false; + } + if (p->fd < 0) { return false; } - if( p->fd < 0 ) return false; writeControlString(); int nwant = strlen(buf)+1; int nwrite = WRITE_FILE(p->fd,buf,nwant); - if( nwrite != nwant ) return false; + if (nwrite != nwant) { + return false; + } return p->unlockControlFile(); } bool EGS_JCFControl::openControlFile() { string cfile = egsJoinPath(app->getAppDir(),app->getFinalOutputFile()); cfile += ".lock"; - if( !p->openControlFile(cfile.c_str()) ) { + if (!p->openControlFile(cfile.c_str())) { egsWarning("EGS_JCFControl: failed to open the " - " job control file %s\n\n",cfile.c_str()); + " job control file %s\n\n",cfile.c_str()); return false; } return true; } #ifdef NO_SSTREAM -#include -#define MY_OSTREAM std::ostrstream -#define MY_ISTREAM std::istrstream + #include + #define MY_OSTREAM std::ostrstream + #define MY_ISTREAM std::istrstream #else -#include -#define MY_OSTREAM std::ostringstream -#define MY_ISTREAM std::istringstream + #include + #define MY_OSTREAM std::ostringstream + #define MY_ISTREAM std::istringstream #endif bool EGS_JCFControl::writeControlString() { //if( first_time ) { start_time = time(0); first_time = false; } - if( first_time ) start_time = time(0); + if (first_time) { + start_time = time(0); + } /* MY_OSTREAM data(buf); //ostream &data = cout; @@ -412,24 +504,39 @@ bool EGS_JCFControl::writeControlString() { return data.good(); */ double f = tsum*norm, df; - if( tsum > 0 && tsum2 > 0 && norm > 0 && tcount > 1 ) { + if (tsum > 0 && tsum2 > 0 && norm > 0 && tcount > 1) { f = tsum*norm/tcount; df = tcount*tsum2/(tsum*tsum)-1; - if( df > 0 ) df = 100*sqrt(df/(tcount-1)); else df = 100; - } else df = 100; + if (df > 0) { + df = 100*sqrt(df/(tcount-1)); + } + else { + df = 100; + } + } + else { + df = 100; + } sprintf(buf,"%lld %lld %d %lg %lg %lg %lg %lg %ld ",ntot,nleft,njob,tsum, tsum2,tcount,f,df,start_time); return true; } bool EGS_JCFControl::getCombinedResult(double &f, double &df) const { - if( tsum > 0 && tsum2 > 0 && norm > 0 && tcount > 1 ) { + if (tsum > 0 && tsum2 > 0 && norm > 0 && tcount > 1) { f = tsum*norm/tcount; df = tcount*tsum2/(tsum*tsum)-1; - if( df > 0 ) df = 100*sqrt(df/(tcount-1)); else df = 100; + if (df > 0) { + df = 100*sqrt(df/(tcount-1)); + } + else { + df = 100; + } return true; } - df = 100; f = 0; return false; + df = 100; + f = 0; + return false; } bool EGS_JCFControl::readControlString() { @@ -443,87 +550,109 @@ bool EGS_JCFControl::readControlString() { */ double f,df; int res = sscanf(buf,"%lld %lld %d %lg %lg %lg %lg %lg %ld", - &ntot,&nleft,&njob,&tsum,&tsum2,&tcount,&f,&df,&start_time); - if( res == EOF || res != 9 ) return false; + &ntot,&nleft,&njob,&tsum,&tsum2,&tcount,&f,&df,&start_time); + if (res == EOF || res != 9) { + return false; + } return true; } int EGS_JCFControl::startSimulation() { int res = EGS_RunControl::startSimulation(); - if( res ) return res; + if (res) { + return res; + } bool ok = (ipar == 1) ? createControlFile() : openControlFile(); - if( ok ) { + if (ok) { egsInformation(" Parallel run with %d jobs and %d chunks per " - "job\n\n\n",npar,nchunk); + "job\n\n\n",npar,nchunk); return 0; } return -99; } bool EGS_JCFControl::readControlFile() { - if( !p->rewindControlFile() ) { + if (!p->rewindControlFile()) { egsWarning("EGS_JCFControl: failed to rewind the job control file\n"); return false; } int res = READ_FILE(p->fd,buf,nbuf-1); - if( res <= 0 ) { + if (res <= 0) { p->unlockControlFile(); egsWarning("EGS_JCFControl: failed to read the job control file\n"); return false; } buf[res] = 0; - if( !readControlString() ) { + if (!readControlString()) { p->unlockControlFile(); egsWarning("EGS_JCFControl: failed to read from the control string" - " <%s>\n",buf); return false; + " <%s>\n",buf); + return false; } return true; } bool EGS_JCFControl::writeControlFile() { - if( !writeControlString() ) { + if (!writeControlString()) { egsWarning("EGS_JCFControl::writeControlFile: failed to write to the " - "control string\n"); return false; + "control string\n"); + return false; } - if( !p->rewindControlFile() ) { + if (!p->rewindControlFile()) { egsWarning("EGS_JCFControl: failed to rewind the job control file\n"); return false; } int nwant = strlen(buf)+1; int nwrite = WRITE_FILE(p->fd,buf,nwant); - if( !p->unlockControlFile() ) { + if (!p->unlockControlFile()) { egsWarning("EGS_JCFControl::writeControlFile: failed to unlock the " - "control file\n"); return false; + "control file\n"); + return false; } - if( nwrite != nwant ) { + if (nwrite != nwant) { egsWarning("EGS_JCFControl::getNextChunk: could write only %d " - "instead of %d chars to the job control file?\n",nwrite,nwant); + "instead of %d chars to the job control file?\n",nwrite,nwant); return false; } return true; } EGS_I64 EGS_JCFControl::getNextChunk() { - if( !readControlFile() ) return -1; - if( first_time ) { first_time = false; njob++; } + if (!readControlFile()) { + return -1; + } + if (first_time) { + first_time = false; + njob++; + } double sum, sum2, count; app->getCurrentResult(sum,sum2,norm,count); - tsum += sum - last_sum; tsum2 += sum2 - last_sum2; + tsum += sum - last_sum; + tsum2 += sum2 - last_sum2; tcount += count - last_count; - last_sum = sum; last_sum2 = sum2; last_count = count; + last_sum = sum; + last_sum2 = sum2; + last_count = count; EGS_I64 nrun = ncase/(npar*nchunk); - if( nrun < 1 ) nrun = 1; - if( nrun > nleft ) nrun = nleft; - if( nrun > 0 ) app->setSimulationChunk(ntot,nrun); - nleft -= nrun; ntot += nrun; + if (nrun < 1) { + nrun = 1; + } + if (nrun > nleft) { + nrun = nleft; + } + if (nrun > 0) { + app->setSimulationChunk(ntot,nrun); + } + nleft -= nrun; + ntot += nrun; writeControlFile(); double f,df; - if( accu > 0 && getCombinedResult(f,df) ) { - if( df < 100 && df < accu ) { + if (accu > 0 && getCombinedResult(f,df)) { + if (df < 100 && df < accu) { char c = '%'; egsWarning("\n\n*** After combining the results of all parallel " - "jobs the requested\n uncertainty of %g%c was reached: %g%c\n" - " => terminating simulation.\n\n",accu,c,df,c); + "jobs the requested\n uncertainty of %g%c was reached: %g%c\n" + " => terminating simulation.\n\n",accu,c,df,c); return 0; } } @@ -534,20 +663,21 @@ int EGS_RunControl::finishSimulation() { cpu_time = timer.time(); egsInformation("\n\nFinished simulation\n\n"); egsInformation("%-40s%.2f (sec.) %.4f(hours)\n", - "Total cpu time for this run:",cpu_time,cpu_time/3600); + "Total cpu time for this run:",cpu_time,cpu_time/3600); //egsInformation("Total cpu time for this run: %g seconds (%g hours)\n\n", // cpu_time, cpu_time/3600); - if( previous_cpu_time > 0 ) + if (previous_cpu_time > 0) egsInformation("%-40s%.2f (sec.) %.4f(hours)\n", - "CPU time including previous runs:",cpu_time+previous_cpu_time, - (cpu_time+previous_cpu_time)/3600); + "CPU time including previous runs:",cpu_time+previous_cpu_time, + (cpu_time+previous_cpu_time)/3600); egsInformation("%-40s%-14g\n","Histories per hour:",3600.*ndone/ - (cpu_time+previous_cpu_time)); + (cpu_time+previous_cpu_time)); egsInformation("%-40s%-14lld\n","Number of random numbers used:", - app->randomNumbersUsed()); - double ch_steps, all_steps; app->getElectronSteps(ch_steps,all_steps); + app->randomNumbersUsed()); + double ch_steps, all_steps; + app->getElectronSteps(ch_steps,all_steps); egsInformation("%-40s%-14g\n","Number of electron CH steps:", - ch_steps); + ch_steps); //egsInformation("%-40s%14g\n","Number of all electron steps:", // all_steps); egsInformation("%-40s","Number of all electron steps:"); @@ -557,12 +687,21 @@ int EGS_RunControl::finishSimulation() { int EGS_JCFControl::finishSimulation() { int err = EGS_RunControl::finishSimulation(); - if( err < 0 ) return err; - if( removed_jcf ) return 0; - if( !readControlFile() ) return -2; + if (err < 0) { + return err; + } + if (removed_jcf) { + return 0; + } + if (!readControlFile()) { + return -2; + } njob--; - writeControlFile(); p->closeControlFile(); - if( njob > 0 || removed_jcf ) return 0; + writeControlFile(); + p->closeControlFile(); + if (njob > 0 || removed_jcf) { + return 0; + } string cfile = egsJoinPath(app->getAppDir(),app->getFinalOutputFile()); cfile += ".lock"; #ifdef WIN32 @@ -570,39 +709,57 @@ int EGS_JCFControl::finishSimulation() { #else int res = unlink(cfile.c_str()); #endif - if( res ) egsWarning("EGS_JCFControl::finishSimulation: failed to remove " - " the job control file %s\n",cfile.c_str()); + if (res) egsWarning("EGS_JCFControl::finishSimulation: failed to remove " + " the job control file %s\n",cfile.c_str()); removed_jcf = true; return 1; } -EGS_JCFControl::~EGS_JCFControl() { delete p; } +EGS_JCFControl::~EGS_JCFControl() { + delete p; +} -bool EGS_JCFControl::closeControlFile() { return p->closeControlFile(); } +bool EGS_JCFControl::closeControlFile() { + return p->closeControlFile(); +} -bool EGS_JCFControl::lockControlFile() { return p->lockControlFile(); } +bool EGS_JCFControl::lockControlFile() { + return p->lockControlFile(); +} -bool EGS_JCFControl::unlockControlFile() { return p->unlockControlFile(); } +bool EGS_JCFControl::unlockControlFile() { + return p->unlockControlFile(); +} -bool EGS_JCFControl::rewindControlFile() { return p->rewindControlFile(); } +bool EGS_JCFControl::rewindControlFile() { + return p->rewindControlFile(); +} -typedef EGS_RunControl* (*EGS_RunControlCreationFunction)(EGS_Application *); +typedef EGS_RunControl *(*EGS_RunControlCreationFunction)(EGS_Application *); -EGS_RunControl* EGS_RunControl::getRunControlObject(EGS_Application *a) { - if( !a ) { +EGS_RunControl *EGS_RunControl::getRunControlObject(EGS_Application *a) { + if (!a) { egsWarning("EGS_RunControl::getRunControlObject(): " - "null application?\n"); return 0; + "null application?\n"); + return 0; } - EGS_Input *inp = a->getInput(); EGS_Input *irc = 0; - if( inp ) irc = inp->getInputItem("run control"); - if( !irc ) { + EGS_Input *inp = a->getInput(); + EGS_Input *irc = 0; + if (inp) { + irc = inp->getInputItem("run control"); + } + if (!irc) { /* egsWarning("EGS_RunControl::getRunControlObject(): " "the application does not have any input\n"); return 0; */ - if( a->getNparallel() > 0 ) return new EGS_JCFControl(a); - else return new EGS_RunControl(a); + if (a->getNparallel() > 0) { + return new EGS_JCFControl(a); + } + else { + return new EGS_RunControl(a); + } } /* EGS_Input *irc = inp->getInputItem("run control"); @@ -612,40 +769,52 @@ EGS_RunControl* EGS_RunControl::getRunControlObject(EGS_Application *a) { return 0; } */ - string libname; int err = irc->getInput("library",libname); + string libname; + int err = irc->getInput("library",libname); EGS_RunControl *result; - if( !err ) { + if (!err) { EGS_Library *lib = 0; - for(unsigned int j=0; jlibraryName() ) { - lib = rc_libs[j]; break; + for (unsigned int j=0; jlibraryName()) { + lib = rc_libs[j]; + break; } } - if( !lib ) { + if (!lib) { string dsodir = egsJoinPath("egs++","dso"); dsodir = egsJoinPath(dsodir,CONFIG_NAME); dsodir = egsJoinPath(a->getHenHouse(),dsodir); lib = new EGS_Library(libname.c_str(),dsodir.c_str()); lib->load(); - if( !lib->isLoaded() ) { + if (!lib->isLoaded()) { egsWarning("EGS_RunControl::getRunControlObject: failed to" - " load the library %s from %s\n",libname.c_str(), - dsodir.c_str()); delete irc; return 0; + " load the library %s from %s\n",libname.c_str(), + dsodir.c_str()); + delete irc; + return 0; } rc_libs.push_back(lib); } EGS_RunControlCreationFunction create = (EGS_RunControlCreationFunction) lib->resolve("createRunControl"); - if( !create ) { + if (!create) { egsWarning("EGS_RunControl::getRunControlObject: failed to" - " resolve the run control creation function of library %s\n", - libname.c_str()); result = 0; + " resolve the run control creation function of library %s\n", + libname.c_str()); + result = 0; + } + else { + result = create(a); } - else result = create(a); } else { - if( a->getNparallel() > 0 ) result = new EGS_JCFControl(a); - else result = new EGS_RunControl(a); + if (a->getNparallel() > 0) { + result = new EGS_JCFControl(a); + } + else { + result = new EGS_RunControl(a); + } } - delete irc; return result; + delete irc; + return result; } diff --git a/HEN_HOUSE/egs++/egs_run_control.h b/HEN_HOUSE/egs++/egs_run_control.h index 6c6a0dd9f..809b86e61 100644 --- a/HEN_HOUSE/egs++/egs_run_control.h +++ b/HEN_HOUSE/egs++/egs_run_control.h @@ -101,25 +101,43 @@ class EGS_EXPORT EGS_RunControl { virtual ~EGS_RunControl(); /*! \brief Set the number of particles to be simulated to \a n */ - void setNcase(EGS_I64 n) { if( n > 0 ) ncase = n; }; + void setNcase(EGS_I64 n) { + if (n > 0) { + ncase = n; + } + }; /*! \brief Set the number of batches to \a n */ - void setNbatch(int n) { if( n > 0 ) nbatch = n; }; + void setNbatch(int n) { + if (n > 0) { + nbatch = n; + } + }; /*! \brief Set the maximum CPU time for the simulation to \a t */ - void setMaxTime(EGS_Float t) { maxt = t; }; + void setMaxTime(EGS_Float t) { + maxt = t; + }; /*! \brief Set the required statistical uncertainty to \a a */ - void setRequiredUncertainty(EGS_Float a) { accu = a; }; + void setRequiredUncertainty(EGS_Float a) { + accu = a; + }; /*! \brief Returns the total number of particles to be simulated */ - EGS_I64 getNcase() const { return ncase; }; + EGS_I64 getNcase() const { + return ncase; + }; /*! \brief Returns the number of batches per simulation chunk */ - int getNbatch() const { return nbatch; }; + int getNbatch() const { + return nbatch; + }; /*! \brief Returns the number of simulation chunks */ - int getNchunk() const { return nchunk; }; + int getNchunk() const { + return nchunk; + }; /*! \brief Starts the simulation. @@ -139,7 +157,9 @@ class EGS_EXPORT EGS_RunControl { are in such a chunk. This function is called from within the runSimulation() function of EGS_Application. */ - virtual EGS_I64 getNextChunk() { return getNcase() - ndone; }; + virtual EGS_I64 getNextChunk() { + return getNcase() - ndone; + }; /*! Finish the simulation. @@ -173,15 +193,24 @@ class EGS_EXPORT EGS_RunControl { virtual bool setState(istream &data); virtual bool addState(istream &data); virtual void resetCounter(); - virtual bool getCombinedResult(double &, double &) const - { return false; }; - - virtual EGS_I64 getNdone() const { return ndone; }; - virtual void setNdone(EGS_I64 Ndone) { ndone = Ndone; }; - virtual void incrementNdone() { ++ndone; }; - virtual EGS_Float getCPUTime() const { return cpu_time+previous_cpu_time;}; - - static EGS_RunControl* getRunControlObject(EGS_Application *); + virtual bool getCombinedResult(double &, double &) const { + return false; + }; + + virtual EGS_I64 getNdone() const { + return ndone; + }; + virtual void setNdone(EGS_I64 Ndone) { + ndone = Ndone; + }; + virtual void incrementNdone() { + ++ndone; + }; + virtual EGS_Float getCPUTime() const { + return cpu_time+previous_cpu_time; + }; + + static EGS_RunControl *getRunControlObject(EGS_Application *); int geomErrorCount, geomErrorMax; @@ -196,9 +225,9 @@ class EGS_EXPORT EGS_RunControl { EGS_Float accu; // statistical uncertainty sought. int nbatch; // number of batches. int restart;// =0 => fresh calculation - // =1 => restart calculation - // =2 => analyze results - // =3 => combine parallel run + // =1 => restart calculation + // =2 => analyze results + // =3 => combine parallel run int nchunk; // number of simulation "chunks" EGS_Timer timer; @@ -232,7 +261,11 @@ class EGS_EXPORT EGS_JCFControl : public EGS_RunControl { EGS_JCFControl(EGS_Application *, int Nbuf=1024); ~EGS_JCFControl(); - void setNchunkForParallel(int n) { if( n > 0 ) nchunk = n; }; + void setNchunkForParallel(int n) { + if (n > 0) { + nchunk = n; + } + }; int startSimulation(); EGS_I64 getNextChunk(); int finishSimulation(); diff --git a/HEN_HOUSE/egs++/egs_scoring.cpp b/HEN_HOUSE/egs++/egs_scoring.cpp index c014b98fa..a2dda153c 100644 --- a/HEN_HOUSE/egs++/egs_scoring.cpp +++ b/HEN_HOUSE/egs++/egs_scoring.cpp @@ -42,19 +42,25 @@ using std::string; EGS_ScoringArray::EGS_ScoringArray(int N) : current_ncase(0), current_ncase_65536(0), current_ncase_short(0) { - if( N <= 0 ) egsFatal("EGS_ScoringArray::EGS_ScoringArray:\n" - " attempt to construct a scoring array with non-positive size\n"); - result = new EGS_ScoringSingle [N]; nreg = N; + if (N <= 0) egsFatal("EGS_ScoringArray::EGS_ScoringArray:\n" + " attempt to construct a scoring array with non-positive size\n"); + result = new EGS_ScoringSingle [N]; + nreg = N; } -EGS_ScoringArray::~EGS_ScoringArray() { delete [] result; } +EGS_ScoringArray::~EGS_ScoringArray() { + delete [] result; +} void EGS_ScoringArray::setHistory(EGS_I64 ncase) { - if( ncase != current_ncase ) { - current_ncase = ncase; EGS_I64 aux = ncase >> 16; - if( aux != current_ncase_65536 ) { + if (ncase != current_ncase) { + current_ncase = ncase; + EGS_I64 aux = ncase >> 16; + if (aux != current_ncase_65536) { current_ncase_65536 = aux; - for(int j=0; j 0) ? 100*dr/r : 100; - else dr *= norm; + for (int j=0; j 0) ? 100*dr/r : 100; + } + else { + dr *= norm; + } egsInformation(oformat,j,r*norm,dr,c); } } diff --git a/HEN_HOUSE/egs++/egs_scoring.h b/HEN_HOUSE/egs++/egs_scoring.h index 65c580ffa..4f4300a04 100644 --- a/HEN_HOUSE/egs++/egs_scoring.h +++ b/HEN_HOUSE/egs++/egs_scoring.h @@ -76,8 +76,12 @@ class EGS_EXPORT EGS_ScoringSingle { is started. */ inline void score(unsigned short ncase, EGS_Float f) { - if( ncase == current_ncase ) tmp += f; - else finishCase(ncase,f); + if (ncase == current_ncase) { + tmp += f; + } + else { + finishCase(ncase,f); + } }; /*! \brief Finish the current 'case' (event) and start a new event @@ -85,21 +89,29 @@ class EGS_EXPORT EGS_ScoringSingle { */ inline void finishCase(unsigned short new_case, EGS_Float new_result) { current_ncase = new_case; - sum += tmp; sum2 += tmp*tmp; tmp = new_result; + sum += tmp; + sum2 += tmp*tmp; + tmp = new_result; }; /*! \brief Returns the score of the current event. */ - EGS_Float currentScore() const { return tmp; }; + EGS_Float currentScore() const { + return tmp; + }; /*! \brief Sets \a s to the score of the current event and \a ncase to the index of the current event. */ void currentScore(EGS_Float &s, unsigned short &ncase) const { - s = tmp; ncase = current_ncase; + s = tmp; + ncase = current_ncase; }; /*! \brief Sets \a s to the sum of scores collected so far and \a s2 to the sum of scores squared */ - void currentScore(double &s, double &s2) { s=sum; s2=sum2; }; + void currentScore(double &s, double &s2) { + s=sum; + s2=sum2; + }; /*! \brief Sets \a r to the current result and \a dr to its statistical uncertainty assuming \a ncase statistically independent events. @@ -108,9 +120,14 @@ class EGS_EXPORT EGS_ScoringSingle { so far and \a ncase and \a dr to the statistical uncertainty of \a r. */ void currentResult(EGS_I64 ncase, double &r, double &dr) { - r = sum + tmp; dr = sum2 + tmp*tmp; - r /= ncase; dr /= ncase; dr -= r*r; - if( dr > 0 ) dr = sqrt(dr/(ncase-1)); + r = sum + tmp; + dr = sum2 + tmp*tmp; + r /= ncase; + dr /= ncase; + dr -= r*r; + if (dr > 0) { + dr = sqrt(dr/(ncase-1)); + } }; /*! \brief Stores the state of the scoring object into the data stream @@ -127,7 +144,7 @@ class EGS_EXPORT EGS_ScoringSingle { bool storeState(ostream &data) { //sum += tmp; sum2 += tmp*tmp; tmp = 0; //data << current_ncase << " " << sum << " " << sum2 << endl; - data << current_ncase << " " << sum+tmp << " " << sum2+tmp*tmp + data << current_ncase << " " << sum+tmp << " " << sum2+tmp *tmp << endl; return data.good(); }; @@ -142,14 +159,20 @@ class EGS_EXPORT EGS_ScoringSingle { \sa storeState() */ bool setState(istream &data) { - data >> current_ncase >> sum >> sum2; tmp = 0; + data >> current_ncase >> sum >> sum2; + tmp = 0; return data.good(); }; /*! \brief Reset the scoring object to a pristine state (\em i.e. all counters set to zero). */ - void reset() { current_ncase = 0; tmp = 0; sum = 0; sum2 = 0; }; + void reset() { + current_ncase = 0; + tmp = 0; + sum = 0; + sum2 = 0; + }; /*! \brief Combine the results of two scoring objects. @@ -161,7 +184,8 @@ class EGS_EXPORT EGS_ScoringSingle { EGS_ScoringSingle &operator+=(const EGS_ScoringSingle &x) { sum += tmp + x.sum + x.tmp; sum2 += tmp*tmp + x.sum2 + x.tmp*x.tmp; - current_ncase = 0; tmp = 0; + current_ncase = 0; + tmp = 0; return *this; }; @@ -233,7 +257,8 @@ class EGS_EXPORT EGS_ScoringArray { /*! \brief Returns the score in \a ireg in the current event. */ EGS_Float thisHistoryScore(int ireg) const { - EGS_Float res; unsigned short nc; + EGS_Float res; + unsigned short nc; result[ireg].currentScore(res,nc); return nc == current_ncase_short ? res : 0; }; @@ -275,7 +300,7 @@ class EGS_EXPORT EGS_ScoringArray { pointer to a format string with \a format. */ void reportResults(double norm, const char *title, bool relative_error, - const char *format = 0); + const char *format = 0); /*! \brief Stores the state of the scoring array object into the data stream \a data. @@ -290,11 +315,17 @@ class EGS_EXPORT EGS_ScoringArray { */ bool storeState(ostream &data) { data << nreg << " " << current_ncase_short << endl; - if( !egsStoreI64(data,current_ncase) ) return false; - if( !egsStoreI64(data,current_ncase_65536) ) return false; + if (!egsStoreI64(data,current_ncase)) { + return false; + } + if (!egsStoreI64(data,current_ncase_65536)) { + return false; + } data << endl; - for(int j=0; j> nreg1 >> current_ncase_short; - if( !data.good() || nreg1 < 1 ) return false; - if( !egsGetI64(data,current_ncase) ) return false; - if( !egsGetI64(data,current_ncase_65536) ) return false; - if( nreg1 != nreg ) { - if( nreg > 0 ) delete [] result; - nreg = nreg1; result = new EGS_ScoringSingle [nreg]; + int nreg1; + data >> nreg1 >> current_ncase_short; + if (!data.good() || nreg1 < 1) { + return false; + } + if (!egsGetI64(data,current_ncase)) { + return false; + } + if (!egsGetI64(data,current_ncase_65536)) { + return false; + } + if (nreg1 != nreg) { + if (nreg > 0) { + delete [] result; + } + nreg = nreg1; + result = new EGS_ScoringSingle [nreg]; } - for(int j=0; j> 16; EGS_I64 aux = current_ncase - (current_ncase_65536 << 16); current_ncase_short = (unsigned short) aux; - for(int j=0; j - shape_creator(string("egs++/dso/")+CONFIG_NAME,"EGS_BaseShape"); +shape_creator(string("egs++/dso/")+CONFIG_NAME,"EGS_BaseShape"); -EGS_BaseShape* EGS_BaseShape::createShape(EGS_Input *i) { - if(!__shape_count) { +EGS_BaseShape *EGS_BaseShape::createShape(EGS_Input *i) { + if (!__shape_count) { shape_creator.addKnownObject(new EGS_PointShape); shape_creator.addKnownObject(new EGS_BoxShape); shape_creator.addKnownObject(new EGS_SphereShape); @@ -60,13 +60,15 @@ EGS_BaseShape* EGS_BaseShape::createShape(EGS_Input *i) { return dynamic_cast(o); } -EGS_BaseShape* EGS_BaseShape::getShape(const string &Name) { +EGS_BaseShape *EGS_BaseShape::getShape(const string &Name) { EGS_Object *o = shape_creator.getObject(Name); return dynamic_cast(o); } void EGS_BaseShape::setTransformation(EGS_Input *input) { - if( T ) delete T; + if (T) { + delete T; + } T = EGS_AffineTransform::getTransformation(input); } @@ -79,87 +81,106 @@ void EGS_BaseShape::setTransformation(EGS_Input *input) { /********************** Point *******************************/ -EGS_Object* EGS_PointShape::createObject(EGS_Input *input) { +EGS_Object *EGS_PointShape::createObject(EGS_Input *input) { vector pos; int err = input->getInput("position",pos); - if( err ) { + if (err) { egsWarning("EGS_PointShape::createShape: no 'position' input\n"); return 0; } - if( pos.size() != 3 ) { + if (pos.size() != 3) { egsWarning("EGS_PointShape::createShape: found %d inputs " - "instead of 3\n",pos.size()); return 0; + "instead of 3\n",pos.size()); + return 0; } EGS_PointShape *res = new EGS_PointShape(EGS_Vector(pos[0],pos[1],pos[2])); - res->setName(input); return res; + res->setName(input); + return res; } /********************** Box **********************************/ -EGS_Object* EGS_BoxShape::createObject(EGS_Input *input) { +EGS_Object *EGS_BoxShape::createObject(EGS_Input *input) { vector s; int err = input->getInput("box size",s); - if( err ) { + if (err) { egsWarning("EGS_BoxShape::createShape: no 'box size' input?\n"); return 0; } EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); EGS_BoxShape *result; - if( s.size() == 1 ) result = new EGS_BoxShape(s[0],t); - else if( s.size() == 3 ) result = new EGS_BoxShape(s[0],s[1],s[2],t); + if (s.size() == 1) { + result = new EGS_BoxShape(s[0],t); + } + else if (s.size() == 3) { + result = new EGS_BoxShape(s[0],s[1],s[2],t); + } else { egsWarning("EGS_BoxShape::createShape: invalid 'box size' input\n"); result = 0; } - if( t ) delete t; + if (t) { + delete t; + } result->setName(input); return result; } /********************** Sphere **********************************/ -EGS_Object* EGS_SphereShape::createObject(EGS_Input *input) { +EGS_Object *EGS_SphereShape::createObject(EGS_Input *input) { EGS_Float r; int err = input->getInput("radius",r); - if( err ) { + if (err) { egsWarning("EGS_SphereShape::createShape: wrong/missing 'radius'" - " input\n"); return 0; + " input\n"); + return 0; } EGS_SphereShape *result; vector xo; err = input->getInput("midpoint",xo); - if( !err && xo.size() == 3 ) + if (!err && xo.size() == 3) { result = new EGS_SphereShape(r,EGS_Vector(xo[0],xo[1],xo[2])); - else result = new EGS_SphereShape(r); + } + else { + result = new EGS_SphereShape(r); + } result->setName(input); return result; } /********************** Cylinder **********************************/ -EGS_Object* EGS_CylinderShape::createObject(EGS_Input *input) { +EGS_Object *EGS_CylinderShape::createObject(EGS_Input *input) { EGS_Float r, H; int err = input->getInput("radius",r); - if( err ) { + if (err) { egsWarning("EGS_CylinderShape::getShape: wrong/missing 'radius'" - " input\n"); return 0; + " input\n"); + return 0; } err = input->getInput("height",H); - if( err ) { + if (err) { egsWarning("EGS_CylinderShape::getShape: wrong/missing 'height'" - " input\n"); return 0; + " input\n"); + return 0; } - vector phi_range; bool set_phi = false; - if( !input->getInput("phi range",phi_range) && phi_range.size() == 2 ) { + vector phi_range; + bool set_phi = false; + if (!input->getInput("phi range",phi_range) && phi_range.size() == 2) { set_phi = true; - phi_range[0] *= M_PI/180; phi_range[1] *= M_PI/180; + phi_range[0] *= M_PI/180; + phi_range[1] *= M_PI/180; } EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); - if( t ) { + if (t) { EGS_CylinderShape *result = new EGS_CylinderShape(r,H,t); result->setName(input); - if( set_phi ) result->setPhiRange(phi_range[0],phi_range[1]); - delete t; return result; + if (set_phi) { + result->setPhiRange(phi_range[0],phi_range[1]); + } + delete t; + return result; } vector Xo, A; int err1 = input->getInput("midpoint",Xo); @@ -167,15 +188,19 @@ EGS_Object* EGS_CylinderShape::createObject(EGS_Input *input) { bool has_Xo = (err1 == 0 && Xo.size() == 3); bool has_A = (err2 == 0 && A.size() == 3); EGS_CylinderShape *result; - if( has_Xo && has_A ) result = new EGS_CylinderShape(r,H, - EGS_Vector(Xo[0],Xo[1],Xo[2]),EGS_Vector(A[0],A[1],A[2])); - else if( has_Xo ) result = new EGS_CylinderShape(r,H, - EGS_Vector(Xo[0],Xo[1],Xo[2])); - else if( has_A ) result = new EGS_CylinderShape(r,H, - EGS_Vector(0,0,0),EGS_Vector(A[0],A[1],A[2])); - else result = new EGS_CylinderShape(r,H); + if (has_Xo && has_A) result = new EGS_CylinderShape(r,H, + EGS_Vector(Xo[0],Xo[1],Xo[2]),EGS_Vector(A[0],A[1],A[2])); + else if (has_Xo) result = new EGS_CylinderShape(r,H, + EGS_Vector(Xo[0],Xo[1],Xo[2])); + else if (has_A) result = new EGS_CylinderShape(r,H, + EGS_Vector(0,0,0),EGS_Vector(A[0],A[1],A[2])); + else { + result = new EGS_CylinderShape(r,H); + } result->setName(input); - if( set_phi ) result->setPhiRange(phi_range[0],phi_range[1]); + if (set_phi) { + result->setPhiRange(phi_range[0],phi_range[1]); + } return result; } diff --git a/HEN_HOUSE/egs++/egs_shapes.h b/HEN_HOUSE/egs++/egs_shapes.h index 71d8103e8..d0e685e1f 100644 --- a/HEN_HOUSE/egs++/egs_shapes.h +++ b/HEN_HOUSE/egs++/egs_shapes.h @@ -115,9 +115,15 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { /*! \brief Construct a shape named \a Name */ EGS_BaseShape(const string &Name="",EGS_ObjectFactory *f=0) : - EGS_Object(Name,f), T(0) { otype = "base_shape"; }; + EGS_Object(Name,f), T(0) { + otype = "base_shape"; + }; /*! \brief Destructor. Deletes #T if it is not \c null. */ - virtual ~EGS_BaseShape() { if(T) delete T; }; + virtual ~EGS_BaseShape() { + if (T) { + delete T; + } + }; /*! \brief Returns a random 3D vector. * @@ -126,8 +132,12 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * returning it. */ virtual EGS_Vector getRandomPoint(EGS_RandomGenerator *rndm) { - if( T ) return (*T)*getPoint(rndm); - else return getPoint(rndm); + if (T) { + return (*T)*getPoint(rndm); + } + else { + return getPoint(rndm); + } }; /*! \brief Sample and return a random 3D vector. @@ -157,13 +167,17 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * The shape makes a copy of the transformation pointed to by \a t. */ void setTransformation(EGS_AffineTransform *t) { - if( T ) delete T; + if (T) { + delete T; + } T = new EGS_AffineTransform(*t); }; /*! \brief Get a pointer to the affine transformation attached to this * shape. */ - const EGS_AffineTransform *getTransform() const { return T; }; + const EGS_AffineTransform *getTransform() const { + return T; + }; /*! \brief Create a shape from the information pointed to by \a inp. * @@ -172,7 +186,7 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * shape or \c null, if the information pointed to by \a inp was not * sufficient to create a shape. */ - static EGS_BaseShape* createShape(EGS_Input *inp); + static EGS_BaseShape *createShape(EGS_Input *inp); /*! \brief Get a pointer to the shape named \a Name. * @@ -180,14 +194,16 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * If a shape with name \a Name exists in this list, a pointer to * this shape is returned. Otherwise the return value is \c null. */ - static EGS_BaseShape* getShape(const string &Name); + static EGS_BaseShape *getShape(const string &Name); /*! Does this shape implement the getPointSourceDirection() method? * * This virtual function should be re-implemented in derived classes * if the shape supports the getPointSourceDirection() method. */ - virtual bool supportsDirectionMethod() const { return false; }; + virtual bool supportsDirectionMethod() const { + return false; + }; /*! Get a random direction given a source position \a xo. * @@ -202,9 +218,9 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * probability distribution results. */ virtual void getPointSourceDirection(const EGS_Vector &xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { egsFatal("getPointSourceDirection: you have to implement this " - "method for the %s shape if you want to use it\n",otype.c_str()); + "method for the %s shape if you want to use it\n",otype.c_str()); }; /*! Get the area of this shape. @@ -213,7 +229,9 @@ class EGS_EXPORT EGS_BaseShape : public EGS_Object { * their area. It is used by some of the particle sources to define * fluence as the number of particles per unit area. */ - virtual EGS_Float area() const { return 1; }; + virtual EGS_Float area() const { + return 1; + }; protected: @@ -243,20 +261,28 @@ class EGS_EXPORT EGS_SurfaceShape : public EGS_BaseShape { /*! \brief Always returns true. Shapes derived from this class \em must * implement the getPoint() method to return points on a given surface. */ - bool supportsDirectionMethod() const { return true; }; + bool supportsDirectionMethod() const { + return true; + }; /*! \brief Returns the area of this surface shape */ - EGS_Float area() const { return A; }; + EGS_Float area() const { + return A; + }; /*! \brief Get a random direction given a source position \a Xo. * * \sa EGS_BaseShape::getPointSourceDirection() */ void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; EGS_Vector x = getPoint(rndm); - u = x - xo; EGS_Float d2i = 1/u.length2(), di = sqrt(d2i); - u *= di; wt = A*fabs(u.z)*d2i; - if( T ) T->rotate(u); + u = x - xo; + EGS_Float d2i = 1/u.length2(), di = sqrt(d2i); + u *= di; + wt = A*fabs(u.z)*d2i; + if (T) { + T->rotate(u); + } }; protected: @@ -291,15 +317,19 @@ class EGS_EXPORT EGS_PointShape : public EGS_BaseShape { /*! \brief Construct a point shape located at \a Xo.*/ EGS_PointShape(const EGS_Vector &Xo = EGS_Vector(), - const string &Name="",EGS_ObjectFactory *f=0 ) : - EGS_BaseShape(Name,f), xo(Xo) { otype = "point"; }; + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), xo(Xo) { + otype = "point"; + }; ~EGS_PointShape() { }; /*! \brief Returns a fixed point */ - EGS_Vector getPoint(EGS_RandomGenerator *) { return xo; }; + EGS_Vector getPoint(EGS_RandomGenerator *) { + return xo; + }; /*! \brief Creates a point shape from the input \a inp and returns * a pointer to it. */ - EGS_Object* createObject(EGS_Input *inp); + EGS_Object *createObject(EGS_Input *inp); protected: @@ -338,17 +368,21 @@ class EGS_EXPORT EGS_BoxShape : public EGS_BaseShape { }; /*! \brief Create a cube with size \a A. */ EGS_BoxShape(EGS_Float A, const EGS_AffineTransform *t = 0, - const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), ax(A), ay(A), az(A) { - if( t ) T = new EGS_AffineTransform(*t); + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), ax(A), ay(A), az(A) { + if (t) { + T = new EGS_AffineTransform(*t); + } otype="box"; }; /*! \brief Create a box shape with size Ax,Ay,Az. */ EGS_BoxShape(EGS_Float Ax, EGS_Float Ay, EGS_Float Az, - const EGS_AffineTransform *t = 0, - const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), ax(Ax), ay(Ay), az(Az) { - if( t ) T = new EGS_AffineTransform(*t); + const EGS_AffineTransform *t = 0, + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), ax(Ax), ay(Ay), az(Az) { + if (t) { + T = new EGS_AffineTransform(*t); + } otype="box"; }; /*! \brief Destructor. Does nothing */ @@ -365,46 +399,72 @@ class EGS_EXPORT EGS_BoxShape : public EGS_BaseShape { /*! \brief Create a box shape from the information pointed to by \a inp and * return a pointer to it. */ - EGS_Object* createObject(EGS_Input *); + EGS_Object *createObject(EGS_Input *); /*! \brief Returns \c true. (It is easy to implement the * getPointSourceDirection() method for a box.) */ - bool supportsDirectionMethod() const { return true; }; + bool supportsDirectionMethod() const { + return true; + }; /*! \brief Sets the direction \a u by picking a random point uniformely the * on the box surface. * \sa EGS_BaseShape::getPointSourceDirection() */ void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; EGS_Float eta = rndm->getUniform()*area(); - if( eta < 2*ax*ay ) { + if (eta < 2*ax*ay) { u.x = ax*(rndm->getUniform()-0.5); u.y = ay*(rndm->getUniform()-0.5); - if( eta < ax*ay ) { u.z = az/2; wt = u.z - xo.z; } - else { u.z = -az/2; wt = xo.z - u.z; } + if (eta < ax*ay) { + u.z = az/2; + wt = u.z - xo.z; + } + else { + u.z = -az/2; + wt = xo.z - u.z; + } } - else if( eta < 2*(ax*ay + ax*az) ) { + else if (eta < 2*(ax*ay + ax*az)) { u.x = ax*(rndm->getUniform()-0.5); u.z = az*(rndm->getUniform()-0.5); - if( eta < 2*ax*ay + ax*az ) { u.y = ay/2; wt = u.y - xo.y; } - else { u.y = -ay/2; wt = xo.y - u.y; } + if (eta < 2*ax*ay + ax*az) { + u.y = ay/2; + wt = u.y - xo.y; + } + else { + u.y = -ay/2; + wt = xo.y - u.y; + } } else { eta -= 2*(ax*ay + ax*az); u.y = ay*(rndm->getUniform()-0.5); u.z = az*(rndm->getUniform()-0.5); - if( eta < ay*az ) { u.x = ax/2; wt = u.x - xo.x; } - else { u.x = -ax/2; wt = xo.x - u.x; } + if (eta < ay*az) { + u.x = ax/2; + wt = u.x - xo.x; + } + else { + u.x = -ax/2; + wt = xo.x - u.x; + } + } + u -= xo; + EGS_Float d2 = u.length2(), d = sqrt(d2); + u *= (1/d); + wt *= (area()/(d2*d)); + if (T) { + T->rotate(u); } - u -= xo; EGS_Float d2 = u.length2(), d = sqrt(d2); - u *= (1/d); wt *= (area()/(d2*d)); - if( T ) T->rotate(u); }; /*! \brief Returns the box surface area.*/ - EGS_Float area() const { return 2*(ax*ay + ax*az + ay*az); }; + EGS_Float area() const { + return 2*(ax*ay + ax*az + ay*az); + }; }; @@ -436,57 +496,78 @@ class EGS_EXPORT EGS_SphereShape : public EGS_BaseShape { /*! \brief Construct a sphere of unit radius about the origin. */ EGS_SphereShape(const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), R(1), xo() { otype="sphere"; }; + EGS_BaseShape(Name,f), R(1), xo() { + otype="sphere"; + }; /*! \brief Construct a sphere of radius \a r with midpoint \a Xo */ EGS_SphereShape(EGS_Float r, const EGS_Vector &Xo = EGS_Vector(0,0,0), - const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), R(r), xo(Xo) { otype = "sphere"; }; + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), R(r), xo(Xo) { + otype = "sphere"; + }; /*! Destructor. Does nothing. */ ~EGS_SphereShape() {}; /*! \brief Returns a random point within the sphere. */ EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Float r = rndm->getUniform(), r1 = rndm->getUniform(), - r2 = rndm->getUniform(); - if( r1 > r ) r = r1; - if( r2 > r ) r = r2; + r2 = rndm->getUniform(); + if (r1 > r) { + r = r1; + } + if (r2 > r) { + r = r2; + } EGS_Float cost = 2*rndm->getUniform()-1; - EGS_Float sint = sqrt(1-cost*cost); r1 = R*r*sint; - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + EGS_Float sint = sqrt(1-cost*cost); + r1 = R*r*sint; + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); return xo + EGS_Vector(r1*cphi,r1*sphi,R*r*cost); }; /*! Create a sphere shape from the information pointed to by \a inp, or null * if the information is insufficient. */ - EGS_Object* createObject(EGS_Input *inp); + EGS_Object *createObject(EGS_Input *inp); /*! \brief Returns \c true. (It is easy to implement the * getPointSourceDirection() method for a sphere.) */ - bool supportsDirectionMethod() const { return true; }; + bool supportsDirectionMethod() const { + return true; + }; /*! \brief Sets the direction \a u by picking a random point uniformely * on the sphere surface. * \sa EGS_BaseShape::getPointSourceDirection() */ void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; EGS_Float cost = 2*rndm->getUniform()-1; EGS_Float sint = 1-cost*cost; EGS_Vector x; - if( sint > 1e-10 ) { - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + if (sint > 1e-10) { + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); sint = R*sqrt(sint); - x.x = sint*cphi; x.y = sint*sphi; x.z = R*cost; + x.x = sint*cphi; + x.y = sint*sphi; + x.z = R*cost; + } + else { + x.z = R*cost; } - else x.z = R*cost; - u = (x + this->xo) - xo; EGS_Float di = 1/u.length(); u *= di; + u = (x + this->xo) - xo; + EGS_Float di = 1/u.length(); + u *= di; wt = u*x*4*M_PI*R*di*di; }; /*! \brief Returns the sphere surface area.*/ - EGS_Float area() const { return 4*M_PI*R*R; }; + EGS_Float area() const { + return 4*M_PI*R*R; + }; }; /*! \brief A cylinder shape. @@ -526,17 +607,22 @@ class EGS_EXPORT EGS_CylinderShape : public EGS_BaseShape { /*! \brief Get a point uniformly distributed within a circle */ inline void getPointInCircle(EGS_RandomGenerator *rndm, EGS_Float &x, - EGS_Float &y) { - if( !has_phi ) { - do { x = 2*rndm->getUniform()-1; y = 2*rndm->getUniform()-1; } - while( x*x + y*y > 1); - x *= R; y *= R; + EGS_Float &y) { + if (!has_phi) { + do { + x = 2*rndm->getUniform()-1; + y = 2*rndm->getUniform()-1; + } + while (x*x + y*y > 1); + x *= R; + y *= R; } else { EGS_Float r = R*sqrt(rndm->getUniform()); EGS_Float eta = rndm->getUniform(); EGS_Float phi = phi_min*(1-eta) + phi_max*eta; - x = r*cos(phi); y = r*sin(phi); + x = r*cos(phi); + y = r*sin(phi); } }; @@ -548,26 +634,31 @@ class EGS_EXPORT EGS_CylinderShape : public EGS_BaseShape { */ EGS_CylinderShape(const string &Name="",EGS_ObjectFactory *f=0) : EGS_BaseShape(), R(1), h(1), xo(), a(0,0,1), - phi_min(0), phi_max(2*M_PI), has_phi(false) { otype="cylinder";}; + phi_min(0), phi_max(2*M_PI), has_phi(false) { + otype="cylinder"; + }; EGS_CylinderShape(EGS_Float r, EGS_Float H, - const EGS_Vector &Xo = EGS_Vector(0,0,0), - const EGS_Vector &A = EGS_Vector(0,0,1), - const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), R(r), h(H), xo(Xo), a(A), - phi_min(0), phi_max(2*M_PI), has_phi(false) { + const EGS_Vector &Xo = EGS_Vector(0,0,0), + const EGS_Vector &A = EGS_Vector(0,0,1), + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), R(r), h(H), xo(Xo), a(A), + phi_min(0), phi_max(2*M_PI), has_phi(false) { EGS_RotationMatrix rmat(a); - if( xo.length2() > 1e-10 || !rmat.isI() ) + if (xo.length2() > 1e-10 || !rmat.isI()) { T = new EGS_AffineTransform(rmat.inverse(),xo); + } otype="cylinder"; }; /*! Construct a cylinder shape with radius \a r and height \a H centered * about the origin with axis along the z-axis. */ EGS_CylinderShape(EGS_Float r, EGS_Float H, const EGS_AffineTransform *t, - const string &Name="",EGS_ObjectFactory *f=0) : - EGS_BaseShape(Name,f), R(r), h(H), - phi_min(0), phi_max(2*M_PI), has_phi(false) { - if( t ) T = new EGS_AffineTransform(*t); + const string &Name="",EGS_ObjectFactory *f=0) : + EGS_BaseShape(Name,f), R(r), h(H), + phi_min(0), phi_max(2*M_PI), has_phi(false) { + if (t) { + T = new EGS_AffineTransform(*t); + } otype="cylinder"; }; /*! Destructor. Does nothing. */ @@ -575,65 +666,96 @@ class EGS_EXPORT EGS_CylinderShape : public EGS_BaseShape { /*! Set a restriction on the azimuthal angular range */ void setPhiRange(EGS_Float Phi_min, EGS_Float Phi_max) { - if( Phi_min < Phi_max ) { phi_min = Phi_min; phi_max = Phi_max; } - else { phi_min = Phi_max; phi_max = Phi_min; } - if( phi_max - phi_min < 1.99999*M_PI ) has_phi = true; - else has_phi = false; + if (Phi_min < Phi_max) { + phi_min = Phi_min; + phi_max = Phi_max; + } + else { + phi_min = Phi_max; + phi_max = Phi_min; + } + if (phi_max - phi_min < 1.99999*M_PI) { + has_phi = true; + } + else { + has_phi = false; + } }; /*! \brief Samples and returns a point uniformly distributed within the * cylinder. */ EGS_Vector getPoint(EGS_RandomGenerator *rndm) { - EGS_Float x,y; getPointInCircle(rndm,x,y); + EGS_Float x,y; + getPointInCircle(rndm,x,y); EGS_Float z = h*(rndm->getUniform()-0.5); - return EGS_Vector(x,y,z); + return EGS_Vector(x,y,z) + xo; }; /*! Creates and returns a pointer to a cylinder shape from the information * pointed to by \a inp, or \c null if the information is insufficient. */ - EGS_Object* createObject(EGS_Input *); + EGS_Object *createObject(EGS_Input *); /*! Get the cylinder radius */ - EGS_Float getRadius() const { return R; }; + EGS_Float getRadius() const { + return R; + }; /*! Get the cylinder height */ - EGS_Float getHeight() const { return h; }; + EGS_Float getHeight() const { + return h; + }; /*! \brief Returns \c true. (It is easy to implement the * getPointSourceDirection() method for a cylinder.) */ - bool supportsDirectionMethod() const { return true; }; + bool supportsDirectionMethod() const { + return true; + }; /*! \brief Sets the direction \a u by picking a random point uniformly * on the cylinder surface. * \sa EGS_BaseShape::getPointSourceDirection() */ void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; EGS_Float eta = rndm->getUniform()*(R+h); EGS_Vector x; // point on cylinder with respect to midpoint EGS_Vector n; // normal to cylinder at point x - if( eta < R ) { + if (eta < R) { getPointInCircle(rndm,x.x,x.y); - if( 2*eta < R ) { x.z = h/2; n.z = 1; } // top face: normal is up - else { x.z = -h/2; n.z = -1; } // bottom face: normal is down + if (2*eta < R) { + x.z = h/2; // top face: normal is up + n.z = 1; + } + else { + x.z = -h/2; // bottom face: normal is down + n.z = -1; + } } else { - EGS_Float cphi,sphi; rndm->getAzimuth(cphi,sphi); - x.x = R*cphi; x.y = R*sphi; x.z = h*(rndm->getUniform()-0.5); - n.x = x.x; n.y = x.y; // side face: normal is (x,y) + EGS_Float cphi,sphi; + rndm->getAzimuth(cphi,sphi); + x.x = R*cphi; + x.y = R*sphi; + x.z = h*(rndm->getUniform()-0.5); + n.x = x.x; + n.y = x.y; // side face: normal is (x,y) } u = (x+this->xo) - xo; // direction vector from origin to cylinder point EGS_Float d2 = u.length2(), d = sqrt(d2); u *= (1/d); // normalize direction vectors n.normalize(); // normalize normal wt = u*n*area()/d2; - if( T ) T->rotate(u); + if (T) { + T->rotate(u); + } }; /*! \brief Returns the cylinder surface area. */ - EGS_Float area() const { return 2*M_PI*R*(R+h); }; + EGS_Float area() const { + return 2*M_PI*R*(R+h); + }; }; #endif diff --git a/HEN_HOUSE/egs++/egs_simple_application.cpp b/HEN_HOUSE/egs++/egs_simple_application.cpp index cddff31d0..2607c2157 100644 --- a/HEN_HOUSE/egs++/egs_simple_application.cpp +++ b/HEN_HOUSE/egs++/egs_simple_application.cpp @@ -52,16 +52,23 @@ static EGS_SimpleApplication *egsApp = 0; void _null_terminate(char *s, int len) { int j; - for(j=len-1; j>=0; j--) { - if( !isspace(s[j]) ) { if( j < len-1 ) s[j+1] = 0; break; } + for (j=len-1; j>=0; j--) { + if (!isspace(s[j])) { + if (j < len-1) { + s[j+1] = 0; + } + break; + } + } + if (j < 0) { + s[0] = 0; } - if( j < 0 ) s[0] = 0; } #ifdef WIN32 -const char fs = 92; + const char fs = 92; #else -const char fs = '/'; + const char fs = '/'; #endif const char *EGS_SimpleApplication::egsHome() const { @@ -102,24 +109,31 @@ int EGS_SimpleApplication::nParallel() const { EGS_SimpleApplication::EGS_SimpleApplication(int argc, char **argv) { - g = 0; source = 0; rndm = 0; input = 0; + g = 0; + source = 0; + rndm = 0; + input = 0; // // *** make sure that there is only a single application. // - if( egsApp ) egsFatal("There can only be a single EGS_SimpleApplication" - " in a program\n"); - egsApp = this; ncase = 0; + if (egsApp) egsFatal("There can only be a single EGS_SimpleApplication" + " in a program\n"); + egsApp = this; + ncase = 0; // // *** set the number of histories to run // - for(int i=0; iegs_home); ifile += the_egsio->user_code; - ifile += fs; ifile += the_egsio->input_file; + string ifile(the_egsio->egs_home); + ifile += the_egsio->user_code; + ifile += fs; + ifile += the_egsio->input_file; ifile += ".egsinp"; - input = new EGS_Input; input->setContentFromFile(ifile.c_str()); + input = new EGS_Input; + input->setContentFromFile(ifile.c_str()); // // ********** Construct a simulation geometry from the input // EGS_Input *geom_input = input->takeInputItem("geometry definition"); - if( !geom_input ) egsFatal("No geometry definition in the input file\n"); + if (!geom_input) { + egsFatal("No geometry definition in the input file\n"); + } g = EGS_BaseGeometry::createGeometry(geom_input); - if( !g ) egsFatal("Failed to construct the simulation geometry\n"); + if (!g) { + egsFatal("Failed to construct the simulation geometry\n"); + } delete geom_input; EGS_BaseGeometry::describeGeometries(); egsInformation("\nThe simulation geometry is of type %s and has the " - "name '%s'\n\n",g->getType().c_str(),g->getName().c_str()); + "name '%s'\n\n",g->getType().c_str(),g->getName().c_str()); // // *********** Add the media names present in the geometry // - for(int j=0; jnMedia(); j++) { + for (int j=0; jnMedia(); j++) { const char *medname = g->getMediumName(j); int len = strlen(medname); int ind = egsAddMedium(medname, len); - if( ind != j+1 ) egsFatal("Medium index mismatch: %d %d\n",ind,j+1); + if (ind != j+1) { + egsFatal("Medium index mismatch: %d %d\n",ind,j+1); + } } // // ********** Construct a particle source from the input // EGS_Input *source_input = input->takeInputItem("source definition"); - if( !source_input ) egsFatal("No source definition in the input file\n"); + if (!source_input) { + egsFatal("No source definition in the input file\n"); + } source = EGS_BaseSource::createSource(source_input); - if( !source ) egsFatal("Failed to construct the particle source\n"); + if (!source) { + egsFatal("Failed to construct the particle source\n"); + } delete source_input; // // ********* Construct a random number generator from the input // rndm = EGS_RandomGenerator::createRNG(input,the_egsio->i_parallel); - if( !rndm ) rndm = EGS_RandomGenerator::defaultRNG(the_egsio->i_parallel); + if (!rndm) { + rndm = EGS_RandomGenerator::defaultRNG(the_egsio->i_parallel); + } // // ********** Get transport parameter settings from the input file @@ -203,28 +232,40 @@ EGS_SimpleApplication::EGS_SimpleApplication(int argc, char **argv) { // ********** Now check if the cross section data covers the energy // range needed by the source // - EGS_Float Emax = source->getEmax(); bool is_ok = true; - for(int imed=0; imednMedia(); imed++) { - if( Emax > the_thresh->up[imed] || - Emax > the_thresh->ue[imed] - the_useful->rm ) { + EGS_Float Emax = source->getEmax(); + bool is_ok = true; + for (int imed=0; imednMedia(); imed++) { + if (Emax > the_thresh->up[imed] || + Emax > the_thresh->ue[imed] - the_useful->rm) { egsWarning("The maximum energy of the source (%g) is higher than\n" - " the cross section data energy range for medium %d\n", - Emax,imed+1); + " the cross section data energy range for medium %d\n", + Emax,imed+1); is_ok = false; } } - if( !is_ok ) egsFatal("Create new PEGS data sets and retry\n"); + if (!is_ok) { + egsFatal("Create new PEGS data sets and retry\n"); + } nreport = 10; } EGS_SimpleApplication::~EGS_SimpleApplication() { - if( g ) { - if( g->deref() ) delete g; + if (g) { + if (g->deref()) { + delete g; + } + } + if (source) { + delete source; + } + if (rndm) { + delete rndm; + } + if (input) { + delete input; } - if( source ) delete source; - if( rndm ) delete rndm; if( input ) delete input; } void EGS_SimpleApplication::finish() { @@ -234,43 +275,75 @@ void EGS_SimpleApplication::finish() { int EGS_SimpleApplication::run() { egsInformation("\n\nSimulating %d particles...\n\n",ncase); - EGS_Timer timer; timer.start(); - EGS_I64 nperb = ncase/nreport; if( nperb < 1 ) nperb = 1; + EGS_Timer timer; + timer.start(); + EGS_I64 nperb = ncase/nreport; + if (nperb < 1) { + nperb = 1; + } EGS_Float aperb = ((EGS_Float)nperb)/((EGS_Float)ncase); - int q, latch; EGS_Float E, wt; EGS_Vector x,u; - sum_E = 0; sum_E2 = 0; Etot = 0; sum_w = 0; sum_w2 = 0; - for(EGS_I64 icase=1; icase<=ncase; icase++) { - if( icase%nperb == 0 ) egsInformation("+Finished %7.2f percent of" - " cases, cpu time = %9.3f\n", - 100*aperb*(icase/nperb),timer.time()); + int q, latch; + EGS_Float E, wt; + EGS_Vector x,u; + sum_E = 0; + sum_E2 = 0; + Etot = 0; + sum_w = 0; + sum_w2 = 0; + for (EGS_I64 icase=1; icase<=ncase; icase++) { + if (icase%nperb == 0) egsInformation("+Finished %7.2f percent of" + " cases, cpu time = %9.3f\n", + 100*aperb*(icase/nperb),timer.time()); EGS_I64 this_case = source->getNextParticle(rndm,q,latch,E,wt,x,u); //egsInformation("Got %d %g %g (%g,%g,%g) (%g,%g,%g) %lld\n", // q,E,wt,x.x,x.y,x.z,u.x,u.y,u.z,this_case); - sum_E += E*wt; sum_E2 += wt*E*E; sum_w += wt; sum_w2 += wt*wt; + sum_E += E*wt; + sum_E2 += wt*E*E; + sum_w += wt; + sum_w2 += wt*wt; int ireg = g->isWhere(x); - if( ireg < 0 ) { - EGS_Float t = 1e30; ireg = g->howfar(ireg,x,u,t); - if( ireg >= 0 ) x += u*t; + if (ireg < 0) { + EGS_Float t = 1e30; + ireg = g->howfar(ireg,x,u,t); + if (ireg >= 0) { + x += u*t; + } } - if( ireg >= 0 ) { + if (ireg >= 0) { //egsInformation(" entering in region %d\n",ireg); last_case = this_case; - if( q == 1 ) Etot += (E + 2*the_useful->rm)*wt; else Etot += E*wt; + if (q == 1) { + Etot += (E + 2*the_useful->rm)*wt; + } + else { + Etot += E*wt; + } the_stack->E[0] = (q) ? E + the_useful->rm : E; - the_stack->x[0] = x.x; the_stack->y[0] = x.y; the_stack->z[0] = x.z; - the_stack->u[0] = u.x; the_stack->v[0] = u.y; the_stack->w[0] = u.z; - the_stack->dnear[0] = 0; the_stack->wt[0] = wt; - the_stack->ir[0] = ireg+2; the_stack->iq[0] = q; - the_stack->latch[0] = latch; the_stack->np = 1; + the_stack->x[0] = x.x; + the_stack->y[0] = x.y; + the_stack->z[0] = x.z; + the_stack->u[0] = u.x; + the_stack->v[0] = u.y; + the_stack->w[0] = u.z; + the_stack->dnear[0] = 0; + the_stack->wt[0] = wt; + the_stack->ir[0] = ireg+2; + the_stack->iq[0] = q; + the_stack->latch[0] = latch; + the_stack->np = 1; startHistory(this_case); egsShower(); endHistory(); } } egsInformation("\n\nFinished simulation, CPU time was %g\n\n", - timer.time()); - sum_E = sum_E/sum_w; sum_E2 = sum_E2/sum_w; sum_E2 -= sum_E*sum_E; - if( sum_E2 > 0 ) sum_E2 = sqrt(sum_E2/(sum_w*sum_w/sum_w2-1)); + timer.time()); + sum_E = sum_E/sum_w; + sum_E2 = sum_E2/sum_w; + sum_E2 -= sum_E*sum_E; + if (sum_E2 > 0) { + sum_E2 = sqrt(sum_E2/(sum_w*sum_w/sum_w2-1)); + } egsInformation("Average particle energy: %g +/- %g\n\n",sum_E,sum_E2); return 0; @@ -282,16 +355,21 @@ void EGS_SimpleApplication::fillRandomArray(int n, EGS_Float *rarray) { } extern __extc__ void egsHowfar() { - int np = the_stack->np-1; int ireg = the_stack->ir[np]-2; - if( ireg < 0 ) { the_epcont->idisc = 1; return; } + int np = the_stack->np-1; + int ireg = the_stack->ir[np]-2; + if (ireg < 0) { + the_epcont->idisc = 1; + return; + } int newmed; int inew = egsApp->howfar(ireg, - EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]), - EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]), - the_epcont->ustep,&newmed); - if( inew != ireg ) { - the_epcont->irnew = inew+2; the_useful->medium_new = newmed+1; - if( inew < 0 ) { + EGS_Vector(the_stack->x[np],the_stack->y[np],the_stack->z[np]), + EGS_Vector(the_stack->u[np],the_stack->v[np],the_stack->w[np]), + the_epcont->ustep,&newmed); + if (inew != ireg) { + the_epcont->irnew = inew+2; + the_useful->medium_new = newmed+1; + if (inew < 0) { the_epcont->idisc = -1; // i.e. discard after the step. the_useful->medium_new = 0; } @@ -303,14 +381,17 @@ extern __extc__ void egsAusgab(EGS_I32 *iarg) { } extern __extc__ void egsHownear(EGS_Float *tperp) { - int np = the_stack->np-1; int ireg = the_stack->ir[np]-2; + int np = the_stack->np-1; + int ireg = the_stack->ir[np]-2; *tperp = egsApp->hownear(ireg,EGS_Vector(the_stack->x[np],the_stack->y[np], - the_stack->z[np])); + the_stack->z[np])); } extern __extc__ void egsStartParticle() { - int np = the_stack->np - 1; int ir = the_stack->ir[np]-2; - the_useful->medium = egsApp->getMedium(ir)+1; the_epcont->idisc = 0; + int np = the_stack->np - 1; + int ir = the_stack->ir[np]-2; + the_useful->medium = egsApp->getMedium(ir)+1; + the_epcont->idisc = 0; } extern __extc__ void egsFillRandomArray(const EGS_I32 *n, EGS_Float *rarray) { diff --git a/HEN_HOUSE/egs++/egs_simple_application.h b/HEN_HOUSE/egs++/egs_simple_application.h index 52b701dbe..6995ba4ac 100644 --- a/HEN_HOUSE/egs++/egs_simple_application.h +++ b/HEN_HOUSE/egs++/egs_simple_application.h @@ -95,13 +95,18 @@ class APP_EXPORT EGS_SimpleApplication { /*! \brief See the EGSnrc \link EGS_BaseGeometry::howfar() howfar geometry specification \endlink */ inline int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed) { return g->howfar(ireg,x,u,t,newmed); }; + EGS_Float &t, int *newmed) { + return g->howfar(ireg,x,u,t,newmed); + }; /*! \brief See the EGSnrc \link EGS_BaseGeometry::hownear() hownear geometry specification \endlink */ inline EGS_Float hownear(int ireg,const EGS_Vector &x) { - return g->hownear(ireg,x); }; + return g->hownear(ireg,x); + }; /*! \brief Get the medium index in region \a ireg */ - inline int getMedium(int ireg) { return g->medium(ireg); }; + inline int getMedium(int ireg) { + return g->medium(ireg); + }; // // ******************** ausgab *************************************** @@ -113,7 +118,9 @@ class APP_EXPORT EGS_SimpleApplication { ausgab() is called with a corresponding integer argument on various events during the simulation (see PIRS-701). */ - virtual int ausgab(int) { return 0; }; + virtual int ausgab(int) { + return 0; + }; // // ********* finish the simulation @@ -145,7 +152,9 @@ class APP_EXPORT EGS_SimpleApplication { /*! \brief Set the number of times the shower loop in run() reports the progress of the simulation to \a nprog. */ - void setNProgress(int nprog) { nreport = nprog; }; + void setNProgress(int nprog) { + nreport = nprog; + }; // // ********* functions to be executed before and after a shower. diff --git a/HEN_HOUSE/egs++/egs_simple_container.h b/HEN_HOUSE/egs++/egs_simple_container.h index fb097ee63..6b1278c90 100644 --- a/HEN_HOUSE/egs++/egs_simple_container.h +++ b/HEN_HOUSE/egs++/egs_simple_container.h @@ -48,52 +48,85 @@ template class EGS_EXPORT EGS_SimpleContainer { EGS_SimpleContainer() : n_have(0), n_tot(0), n_start(4), n_max(1000000) {}; EGS_SimpleContainer(int size) : n_have(0), n_tot(size), n_start(4), - n_max(1000000) { - if( n_tot > 0 ) array = new T [n_tot]; - else n_tot = 0; + n_max(1000000) { + if (n_tot > 0) { + array = new T [n_tot]; + } + else { + n_tot = 0; + } }; - ~EGS_SimpleContainer() { if( n_tot > 0 ) delete [] array; }; + ~EGS_SimpleContainer() { + if (n_tot > 0) { + delete [] array; + } + }; void add(const T &t) { - if( n_have >= n_tot ) grow(); + if (n_have >= n_tot) { + grow(); + } array[n_have++] = t; }; - void clear() { n_have = 0; }; + void clear() { + n_have = 0; + }; - T &operator[](int j) { return array[j]; }; + T &operator[](int j) { + return array[j]; + }; - const T &operator[](int j) const { return array[j]; }; + const T &operator[](int j) const { + return array[j]; + }; void setNmax(int Nmax) { - if( Nmax > n_tot ) { n_max = Nmax; } + if (Nmax > n_tot) { + n_max = Nmax; + } }; - T &pop() { return array[--n_have]; } + T &pop() { + return array[--n_have]; + } - unsigned int size() const { return n_have; }; + unsigned int size() const { + return n_have; + }; - unsigned int maxSize() const { return n_tot; }; + unsigned int maxSize() const { + return n_tot; + }; - unsigned int maxAllowedSize() const { return n_max; }; + unsigned int maxAllowedSize() const { + return n_max; + }; protected: void grow() { - if( n_tot > 0 ) { + if (n_tot > 0) { int nnew = 2*n_tot; - if( nnew > n_max ) { + if (nnew > n_max) { nnew = n_max; - if( nnew <= n_tot ) egsFatal("EGS_SimpleContainer::grow(): " - "reached maximum allowed size of %d\n",n_max); + if (nnew <= n_tot) egsFatal("EGS_SimpleContainer::grow(): " + "reached maximum allowed size of %d\n",n_max); } T *tmp = new T [nnew]; - for(int j=0; j #ifndef NO_SSTREAM -#include -#define S_STREAM std::istringstream + #include + #define S_STREAM std::istringstream #else -#include -#define S_STREAM std::istrstream + #include + #define S_STREAM std::istrstream #endif using namespace std; void EGS_BaseSpectrum::reportAverageEnergy() const { egsInformation("expected average energy: %g\n",expectedAverage()); - EGS_Float e=0,de=0; getSampledAverage(e,de); + EGS_Float e=0,de=0; + getSampledAverage(e,de); egsInformation("sampled average energy: %g +/- %g\n",e,de); } @@ -77,27 +78,41 @@ class EGS_EXPORT EGS_MonoEnergy : public EGS_BaseSpectrum { /*! \brief Construct a monoenergetic spectrum with energy \a energy. */ EGS_MonoEnergy(EGS_Float energy) : EGS_BaseSpectrum(), E(energy) { - char buf[1024]; sprintf(buf,"monoenergetic %g MeV",E); + char buf[1024]; + sprintf(buf,"monoenergetic %g MeV",E); type = buf; }; ~EGS_MonoEnergy() {}; - EGS_Float expectedAverage() const { return E; }; - EGS_Float maxEnergy() const { return E; }; + EGS_Float expectedAverage() const { + return E; + }; + EGS_Float maxEnergy() const { + return E; + }; protected: - EGS_Float sample(EGS_RandomGenerator *) { return E; }; + EGS_Float sample(EGS_RandomGenerator *) { + return E; + }; EGS_Float E; //!< The spectrum energy. }; static inline EGS_Float getGaussianRN(EGS_RandomGenerator *rndm) { - static bool have_x = false; static EGS_Float the_x; - if( have_x ) { have_x = false; return the_x; } + static bool have_x = false; + static EGS_Float the_x; + if (have_x) { + have_x = false; + return the_x; + } EGS_Float r = sqrt(-2*log(1-rndm->getUniform())); - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); - the_x = r*sphi; have_x = true; return r*cphi; + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); + the_x = r*sphi; + have_x = true; + return r*cphi; }; /*! \brief A Gaussian spectrum @@ -128,24 +143,38 @@ class EGS_EXPORT EGS_GaussianSpectrum : public EGS_BaseSpectrum { */ EGS_GaussianSpectrum(EGS_Float mean_energy, EGS_Float Sigma) : EGS_BaseSpectrum(), Eo(mean_energy), sigma(Sigma) { - if( Eo <= 0 ) egsFatal("EGS_GaussianSpectrum: attempt to construct " - "a spectrum with a negative mean energy (%g)\n",Eo); - if( sigma < 0 ) sigma = -sigma*0.4246609; // i.e. assume - // the user has specified FWHM + if (Eo <= 0) egsFatal("EGS_GaussianSpectrum: attempt to construct " + "a spectrum with a negative mean energy (%g)\n",Eo); + if (sigma < 0) { + sigma = -sigma*0.4246609; // i.e. assume + } + // the user has specified FWHM char buf[1024]; sprintf(buf,"Gaussian spectrum with Eo = %g and sigma = %g",Eo,sigma); type = buf; - if( Eo - 5*sigma > 0 ) Emax = Eo + 5*sigma; else Emax = 2*Eo; + if (Eo - 5*sigma > 0) { + Emax = Eo + 5*sigma; + } + else { + Emax = 2*Eo; + } }; ~EGS_GaussianSpectrum() {}; - EGS_Float expectedAverage() const { return Eo; }; - EGS_Float maxEnergy() const { return Emax; }; + EGS_Float expectedAverage() const { + return Eo; + }; + EGS_Float maxEnergy() const { + return Emax; + }; protected: EGS_Float sample(EGS_RandomGenerator *rndm) { EGS_Float E; - do { E = Eo + sigma*getGaussianRN(rndm); } while ( E <= 0 || E > Emax ); + do { + E = Eo + sigma*getGaussianRN(rndm); + } + while (E <= 0 || E > Emax); return E; }; @@ -190,13 +219,17 @@ class EGS_EXPORT EGS_DoubleGaussianSpectrum : public EGS_BaseSpectrum { * \a mean_energy and widths \a sig_left and \a sig_right. */ EGS_DoubleGaussianSpectrum(EGS_Float mean_energy, EGS_Float sig_left, - EGS_Float sig_right) : EGS_BaseSpectrum(), Eo(mean_energy), - sleft(sig_left), sright(sig_right) { - if( sleft < 0 ) sleft = -sleft*0.4246609; - if( sright< 0 ) sright= -sright*0.4246609; + EGS_Float sig_right) : EGS_BaseSpectrum(), Eo(mean_energy), + sleft(sig_left), sright(sig_right) { + if (sleft < 0) { + sleft = -sleft*0.4246609; + } + if (sright< 0) { + sright= -sright*0.4246609; + } Emax = Eo + 4*sright; - if( Eo - 4*sleft < 0 ) egsWarning("EGS_DoubleGaussianSpectrum: " - "for Eo=%g, sigma=%g there will be negative energy sampled\n"); + if (Eo - 4*sleft < 0) egsWarning("EGS_DoubleGaussianSpectrum: " + "for Eo=%g, sigma=%g there will be negative energy sampled\n"); p = sleft/(sleft + sright); char buf[1024]; sprintf(buf,"Double Gaussian spectrum with Eo = %g sig(left) = %g" @@ -204,30 +237,38 @@ class EGS_EXPORT EGS_DoubleGaussianSpectrum : public EGS_BaseSpectrum { type = buf; }; ~EGS_DoubleGaussianSpectrum() {}; - EGS_Float maxEnergy() const { return Emax; }; - EGS_Float expectedAverage() const { - return Eo + sqrt(2/M_PI)*(sright-sleft); - }; + EGS_Float maxEnergy() const { + return Emax; + }; + EGS_Float expectedAverage() const { + return Eo + sqrt(2/M_PI)*(sright-sleft); + }; protected: - EGS_Float Eo; //!< The mean energy - EGS_Float Emax; //!< The maximum energy - EGS_Float sleft; //!< The width of the spectrum left of Eo - EGS_Float sright; //!< The width of the spectrum right of Eo - EGS_Float p; /*!< The probability for picking energies from the left + EGS_Float Eo; //!< The mean energy + EGS_Float Emax; //!< The maximum energy + EGS_Float sleft; //!< The width of the spectrum left of Eo + EGS_Float sright; //!< The width of the spectrum right of Eo + EGS_Float p; /*!< The probability for picking energies from the left or right Gaussian */ - EGS_Float sample(EGS_RandomGenerator *rndm) { - EGS_Float E; - if( rndm->getUniform() < p ) { - do { E = Eo-sleft*fabs(getGaussianRN(rndm)); } while ( E <= 0 ); - } - else { - do { E = Eo+sright*fabs(getGaussianRN(rndm)); } while ( E > Emax ); - } - return E; - }; + EGS_Float sample(EGS_RandomGenerator *rndm) { + EGS_Float E; + if (rndm->getUniform() < p) { + do { + E = Eo-sleft*fabs(getGaussianRN(rndm)); + } + while (E <= 0); + } + else { + do { + E = Eo+sright*fabs(getGaussianRN(rndm)); + } + while (E > Emax); + } + return E; + }; }; @@ -261,8 +302,12 @@ class EGS_EXPORT EGS_UniformSpectrum : public EGS_BaseSpectrum { type = buf; }; ~EGS_UniformSpectrum() {}; - EGS_Float maxEnergy() const { return Emax; }; - EGS_Float expectedAverage() const { return (Emin+Emax)/2; }; + EGS_Float maxEnergy() const { + return Emax; + }; + EGS_Float expectedAverage() const { + return (Emin+Emax)/2; + }; protected: @@ -346,11 +391,17 @@ class EGS_EXPORT EGS_TabulatedSpectrum : public EGS_BaseSpectrum { * spectrum. */ EGS_TabulatedSpectrum(int N, const EGS_Float *x, const EGS_Float *f, - int Type = 1, const char *fname = 0) : EGS_BaseSpectrum(), - table(new EGS_AliasTable(N,x,f,Type)) { setType(Type,fname); }; + int Type = 1, const char *fname = 0) : EGS_BaseSpectrum(), + table(new EGS_AliasTable(N,x,f,Type)) { + setType(Type,fname); + }; - ~EGS_TabulatedSpectrum() { delete table; }; - EGS_Float maxEnergy() const { return table->getMaximum(); }; + ~EGS_TabulatedSpectrum() { + delete table; + }; + EGS_Float maxEnergy() const { + return table->getMaximum(); + }; EGS_Float expectedAverage() const { return table->getAverage(); }; @@ -359,11 +410,22 @@ class EGS_EXPORT EGS_TabulatedSpectrum : public EGS_BaseSpectrum { EGS_AliasTable *table; //!< The alias table object used to sample energies. void setType(int Type,const char *fname) { - if( Type == 0 ) type = "tabulated line spectrum"; - else if( Type == 1 ) type = "tabulated histogram spectrum"; - else type = "tabulated spectrum"; - if( fname ) { type += " defined in "; type += fname; } - else type += " defined inline"; + if (Type == 0) { + type = "tabulated line spectrum"; + } + else if (Type == 1) { + type = "tabulated histogram spectrum"; + } + else { + type = "tabulated spectrum"; + } + if (fname) { + type += " defined in "; + type += fname; + } + else { + type += " defined inline"; + } }; EGS_Float sample(EGS_RandomGenerator *rndm) { @@ -382,244 +444,334 @@ static char spec_msg1[] = "EGS_BaseSpectrum::createSpectrum:"; // istream &skipsep(istream &in) { char c; - while(1) { - in.get(c); if( in.eof() || in.fail() || !in.good() ) break; - if( c == ',' ) break; - if( !isspace(c) ) { in.putback(c); break; } + while (1) { + in.get(c); + if (in.eof() || in.fail() || !in.good()) { + break; + } + if (c == ',') { + break; + } + if (!isspace(c)) { + in.putback(c); + break; + } } return in; } -EGS_BaseSpectrum* EGS_BaseSpectrum::createSpectrum(EGS_Input *input) { - if( !input ) { +EGS_BaseSpectrum *EGS_BaseSpectrum::createSpectrum(EGS_Input *input) { + if (!input) { egsWarning("%s got null input?\n",spec_msg1); return 0; } - EGS_Input *inp = input; bool delete_it = false; - if( !input->isA("spectrum") ) { + EGS_Input *inp = input; + bool delete_it = false; + if (!input->isA("spectrum")) { inp = input->takeInputItem("spectrum"); - if( !inp ) { - egsWarning("%s no 'spectrum' input!\n",spec_msg1); return 0; + if (!inp) { + egsWarning("%s no 'spectrum' input!\n",spec_msg1); + return 0; } delete_it = true; } - string stype; int err = inp->getInput("type",stype); - if( err ) { + string stype; + int err = inp->getInput("type",stype); + if (err) { egsWarning("%s wrong/missing 'type' input\n",spec_msg1); - if( delete_it ) delete inp; return 0; + if (delete_it) { + delete inp; + } + return 0; } EGS_BaseSpectrum *spec = 0; - if( inp->compare(stype,"monoenergetic") ) { - EGS_Float Eo; err = inp->getInput("energy",Eo); - if( err ) egsWarning("%s wrong/missing 'energy' input for a " - "monoenergetic spectrum\n",spec_msg1); - else spec = new EGS_MonoEnergy(Eo); + if (inp->compare(stype,"monoenergetic")) { + EGS_Float Eo; + err = inp->getInput("energy",Eo); + if (err) egsWarning("%s wrong/missing 'energy' input for a " + "monoenergetic spectrum\n",spec_msg1); + else { + spec = new EGS_MonoEnergy(Eo); + } } - else if( inp->compare(stype,"Gaussian") ) { + else if (inp->compare(stype,"Gaussian")) { EGS_Float Eo, sig, fwhm; int err1 = inp->getInput("mean energy",Eo); int err2 = inp->getInput("sigma",sig); int err3 = inp->getInput("fwhm",fwhm); - if( err1 || (err2 && err3) ) { - if( err1 ) egsWarning("%s wrong/missing 'mean energy' input" - " for a Gaussian spectrum\n",spec_msg1); + if (err1 || (err2 && err3)) { + if (err1) egsWarning("%s wrong/missing 'mean energy' input" + " for a Gaussian spectrum\n",spec_msg1); else egsWarning("%s wrong/missing 'sigma' and 'FWHM' input for a " - "Gaussian spectrum\n",spec_msg1); + "Gaussian spectrum\n",spec_msg1); - } else { - if( Eo <= 0 ) egsWarning("%s mean energy must be positive but your" - " input was %g\n",Eo); + } + else { + if (Eo <= 0) egsWarning("%s mean energy must be positive but your" + " input was %g\n",Eo); else { - if( !err2 ) { - if( sig <= 0 ) egsWarning("%s sigma must be positive" - " but your input was %g\n",spec_msg1,sig); - else spec = new EGS_GaussianSpectrum(Eo,sig); + if (!err2) { + if (sig <= 0) egsWarning("%s sigma must be positive" + " but your input was %g\n",spec_msg1,sig); + else { + spec = new EGS_GaussianSpectrum(Eo,sig); + } } else { - if( fwhm <= 0 ) egsWarning("%s FWHM must be positive" - " but your input was %g\n",spec_msg1,fwhm); - else spec = new EGS_GaussianSpectrum(Eo,-fwhm); + if (fwhm <= 0) egsWarning("%s FWHM must be positive" + " but your input was %g\n",spec_msg1,fwhm); + else { + spec = new EGS_GaussianSpectrum(Eo,-fwhm); + } } } } } - else if( inp->compare(stype,"Double Gaussian") ) { - EGS_Float Eo; vector sig, fwhm; + else if (inp->compare(stype,"Double Gaussian")) { + EGS_Float Eo; + vector sig, fwhm; int err1 = inp->getInput("mean energy",Eo); int err2 = inp->getInput("sigma",sig); int err3 = inp->getInput("fwhm",fwhm); - if( !err1 && Eo <= 0 ) err1 = 1; - if( !err2 && sig.size() != 2 ) err2 = 1; - if( !err2 && (sig[0] <= 0 || sig[1] <= 0) ) err2 = 1; - if( !err3 && fwhm.size() != 2 ) err3 = 1; - if( !err3 && (fwhm[0] <= 0 || fwhm[1] <= 0) ) err3 = 1; - if( err1 || (err2 && err3) ) { - if( err1 ) egsWarning("%s wrong/missing 'mean energy' input" - " for a Double Gaussian spectrum\n",spec_msg1); - if( err2 && err3 ) egsWarning("%s wrong/missing 'sigma' and 'FWHM'" - " input for a Double Gaussian spectrum\n",spec_msg1); - } else { - if( !err2 && !err3 ) egsWarning("%s found 'sigma' and 'FWHM' " - "input, using 'sigma'\n",spec_msg1); - if( !err2 ) spec = new EGS_DoubleGaussianSpectrum(Eo,sig[0],sig[1]); - else spec = new EGS_DoubleGaussianSpectrum(Eo,-fwhm[0],-fwhm[1]); + if (!err1 && Eo <= 0) { + err1 = 1; + } + if (!err2 && sig.size() != 2) { + err2 = 1; + } + if (!err2 && (sig[0] <= 0 || sig[1] <= 0)) { + err2 = 1; + } + if (!err3 && fwhm.size() != 2) { + err3 = 1; + } + if (!err3 && (fwhm[0] <= 0 || fwhm[1] <= 0)) { + err3 = 1; + } + if (err1 || (err2 && err3)) { + if (err1) egsWarning("%s wrong/missing 'mean energy' input" + " for a Double Gaussian spectrum\n",spec_msg1); + if (err2 && err3) egsWarning("%s wrong/missing 'sigma' and 'FWHM'" + " input for a Double Gaussian spectrum\n",spec_msg1); + } + else { + if (!err2 && !err3) egsWarning("%s found 'sigma' and 'FWHM' " + "input, using 'sigma'\n",spec_msg1); + if (!err2) { + spec = new EGS_DoubleGaussianSpectrum(Eo,sig[0],sig[1]); + } + else { + spec = new EGS_DoubleGaussianSpectrum(Eo,-fwhm[0],-fwhm[1]); + } } } - else if( inp->compare(stype,"uniform") ) { - vector range; EGS_Float Emin, Emax; + else if (inp->compare(stype,"uniform")) { + vector range; + EGS_Float Emin, Emax; int err1 = inp->getInput("range",range); int err2 = inp->getInput("minimum energy",Emin); int err3 = inp->getInput("maximum energy",Emax); - if( !err2 && !err3 && Emin > Emax ) { + if (!err2 && !err3 && Emin > Emax) { egsWarning("%s Emin (%g) is greater than Emax (%g)?\n", - spec_msg1,Emin,Emax); - err2 = 1; err3 = 1; + spec_msg1,Emin,Emax); + err2 = 1; + err3 = 1; } - if( err1 && err2 && err3 ) egsWarning("%s wrong/missing 'range' and" - " 'minimum/maximum energy' input\n",spec_msg1); + if (err1 && err2 && err3) egsWarning("%s wrong/missing 'range' and" + " 'minimum/maximum energy' input\n",spec_msg1); else { - if( !err2 && !err3 ) spec = new EGS_UniformSpectrum(Emin,Emax); + if (!err2 && !err3) { + spec = new EGS_UniformSpectrum(Emin,Emax); + } else { - if( range[0] < range[1] ) + if (range[0] < range[1]) { spec = new EGS_UniformSpectrum(range[0],range[1]); - else + } + else { spec = new EGS_UniformSpectrum(range[1],range[0]); + } } } } - else if( inp->compare(stype,"tabulated spectrum") ) { + else if (inp->compare(stype,"tabulated spectrum")) { string spec_file; err = inp->getInput("spectrum file",spec_file); - if( !err ) { + if (!err) { ifstream sdata(spec_file.c_str()); - if( !sdata ) egsWarning("%s failed to open spectrum file %s\n", - spec_msg1,spec_file.c_str()); + if (!sdata) egsWarning("%s failed to open spectrum file %s\n", + spec_msg1,spec_file.c_str()); else { char title[1024]; sdata.getline(title,1023); - if( sdata.eof() || sdata.fail() || !sdata.good() ) { + if (sdata.eof() || sdata.fail() || !sdata.good()) { egsWarning("%s error while reading title of spectrum file" - "%s\n",spec_msg1,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + "%s\n",spec_msg1,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } - if( sdata.eof() || sdata.fail() || !sdata.good() ) { + if (sdata.eof() || sdata.fail() || !sdata.good()) { egsWarning("%s error while reading spectrum type and " - "number of bins in spectrum file %s\n", - spec_msg1,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + "number of bins in spectrum file %s\n", + spec_msg1,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } - EGS_Float dum; int nbin, mode; + EGS_Float dum; + int nbin, mode; sdata >> nbin >> skipsep >> dum >> skipsep >> mode; - if( sdata.eof() || sdata.fail() || !sdata.good() ) { + if (sdata.eof() || sdata.fail() || !sdata.good()) { egsWarning("%s error while reading spectrum type and " - "number of bins in spectrum file %s\n", - spec_msg1,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + "number of bins in spectrum file %s\n", + spec_msg1,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } - if( nbin < 2 ) { + if (nbin < 2) { egsWarning("%s nbin in a spectrum must be at least 2\n" - " you have %d in the spectrum file %s\n", - spec_msg1,nbin,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + " you have %d in the spectrum file %s\n", + spec_msg1,nbin,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } - if( mode < 0 || mode > 3 ) { + if (mode < 0 || mode > 3) { egsWarning("%s unknown spectrum type %d in spectrum file" - " %s\n",spec_msg1,mode,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + " %s\n",spec_msg1,mode,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } - EGS_Float *en_array, *f_array; int ibin; + EGS_Float *en_array, *f_array; + int ibin; f_array = new EGS_Float [nbin]; - if( mode == 0 || mode == 1 ) { + if (mode == 0 || mode == 1) { en_array = new EGS_Float [nbin+1]; - en_array[0] = dum; ibin=1; + en_array[0] = dum; + ibin=1; } else { - en_array = new EGS_Float [nbin]; ibin=0; + en_array = new EGS_Float [nbin]; + ibin=0; } - for(int j=0; j> en_array[ibin++] >> skipsep >> f_array[j]; - if( sdata.eof() || sdata.fail() || !sdata.good() ) { + if (sdata.eof() || sdata.fail() || !sdata.good()) { egsWarning("%s error on line %d in spectrum file %s\n", - spec_msg1,j+2,spec_file.c_str()); - if( delete_it ) delete inp; - delete [] en_array; delete [] f_array; + spec_msg1,j+2,spec_file.c_str()); + if (delete_it) { + delete inp; + } + delete [] en_array; + delete [] f_array; return 0; } - if( mode != 2 && ibin > 1 ) { - if( en_array[ibin-1] <= en_array[ibin-2] ) { + if (mode != 2 && ibin > 1) { + if (en_array[ibin-1] <= en_array[ibin-2]) { egsWarning("%s energies must be in increasing " - "order.\n This is not the case for input on " - "lines %d,%d in spectrum file %s\n", - spec_msg1,j+2,j+1,spec_file.c_str()); - if( delete_it ) delete inp; return 0; + "order.\n This is not the case for input on " + "lines %d,%d in spectrum file %s\n", + spec_msg1,j+2,j+1,spec_file.c_str()); + if (delete_it) { + delete inp; + } + return 0; } } - if( mode == 0 ) - f_array[j]/=(en_array[ibin-1]-en_array[ibin-2]); + if (mode == 0) { + f_array[j]/=(en_array[ibin-1]-en_array[ibin-2]); + } } int itype = 1; - if( mode == 2 ) itype = 0; - else if( mode == 3 ) itype = 2; + if (mode == 2) { + itype = 0; + } + else if (mode == 3) { + itype = 2; + } int nb = itype == 1 ? nbin+1 : nbin; spec = new EGS_TabulatedSpectrum(nb,en_array,f_array,itype, - spec_file.c_str()); - delete [] en_array; delete [] f_array; + spec_file.c_str()); + delete [] en_array; + delete [] f_array; } } else { - vector eners, probs; int itype=1; + vector eners, probs; + int itype=1; int err1 = inp->getInput("energies",eners); int err2 = inp->getInput("probabilities",probs); int err3 = inp->getInput("spectrum type",itype); - if( err1 || err2 ) { - if( err1 ) egsWarning("%s wrong/missing 'energies' input\n", - spec_msg1); - if( err2 ) egsWarning("%s wrong/missing 'probabilities' " - "input\n",spec_msg1); + if (err1 || err2) { + if (err1) egsWarning("%s wrong/missing 'energies' input\n", + spec_msg1); + if (err2) egsWarning("%s wrong/missing 'probabilities' " + "input\n",spec_msg1); } else { - if( itype == 1 && probs.size() != eners.size()-1 ) + if (itype == 1 && probs.size() != eners.size()-1) egsWarning("%s for spectrum type 1 the number of energies" - " must be the number of probabilities + 1\n", - spec_msg1); - else if( (itype == 0 || itype == 2) && - probs.size() != eners.size() ) + " must be the number of probabilities + 1\n", + spec_msg1); + else if ((itype == 0 || itype == 2) && + probs.size() != eners.size()) egsWarning("%s for spectrum types 0 and 2 the number of " - "energies must be equal to the number of probabilities\n", - spec_msg1); + "energies must be equal to the number of probabilities\n", + spec_msg1); else { int nbin = eners.size(); int nbin1 = itype == 1 ? nbin-1 : nbin; EGS_Float *x = new EGS_Float [nbin], - *f = new EGS_Float [nbin1]; + *f = new EGS_Float [nbin1]; int ibin = 0; - if( itype == 1 ) { ibin = 1; x[0] = eners[0]; } + if (itype == 1) { + ibin = 1; + x[0] = eners[0]; + } egsWarning("type = %d nbin = %d nbin1 = %d\n",itype, - nbin,nbin1); - for(int j=0; j 1 ) { - if( x[ibin-1] <= x[ibin-2] ) { + if (itype != 0 && ibin > 1) { + if (x[ibin-1] <= x[ibin-2]) { egsWarning("%s energies must be given in " - "increasing order\n This is not the case" - " for inputs %d and %d (%g,%g) %d\n", - spec_msg1,ibin-2,ibin-1,x[ibin-2],x[ibin-1], - j); - if( delete_it ) delete inp; - delete [] x; delete [] f; return 0; + "increasing order\n This is not the case" + " for inputs %d and %d (%g,%g) %d\n", + spec_msg1,ibin-2,ibin-1,x[ibin-2],x[ibin-1], + j); + if (delete_it) { + delete inp; + } + delete [] x; + delete [] f; + return 0; } } } spec = new EGS_TabulatedSpectrum(nbin,x,f,itype,0); - delete [] x; delete [] f; + delete [] x; + delete [] f; } } } } - else egsWarning("%s unknown spectrum type %s\n",spec_msg1,stype.c_str()); - if( delete_it ) delete inp; + else { + egsWarning("%s unknown spectrum type %s\n",spec_msg1,stype.c_str()); + } + if (delete_it) { + delete inp; + } return spec; } diff --git a/HEN_HOUSE/egs++/egs_timer.cpp b/HEN_HOUSE/egs++/egs_timer.cpp index 8b1505503..25a2bb3f6 100644 --- a/HEN_HOUSE/egs++/egs_timer.cpp +++ b/HEN_HOUSE/egs++/egs_timer.cpp @@ -42,12 +42,15 @@ class EGS_PrivateTimer { public: - EGS_PrivateTimer() : mark(clock()) {}; - unsigned long mark; - void start() { mark = clock(); }; - EGS_Float time() { - EGS_Float cpu = clock(); return (cpu - mark)/CLOCKS_PER_SEC; - }; + EGS_PrivateTimer() : mark(clock()) {}; + unsigned long mark; + void start() { + mark = clock(); + }; + EGS_Float time() { + EGS_Float cpu = clock(); + return (cpu - mark)/CLOCKS_PER_SEC; + }; }; #else @@ -66,30 +69,41 @@ clock_t clps = 0; */ class EGS_PrivateTimer { public: - tms tstart, tend; - EGS_PrivateTimer() { - if( !clps ) { - clps = sysconf(_SC_CLK_TCK); - } - times(&tstart); - }; - void start() { - if( times(&tstart) < 0 ) egsWarning(" times returned < 0???\n"); - }; - EGS_Float time() { - times(&tend); EGS_Float cpu = tend.tms_utime; - return (cpu - tstart.tms_utime)/clps; - }; + tms tstart, tend; + EGS_PrivateTimer() { + if (!clps) { + clps = sysconf(_SC_CLK_TCK); + } + times(&tstart); + }; + void start() { + if (times(&tstart) < 0) { + egsWarning(" times returned < 0???\n"); + } + }; + EGS_Float time() { + times(&tend); + EGS_Float cpu = tend.tms_utime; + return (cpu - tstart.tms_utime)/clps; + }; }; #endif #endif -EGS_Timer::EGS_Timer() { p = new EGS_PrivateTimer; } +EGS_Timer::EGS_Timer() { + p = new EGS_PrivateTimer; +} -EGS_Timer::~EGS_Timer() { delete p; } +EGS_Timer::~EGS_Timer() { + delete p; +} -void EGS_Timer::start() { p->start(); } +void EGS_Timer::start() { + p->start(); +} -EGS_Float EGS_Timer::time() { return p->time(); } +EGS_Float EGS_Timer::time() { + return p->time(); +} diff --git a/HEN_HOUSE/egs++/egs_transformations.cpp b/HEN_HOUSE/egs++/egs_transformations.cpp index a890e3c99..449a53f50 100644 --- a/HEN_HOUSE/egs++/egs_transformations.cpp +++ b/HEN_HOUSE/egs++/egs_transformations.cpp @@ -40,52 +40,68 @@ #include using std::vector; -EGS_AffineTransform* EGS_AffineTransform::getTransformation(EGS_Input *i) { - if( !i ) return 0; - EGS_Input *input; bool delete_it = false; - if( i->isA("transformation") ) input = i; +EGS_AffineTransform *EGS_AffineTransform::getTransformation(EGS_Input *i) { + if (!i) { + return 0; + } + EGS_Input *input; + bool delete_it = false; + if (i->isA("transformation")) { + input = i; + } else { input = i->takeInputItem("transformation"); - if( !input ) return 0; + if (!input) { + return 0; + } delete_it = true; } - EGS_Vector t; vector tmp; + EGS_Vector t; + vector tmp; int err = input->getInput("translation",tmp); - if( !err && tmp.size() == 3 ) t = EGS_Vector(tmp[0],tmp[1],tmp[2]); + if (!err && tmp.size() == 3) { + t = EGS_Vector(tmp[0],tmp[1],tmp[2]); + } EGS_AffineTransform *result; err = input->getInput("rotation vector",tmp); - if( !err && tmp.size() == 3 ) + if (!err && tmp.size() == 3) result = new EGS_AffineTransform( - EGS_RotationMatrix(EGS_Vector(tmp[0],tmp[1],tmp[2])),t); + EGS_RotationMatrix(EGS_Vector(tmp[0],tmp[1],tmp[2])),t); else { err = input->getInput("rotation",tmp); - if( !err ) { - if( tmp.size() == 2 ) result = new EGS_AffineTransform( + if (!err) { + if (tmp.size() == 2) result = new EGS_AffineTransform( EGS_RotationMatrix(tmp[0],tmp[1]),t); - else if( tmp.size() == 3 ) result = new EGS_AffineTransform( + else if (tmp.size() == 3) result = new EGS_AffineTransform( EGS_RotationMatrix(tmp[0],tmp[1],tmp[2]),t); - else if( tmp.size() == 4 ) { + else if (tmp.size() == 4) { EGS_Vector tmp1(tmp[0],tmp[1],tmp[2]); EGS_RotationMatrix R1(tmp1); EGS_RotationMatrix R2(EGS_RotationMatrix::rotZ(tmp[3])); EGS_RotationMatrix Rtot = R1.inverse()*R2*R1; result = new EGS_AffineTransform(Rtot,t); } - else if( tmp.size() == 9 ) { + else if (tmp.size() == 9) { EGS_RotationMatrix R(tmp[0],tmp[1],tmp[2], tmp[3],tmp[4],tmp[5], tmp[6],tmp[7],tmp[8]); - if( !R.isRotation() ) + if (!R.isRotation()) egsWarning("getTransformation: the rotation specified by\n" - " %g %g %g\n %g %g %g\n %g %g %g\n" - " is not a rotation\n",tmp[0],tmp[1],tmp[2], - tmp[3],tmp[4],tmp[5],tmp[6],tmp[7],tmp[8]); + " %g %g %g\n %g %g %g\n %g %g %g\n" + " is not a rotation\n",tmp[0],tmp[1],tmp[2], + tmp[3],tmp[4],tmp[5],tmp[6],tmp[7],tmp[8]); result = new EGS_AffineTransform(R,t); } - else result = new EGS_AffineTransform(EGS_RotationMatrix(),t); + else { + result = new EGS_AffineTransform(EGS_RotationMatrix(),t); + } + } + else { + result = new EGS_AffineTransform(EGS_RotationMatrix(),t); } - else result = new EGS_AffineTransform(EGS_RotationMatrix(),t); } - if( delete_it ) delete input; + if (delete_it) { + delete input; + } return result; } diff --git a/HEN_HOUSE/egs++/egs_transformations.h b/HEN_HOUSE/egs++/egs_transformations.h index c77ebb8ad..0f8d0532b 100644 --- a/HEN_HOUSE/egs++/egs_transformations.h +++ b/HEN_HOUSE/egs++/egs_transformations.h @@ -66,270 +66,324 @@ class EGS_EXPORT EGS_RotationMatrix { protected: /*! The 9 rotation matrix coefficients */ - EGS_Float rxx, rxy, rxz, - ryx, ryy, ryz, - rzx, rzy, rzz; + EGS_Float rxx, rxy, rxz, + ryx, ryy, ryz, + rzx, rzy, rzz; public: - //! \brief Default constructor, results in a unit matrix object. - EGS_RotationMatrix() { - rxx=1; rxy=0; rxz=0; - ryx=0; ryy=1; ryz=0; - rzx=0; rzy=0; rzz=1; - }; - - // - // hopefully no one will use this constructor - // with a non-rotation matrix elements - // - /*! \brief Construct a rotation matrix object from 9 floating point numbers*/ - EGS_RotationMatrix(EGS_Float xx, EGS_Float xy, EGS_Float xz, - EGS_Float yx, EGS_Float yy, EGS_Float yz, - EGS_Float zx, EGS_Float zy, EGS_Float zz) { - rxx=xx; rxy=xy; rxz=xz; - ryx=yx; ryy=yy; ryz=yz; - rzx=zx; rzy=zy; rzz=zz; - }; - - //! \brief Copy constructor - EGS_RotationMatrix(const EGS_RotationMatrix &m) { - rxx=m.rxx; rxy=m.rxy; rxz=m.rxz; - ryx=m.ryx; ryy=m.ryy; ryz=m.ryz; - rzx=m.rzx; rzy=m.rzy; rzz=m.rzz; - }; - - /*! \brief Is this object a real rotation matrix? - - Returns true if the object is a real rotation matrix, false otherwise. - A 3x3 matrix \f$R\f$ is a rotation matrix if its determinant is unity - and if \f$ R R^T\f$ is a unity matrix, where \f$ R^T\f$ is the transposed - matrix. - */ - bool isRotation() const { - EGS_Float d = det() - 1; EGS_RotationMatrix t((*this)*inverse()); - if( fabs(d) > 1e-4 || !t.isI() ) return false; - return true; - }; - - // creates a matrix which, when applied to the vector v, - // transforms it into a vector along the z-axis. - // why z-axis? - // well, it has to be one of the axis and in physics - // things usually happen along the z-axis! - /*! \brief Create a rotation matrix from the vector \a v. - - This constructs a matrix which, when applied to the vector \a v, - transforms it into a vector along the z-axis. Why z-axis? - Well, it has to be one of the axis and in physics things usually happen - along the z-axis! - */ - EGS_RotationMatrix(const EGS_Vector &v) { - EGS_Float sinz = v.x*v.x + v.y*v.y; - EGS_Float norm = sinz + v.z*v.z; - if( norm < 1e-15 ) egsFatal("EGS_RotationMatrix::EGS_RotationMatrix: \n" - " no construction from a zero vector possible!\n"); - norm = sqrt(norm); - if( sinz > 1e-15 ) { - sinz = sqrt(sinz); - EGS_Float cphi = v.x/sinz; register EGS_Float sphi = v.y/sinz; - EGS_Float cost = v.z/norm; register EGS_Float sint = -sinz/norm; - *this = rotY(cost,sint)*rotZ(cphi,sphi); - } - else { // v is along the z-axis => matrix is the unit transformation - rxx = 1; rxy = 0; rxz = 0; - ryx = 0; ryy = 1; ryz = 0; - rzx = 0; rzy = 0; rzz = 1; - } - }; - - // R_x(alpha) * R_y(beta) * R_z(gamma) - /*! \brief Constructs a rotation matrix from rotation angles - around the x-, y-, and z-axis as \f$R_x(\alpha) R_y(\beta) R_z(\gamma)\f$ - */ - EGS_RotationMatrix(EGS_Float alpha, EGS_Float beta, EGS_Float gamma) { - *this = rotX(alpha)*rotY(beta)*rotZ(gamma); - }; - - // R_z(phi) * R_x(theta) - /*! \brief Constructs a rotation matrix from the angles \a theta and - \a phi (polar and azimuthal) as \f$R_z(\phi) R_x(\theta)\f$ - */ - EGS_RotationMatrix(EGS_Float phi, EGS_Float theta) { - *this = rotZ(phi)*rotX(theta); - }; - - //! \brief Assignment operator - EGS_RotationMatrix &operator=(const EGS_RotationMatrix &m) { - rxx=m.rxx; rxy=m.rxy; rxz=m.rxz; - ryx=m.ryx; ryy=m.ryy; ryz=m.ryz; - rzx=m.rzx; rzy=m.rzy; rzz=m.rzz; - return *this; - }; - - //! \brief Comparison operator - bool operator==(const EGS_RotationMatrix &m) { - return - ( (rxx == m.rxx) && (rxy == m.rxy) && (rxz == m.rxz) && - (ryx == m.ryx) && (ryy == m.ryy) && (ryz == m.ryz) && - (rzx == m.rxz) && (rzy == m.rzy) && (rzz == m.rzz) ) ? true : false; - }; - - /*! \brief Returns \c true, if this object is a unity matrix, \a false - otherwise */ - bool isI() const { - return ( rxx == 1 && rxy == 0 && rxz == 0 && ryx == 0 && ryy == 1 && - ryz == 0 && rzx == 0 && rzy == 0 && rzz == 1 ); - }; - - /*! \brief Returns the rotated a vector \f$ R \cdot \vec{v}\f$ */ - EGS_Vector operator*(const EGS_Vector &v) const { - return EGS_Vector(rxx*v.x + rxy*v.y + rxz*v.z, - ryx*v.x + ryy*v.y + ryz*v.z, - rzx*v.x + rzy*v.y + rzz*v.z); - }; - - /*! \brief Multiplies the invoking object with \a m from the right - and returns the result. */ - EGS_RotationMatrix operator*(const EGS_RotationMatrix &m) const { - return EGS_RotationMatrix( - rxx*m.rxx+rxy*m.ryx+rxz*m.rzx, rxx*m.rxy+rxy*m.ryy+rxz*m.rzy, - rxx*m.rxz+rxy*m.ryz+rxz*m.rzz, - ryx*m.rxx+ryy*m.ryx+ryz*m.rzx, ryx*m.rxy+ryy*m.ryy+ryz*m.rzy, - ryx*m.rxz+ryy*m.ryz+ryz*m.rzz, - rzx*m.rxx+rzy*m.ryx+rzz*m.rzx, rzx*m.rxy+rzy*m.ryy+rzz*m.rzy, - rzx*m.rxz+rzy*m.ryz+rzz*m.rzz); - }; - - // r *= m means r = r*m - /*! \brief Multiplies the invoking object with \a m from the right and - assigns the resulting matrix to the invoking object returning a reference - to it. */ - EGS_RotationMatrix &operator*=(const EGS_RotationMatrix &m) { - return *this = operator * (m); - }; - - // r.multiply(m) means r = m*r; - /*! \brief Multiplies the invoking object with \a m from the left and returns - the result. - - Note: \f$ R \cdot M \ne R \cdot M\f$ and therefore one needs to distinguish - between multiplication from the right as in operator*() and multiplication - from the left. - */ - void multiply(const EGS_RotationMatrix &m) { - *this = m.operator * (*this); - }; - - /*! \brief Returns the inverse matrix. - - Note that the implementation simply assumes that the matrix is a real - rotation matrix and therefore returns the transposed matrix. - */ - EGS_RotationMatrix inverse() const { - return EGS_RotationMatrix(rxx,ryx,rzx,rxy,ryy,rzy,rxz,ryz,rzz); - }; - - //! \brief Returns the transposed matrix. - EGS_RotationMatrix T() { - return EGS_RotationMatrix(rxx,ryx,rzx,rxy,ryy,rzy,rxz,ryz,rzz); - }; - - //! \brief Inverts the matrix and returns a reference to it. - EGS_RotationMatrix &invert() { - return *this = inverse(); - }; - - /*! \brief Returns a rotation around the x-axis by the angle \f$\phi\f$ - with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. - */ - static EGS_RotationMatrix rotX(EGS_Float cphi,EGS_Float sphi) { - return EGS_RotationMatrix( - (EGS_Float)1,(EGS_Float)0,(EGS_Float)0, - (EGS_Float)0, cphi, sphi, - (EGS_Float)0, -sphi, cphi); - }; - - /*! \brief Returns a rotation around the y-axis by the angle \f$\phi\f$ - with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. - */ - static EGS_RotationMatrix rotY(EGS_Float cphi,EGS_Float sphi) { - return EGS_RotationMatrix( cphi, (EGS_Float)0, sphi, - (EGS_Float)0, (EGS_Float)1, (EGS_Float)0, - -sphi, (EGS_Float)0, cphi); - }; - - /*! \brief Returns a rotation around the z-axis by the angle \f$\phi\f$ - with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. - */ - static EGS_RotationMatrix rotZ(EGS_Float cphi,EGS_Float sphi) { - return EGS_RotationMatrix( cphi, sphi, (EGS_Float)0, - -sphi, cphi, (EGS_Float)0, - (EGS_Float)0,(EGS_Float)0, (EGS_Float)1); - }; - - //! \brief Returns a rotation around the x-axis by the angle \a phi - static EGS_RotationMatrix rotX(EGS_Float phi) { - return rotX(cos(phi),sin(phi)); - }; - - //! \brief Returns a rotation around the y-axis by the angle \a phi - static EGS_RotationMatrix rotY(EGS_Float phi) { - return rotY(cos(phi),sin(phi)); - }; - - //! \brief Returns a rotation around the z-axis by the angle \a phi - static EGS_RotationMatrix rotZ(EGS_Float phi) { - return rotZ(cos(phi),sin(phi)); - }; - - /*! \brief Returns a rotation by the angle \a phi around the axis - defined by the vector \a v. - */ - static EGS_RotationMatrix rotV(EGS_Float phi, const EGS_Vector &v) { - return rotV(cos(phi),sin(phi),v); - }; - - /*! \overload */ - static EGS_RotationMatrix rotV(EGS_Float cphi, EGS_Float sphi, - const EGS_Vector &v) { - EGS_RotationMatrix m(v); - return (m.inverse())*(rotZ(cphi,sphi))*(m); - }; - - //! \brief Calculates and returns the determinant of the matrix - EGS_Float det() const { - return rxx*ryy*rzz + rxy*ryz*rzx + ryx*rzy*rxz - - rxz*ryy*rzx - rxy*ryx*rzz - rzy*ryz*rxx; - }; - - /*! \brief Multiplies the invoking vector \a v from the right with the - matrix \a m and returns the result. - */ - friend EGS_Vector operator*(const EGS_Vector &v, - const EGS_RotationMatrix &m) { - return EGS_Vector(v.x*m.rxx+v.y*m.ryx+v.z*m.rzx, - v.x*m.rxy+v.y*m.ryy+v.z*m.rzy, - v.x*m.rxz+v.y*m.ryz+v.z*m.rzz); - }; - - /*! \brief Multiplies the invoking vector \a v from the right with the - matrix \a m and assigns the result to the invoking vector. - Returns a reference to the resulting vector. - */ - friend EGS_Vector &operator*=(EGS_Vector &v, const EGS_RotationMatrix &m) { - v = v*m; return v; - }; - - inline EGS_Float xx() const { return rxx; }; - inline EGS_Float xy() const { return rxy; }; - inline EGS_Float xz() const { return rxz; }; - inline EGS_Float yx() const { return ryx; }; - inline EGS_Float yy() const { return ryy; }; - inline EGS_Float yz() const { return ryz; }; - inline EGS_Float zx() const { return rzx; }; - inline EGS_Float zy() const { return rzy; }; - inline EGS_Float zz() const { return rzz; }; + //! \brief Default constructor, results in a unit matrix object. + EGS_RotationMatrix() { + rxx=1; + rxy=0; + rxz=0; + ryx=0; + ryy=1; + ryz=0; + rzx=0; + rzy=0; + rzz=1; + }; + + // + // hopefully no one will use this constructor + // with a non-rotation matrix elements + // + /*! \brief Construct a rotation matrix object from 9 floating point numbers*/ + EGS_RotationMatrix(EGS_Float xx, EGS_Float xy, EGS_Float xz, + EGS_Float yx, EGS_Float yy, EGS_Float yz, + EGS_Float zx, EGS_Float zy, EGS_Float zz) { + rxx=xx; + rxy=xy; + rxz=xz; + ryx=yx; + ryy=yy; + ryz=yz; + rzx=zx; + rzy=zy; + rzz=zz; + }; + + //! \brief Copy constructor + EGS_RotationMatrix(const EGS_RotationMatrix &m) { + rxx=m.rxx; + rxy=m.rxy; + rxz=m.rxz; + ryx=m.ryx; + ryy=m.ryy; + ryz=m.ryz; + rzx=m.rzx; + rzy=m.rzy; + rzz=m.rzz; + }; + + /*! \brief Is this object a real rotation matrix? + + Returns true if the object is a real rotation matrix, false otherwise. + A 3x3 matrix \f$R\f$ is a rotation matrix if its determinant is unity + and if \f$ R R^T\f$ is a unity matrix, where \f$ R^T\f$ is the transposed + matrix. + */ + bool isRotation() const { + EGS_Float d = det() - 1; + EGS_RotationMatrix t((*this)*inverse()); + if (fabs(d) > 1e-4 || !t.isI()) { + return false; + } + return true; + }; + + // creates a matrix which, when applied to the vector v, + // transforms it into a vector along the z-axis. + // why z-axis? + // well, it has to be one of the axis and in physics + // things usually happen along the z-axis! + /*! \brief Create a rotation matrix from the vector \a v. + + This constructs a matrix which, when applied to the vector \a v, + transforms it into a vector along the z-axis. Why z-axis? + Well, it has to be one of the axis and in physics things usually happen + along the z-axis! + */ + EGS_RotationMatrix(const EGS_Vector &v) { + EGS_Float sinz = v.x*v.x + v.y*v.y; + EGS_Float norm = sinz + v.z*v.z; + if (norm < 1e-15) egsFatal("EGS_RotationMatrix::EGS_RotationMatrix: \n" + " no construction from a zero vector possible!\n"); + norm = sqrt(norm); + if (sinz > 1e-15) { + sinz = sqrt(sinz); + EGS_Float cphi = v.x/sinz; + register EGS_Float sphi = v.y/sinz; + EGS_Float cost = v.z/norm; + register EGS_Float sint = -sinz/norm; + *this = rotY(cost,sint)*rotZ(cphi,sphi); + } + else { // v is along the z-axis => matrix is the unit transformation + rxx = 1; + rxy = 0; + rxz = 0; + ryx = 0; + ryy = 1; + ryz = 0; + rzx = 0; + rzy = 0; + rzz = 1; + } + }; + + // R_x(alpha) * R_y(beta) * R_z(gamma) + /*! \brief Constructs a rotation matrix from rotation angles + around the x-, y-, and z-axis as \f$R_x(\alpha) R_y(\beta) R_z(\gamma)\f$ + */ + EGS_RotationMatrix(EGS_Float alpha, EGS_Float beta, EGS_Float gamma) { + *this = rotX(alpha)*rotY(beta)*rotZ(gamma); + }; + + // R_z(phi) * R_x(theta) + /*! \brief Constructs a rotation matrix from the angles \a theta and + \a phi (polar and azimuthal) as \f$R_z(\phi) R_x(\theta)\f$ + */ + EGS_RotationMatrix(EGS_Float phi, EGS_Float theta) { + *this = rotZ(phi)*rotX(theta); + }; + + //! \brief Assignment operator + EGS_RotationMatrix &operator=(const EGS_RotationMatrix &m) { + rxx=m.rxx; + rxy=m.rxy; + rxz=m.rxz; + ryx=m.ryx; + ryy=m.ryy; + ryz=m.ryz; + rzx=m.rzx; + rzy=m.rzy; + rzz=m.rzz; + return *this; + }; + + //! \brief Comparison operator + bool operator==(const EGS_RotationMatrix &m) { + return + ((rxx == m.rxx) && (rxy == m.rxy) && (rxz == m.rxz) && + (ryx == m.ryx) && (ryy == m.ryy) && (ryz == m.ryz) && + (rzx == m.rxz) && (rzy == m.rzy) && (rzz == m.rzz)) ? true : false; + }; + + /*! \brief Returns \c true, if this object is a unity matrix, \a false + otherwise */ + bool isI() const { + return (rxx == 1 && rxy == 0 && rxz == 0 && ryx == 0 && ryy == 1 && + ryz == 0 && rzx == 0 && rzy == 0 && rzz == 1); + }; + + /*! \brief Returns the rotated a vector \f$ R \cdot \vec{v}\f$ */ + EGS_Vector operator*(const EGS_Vector &v) const { + return EGS_Vector(rxx*v.x + rxy*v.y + rxz*v.z, + ryx*v.x + ryy*v.y + ryz*v.z, + rzx*v.x + rzy*v.y + rzz*v.z); + }; + + /*! \brief Multiplies the invoking object with \a m from the right + and returns the result. */ + EGS_RotationMatrix operator*(const EGS_RotationMatrix &m) const { + return EGS_RotationMatrix( + rxx*m.rxx+rxy*m.ryx+rxz*m.rzx, rxx*m.rxy+rxy*m.ryy+rxz*m.rzy, + rxx*m.rxz+rxy*m.ryz+rxz*m.rzz, + ryx*m.rxx+ryy*m.ryx+ryz*m.rzx, ryx*m.rxy+ryy*m.ryy+ryz*m.rzy, + ryx*m.rxz+ryy*m.ryz+ryz*m.rzz, + rzx*m.rxx+rzy*m.ryx+rzz*m.rzx, rzx*m.rxy+rzy*m.ryy+rzz*m.rzy, + rzx*m.rxz+rzy*m.ryz+rzz*m.rzz); + }; + + // r *= m means r = r*m + /*! \brief Multiplies the invoking object with \a m from the right and + assigns the resulting matrix to the invoking object returning a reference + to it. */ + EGS_RotationMatrix &operator*=(const EGS_RotationMatrix &m) { + return *this = operator * (m); + }; + + // r.multiply(m) means r = m*r; + /*! \brief Multiplies the invoking object with \a m from the left and returns + the result. + + Note: \f$ R \cdot M \ne R \cdot M\f$ and therefore one needs to distinguish + between multiplication from the right as in operator*() and multiplication + from the left. + */ + void multiply(const EGS_RotationMatrix &m) { + *this = m.operator * (*this); + }; + + /*! \brief Returns the inverse matrix. + + Note that the implementation simply assumes that the matrix is a real + rotation matrix and therefore returns the transposed matrix. + */ + EGS_RotationMatrix inverse() const { + return EGS_RotationMatrix(rxx,ryx,rzx,rxy,ryy,rzy,rxz,ryz,rzz); + }; + + //! \brief Returns the transposed matrix. + EGS_RotationMatrix T() { + return EGS_RotationMatrix(rxx,ryx,rzx,rxy,ryy,rzy,rxz,ryz,rzz); + }; + + //! \brief Inverts the matrix and returns a reference to it. + EGS_RotationMatrix &invert() { + return *this = inverse(); + }; + + /*! \brief Returns a rotation around the x-axis by the angle \f$\phi\f$ + with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. + */ + static EGS_RotationMatrix rotX(EGS_Float cphi,EGS_Float sphi) { + return EGS_RotationMatrix( + (EGS_Float)1,(EGS_Float)0,(EGS_Float)0, + (EGS_Float)0, cphi, sphi, + (EGS_Float)0, -sphi, cphi); + }; + + /*! \brief Returns a rotation around the y-axis by the angle \f$\phi\f$ + with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. + */ + static EGS_RotationMatrix rotY(EGS_Float cphi,EGS_Float sphi) { + return EGS_RotationMatrix(cphi, (EGS_Float)0, sphi, + (EGS_Float)0, (EGS_Float)1, (EGS_Float)0, + -sphi, (EGS_Float)0, cphi); + }; + + /*! \brief Returns a rotation around the z-axis by the angle \f$\phi\f$ + with \a cphi, \a sphi = \f$ \cos(\phi), \sin(\phi)\f$. + */ + static EGS_RotationMatrix rotZ(EGS_Float cphi,EGS_Float sphi) { + return EGS_RotationMatrix(cphi, sphi, (EGS_Float)0, + -sphi, cphi, (EGS_Float)0, + (EGS_Float)0,(EGS_Float)0, (EGS_Float)1); + }; + + //! \brief Returns a rotation around the x-axis by the angle \a phi + static EGS_RotationMatrix rotX(EGS_Float phi) { + return rotX(cos(phi),sin(phi)); + }; + + //! \brief Returns a rotation around the y-axis by the angle \a phi + static EGS_RotationMatrix rotY(EGS_Float phi) { + return rotY(cos(phi),sin(phi)); + }; + + //! \brief Returns a rotation around the z-axis by the angle \a phi + static EGS_RotationMatrix rotZ(EGS_Float phi) { + return rotZ(cos(phi),sin(phi)); + }; + + /*! \brief Returns a rotation by the angle \a phi around the axis + defined by the vector \a v. + */ + static EGS_RotationMatrix rotV(EGS_Float phi, const EGS_Vector &v) { + return rotV(cos(phi),sin(phi),v); + }; + + /*! \overload */ + static EGS_RotationMatrix rotV(EGS_Float cphi, EGS_Float sphi, + const EGS_Vector &v) { + EGS_RotationMatrix m(v); + return (m.inverse())*(rotZ(cphi,sphi))*(m); + }; + + //! \brief Calculates and returns the determinant of the matrix + EGS_Float det() const { + return rxx*ryy*rzz + rxy*ryz*rzx + ryx*rzy*rxz - + rxz*ryy*rzx - rxy*ryx*rzz - rzy*ryz*rxx; + }; + + /*! \brief Multiplies the invoking vector \a v from the right with the + matrix \a m and returns the result. + */ + friend EGS_Vector operator*(const EGS_Vector &v, + const EGS_RotationMatrix &m) { + return EGS_Vector(v.x*m.rxx+v.y*m.ryx+v.z*m.rzx, + v.x*m.rxy+v.y*m.ryy+v.z*m.rzy, + v.x*m.rxz+v.y*m.ryz+v.z*m.rzz); + }; + + /*! \brief Multiplies the invoking vector \a v from the right with the + matrix \a m and assigns the result to the invoking vector. + Returns a reference to the resulting vector. + */ + friend EGS_Vector &operator*=(EGS_Vector &v, const EGS_RotationMatrix &m) { + v = v*m; + return v; + }; + + inline EGS_Float xx() const { + return rxx; + }; + inline EGS_Float xy() const { + return rxy; + }; + inline EGS_Float xz() const { + return rxz; + }; + inline EGS_Float yx() const { + return ryx; + }; + inline EGS_Float yy() const { + return ryy; + }; + inline EGS_Float yz() const { + return ryz; + }; + inline EGS_Float zx() const { + return rzx; + }; + inline EGS_Float zy() const { + return rzy; + }; + inline EGS_Float zz() const { + return rzz; + }; }; @@ -347,188 +401,239 @@ class EGS_EXPORT EGS_AffineTransform { protected: - EGS_RotationMatrix R; - EGS_Vector t; - bool has_t, has_R; + EGS_RotationMatrix R; + EGS_Vector t; + bool has_t, has_R; public: - /*! \brief Constructs a unit affine transformation */ - EGS_AffineTransform() : R(),t(),has_t(false),has_R(false) {}; - - /*! \brief Copy constructor */ - EGS_AffineTransform(const EGS_AffineTransform &tr) : - R(tr.R),t(tr.t),has_t(tr.has_t),has_R(tr.has_R) {}; - - /*! \brief Constructs an affine transformation object from the rotation - \a m and translation \a v. */ - EGS_AffineTransform(const EGS_RotationMatrix &m, const EGS_Vector &v) : - R(m),t(v) { - if( t.length2() > 0 ) has_t = true; else has_t = false; - if( R.isI() ) has_R = false; else has_R = true; - }; - - /*! \brief Constructs an affine transformation object from the rotation - \a m, which has no translation. */ - EGS_AffineTransform(const EGS_RotationMatrix &m) : R(m),t() { - has_t = false; - if( R.isI() ) has_R = false; else has_R = true; - }; - - /*! \brief Constructs an affine transformation object from the translation - \a v, which has no rotation. */ - EGS_AffineTransform(const EGS_Vector &v) : R(),t(v) { - has_R = false; - if( t.length2() > 0 ) has_t = true; else has_t = false; - }; - - /*! \brief Returns the multiplication of the invoking object with \a tr. - - The multiplication of 2 affine transformations \f$T_1=(R_1,\vec{t_1})\f$ - and \f$T_2=(R_2,\vec{t_2})\f$ is defined as the affine transformation - \f$T=(R,\vec{t})\f$ which, when applied on any vecor \f$\vec{x}\f$, - results in the same vector that one would obtain by first transforming - it with \f$T_1\f$ and then with \f$T_2\f$. It is easy to see that - \f$ R = R_2 \cdot R_1\f$ and \f$ t = R_2 \cdot \vec{t}_1 + \vec{t}_2\f$. - */ - EGS_AffineTransform operator*(const EGS_AffineTransform &tr) const { - return EGS_AffineTransform(R*tr.R,R*tr.t+t); - }; - - /*! \brief Returns the affine transformation \f$ (R \cdot m, \vec{t})\f$, - where \f$R\f$ and \f$\vec{t}\f$ are the rotation and translation of the - invoking object.*/ - EGS_AffineTransform operator*(const EGS_RotationMatrix &m) const { - return EGS_AffineTransform(R*m,t); - }; - - /*! \brief Multiplies the invoking object from the right with \a tr. - Returns a reference to the result. - - \sa operator *(EGS_AffineTransform &) - */ - EGS_AffineTransform &operator*=(const EGS_AffineTransform &tr) { - return *this = operator * (tr); - }; - - /*! \brief Multiplies the invoking object from the right with \a m. - Returns a reference to the result. - - \sa operator *(EGS_RotationMatrix &) - */ - EGS_AffineTransform &operator*=(const EGS_RotationMatrix &m) { - return *this = operator * (m); - }; - - EGS_AffineTransform operator+(const EGS_Vector &v) const { - return EGS_AffineTransform(R,t+v); - }; - - EGS_AffineTransform &operator+=(const EGS_Vector &v) { - t += v; return *this; - }; - - /*! \brief Applies the transformation to the vector \a v from the - left and returns the result. - */ - EGS_Vector operator*(const EGS_Vector &v) const { - return (R*v + t); - }; - - /*! \brief Applies the transformation \a tr to the invoking vector from - the right and returns the result. */ - friend EGS_Vector operator*(const EGS_Vector &v, - const EGS_AffineTransform &tr) { - return ((v-tr.t)*tr.R); - }; - - /*! \brief Applies the transformation \a tr to the invoking vector from - the right, assignes the result to \a v and returns a reference to it */ - friend EGS_Vector &operator*=(EGS_Vector &v, + /*! \brief Constructs a unit affine transformation */ + EGS_AffineTransform() : R(),t(),has_t(false),has_R(false) {}; + + /*! \brief Copy constructor */ + EGS_AffineTransform(const EGS_AffineTransform &tr) : + R(tr.R),t(tr.t),has_t(tr.has_t),has_R(tr.has_R) {}; + + /*! \brief Constructs an affine transformation object from the rotation + \a m and translation \a v. */ + EGS_AffineTransform(const EGS_RotationMatrix &m, const EGS_Vector &v) : + R(m),t(v) { + if (t.length2() > 0) { + has_t = true; + } + else { + has_t = false; + } + if (R.isI()) { + has_R = false; + } + else { + has_R = true; + } + }; + + /*! \brief Constructs an affine transformation object from the rotation + \a m, which has no translation. */ + EGS_AffineTransform(const EGS_RotationMatrix &m) : R(m),t() { + has_t = false; + if (R.isI()) { + has_R = false; + } + else { + has_R = true; + } + }; + + /*! \brief Constructs an affine transformation object from the translation + \a v, which has no rotation. */ + EGS_AffineTransform(const EGS_Vector &v) : R(),t(v) { + has_R = false; + if (t.length2() > 0) { + has_t = true; + } + else { + has_t = false; + } + }; + + /*! \brief Returns the multiplication of the invoking object with \a tr. + + The multiplication of 2 affine transformations \f$T_1=(R_1,\vec{t_1})\f$ + and \f$T_2=(R_2,\vec{t_2})\f$ is defined as the affine transformation + \f$T=(R,\vec{t})\f$ which, when applied on any vecor \f$\vec{x}\f$, + results in the same vector that one would obtain by first transforming + it with \f$T_1\f$ and then with \f$T_2\f$. It is easy to see that + \f$ R = R_2 \cdot R_1\f$ and \f$ t = R_2 \cdot \vec{t}_1 + \vec{t}_2\f$. + */ + EGS_AffineTransform operator*(const EGS_AffineTransform &tr) const { + return EGS_AffineTransform(R*tr.R,R*tr.t+t); + }; + + /*! \brief Returns the affine transformation \f$ (R \cdot m, \vec{t})\f$, + where \f$R\f$ and \f$\vec{t}\f$ are the rotation and translation of the + invoking object.*/ + EGS_AffineTransform operator*(const EGS_RotationMatrix &m) const { + return EGS_AffineTransform(R*m,t); + }; + + /*! \brief Multiplies the invoking object from the right with \a tr. + Returns a reference to the result. + + \sa operator *(EGS_AffineTransform &) + */ + EGS_AffineTransform &operator*=(const EGS_AffineTransform &tr) { + return *this = operator * (tr); + }; + + /*! \brief Multiplies the invoking object from the right with \a m. + Returns a reference to the result. + + \sa operator *(EGS_RotationMatrix &) + */ + EGS_AffineTransform &operator*=(const EGS_RotationMatrix &m) { + return *this = operator * (m); + }; + + EGS_AffineTransform operator+(const EGS_Vector &v) const { + return EGS_AffineTransform(R,t+v); + }; + + EGS_AffineTransform &operator+=(const EGS_Vector &v) { + t += v; + return *this; + }; + + /*! \brief Applies the transformation to the vector \a v from the + left and returns the result. + */ + EGS_Vector operator*(const EGS_Vector &v) const { + return (R*v + t); + }; + + /*! \brief Applies the transformation \a tr to the invoking vector from + the right and returns the result. */ + friend EGS_Vector operator*(const EGS_Vector &v, const EGS_AffineTransform &tr) { - v = v*tr; return v; - }; - - /*! \brief Transforms the vector \a v */ - void transform(EGS_Vector &v) const { - if( has_R ) v = R*v; - if( has_t ) v += t; - }; - - /*! \brief Applies the inverse transformation to the vector \a v */ - void inverseTransform(EGS_Vector &v) const { - if( has_t ) v -= t; - if( has_R ) v *= R; - //v -= t; v *= R; - }; - - /*! \brief Returns the inverse affine transformation */ - EGS_AffineTransform inverse() const { - EGS_Vector tmp; tmp -= t*R; - return EGS_AffineTransform(R.inverse(),tmp); - }; - - /*! \brief Applies the rotation to the vector \a v */ - void rotate(EGS_Vector &v) const { if( has_R ) v = R*v; }; - /*! \brief Applies the inverse rotation to the vector \a v */ - void rotateInverse(EGS_Vector &v) const { if( has_R ) v *= R; }; - /*! \brief Applies the translation to the vector \a v */ - void translate(EGS_Vector &v) const { v += t; }; - - /*! \brief Returns the translation vector of the affine transformation - object*/ - const EGS_Vector &getTranslation() const { return t; }; - /*! \brief Returns the rotation matrix of the affine transformation - object*/ - const EGS_RotationMatrix &getRotation() const { return R; }; - - /*! \brief Returns \c true if the object is a unity transformation, - \c false otherwise. */ - bool isI() const { return (!has_R && !has_t); }; - - /*! \brief Returns \c true if the transformation involves a translation, - \c false otherwise. */ - bool hasTranslation() const { return has_t; }; - - /*! \brief Returns \c true if the transformation involves a rotation, - \c false otherwise. */ - bool hasRotation() const { return has_R; }; - -/*! \brief Constructs an affine transformation object from the input - pointed to by \a inp and returns a pointer to it. - -A transformation is defined in the input file using the following set -of keys: -\verbatim -:start transformation: - translation = tx, ty, tz - rotation = 2, 3 or 9 floating point numbers - or - rotation vector = 3 floating point numbers -:stop transformation: -\endverbatim -There are many different ways to define a rotation. The - rotation vector input defines a rotation which, -when applied to the 3D vector defined by the input, transforms it -into a vector along the positive z-axis. For instance, if one wanted -to have a rotation of +45 degrees around the y-axis, one would use --1,0,1 as input to the rotation vector key. -The input to the \c rotation key is interpreted as follows: -- If followed by two floating point numbers, this input defines a rotation - by the polar angle \f$\theta\f$ defined by the second input and the - azimuthal angle \f$\phi\f$ - defined by the first input with both angles considered to be in radian - (\em i.e. a rotation by \f$\theta\f$ around the x-axis followed by a rotation - by \f$\phi\f$ around the z-axis) -- If followed by three floating point numbers, this input defines a rotation - that is the combination of a rotation by the third input in radian around - the z-axis, followed by a rotation by the second input around the y-axis, - followed by a rotation by the first input around the x-axis. -- If followed by 9 floating point numbers, the 9 numbers are considered - as the 9 elements of a 3x3 rotation matrix in the order \f$R_{xx}, R_{xy}, - R_{xz}, R_{yx}, R_{yy}, R_{yz}, R_{zx} R_{zy}, R_{zz}\f$. -*/ - static EGS_AffineTransform* getTransformation(EGS_Input *inp); + return ((v-tr.t)*tr.R); + }; + + /*! \brief Applies the transformation \a tr to the invoking vector from + the right, assignes the result to \a v and returns a reference to it */ + friend EGS_Vector &operator*=(EGS_Vector &v, + const EGS_AffineTransform &tr) { + v = v*tr; + return v; + }; + + /*! \brief Transforms the vector \a v */ + void transform(EGS_Vector &v) const { + if (has_R) { + v = R*v; + } + if (has_t) { + v += t; + } + }; + + /*! \brief Applies the inverse transformation to the vector \a v */ + void inverseTransform(EGS_Vector &v) const { + if (has_t) { + v -= t; + } + if (has_R) { + v *= R; + } + //v -= t; v *= R; + }; + + /*! \brief Returns the inverse affine transformation */ + EGS_AffineTransform inverse() const { + EGS_Vector tmp; + tmp -= t*R; + return EGS_AffineTransform(R.inverse(),tmp); + }; + + /*! \brief Applies the rotation to the vector \a v */ + void rotate(EGS_Vector &v) const { + if (has_R) { + v = R*v; + } + }; + /*! \brief Applies the inverse rotation to the vector \a v */ + void rotateInverse(EGS_Vector &v) const { + if (has_R) { + v *= R; + } + }; + /*! \brief Applies the translation to the vector \a v */ + void translate(EGS_Vector &v) const { + v += t; + }; + + /*! \brief Returns the translation vector of the affine transformation + object*/ + const EGS_Vector &getTranslation() const { + return t; + }; + /*! \brief Returns the rotation matrix of the affine transformation + object*/ + const EGS_RotationMatrix &getRotation() const { + return R; + }; + + /*! \brief Returns \c true if the object is a unity transformation, + \c false otherwise. */ + bool isI() const { + return (!has_R && !has_t); + }; + + /*! \brief Returns \c true if the transformation involves a translation, + \c false otherwise. */ + bool hasTranslation() const { + return has_t; + }; + + /*! \brief Returns \c true if the transformation involves a rotation, + \c false otherwise. */ + bool hasRotation() const { + return has_R; + }; + + /*! \brief Constructs an affine transformation object from the input + pointed to by \a inp and returns a pointer to it. + + A transformation is defined in the input file using the following set + of keys: + \verbatim + :start transformation: + translation = tx, ty, tz + rotation = 2, 3 or 9 floating point numbers + or + rotation vector = 3 floating point numbers + :stop transformation: + \endverbatim + There are many different ways to define a rotation. The + rotation vector input defines a rotation which, + when applied to the 3D vector defined by the input, transforms it + into a vector along the positive z-axis. For instance, if one wanted + to have a rotation of +45 degrees around the y-axis, one would use + -1,0,1 as input to the rotation vector key. + The input to the \c rotation key is interpreted as follows: + - If followed by two floating point numbers, this input defines a rotation + by the polar angle \f$\theta\f$ defined by the second input and the + azimuthal angle \f$\phi\f$ + defined by the first input with both angles considered to be in radian + (\em i.e. a rotation by \f$\theta\f$ around the x-axis followed by a rotation + by \f$\phi\f$ around the z-axis) + - If followed by three floating point numbers, this input defines a rotation + that is the combination of a rotation by the third input in radian around + the z-axis, followed by a rotation by the second input around the y-axis, + followed by a rotation by the first input around the x-axis. + - If followed by 9 floating point numbers, the 9 numbers are considered + as the 9 elements of a 3x3 rotation matrix in the order \f$R_{xx}, R_{xy}, + R_{xz}, R_{yx}, R_{yy}, R_{yz}, R_{zx} R_{zy}, R_{zz}\f$. + */ + static EGS_AffineTransform *getTransformation(EGS_Input *inp); }; diff --git a/HEN_HOUSE/egs++/egs_vector.h b/HEN_HOUSE/egs++/egs_vector.h index 9443e4e54..a70d3181c 100644 --- a/HEN_HOUSE/egs++/egs_vector.h +++ b/HEN_HOUSE/egs++/egs_vector.h @@ -56,93 +56,116 @@ class EGS_EXPORT EGS_Vector { public: - EGS_Float x; //!< x-component - EGS_Float y; //!< y-component - EGS_Float z; //!< z-component - - EGS_Vector(EGS_Float xx, EGS_Float yy, EGS_Float zz) : x(xx), y(yy), z(zz) {}; - EGS_Vector(const EGS_Vector &v) : x(v.x), y(v.y), z(v.z) {}; - EGS_Vector() : x(0), y(0), z(0) {}; - - EGS_Vector &operator=(const EGS_Vector &v) { - x = v.x; y = v.y; z = v.z; - return *this; - }; - - // EGS_Vector additions - // - EGS_Vector operator+(const EGS_Vector &v) const { - return EGS_Vector(x+v.x, y+v.y, z+v.z); - }; - EGS_Vector &operator+=(const EGS_Vector &v) { - x += v.x; y += v.y; z += v.z; return *this; - }; - - // EGS_Vector substractions - // - EGS_Vector operator-(const EGS_Vector &v) const { - return EGS_Vector(x-v.x,y-v.y,z-v.z); - } - EGS_Vector &operator-=(const EGS_Vector &v) { - x -= v.x; y -= v.y; z -= v.z; return *this; - }; - - // EGS_Vector multiplications - // - EGS_Vector operator*(const EGS_Float f) const { - return EGS_Vector(x*f,y*f,z*f); - }; - EGS_Vector &operator*=(const EGS_Float f) { - x *= f; y *= f; z *= f; return *this; - }; - friend EGS_Vector operator*(EGS_Float f, EGS_Vector &v) { - return v*f; - }; - EGS_Float operator*(const EGS_Vector &v) const { - return x*v.x + y*v.y + z*v.z; - }; - - // vector product - EGS_Vector times(const EGS_Vector &v) const { - return EGS_Vector(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); - }; - EGS_Vector operator%(const EGS_Vector &v) const { - return EGS_Vector(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); - }; - - // scale - EGS_Vector getScaled(const EGS_Vector &s) const { - return EGS_Vector(x*s.x,y*s.y,z*s.z); - }; - void scale(const EGS_Vector &s) { - x *= s.x; y *= s.y; z *= s.z; - }; - - // Some other useful methods. - EGS_Float length() const { return sqrt(x*x+y*y+z*z); }; - EGS_Float length2() const { return x*x+y*y+z*z; }; - void normalize() { - EGS_Float tmp = 1./length(); x *= tmp; y *= tmp; z *= tmp; - }; - - void rotate(EGS_Float cos_t, EGS_Float sin_t, - EGS_Float c_phi, EGS_Float s_phi) { - EGS_Float sin_z = x*x + y*y; - if( sin_z > 1e-10 ) { - sin_z = sqrt(sin_z); - EGS_Float temp = sin_t/sin_z; - EGS_Float temp_phi = z*c_phi; - EGS_Float temp_x = x*cos_t; register EGS_Float temp_y = y*cos_t; - EGS_Float temp_x1 = temp_phi*x-y*s_phi; - EGS_Float temp_y1 = temp_phi*y+x*s_phi; - x = temp*temp_x1+temp_x; - y = temp*temp_y1+temp_y; - z = z*cos_t-sin_z*sin_t*c_phi; + EGS_Float x; //!< x-component + EGS_Float y; //!< y-component + EGS_Float z; //!< z-component + + EGS_Vector(EGS_Float xx, EGS_Float yy, EGS_Float zz) : x(xx), y(yy), z(zz) {}; + EGS_Vector(const EGS_Vector &v) : x(v.x), y(v.y), z(v.z) {}; + EGS_Vector() : x(0), y(0), z(0) {}; + + EGS_Vector &operator=(const EGS_Vector &v) { + x = v.x; + y = v.y; + z = v.z; + return *this; + }; + + // EGS_Vector additions + // + EGS_Vector operator+(const EGS_Vector &v) const { + return EGS_Vector(x+v.x, y+v.y, z+v.z); + }; + EGS_Vector &operator+=(const EGS_Vector &v) { + x += v.x; + y += v.y; + z += v.z; + return *this; + }; + + // EGS_Vector substractions + // + EGS_Vector operator-(const EGS_Vector &v) const { + return EGS_Vector(x-v.x,y-v.y,z-v.z); } - else { - x = sin_t*c_phi; y = sin_t*s_phi; z *= cos_t; - } - }; + EGS_Vector &operator-=(const EGS_Vector &v) { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + }; + + // EGS_Vector multiplications + // + EGS_Vector operator*(const EGS_Float f) const { + return EGS_Vector(x*f,y*f,z*f); + }; + EGS_Vector &operator*=(const EGS_Float f) { + x *= f; + y *= f; + z *= f; + return *this; + }; + friend EGS_Vector operator*(EGS_Float f, EGS_Vector &v) { + return v*f; + }; + EGS_Float operator*(const EGS_Vector &v) const { + return x*v.x + y*v.y + z*v.z; + }; + + // vector product + EGS_Vector times(const EGS_Vector &v) const { + return EGS_Vector(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); + }; + EGS_Vector operator%(const EGS_Vector &v) const { + return EGS_Vector(y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); + }; + + // scale + EGS_Vector getScaled(const EGS_Vector &s) const { + return EGS_Vector(x*s.x,y*s.y,z*s.z); + }; + void scale(const EGS_Vector &s) { + x *= s.x; + y *= s.y; + z *= s.z; + }; + + // Some other useful methods. + EGS_Float length() const { + return sqrt(x*x+y*y+z*z); + }; + EGS_Float length2() const { + return x*x+y*y+z*z; + }; + void normalize() { + EGS_Float tmp = 1./length(); + x *= tmp; + y *= tmp; + z *= tmp; + }; + + void rotate(EGS_Float cos_t, EGS_Float sin_t, + EGS_Float c_phi, EGS_Float s_phi) { + EGS_Float sin_z = x*x + y*y; + if (sin_z > 1e-10) { + sin_z = sqrt(sin_z); + EGS_Float temp = sin_t/sin_z; + EGS_Float temp_phi = z*c_phi; + EGS_Float temp_x = x*cos_t; + register EGS_Float temp_y = y*cos_t; + EGS_Float temp_x1 = temp_phi*x-y*s_phi; + EGS_Float temp_y1 = temp_phi*y+x*s_phi; + x = temp*temp_x1+temp_x; + y = temp*temp_y1+temp_y; + z = z*cos_t-sin_z*sin_t*c_phi; + } + else { + x = sin_t*c_phi; + y = sin_t*s_phi; + z *= cos_t; + } + }; }; diff --git a/HEN_HOUSE/egs++/egspp.cpp b/HEN_HOUSE/egs++/egspp.cpp index 165368621..0f28b7485 100644 --- a/HEN_HOUSE/egs++/egspp.cpp +++ b/HEN_HOUSE/egs++/egspp.cpp @@ -43,12 +43,12 @@ using namespace std; #ifdef WIN32 -const char fs = 92; + const char fs = 92; #else -const char fs = '/'; + const char fs = '/'; #endif -typedef EGS_Application* (*createAppFunction)(int argc, char **argv); +typedef EGS_Application *(*createAppFunction)(int argc, char **argv); /*! \brief A main program for egspp applications. @@ -58,30 +58,39 @@ typedef EGS_Application* (*createAppFunction)(int argc, char **argv); int main(int argc, char **argv) { string app_name; - if( !EGS_Application::getArgument(argc,argv,"-a","--application",app_name) ) + if (!EGS_Application::getArgument(argc,argv,"-a","--application",app_name)) egsFatal("\nUsage: %s -a application -p pegs_file [-i input_file] [-o output_file] " - "[-b] [-P number_of_parallel_jobs] [-j job_index]\n\n",argv[0]); + "[-b] [-P number_of_parallel_jobs] [-j job_index]\n\n",argv[0]); string lib_dir; EGS_Application::checkEnvironmentVar(argc,argv,"-e","--egs-home","EGS_HOME",lib_dir); - lib_dir += "bin"; lib_dir += fs; lib_dir += CONFIG_NAME; lib_dir += fs; + lib_dir += "bin"; + lib_dir += fs; + lib_dir += CONFIG_NAME; + lib_dir += fs; EGS_Library egs_lib(app_name.c_str(),lib_dir.c_str()); - if( !egs_lib.load() ) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", - argv[0],app_name.c_str(),lib_dir.c_str()); + if (!egs_lib.load()) egsFatal("\n%s: Failed to load the %s application library from %s\n\n", + argv[0],app_name.c_str(),lib_dir.c_str()); createAppFunction createApp = (createAppFunction) egs_lib.resolve("createApplication"); - if( !createApp ) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" - " in the application library %s\n\n",argv[0],egs_lib.libraryFile()); + if (!createApp) egsFatal("\n%s: Failed to resolve the address of the 'createApplication' function" + " in the application library %s\n\n",argv[0],egs_lib.libraryFile()); EGS_Application *app = createApp(argc,argv); - if( !app ) egsFatal("\n%s: Failed to construct the application %s\n\n",argv[0],app_name.c_str()); + if (!app) { + egsFatal("\n%s: Failed to construct the application %s\n\n",argv[0],app_name.c_str()); + } int err = app->initSimulation(); - if( err ) return err; + if (err) { + return err; + } err = app->runSimulation(); - if( err < 0 ) return err; + if (err < 0) { + return err; + } err = app->finishSimulation(); delete app; diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp index 832d0cecf..4086b8a54 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.cpp @@ -49,31 +49,44 @@ static char EGS_BOX_LOCAL ebox_message1[] = "createGeometry(box): %s\n"; static char EGS_BOX_LOCAL ebox_message2[] = "null input?"; static char EGS_BOX_LOCAL ebox_message3[] = "wrong/missing 'box size' input?"; static char EGS_BOX_LOCAL ebox_message4[] = - "expecting 1 or 3 float inputs for 'box size'"; + "expecting 1 or 3 float inputs for 'box size'"; static char EGS_BOX_LOCAL ebox_key1[] = "box size"; extern "C" { -EGS_BOX_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { egsWarning(ebox_message1,ebox_message2); return 0; } - vector s; - int err = input->getInput(ebox_key1,s); - if( err ) { - egsWarning(ebox_message1,ebox_message3); return 0; + EGS_BOX_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning(ebox_message1,ebox_message2); + return 0; + } + vector s; + int err = input->getInput(ebox_key1,s); + if (err) { + egsWarning(ebox_message1,ebox_message3); + return 0; + } + EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); + EGS_Box *result; + if (s.size() == 1) { + result = new EGS_Box(s[0],t); + } + else if (s.size() == 3) { + result = new EGS_Box(s[0],s[1],s[2],t); + } + else { + egsWarning(ebox_message1,ebox_message4); + if (t) { + delete t; + } + return 0; + } + if (t) { + delete t; + } + result->setName(input); + result->setMedia(input); + result->setLabels(input); + return result; } - EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); - EGS_Box *result; - if( s.size() == 1 ) result = new EGS_Box(s[0],t); - else if( s.size() == 3 ) result = new EGS_Box(s[0],s[1],s[2],t); - else { - egsWarning(ebox_message1,ebox_message4); - if( t ) delete t; return 0; - } - if( t ) delete t; - result->setName(input); - result->setMedia(input); - result->setLabels(input); - return result; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h index 6c832a780..59d044956 100644 --- a/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h +++ b/HEN_HOUSE/egs++/geometry/egs_box/egs_box.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_BOX_DLL -#define EGS_BOX_EXPORT __declspec(dllexport) -#else -#define EGS_BOX_EXPORT __declspec(dllimport) -#endif -#define EGS_BOX_LOCAL + #ifdef BUILD_BOX_DLL + #define EGS_BOX_EXPORT __declspec(dllexport) + #else + #define EGS_BOX_EXPORT __declspec(dllimport) + #endif + #define EGS_BOX_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_BOX_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_BOX_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_BOX_EXPORT -#define EGS_BOX_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_BOX_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_BOX_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_BOX_EXPORT + #define EGS_BOX_LOCAL + #endif #endif @@ -95,135 +95,228 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { EGS_Box(EGS_Float a, const EGS_AffineTransform *t = 0, const string &Name = "") : EGS_BaseGeometry(Name), - ax(a), ay(a), az(a), T(0) { - if( t ) T = new EGS_AffineTransform(*t); + ax(a), ay(a), az(a), T(0) { + if (t) { + T = new EGS_AffineTransform(*t); + } nreg = 1; }; EGS_Box(EGS_Float Ax, EGS_Float Ay, EGS_Float Az, const EGS_AffineTransform *t = 0, const string &Name = "") : EGS_BaseGeometry(Name), - ax(Ax), ay(Ay), az(Az), T(0) { - if( t ) T = new EGS_AffineTransform(*t); + ax(Ax), ay(Ay), az(Az), T(0) { + if (t) { + T = new EGS_AffineTransform(*t); + } nreg = 1; }; - ~EGS_Box() { if( T ) delete T; }; + ~EGS_Box() { + if (T) { + delete T; + } + }; bool isInside(const EGS_Vector &x) { EGS_Vector xp = T ? x*(*T) : x; - if( 2*xp.x + ax < 0 || 2*xp.x - ax > 0 ) return false; - if( 2*xp.y + ay < 0 || 2*xp.y - ay > 0 ) return false; - if( 2*xp.z + az < 0 || 2*xp.z - az > 0 ) return false; + if (2*xp.x + ax < 0 || 2*xp.x - ax > 0) { + return false; + } + if (2*xp.y + ay < 0 || 2*xp.y - ay > 0) { + return false; + } + if (2*xp.z + az < 0 || 2*xp.z - az > 0) { + return false; + } return true; }; - int isWhere(const EGS_Vector &x) { return isInside(x) ? 0 : -1; }; + int isWhere(const EGS_Vector &x) { + return isInside(x) ? 0 : -1; + }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { + const EGS_Vector &u) { EGS_Float t = 1e30; - howfar(ireg,x,u,t); return t; + howfar(ireg,x,u,t); + return t; }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { EGS_Vector xp(x), up(u); - if( T ) { xp = x*(*T); up = u*T->getRotation(); } - if( ireg == 0 ) { - EGS_Float t1 = 1e30; int inew = 0; EGS_Vector n; - if( up.x > 0 ) { t1 = (ax - 2*xp.x)/(2*up.x); n.x = -1; } - else if( up.x < 0 ) { t1 = -(ax + 2*xp.x)/(2*up.x); n.x = 1; } - if( t1 < t ) { t = t1; inew = -1; } + if (T) { + xp = x*(*T); + up = u*T->getRotation(); + } + if (ireg == 0) { + EGS_Float t1 = 1e30; + int inew = 0; + EGS_Vector n; + if (up.x > 0) { + t1 = (ax - 2*xp.x)/(2*up.x); + n.x = -1; + } + else if (up.x < 0) { + t1 = -(ax + 2*xp.x)/(2*up.x); + n.x = 1; + } + if (t1 < t) { + t = t1; + inew = -1; + } t1 = 1e30; - if( up.y > 0 ) t1 = (ay - 2*xp.y)/(2*up.y); - else if( up.y < 0 ) t1 = -(ay + 2*xp.y)/(2*up.y); - if( t1 < t ) { - n.x = 0; n.y = up.y > 0 ? -1 : 1; - t = t1; inew = -1; + if (up.y > 0) { + t1 = (ay - 2*xp.y)/(2*up.y); + } + else if (up.y < 0) { + t1 = -(ay + 2*xp.y)/(2*up.y); + } + if (t1 < t) { + n.x = 0; + n.y = up.y > 0 ? -1 : 1; + t = t1; + inew = -1; } t1 = 1e30; - if( up.z > 0 ) t1 = (az - 2*xp.z)/(2*up.z); - else if( up.z < 0 ) t1 = -(az + 2*xp.z)/(2*up.z); - if( t1 < t ) { - t = t1; inew = -1; - n.x = n.y = 0; n.z = up.z > 0 ? -1 : 1; + if (up.z > 0) { + t1 = (az - 2*xp.z)/(2*up.z); } - if( inew < 0 ) { - if( newmed ) *newmed = -1; - if( normal ) { - if( T ) *normal = T->getRotation()*n; - else *normal = n; + else if (up.z < 0) { + t1 = -(az + 2*xp.z)/(2*up.z); + } + if (t1 < t) { + t = t1; + inew = -1; + n.x = n.y = 0; + n.z = up.z > 0 ? -1 : 1; + } + if (inew < 0) { + if (newmed) { + *newmed = -1; + } + if (normal) { + if (T) { + *normal = T->getRotation()*n; + } + else { + *normal = n; + } } } return inew; } EGS_Float t1 = 1e30; - if( 2*xp.x + ax < 0 && up.x > 0 ) t1 = -(2*xp.x + ax)/(2*up.x); - else if( 2*xp.x - ax > 0 && up.x < 0 ) t1 = -(2*xp.x - ax)/(2*up.x); - if( t1 < t ) { + if (2*xp.x + ax < 0 && up.x > 0) { + t1 = -(2*xp.x + ax)/(2*up.x); + } + else if (2*xp.x - ax > 0 && up.x < 0) { + t1 = -(2*xp.x - ax)/(2*up.x); + } + if (t1 < t) { EGS_Float y1 = xp.y + up.y*t1, z1 = xp.z + up.z*t1; - if( 2*y1 + ay >= 0 && 2*y1 - ay <= 0 && - 2*z1 + az >= 0 && 2*z1 - az <= 0 ) { + if (2*y1 + ay >= 0 && 2*y1 - ay <= 0 && + 2*z1 + az >= 0 && 2*z1 - az <= 0) { t = t1; - if( newmed ) *newmed = med; - if( normal ) { - if( T ) { + if (newmed) { + *newmed = med; + } + if (normal) { + if (T) { const EGS_RotationMatrix &R = T->getRotation(); - if( up.x > 0 ) *normal = R*EGS_Vector(-1,0,0); - else *normal = R*EGS_Vector(1,0,0); + if (up.x > 0) { + *normal = R*EGS_Vector(-1,0,0); + } + else { + *normal = R*EGS_Vector(1,0,0); + } } else { - if( up.x > 0 ) *normal = EGS_Vector(-1,0,0); - else *normal = EGS_Vector(1,0,0); + if (up.x > 0) { + *normal = EGS_Vector(-1,0,0); + } + else { + *normal = EGS_Vector(1,0,0); + } } } return 0; } } t1 = 1e30; - if( 2*xp.y + ay < 0 && up.y > 0 ) t1 = -(2*xp.y + ay)/(2*up.y); - else if( 2*xp.y - ay > 0 && up.y < 0 ) t1 = -(2*xp.y - ay)/(2*up.y); - if( t1 < t ) { + if (2*xp.y + ay < 0 && up.y > 0) { + t1 = -(2*xp.y + ay)/(2*up.y); + } + else if (2*xp.y - ay > 0 && up.y < 0) { + t1 = -(2*xp.y - ay)/(2*up.y); + } + if (t1 < t) { EGS_Float x1 = xp.x + up.x*t1, z1 = xp.z + up.z*t1; - if( 2*x1 + ax >= 0 && 2*x1 - ax <= 0 && - 2*z1 + az >= 0 && 2*z1 - az <= 0 ) { + if (2*x1 + ax >= 0 && 2*x1 - ax <= 0 && + 2*z1 + az >= 0 && 2*z1 - az <= 0) { t = t1; - if( newmed ) *newmed = med; - if( normal ) { - if( T ) { + if (newmed) { + *newmed = med; + } + if (normal) { + if (T) { const EGS_RotationMatrix &R = T->getRotation(); - if( up.y > 0 ) *normal = R*EGS_Vector(0,-1,0); - else *normal = R*EGS_Vector(0,1,0); + if (up.y > 0) { + *normal = R*EGS_Vector(0,-1,0); + } + else { + *normal = R*EGS_Vector(0,1,0); + } } else { - if( up.y > 0 ) *normal = EGS_Vector(0,-1,0); - else *normal = EGS_Vector(0,1,0); + if (up.y > 0) { + *normal = EGS_Vector(0,-1,0); + } + else { + *normal = EGS_Vector(0,1,0); + } } } return 0; } } t1 = 1e30; - if( 2*xp.z + az < 0 && up.z > 0 ) t1 = -(2*xp.z + az)/(2*up.z); - else if( 2*xp.z - az > 0 && up.z < 0 ) t1 = -(2*xp.z - az)/(2*up.z); - if( t1 < t ) { + if (2*xp.z + az < 0 && up.z > 0) { + t1 = -(2*xp.z + az)/(2*up.z); + } + else if (2*xp.z - az > 0 && up.z < 0) { + t1 = -(2*xp.z - az)/(2*up.z); + } + if (t1 < t) { EGS_Float x1 = xp.x + up.x*t1, y1 = xp.y + up.y*t1; - if( 2*x1 + ax >= 0 && 2*x1 - ax <= 0 && - 2*y1 + ay >= 0 && 2*y1 - ay <= 0 ) { + if (2*x1 + ax >= 0 && 2*x1 - ax <= 0 && + 2*y1 + ay >= 0 && 2*y1 - ay <= 0) { t = t1; - if( newmed ) *newmed = med; - if( normal ) { - if( T ) { + if (newmed) { + *newmed = med; + } + if (normal) { + if (T) { const EGS_RotationMatrix &R = T->getRotation(); - if( up.z > 0 ) *normal = R*EGS_Vector(0,0,-1); - else *normal = R*EGS_Vector(0,0,1); + if (up.z > 0) { + *normal = R*EGS_Vector(0,0,-1); + } + else { + *normal = R*EGS_Vector(0,0,1); + } } else { - if( up.z > 0 ) *normal = EGS_Vector(0,0,-1); - else *normal = EGS_Vector(0,0,1); + if (up.z > 0) { + *normal = EGS_Vector(0,0,-1); + } + else { + *normal = EGS_Vector(0,0,1); + } } } return 0; @@ -234,40 +327,80 @@ class EGS_BOX_EXPORT EGS_Box : public EGS_BaseGeometry { EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Vector xp = T ? x*(*T) : x; - if( ireg >= 0 ) { + if (ireg >= 0) { EGS_Float tmin; EGS_Float t1 = xp.x + 0.5*ax, t2 = 0.5*ax - xp.x; - if( t1 < t2 ) tmin = t1; else tmin = t2; - t1 = xp.y + 0.5*ay; if( t1 < tmin ) tmin = t1; - t1 = 0.5*ay - xp.y; if( t1 < tmin ) tmin = t1; - t1 = xp.z + 0.5*az; if( t1 < tmin ) tmin = t1; - t1 = 0.5*az - xp.z; if( t1 < tmin ) tmin = t1; + if (t1 < t2) { + tmin = t1; + } + else { + tmin = t2; + } + t1 = xp.y + 0.5*ay; + if (t1 < tmin) { + tmin = t1; + } + t1 = 0.5*ay - xp.y; + if (t1 < tmin) { + tmin = t1; + } + t1 = xp.z + 0.5*az; + if (t1 < tmin) { + tmin = t1; + } + t1 = 0.5*az - xp.z; + if (t1 < tmin) { + tmin = t1; + } return tmin; } - EGS_Float s1=0, s2=0; int nout = 0; - if( 2*xp.x + ax < 0 ) { - EGS_Float t = -0.5*ax - xp.x; s1 += t; s2 += t*t; nout++; + EGS_Float s1=0, s2=0; + int nout = 0; + if (2*xp.x + ax < 0) { + EGS_Float t = -0.5*ax - xp.x; + s1 += t; + s2 += t*t; + nout++; } - else if(2*xp.x - ax > 0) { - EGS_Float t = xp.x - 0.5*ax; s1 += t; s2 += t*t; nout++; + else if (2*xp.x - ax > 0) { + EGS_Float t = xp.x - 0.5*ax; + s1 += t; + s2 += t*t; + nout++; } - if( 2*xp.y + ay < 0 ) { - EGS_Float t = -0.5*ay - xp.y; s1 += t; s2 += t*t; nout++; + if (2*xp.y + ay < 0) { + EGS_Float t = -0.5*ay - xp.y; + s1 += t; + s2 += t*t; + nout++; } - else if(2*xp.y - ay > 0) { - EGS_Float t = xp.y - 0.5*ay; s1 += t; s2 += t*t; nout++; + else if (2*xp.y - ay > 0) { + EGS_Float t = xp.y - 0.5*ay; + s1 += t; + s2 += t*t; + nout++; } - if( 2*xp.z + az < 0 ) { - EGS_Float t = -0.5*az - xp.z; s1 += t; s2 += t*t; nout++; + if (2*xp.z + az < 0) { + EGS_Float t = -0.5*az - xp.z; + s1 += t; + s2 += t*t; + nout++; } - else if(2*xp.z - az > 0) { - EGS_Float t = xp.z - 0.5*az; s1 += t; s2 += t*t; nout++; + else if (2*xp.z - az > 0) { + EGS_Float t = xp.z - 0.5*az; + s1 += t; + s2 += t*t; + nout++; + } + if (nout < 2) { + return s1; } - if( nout < 2 ) return s1; return sqrt(s2); }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; diff --git a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp index 78dd84d6c..e6526c500 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cd_geometry/egs_cd_geometry.cpp @@ -38,214 +38,270 @@ #include "egs_input.h" #ifdef NO_SSTREAM -#include -#define S_STREAM std::istrstream + #include + #define S_STREAM std::istrstream #else -#include -#define S_STREAM std::istringstream + #include + #define S_STREAM std::istringstream #endif string EGS_CDGeometry::type = "EGS_CDGeometry"; void EGS_CDGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_CDGeometry::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_CDGeometry::setRelativeRho(int start, int end, EGS_Float rho) { egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n" - " Use the setRelativeRho() methods of the geometry objects that make" - " up this geometry\n"); + " Use the setRelativeRho() methods of the geometry objects that make" + " up this geometry\n"); } void EGS_CDGeometry::setRelativeRho(EGS_Input *) { egsWarning("EGS_CDGeometry::setRelativeRho(): don't use this method\n" - " Use the setRelativeRho() methods of the geometry objects that make" - " up this geometry\n"); + " Use the setRelativeRho() methods of the geometry objects that make" + " up this geometry\n"); } void EGS_CDGeometry::setUpIndexing() { - int nr = 0; int j; - for(j=0; jregions(); - else ++nr; + int nr = 0; + int j; + for (j=0; jregions(); + } + else { + ++nr; + } } reg_to_base = new int [nr]; local_start = new int [nbase]; int ir=0; - for(j=0; jregions(); - for(int i=0; itakeInputItem("geometry",false)) != 0 ) { - EGS_BaseGeometry::createSingleGeometry(ij); - delete ij; - } - string bg_name; - int err = input->getInput("base geometry",bg_name); - if( err ) { - egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n"); - return 0; - } - EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(bg_name); - if( !g ) { - egsWarning("createGeometry(CD_Geometry): no geometry named %s is" - " defined\n",bg_name.c_str()); - return 0; - } - int nreg = g->regions(); - if( nreg < 1 ) { - egsWarning("createGeometry(CD_Geometry): the base geometry has %d" - " regions?\n",nreg); return 0; - } - EGS_BaseGeometry **G = new EGS_BaseGeometry* [nreg]; int j; - for(j=0; jtakeInputItem("set geometry")) != 0 ) { - vector aux; ij->getInput("set geometry",aux); - int istart, iend; string name; - bool is_ok = true; - if( aux.size() == 2 ) { - string auxx = aux[0]; auxx += ' '; auxx += aux[1]; auxx += ' '; - S_STREAM in(auxx.c_str()); - in >> istart >> name; - if( in.fail() || !in.good() ) { - egsWarning("createGeometry(CD_Geometry): parse error in\n" - " set geometry = %s\n",auxx.c_str()); - err++; is_ok = false; - } else { - if( istart < 0 || istart > nreg-1 ) { - istart = -1; iend = -2; - } else { iend = istart+1; } - } + EGS_CDGEOMETRY_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning("createGeometry(CD_Geometry): null input?\n"); + return 0; } - else if( aux.size() == 3 ) { - string auxx = aux[0]; auxx += ' '; auxx += aux[1]; auxx += ' '; - auxx += aux[2]; auxx += ' '; - S_STREAM in(auxx.c_str()); - in >> istart >> iend >> name; - if( in.fail() || !in.good() ) { - egsWarning("createGeometry(CD_Geometry): parse error in\n" - " set geometry = %s\n",auxx.c_str()); - err++; is_ok = false; - } else { - if( istart < 0 ) istart = 0; - if( iend > nreg ) iend = nreg; - } + EGS_Input *ij; + while ((ij = input->takeInputItem("geometry",false)) != 0) { + EGS_BaseGeometry::createSingleGeometry(ij); + delete ij; } - else { - err++; is_ok = false; + string bg_name; + int err = input->getInput("base geometry",bg_name); + if (err) { + egsWarning("createGeometry(CD_Geometry): no 'base geometry' input\n"); + return 0; + } + EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(bg_name); + if (!g) { + egsWarning("createGeometry(CD_Geometry): no geometry named %s is" + " defined\n",bg_name.c_str()); + return 0; } - if( is_ok ) { - EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(name); - if( !gj ) { - egsWarning("createGeometry(CD_Geometry): no geometry named %s" - " is defined\n",name.c_str()); err++; + int nreg = g->regions(); + if (nreg < 1) { + egsWarning("createGeometry(CD_Geometry): the base geometry has %d" + " regions?\n",nreg); + return 0; + } + EGS_BaseGeometry **G = new EGS_BaseGeometry* [nreg]; + int j; + for (j=0; jtakeInputItem("set geometry")) != 0) { + vector aux; + ij->getInput("set geometry",aux); + int istart, iend; + string name; + bool is_ok = true; + if (aux.size() == 2) { + string auxx = aux[0]; + auxx += ' '; + auxx += aux[1]; + auxx += ' '; + S_STREAM in(auxx.c_str()); + in >> istart >> name; + if (in.fail() || !in.good()) { + egsWarning("createGeometry(CD_Geometry): parse error in\n" + " set geometry = %s\n",auxx.c_str()); + err++; + is_ok = false; + } + else { + if (istart < 0 || istart > nreg-1) { + istart = -1; + iend = -2; + } + else { + iend = istart+1; + } + } + } + else if (aux.size() == 3) { + string auxx = aux[0]; + auxx += ' '; + auxx += aux[1]; + auxx += ' '; + auxx += aux[2]; + auxx += ' '; + S_STREAM in(auxx.c_str()); + in >> istart >> iend >> name; + if (in.fail() || !in.good()) { + egsWarning("createGeometry(CD_Geometry): parse error in\n" + " set geometry = %s\n",auxx.c_str()); + err++; + is_ok = false; + } + else { + if (istart < 0) { + istart = 0; + } + if (iend > nreg) { + iend = nreg; + } + } } else { - for(int j=istart; jderef(); - /* - if( !G[j] ) gj->ref(); - else { - if( G[j] != gj ) G[j]->deref(); + err++; + is_ok = false; + } + if (is_ok) { + EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(name); + if (!gj) { + egsWarning("createGeometry(CD_Geometry): no geometry named %s" + " is defined\n",name.c_str()); + err++; + } + else { + for (int j=istart; jderef(); + } + /* + if( !G[j] ) gj->ref(); + else { + if( G[j] != gj ) G[j]->deref(); + } + */ + G[j] = gj; + gj->ref(); + ng++; } - */ - G[j] = gj; gj->ref(); ng++; } } + delete ij; } - delete ij; - } - if( err ) { - egsWarning("createGeometry(CD_Geometry): %d errors\n",err); - for(j=0; jderef() ) delete G[j]; } + if (err) { + egsWarning("createGeometry(CD_Geometry): %d errors\n",err); + for (j=0; jderef()) { + delete G[j]; + } + } + } + delete [] G[j]; + return 0; } - delete [] G[j]; return 0; - } - if( !ng ) - egsWarning("createGeometry(CD_Geometry): no geometries in addition to" - " the base geometry defined?\n" - " Hope you know what you are doing\n"); - g->ref(); - int indexing = 0; - input->getInput("new indexing style",indexing); - EGS_BaseGeometry *result = new EGS_CDGeometry(g,G,"",indexing); - delete [] G; - result->setName(input); - result->setLabels(input); - return result; + if (!ng) + egsWarning("createGeometry(CD_Geometry): no geometries in addition to" + " the base geometry defined?\n" + " Hope you know what you are doing\n"); + g->ref(); + int indexing = 0; + input->getInput("new indexing style",indexing); + EGS_BaseGeometry *result = new EGS_CDGeometry(g,G,"",indexing); + delete [] G; + result->setName(input); + result->setLabels(input); + return result; -} + } -void EGS_CDGeometry::getLabelRegions (const string &str, vector ®s) { + void EGS_CDGeometry::getLabelRegions(const string &str, vector ®s) { - // label defined in the base geometry - vector bgregs; - bg->getLabelRegions(str, bgregs); + // label defined in the base geometry + vector bgregs; + bg->getLabelRegions(str, bgregs); - // expand base regions to global region lists - int rstart = 0; - int rend = 0; - for (int i=0; i gregs; - int shift=0; - for (int i=0; i gregs; + int shift=0; + for (int i=0; igetLabelRegions(str, gregs); + // add regions from set geometries + gregs.clear(); + if (g[i]) { + g[i]->getLabelRegions(str, gregs); + } - // shift region numbers according to indexing style - if (new_indexing) shift = local_start[i]; - else shift = i*nmax; - for (int j=0; jregions(); - g = new EGS_BaseGeometry* [nbase]; - bg = G1; //bg->ref(); - for(int j=0; jref(); - int n = g[j]->regions(); if( n > nmax ) nmax = n; - } - } - if( !nmax ) nmax = 1; - nreg = nbase*nmax; is_convex = false; - if( indexing ) setUpIndexing(); - setHasRhoScaling(); - }; - - EGS_CDGeometry(EGS_BaseGeometry *G1, const vector &G, - const string &Name = "",int indexing=0) : EGS_BaseGeometry(Name) { - if( !G1 ) egsFatal("EGS_CDGeometry: got a null pointer to the" - " base geometry?\n"); - nbase = G1->regions(); new_indexing = false; - reg_to_base = 0; local_start = 0; - if( nbase != G.size() ) egsFatal("EGS_CDGeometry: number of passed" - " geometries (%d) is not the same as the number of regions (%d)\n", - nbase,G.size()); - nmax = 0; g = new EGS_BaseGeometry* [nbase]; bg = G1; //bg->ref(); - for(int j=0; jref(); - int n = g[j]->regions(); if( n > nmax ) nmax = n; - } - } - if( !nmax ) nmax = 1; - nreg = nbase*nmax; is_convex = false; - if( indexing ) setUpIndexing(); - setHasRhoScaling(); - }; - - - ~EGS_CDGeometry() { - for(int j=0; jderef() ) delete g[j]; - } - } - delete [] g; - if( !bg->deref() ) delete bg; - if( new_indexing ) { - if( reg_to_base ) delete [] reg_to_base; - if( local_start ) delete [] local_start; - } - }; - - int medium(int ireg) const { - /* - int ibase = ireg/nmax; - if( g[ibase] ) return g[ibase]->medium(ireg-ibase*nmax); - return bg->medium(ibase); - */ - int ibase, ilocal; - if( new_indexing ) { - ibase = reg_to_base[ireg]; ilocal = ireg - local_start[ibase]; - } - else { - ibase = ireg/nmax; ilocal = ireg-ibase*nmax; - } - return g[ibase] ? g[ibase]->medium(ilocal) : bg->medium(ibase); - }; - - bool isRealRegion(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return false; - int ibase, icd; - if( new_indexing ) { - ibase = reg_to_base[ireg]; icd = ireg-local_start[ibase]; - } - else { ibase = ireg/nmax; icd = ireg - ibase*nmax; } - return g[ibase] ? g[ibase]->isRealRegion(icd) : - bg->isRealRegion(ibase); - }; - - bool isInside(const EGS_Vector &x) { - int ibase = bg->isWhere(x); - if( ibase < 0 ) return false; - if( g[ibase] ) return g[ibase]->isInside(x); - return true; - }; - - int isWhere(const EGS_Vector &x) { - int ibase = bg->isWhere(x); - if( ibase < 0 ) return ibase; - int ir = 0; - if( g[ibase] ) { - ir = g[ibase]->isWhere(x); - if( ir < 0 ) return ir; - } - return new_indexing ? local_start[ibase] + ir : ibase*nmax + ir; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { - if( ireg >= 0 ) { - // - // *** We are inside and ibase is the current base geometry - // region and icd the local region of the geometry inscribed - // in ibase (if any) - int ibase, icd; - if( new_indexing ) { - ibase = reg_to_base[ireg]; icd = ireg-local_start[ibase]; - } - else { ibase = ireg/nmax; icd = ireg - ibase*nmax; } - // - // *** See if we will hit a boundary in the base geometry. - // If we do, newmed and normal will get set accordingly. - // - int ibase_new = bg->howfar(ibase,x,u,t,newmed,normal); - if( g[ibase] ) { - // - // *** There is another geometry in this base geometry region. - // See if will hit one of its boundaries first. - // - int icd_new = g[ibase]->howfar(icd,x,u,t,newmed,normal); - if( icd_new < 0 ) return icd_new; - // above: yes we do but the new region is outside - // => we exit the entire geometry. newmed and normal - // must have been set accordingly. - if( icd_new != icd ) - return new_indexing ? local_start[ibase] + icd_new : - ibase*nmax + icd_new; - // above: yes we do and we enter the local region icd_new - // => calculate the new region and return - // newmed and normal must have been set in g[ibase]->howfar - } - if( ibase_new != ibase ) { - // we have entered a new base geometry region. - if( ibase_new < 0 ) return ibase_new; - // but this region is outside => just return. - if( g[ibase_new] ) { - // there is a geometry in this new base geometry region. - // are we already inside? - EGS_Vector tmp(x + u*t); - int icd_new = g[ibase_new]->isWhere(tmp); - if( icd_new < 0 ) return icd_new; - // above: no, we are not => we exit the entire geometry. - // below: yes, we are in local region icd_new - // simply calculate the new global region and return - // newmed and normal have been set in bg->howfar above - if( newmed ) *newmed = g[ibase_new]->medium(icd_new); - return new_indexing ? local_start[ibase_new] + icd_new : - ibase_new*nmax + icd_new; - } - // there is no cd geometry in this base geometry region - // => simply calculate the new global region and return - // newmed and normal have been set in bg->howfar above - return new_indexing ? local_start[ibase_new] : ibase_new*nmax; - } - // new region is the same as old region (i.e. we don't reach - // a boundary => simply return the old region. - return ireg; - } - - // - // *** If here, we are outside. - // Are we already inside the base geometry ? - // - int ibase = bg->isWhere(x); - EGS_Float tb=0, ttot=0; - bool first_time = true;// first time checking base geometry? - EGS_Vector n; int mednew; - EGS_Vector *pn = normal ? &n : 0; - int *pmednew = newmed ? &mednew : 0; - if( ibase >= 0 ) { - // - // IK Feb 22 2007: - // The following seems flawed. Yes, if there is no inscribed - // geometry we can assume that ibase>=0 is due to roundoff, - // but if there is, we might as well be about to enter this - // geometry (but isInside() thinks that we are already inside). - // What would be the best way to check? Don't know yet. - // - // already inside the base geometry. - // unfortunately, due to roundoff we may think that - // we are inside the base geometry but we are actually - // outside. To make the logic below work, we need to - // check if we are inside the geometry inscribed in region - // ibase. - int icd = g[ibase] ? g[ibase]->isWhere(x) : 0; - if( icd >= 0 ) { - - // We think we are outside, but isWhere(x) reports that we are - // inside. This can be caused by numerical roundoff. - // There are 2 possibilities: - // a) The particle has just left geometry, but due to roundoff - // we still find it inside for the next step. This possibility - // can be checked by checking the distance to the exit point - // b) The particle is approaching the geometry but due to roundoff - // we already find it inside. This possibility can be checked - // by determining the distance to exit point moving along the - // direction oposite to the particle direction. - //*********************************************************************** - // EMH April 12 2013: Check 0 for (b) below was ambiguosly defined as there - // will be situations where u and -u will not hit the geometry. An univocally - // defined test is to check whether particle actually enters the geometry from - // the boundary or a location near it (round-off). - // REMEMBER: - isWhere will return ir >= 0 when particle seats at a boundary. - // - We are here either due to roundoff or just at the boundary - // - // 0. Proper check for a and b) - int ixold = new_indexing ? local_start[ibase] + icd : - ibase*nmax + icd; - //EGS_Float tb_neg = 1e30; int ixnew_neg = howfar(ixold,x,u*(-1),tb_neg,0,pn); - //EGS_Float tb_pos = 1e30; int ixnew_pos = howfar(ixold,x,u,tb_pos,0,pn); - // Call to CD geometry howfar with updated region ixold. If it is aimed away from - // geometry, it will return ixnew = -1 and assumption a) was correct. If it is - // aimed into geometry, it will return ixnew >=0 and assumption b) was correct. - tb = 1e30; int ixnew = howfar(ixold,x,u,tb,0,pn); - // Enters geometry and at a boundary or very close to one. - //if( ixnew_pos >= 0 && ixnew_neg < 0 && tb_neg <= epsilon && tb_pos <= epsilon) { - if( ixnew >= 0 && tb <= epsilon ) { // (b) is true - t = 0; - if( newmed ) *newmed = g[ibase] ? g[ibase]->medium(icd) : - bg->medium(ibase); - //if( normal ) *normal = (*pn)*(-1); - if( normal ) *normal = *pn; - return ixold; - } - else if( ixnew < 0 && tb <= epsilon ){ // (a) is true - return ixnew; - } - //*********************************************************************** - - // 1. Check if we exit the base geometry after a sufficiently small - // distance. - EGS_Float t1=1e30, t2 = 1e30; int ibase_n, ic_n=0; - ibase_n = bg->howfar(ibase,x,u,t1); - if( ibase_n < 0 && t1 < 1e-4 ) { - // Yes we do => we assume that it was a roundoff problem - // and in reality the particle was outside the base geometry. - // We then check if it will enter the base geometry. - EGS_Vector xtmp(x + u*t1); tb = t-t1; - ibase = bg->howfar(ibase_n,xtmp,u,tb,pmednew,pn); - if( ibase_n < 0 ) return ibase_n; // no, so just return. - // yes, so transport to entry point and follow normal outside logic - tb += t1; ttot = tb; ibase = ibase_n; first_time = false; - goto do_checks; - } - // If here, particle is inside base geometry and also doesn't exit base geometry - // very soon. So, we must do check 2.: - // 2. Check if we exit the inscribed geometry after a sufficiently small - // distance. - if( g[ibase] ) { - ic_n = g[ibase]->howfar(icd,x,u,t2); - if( ic_n < 0 && t2 < 1e-4 ) { - // Yes we do => we assume that it was a roundoff problem - // and in reality the particle was outside the inscribed geometry. - // We move to the boundary and check again the base geometry. - EGS_Vector xtmp(x + u*t2); - ibase = bg->isWhere(xtmp); - if( ibase < 0 ) { - tb = t - t2; - ibase = bg->howfar(ibase,xtmp,u,tb,pmednew,pn); - if( ibase < 0 ) return ibase; - tb += t2; ttot = tb; first_time = false; - } else { tb = t2; ttot = tb; } - goto do_checks; - } - } - if( t1 < 1e-4 && ibase_n >= 0 && g[ibase_n] ) { - // last resort. - EGS_Vector xtmp(x + u*t1); - int icdx = g[ibase_n]->isWhere(xtmp); - if( icdx < 0 ) { - tb = t1; ttot = tb; ibase = ibase_n; first_time = true; - goto do_checks; - } - } - if( t1 > 1e-3 && t2 > 1e-3 ) { - error_flag = 1; - egsWarning("EGS_CDGeometry::howfar: ireg<0, but position appears inside\n"); - egsWarning(" name=%s base name=%s inscribed name=%s\n",name.c_str(), - bg->getName().c_str(),g[ibase] ? g[ibase]->getName().c_str() : "none"); - egsWarning(" x=(%g,%g,%g) u=(%g,%g,%g) ibase=%d icd=%d\n", - x.x,x.y,x.z,u.x,u.y,u.z,ibase,icd); - egsWarning(" distance to boundaries: base=(%d,%g) inscribed=(%d,%g)\n", - ibase_n,t1,ic_n,t2); - } - } - if( icd >= 0 ) return ireg; - tb = 0; ttot = 0; - } // yes, we are. - else { - // no, we are not. Check if we will enter the base geometry. - first_time = false; - tb = t; ibase = bg->howfar(ireg,x,u,tb,pmednew,pn); - if( ibase < 0 ) return ibase; // no, we will not. - ttot = tb; // i.e. we enter the base geometry after a - // path-length of tb (wich is less than t). - // if this happens, newmed and normal are set - // by the bg->howfar call. - } + EGS_CDGeometry(EGS_BaseGeometry *G1, EGS_BaseGeometry **G, + const string &Name = "", int indexing=0) : EGS_BaseGeometry(Name) { + nmax = 0; + new_indexing = false; + reg_to_base = 0; + local_start = 0; + nbase = G1->regions(); + g = new EGS_BaseGeometry* [nbase]; + bg = G1; //bg->ref(); + for (int j=0; jref(); + int n = g[j]->regions(); + if (n > nmax) { + nmax = n; + } + } + } + if (!nmax) { + nmax = 1; + } + nreg = nbase*nmax; + is_convex = false; + if (indexing) { + setUpIndexing(); + } + setHasRhoScaling(); + }; + + EGS_CDGeometry(EGS_BaseGeometry *G1, const vector &G, + const string &Name = "",int indexing=0) : EGS_BaseGeometry(Name) { + if (!G1) egsFatal("EGS_CDGeometry: got a null pointer to the" + " base geometry?\n"); + nbase = G1->regions(); + new_indexing = false; + reg_to_base = 0; + local_start = 0; + if (nbase != G.size()) egsFatal("EGS_CDGeometry: number of passed" + " geometries (%d) is not the same as the number of regions (%d)\n", + nbase,G.size()); + nmax = 0; + g = new EGS_BaseGeometry* [nbase]; + bg = G1; //bg->ref(); + for (int j=0; jref(); + int n = g[j]->regions(); + if (n > nmax) { + nmax = n; + } + } + } + if (!nmax) { + nmax = 1; + } + nreg = nbase*nmax; + is_convex = false; + if (indexing) { + setUpIndexing(); + } + setHasRhoScaling(); + }; + + + ~EGS_CDGeometry() { + for (int j=0; jderef()) { + delete g[j]; + } + } + } + delete [] g; + if (!bg->deref()) { + delete bg; + } + if (new_indexing) { + if (reg_to_base) { + delete [] reg_to_base; + } + if (local_start) { + delete [] local_start; + } + } + }; + + int medium(int ireg) const { + /* + int ibase = ireg/nmax; + if( g[ibase] ) return g[ibase]->medium(ireg-ibase*nmax); + return bg->medium(ibase); + */ + int ibase, ilocal; + if (new_indexing) { + ibase = reg_to_base[ireg]; + ilocal = ireg - local_start[ibase]; + } + else { + ibase = ireg/nmax; + ilocal = ireg-ibase*nmax; + } + return g[ibase] ? g[ibase]->medium(ilocal) : bg->medium(ibase); + }; + + bool isRealRegion(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return false; + } + int ibase, icd; + if (new_indexing) { + ibase = reg_to_base[ireg]; + icd = ireg-local_start[ibase]; + } + else { + ibase = ireg/nmax; + icd = ireg - ibase*nmax; + } + return g[ibase] ? g[ibase]->isRealRegion(icd) : + bg->isRealRegion(ibase); + }; + + bool isInside(const EGS_Vector &x) { + int ibase = bg->isWhere(x); + if (ibase < 0) { + return false; + } + if (g[ibase]) { + return g[ibase]->isInside(x); + } + return true; + }; + + int isWhere(const EGS_Vector &x) { + int ibase = bg->isWhere(x); + if (ibase < 0) { + return ibase; + } + int ir = 0; + if (g[ibase]) { + ir = g[ibase]->isWhere(x); + if (ir < 0) { + return ir; + } + } + return new_indexing ? local_start[ibase] + ir : ibase*nmax + ir; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + if (ireg >= 0) { + // + // *** We are inside and ibase is the current base geometry + // region and icd the local region of the geometry inscribed + // in ibase (if any) + int ibase, icd; + if (new_indexing) { + ibase = reg_to_base[ireg]; + icd = ireg-local_start[ibase]; + } + else { + ibase = ireg/nmax; + icd = ireg - ibase*nmax; + } + // + // *** See if we will hit a boundary in the base geometry. + // If we do, newmed and normal will get set accordingly. + // + int ibase_new = bg->howfar(ibase,x,u,t,newmed,normal); + if (g[ibase]) { + // + // *** There is another geometry in this base geometry region. + // See if will hit one of its boundaries first. + // + int icd_new = g[ibase]->howfar(icd,x,u,t,newmed,normal); + if (icd_new < 0) { + return icd_new; + } + // above: yes we do but the new region is outside + // => we exit the entire geometry. newmed and normal + // must have been set accordingly. + if (icd_new != icd) + return new_indexing ? local_start[ibase] + icd_new : + ibase*nmax + icd_new; + // above: yes we do and we enter the local region icd_new + // => calculate the new region and return + // newmed and normal must have been set in g[ibase]->howfar + } + if (ibase_new != ibase) { + // we have entered a new base geometry region. + if (ibase_new < 0) { + return ibase_new; + } + // but this region is outside => just return. + if (g[ibase_new]) { + // there is a geometry in this new base geometry region. + // are we already inside? + EGS_Vector tmp(x + u*t); + int icd_new = g[ibase_new]->isWhere(tmp); + if (icd_new < 0) { + return icd_new; + } + // above: no, we are not => we exit the entire geometry. + // below: yes, we are in local region icd_new + // simply calculate the new global region and return + // newmed and normal have been set in bg->howfar above + if (newmed) { + *newmed = g[ibase_new]->medium(icd_new); + } + return new_indexing ? local_start[ibase_new] + icd_new : + ibase_new*nmax + icd_new; + } + // there is no cd geometry in this base geometry region + // => simply calculate the new global region and return + // newmed and normal have been set in bg->howfar above + return new_indexing ? local_start[ibase_new] : ibase_new*nmax; + } + // new region is the same as old region (i.e. we don't reach + // a boundary => simply return the old region. + return ireg; + } + + // + // *** If here, we are outside. + // Are we already inside the base geometry ? + // + int ibase = bg->isWhere(x); + EGS_Float tb=0, ttot=0; + bool first_time = true;// first time checking base geometry? + EGS_Vector n; + int mednew; + EGS_Vector *pn = normal ? &n : 0; + int *pmednew = newmed ? &mednew : 0; + if (ibase >= 0) { + // + // IK Feb 22 2007: + // The following seems flawed. Yes, if there is no inscribed + // geometry we can assume that ibase>=0 is due to roundoff, + // but if there is, we might as well be about to enter this + // geometry (but isInside() thinks that we are already inside). + // What would be the best way to check? Don't know yet. + // + // already inside the base geometry. + // unfortunately, due to roundoff we may think that + // we are inside the base geometry but we are actually + // outside. To make the logic below work, we need to + // check if we are inside the geometry inscribed in region + // ibase. + int icd = g[ibase] ? g[ibase]->isWhere(x) : 0; + if (icd >= 0) { + + // We think we are outside, but isWhere(x) reports that we are + // inside. This can be caused by numerical roundoff. + // There are 2 possibilities: + // a) The particle has just left geometry, but due to roundoff + // we still find it inside for the next step. This possibility + // can be checked by checking the distance to the exit point + // b) The particle is approaching the geometry but due to roundoff + // we already find it inside. This possibility can be checked + // by determining the distance to exit point moving along the + // direction oposite to the particle direction. + //*********************************************************************** + // EMH April 12 2013: Check 0 for (b) below was ambiguosly defined as there + // will be situations where u and -u will not hit the geometry. An univocally + // defined test is to check whether particle actually enters the geometry from + // the boundary or a location near it (round-off). + // REMEMBER: - isWhere will return ir >= 0 when particle seats at a boundary. + // - We are here either due to roundoff or just at the boundary + // + // 0. Proper check for a and b) + int ixold = new_indexing ? local_start[ibase] + icd : + ibase*nmax + icd; + //EGS_Float tb_neg = 1e30; int ixnew_neg = howfar(ixold,x,u*(-1),tb_neg,0,pn); + //EGS_Float tb_pos = 1e30; int ixnew_pos = howfar(ixold,x,u,tb_pos,0,pn); + // Call to CD geometry howfar with updated region ixold. If it is aimed away from + // geometry, it will return ixnew = -1 and assumption a) was correct. If it is + // aimed into geometry, it will return ixnew >=0 and assumption b) was correct. + tb = 1e30; + int ixnew = howfar(ixold,x,u,tb,0,pn); + // Enters geometry and at a boundary or very close to one. + //if( ixnew_pos >= 0 && ixnew_neg < 0 && tb_neg <= epsilon && tb_pos <= epsilon) { + if (ixnew >= 0 && tb <= epsilon) { // (b) is true + t = 0; + if (newmed) *newmed = g[ibase] ? g[ibase]->medium(icd) : + bg->medium(ibase); + //if( normal ) *normal = (*pn)*(-1); + if (normal) { + *normal = *pn; + } + return ixold; + } + else if (ixnew < 0 && tb <= epsilon) { // (a) is true + return ixnew; + } + //*********************************************************************** + + // 1. Check if we exit the base geometry after a sufficiently small + // distance. + EGS_Float t1=1e30, t2 = 1e30; + int ibase_n, ic_n=0; + ibase_n = bg->howfar(ibase,x,u,t1); + if (ibase_n < 0 && t1 < 1e-4) { + // Yes we do => we assume that it was a roundoff problem + // and in reality the particle was outside the base geometry. + // We then check if it will enter the base geometry. + EGS_Vector xtmp(x + u*t1); + tb = t-t1; + ibase = bg->howfar(ibase_n,xtmp,u,tb,pmednew,pn); + if (ibase_n < 0) { + return ibase_n; // no, so just return. + } + // yes, so transport to entry point and follow normal outside logic + tb += t1; + ttot = tb; + ibase = ibase_n; + first_time = false; + goto do_checks; + } + // If here, particle is inside base geometry and also doesn't exit base geometry + // very soon. So, we must do check 2.: + // 2. Check if we exit the inscribed geometry after a sufficiently small + // distance. + if (g[ibase]) { + ic_n = g[ibase]->howfar(icd,x,u,t2); + if (ic_n < 0 && t2 < 1e-4) { + // Yes we do => we assume that it was a roundoff problem + // and in reality the particle was outside the inscribed geometry. + // We move to the boundary and check again the base geometry. + EGS_Vector xtmp(x + u*t2); + ibase = bg->isWhere(xtmp); + if (ibase < 0) { + tb = t - t2; + ibase = bg->howfar(ibase,xtmp,u,tb,pmednew,pn); + if (ibase < 0) { + return ibase; + } + tb += t2; + ttot = tb; + first_time = false; + } + else { + tb = t2; + ttot = tb; + } + goto do_checks; + } + } + if (t1 < 1e-4 && ibase_n >= 0 && g[ibase_n]) { + // last resort. + EGS_Vector xtmp(x + u*t1); + int icdx = g[ibase_n]->isWhere(xtmp); + if (icdx < 0) { + tb = t1; + ttot = tb; + ibase = ibase_n; + first_time = true; + goto do_checks; + } + } + if (t1 > 1e-3 && t2 > 1e-3) { + error_flag = 1; + egsWarning("EGS_CDGeometry::howfar: ireg<0, but position appears inside\n"); + egsWarning(" name=%s base name=%s inscribed name=%s\n",name.c_str(), + bg->getName().c_str(),g[ibase] ? g[ibase]->getName().c_str() : "none"); + egsWarning(" x=(%g,%g,%g) u=(%g,%g,%g) ibase=%d icd=%d\n", + x.x,x.y,x.z,u.x,u.y,u.z,ibase,icd); + egsWarning(" distance to boundaries: base=(%d,%g) inscribed=(%d,%g)\n", + ibase_n,t1,ic_n,t2); + } + } + if (icd >= 0) { + return ireg; + } + tb = 0; + ttot = 0; + } // yes, we are. + else { + // no, we are not. Check if we will enter the base geometry. + first_time = false; + tb = t; + ibase = bg->howfar(ireg,x,u,tb,pmednew,pn); + if (ibase < 0) { + return ibase; // no, we will not. + } + ttot = tb; // i.e. we enter the base geometry after a + // path-length of tb (wich is less than t). + // if this happens, newmed and normal are set + // by the bg->howfar call. + } do_checks: - EGS_Vector tmp(x + u*tb); // position at which we are inside - // the base geometry - while(1) { - if( !g[ibase] ) {// no inscribed geometry in this base geometry region - t = ttot; - if( newmed ) *newmed = mednew; - if( normal ) *normal = n; - return new_indexing ? local_start[ibase] : ibase*nmax; - } - // => we have entered. - int icd = -1; - if( !first_time ) {// already howfar-checked base geometry - icd = g[ibase]->isWhere(tmp); - if( icd >= 0 ) { - // already inside of the geometry of this base geometry - // region. - t = ttot; - if( newmed ) *newmed = g[ibase]->medium(icd); - if( normal ) *normal = n; - return new_indexing ? local_start[ibase] + icd : - ibase*nmax + icd; - } - first_time = false; - } - - // see if we will enter a new base geometry region before t - EGS_Float tnew = t - ttot; - int ibase_new = bg->howfar(ibase,tmp,u,tnew,pmednew,pn); - // see if we will enter the cd geometry of this base geometry - // region. - int icd_new = g[ibase]->howfar(-1,tmp,u,tnew,pmednew,pn); - if( icd_new >= 0 ) { - // yes, we will. - t = ttot + tnew; - if( newmed ) *newmed = mednew; - if( normal ) *normal = n; - return new_indexing ? local_start[ibase] + icd_new : - ibase*nmax + icd_new; - } - // if the base region is the same or we have exited the - // base geometry, the particle never enters. - - //if( ibase_new == ibase || ibase_new < 0 ) return -1; - if( ibase_new == ibase ) return -1; - if( ibase_new < 0 ) { - tmp += u*tnew; ttot += tnew; tnew = t - ttot; - ibase_new = bg->howfar(-1,tmp,u,tnew,pmednew,pn); - if( ibase_new < 0 ) return -1; - //tb = tnew; ttot += tnew; first_time = false; - //goto do_checks; - } - // OK, we are in a new base geometry now, adjust - // position and path-length so-far and retry. - if( tnew < 1e-6 ) tnew = 1e-6; - tmp += u*tnew; ttot += tnew; ibase = ibase_new; - first_time = false; - } - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - int ibase, icd; - if( new_indexing ) { - ibase = reg_to_base[ireg]; icd = ireg - local_start[ibase]; - } - else { ibase = ireg/nmax; icd = ireg - ibase*nmax; } - EGS_Float t = bg->hownear(ibase,x); - if( !g[ibase] || t <= 0 ) return t; - EGS_Float t1 = g[ibase]->hownear(icd,x); - return (t1 < t ? t1 : t ); - } - int ibase = bg->isWhere(x); - if( ibase < 0 ) { - EGS_Float tt = bg->hownear(ireg,x); - return tt; - } - EGS_Float t = bg->hownear(ibase,x); - if( g[ibase] ) { - EGS_Float t1 = g[ibase]->hownear(-1,x); - if( t1 < t ) t = t1; - } - return t; - }; - - int getMaxStep() const { - int nstep = 0; - for(int j=0; jregions(); ++j) { - if( g[j] ) nstep += g[j]->getMaxStep(); else ++nstep; - } - return nstep + 1; - } - - bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( ireg >= 0 && ireg < nreg ) { - int ibase = ireg/nmax; - return g[ibase] ? - g[ibase]->hasBooleanProperty(ireg - ibase*nmax,prop) : - bg->hasBooleanProperty(ibase,prop); - } - return false; - }; - void setBooleanProperty(EGS_BPType) { - setPropertError("setBooleanProperty()"); - }; - void addBooleanProperty(int) { - setPropertError("addBooleanProperty()"); - }; - void setBooleanProperty(EGS_BPType,int,int,int step=1) { - setPropertError("setBooleanProperty()"); - }; - void addBooleanProperty(int,int,int,int step=1) { - setPropertError("addBooleanProperty()"); - }; - - const string &getType() const { return type; }; - - void setRelativeRho(int start, int end, EGS_Float rho); - void setRelativeRho(EGS_Input *); - EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nbase*nmax ) return 1; - int ibase = ireg/nmax; - return g[ibase] ? g[ibase]->getRelativeRho(ireg-ibase*nmax) : - bg->getRelativeRho(ibase); - }; - - virtual void getLabelRegions (const string &str, vector ®s); + EGS_Vector tmp(x + u*tb); // position at which we are inside + // the base geometry + while (1) { + if (!g[ibase]) { // no inscribed geometry in this base geometry region + t = ttot; + if (newmed) { + *newmed = mednew; + } + if (normal) { + *normal = n; + } + return new_indexing ? local_start[ibase] : ibase*nmax; + } + // => we have entered. + int icd = -1; + if (!first_time) { // already howfar-checked base geometry + icd = g[ibase]->isWhere(tmp); + if (icd >= 0) { + // already inside of the geometry of this base geometry + // region. + t = ttot; + if (newmed) { + *newmed = g[ibase]->medium(icd); + } + if (normal) { + *normal = n; + } + return new_indexing ? local_start[ibase] + icd : + ibase*nmax + icd; + } + first_time = false; + } + + // see if we will enter a new base geometry region before t + EGS_Float tnew = t - ttot; + int ibase_new = bg->howfar(ibase,tmp,u,tnew,pmednew,pn); + // see if we will enter the cd geometry of this base geometry + // region. + int icd_new = g[ibase]->howfar(-1,tmp,u,tnew,pmednew,pn); + if (icd_new >= 0) { + // yes, we will. + t = ttot + tnew; + if (newmed) { + *newmed = mednew; + } + if (normal) { + *normal = n; + } + return new_indexing ? local_start[ibase] + icd_new : + ibase*nmax + icd_new; + } + // if the base region is the same or we have exited the + // base geometry, the particle never enters. + + //if( ibase_new == ibase || ibase_new < 0 ) return -1; + if (ibase_new == ibase) { + return -1; + } + if (ibase_new < 0) { + tmp += u*tnew; + ttot += tnew; + tnew = t - ttot; + ibase_new = bg->howfar(-1,tmp,u,tnew,pmednew,pn); + if (ibase_new < 0) { + return -1; + } + //tb = tnew; ttot += tnew; first_time = false; + //goto do_checks; + } + // OK, we are in a new base geometry now, adjust + // position and path-length so-far and retry. + if (tnew < 1e-6) { + tnew = 1e-6; + } + tmp += u*tnew; + ttot += tnew; + ibase = ibase_new; + first_time = false; + } + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + int ibase, icd; + if (new_indexing) { + ibase = reg_to_base[ireg]; + icd = ireg - local_start[ibase]; + } + else { + ibase = ireg/nmax; + icd = ireg - ibase*nmax; + } + EGS_Float t = bg->hownear(ibase,x); + if (!g[ibase] || t <= 0) { + return t; + } + EGS_Float t1 = g[ibase]->hownear(icd,x); + return (t1 < t ? t1 : t); + } + int ibase = bg->isWhere(x); + if (ibase < 0) { + EGS_Float tt = bg->hownear(ireg,x); + return tt; + } + EGS_Float t = bg->hownear(ibase,x); + if (g[ibase]) { + EGS_Float t1 = g[ibase]->hownear(-1,x); + if (t1 < t) { + t = t1; + } + } + return t; + }; + + int getMaxStep() const { + int nstep = 0; + for (int j=0; jregions(); ++j) { + if (g[j]) { + nstep += g[j]->getMaxStep(); + } + else { + ++nstep; + } + } + return nstep + 1; + } + + bool hasBooleanProperty(int ireg, EGS_BPType prop) const { + if (ireg >= 0 && ireg < nreg) { + int ibase = ireg/nmax; + return g[ibase] ? + g[ibase]->hasBooleanProperty(ireg - ibase*nmax,prop) : + bg->hasBooleanProperty(ibase,prop); + } + return false; + }; + void setBooleanProperty(EGS_BPType) { + setPropertError("setBooleanProperty()"); + }; + void addBooleanProperty(int) { + setPropertError("addBooleanProperty()"); + }; + void setBooleanProperty(EGS_BPType,int,int,int step=1) { + setPropertError("setBooleanProperty()"); + }; + void addBooleanProperty(int,int,int,int step=1) { + setPropertError("addBooleanProperty()"); + }; + + const string &getType() const { + return type; + }; + + void setRelativeRho(int start, int end, EGS_Float rho); + void setRelativeRho(EGS_Input *); + EGS_Float getRelativeRho(int ireg) const { + if (ireg < 0 || ireg >= nbase*nmax) { + return 1; + } + int ibase = ireg/nmax; + return g[ibase] ? g[ibase]->getRelativeRho(ireg-ibase*nmax) : + bg->getRelativeRho(ibase); + }; + + virtual void getLabelRegions(const string &str, vector ®s); protected: - EGS_BaseGeometry *bg; - EGS_BaseGeometry **g; - int nbase, nmax; - static string type; - - /* New indexing style: - - If the base geometry has \f$N_B\f$ regions and the inscribed - geometries \f$G_j\f$ have \f$n_j\f$ regions, then the CD geometry - will have \f$n_1 + n_2 + \cdots n_{N_B}\f$ regions - (if there is no inscribed geometry is some region, then - \f$n_j = 1\f$). Then, for a CD geometry region \f$i\f$ - the base region \f$i_B\f$ is given by reg_to_base[i] and - the local region in the inscribed geometry (if any) is - \f$i\f$ - local_start[\f$i_B\f$]. - */ - - /*! If true, use new indexing style */ - bool new_indexing; - /*! If new indexing style is used, converts global region to - base region */ - int *reg_to_base; - /*! If new indexing style is used, local_start[ibase] is the first - region in base region ibase */ - int *local_start; - - void setMedia(EGS_Input *inp, int, const int *); + EGS_BaseGeometry *bg; + EGS_BaseGeometry **g; + int nbase, nmax; + static string type; + + /* New indexing style: + + If the base geometry has \f$N_B\f$ regions and the inscribed + geometries \f$G_j\f$ have \f$n_j\f$ regions, then the CD geometry + will have \f$n_1 + n_2 + \cdots n_{N_B}\f$ regions + (if there is no inscribed geometry is some region, then + \f$n_j = 1\f$). Then, for a CD geometry region \f$i\f$ + the base region \f$i_B\f$ is given by reg_to_base[i] and + the local region in the inscribed geometry (if any) is + \f$i\f$ - local_start[\f$i_B\f$]. + */ + + /*! If true, use new indexing style */ + bool new_indexing; + /*! If new indexing style is used, converts global region to + base region */ + int *reg_to_base; + /*! If new indexing style is used, local_start[ibase] is the first + region in base region ibase */ + int *local_start; + + void setMedia(EGS_Input *inp, int, const int *); private: - void setPropertError(const char *funcname) { - egsFatal("EGS_CDGeometry::%s: don't use this method\n Define " - "properties in the constituent geometries instead\n"); - }; - - void setHasRhoScaling() { - has_rho_scaling = false; - if( bg->hasRhoScaling() ) { has_rho_scaling = true; return; } - for(int j=0; jhasRhoScaling()) { - has_rho_scaling = true; return; } - } - } - }; - - void setUpIndexing(); + void setPropertError(const char *funcname) { + egsFatal("EGS_CDGeometry::%s: don't use this method\n Define " + "properties in the constituent geometries instead\n"); + }; + + void setHasRhoScaling() { + has_rho_scaling = false; + if (bg->hasRhoScaling()) { + has_rho_scaling = true; + return; + } + for (int j=0; jhasRhoScaling()) { + has_rho_scaling = true; + return; + } + } + } + }; + + void setUpIndexing(); }; #endif diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp index 256a35592..e263d2641 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.cpp @@ -41,7 +41,7 @@ using std::vector; #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif string EGS_SimpleCone::type = "EGS_SimpleCone"; @@ -50,16 +50,21 @@ string EGS_ConeSet::type = "EGS_ConeSet"; string EGS_ConeStack::type = "EGS_ConeStack"; void EGS_ConeStack::clear(bool all) { - if( nltot > 0 ) { - if( all ) { - for(int j=0; jderef() ) delete cones[j][i]; + if (nltot > 0) { + if (all) { + for (int j=0; jderef()) { + delete cones[j][i]; + } delete [] cones[j]; } nl = 0; } - delete [] cones; delete [] pos; delete [] nr; delete [] flag; + delete [] cones; + delete [] pos; + delete [] nr; + delete [] flag; nltot = 0; } } @@ -69,73 +74,101 @@ void EGS_ConeStack::resize() { int nnew = nltot + N_CS_GROW; int *new_nr = new int [nnew], *new_flag = new int [nnew]; EGS_Float *new_pos = new EGS_Float [nnew+1]; - EGS_SimpleCone ***new_cones = new EGS_SimpleCone** [nnew]; - for(int j=0; j 0) { + new_pos[nl] = pos[nl]; } - if( nl > 0 ) new_pos[nl] = pos[nl]; clear(false); - nr = new_nr; pos = new_pos; flag = new_flag; cones = new_cones; + nr = new_nr; + pos = new_pos; + flag = new_flag; + cones = new_cones; nltot = nnew; } void EGS_ConeStack::addLayer(EGS_Float thick, const vector &rtop, - const vector &rbottom, - const vector &med_names) { + const vector &rbottom, + const vector &med_names) { int this_nr = rbottom.size(); - if( !this_nr ) { + if (!this_nr) { egsWarning("EGS_ConeStack::addLayer: no bottom radii?\n"); - egsWarning(" --> ignoring layer\n"); return; + egsWarning(" --> ignoring layer\n"); + return; } - if( med_names.size() != this_nr ) { + if (med_names.size() != this_nr) { egsWarning("EGS_ConeStack::addLayer: number of cone radii (%d) is" - " different from number of media (%d)\n",this_nr,med_names.size()); - egsWarning(" --> ignoting layer\n"); return; + " different from number of media (%d)\n",this_nr,med_names.size()); + egsWarning(" --> ignoting layer\n"); + return; } bool same_radii = false; - if( rtop.size() != rbottom.size() ) { - if( !rtop.size() ) { - if( !nl ) { + if (rtop.size() != rbottom.size()) { + if (!rtop.size()) { + if (!nl) { egsWarning("EGS_ConeStack::addLayer: zero top radii does not" - " work for the first layer\n"); - egsWarning(" --> ignoting layer\n"); return; + " work for the first layer\n"); + egsWarning(" --> ignoting layer\n"); + return; } same_radii = true; } else { egsWarning("EGS_ConeStack::addLayer: number of bottom radii (%d)" - " is different from number of top radii (%d)\n",this_nr, - rtop.size()); - egsWarning(" --> ignoting layer\n"); return; + " is different from number of top radii (%d)\n",this_nr, + rtop.size()); + egsWarning(" --> ignoting layer\n"); + return; } } - if( nl >= nltot ) resize(); - if( !nl ) { - pos[nl] = xo*a; Rout = rbottom[this_nr-1]; + if (nl >= nltot) { + resize(); + } + if (!nl) { + pos[nl] = xo*a; + Rout = rbottom[this_nr-1]; Rout2 = Rout*Rout; - if( fabs(rtop[this_nr-1]-Rout) > 1e-5 ) same_Rout = false; + if (fabs(rtop[this_nr-1]-Rout) > 1e-5) { + same_Rout = false; + } } cones[nl] = new EGS_SimpleCone * [this_nr]; - nr[nl] = this_nr; pos[nl+1] = pos[nl] + thick; + nr[nl] = this_nr; + pos[nl+1] = pos[nl] + thick; EGS_Vector x(xo+a*(pos[nl]-pos[0])); //egsInformation(" layer %d x = (%g,%g,%g)\n",nl,x.x,x.y,x.z); - for(int ir=0; irgetRadius(x) : rtop[ir]; cones[nl][ir] = new EGS_SimpleCone(x,a,thick,Rtop,rbottom[ir]); cones[nl][ir]->setMedium(med_names[ir]); cones[nl][ir]->ref(); - if( ir == this_nr-1 ) { - if( fabs(rbottom[this_nr-1]-Rout) > 1e-5 ) same_Rout = false; - if( fabs(Rtop-Rout) > 1e-5 ) same_Rout = false; + if (ir == this_nr-1) { + if (fabs(rbottom[this_nr-1]-Rout) > 1e-5) { + same_Rout = false; + } + if (fabs(Rtop-Rout) > 1e-5) { + same_Rout = false; + } } } - if( same_radii ) { - flag[nl-1] += 2; flag[nl] = 1; - } else flag[nl] = 0; - if( this_nr > nmax ) nmax = this_nr; - ++nl; nreg = nl*nmax; + if (same_radii) { + flag[nl-1] += 2; + flag[nl] = 1; + } + else { + flag[nl] = 0; + } + if (this_nr > nmax) { + nmax = this_nr; + } + ++nl; + nreg = nl*nmax; //egsInformation("addLayer: the following layers are defined:\n"); //for(int j=0; j &rtop, void EGS_ConeStack::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation("number of layers: %d\n",nl); - for(int il=0; ilgetRadius(x)); + } egsInformation("\n bottom radii: "); x = xo + a*(pos[il+1]-pos[0]); - for(i=0; igetRadius(x)); + } egsInformation("\n media: "); - for(i=0; imedium(0)); + } egsInformation("\n"); } egsInformation("=====================================================\n"); @@ -168,8 +205,12 @@ void EGS_SimpleCone::printInfo() const { egsInformation(" cone apex = (%g,%g,%g)\n",xo.x,xo.y,xo.z); egsInformation(" cone axis = (%g,%g,%g)\n",a.x,a.y,a.z); egsInformation(" opening angle = %g degrees\n",180*atan(gamma)/M_PI); - if( open ) egsInformation(" cone is open\n"); - else egsInformation(" cone height %g\n",-d1); + if (open) { + egsInformation(" cone is open\n"); + } + else { + egsInformation(" cone height %g\n",-d1); + } egsInformation("=====================================================\n"); } @@ -179,8 +220,9 @@ void EGS_ParallelCones::printInfo() const { egsInformation(" opening angle = %g degrees\n",180*atan(gamma)/M_PI); egsInformation(" number of cones = %d\n",nc); egsInformation(" cone apexes:\n "); - for(int j=0; jgetInput("type",type); - if( err ) { - egsWarning("createGeometry(cones): object type not specified\n"); - return 0; - } - if( type == "EGS_ConeStack" ) { - vector axis; - err = input->getInput("axis",axis); - if( err ) { - egsWarning("createGeometry(EGS_ConeStack): no axis input\n"); + if (!input) { + egsWarning("createGeometry(cones): null input?\n"); return 0; } - if( axis.size() != 6 ) { - egsWarning("createGeometry(EGS_ConeStack): wrong axis input" - " (expecting 6 instead of %d inputs)\n",axis.size()); + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(cones): object type not specified\n"); return 0; } - EGS_ConeStack *g = new EGS_ConeStack( + if (type == "EGS_ConeStack") { + vector axis; + err = input->getInput("axis",axis); + if (err) { + egsWarning("createGeometry(EGS_ConeStack): no axis input\n"); + return 0; + } + if (axis.size() != 6) { + egsWarning("createGeometry(EGS_ConeStack): wrong axis input" + " (expecting 6 instead of %d inputs)\n",axis.size()); + return 0; + } + EGS_ConeStack *g = new EGS_ConeStack( EGS_Vector(axis[0],axis[1],axis[2]), EGS_Vector(axis[3],axis[4],axis[5]),""); - EGS_Input *layer; int nl = 0; - vector layerLabels; - while( (layer = input->takeInputItem("layer")) ) { - vector rtop, rbottom; - vector media; - EGS_Float thickness; - err = layer->getInput("thickness",thickness); - if( err ) - egsWarning("createGeometry(EGS_ConeStack): missing 'thickness'" - " input for layer %d\n --> layer ignored\n",nl); - else { - err = layer->getInput("top radii",rtop); - err = layer->getInput("bottom radii",rbottom); - if( err ) egsWarning("createGeometry(EGS_ConeStack): missing " - "'bottom radii' input for layer %d\n",nl); - int err1 = layer->getInput("media",media); - if( err1 ) egsWarning("createGeometry(EGS_ConeStack): missing " - "'media' input for layer %d\n",nl); - if( err || err1 ) egsWarning(" --> layer ignored\n"); - else g->addLayer(thickness,rtop,rbottom,media); + EGS_Input *layer; + int nl = 0; + vector layerLabels; + while ((layer = input->takeInputItem("layer"))) { + vector rtop, rbottom; + vector media; + EGS_Float thickness; + err = layer->getInput("thickness",thickness); + if (err) + egsWarning("createGeometry(EGS_ConeStack): missing 'thickness'" + " input for layer %d\n --> layer ignored\n",nl); + else { + err = layer->getInput("top radii",rtop); + err = layer->getInput("bottom radii",rbottom); + if (err) egsWarning("createGeometry(EGS_ConeStack): missing " + "'bottom radii' input for layer %d\n",nl); + int err1 = layer->getInput("media",media); + if (err1) egsWarning("createGeometry(EGS_ConeStack): missing " + "'media' input for layer %d\n",nl); + if (err || err1) { + egsWarning(" --> layer ignored\n"); + } + else { + g->addLayer(thickness,rtop,rbottom,media); + } + } + layerLabels.push_back(g->setLabels(layer)); + delete layer; + ++nl; } - layerLabels.push_back(g->setLabels(layer)); - delete layer; ++nl; - } - if( !g->nLayer() ) { - egsWarning("createGeometry(EGS_ConeStack): zero layers\n"); - delete g; return 0; - } - - // adjust lable region numbering in each layer - int count=0; - for (int i=0; ishiftLabelRegions(count,i); - count++; + if (!g->nLayer()) { + egsWarning("createGeometry(EGS_ConeStack): zero layers\n"); + delete g; + return 0; } - } - g->setName(input); - g->setLabels(input); - return g; - } + // adjust lable region numbering in each layer + int count=0; + for (int i=0; ishiftLabelRegions(count,i); + count++; + } + } - // get cone apex position - vector tmp; EGS_Vector Xo; - err = input->getInput("apex",tmp); - if( err || tmp.size() != 3 ) - egsWarning("createGeometry(cones): no 'apex' input, " - "assuming (0,0,0)\n"); - else { Xo.x = tmp[0]; Xo.y = tmp[1]; Xo.z = tmp[2]; } - tmp.clear(); + g->setName(input); + g->setLabels(input); + return g; + } - // get cone axis - EGS_Vector axis(0,0,1); err = input->getInput("axis",tmp); - if( err || tmp.size() != 3 ) - egsWarning("createGeometry(cones): no 'axis' input, assuming " - "(0,0,1)\n"); - else { axis.x = tmp[0]; axis.y = tmp[1]; axis.z = tmp[2]; } + // get cone apex position + vector tmp; + EGS_Vector Xo; + err = input->getInput("apex",tmp); + if (err || tmp.size() != 3) + egsWarning("createGeometry(cones): no 'apex' input, " + "assuming (0,0,0)\n"); + else { + Xo.x = tmp[0]; + Xo.y = tmp[1]; + Xo.z = tmp[2]; + } + tmp.clear(); - EGS_BaseGeometry *g; - if( input->compare(type,"EGS_ConeSet") ) { - vector angles; - err = input->getInput("opening angles",angles); - bool is_radian = false; - if( err ) { - angles.clear(); - err = input->getInput("opening angles in radian",angles); - if( err ) { - egsWarning("createGeometry(cones): no 'opening angles' or " - "'opening angles in radian' input\n"); return 0; - } - is_radian = true; + // get cone axis + EGS_Vector axis(0,0,1); + err = input->getInput("axis",tmp); + if (err || tmp.size() != 3) + egsWarning("createGeometry(cones): no 'axis' input, assuming " + "(0,0,1)\n"); + else { + axis.x = tmp[0]; + axis.y = tmp[1]; + axis.z = tmp[2]; } - int flag = 0; - err = input->getInput("flag",flag); - int nc = angles.size(); - EGS_Float *gamma = new EGS_Float [nc]; - for(int j=0; j= M_PI/2 ) { - egsWarning("createGeometry(cones): opening angles can not be" - " greater than Pi/2\n"); delete [] gamma; return 0; + + EGS_BaseGeometry *g; + if (input->compare(type,"EGS_ConeSet")) { + vector angles; + err = input->getInput("opening angles",angles); + bool is_radian = false; + if (err) { + angles.clear(); + err = input->getInput("opening angles in radian",angles); + if (err) { + egsWarning("createGeometry(cones): no 'opening angles' or " + "'opening angles in radian' input\n"); + return 0; + } + is_radian = true; } - if( j > 0 ) { - if( angles[j] <= angles[j-1] ) { + int flag = 0; + err = input->getInput("flag",flag); + int nc = angles.size(); + EGS_Float *gamma = new EGS_Float [nc]; + for (int j=0; j= M_PI/2) { + egsWarning("createGeometry(cones): opening angles can not be" + " greater than Pi/2\n"); + delete [] gamma; + return 0; + } + if (j > 0) { + if (angles[j] <= angles[j-1]) { + egsWarning("createGeometry(cones): opening angles must be" + " in increasing order\n"); + delete [] gamma; + return 0; + } } + gamma[j] = tan(a); } - gamma[j] = tan(a); + g = new EGS_ConeSet(Xo,axis,nc,gamma,flag); + delete [] gamma; } - g = new EGS_ConeSet(Xo,axis,nc,gamma,flag); - delete [] gamma; - } - else { - // get opening angle - EGS_Float angle; - err = input->getInput("opening angle",angle); - if( err ) { - err = input->getInput("opening angle in radian",angle); - if( err ) { - egsWarning("createGeometry(cones): no 'opening angle' or " - "'opening angle in radian' input\n"); return 0; + else { + // get opening angle + EGS_Float angle; + err = input->getInput("opening angle",angle); + if (err) { + err = input->getInput("opening angle in radian",angle); + if (err) { + egsWarning("createGeometry(cones): no 'opening angle' or " + "'opening angle in radian' input\n"); + return 0; + } } - } else angle *= (M_PI/180); - if( angle >= M_PI/2 ) { - egsWarning("createGeometry(cones): it is not allowed to have" - " an opening angle greater than Pi/2, your input was %g\n",angle); - return 0; - } - EGS_Float gamma = tan(angle); - if( input->compare(type,"EGS_SimpleCone") ) { - EGS_Float height; EGS_Float *h = 0; - err = input->getInput("height",height); - if( !err ) { - if( height <= 0 ) - egsWarning("createGeometry(cones): the cone height" - " must be greater than zero, your input was %g\n",height); - else h = &height; + else { + angle *= (M_PI/180); + } + if (angle >= M_PI/2) { + egsWarning("createGeometry(cones): it is not allowed to have" + " an opening angle greater than Pi/2, your input was %g\n",angle); + return 0; + } + EGS_Float gamma = tan(angle); + if (input->compare(type,"EGS_SimpleCone")) { + EGS_Float height; + EGS_Float *h = 0; + err = input->getInput("height",height); + if (!err) { + if (height <= 0) + egsWarning("createGeometry(cones): the cone height" + " must be greater than zero, your input was %g\n",height); + else { + h = &height; + } + } + g = new EGS_SimpleCone(Xo,axis,gamma,h,""); + } + else if (input->compare(type,"EGS_ParallelCones")) { + vector d; + err = input->getInput("apex distances",d); + EGS_Float *dist=0; + int nc=1; + if (!err && d.size() > 0) { + dist = new EGS_Float [d.size()]; + for (int j=0; jcompare(type,"EGS_ParallelCones") ) { - vector d; - err = input->getInput("apex distances",d); - EGS_Float *dist=0; int nc=1; - if( !err && d.size() > 0 ) { - dist = new EGS_Float [d.size()]; - for(int j=0; jsetName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; + } } \ No newline at end of file diff --git a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.h b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.h index 0e9654853..c47a09fd8 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.h +++ b/HEN_HOUSE/egs++/geometry/egs_cones/egs_cones.h @@ -46,22 +46,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_CONES_DLL -#define EGS_CONES_EXPORT __declspec(dllexport) -#else -#define EGS_CONES_EXPORT __declspec(dllimport) -#endif -#define EGS_CONES_LOCAL + #ifdef BUILD_CONES_DLL + #define EGS_CONES_EXPORT __declspec(dllexport) + #else + #define EGS_CONES_EXPORT __declspec(dllimport) + #endif + #define EGS_CONES_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_CONES_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_CONES_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_CONES_EXPORT -#define EGS_CONES_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_CONES_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_CONES_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_CONES_EXPORT + #define EGS_CONES_LOCAL + #endif #endif @@ -116,8 +116,8 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { public: // constructor - EGS_SimpleCone (const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float Gamma, - const EGS_Float *distance=0, const string &N="") + EGS_SimpleCone(const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float Gamma, + const EGS_Float *distance=0, const string &N="") : EGS_BaseGeometry(N), xo(Xo), a(A), gamma(Gamma), g12(1+Gamma*Gamma), open(true), is_cyl(false) { @@ -133,15 +133,16 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { Ro = -d1*gamma; Ro2 = Ro*Ro; } - else + else { egsWarning("EGS_SimpleCone: the distance to the closing plane must be positive\n"); + } } nreg = 1; } // constructor - EGS_SimpleCone (const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float dz, - EGS_Float Rtop, EGS_Float Rbottom, bool Open=true, const string &N="") + EGS_SimpleCone(const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float dz, + EGS_Float Rtop, EGS_Float Rbottom, bool Open=true, const string &N="") : EGS_BaseGeometry(N), a(A), open(Open), is_cyl(false) { @@ -181,41 +182,49 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { ~EGS_SimpleCone() {} // isInside - bool isInside (const EGS_Vector &x) { + bool isInside(const EGS_Vector &x) { EGS_Vector xp(x-xo); // vector from cone apex xo to test point x EGS_Float aa = xp*a; // projection of xp on axis vector a // check bounds along cone axis - if (!open && (aa < 0 || aa+d1 > 0)) return false; + if (!open && (aa < 0 || aa+d1 > 0)) { + return false; + } // check cylinder radius if (is_cyl) { EGS_Float r2 = xp.length2() - aa*aa; - if (r2 <= Ro2) return true; + if (r2 <= Ro2) { + return true; + } return false; } // check cone radius EGS_Float r2 = xp.length2(); - if (r2 <= aa*aa*g12 ) return true; + if (r2 <= aa*aa*g12) { + return true; + } return false; } // isWhere - int isWhere (const EGS_Vector &x) { - if (isInside(x)) return 0; + int isWhere(const EGS_Vector &x) { + if (isInside(x)) { + return 0; + } return -1; } // inside - int inside (const EGS_Vector &x) { + int inside(const EGS_Vector &x) { return isWhere(x); } // howfar - int howfar (int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { EGS_Vector xp(x-xo); // vector from cone apex xo to test point x EGS_Float aa = xp*a; // projection of xp on cone axis a @@ -227,7 +236,9 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { if (is_cyl) { // u is parallel to a (u and a are normalized) - if (fabs(b) >= 1) return ireg; + if (fabs(b) >= 1) { + return ireg; + } EGS_Float A = 1 - b*b; // A = 1-cos^2(t) = sin^2(t) EGS_Float B = c - b*aa; // B = u * [xp - (xp*a)a] = u * n @@ -237,39 +248,58 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // from inside cylinder if (!ireg) { EGS_Float D = B*B-A*C; // R0^2 - [ n^2 - ((n*u)/sint)^2 ] - if (D < 0 || (C > 0 && B > 0) ) d = 0; - // ^ hopefully a precision problem. - else d = B<=0 ? (sqrt(D)-B)/A : -C/(sqrt(D)+B); + if (D < 0 || (C > 0 && B > 0)) { + d = 0; + } + // ^ hopefully a precision problem. + else { + d = B<=0 ? (sqrt(D)-B)/A : -C/(sqrt(D)+B); + } } // from outside cylinder else { if (C < 0) { // inside cylinder: fp precision error - if (B < 0) d = 0; // assume we are on the cylinder - else return ireg; // u points away from cylinder + if (B < 0) { + d = 0; // assume we are on the cylinder + } + else { + return ireg; // u points away from cylinder + } } else { - if (B >= 0) return ireg; // u points away from cylinder + if (B >= 0) { + return ireg; // u points away from cylinder + } EGS_Float D = B*B-A*C; // R0^2 - [ n^2 - ((n*u)/sint)^2 ] - if (D < 0) return ireg; // u line does not intersect cylinder + if (D < 0) { + return ireg; // u line does not intersect cylinder + } d = C/(sqrt(D)-B); // solve (n + d*(u-a(u*a)))^2 - R0^2 = 0 } } // distance to cylinder is longer than step length - if (d > t) return ireg; + if (d > t) { + return ireg; + } // intersection with cylinder is beyond boundary planes if (!open) { EGS_Float aux = aa + d*b; - if (aux < 0 || aux+d1 > 0) return ireg; + if (aux < 0 || aux+d1 > 0) { + return ireg; + } } // intersect with cylinder t = d; - if( newmed && ireg < 0 ) *newmed = med; + if (newmed && ireg < 0) { + *newmed = med; + } if (normal) { EGS_Float lam = aa+b*d; - EGS_Vector aux(xp+u*d-a*lam); aux.normalize(); + EGS_Vector aux(xp+u*d-a*lam); + aux.normalize(); *normal = ireg < 0 ? aux : aux*(-1); } @@ -286,15 +316,21 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { inew = 0; if (ireg < 0) { // we are coming from outside t = 0; - if (newmed) *newmed = med; - if (normal) *normal = a*(-1); + if (newmed) { + *newmed = med; + } + if (normal) { + *normal = a*(-1); + } } else if (!open && b>0) { // check closing plane EGS_Float tt = -d1/b; // tt = -(aa + d1)/b but aa=0 if here if (tt <= t) { t = tt; inew = -1; - if (normal) *normal = a*(-1); + if (normal) { + *normal = a*(-1); + } } } } @@ -303,7 +339,9 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { inew = -1; if (ireg >= 0) { // we are coming from inside t = 0; - if (normal) *normal = a; + if (normal) { + *normal = a; + } } } @@ -320,9 +358,13 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { EGS_Float tt = -(aa+d1)/b; // distance to closing plane if (tt <= t) { EGS_Float r2p = r2 + tt*(tt + 2*c); - if( r2p <= d1*d1*g12 ) { // enter via the closing plane - if (newmed) *newmed = med; - if (normal) *normal = a; + if (r2p <= d1*d1*g12) { // enter via the closing plane + if (newmed) { + *newmed = med; + } + if (normal) { + *normal = a; + } t = tt; return 0; } @@ -330,7 +372,9 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // if we are inside the conical surface, the only way to enter is via the // closing plane. but if (r2 <= aa*aa*g12), we didn't enter: simply return - if (r2 <= aa*aa*g12) return ireg; + if (r2 <= aa*aa*g12) { + return ireg; + } } } // from inside cone @@ -339,9 +383,13 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { EGS_Float tt = -(aa+d1)/b; // distance to closing plane if (tt <= t) { EGS_Float r2p = r2 + tt*(tt + 2*c); - if( r2p <= d1*d1*g12 ) { // exit via the closing plane - if (newmed) *newmed = -1; - if (normal) *normal = a*(-1); + if (r2p <= d1*d1*g12) { // exit via the closing plane + if (newmed) { + *newmed = -1; + } + if (normal) { + *normal = a*(-1); + } t = tt; return -1; } @@ -365,10 +413,12 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // moving parallel to the cone surface (A=0, within hard-coded tolerance): // solution: t = -C/(2*B), if t>0 - if ( (!ireg && B>0) || (ireg && B<0)) { + if ((!ireg && B>0) || (ireg && B<0)) { EGS_Float ttt = -C/(2*B); // solution lam = aa+b*ttt; // (x+t*u)*a >= 0: on "positive" cone - if (ttt >= 0 && lam >= 0) tt = ttt; // distance to cone surface + if (ttt >= 0 && lam >= 0) { + tt = ttt; // distance to cone surface + } } } else { @@ -393,24 +443,40 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { EGS_Float ttt = -1; EGS_Float D = B*B-A*C; // determinant - if (D<0) return ireg; // no real solution: no intersection + if (D<0) { + return ireg; // no real solution: no intersection + } if (!ireg && !(A<0 && B<0)) { // inside cone - if (B>0) ttt = -C/(B+sqrt(D)); - else ttt = (sqrt(D)-B)/A; + if (B>0) { + ttt = -C/(B+sqrt(D)); + } + else { + ttt = (sqrt(D)-B)/A; + } } else if (ireg && !(A>0 && B>0)) { // outside cone - if (B<0) ttt = C/(sqrt(D)-B); - else ttt = -(sqrt(D)+B)/A; + if (B<0) { + ttt = C/(sqrt(D)-B); + } + else { + ttt = -(sqrt(D)+B)/A; + } + } + else { + return ireg; // no intersection } - else return ireg; // no intersection lam = aa+b*ttt; // (x+t*u)*a >= 0: on "positive" cone - if (ttt >= -2e-5 && lam >= 0) tt = ttt; // why the hard-coded -2e-5 bound?? + if (ttt >= -2e-5 && lam >= 0) { + tt = ttt; // why the hard-coded -2e-5 bound?? + } } // distance too far, or intersection beyond bounding plane - if (tt > t || (!open && ireg && d1 + aa + tt*b > 0)) return ireg; + if (tt > t || (!open && ireg && d1 + aa + tt*b > 0)) { + return ireg; + } // set distance and new region @@ -418,11 +484,15 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { int inew = ireg ? 0 : -1; // set medium and surface normal - if (newmed) *newmed = inew ? -1 : med; + if (newmed) { + *newmed = inew ? -1 : med; + } if (normal) { *normal = xp + u*t - a*(lam*g12); normal->normalize(); - if (!ireg) *normal *= (-1); + if (!ireg) { + *normal *= (-1); + } } // return new region @@ -431,7 +501,7 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // hownear - EGS_Float hownear (int ireg, const EGS_Vector &x) { + EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Vector xp(x-xo); // position with respect to cone origin EGS_Float aa = xp*a; // position along cone axis @@ -444,21 +514,31 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // open, or within bounding planes if (open || (aa > 0 && aa+d1 < 0)) { r2 = sqrt(r2 - aa*aa); // radial distance from axis - if (ireg) return r2-Ro; // from outside - else return Ro-r2; // from inside + if (ireg) { + return r2-Ro; // from outside + } + else { + return Ro-r2; // from inside + } } r2 = sqrt(r2 - aa*aa); // radial distance from axis // inside the radius of cylinder: shortest distance is to closing plane if (r2 < Ro) { - if (aa<0) return -aa; // distance to "0" closing plane - else return aa+d1; // distance to "d1" closing plane + if (aa<0) { + return -aa; // distance to "0" closing plane + } + else { + return aa+d1; // distance to "d1" closing plane + } } // outside the radius of cylinder: shortest distance is to cylinder cap "corner" EGS_Float aux = r2-Ro; - if (aa<0) return sqrt(aa*aa + aux*aux); // distance to "0" cap + if (aa<0) { + return sqrt(aa*aa + aux*aux); // distance to "0" cap + } EGS_Float tp = aa+d1; return sqrt(tp*tp + aux*aux); // distance to "d1" cap @@ -475,7 +555,9 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { EGS_Float tc = fabs((ag-r2a)*g12i); // distance to cone (perp. to cone surface) // open cone: tc is the shortest distance - if (open) return tc; + if (open) { + return tc; + } // closed cone: check closing plane EGS_Float tp = d1+aa; // signed axial distance to closing plane @@ -483,18 +565,22 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { // inside cone if (!ireg) { tp = -tp; // adjust sign of distance - if (tp < tc) tc = tp; // pick shortest distance + if (tp < tc) { + tc = tp; // pick shortest distance + } } // outside, but inside conical surface - else if (tp > 0 && r2 < aa*aa*g12 ) { + else if (tp > 0 && r2 < aa*aa*g12) { if (r2a2 > Ro2) { // outside the cone base cylinder EGS_Float aux = r2a - Ro; tc = sqrt(tp*tp + aux*aux); // nearest point is cone base "corner" } - else tc = tp; // inside the cone base cylinder + else { + tc = tp; // inside the cone base cylinder + } } // outside, and outside conical surface - else if (tp + tc*gamma*g12i > 0 ) { // nearest point is cone base "corner" + else if (tp + tc*gamma*g12i > 0) { // nearest point is cone base "corner" EGS_Float aux = r2a + d1*gamma; // distance to cone base cylinder tc = sqrt(aux*aux + tp*tp); // distance to cone base "corner" } @@ -504,25 +590,37 @@ class EGS_CONES_EXPORT EGS_SimpleCone : public EGS_BaseGeometry { } // getType accessor - const string &getType() const { return type; } + const string &getType() const { + return type; + } // printInfo accessor void printInfo() const; // getApex accessor - EGS_Vector getApex() const { return xo; } + EGS_Vector getApex() const { + return xo; + } // getAxis accessor - EGS_Vector getAxis() const { return a; } + EGS_Vector getAxis() const { + return a; + } // getGamma accessor - EGS_Float getGamma() const { return gamma; } + EGS_Float getGamma() const { + return gamma; + } // getRadius accessor EGS_Float getRadius(const EGS_Vector &x) const { - if (is_cyl) return Ro; + if (is_cyl) { + return Ro; + } EGS_Float xp = (x-xo)*a; - if (xp <= 0) return 0; + if (xp <= 0) { + return 0; + } return xp*gamma; } }; @@ -583,15 +681,17 @@ class EGS_ParallelCones : public EGS_BaseGeometry { public: // constructor - EGS_ParallelCones (int Nc, const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float Gamma, - const EGS_Float *distances, const string &N="") + EGS_ParallelCones(int Nc, const EGS_Vector &Xo, const EGS_Vector &A, EGS_Float Gamma, + const EGS_Float *distances, const string &N="") : EGS_BaseGeometry(N), a(A), gamma(Gamma), g12(1+Gamma*Gamma), nc(Nc) { a.normalize(); g12i = 1/sqrt(g12); - if (nc < 1) nc=1; // enforce nc >= 1 + if (nc < 1) { + nc=1; // enforce nc >= 1 + } nreg = nc; // one region per cone xo = new EGS_Vector[nc]; // vector of cone apex positions xo[0] = Xo; // apex of first cone @@ -603,8 +703,9 @@ class EGS_ParallelCones : public EGS_BaseGeometry { d = new EGS_Float [nc-1]; for (int j=1; j 1) delete [] d; + if (nc > 1) { + delete [] d; + } } // isInside - bool isInside (const EGS_Vector &x) { + bool isInside(const EGS_Vector &x) { EGS_Vector xp(x-xo[0]); // current position with respect to apex EGS_Float aa = xp*a; // current axial position - if (aa < 0) return false; // on "negative" side of cones + if (aa < 0) { + return false; // on "negative" side of cones + } EGS_Float r2 = xp.length2(); // distance^2 to apex - if (r2 <= aa*aa*g12) return true; // inside outer cone + if (r2 <= aa*aa*g12) { + return true; // inside outer cone + } return false; }; // isWhere - int isWhere (const EGS_Vector &x) { + int isWhere(const EGS_Vector &x) { EGS_Vector xp(x-xo[0]); // current position with respect to apex EGS_Float aa = xp*a; // current axial position - if (aa < 0) return -1; // on "negative" side of apex + if (aa < 0) { + return -1; // on "negative" side of apex + } EGS_Float r2 = xp.length2(); // distance^2 to apex - if (r2 > aa*aa*g12) return -1; // outside outer cone + if (r2 > aa*aa*g12) { + return -1; // outside outer cone + } EGS_Float r2a2 = r2 - aa*aa; // distance to cone set axis for (int j=0; j ajg*ajg) return j; // on "negative" side or outside of cone j + if (aj < 0 || r2a2 > ajg*ajg) { + return j; // on "negative" side or outside of cone j + } } return nc-1; // then it must be in last cone } // inside - int inside (const EGS_Vector &x) { + int inside(const EGS_Vector &x) { return isWhere(x); } // howfar - int howfar (int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, - int *newmed=0, EGS_Vector *normal=0) { + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, + int *newmed=0, EGS_Vector *normal=0) { // not in innermost cone if (ireg < nc-1) { @@ -658,8 +771,12 @@ class EGS_ParallelCones : public EGS_BaseGeometry { bool hit = false; // howfar hit flag // apex position of "next" inner cone - if (ireg < 0) xp = x-xo[0]; // apex of outer cone - else xp = x-xo[ireg+1]; // apex of next inner cone + if (ireg < 0) { + xp = x-xo[0]; // apex of outer cone + } + else { + xp = x-xo[ireg+1]; // apex of next inner cone + } // general solution EGS_Float aa = xp*a; // axial position in current cone @@ -684,22 +801,30 @@ class EGS_ParallelCones : public EGS_BaseGeometry { // general solution else { EGS_Float D = B*B-A*C; - if( D >= 0 && !( A > 0 && B > 0 ) ) { + if (D >= 0 && !(A > 0 && B > 0)) { EGS_Float ttt = B < 0 ? C/(sqrt(D)-B) : -(sqrt(D)+B)/A; lam = aa+b*ttt; - if( ttt >= 0 && lam >= 0 ) { tt = ttt; hit = true; } + if (ttt >= 0 && lam >= 0) { + tt = ttt; + hit = true; + } } } if (tt <= t) { - int inew = ireg < 0 ? 0 : ireg+1; t = tt; - if (newmed) *newmed = medium(inew); + int inew = ireg < 0 ? 0 : ireg+1; + t = tt; + if (newmed) { + *newmed = medium(inew); + } if (normal) { *normal = xp + u*t - a*(lam*g12); normal->normalize(); } return inew; } - if (ireg < 0 || hit) return ireg; + if (ireg < 0 || hit) { + return ireg; + } } // inside and not hitting the next inner cone. @@ -708,27 +833,35 @@ class EGS_ParallelCones : public EGS_BaseGeometry { EGS_Float aa = xp*a, b = u*a, r2 = xp.length2(), c = u*xp; EGS_Float A = 1 - b*b*g12, B = c - aa*b*g12, C = r2 - aa*aa*g12; EGS_Float to = 1e30, lamo = -1; - if( fabs(A) < 1e-6 ) { // moving parallel to the cone surface. + if (fabs(A) < 1e-6) { // moving parallel to the cone surface. // for the outer cone we only have a solution if a*u < 0. // i.e. if we are moving towards the apex. - if( b < 0 ) { - EGS_Float ttt = -C/(2*B); lamo = aa+b*ttt; - if( ttt >= 0 && lamo >= 0 ) to = ttt; + if (b < 0) { + EGS_Float ttt = -C/(2*B); + lamo = aa+b*ttt; + if (ttt >= 0 && lamo >= 0) { + to = ttt; + } } } else { EGS_Float D = B*B-A*C; // avoid numerical problems when |A*C| << |B| - if( D >= 0 && !(A < 0 && B < 0) ) { + if (D >= 0 && !(A < 0 && B < 0)) { EGS_Float ttt = B > 0 ? -C/(B+sqrt(D)) : (sqrt(D)-B)/A; lamo = aa+b*ttt; - if( ttt >= 0 && lamo >= 0 ) to = ttt; + if (ttt >= 0 && lamo >= 0) { + to = ttt; + } } } - if( to <= t ) { - t = to; int inew = ireg-1; - if( newmed ) *newmed = inew < 0 ? -1 : medium(inew); - if( normal ) { + if (to <= t) { + t = to; + int inew = ireg-1; + if (newmed) { + *newmed = inew < 0 ? -1 : medium(inew); + } + if (normal) { *normal = xp + u*t - a*(lamo*g12); normal->normalize(); } @@ -738,18 +871,28 @@ class EGS_ParallelCones : public EGS_BaseGeometry { } // hownear - EGS_Float hownear (int ireg, const EGS_Vector &x) { + EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float tc; if (ireg < 0 || ireg < nc-1) { EGS_Vector xp; - if( ireg < 0 ) xp = x - xo[0]; - else xp = x - xo[ireg+1]; + if (ireg < 0) { + xp = x - xo[0]; + } + else { + xp = x - xo[ireg+1]; + } EGS_Float aa = xp*a; EGS_Float ag = aa*gamma; EGS_Float r2 = xp.length2(); - if (aa < 0 && ag*ag > r2*g12) tc = sqrt(r2); - else tc = fabs((ag-sqrt(r2-aa*aa))*g12i); - if (ireg < 0) return tc; + if (aa < 0 && ag*ag > r2*g12) { + tc = sqrt(r2); + } + else { + tc = fabs((ag-sqrt(r2-aa*aa))*g12i); + } + if (ireg < 0) { + return tc; + } } EGS_Vector xp(x-xo[ireg]); EGS_Float aa = xp*a; @@ -839,59 +982,95 @@ class EGS_ConeSet : public EGS_BaseGeometry { EGS_Float *Gamma, int Flag = 0, const string &Name = "") : EGS_BaseGeometry(Name), xo(Xo), a(A), flag(Flag) { a.normalize(); - if( Nc < 1 ) + if (Nc < 1) { egsFatal("EGS_ConeSet: number of cones must be positive\n"); - nc = Nc; gamma = new EGS_Float [nc]; g12 = new EGS_Float [nc]; + } + nc = Nc; + gamma = new EGS_Float [nc]; + g12 = new EGS_Float [nc]; g12i = new EGS_Float [nc]; - if( flag < 0 || flag > 2 ) { + if (flag < 0 || flag > 2) { egsWarning("EGS_ConeSet: flag must be 0,1 or 2, reseting to 0\n"); flag = 0; } - for(int j=0; j 0 ) { - if( Gamma[j] <= gamma[j-1] ) egsFatal("EGS_ConeSet: " - "gamma's must be in increasing order\n"); } - gamma[j] = Gamma[j]; g12[j] = 1 + gamma[j]*gamma[j]; + if (j > 0) { + if (Gamma[j] <= gamma[j-1]) egsFatal("EGS_ConeSet: " + "gamma's must be in increasing order\n"); + } + gamma[j] = Gamma[j]; + g12[j] = 1 + gamma[j]*gamma[j]; g12i[j] = 1/sqrt(g12[j]); } - if( flag == 0 ) nreg = nc; - else nreg = 2*nc + 1; - if( flag == 1 ) is_convex = false; + if (flag == 0) { + nreg = nc; + } + else { + nreg = 2*nc + 1; + } + if (flag == 1) { + is_convex = false; + } } - ~EGS_ConeSet() { delete [] gamma; delete [] g12; delete [] g12i; } + ~EGS_ConeSet() { + delete [] gamma; + delete [] g12; + delete [] g12i; + } bool isInside(const EGS_Vector &x) { - if( flag == 2 ) return true; - EGS_Vector xp(x-xo); EGS_Float aa = xp*a; - if( flag == 0 && aa < 0 ) return false; + if (flag == 2) { + return true; + } + EGS_Vector xp(x-xo); + EGS_Float aa = xp*a; + if (flag == 0 && aa < 0) { + return false; + } EGS_Float r2 = xp.length2(); - if( r2 <= aa*aa*g12[nc-1] ) return true; + if (r2 <= aa*aa*g12[nc-1]) { + return true; + } return false; } int isWhere(const EGS_Vector &x) { - EGS_Vector xp(x-xo); EGS_Float aa = xp*a; - if( flag == 0 && aa < 0 ) return -1; - EGS_Float r2 = xp.length2(); int j; - for(j=0; j= 0 ) return j; + EGS_Vector xp(x-xo); + EGS_Float aa = xp*a; + if (flag == 0 && aa < 0) { + return -1; + } + EGS_Float r2 = xp.length2(); + int j; + for (j=0; j= 0) { + return j; + } return 2*nc-j; } - if( flag != 2 ) return -1; + if (flag != 2) { + return -1; + } return nc; } bool isRealRegion(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return false; + if (ireg < 0 || ireg >= nreg) { + return false; + } return flag != 1 ? true : (ireg != nc); } - int inside(const EGS_Vector &x) { return isWhere(x); } + int inside(const EGS_Vector &x) { + return isWhere(x); + } int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { @@ -899,97 +1078,132 @@ class EGS_ConeSet : public EGS_BaseGeometry { EGS_Float aa = xp*a, b = u*a, r2 = xp.length2(), c = u*xp; //if( debug ) egsWarning(" ireg = %d x = (%g,%g,%g) a = %g" // " b = %g r2 = %g c = %g\n",ireg,x.x,x.y,x.z,aa,b,r2,c); - if( !xp.length2() ) { + if (!xp.length2()) { // handle odd case where position coincides with apex int inew = isWhere(xp + u); - if( inew != ireg ) { + if (inew != ireg) { t = 0; - if( normal ) *normal = a; - if( newmed ) *newmed = inew >= 0 ? medium(inew) : -1; + if (normal) { + *normal = a; + } + if (newmed) { + *newmed = inew >= 0 ? medium(inew) : -1; + } } return inew; } - if( ireg != 0 && ireg != 2*nc ) { + if (ireg != 0 && ireg != 2*nc) { // Not in the inner-most cone. // If outside (ireg < 0 || flag=2 and ireg=nc), check for // intersection with the outer-most cone // If inside, check for intersection with the inner cone. EGS_Float gam12; - if( ireg < 0 || ireg == nc ) gam12 = g12[nc-1]; - else gam12 = ireg < nc ? g12[ireg-1] : g12[2*nc-ireg-1]; + if (ireg < 0 || ireg == nc) { + gam12 = g12[nc-1]; + } + else { + gam12 = ireg < nc ? g12[ireg-1] : g12[2*nc-ireg-1]; + } EGS_Float A=1-b*b*gam12, B=c-aa*b*gam12, C=r2-aa*aa*gam12; //if( debug ) egsWarning(" gam12 = %g A = %g B = %g " // "C = %g\n",gam12,A,B,C); - EGS_Float tt = -1, lam; bool hit = false; - if( fabs(A) < 1e-6 ) { - if( (ireg < nc && b > 0) || (ireg >= nc && b < 0) ) + EGS_Float tt = -1, lam; + bool hit = false; + if (fabs(A) < 1e-6) { + if ((ireg < nc && b > 0) || (ireg >= nc && b < 0)) { tt = -C/(2*B); + } } else { EGS_Float D = B*B-A*C; - if( D >= 0 && !( A > 0 && B > 0 ) ) + if (D >= 0 && !(A > 0 && B > 0)) { tt = B < 0 ? C/(sqrt(D)-B) : -(sqrt(D)+B)/A; + } } - if( tt >= 0 ) { // possible intersection - lam = aa+b*tt; int inew; - if( ireg == nc || ireg == -1 ) { + if (tt >= 0) { // possible intersection + lam = aa+b*tt; + int inew; + if (ireg == nc || ireg == -1) { // outside the outer-most cone. // if flag=1 or flag=2, we are allowed to hit either // of the two cones - if( flag ) { - hit = true; inew = lam >= 0 ? nc-1 : nc+1; + if (flag) { + hit = true; + inew = lam >= 0 ? nc-1 : nc+1; } // if flag=0, we are allowed to hit only the lower // cone (lam >= 0) - else if( !flag && lam>=0 ) { hit = true; inew = nc-1; } + else if (!flag && lam>=0) { + hit = true; + inew = nc-1; + } } else { // inside. In this case we are only allowed to hit // the cone on the same side of the apex. - if( lam*aa >= 0 ) { + if (lam*aa >= 0) { hit = true; inew = lam >= 0 ? ireg-1 : ireg+1; } } - if( hit && tt <= t ) { + if (hit && tt <= t) { t = tt; - if( newmed ) *newmed = medium(inew); - if( normal ) { + if (newmed) { + *newmed = medium(inew); + } + if (normal) { *normal = xp + u*t - a*(lam*gam12); normal->normalize(); } return inew; } } - if( ireg < 0 || ireg == nc || hit ) return ireg; + if (ireg < 0 || ireg == nc || hit) { + return ireg; + } } //EGS_Float gam12 = ireg < nc-1 ? g12[ireg] : g12[2*nc-ireg]; EGS_Float gam12 = ireg < nc ? g12[ireg] : g12[2*nc-ireg]; EGS_Float A=1-b*b*gam12, B=c-aa*b*gam12, C=r2-aa*aa*gam12; EGS_Float tt=-1; - if( fabs(A) < 1e-6 ) { - if( (ireg < nc && b < 0) || (ireg > nc && b > 0) ) tt = -C/(2*B); + if (fabs(A) < 1e-6) { + if ((ireg < nc && b < 0) || (ireg > nc && b > 0)) { + tt = -C/(2*B); + } } else { EGS_Float D = B*B-A*C; // avoid numerical problems when |A*C| << |B| - if( D >= 0 && !(A < 0 && B < 0) ) { + if (D >= 0 && !(A < 0 && B < 0)) { tt = B > 0 ? -C/(B+sqrt(D)) : (sqrt(D)-B)/A; } } - if( tt < 0 ) return ireg; + if (tt < 0) { + return ireg; + } EGS_Float lam = aa + b*tt; - if( (ireg < nc && lam < 0) || (ireg > nc && lam > 0) ) return ireg; - if( tt <= t ) { - t = tt; int inew; - if( ireg < nc ) { - inew = ireg+1; if( inew == nc && flag < 2 ) inew = -1; + if ((ireg < nc && lam < 0) || (ireg > nc && lam > 0)) { + return ireg; + } + if (tt <= t) { + t = tt; + int inew; + if (ireg < nc) { + inew = ireg+1; + if (inew == nc && flag < 2) { + inew = -1; + } } else { - inew = ireg-1; if( inew == nc && flag < 2 ) inew = -1; + inew = ireg-1; + if (inew == nc && flag < 2) { + inew = -1; + } + } + if (newmed) { + *newmed = inew < 0 ? -1 : medium(inew); } - if( newmed ) *newmed = inew < 0 ? -1 : medium(inew); - if( normal ) { + if (normal) { *normal = xp + u*t - a*(lam*gam12); normal->normalize(); } @@ -999,31 +1213,52 @@ class EGS_ConeSet : public EGS_BaseGeometry { } EGS_Float hownear(int ireg, const EGS_Vector &x) { - EGS_Float tc; EGS_Vector xp(x-xo); + EGS_Float tc; + EGS_Vector xp(x-xo); EGS_Float aa = xp*a, r2 = xp.length2(), ag; //egsWarning("hownear: ireg = %d x = (%g,%g,%g) aa = %g r2 = %g\n", // ireg,x.x,x.y,x.z,aa,r2); - if( ireg != 0 && ireg != 2*nc ) { + if (ireg != 0 && ireg != 2*nc) { int i; - if( ireg < 0 || ireg == nc ) i = nc-1; - else i = ireg < nc ? ireg-1 : 2*nc-ireg-1; + if (ireg < 0 || ireg == nc) { + i = nc-1; + } + else { + i = ireg < nc ? ireg-1 : 2*nc-ireg-1; + } ag = aa*gamma[i]; - if( flag == 0 && aa < 0 && ag*ag > r2*g12[i] ) tc = sqrt(r2); - else tc = fabs((fabs(ag)-sqrt(r2-aa*aa))*g12i[i]); + if (flag == 0 && aa < 0 && ag*ag > r2*g12[i]) { + tc = sqrt(r2); + } + else { + tc = fabs((fabs(ag)-sqrt(r2-aa*aa))*g12i[i]); + } //egsWarning(" i = %d ag = %g g12i = %g tc = %g\n",i,ag,g12i[i],tc); - if( ireg < 0 || ireg == nc ) return tc; + if (ireg < 0 || ireg == nc) { + return tc; + } } EGS_Float gam12i; - if( ireg < nc ) { ag = aa*gamma[ireg]; gam12i = g12i[ireg]; } - else { ag = -aa*gamma[2*nc-ireg]; gam12i = g12i[2*nc-ireg]; } + if (ireg < nc) { + ag = aa*gamma[ireg]; + gam12i = g12i[ireg]; + } + else { + ag = -aa*gamma[2*nc-ireg]; + gam12i = g12i[2*nc-ireg]; + } EGS_Float tco = fabs((ag-sqrt(r2-aa*aa))*gam12i); //egsWarning(" ag = %g tco = %g\n",ag,tco); return tco < tc ? tco : tc; } - int getMaxStep() const { return 4*nreg + 2; } + int getMaxStep() const { + return 4*nreg + 2; + } - const string &getType() const { return type; } + const string &getType() const { + return type; + } void printInfo() const; }; @@ -1100,10 +1335,10 @@ class EGS_ConeStack : public EGS_BaseGeometry { public: // constructor (empty cone stack) - EGS_ConeStack (const EGS_Vector &Xo, const EGS_Vector &A, const string &Name) + EGS_ConeStack(const EGS_Vector &Xo, const EGS_Vector &A, const string &Name) : xo(Xo), a(A), nl(0), nltot(0), nmax(0), same_Rout(true), Rout(0), Rout2(0), EGS_BaseGeometry(Name) { - a.normalize(); + a.normalize(); } // destructor @@ -1112,48 +1347,56 @@ class EGS_ConeStack : public EGS_BaseGeometry { } // add a layer - void addLayer (EGS_Float thick, const vector &rtop, - const vector &rbottom, - const vector &med_names); + void addLayer(EGS_Float thick, const vector &rtop, + const vector &rbottom, + const vector &med_names); // get medium - int medium (int ireg) const { - int il = ireg/nmax; int ir = ireg - il*nmax; + int medium(int ireg) const { + int il = ireg/nmax; + int ir = ireg - il*nmax; return cones[il][ir]->medium(0); } // isInside - bool isInside (const EGS_Vector &x) { + bool isInside(const EGS_Vector &x) { EGS_Float p = x*a; - if (p < pos[0] || p > pos[nl] ) return false; + if (p < pos[0] || p > pos[nl]) { + return false; + } int il = findRegion(p,nl+1,pos); return cones[il][nr[il]-1]->isInside(x); } // isWhere - int isWhere (const EGS_Vector &x) { + int isWhere(const EGS_Vector &x) { EGS_Float p = x*a; - if (p < pos[0] || p > pos[nl] ) return -1; + if (p < pos[0] || p > pos[nl]) { + return -1; + } int il = findRegion(p,nl+1,pos); int ir = isWhere(il,x); return ir < 0 ? -1 : il*nmax+ir; } // inside - int inside (const EGS_Vector &x) { + int inside(const EGS_Vector &x) { return isWhere(x); } // isRealRegion - bool isRealRegion (int ireg) const { - if (ireg < 0 || ireg >= nreg ) return false; - int il = ireg/nmax; int ir = ireg - il*nmax; + bool isRealRegion(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return false; + } + int il = ireg/nmax; + int ir = ireg - il*nmax; return (ir < nr[il]); } // howfar - int howfar (int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { EGS_Float xp = x*a; EGS_Float up = u*a; @@ -1203,28 +1446,42 @@ class EGS_ConeStack : public EGS_BaseGeometry { // hit a cone boundary if (hitc) { - if (irnew < 0) return irnew; // we are moving out of conestack, return -1 - if (newmed) *newmed = cones[il][irnew]->medium(0); + if (irnew < 0) { + return irnew; // we are moving out of conestack, return -1 + } + if (newmed) { + *newmed = cones[il][irnew]->medium(0); + } return il*nmax + irnew; } // did not hit a plane (nor a cone: should not happen!) - if (!hitp) return ireg; + if (!hitp) { + return ireg; + } // change layer int ilnew = il + dir; // new layer index - if (normal) *normal = dir > 0 ? a*(-1) : a; - if (ilnew < 0 || ilnew >= nl) return -1;// beyond conestack bounding planes => outside + if (normal) { + *normal = dir > 0 ? a*(-1) : a; + } + if (ilnew < 0 || ilnew >= nl) { + return -1; // beyond conestack bounding planes => outside + } // next layer radii are congruent (add nmax to ireg) if (dir > 0 && flag[il] >= 2) { - if (newmed) *newmed = cones[il+1][ir]->medium(0); + if (newmed) { + *newmed = cones[il+1][ir]->medium(0); + } return ireg+nmax; } // previous layer radii are congruent (subtract nmax from ireg) - if (dir < 0 && (flag[il] == 1 || flag[il] == 3) ) { - if (newmed) *newmed = cones[il-1][ir]->medium(0); + if (dir < 0 && (flag[il] == 1 || flag[il] == 3)) { + if (newmed) { + *newmed = cones[il-1][ir]->medium(0); + } return ireg-nmax; } @@ -1232,8 +1489,12 @@ class EGS_ConeStack : public EGS_BaseGeometry { il += dir; // new layer index EGS_Vector tmp(x+u*t); // position of the hit on new layer ir = isWhere(il,tmp); // get region index in that layer - if (ir<0) return ir; // moved out of constack - if (newmed) *newmed = cones[il][ir]->medium(0); + if (ir<0) { + return ir; // moved out of constack + } + if (newmed) { + *newmed = cones[il][ir]->medium(0); + } return il*nmax+ir; // return overall new region index } @@ -1246,9 +1507,13 @@ class EGS_ConeStack : public EGS_BaseGeometry { // outside the first boundary plane if (xp <= pos[0]) { - if (up <= 0) return ireg; // moving away from conestack: no hit + if (up <= 0) { + return ireg; // moving away from conestack: no hit + } tp = (pos[0]-xp)/up; // distance to first boundary plane - if (tp > t) return ireg; // distance greater than maximum t: no hit + if (tp > t) { + return ireg; // distance greater than maximum t: no hit + } tmp += u*tp; // move to first plane ttot = tp; // increase cumulative travel distance il = 0; // index of current layer @@ -1266,21 +1531,32 @@ class EGS_ConeStack : public EGS_BaseGeometry { // BUT indeed we may be glancing on a "corner" of the ConeStack, so we should still // check if a subsequent call to howfar(ir,tmp,...) takes us outside within epsilon. // It that case we are not really entering the geometry. - EGS_Float tb = 1e30; int inew_g = howfar(ir,tmp,u,tb,0,normal); - if (inew_g < 0 && tb <= epsilon) return ireg; // exits geometry + EGS_Float tb = 1e30; + int inew_g = howfar(ir,tmp,u,tb,0,normal); + if (inew_g < 0 && tb <= epsilon) { + return ireg; // exits geometry + } //*************************************************************** t = tp; // distance to hit is distance to plane - if (newmed) *newmed = cones[0][ir]->medium(0); - if (normal) *normal = a*(-1); + if (newmed) { + *newmed = cones[0][ir]->medium(0); + } + if (normal) { + *normal = a*(-1); + } return ir; // return region number } } // outside the last boundary plane else if (xp >= pos[nl]) { - if (up >= 0) return ireg; // moving away from the conestack: no hit + if (up >= 0) { + return ireg; // moving away from the conestack: no hit + } tp = (pos[nl]-xp)/up; // distance to last boundary plane - if (tp > t) return ireg; // distance greater than maximum t: no hit + if (tp > t) { + return ireg; // distance greater than maximum t: no hit + } tmp += u*tp; // hit position on last plane ttot = tp; // increase cumulative travel distance il = nl-1; // index of last plane @@ -1298,12 +1574,19 @@ class EGS_ConeStack : public EGS_BaseGeometry { // BUT indeed we may be glancing on a "corner" of the ConeStack, so we should still // check if a subsequent call to howfar(il*nmax+ir) takes us outside within epsilon. // It that case we are not really entering the geometry. - EGS_Float tb = 1e30; int inew_g = howfar(il*nmax+ir,tmp,u,tb,0,normal); - if (inew_g < 0 && tb <= epsilon) return ireg; // exits geometry + EGS_Float tb = 1e30; + int inew_g = howfar(il*nmax+ir,tmp,u,tb,0,normal); + if (inew_g < 0 && tb <= epsilon) { + return ireg; // exits geometry + } //*************************************************************** t = tp; // distance to hit is distance to plane - if( newmed ) *newmed = cones[il][ir]->medium(0); - if( normal ) *normal = a; // set normal + if (newmed) { + *newmed = cones[il][ir]->medium(0); + } + if (normal) { + *normal = a; // set normal + } return il*nmax+ir; // return region number } } @@ -1328,7 +1611,7 @@ class EGS_ConeStack : public EGS_BaseGeometry { // the geometry. irnow SHOULD be -1, but if a particle is at a boundary or // very close to one, isWhere returns irnow >= 0 values. int irnow = isWhere(x);// irnow > 0 indicates round-off error near boundary - // irnow = -1 indicates proper call from outside + // irnow = -1 indicates proper call from outside // howfar call using irnow instead of -1 in the hope particle gets out of boundary // // int irnew = cones[0][nr[0]-1]->howfar(irnow,x,u,tt,0,&tmp_normal); @@ -1342,23 +1625,32 @@ class EGS_ConeStack : public EGS_BaseGeometry { // fp inconsistency: irnow >= 0 (inside) but called with ireg = -1 (outside) if (irnow >= 0) { - EGS_Float tb = 1e30; int inew_g = howfar(irnow,x,u,tb,0,&tmp_normal); - if (inew_g < 0 && tb <= epsilon) return ireg; // exits geometry + EGS_Float tb = 1e30; + int inew_g = howfar(irnow,x,u,tb,0,&tmp_normal); + if (inew_g < 0 && tb <= epsilon) { + return ireg; // exits geometry + } } //*************************************************************** int irnew = cones[0][nr[0]-1]->howfar(ireg,x,u,tt,0,&tmp_normal); - if (irnew < 0) return -1; // no hit + if (irnew < 0) { + return -1; // no hit + } EGS_Float aux = xp + up*tt; // axis position of hit point on outer cylinder if (aux < pos[0] || aux > pos[nl] ||// beyond conestack bounding planes - (aux == pos[0] && up <= 0) ||// on first plane, going out - (aux == pos[nl] && up >= 0)) { // on last plane, going out + (aux == pos[0] && up <= 0) ||// on first plane, going out + (aux == pos[nl] && up >= 0)) { // on last plane, going out return -1; // => no hit: we're done } il = findRegion(aux,nl+1,pos); // layer index for axis position aux - if (newmed) *newmed = cones[il][nr[il]-1]->medium(0); - if (normal) *normal = tmp_normal; // set normal to normal from howfar + if (newmed) { + *newmed = cones[il][nr[il]-1]->medium(0); + } + if (normal) { + *normal = tmp_normal; // set normal to normal from howfar + } t = tt; // set distance return il*nmax + nr[il]-1; // return region index } @@ -1385,7 +1677,9 @@ class EGS_ConeStack : public EGS_BaseGeometry { } if (tp < epsilon) { il += dir; - if (il < 0 || il >= nl) return ireg; + if (il < 0 || il >= nl) { + return ireg; + } isc = cones[il][nr[il]-1]->isInside(x); } @@ -1429,22 +1723,34 @@ class EGS_ConeStack : public EGS_BaseGeometry { if (!irnew) { // hit the outer cone if (tp > ttot + tt) { // plane is further than cone: we're done t = ttot+tt; // final distance to conestack - if (newmed) *newmed = tmp_med; // set media - if (normal) *normal = tmp_normal; // set normal + if (newmed) { + *newmed = tmp_med; // set media + } + if (normal) { + *normal = tmp_normal; // set normal + } return il*nmax+nr[il]-1; // return final region index } } - if (tp > t || !dir ) break; // guard against glancing hits + if (tp > t || !dir) { + break; // guard against glancing hits + } il += dir; // move to previous or next layer - if (il < 0 || il >= nl) break; // enforce conestack bounding planes + if (il < 0 || il >= nl) { + break; // enforce conestack bounding planes + } ttot = tp; // increase cumulative travel distance tmp = x + u*tp; // move along to position hit on next plane int itest = isWhere(il,tmp); // check where we are in next layer if (itest >= 0) { // we are inside a cone in next layer t = ttot; // update distance - if (newmed) *newmed = cones[il][itest]->medium(0); - if (normal) *normal = dir > 0 ? a*(-1) : a; + if (newmed) { + *newmed = cones[il][itest]->medium(0); + } + if (normal) { + *normal = dir > 0 ? a*(-1) : a; + } return il*nmax + itest; // return final region index } } @@ -1452,7 +1758,7 @@ class EGS_ConeStack : public EGS_BaseGeometry { } // hownear - EGS_Float hownear (int ireg, const EGS_Vector &x) { + EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float xp = x*a; // current position along the axis EGS_Float tp, tc; // distances @@ -1463,7 +1769,9 @@ class EGS_ConeStack : public EGS_BaseGeometry { int ir = ireg - il*nmax; // region index in current layer tp = min(xp-pos[il],pos[il+1]-xp); // min of distance to planes on either side tc = cones[il][ir]->hownear(0,x); // distance to outer conical boundary - if (ir > 0) tc = min(tc,cones[il][ir-1]->hownear(-1,x)); // to inner conical boundary + if (ir > 0) { + tc = min(tc,cones[il][ir-1]->hownear(-1,x)); // to inner conical boundary + } return min(tp,tc); // return minimum distance } @@ -1471,8 +1779,12 @@ class EGS_ConeStack : public EGS_BaseGeometry { // general it would be worse to check hownear on the outer cones in all layer! To mitigate // hownear calls to layer planes, one can inscribe the conestack in a fitting envelope. - if (xp <= pos[0]) return pos[0] - xp; // distance to first layer plane - if (xp >= pos[nl]) return xp - pos[nl]; // distance to last layer plane + if (xp <= pos[0]) { + return pos[0] - xp; // distance to first layer plane + } + if (xp >= pos[nl]) { + return xp - pos[nl]; // distance to last layer plane + } int il = findRegion(xp,nl+1,pos); // find current layer index tp = min(xp-pos[il],pos[il+1]-xp); // min of distance to planes on either side return min(tp,cones[il][nr[il]-1]->hownear(-1,x)); // min dist. to planes and outer cone @@ -1482,7 +1794,9 @@ class EGS_ConeStack : public EGS_BaseGeometry { // getMaxStep int getMaxStep() const { int nstep = 0; - for (int j=0; j top and bottom radii different from adjacent layers - // = 1 -> top radii are the same as bottom of previous layer - // = 2 -> bottom radii are the same as top of next layer - // = 3 -> top and bottom radii same as adjacent layers - EGS_SimpleCone ***cones; // the cones for each layer. + // = 0 -> top and bottom radii different from adjacent layers + // = 1 -> top radii are the same as bottom of previous layer + // = 2 -> bottom radii are the same as top of next layer + // = 3 -> top and bottom radii same as adjacent layers + EGS_SimpleCone ** *cones; // the cones for each layer. static string type; // resize @@ -1534,10 +1848,14 @@ class EGS_ConeStack : public EGS_BaseGeometry { void clear(bool); // isWhere - inline int isWhere (int il, const EGS_Vector &x) { - if (!cones[il][nr[il]-1]->isInside(x)) return -1; + inline int isWhere(int il, const EGS_Vector &x) { + if (!cones[il][nr[il]-1]->isInside(x)) { + return -1; + } for (int j=0; jisInside(x)) return j; + if (cones[il][j]->isInside(x)) { + return j; + } } return nr[il]-1; } diff --git a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp index 065f4f53b..a2e1d8472 100644 --- a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.cpp @@ -39,85 +39,99 @@ string Projector::type = "EGS_conez"; extern "C" { -EGS_CONEZ_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { + EGS_CONEZ_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { - // valid input - if( !input ) { - egsWarning("createGeometry(conez): null input?\n"); - return 0; - } - string type; int err = input ->getInput("type",type); - if(err) - { egsWarning("createGeometry(conez): missing type key\n"); - return 0; - } + // valid input + if (!input) { + egsWarning("createGeometry(conez): null input?\n"); + return 0; + } + string type; + int err = input ->getInput("type",type); + if (err) { + egsWarning("createGeometry(conez): missing type key\n"); + return 0; + } - // apex - EGS_Vector xo; vector tmp; - err = input->getInput("apex",tmp); - if( !err && tmp.size() == 3 ) xo=EGS_Vector(tmp[0],tmp[1],tmp[2]); - else - { egsWarning("createGeometry(conez): invalid apex\n"); - return 0; - } + // apex + EGS_Vector xo; + vector tmp; + err = input->getInput("apex",tmp); + if (!err && tmp.size() == 3) { + xo=EGS_Vector(tmp[0],tmp[1],tmp[2]); + } + else { + egsWarning("createGeometry(conez): invalid apex\n"); + return 0; + } - // opening angles + // opening angles vector angles; err = input->getInput("opening angles",angles); bool is_radian = false; - if( err ) { + if (err) { angles.clear(); err = input->getInput("opening angles in radian",angles); - if( err ) { + if (err) { egsWarning("createGeometry(conez): no 'opening angles' or " - "'opening angles in radian' input\n"); return 0; + "'opening angles in radian' input\n"); + return 0; } is_radian = true; } // check valid angles int nc = angles.size(); - for(int j=0; j= 90 ) { + if (angles[j] >= 90) { egsWarning("createGeometry(conez): opening angles should be " - "less than 90\n"); return 0; + "less than 90\n"); + return 0; } - if( j > 0 ) { - if( angles[j] <= angles[j-1] ) { + if (j > 0) { + if (angles[j] <= angles[j-1]) { egsWarning("createGeometry(conez): opening angles must be" - " in increasing order\n"); return 0; + " in increasing order\n"); + return 0; } } } EGS_Float *t=new EGS_Float [angles.size()]; - for(int i=0;i a; - err=input->getInput("axis",a); - if( err || a.size() !=3 ) - { egsWarning("createGeometry(conez): missing/wrong input\n"); - return 0; - } - egsWarning("got axis (%g,%g,%g)\n",a[0],a[1],a[2]); + // select geometry + EGS_BaseGeometry *g; + if (type == "EGS_Xconez") { + g = new EGS_ConezX(nc,t,xo,"",XProjector()); + } + else if (type == "EGS_Yconez") { + g = new EGS_ConezY(nc,t,xo,"",YProjector()); + } + else if (type == "EGS_Yconez") { + g = new EGS_ConezZ(nc,t,xo,"",ZProjector()); + } + else { + vector a; + err=input->getInput("axis",a); + if (err || a.size() !=3) { + egsWarning("createGeometry(conez): missing/wrong input\n"); + return 0; + } + egsWarning("got axis (%g,%g,%g)\n",a[0],a[1],a[2]); - g = new EGS_Conez(nc,t,xo,"", - Projector(EGS_Vector(a[0],a[1],a[2]))); - } + g = new EGS_Conez(nc,t,xo,"", + Projector(EGS_Vector(a[0],a[1],a[2]))); + } - g->setName(input); g->setMedia(input); - return g; -} + g->setName(input); + g->setMedia(input); + return g; + } } diff --git a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.h b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.h index 14eef8390..a02c6a6a9 100644 --- a/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.h +++ b/HEN_HOUSE/egs++/geometry/egs_conez/egs_conez.h @@ -39,29 +39,28 @@ #ifdef WIN32 -#ifdef BUILD_CONEZ_DLL -#define EGS_CONEZ_EXPORT __declspec(dllexport) -#else -#define EGS_CONEZ_EXPORT __declspec(dllimport) -#endif -#define EGS_CONEZ_LOCAL + #ifdef BUILD_CONEZ_DLL + #define EGS_CONEZ_EXPORT __declspec(dllexport) + #else + #define EGS_CONEZ_EXPORT __declspec(dllimport) + #endif + #define EGS_CONEZ_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_CONEZ_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_CONEZ_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_CONEZ_EXPORT -#define EGS_CONEZ_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_CONEZ_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_CONEZ_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_CONEZ_EXPORT + #define EGS_CONEZ_LOCAL + #endif #endif template -class EGS_CONEZ_EXPORT EGS_ConezT : public EGS_BaseGeometry -{ - protected: +class EGS_CONEZ_EXPORT EGS_ConezT : public EGS_BaseGeometry { +protected: EGS_Float *theta,*cos_t,*cos2_t,*sin_t,*sin2_t; // for conc-cones, all apices coincide @@ -69,383 +68,438 @@ class EGS_CONEZ_EXPORT EGS_ConezT : public EGS_BaseGeometry // projection operator T a; - public: +public: - ~EGS_ConezT() - { if(nreg) { delete [] theta; delete [] cos_t; - delete [] cos2_t; - delete [] sin_t; - delete [] sin2_t; } }; + ~EGS_ConezT() { + if (nreg) { + delete [] theta; + delete [] cos_t; + delete [] cos2_t; + delete [] sin_t; + delete [] sin2_t; + } + }; EGS_ConezT(int nc, const EGS_Float *angle, const EGS_Vector &position, const string &Name, - const T &A) : EGS_BaseGeometry(Name), a(A), xo(position) - { - if(nc>0) - { theta=new EGS_Float [nc]; cos_t=new EGS_Float [nc]; - cos2_t=new EGS_Float [nc]; - sin_t=new EGS_Float [nc]; - sin2_t=new EGS_Float [nc]; - - for(int i=0;i0) { + theta=new EGS_Float [nc]; + cos_t=new EGS_Float [nc]; + cos2_t=new EGS_Float [nc]; + sin_t=new EGS_Float [nc]; + sin2_t=new EGS_Float [nc]; + + for (int i=0; i &angle, const EGS_Vector &position, const string &Name, - const T &A) : EGS_BaseGeometry(Name), a(A), xo(position) - { - if(angle.size()>0) - { theta=new EGS_Float [angle.size()]; - cos_t=new EGS_Float [angle.size()]; - cos2_t=new EGS_Float [angle.size()]; - sin_t=new EGS_Float [angle.size()]; - sin2_t=new EGS_Float [angle.size()]; - - for(int i=0;i0) { + theta=new EGS_Float [angle.size()]; + cos_t=new EGS_Float [angle.size()]; + cos2_t=new EGS_Float [angle.size()]; + sin_t=new EGS_Float [angle.size()]; + sin2_t=new EGS_Float [angle.size()]; + + for (int i=0; icos2_t[0]) return 0; // inside central cone -*/ -if(region_test==1 && cos2_phicos2_t[0]) region_test=0; - - // find particle region - int ic=0,oc=nreg,ms; -if(region_test==1) -{ - while(oc-ic>1) - { - ms=(ic+oc)/2; - if(cos2_phi>cos2_t[ms]) oc=ms; - else ic=ms; - } -region_test=oc; -} + /* + if(cos2_phicos2_t[0]) return 0; // inside central cone + */ + if (region_test==1 && cos2_phicos2_t[0]) { + region_test=0; + } -/* - return oc; -*/ -EGS_Float tmp; -if(rcp<0) tmp=acos(sqrt(cos2_phi))*180/M_PI+90; -else tmp=acos(sqrt(cos2_phi))*180/M_PI; -egsInformation("inside: %2d %12.9f %12.9f %12.9f %12.9f\n", - region_test,rcp,rc.length2(),cos2_phi,tmp); + // find particle region + int ic=0,oc=nreg,ms; + if (region_test==1) { + while (oc-ic>1) { + ms=(ic+oc)/2; + if (cos2_phi>cos2_t[ms]) { + oc=ms; + } + else { + ic=ms; + } + } + region_test=oc; + } + + /* + return oc; + */ + EGS_Float tmp; + if (rcp<0) { + tmp=acos(sqrt(cos2_phi))*180/M_PI+90; + } + else { + tmp=acos(sqrt(cos2_phi))*180/M_PI; + } + egsInformation("inside: %2d %12.9f %12.9f %12.9f %12.9f\n", + region_test,rcp,rc.length2(),cos2_phi,tmp); -return region_test; + return region_test; }; - bool isInside(const EGS_Vector &x) { return false; } - int isWhere(const EGS_Vector &x) { return -1; } + bool isInside(const EGS_Vector &x) { + return false; + } + int isWhere(const EGS_Vector &x) { + return -1; + } int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) - { - egsInformation("howfar: ireg = %d x = (%g,%g,%g) u = (%g,%g,%g)\n",ireg, - x.x,x.y,x.z,u.x,u.y,u.z); - // projections and other often used variables - EGS_Vector rc(x-xo); - /* - EGS_Float - urc=u*rc, - up=a*u, - rcp=a*rc; - */ - EGS_Float urc=u*rc; - EGS_Float up=a*u; - EGS_Float rcp=a*rc; - EGS_Vector rcp_vec=a*rcp; - EGS_Float d=1e30; - int new_region=-1; - -egsInformation("howfar: %2d %12.9f %12.9f\n", - ireg,rcp,acos(rcp/rc.length())*180/M_PI); + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + egsInformation("howfar: ireg = %d x = (%g,%g,%g) u = (%g,%g,%g)\n",ireg, + x.x,x.y,x.z,u.x,u.y,u.z); + // projections and other often used variables + EGS_Vector rc(x-xo); + /* + EGS_Float + urc=u*rc, + up=a*u, + rcp=a*rc; + */ + EGS_Float urc=u*rc; + EGS_Float up=a*u; + EGS_Float rcp=a*rc; + EGS_Vector rcp_vec=a*rcp; + EGS_Float d=1e30; + int new_region=-1; + + egsInformation("howfar: %2d %12.9f %12.9f\n", + ireg,rcp,acos(rcp/rc.length())*180/M_PI); //egsInformation("howfar: %2d %12.9f %12.9f %12f.9\n", // ireg,rcp,rc.length(), // acos(rcp/rc.length())*180/M_PI); - // in any region? - if(ireg>=0) - { - // outer cone normal at near side of cone - EGS_Vector n=(rc-rcp_vec)*cos2_t[ireg]*2-rcp_vec*sin2_t[ireg]*2; - // outer cone normal at far side of cone - EGS_Vector n_reflected=a*(2*(a*n))-n; - - if(!(u*n<0 && u*n_reflected<0)) // outer cone hit - { - EGS_Float A=cos2_t[ireg]-up*up; - EGS_Float B=0.5*(u*n); - EGS_Float C=rc.length2()*cos2_t[ireg]-rcp*rcp; - - if((u*n)*(u*n_reflected)<0) // two hits on physical cone - { - d=-B+sqrt(B*B-A*C); - d/=A; + // in any region? + if (ireg>=0) { + // outer cone normal at near side of cone + EGS_Vector n=(rc-rcp_vec)*cos2_t[ireg]*2-rcp_vec*sin2_t[ireg]*2; + // outer cone normal at far side of cone + EGS_Vector n_reflected=a*(2*(a*n))-n; + + if (!(u*n<0 && u*n_reflected<0)) { // outer cone hit + EGS_Float A=cos2_t[ireg]-up*up; + EGS_Float B=0.5*(u*n); + EGS_Float C=rc.length2()*cos2_t[ireg]-rcp*rcp; + + if ((u*n)*(u*n_reflected)<0) { // two hits on physical cone + d=-B+sqrt(B*B-A*C); + d/=A; //egsInformation("%d %f %f %f %f %f %f %f ", // ireg,acos(rcp/rc.length())*181/M_PI,A,B,C,d, // u*n,u*n_reflected); - } - else // one physical, one unphysical hit - { - d=-B-sqrt(B*B-A*C); - d/=A; + } + else { // one physical, one unphysical hit + d=-B-sqrt(B*B-A*C); + d/=A; //egsInformation(" %d %f %f ",ireg,acos(rcp/rc.length())*180/M_PI,d); - } + } - new_region=ireg+1; + new_region=ireg+1; //egsInformation("--> %d\n",new_region); + } + + if (ireg) { // there is an inner cone + int ireg_inner=ireg-1; + + // inner cone normal at near side of cone + EGS_Vector + n=(rc-rcp_vec)*cos2_t[ireg_inner]*2-rcp_vec*sin2_t[ireg_inner]*2; + EGS_Vector n_reflected=a*(2*(a*n))-n; + + if (u*n<0) { // inner cone hit + EGS_Float A=cos2_t[ireg_inner]-up*up; + EGS_Float B=0.5*(u*n); + EGS_Float C=rc.length2()*cos2_t[ireg_inner]-rcp*rcp; + + EGS_Float dd; + if (u*n_reflected<0) { // one physical, one unphysical hit + dd=-B+sqrt(B*B-A*C); + } + else { // two hits on physical cone + dd=-B-sqrt(B*B-A*C); + } + dd/=A; + + if (dd0) // we are in the lower half-plane - { - n=(rc-rcp_vec)*cos2_t[ireg_inner]*2-rcp_vec*sin2_t[ireg_inner]*2; - n_reflected=a*(2*(a*n))-n; - } - - else // we are in the upper half-plane (rcp!=0 as already checked) - { - if(up<0) return -1; - - n_reflected= - rcp_vec*sin2_t[ireg_inner]*2-(rc-rcp_vec)*cos2_t[ireg_inner]*2; - n=a*(2*(a*n_reflected))-n_reflected; - } - - if(u*n<0) // might hit physical cone - { EGS_Float A=cos2_t[ireg_inner]-up*up; - EGS_Float B=0.5*(u*n); - EGS_Float C=rc.length2()*cos2_t[ireg_inner]-rcp*rcp; - - if(u*n_reflected<0) // one real, one unphysical intersection - { - d=-B+sqrt(B*B-A*C); - d/=A; - } - else // either (1 or 2) real intersections - // OR 2 unphysical intersections - { d=-B-sqrt(B*B-A*C); d/=A; - // check for unphysical intersection - if(rcp>0 && (up<0 && -d*up>rcp)) return -1; - if(rcp<0 && (up<0 || -d*up>rcp)) return -1; - } + new_region=ireg_inner; + } + + else { + EGS_Vector n,n_reflected; + if (rcp>0) { // we are in the lower half-plane + n=(rc-rcp_vec)*cos2_t[ireg_inner]*2-rcp_vec*sin2_t[ireg_inner]*2; + n_reflected=a*(2*(a*n))-n; + } + + else { // we are in the upper half-plane (rcp!=0 as already checked) + if (up<0) { + return -1; + } + + n_reflected= + rcp_vec*sin2_t[ireg_inner]*2-(rc-rcp_vec)*cos2_t[ireg_inner]*2; + n=a*(2*(a*n_reflected))-n_reflected; + } + + if (u*n<0) { // might hit physical cone + EGS_Float A=cos2_t[ireg_inner]-up*up; + EGS_Float B=0.5*(u*n); + EGS_Float C=rc.length2()*cos2_t[ireg_inner]-rcp*rcp; + + if (u*n_reflected<0) { // one real, one unphysical intersection + d=-B+sqrt(B*B-A*C); + d/=A; + } + else // either (1 or 2) real intersections + // OR 2 unphysical intersections + { + d=-B-sqrt(B*B-A*C); + d/=A; + + // check for unphysical intersection + if (rcp>0 && (up<0 && -d*up>rcp)) { + return -1; + } + if (rcp<0 && (up<0 || -d*up>rcp)) { + return -1; + } + } + + new_region=ireg_inner; + } + else { + return -1; + } + } + } - new_region=ireg_inner; - } - else return -1; + if (new_region>=nreg) { + new_region=-1; } - } - - if(new_region>=nreg) new_region=-1; - // correct t-step - egsInformation("about to return: new_region = %d d = %g\n",new_region,d); - if(d=0) - { - d=rcp*sin_t[ireg]-srt*cos_t[ireg]; // outer cone + EGS_Float hownear(int ireg, const EGS_Vector &x) { + EGS_Vector rc(x-xo); + EGS_Float d; + EGS_Float rcp=a*rc; + EGS_Float srt=sqrt(rc.length2()-rcp*rcp); + + // check outer cone first if inside geometry (seems to be working) + if (ireg>=0) { + d=rcp*sin_t[ireg]-srt*cos_t[ireg]; // outer cone //egsInformation("%d %f\n",ireg,d); - if(ireg) // inner cone - { int ireg_inner=ireg-1; - EGS_Float dd=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; + if (ireg) { // inner cone + int ireg_inner=ireg-1; + EGS_Float dd=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; //egsInformation(" %d-%d %f",ireg,ireg_inner,dd); - if(dd%f\n",d); - } + } //egsInformation("%d %f %f %f\n",ireg,srt,rcp,d); - } - - else // two choices if in region -1 - { int ireg_inner=nreg-1; - - if(rcp>0) - { /* getting some negative values */ - d=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; -/* -egsInformation("%d %f %f %f %f ---> %f\n", - ireg_inner,srt,rcp,cos_t[ireg_inner],sin_t[ireg_inner],d); -*/ } - else - { /* seems to be working */ - EGS_Float mag=rc.length(); - EGS_Float beta=M_PI/2+asin(-rcp/mag); - - if(2*(beta-theta[ireg_inner])>M_PI) - d=mag; // distance to apex - else - d=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; + else { // two choices if in region -1 + int ireg_inner=nreg-1; + + if (rcp>0) { + /* getting some negative values */ + d=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; + /* + egsInformation("%d %f %f %f %f ---> %f\n", + ireg_inner,srt,rcp,cos_t[ireg_inner],sin_t[ireg_inner],d); + */ + } + + else { + /* seems to be working */ + EGS_Float mag=rc.length(); + EGS_Float beta=M_PI/2+asin(-rcp/mag); + + if (2*(beta-theta[ireg_inner])>M_PI) { + d=mag; // distance to apex + } + else { + d=srt*cos_t[ireg_inner]-rcp*sin_t[ireg_inner]; + } + } } - } - return d; + return d; }; - const string &getType() const { return a.getType(); }; + const string &getType() const { + return a.getType(); + }; - void printInfo() const - { EGS_BaseGeometry::printInfo(); - a.printInfo(); - egsInformation(" cone apex = (%g,%g,%g)\n",xo.x,xo.y,xo.z); - egsInformation(" opening angles (degrees)= "); - for(int j=0; jgetInput("type",type); - if( err ) { - egsWarning("createGeometry(cylinders): missing type key\n"); - return 0; - } + EGS_CYLINDERS_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + // check for valid input + if (!input) { + egsWarning("createGeometry(cylinders): null input?\n"); + return 0; + } + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(cylinders): missing type key\n"); + return 0; + } - // point on cylinder axis - EGS_Vector xo; vector Xo; - err = input->getInput("midpoint",Xo); - if( !err && Xo.size() == 3 ) xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); + // point on cylinder axis + EGS_Vector xo; + vector Xo; + err = input->getInput("midpoint",Xo); + if (!err && Xo.size() == 3) { + xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); + } - // cylinder radii - vector radii; - err = input->getInput("radii",radii); - if( err ) { - egsWarning("createGeometry(cylinders): wrong/missing 'radii' input\n"); - return 0; - } - EGS_Float *r=new EGS_Float [radii.size()]; - for(int i=0;i radii; + err = input->getInput("radii",radii); + if (err) { + egsWarning("createGeometry(cylinders): wrong/missing 'radii' input\n"); + return 0; + } + EGS_Float *r=new EGS_Float [radii.size()]; + for (int i=0; i a; - err = input->getInput("axis",a); - if( err || a.size() != 3 ) { - egsWarning("createGeometry(cylinders): missing/wrong axis input\n"); - return 0; - } - egsWarning("got axis (%g,%g,%g)\n",a[0],a[1],a[2]); - g = new EGS_Cylinders(radii.size(),r,xo,"", - Projector(EGS_Vector(a[0],a[1],a[2]))); + // select geometry + EGS_BaseGeometry *g; + if (type == "EGS_XCylinders") { + g = new EGS_CylindersX(radii.size(),r,xo,"",XProjector()); + } + else if (type == "EGS_YCylinders") { + g = new EGS_CylindersY(radii.size(),r,xo,"",YProjector()); + } + else if (type == "EGS_ZCylinders") { + g = new EGS_CylindersZ(radii.size(),r,xo,"",ZProjector()); + } + else { + vector a; + err = input->getInput("axis",a); + if (err || a.size() != 3) { + egsWarning("createGeometry(cylinders): missing/wrong axis input\n"); + return 0; + } + egsWarning("got axis (%g,%g,%g)\n",a[0],a[1],a[2]); + g = new EGS_Cylinders(radii.size(),r,xo,"", + Projector(EGS_Vector(a[0],a[1],a[2]))); + } + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; } - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.h b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.h index 8b5a0ed21..a599a971a 100644 --- a/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.h +++ b/HEN_HOUSE/egs++/geometry/egs_cylinders/egs_cylinders.h @@ -46,22 +46,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_CYLINDERS_DLL -#define EGS_CYLINDERS_EXPORT __declspec(dllexport) -#else -#define EGS_CYLINDERS_EXPORT __declspec(dllimport) -#endif -#define EGS_CYLINDERS_LOCAL + #ifdef BUILD_CYLINDERS_DLL + #define EGS_CYLINDERS_EXPORT __declspec(dllexport) + #else + #define EGS_CYLINDERS_EXPORT __declspec(dllimport) + #endif + #define EGS_CYLINDERS_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_CYLINDERS_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_CYLINDERS_EXPORT -#define EGS_CYLINDERS_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_CYLINDERS_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_CYLINDERS_EXPORT + #define EGS_CYLINDERS_LOCAL + #endif #endif @@ -111,9 +111,8 @@ instead. */ template -class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry -{ - protected: +class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry { +protected: EGS_Float *R, //!< Radii *R2; //!< Radii squared @@ -126,14 +125,18 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry int last_ireg, last_dir; #endif - public: +public: /*! \brief Desctructor. Deallocates the #R and #R2 arrays */ - ~EGS_CylindersT() - { if(nreg) { delete [] R; delete [] R2; } }; + ~EGS_CylindersT() { + if (nreg) { + delete [] R; + delete [] R2; + } + }; /*! \brief Construct a set of concentric cylinders. @@ -144,81 +147,99 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry */ EGS_CylindersT(int nc, const EGS_Float *radius, const EGS_Vector &position, const string &Name, - const T &A) : EGS_BaseGeometry(Name), a(A), xo(position) - { - if(nc>0) - { R=new EGS_Float [nc]; - R2=new EGS_Float [nc]; - - for(int i=0;i0) { + R=new EGS_Float [nc]; + R2=new EGS_Float [nc]; + + for (int i=0; i &radius, const EGS_Vector &position, const string &Name, - const T &A) : EGS_BaseGeometry(Name), a(A), xo(position) - { - if(radius.size()>0) - { R=new EGS_Float [radius.size()]; - R2=new EGS_Float [radius.size()]; - - for(int i=0;i0) { + R=new EGS_Float [radius.size()]; + R2=new EGS_Float [radius.size()]; + + for (int i=0; iR2[nreg-1]) return false; + if (rho_sq>R2[nreg-1]) { + return false; + } return true; }; int isWhere(const EGS_Vector &x) { EGS_Vector rc(x-xo); EGS_Float rp=a*rc, rho_sq=rc.length2()-rp*rp; - if(rho_sq>R2[nreg-1]) return -1; - if(rho_sqR2[nreg-1]) { + return -1; + } + if (rho_sqR2[nreg-1]) return -1; // outside all cylinders - if(rho_sq1) - { ms=(ic+oc)/2; - if(rho_sqR2[nreg-1]) { + return -1; // outside all cylinders + } + if (rho_sq1) { + ms=(ic+oc)/2; + if (rho_sq=1) return 1e30; // parallel to axis + if (fabs(up)>=1) { + return 1e30; // parallel to axis + } EGS_Float A=1-up*up; - EGS_Vector rc(x-xo); EGS_Float rcp=a*rc, urc=u*rc; + EGS_Vector rc(x-xo); + EGS_Float rcp=a*rc, urc=u*rc; EGS_Float C=rc.length2()-rcp*rcp-R2[nreg-1]; - if( C >= 0 ) return 0; // outside within precision + if (C >= 0) { + return 0; // outside within precision + } EGS_Float B=urc-up*rcp; EGS_Float Dsq = sqrt(B*B-A*C); EGS_Float d = B > 0 ? -C/(Dsq + B) : (Dsq - B)/A; @@ -226,13 +247,15 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { EGS_Float d=1e30; // large distance to any boundry // projections double up=a*u; - if(fabs(up)>=1) return ireg; // parallel to cylinder axis + if (fabs(up)>=1) { + return ireg; // parallel to cylinder axis + } double A=1-up*up; // d^2 coefficient int dir=-1; // direction entering or exiting cylinder boundry @@ -244,41 +267,45 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry EGS_Float rad; // in any region? - if(ireg>=0) { + if (ireg>=0) { double C=rc.length2()-rcp*rcp-R2[ireg]; // d^0 coefficient // B>=0 ... particle travelling radially outwards - if(B>=0 || !ireg) { // OR it is IN the centre cylinder + if (B>=0 || !ireg) { // OR it is IN the centre cylinder rad = -R[ireg]; dir=ireg+1; - if( dir >= nreg ) dir = -1; + if (dir >= nreg) { + dir = -1; + } double Dsq = B*B-A*C; - if( Dsq > 0 ) Dsq = sqrt(Dsq); + if (Dsq > 0) { + Dsq = sqrt(Dsq); + } else { - if( Dsq < -1e-2 ) egsWarning("\nEGS_CylindersT::howfar(): " - "the particle may not be in the region\n we think it " - "is as Dsq = %g\n",Dsq); + if (Dsq < -1e-2) egsWarning("\nEGS_CylindersT::howfar(): " + "the particle may not be in the region\n we think it " + "is as Dsq = %g\n",Dsq); Dsq = 0; } //d=-B+sqrt(B*B-A*C); d = B > 0 ? -C/(Dsq + B) : (Dsq - B)/A; - if( d < 0 ) { - if( C > 1e-2 ) { + if (d < 0) { + if (C > 1e-2) { egsWarning("\nEGS_CylindersT::howfar(): the particle " - "may not be in the region\n we think it is as " - "Cout = %g\n",C); + "may not be in the region\n we think it is as " + "Cout = %g\n",C); egsWarning(" ireg=%d R2=%g R2[%d]=%g\n",ireg, - rc.length2()-rcp*rcp,ireg,R2[ireg]); + rc.length2()-rcp*rcp,ireg,R2[ireg]); egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n", - x.x,x.y,x.z,u.x,u.y,u.z); + x.x,x.y,x.z,u.x,u.y,u.z); egsWarning("B=%g A=%g\n",B,A); #ifdef CYL_DEBUG egsWarning("last:\n"); egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n", - last_x.x,last_x.y,last_x.z,last_u.x,last_u.y,last_u.z); + last_x.x,last_x.y,last_x.z,last_u.x,last_u.y,last_u.z); egsWarning("B=%g A=%g ireg=%d inew=%d\n", - last_B,last_A,last_ireg,last_dir); + last_B,last_A,last_ireg,last_dir); egsWarning("t=%g d=%g\n",last_t,last_d); #endif } @@ -292,35 +319,40 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry C+=dR2; double D_sq=B*B-A*C; - if(D_sq<=0) { // outer cylinder intersection + if (D_sq<=0) { // outer cylinder intersection rad = -R[ireg]; dir=ireg+1; - if( dir >= nreg ) dir = -1; + if (dir >= nreg) { + dir = -1; + } /* D_sq+=A*C; // should we not use C-=dR2; // d = -B + sqrt(D_sq+A*dR2) d=-B+sqrt(D_sq-A*C); // instead? */ D_sq += A*dR2; - if( D_sq > 0 ) D_sq = sqrt(D_sq); + if (D_sq > 0) { + D_sq = sqrt(D_sq); + } else { - if( D_sq < -1e-2 ) + if (D_sq < -1e-2) egsWarning("\nEGS_CylindersT::howfar(): the " - "particle may not be in the region\n we think " - "it is as D_sq = %g\n",D_sq); + "particle may not be in the region\n we think " + "it is as D_sq = %g\n",D_sq); D_sq = 0; } d = (D_sq - B)/A; } else { // inner cylinder intersection - dir=ireg-1; rad = R[dir]; + dir=ireg-1; + rad = R[dir]; //d=-B-sqrt(D_sq); d = C/(sqrt(D_sq) - B); - if( d < 0 ) { - if( C < -1e-2 ) egsWarning("EGS_CylindersT::howfar(): " - "the particle may not be in the region we think it " - "is as Cin = %g\n",C); + if (d < 0) { + if (C < -1e-2) egsWarning("EGS_CylindersT::howfar(): " + "the particle may not be in the region we think it " + "is as Cin = %g\n",C); d = 1e-16; } } @@ -328,142 +360,198 @@ class EGS_CYLINDERS_EXPORT EGS_CylindersT : public EGS_BaseGeometry } else { // outside all regions - if(B<0) { // particle travelling radially inwards + if (B<0) { // particle travelling radially inwards double C=rc.length2()-rcp*rcp-R2[nreg-1], - D_sq=B*B-A*C; + D_sq=B*B-A*C; - if(D_sq>0) { // cylinder intersection - dir=nreg-1; rad = R[dir]; + if (D_sq>0) { // cylinder intersection + dir=nreg-1; + rad = R[dir]; //d=-B-sqrt(D_sq); d = C/(sqrt(D_sq) - B); - if( d < 0 ) { - if( C < -1e-2 ) { + if (d < 0) { + if (C < -1e-2) { egsWarning("EGS_CylindersT::howfar(): " - "we think that the particle is outside, but C=%g\n",C); + "we think that the particle is outside, but C=%g\n",C); egsWarning(" d=%g B=%g D_sq=%g\n",d,B,D_sq); egsWarning(" ireg=%d x=(%g,%g,%g) u=(%g,%g,%g)\n", - ireg,x.x,x.y,x.z,u.x,u.y,u.z); + ireg,x.x,x.y,x.z,u.x,u.y,u.z); } d = 1e-16; } } } - else return ireg; + else { + return ireg; + } } //d/=A; #ifdef CYL_DEBUG - if( isnan(d) ) { + if (isnan(d)) { egsWarning("d is nan: A=%g B=%g ireg=%d R2=%g\n", - A,B,ireg,rc.length2()-rcp*rcp); + A,B,ireg,rc.length2()-rcp*rcp); } - last_x = x; last_u = u; last_B = B; last_A = A; - last_ireg = ireg; last_dir = dir; last_t = t; last_d = d; + last_x = x; + last_u = u; + last_B = B; + last_A = A; + last_ireg = ireg; + last_dir = dir; + last_t = t; + last_d = d; #endif // correct t-step - if(d= 0 ) *newmed = medium(dir); else *newmed=-1; - if( normal ) { - EGS_Vector n(rc + u*t - a*(rcp+up*t)); *normal = n*(1/rad); + if (newmed) if (dir >= 0) { + *newmed = medium(dir); + } + else { + *newmed=-1; + } + if (normal) { + EGS_Vector n(rc + u*t - a*(rcp+up*t)); + *normal = n*(1/rad); } return dir; } return ireg; }; - EGS_Float hownear(int ireg, const EGS_Vector &x) - { - EGS_Vector rc(x-xo); - EGS_Float + EGS_Float hownear(int ireg, const EGS_Vector &x) { + EGS_Vector rc(x-xo); + EGS_Float rcp=a*rc, rho=sqrt(rc.length2()-rcp*rcp); - // check outer cylinder first if inside geometry - if(ireg>=0) - { EGS_Float d=R[ireg]-rho; + // check outer cylinder first if inside geometry + if (ireg>=0) { + EGS_Float d=R[ireg]-rho; - if(ireg) - { EGS_Float dd=rho-R[ireg-1]; - if(ddgetInput("type",type); - if( err ) { - egsWarning("createGeometry(elliptic cylinders): missing type key\n"); - return 0; - } - - // point on cylinder axis - EGS_Vector xo; vector Xo; - err = input->getInput("midpoint",Xo); - if( !err && Xo.size() == 3 ) xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); + EGS_ELLIPTIC_CYLINDERS_EXPORT + EGS_BaseGeometry *createGeometry(EGS_Input *input) { + // check for valid input + if (!input) { + egsWarning("createGeometry(elliptic cylinders): null input?\n"); + return 0; + } + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(elliptic cylinders): missing type key\n"); + return 0; + } - // cylinder radii - vector x_radii, y_radii; - err = input->getInput("x-radii",x_radii); - if( err ) { - egsWarning("createGeometry(elliptic cylinders): wrong/missing " - "'x-radii' input\n"); - return 0; - } - err = input->getInput("y-radii",y_radii); - if( err ) { - egsWarning("createGeometry(elliptic cylinders): wrong/missing " - "'y-radii' input\n"); - return 0; - } - if( x_radii.size() != y_radii.size() ) { - egsWarning("createGeometry(elliptic cylinders): expecting the same " - "number of x- and y-radii, your input is %d %d\n", - x_radii.size(),y_radii.size()); - return 0; - } + // point on cylinder axis + EGS_Vector xo; + vector Xo; + err = input->getInput("midpoint",Xo); + if (!err && Xo.size() == 3) { + xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); + } - // select geometry - EGS_BaseGeometry *g; - if( type == "EGS_EllipticCylindersXY" ) - g = new EGS_EllipticCylindersXY(x_radii,y_radii,xo,"", - EGS_XProjector("X"),EGS_YProjector("Y")); - else if( type == "EGS_EllipticCylindersXZ" ) - g = new EGS_EllipticCylindersXZ(x_radii,y_radii,xo,"", - EGS_XProjector("X"),EGS_ZProjector("Z")); - else if( type == "EGS_EllipticCylindersYZ" ) - g = new EGS_EllipticCylindersYZ(x_radii,y_radii,xo,"", - EGS_YProjector("Y"),EGS_ZProjector("Z")); - else { - vector ax, ay; - err = input->getInput("x-axis",ax); - if( err || ax.size() != 3 ) { - egsWarning("createGeometry(elliptic cylinders): missing/wrong " - "'x-axis' input\n"); + // cylinder radii + vector x_radii, y_radii; + err = input->getInput("x-radii",x_radii); + if (err) { + egsWarning("createGeometry(elliptic cylinders): wrong/missing " + "'x-radii' input\n"); + return 0; + } + err = input->getInput("y-radii",y_radii); + if (err) { + egsWarning("createGeometry(elliptic cylinders): wrong/missing " + "'y-radii' input\n"); return 0; } - err = input->getInput("y-axis",ay); - if( err || ay.size() != 3 ) { - egsWarning("createGeometry(elliptic cylinders): missing/wrong " - "'y-axis' input\n"); + if (x_radii.size() != y_radii.size()) { + egsWarning("createGeometry(elliptic cylinders): expecting the same " + "number of x- and y-radii, your input is %d %d\n", + x_radii.size(),y_radii.size()); return 0; } - g = new EGS_EllipticCylinders(x_radii,y_radii,xo,"", - EGS_Projector(EGS_Vector(ax[0],ax[1],ax[2]),"Any"), - EGS_Projector(EGS_Vector(ay[0],ay[1],ay[2]),"")); + + // select geometry + EGS_BaseGeometry *g; + if (type == "EGS_EllipticCylindersXY") + g = new EGS_EllipticCylindersXY(x_radii,y_radii,xo,"", + EGS_XProjector("X"),EGS_YProjector("Y")); + else if (type == "EGS_EllipticCylindersXZ") + g = new EGS_EllipticCylindersXZ(x_radii,y_radii,xo,"", + EGS_XProjector("X"),EGS_ZProjector("Z")); + else if (type == "EGS_EllipticCylindersYZ") + g = new EGS_EllipticCylindersYZ(x_radii,y_radii,xo,"", + EGS_YProjector("Y"),EGS_ZProjector("Z")); + else { + vector ax, ay; + err = input->getInput("x-axis",ax); + if (err || ax.size() != 3) { + egsWarning("createGeometry(elliptic cylinders): missing/wrong " + "'x-axis' input\n"); + return 0; + } + err = input->getInput("y-axis",ay); + if (err || ay.size() != 3) { + egsWarning("createGeometry(elliptic cylinders): missing/wrong " + "'y-axis' input\n"); + return 0; + } + g = new EGS_EllipticCylinders(x_radii,y_radii,xo,"", + EGS_Projector(EGS_Vector(ax[0],ax[1],ax[2]),"Any"), + EGS_Projector(EGS_Vector(ay[0],ay[1],ay[2]),"")); + } + g->setName(input); + g->setMedia(input); + return g; } - g->setName(input); g->setMedia(input); - return g; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.h b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.h index 2a2d36e91..5e4a1bd0b 100644 --- a/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.h +++ b/HEN_HOUSE/egs++/geometry/egs_elliptic_cylinders/egs_elliptic_cylinders.h @@ -54,22 +54,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_ELLIPTIC_CYLINDERS_DLL -#define EGS_ELLIPTIC_CYLINDERS_EXPORT __declspec(dllexport) -#else -#define EGS_ELLIPTIC_CYLINDERS_EXPORT __declspec(dllimport) -#endif -#define EGS_ELLIPTIC_CYLINDERS_LOCAL + #ifdef BUILD_ELLIPTIC_CYLINDERS_DLL + #define EGS_ELLIPTIC_CYLINDERS_EXPORT __declspec(dllexport) + #else + #define EGS_ELLIPTIC_CYLINDERS_EXPORT __declspec(dllimport) + #endif + #define EGS_ELLIPTIC_CYLINDERS_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_ELLIPTIC_CYLINDERS_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_ELLIPTIC_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_ELLIPTIC_CYLINDERS_EXPORT -#define EGS_ELLIPTIC_CYLINDERS_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_ELLIPTIC_CYLINDERS_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_ELLIPTIC_CYLINDERS_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_ELLIPTIC_CYLINDERS_EXPORT + #define EGS_ELLIPTIC_CYLINDERS_LOCAL + #endif #endif @@ -117,7 +117,7 @@ instead. */ template class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : - public EGS_BaseGeometry { + public EGS_BaseGeometry { protected: @@ -141,10 +141,13 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : Deallocates the arrays */ ~EGS_EllipticCylindersT() { - if(nreg > 0) { - delete [] ax; delete [] axi; - delete [] ay; delete [] ayi; - delete [] sx; delete [] sy; + if (nreg > 0) { + delete [] ax; + delete [] axi; + delete [] ay; + delete [] ayi; + delete [] sx; + delete [] sy; delete [] is_cyl; } }; @@ -158,23 +161,32 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : \a position is a point on the cylinder axis */ EGS_EllipticCylindersT(int nc, const EGS_Float *x_rad, - const EGS_Float *y_rad, - const EGS_Vector &position, const string &Name, - const Tx &A_x, const Ty &A_y) : EGS_BaseGeometry(Name), - Ax(A_x), Ay(A_y), xo(position), nwarn(0) { - if(nc>0) { - ax = new EGS_Float [nc]; axi = new EGS_Float [nc]; - ay = new EGS_Float [nc]; ayi = new EGS_Float [nc]; - sx = new EGS_Float [nc]; sy = new EGS_Float [nc]; + const EGS_Float *y_rad, + const EGS_Vector &position, const string &Name, + const Tx &A_x, const Ty &A_y) : EGS_BaseGeometry(Name), + Ax(A_x), Ay(A_y), xo(position), nwarn(0) { + if (nc>0) { + ax = new EGS_Float [nc]; + axi = new EGS_Float [nc]; + ay = new EGS_Float [nc]; + ayi = new EGS_Float [nc]; + sx = new EGS_Float [nc]; + sy = new EGS_Float [nc]; is_cyl = new bool [nc]; - for(int i=0;i 1e-4 ) { - sx[i] = 1/(z*z-1)/ax[i]; sy[i] = z*sx[i]; + if (fabs(z-1) > 1e-4) { + sx[i] = 1/(z*z-1)/ax[i]; + sy[i] = z*sx[i]; is_cyl[i] = false; - } else is_cyl[i] = true; + } + else { + is_cyl[i] = true; + } } nreg=nc; } @@ -184,23 +196,32 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : /*! \brief \overload */ EGS_EllipticCylindersT(const vector &x_rad, const vector &y_rad, - const EGS_Vector &position, const string &Name, - const Tx &A_x, const Ty &A_y) : EGS_BaseGeometry(Name), - Ax(A_x), Ay(A_y), xo(position), nwarn(0) { + const EGS_Vector &position, const string &Name, + const Tx &A_x, const Ty &A_y) : EGS_BaseGeometry(Name), + Ax(A_x), Ay(A_y), xo(position), nwarn(0) { int nc = x_rad.size(); - if(nc>0) { - ax = new EGS_Float [nc]; axi = new EGS_Float [nc]; - ay = new EGS_Float [nc]; ayi = new EGS_Float [nc]; - sx = new EGS_Float [nc]; sy = new EGS_Float [nc]; + if (nc>0) { + ax = new EGS_Float [nc]; + axi = new EGS_Float [nc]; + ay = new EGS_Float [nc]; + ayi = new EGS_Float [nc]; + sx = new EGS_Float [nc]; + sy = new EGS_Float [nc]; is_cyl = new bool [nc]; - for(int i=0;i 1e-4 ) { - sx[i] = 1/(z*z-1)/ax[i]; sy[i] = z*sx[i]; + if (fabs(z-1) > 1e-4) { + sx[i] = 1/(z*z-1)/ax[i]; + sy[i] = z*sx[i]; is_cyl[i] = false; - } else is_cyl[i] = true; + } + else { + is_cyl[i] = true; + } } nreg=nc; } @@ -214,61 +235,77 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : }; int isWhere(const EGS_Vector &x) { - if( !isInside(x) ) return -1; + if (!isInside(x)) { + return -1; + } EGS_Vector rc(x-xo); - for(int j=0; j 0 ) { + if (ireg < 0 || ireg > 0) { // Particle is outside or inside but not in the inner-most // cylinder. Check for intersection with an inner cylinder. int n = iold-1; EGS_Float ux = Ax*u*axi[n], uy = Ay*u*ayi[n]; EGS_Float u2 = ux*ux + uy*uy; - if( u2 > 0 ) { + if (u2 > 0) { EGS_Float xx = Ax*xp*axi[n], xy = Ay*xp*ayi[n]; EGS_Float xu = xx*ux + xy*uy; - if( xu < 0 ) { + if (xu < 0) { EGS_Float r2 = xx*xx + xy*xy - 1; - if( r2 > 0 ) { + if (r2 > 0) { EGS_Float D = xu*xu - r2*u2; - if( D >= 0 ) { + if (D >= 0) { EGS_Float d = r2/(sqrt(D) - xu); - if( d <= t ) { t = d; inew = n; ihit = inew; } + if (d <= t) { + t = d; + inew = n; + ihit = inew; + } } } - else { t = 0; inew = n; ihit = inew; } + else { + t = 0; + inew = n; + ihit = inew; + } } } } - if( ireg >= 0 && t > 0 ) { + if (ireg >= 0 && t > 0) { // If here, particle is inside. Check for intersection with // the cylinder the particle is in. EGS_Float ux = Ax*u*axi[ireg], uy = Ay*u*ayi[ireg]; EGS_Float u2 = ux*ux + uy*uy; - if( u2 > 0 ) { + if (u2 > 0) { EGS_Float xx = Ax*xp*axi[ireg], xy = Ay*xp*ayi[ireg]; EGS_Float xu = xx*ux + xy*uy; EGS_Float r2 = xx*xx + xy*xy - 1; EGS_Float d = 1e30; - if( r2 >= 0 ) { + if (r2 >= 0) { // we think we are inside but the math shows we are // outside. Hopefully a truncation problem. - if( xu > 0 ) // moving outwards. + if (xu > 0) { // moving outwards. d = 0; + } else { // moving inwards => assume we are at the boundary // and r2 >= 0 is a truncation problem. @@ -279,38 +316,52 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : EGS_Float D = sqrt(xu*xu - r2*u2); d = xu < 0 ? (D-xu)/u2 : -r2/(D+xu); } - if( d <= t ) { - t = d; inew = ireg+1; ihit = ireg; + if (d <= t) { + t = d; + inew = ireg+1; + ihit = ireg; } } } - if( inew == ireg ) return inew; + if (inew == ireg) { + return inew; + } - if( normal ) { + if (normal) { EGS_Vector xhit = xp + u*t; EGS_Float xx = Ax*xhit, xy = Ay*xhit; *normal = Ax.normal()*(xx*ay[ihit]*ay[ihit]) + Ay.normal()*(xy*ax[ihit]*ax[ihit]); normal->normalize(); - if( inew > iold ) *normal *= (-1); + if (inew > iold) { + *normal *= (-1); + } + } + if (inew >= nreg) { + return -1; + } + if (newmed) { + *newmed = medium(inew); } - if( inew >= nreg ) return -1; - if( newmed ) *newmed = medium(inew); return inew; }; EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float xx = fabs(Ax*x), xy = fabs(Ay*x); EGS_Float tperp = ireg >= 0 ? hownear(ireg,xx,xy) : 1e30; - if( ireg && tperp > 0 ) { + if (ireg && tperp > 0) { int n = ireg < 0 ? nreg-1 : ireg-1; EGS_Float t1 = hownear(n,xx,xy); - if( t1 < tperp ) tperp = t1; + if (t1 < tperp) { + tperp = t1; + } } return tperp; }; - const string &getType() const { return mytype; }; + const string &getType() const { + return mytype; + }; void printInfo() const { EGS_BaseGeometry::printInfo(); @@ -318,10 +369,14 @@ class EGS_ELLIPTIC_CYLINDERS_EXPORT EGS_EllipticCylindersT : egsInformation(" midpoint of cylinders = (%g,%g,%g)\n",xo.x,xo.y,xo.z); int j; egsInformation(" radii along 'x' ="); - for(j=0; j -2) ? - uo*(uo*uo-4*(vo*vo+3))/(16*(1+vo*vo)) : - 1 - 0.5*vo*vo/(vo*vo+(uo+1)*(uo+1)); + uo*(uo*uo-4*(vo*vo+3))/(16*(1+vo*vo)) : + 1 - 0.5*vo*vo/(vo*vo+(uo+1)*(uo+1)); int ntry=0; - while(1) { - if( ++ntry > 50 ) { - if( ++nwarn < 20 ) egsWarning("EGS_EllipticCylindersT::" - "hownear: failed to find solution\n"); + while (1) { + if (++ntry > 50) { + if (++nwarn < 20) egsWarning("EGS_EllipticCylindersT::" + "hownear: failed to find solution\n"); return 0; } double vox = vo*x1, uox = uo + x1, xm1 = 1 - x1*x1; double f = vox*vox - uox*uox*xm1; - if( fabs(f) < 1e-7 ) break; + if (fabs(f) < 1e-7) { + break; + } double fs = 2*(vox*vo + uox*(x1*uox-xm1)); x1 -= f/fs; } - double y1 = ay[ireg]*sqrt(1-x1*x1) - xy; x1 = ax[ireg]*x1-xx; + double y1 = ay[ireg]*sqrt(1-x1*x1) - xy; + x1 = ax[ireg]*x1-xx; return sqrt(x1*x1 + y1*y1); }; }; typedef EGS_EllipticCylindersT - EGS_EllipticCylindersXY; +EGS_EllipticCylindersXY; typedef EGS_EllipticCylindersT - EGS_EllipticCylindersXZ; +EGS_EllipticCylindersXZ; typedef EGS_EllipticCylindersT - EGS_EllipticCylindersYZ; +EGS_EllipticCylindersYZ; typedef EGS_EllipticCylindersT - EGS_EllipticCylinders; +EGS_EllipticCylinders; #endif diff --git a/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp index a29e482f4..ec71fca81 100644 --- a/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_genvelope/egs_envelope_geometry.cpp @@ -46,8 +46,8 @@ string EGS_ENVELOPEG_LOCAL EGS_EnvelopeGeometry::type = "EGS_EnvelopeGeometry"; string EGS_ENVELOPEG_LOCAL EGS_FastEnvelope::type = "EGS_FastEnvelope"; void EGS_EnvelopeGeometry::setMedia(EGS_Input *,int,const int *) { - egsWarning("EGS_EnvelopeGeometry::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + egsWarning("EGS_EnvelopeGeometry::setMedia: don't use this method. Use the\n" + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_EnvelopeGeometry::setRelativeRho(int start, int end, EGS_Float rho) { @@ -56,13 +56,13 @@ void EGS_EnvelopeGeometry::setRelativeRho(int start, int end, EGS_Float rho) { void EGS_EnvelopeGeometry::setRelativeRho(EGS_Input *) { egsWarning("EGS_EnvelopeGeometry::setRelativeRho(): don't use this method." - " Use the\n setRelativeRho methods of the geometry objects that make up" - " this geometry\n"); + " Use the\n setRelativeRho methods of the geometry objects that make up" + " this geometry\n"); } void EGS_FastEnvelope::setMedia(EGS_Input *,int,const int *) { - egsWarning("EGS_FastEnvelope::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + egsWarning("EGS_FastEnvelope::setMedia: don't use this method. Use the\n" + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_FastEnvelope::setRelativeRho(int start, int end, EGS_Float rho) { @@ -71,8 +71,8 @@ void EGS_FastEnvelope::setRelativeRho(int start, int end, EGS_Float rho) { void EGS_FastEnvelope::setRelativeRho(EGS_Input *) { egsWarning("EGS_FastEnvelope::setRelativeRho(): don't use this method." - " Use the\n setRelativeRho methods of the geometry objects that make up" - " this geometry\n"); + " Use the\n setRelativeRho methods of the geometry objects that make up" + " this geometry\n"); } struct EGS_ENVELOPEG_LOCAL EnvelopeAux { @@ -80,159 +80,216 @@ struct EGS_ENVELOPEG_LOCAL EnvelopeAux { int nreg; int *regs; EnvelopeAux() : nreg(0) {}; - ~EnvelopeAux() { if(nreg>0) delete [] regs; }; + ~EnvelopeAux() { + if (nreg>0) { + delete [] regs; + } + }; }; EGS_EnvelopeGeometry::EGS_EnvelopeGeometry(EGS_BaseGeometry *G, const vector &geoms, const string &Name, bool newindexing) : - EGS_BaseGeometry(Name), reg_to_inscr(0), local_start(0) { - if( !G ) egsFatal("EGS_EnvelopeGeometry: base geometry must not be null\n"); - g = G; g->ref(); new_indexing = false; + EGS_BaseGeometry(Name), reg_to_inscr(0), local_start(0) { + if (!G) { + egsFatal("EGS_EnvelopeGeometry: base geometry must not be null\n"); + } + g = G; + g->ref(); + new_indexing = false; nbase = g->regions(); - n_in = geoms.size(); nmax = 1; + n_in = geoms.size(); + nmax = 1; int nreg_inscribed = 0; - if( n_in > 0 ) { + if (n_in > 0) { geometries = new EGS_BaseGeometry * [n_in]; - for(int j=0; jref(); + for (int j=0; jref(); int nj = geometries[j]->regions(); - if( nj > nmax ) nmax = nj; + if (nj > nmax) { + nmax = nj; + } nreg_inscribed += nj; } } nreg = nbase + n_in*nmax; is_convex = g->isConvex(); has_rho_scaling = g->hasRhoScaling(); - if( !has_rho_scaling ) { - for(int j=0; jhasRhoScaling() ) { - has_rho_scaling = true; break; + if (!has_rho_scaling) { + for (int j=0; jhasRhoScaling()) { + has_rho_scaling = true; + break; } } } - if( !n_in ) return; - if( newindexing ) { + if (!n_in) { + return; + } + if (newindexing) { new_indexing = true; local_start = new int [n_in]; reg_to_inscr = new int [nreg_inscribed]; int ir=0; - for(int j=0; jregions(); local_start[j] = nbase + ir; - for(int i=0; i &fgeoms, const string &Name, - int newindexing) : - EGS_BaseGeometry(Name), reg_to_inscr(0), local_start(0) { - if( !G ) egsFatal("EGS_FastEnvelope: base geometry must not be null\n"); - g = G; g->ref(); - n_in = fgeoms.size(); nmax = 1; new_indexing = false; - if( !n_in ) egsFatal("EGS_FastEnvelope: no inscribed geometries!\n"); + const vector &fgeoms, const string &Name, + int newindexing) : + EGS_BaseGeometry(Name), reg_to_inscr(0), local_start(0) { + if (!G) { + egsFatal("EGS_FastEnvelope: base geometry must not be null\n"); + } + g = G; + g->ref(); + n_in = fgeoms.size(); + nmax = 1; + new_indexing = false; + if (!n_in) { + egsFatal("EGS_FastEnvelope: no inscribed geometries!\n"); + } geometries = new EGS_BaseGeometry * [n_in]; nbase = g->regions(); - int *iaux = new int [nbase]; int j; - for(j=0; jg; geometries[j]->ref(); + for (j=0; jg; + geometries[j]->ref(); int nj = geometries[j]->regions(); nreg_inscribed += nj; - if( nj > nmax ) nmax = nj; - for(int i=0; inreg; i++) { + if (nj > nmax) { + nmax = nj; + } + for (int i=0; inreg; i++) { int k = fgeoms[j]->regs[i]; - if( k >= 0 && k < nbase ) { ++iaux[k]; ++nlist; } + if (k >= 0 && k < nbase) { + ++iaux[k]; + ++nlist; + } } } n_start = new int [nbase+1]; - glist = new int [nlist]; int ilist=0; - for(j=0; j 0 ) { - for(int l=0; lnreg; i++) { + if (iaux[j] > 0) { + for (int l=0; lnreg; i++) { int k = fgeoms[l]->regs[i]; - if( k == j ) glist[ilist++] = l; + if (k == j) { + glist[ilist++] = l; + } } } } } n_start[nbase] = ilist; - nreg = nbase + n_in*nmax; is_convex = g->isConvex(); + nreg = nbase + n_in*nmax; + is_convex = g->isConvex(); has_rho_scaling = g->hasRhoScaling(); - if( !has_rho_scaling ) { - for(int j=0; jhasRhoScaling() ) { - has_rho_scaling = true; break; + if (!has_rho_scaling) { + for (int j=0; jhasRhoScaling()) { + has_rho_scaling = true; + break; } } } delete [] iaux; - if( newindexing ) { + if (newindexing) { new_indexing = true; local_start = new int [n_in]; reg_to_inscr = new int [nreg_inscribed]; int ir=0; - for(int j=0; jregions(); local_start[j] = nbase + ir; - for(int i=0; ideref() ) delete g; - for(int j=0; jderef() ) delete geometries[j]; + if (!g->deref()) { + delete g; + } + for (int j=0; jderef()) { + delete geometries[j]; + } } delete [] geometries; - if( new_indexing ) { - if( local_start ) delete [] local_start; - if( reg_to_inscr ) delete [] reg_to_inscr; + if (new_indexing) { + if (local_start) { + delete [] local_start; + } + if (reg_to_inscr) { + delete [] reg_to_inscr; + } } } EGS_FastEnvelope::~EGS_FastEnvelope() { - if( !g->deref() ) delete g; - for(int j=0; jderef() ) delete geometries[j]; + if (!g->deref()) { + delete g; + } + for (int j=0; jderef()) { + delete geometries[j]; + } } delete [] geometries; - delete [] n_start; delete [] glist; - if( new_indexing ) { - if( local_start ) delete [] local_start; - if( reg_to_inscr ) delete [] reg_to_inscr; + delete [] n_start; + delete [] glist; + if (new_indexing) { + if (local_start) { + delete [] local_start; + } + if (reg_to_inscr) { + delete [] reg_to_inscr; + } } } void EGS_EnvelopeGeometry::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" base geometry = %s (type %s)\n",g->getName().c_str(), - g->getType().c_str()); + g->getType().c_str()); egsInformation(" inscribed geometries:\n"); - for(int j=0; jgetName().c_str(),geometries[j]->getType().c_str()); + for (int j=0; jgetName().c_str(),geometries[j]->getType().c_str()); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } void EGS_FastEnvelope::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" base geometry = %s (type %s)\n",g->getName().c_str(), - g->getType().c_str()); + g->getType().c_str()); egsInformation(" inscribed geometries:\n"); - for(int j=0; jgetName().c_str(),geometries[j]->getType().c_str()); + for (int j=0; jgetName().c_str(),geometries[j]->getType().c_str()); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } @@ -259,182 +316,213 @@ static char EGS_ENVELOPEG_LOCAL eeg_keyword3[] = "inscribed geometries"; extern "C" { -EGS_ENVELOPEG_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning(eeg_message1,eeg_message2); - return 0; - } - // - // *** new indexing style - // - int indexing = 0; - input->getInput("new indexing style",indexing); - // - // *** Base geometry - // - EGS_Input *i = input->takeInputItem(eeg_keyword1); - if( !i ) { - egsWarning(eeg_message1,eeg_message3); return 0; - } - EGS_Input *ig = i->takeInputItem(eeg_keyword2); - EGS_BaseGeometry *g; - if( ig ) { // defined inline - g = EGS_BaseGeometry::createSingleGeometry(ig); - delete ig; - if( !g ) { - egsWarning(eeg_message1,eeg_message4); - delete i; return 0; + EGS_ENVELOPEG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning(eeg_message1,eeg_message2); + return 0; } - } - else { // defined via a name of a previously defined geometry - string bgname; - int err = i->getInput(eeg_keyword1,bgname); - delete i; - if( err ) { - egsWarning(eeg_message1,eeg_message5); return 0; + // + // *** new indexing style + // + int indexing = 0; + input->getInput("new indexing style",indexing); + // + // *** Base geometry + // + EGS_Input *i = input->takeInputItem(eeg_keyword1); + if (!i) { + egsWarning(eeg_message1,eeg_message3); + return 0; } - g = EGS_BaseGeometry::getGeometry(bgname); - if( !g ) { - egsWarning(eeg_message6,bgname.c_str()); return 0; + EGS_Input *ig = i->takeInputItem(eeg_keyword2); + EGS_BaseGeometry *g; + if (ig) { // defined inline + g = EGS_BaseGeometry::createSingleGeometry(ig); + delete ig; + if (!g) { + egsWarning(eeg_message1,eeg_message4); + delete i; + return 0; + } } - } - vector fgeoms; - EGS_Input *ix; - while( (ix = input->takeInputItem("inscribe in regions")) != 0 ) { - vector values; - ix->getInput("inscribe in regions",values); - if( values.size() < 2 ) egsWarning("createGeometry(envelope geometry):" - " %d inputs for 'inscribe in regions'? 2 or more are needed\n",values.size()); - else { - EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(values[0]); - if( !gj ) egsWarning(eeg_message6,values[0].c_str()); + else { // defined via a name of a previously defined geometry + string bgname; + int err = i->getInput(eeg_keyword1,bgname); + delete i; + if (err) { + egsWarning(eeg_message1,eeg_message5); + return 0; + } + g = EGS_BaseGeometry::getGeometry(bgname); + if (!g) { + egsWarning(eeg_message6,bgname.c_str()); + return 0; + } + } + vector fgeoms; + EGS_Input *ix; + while ((ix = input->takeInputItem("inscribe in regions")) != 0) { + vector values; + ix->getInput("inscribe in regions",values); + if (values.size() < 2) egsWarning("createGeometry(envelope geometry):" + " %d inputs for 'inscribe in regions'? 2 or more are needed\n",values.size()); else { - EnvelopeAux *aux = new EnvelopeAux; - aux->g = gj; - aux->nreg = values.size()-1; - aux->regs = new int [aux->nreg]; - for(int j=0; jnreg; j++) - aux->regs[j] = atoi(values[j+1].c_str()); - fgeoms.push_back(aux); + EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(values[0]); + if (!gj) { + egsWarning(eeg_message6,values[0].c_str()); + } + else { + EnvelopeAux *aux = new EnvelopeAux; + aux->g = gj; + aux->nreg = values.size()-1; + aux->regs = new int [aux->nreg]; + for (int j=0; jnreg; j++) { + aux->regs[j] = atoi(values[j+1].c_str()); + } + fgeoms.push_back(aux); + } } + delete ix; } - delete ix; - } - if( fgeoms.size() > 0 ) { - EGS_BaseGeometry *result = new EGS_FastEnvelope(g,fgeoms,"",indexing); - result->setName(input); - for(int j=0; jtakeInputItem(eeg_keyword3); - vector geoms; - if( !i ) { - if( fgeoms.size() ) egsWarning(eeg_message1,eeg_message7); - } - else { - // first try for inscribed geometries defined inline - while( (ig = i->takeInputItem(eeg_keyword2)) != 0 ) { - EGS_BaseGeometry *gj = EGS_BaseGeometry::createSingleGeometry(ig); - delete ig; - if( !gj ) egsWarning(eeg_message1,eeg_message8); - else geoms.push_back(gj); + if (fgeoms.size() > 0) { + EGS_BaseGeometry *result = new EGS_FastEnvelope(g,fgeoms,"",indexing); + result->setName(input); + for (int j=0; j igeoms; - int err = i->getInput(eeg_keyword3,igeoms); - if( err || !igeoms.size() ) + + // + // *** Inscribed geometries + // + i = input->takeInputItem(eeg_keyword3); + vector geoms; + if (!i) { + if (fgeoms.size()) { egsWarning(eeg_message1,eeg_message7); - else { - for(unsigned int j=0; jtakeInputItem(eeg_keyword2)) != 0) { + EGS_BaseGeometry *gj = EGS_BaseGeometry::createSingleGeometry(ig); + delete ig; + if (!gj) { + egsWarning(eeg_message1,eeg_message8); + } + else { + geoms.push_back(gj); } } + // if geoms.size() is 0, check if inscribed geometries are defined + // via names of previously defined geometries. + if (!geoms.size()) { + vector igeoms; + int err = i->getInput(eeg_keyword3,igeoms); + if (err || !igeoms.size()) { + egsWarning(eeg_message1,eeg_message7); + } + else { + for (unsigned int j=0; jsetName(input); + result->setLabels(input); + return result; + } - /* - EGS_BaseGeometry *result = fgeoms.size() ? - new EGS_EnvelopeGeometry(g,fgeoms,geoms) : - new EGS_EnvelopeGeometry(g,geoms); - */ - EGS_BaseGeometry *result = new EGS_EnvelopeGeometry(g,geoms,"",indexing); - result->setName(input); - result->setLabels(input); - return result; -} + void EGS_EnvelopeGeometry::getLabelRegions(const string &str, vector ®s) { -void EGS_EnvelopeGeometry::getLabelRegions (const string &str, vector ®s) { + // label defined in the envelope geometry + g->getLabelRegions(str, regs); - // label defined in the envelope geometry - g->getLabelRegions(str, regs); + // label defined in the inscribed geometries + vector gregs; + int shift=0; + for (int i=0; i gregs; - int shift=0; - for (int i=0; igetLabelRegions(str, gregs); + } - // add regions from set geometries - gregs.clear(); - if (geometries[i]) geometries[i]->getLabelRegions(str, gregs); + // shift region numbers according to indexing style + if (new_indexing) { + shift = local_start[i]; + } + else { + shift = nbase+i*nmax; + } + for (int j=0; j ®s) { -} + // label defined in the envelope geometry + g->getLabelRegions(str, regs); -void EGS_FastEnvelope::getLabelRegions (const string &str, vector ®s) { + // label defined in the inscribed geometries + vector gregs; + int shift=0; + for (int i=0; igetLabelRegions(str, regs); + // add regions from set geometries + gregs.clear(); + if (geometries[i]) { + geometries[i]->getLabelRegions(str, gregs); + } - // label defined in the inscribed geometries - vector gregs; - int shift=0; - for (int i=0; igetLabelRegions(str, gregs); + // add regions to the list + regs.insert(regs.end(), gregs.begin(), gregs.end()); - // shift region numbers according to indexing style - if (new_indexing) shift = local_start[i]; - else shift = nmax; - for (int j=0; j &geoms, const string &Name = "", - bool newindexing=false); - - ~EGS_EnvelopeGeometry(); - - bool isRealRegion(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return false; - if( ireg < nbase ) return g->isRealRegion(ireg); - int jg, ilocal; - if( new_indexing ) { - jg = reg_to_inscr[ireg-nbase]; ilocal = ireg - local_start[jg]; - } - else { - jg = (ireg - nbase)/nmax; ilocal = ireg - nbase - jg*nmax; - } - return geometries[jg]->isRealRegion(ilocal); - }; - - bool isInside(const EGS_Vector &x) { - return g->isInside(x); - }; - - int isWhere(const EGS_Vector &x) { - int ireg = g->isWhere(x); - if( ireg < 0 ) return ireg; - for(int j=0; jisWhere(x); - if( i >= 0 ) return new_indexing ? local_start[j] + i : - nbase + nmax*j + i; - } - return ireg; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int medium(int ireg) const { - if( ireg < nbase ) return g->medium(ireg); - int jg, ilocal; - if( new_indexing ) { - jg = reg_to_inscr[ireg-nbase]; ilocal = ireg - local_start[jg]; - } - else { - jg = (ireg - nbase)/nmax; ilocal = ireg - nbase - jg*nmax; - } - return geometries[jg]->medium(ilocal); - }; - - int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { - if( n < 1 ) return -1; - int ifirst = 0; EGS_Float t, ttot = 0; EGS_Vector x(X); int imed; - if( ireg < 0 ) { - t = 1e30; ireg = howfar(ireg,x,u,t,&imed); - if( ireg < 0 ) return 0; - isections[0].t = t; isections[0].rhof = 1; - isections[0].ireg = -1; isections[0].imed = -1; - ttot = t; ++ifirst; x += u*t; - } - else imed = medium(ireg); - - - int j = ifirst; int ij = -1, ig; - while(1) { - if( ireg >= nbase ) { - if( new_indexing ) { - ig = reg_to_inscr[ireg-nbase]; - ij = ireg - local_start[ig]; - } - else { - ig = (ireg - nbase)/nmax; ij = ireg - nbase - ig*nmax; - } - } - isections[j].imed = imed; isections[j].ireg = ireg; - isections[j].rhof = getRelativeRho(ireg); - if( ireg < nbase ) {// in one of the regions of the base geometry - t = 1e30; - int ibase = g->howfar(ireg,x,u,t,&imed); - ij = -1, ig; - for(int i=0; ihowfar(-1,x,u,t,&imed); - if( ireg_i >= 0 ) { - ij = ireg_i; ig = i; - } - } - ttot += t; isections[j++].t = ttot; - if( ij < 0 ) ireg = ibase; - else ireg = new_indexing ? local_start[ig] + ij : - nbase + ig*nmax + ij; - if( ireg < 0 ) return j; - if( j >= n ) return -1; - x += u*t; - } - else { - int iadd = new_indexing ? local_start[ig] : nbase + ig*nmax; - int nsec = geometries[ig]->computeIntersections(ij,n-j, - x,u,&isections[j]); - int nm = nsec >= 0 ? nsec+j : n; - for(int i=j; i= n ) return -1; - t = isections[j-1].t - ttot; - x += u*t; ttot = isections[j-1].t; - ireg = g->isWhere(x); - if( ireg < 0 ) return j; - imed = g->medium(ireg); - } - } - return -1; - } - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - EGS_Float d; - if( ireg < nbase ) d = g->howfarToOutside(ireg,x,u); - else if( g->regions() == 1 ) d = g->howfarToOutside(0,x,u); - else { - int ir = g->isWhere(x); - d = g->howfarToOutside(ir,x,u); - } - return d; - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { - if( ireg >= 0 ) { - // inside. - if( ireg < nbase ) { - // in one of the regions of the base geometry - // check if we hit a boundary in the base geometry. - // if we do, newmed and normal get set accordingly. - int ibase = g->howfar(ireg,x,u,t,newmed,normal); - int ij = -1, jg; - // check if we will enter any of the inscribed geometries - // before entering a new region in the base geometry. - for(int j=0; jhowfar(-1,x,u,t,newmed,normal); - if( ireg_j >= 0 ) { - // we do. remember the inscribed geometry index - // and local region - ij = ireg_j; jg = j; - } - } - if( ij < 0 ) return ibase; - // ij<0 implies that we have not hit any of the - // inscribed geometries => return the base geometry index. - // ij>=0 implies that we entered inscribed geometry - // jg in its local region ij. - return new_indexing ? local_start[jg] + ij : - nbase + jg*nmax + ij; - } - // if here, we are in an inscribed geometry. - // calculate its index (jg) and its local region (ilocal). - int jg, ilocal; - if( new_indexing ) { - jg = reg_to_inscr[ireg-nbase]; ilocal = ireg-local_start[jg]; - } - else { - jg = (ireg - nbase)/nmax; ilocal = ireg - nbase - jg*nmax; - } - // and then check if we will hit a boundary in this geometry. - int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal); - if( inew >= 0 ) return new_indexing ? local_start[jg] + inew : - nbase + jg*nmax + inew; - // inew >= 0 implies that we either stay in the same - // region (inew=ilocal) or we entered a new region - // (inew!=ilocal), which is still inside the inscribed geometry - // inew<0 implies that we have exited the inscribed geometry - // => check to see in which base geometry region we are. - inew = g->isWhere(x+u*t); - if( inew >= 0 && newmed ) *newmed = g->medium(inew); - return inew; - } - // if here, we are outside the base geometry. - // check to see if we will enter. - int ienter = g->howfar(ireg,x,u,t,newmed,normal); - if( ienter >= 0 ) { - // yes, we do. see if we are already inside of one of the - // inscribed geometries. - for(int j=0; jisWhere(x+u*t); - if( i >= 0 ) { - // yes, we are. - if( newmed ) *newmed = geometries[j]->medium(i); - return new_indexing ? local_start[j] + i : - nbase + nmax*j + i; - } - } - } - return ienter; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - EGS_Float tmin; - if( ireg < nbase ) { // in one of the regions of the base geom. - tmin = g->hownear(ireg,x); - for(int j=0; jhownear(-1,x); - if( tj < tmin ) { - tmin = tj; - if( tmin <= 0 ) return tmin; - } - } - return tmin; - } - int jg, ilocal; - if( new_indexing ) { - jg = reg_to_inscr[ireg-nbase]; ilocal = ireg-local_start[jg]; - } - else { - jg = (ireg - nbase)/nmax; ilocal = ireg - nbase - jg*nmax; - } - return geometries[jg]->hownear(ilocal,x); - } - return g->hownear(ireg,x); - }; - - int getMaxStep() const { - int nstep = g->getMaxStep(); - for(int j=0; jgetMaxStep(); - return nstep+n_in; - }; - - bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( ireg >= 0 && ireg < nreg ) { - if( ireg < nbase ) return g->hasBooleanProperty(ireg,prop); - int jg = (ireg - nbase)/nmax; int ilocal = ireg - nbase - jg*nmax; - return geometries[jg]->hasBooleanProperty(ilocal,prop); - } - return false; - }; - void setBooleanProperty(EGS_BPType) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int) { - setPropertyError("addBooleanProperty()"); - }; - void setBooleanProperty(EGS_BPType,int,int,int step=1) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int,int,int,int step=1) { - setPropertyError("addBooleanProperty()"); - }; - - const string &getType() const { return type; }; - - void printInfo() const; - - void setRelativeRho(int start, int end, EGS_Float rho); - void setRelativeRho(EGS_Input *); - EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return 1; - if( ireg < nbase ) return g->getRelativeRho(ireg); - int jg = (ireg - nbase)/nmax; - return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax); - }; - - virtual void getLabelRegions (const string &str, vector ®s); + EGS_EnvelopeGeometry(EGS_BaseGeometry *G, + const vector &geoms, const string &Name = "", + bool newindexing=false); + + ~EGS_EnvelopeGeometry(); + + bool isRealRegion(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return false; + } + if (ireg < nbase) { + return g->isRealRegion(ireg); + } + int jg, ilocal; + if (new_indexing) { + jg = reg_to_inscr[ireg-nbase]; + ilocal = ireg - local_start[jg]; + } + else { + jg = (ireg - nbase)/nmax; + ilocal = ireg - nbase - jg*nmax; + } + return geometries[jg]->isRealRegion(ilocal); + }; + + bool isInside(const EGS_Vector &x) { + return g->isInside(x); + }; + + int isWhere(const EGS_Vector &x) { + int ireg = g->isWhere(x); + if (ireg < 0) { + return ireg; + } + for (int j=0; jisWhere(x); + if (i >= 0) return new_indexing ? local_start[j] + i : + nbase + nmax*j + i; + } + return ireg; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int medium(int ireg) const { + if (ireg < nbase) { + return g->medium(ireg); + } + int jg, ilocal; + if (new_indexing) { + jg = reg_to_inscr[ireg-nbase]; + ilocal = ireg - local_start[jg]; + } + else { + jg = (ireg - nbase)/nmax; + ilocal = ireg - nbase - jg*nmax; + } + return geometries[jg]->medium(ilocal); + }; + + int computeIntersections(int ireg, int n, const EGS_Vector &X, + const EGS_Vector &u, EGS_GeometryIntersections *isections) { + if (n < 1) { + return -1; + } + int ifirst = 0; + EGS_Float t, ttot = 0; + EGS_Vector x(X); + int imed; + if (ireg < 0) { + t = 1e30; + ireg = howfar(ireg,x,u,t,&imed); + if (ireg < 0) { + return 0; + } + isections[0].t = t; + isections[0].rhof = 1; + isections[0].ireg = -1; + isections[0].imed = -1; + ttot = t; + ++ifirst; + x += u*t; + } + else { + imed = medium(ireg); + } + + + int j = ifirst; + int ij = -1, ig; + while (1) { + if (ireg >= nbase) { + if (new_indexing) { + ig = reg_to_inscr[ireg-nbase]; + ij = ireg - local_start[ig]; + } + else { + ig = (ireg - nbase)/nmax; + ij = ireg - nbase - ig*nmax; + } + } + isections[j].imed = imed; + isections[j].ireg = ireg; + isections[j].rhof = getRelativeRho(ireg); + if (ireg < nbase) { // in one of the regions of the base geometry + t = 1e30; + int ibase = g->howfar(ireg,x,u,t,&imed); + ij = -1, ig; + for (int i=0; ihowfar(-1,x,u,t,&imed); + if (ireg_i >= 0) { + ij = ireg_i; + ig = i; + } + } + ttot += t; + isections[j++].t = ttot; + if (ij < 0) { + ireg = ibase; + } + else ireg = new_indexing ? local_start[ig] + ij : + nbase + ig*nmax + ij; + if (ireg < 0) { + return j; + } + if (j >= n) { + return -1; + } + x += u*t; + } + else { + int iadd = new_indexing ? local_start[ig] : nbase + ig*nmax; + int nsec = geometries[ig]->computeIntersections(ij,n-j, + x,u,&isections[j]); + int nm = nsec >= 0 ? nsec+j : n; + for (int i=j; i= n) { + return -1; + } + t = isections[j-1].t - ttot; + x += u*t; + ttot = isections[j-1].t; + ireg = g->isWhere(x); + if (ireg < 0) { + return j; + } + imed = g->medium(ireg); + } + } + return -1; + } + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + EGS_Float d; + if (ireg < nbase) { + d = g->howfarToOutside(ireg,x,u); + } + else if (g->regions() == 1) { + d = g->howfarToOutside(0,x,u); + } + else { + int ir = g->isWhere(x); + d = g->howfarToOutside(ir,x,u); + } + return d; + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + if (ireg >= 0) { + // inside. + if (ireg < nbase) { + // in one of the regions of the base geometry + // check if we hit a boundary in the base geometry. + // if we do, newmed and normal get set accordingly. + int ibase = g->howfar(ireg,x,u,t,newmed,normal); + int ij = -1, jg; + // check if we will enter any of the inscribed geometries + // before entering a new region in the base geometry. + for (int j=0; jhowfar(-1,x,u,t,newmed,normal); + if (ireg_j >= 0) { + // we do. remember the inscribed geometry index + // and local region + ij = ireg_j; + jg = j; + } + } + if (ij < 0) { + return ibase; + } + // ij<0 implies that we have not hit any of the + // inscribed geometries => return the base geometry index. + // ij>=0 implies that we entered inscribed geometry + // jg in its local region ij. + return new_indexing ? local_start[jg] + ij : + nbase + jg*nmax + ij; + } + // if here, we are in an inscribed geometry. + // calculate its index (jg) and its local region (ilocal). + int jg, ilocal; + if (new_indexing) { + jg = reg_to_inscr[ireg-nbase]; + ilocal = ireg-local_start[jg]; + } + else { + jg = (ireg - nbase)/nmax; + ilocal = ireg - nbase - jg*nmax; + } + // and then check if we will hit a boundary in this geometry. + int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal); + if (inew >= 0) return new_indexing ? local_start[jg] + inew : + nbase + jg*nmax + inew; + // inew >= 0 implies that we either stay in the same + // region (inew=ilocal) or we entered a new region + // (inew!=ilocal), which is still inside the inscribed geometry + // inew<0 implies that we have exited the inscribed geometry + // => check to see in which base geometry region we are. + inew = g->isWhere(x+u*t); + if (inew >= 0 && newmed) { + *newmed = g->medium(inew); + } + return inew; + } + // if here, we are outside the base geometry. + // check to see if we will enter. + int ienter = g->howfar(ireg,x,u,t,newmed,normal); + if (ienter >= 0) { + // yes, we do. see if we are already inside of one of the + // inscribed geometries. + for (int j=0; jisWhere(x+u*t); + if (i >= 0) { + // yes, we are. + if (newmed) { + *newmed = geometries[j]->medium(i); + } + return new_indexing ? local_start[j] + i : + nbase + nmax*j + i; + } + } + } + return ienter; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + EGS_Float tmin; + if (ireg < nbase) { // in one of the regions of the base geom. + tmin = g->hownear(ireg,x); + for (int j=0; jhownear(-1,x); + if (tj < tmin) { + tmin = tj; + if (tmin <= 0) { + return tmin; + } + } + } + return tmin; + } + int jg, ilocal; + if (new_indexing) { + jg = reg_to_inscr[ireg-nbase]; + ilocal = ireg-local_start[jg]; + } + else { + jg = (ireg - nbase)/nmax; + ilocal = ireg - nbase - jg*nmax; + } + return geometries[jg]->hownear(ilocal,x); + } + return g->hownear(ireg,x); + }; + + int getMaxStep() const { + int nstep = g->getMaxStep(); + for (int j=0; jgetMaxStep(); + } + return nstep+n_in; + }; + + bool hasBooleanProperty(int ireg, EGS_BPType prop) const { + if (ireg >= 0 && ireg < nreg) { + if (ireg < nbase) { + return g->hasBooleanProperty(ireg,prop); + } + int jg = (ireg - nbase)/nmax; + int ilocal = ireg - nbase - jg*nmax; + return geometries[jg]->hasBooleanProperty(ilocal,prop); + } + return false; + }; + void setBooleanProperty(EGS_BPType) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int) { + setPropertyError("addBooleanProperty()"); + }; + void setBooleanProperty(EGS_BPType,int,int,int step=1) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int,int,int,int step=1) { + setPropertyError("addBooleanProperty()"); + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + void setRelativeRho(int start, int end, EGS_Float rho); + void setRelativeRho(EGS_Input *); + EGS_Float getRelativeRho(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return 1; + } + if (ireg < nbase) { + return g->getRelativeRho(ireg); + } + int jg = (ireg - nbase)/nmax; + return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax); + }; + + virtual void getLabelRegions(const string &str, vector ®s); protected: - EGS_BaseGeometry *g; //!< The envelope geometry - EGS_BaseGeometry **geometries; //!< The inscribed geometries - int n_in; //!< Number of inscribed geometries - int nbase, //!< Number of regions in the base geometry - nmax; /*!< Max. number of regions in any inscribed + EGS_BaseGeometry *g; //!< The envelope geometry + EGS_BaseGeometry **geometries; //!< The inscribed geometries + int n_in; //!< Number of inscribed geometries + int nbase, //!< Number of regions in the base geometry + nmax; /*!< Max. number of regions in any inscribed geometry */ - static string type; //!< Geometry type + static string type; //!< Geometry type - bool new_indexing; //!< If true, use new indexing style - int* reg_to_inscr; //!< Region to inscribed geometry conversion - int* local_start; //!< First region for each inscribed geometry + bool new_indexing; //!< If true, use new indexing style + int *reg_to_inscr; //!< Region to inscribed geometry conversion + int *local_start; //!< First region for each inscribed geometry - /*! \brief Don't set media for an envelope geometry + /*! \brief Don't set media for an envelope geometry - This function is re-implemented to warn the user to not set media - in the envelope geometry. Instead, media should be set for the envelope - and in the inscribed geometries. - */ - void setMedia(EGS_Input *,int,const int *); + This function is re-implemented to warn the user to not set media + in the envelope geometry. Instead, media should be set for the envelope + and in the inscribed geometries. + */ + void setMedia(EGS_Input *,int,const int *); private: - void setPropertyError(const char *funcname) { - egsFatal("EGS_EnvelopeGeometry::%s: don't use this method\n Define " - "properties in the constituent geometries instead\n", - funcname); - }; + void setPropertyError(const char *funcname) { + egsFatal("EGS_EnvelopeGeometry::%s: don't use this method\n Define " + "properties in the constituent geometries instead\n", + funcname); + }; }; @@ -494,295 +570,376 @@ class EGS_ENVELOPEG_EXPORT EGS_FastEnvelope : public EGS_BaseGeometry { public: - EGS_FastEnvelope(EGS_BaseGeometry *G, - const vector &fgeoms, const string &Name = "", - int newindexing=false); - - ~EGS_FastEnvelope(); - - bool isRealRegion(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return false; - if( ireg < nbase ) return g->isRealRegion(ireg); - int jg, ilocal; - if( new_indexing ) { - jg = reg_to_inscr[ireg-nbase]; ilocal = ireg - local_start[jg]; - } - else { - jg = (ireg - nbase)/nmax; ilocal = ireg - nbase - jg*nmax; - } - return geometries[jg]->isRealRegion(ilocal); - }; - - bool isInside(const EGS_Vector &x) { - return g->isInside(x); - }; - - int isWhere(const EGS_Vector &x) { - int ireg = g->isWhere(x); - if( ireg < 0 || n_start[ireg] < 0 ) return ireg; - for(int jj=n_start[ireg]; jjisWhere(x); - if( i >= 0 ) return nbase + nmax*j + i; - } - return ireg; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int medium(int ireg) const { - if( ireg < nbase ) return g->medium(ireg); - int jg = (ireg - nbase)/nmax; int ilocal = ireg - nbase - jg*nmax; - return geometries[jg]->medium(ilocal); - }; - - int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { - if( n < 1 ) return -1; - int ifirst = 0; EGS_Float t, ttot = 0; EGS_Vector x(X); int imed; - //egsInformation("computeIntersections: ireg=%d x=(%g,%g,%g) " - // "u=(%g,%g,%g)\n",ireg,x.x,x.y,x.z,u.x,u.y,u.z); - if( ireg < 0 ) { - t = 1e30; ireg = howfar(ireg,x,u,t,&imed); - if( ireg < 0 ) return 0; - isections[0].t = t; isections[0].rhof = 1; - isections[0].ireg = -1; isections[0].imed = -1; - ttot = t; ++ifirst; x += u*t; - //egsInformation("entered after t=%g in ireg=%d at x=(%g,%g,%g)\n", - // t,ireg,x.x,x.y,x.z); - } - else imed = medium(ireg); - - - int j = ifirst; int ij = -1, ig; - while(1) { - //egsInformation("in loop: j=%d ireg=%d imed=%d x=(%g,%g,%g)\n", - // j,ireg,imed,x.x,x.y,x.z); - if( ireg >= nbase ) { - ig = (ireg - nbase)/nmax; ij = ireg - nbase - ig*nmax; - } - isections[j].imed = imed; isections[j].ireg = ireg; - isections[j].rhof = getRelativeRho(ireg); - if( ireg < nbase ) {// in one of the regions of the base geometry - t = 1e30; - int ibase = g->howfar(ireg,x,u,t,&imed); - //egsInformation("In base geometry: t=%g inew=%d\n",t,ibase); - ij = -1, ig; - for(int ii=n_start[ireg]; iihowfar(-1,x,u,t,&imed); - if( ireg_i >= 0 ) { - ij = ireg_i; ig = i; - } - } - ttot += t; isections[j++].t = ttot; - //egsInformation("after inscribed loop: t=%g ij=%d ig=%d" - // " ttot=%g\n",t,ij,ig,ttot); - if( ij < 0 ) ireg = ibase; - else ireg = nbase + ig*nmax + ij; - if( ireg < 0 ) return j; - if( j >= n ) return -1; - x += u*t; - } - else { - int iadd = nbase + ig*nmax; - int nsec = geometries[ig]->computeIntersections(ij,n-j, - x,u,&isections[j]); - //egsInformation("In inscribed %d: got %d intersections\n",ig, - // nsec); - int nm = nsec >= 0 ? nsec+j : n; - for(int i=j; i= n ) return -1; - t = isections[j-1].t - ttot; - x += u*t; ttot = isections[j-1].t; - ireg = g->isWhere(x); - //egsInformation("new region: %d\n",ireg); - if( ireg < 0 ) return j; - imed = g->medium(ireg); - } - } - return -1; - } - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - EGS_Float d; - if( ireg < nbase ) d = g->howfarToOutside(ireg,x,u); - else if( g->regions() == 1 ) d = g->howfarToOutside(0,x,u); - else { - int ir = g->isWhere(x); - d = g->howfarToOutside(ir,x,u); - } - return d; - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { - if( ireg >= 0 ) { - // inside. - if( ireg < nbase ) { - // in one of the regions of the base geometry - // check if we hit a boundary in the base geometry. - // if we do, newmed and normal get set accordingly. - int ibase = g->howfar(ireg,x,u,t,newmed,normal); - int ij = -1, jg; - // check if we will enter any of the inscribed geometries - // before entering a new region in the base geometry. - for(int jj=n_start[ireg]; jjhowfar(-1,x,u,t,newmed,normal); - if( ireg_j >= 0 ) { - // we do. remember the inscribed geometry index - // and local region - ij = ireg_j; jg = j; - } - } - if( ij < 0 ) return ibase; - // ij<0 implies that we have not hit any of the - // inscribed geometries => return the base geometry index. - // ij>=0 implies that we entered inscribed geometry - // jg in its local region ij. - return nbase + jg*nmax + ij; - } - // if here, we are in an inscribed geometry. - // calculate its index (jg) and its local region (ilocal). - int jg = (ireg - nbase)/nmax; int ilocal = ireg - nbase - jg*nmax; - // and then check if we will hit a boundary in this geometry. - int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal); - if( inew >= 0 ) return nbase + jg*nmax + inew; - // inew >= 0 implies that we either stay in the same - // region (inew=ilocal) or we entered a new region - // (inew!=ilocal), which is still inside the inscribed geometry - // inew<0 implies that we have exited the inscribed geometry - // => check to see in which base geometry region we are. - inew = g->isWhere(x+u*t); - if( inew >= 0 && newmed ) *newmed = g->medium(inew); - return inew; - } - // if here, we are outside the base geometry. - // check to see if we will enter. - int ienter = g->howfar(ireg,x,u,t,newmed,normal); - if( ienter >= 0 ) { - // yes, we do. see if we are already inside of one of the - // inscribed geometries. - //if( n_start[ienter] < 0 ) return ienter; - for(int jj=n_start[ienter]; jjisWhere(x+u*t); - if( i >= 0 ) { - // yes, we are. - if( newmed ) *newmed = geometries[j]->medium(i); - return nbase + nmax*j + i; - } - } - } - return ienter; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - EGS_Float tmin; - if( ireg < nbase ) { // in one of the regions of the base geom. - tmin = g->hownear(ireg,x); - if( tmin <= 0 ) return tmin; - for(int jj=n_start[ireg]; jjhownear(-1,x); - if( tj < tmin ) { - tmin = tj; - if( tmin <= 0 ) return tmin; - } - } - return tmin; - } - int jg = (ireg - nbase)/nmax; int ilocal = ireg - nbase - jg*nmax; - return geometries[jg]->hownear(ilocal,x); - } - return g->hownear(ireg,x); - }; - - bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( ireg >= 0 && ireg < nreg ) { - if( ireg < nbase ) return g->hasBooleanProperty(ireg,prop); - int jg = (ireg - nbase)/nmax; int ilocal = ireg - nbase - jg*nmax; - return geometries[jg]->hasBooleanProperty(ilocal,prop); - } - return false; - }; - void setBooleanProperty(EGS_BPType) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int) { - setPropertyError("addBooleanProperty()"); - }; - void setBooleanProperty(EGS_BPType,int,int,int step=1) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int,int,int,int step=1) { - setPropertyError("addBooleanProperty()"); - }; - - int getMaxStep() const { - int nstep = g->getMaxStep(); - for(int j=0; jgetMaxStep(); - return nstep+n_in; - }; - - const string &getType() const { return type; }; - - void printInfo() const; - - void setRelativeRho(int start, int end, EGS_Float rho); - void setRelativeRho(EGS_Input *); - EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return 1; - if( ireg < nbase ) return g->getRelativeRho(ireg); - int jg = (ireg - nbase)/nmax; - return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax); - }; - - virtual void getLabelRegions (const string &str, vector ®s); + EGS_FastEnvelope(EGS_BaseGeometry *G, + const vector &fgeoms, const string &Name = "", + int newindexing=false); + + ~EGS_FastEnvelope(); + + bool isRealRegion(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return false; + } + if (ireg < nbase) { + return g->isRealRegion(ireg); + } + int jg, ilocal; + if (new_indexing) { + jg = reg_to_inscr[ireg-nbase]; + ilocal = ireg - local_start[jg]; + } + else { + jg = (ireg - nbase)/nmax; + ilocal = ireg - nbase - jg*nmax; + } + return geometries[jg]->isRealRegion(ilocal); + }; + + bool isInside(const EGS_Vector &x) { + return g->isInside(x); + }; + + int isWhere(const EGS_Vector &x) { + int ireg = g->isWhere(x); + if (ireg < 0 || n_start[ireg] < 0) { + return ireg; + } + for (int jj=n_start[ireg]; jjisWhere(x); + if (i >= 0) { + return nbase + nmax*j + i; + } + } + return ireg; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int medium(int ireg) const { + if (ireg < nbase) { + return g->medium(ireg); + } + int jg = (ireg - nbase)/nmax; + int ilocal = ireg - nbase - jg*nmax; + return geometries[jg]->medium(ilocal); + }; + + int computeIntersections(int ireg, int n, const EGS_Vector &X, + const EGS_Vector &u, EGS_GeometryIntersections *isections) { + if (n < 1) { + return -1; + } + int ifirst = 0; + EGS_Float t, ttot = 0; + EGS_Vector x(X); + int imed; + //egsInformation("computeIntersections: ireg=%d x=(%g,%g,%g) " + // "u=(%g,%g,%g)\n",ireg,x.x,x.y,x.z,u.x,u.y,u.z); + if (ireg < 0) { + t = 1e30; + ireg = howfar(ireg,x,u,t,&imed); + if (ireg < 0) { + return 0; + } + isections[0].t = t; + isections[0].rhof = 1; + isections[0].ireg = -1; + isections[0].imed = -1; + ttot = t; + ++ifirst; + x += u*t; + //egsInformation("entered after t=%g in ireg=%d at x=(%g,%g,%g)\n", + // t,ireg,x.x,x.y,x.z); + } + else { + imed = medium(ireg); + } + + + int j = ifirst; + int ij = -1, ig; + while (1) { + //egsInformation("in loop: j=%d ireg=%d imed=%d x=(%g,%g,%g)\n", + // j,ireg,imed,x.x,x.y,x.z); + if (ireg >= nbase) { + ig = (ireg - nbase)/nmax; + ij = ireg - nbase - ig*nmax; + } + isections[j].imed = imed; + isections[j].ireg = ireg; + isections[j].rhof = getRelativeRho(ireg); + if (ireg < nbase) { // in one of the regions of the base geometry + t = 1e30; + int ibase = g->howfar(ireg,x,u,t,&imed); + //egsInformation("In base geometry: t=%g inew=%d\n",t,ibase); + ij = -1, ig; + for (int ii=n_start[ireg]; iihowfar(-1,x,u,t,&imed); + if (ireg_i >= 0) { + ij = ireg_i; + ig = i; + } + } + ttot += t; + isections[j++].t = ttot; + //egsInformation("after inscribed loop: t=%g ij=%d ig=%d" + // " ttot=%g\n",t,ij,ig,ttot); + if (ij < 0) { + ireg = ibase; + } + else { + ireg = nbase + ig*nmax + ij; + } + if (ireg < 0) { + return j; + } + if (j >= n) { + return -1; + } + x += u*t; + } + else { + int iadd = nbase + ig*nmax; + int nsec = geometries[ig]->computeIntersections(ij,n-j, + x,u,&isections[j]); + //egsInformation("In inscribed %d: got %d intersections\n",ig, + // nsec); + int nm = nsec >= 0 ? nsec+j : n; + for (int i=j; i= n) { + return -1; + } + t = isections[j-1].t - ttot; + x += u*t; + ttot = isections[j-1].t; + ireg = g->isWhere(x); + //egsInformation("new region: %d\n",ireg); + if (ireg < 0) { + return j; + } + imed = g->medium(ireg); + } + } + return -1; + } + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + EGS_Float d; + if (ireg < nbase) { + d = g->howfarToOutside(ireg,x,u); + } + else if (g->regions() == 1) { + d = g->howfarToOutside(0,x,u); + } + else { + int ir = g->isWhere(x); + d = g->howfarToOutside(ir,x,u); + } + return d; + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + if (ireg >= 0) { + // inside. + if (ireg < nbase) { + // in one of the regions of the base geometry + // check if we hit a boundary in the base geometry. + // if we do, newmed and normal get set accordingly. + int ibase = g->howfar(ireg,x,u,t,newmed,normal); + int ij = -1, jg; + // check if we will enter any of the inscribed geometries + // before entering a new region in the base geometry. + for (int jj=n_start[ireg]; jjhowfar(-1,x,u,t,newmed,normal); + if (ireg_j >= 0) { + // we do. remember the inscribed geometry index + // and local region + ij = ireg_j; + jg = j; + } + } + if (ij < 0) { + return ibase; + } + // ij<0 implies that we have not hit any of the + // inscribed geometries => return the base geometry index. + // ij>=0 implies that we entered inscribed geometry + // jg in its local region ij. + return nbase + jg*nmax + ij; + } + // if here, we are in an inscribed geometry. + // calculate its index (jg) and its local region (ilocal). + int jg = (ireg - nbase)/nmax; + int ilocal = ireg - nbase - jg*nmax; + // and then check if we will hit a boundary in this geometry. + int inew = geometries[jg]->howfar(ilocal,x,u,t,newmed,normal); + if (inew >= 0) { + return nbase + jg*nmax + inew; + } + // inew >= 0 implies that we either stay in the same + // region (inew=ilocal) or we entered a new region + // (inew!=ilocal), which is still inside the inscribed geometry + // inew<0 implies that we have exited the inscribed geometry + // => check to see in which base geometry region we are. + inew = g->isWhere(x+u*t); + if (inew >= 0 && newmed) { + *newmed = g->medium(inew); + } + return inew; + } + // if here, we are outside the base geometry. + // check to see if we will enter. + int ienter = g->howfar(ireg,x,u,t,newmed,normal); + if (ienter >= 0) { + // yes, we do. see if we are already inside of one of the + // inscribed geometries. + //if( n_start[ienter] < 0 ) return ienter; + for (int jj=n_start[ienter]; jjisWhere(x+u*t); + if (i >= 0) { + // yes, we are. + if (newmed) { + *newmed = geometries[j]->medium(i); + } + return nbase + nmax*j + i; + } + } + } + return ienter; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + EGS_Float tmin; + if (ireg < nbase) { // in one of the regions of the base geom. + tmin = g->hownear(ireg,x); + if (tmin <= 0) { + return tmin; + } + for (int jj=n_start[ireg]; jjhownear(-1,x); + if (tj < tmin) { + tmin = tj; + if (tmin <= 0) { + return tmin; + } + } + } + return tmin; + } + int jg = (ireg - nbase)/nmax; + int ilocal = ireg - nbase - jg*nmax; + return geometries[jg]->hownear(ilocal,x); + } + return g->hownear(ireg,x); + }; + + bool hasBooleanProperty(int ireg, EGS_BPType prop) const { + if (ireg >= 0 && ireg < nreg) { + if (ireg < nbase) { + return g->hasBooleanProperty(ireg,prop); + } + int jg = (ireg - nbase)/nmax; + int ilocal = ireg - nbase - jg*nmax; + return geometries[jg]->hasBooleanProperty(ilocal,prop); + } + return false; + }; + void setBooleanProperty(EGS_BPType) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int) { + setPropertyError("addBooleanProperty()"); + }; + void setBooleanProperty(EGS_BPType,int,int,int step=1) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int,int,int,int step=1) { + setPropertyError("addBooleanProperty()"); + }; + + int getMaxStep() const { + int nstep = g->getMaxStep(); + for (int j=0; jgetMaxStep(); + } + return nstep+n_in; + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + void setRelativeRho(int start, int end, EGS_Float rho); + void setRelativeRho(EGS_Input *); + EGS_Float getRelativeRho(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return 1; + } + if (ireg < nbase) { + return g->getRelativeRho(ireg); + } + int jg = (ireg - nbase)/nmax; + return geometries[jg]->getRelativeRho(ireg - nbase - jg*nmax); + }; + + virtual void getLabelRegions(const string &str, vector ®s); protected: - EGS_BaseGeometry *g; //!< The envelope geometry - EGS_BaseGeometry **geometries; //!< The inscribed geometries - int n_in; //!< Number of inscribed geometries - int nbase, //!< Number of regions in the base geometry - nmax; /*!< Max. number of regions in any inscribed + EGS_BaseGeometry *g; //!< The envelope geometry + EGS_BaseGeometry **geometries; //!< The inscribed geometries + int n_in; //!< Number of inscribed geometries + int nbase, //!< Number of regions in the base geometry + nmax; /*!< Max. number of regions in any inscribed geometry */ - int *glist; - int *n_start; - static string type; //!< Geometry type + int *glist; + int *n_start; + static string type; //!< Geometry type - bool new_indexing; //!< If true, use new indexing style - int* reg_to_inscr; //!< Region to inscribed geometry conversion - int* local_start; //!< First region for each inscribed geometry + bool new_indexing; //!< If true, use new indexing style + int *reg_to_inscr; //!< Region to inscribed geometry conversion + int *local_start; //!< First region for each inscribed geometry - /*! \brief Don't set media for an envelope geometry + /*! \brief Don't set media for an envelope geometry - This function is re-implemented to warn the user to not set media - in the envelope geometry. Instead, media should be set for the envelope - and in the inscribed geometries. - */ - void setMedia(EGS_Input *,int,const int *); + This function is re-implemented to warn the user to not set media + in the envelope geometry. Instead, media should be set for the envelope + and in the inscribed geometries. + */ + void setMedia(EGS_Input *,int,const int *); private: - void setPropertyError(const char *funcname) { - egsFatal("EGS_FastEnvelope::%s: don't use this method\n Define " - "properties in the constituent geometries instead\n", - funcname); - }; + void setPropertyError(const char *funcname) { + egsFatal("EGS_FastEnvelope::%s: don't use this method\n Define " + "properties in the constituent geometries instead\n", + funcname); + }; }; diff --git a/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp index 40c6c5775..b95e56a38 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gstack/egs_stack_geometry.cpp @@ -42,39 +42,49 @@ string EGS_StackGeometry::type = "EGS_StackGeometry"; EGS_StackGeometry::EGS_StackGeometry(const vector &geoms, - EGS_Float Tol, const string &Name) : EGS_BaseGeometry(Name), eps(Tol) { - if( geoms.size() < 2 ) egsFatal("EGS_StackGeometry::EGS_StackGeometry: " - " less than 2 geometries is not mermitted\n"); + EGS_Float Tol, const string &Name) : EGS_BaseGeometry(Name), eps(Tol) { + if (geoms.size() < 2) egsFatal("EGS_StackGeometry::EGS_StackGeometry: " + " less than 2 geometries is not mermitted\n"); ng = geoms.size(); - g = new EGS_BaseGeometry* [ng]; nmax = 1; + g = new EGS_BaseGeometry* [ng]; + nmax = 1; has_rho_scaling = false; - for(int j=0; jref(); - int n = g[j]->regions(); if( n > nmax ) nmax = n; - if( !has_rho_scaling ) has_rho_scaling = g[j]->hasRhoScaling(); + for (int j=0; jref(); + int n = g[j]->regions(); + if (n > nmax) { + nmax = n; + } + if (!has_rho_scaling) { + has_rho_scaling = g[j]->hasRhoScaling(); + } } - nreg = ng*nmax; is_convex = false; + nreg = ng*nmax; + is_convex = false; } EGS_StackGeometry::~EGS_StackGeometry() { - for(int j=0; jderef() ) delete g[j]; + for (int j=0; jderef()) { + delete g[j]; + } delete [] g; } void EGS_StackGeometry::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" geometries:\n"); - for(int j=0; jgetName().c_str(),g[j]->getType().c_str()); + for (int j=0; jgetName().c_str(),g[j]->getType().c_str()); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } void EGS_StackGeometry::setMedia(EGS_Input *,int,const int *) { egsWarning("EGS_StackGeometry::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_StackGeometry::setRelativeRho(int start, int end, EGS_Float rho) { @@ -83,59 +93,62 @@ void EGS_StackGeometry::setRelativeRho(int start, int end, EGS_Float rho) { void EGS_StackGeometry::setRelativeRho(EGS_Input *) { egsWarning("EGS_StackGeometry::setRelativeRho(): don't use this method.\n" - " Use the setRelativeRho methods of the geometry objects that make up" - " this geometry\n"); + " Use the setRelativeRho methods of the geometry objects that make up" + " this geometry\n"); } extern "C" { -EGS_STACKG_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning("createGeometry(stack): null input?\n"); - return 0; - } - vector gnames; vector geoms; - int err = input->getInput("geometries",gnames); - if( err || gnames.size() < 2 ) { - egsWarning("createGeometry(stack): missing/wrong 'geometries' input\n"); - return 0; - } - for(unsigned int j=0; j gnames; + vector geoms; + int err = input->getInput("geometries",gnames); + if (err || gnames.size() < 2) { + egsWarning("createGeometry(stack): missing/wrong 'geometries' input\n"); + return 0; + } + for (unsigned int j=0; jgetInput("tolerance",tol); + EGS_BaseGeometry *result = new EGS_StackGeometry(geoms,tol); + result->setName(input); + result->setLabels(input); + return result; } - EGS_Float tol = 1e-4; - err = input->getInput("tolerance",tol); - EGS_BaseGeometry *result = new EGS_StackGeometry(geoms,tol); - result->setName(input); - result->setLabels(input); - return result; -} -void EGS_StackGeometry::getLabelRegions (const string &str, vector ®s) { + void EGS_StackGeometry::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // label defined in the stacked geometries - for (int i=0; igetLabelRegions(str, local_regs); - for (int j=0; jgetLabelRegions(str, local_regs); + for (int j=0; j= nreg ) return false; - int jg = ireg/nmax; int jl = ireg - jg*nmax; + if (ireg < 0 || ireg >= nreg) { + return false; + } + int jg = ireg/nmax; + int jl = ireg - jg*nmax; return g[jg]->isRealRegion(jl); }; bool isInside(const EGS_Vector &x) { - for(int j=0; jisInside(x) ) return true; + for (int j=0; jisInside(x)) { + return true; + } return false; }; int isWhere(const EGS_Vector &x) { - for(int j=0; jisWhere(x); - if( i >= 0 ) return nmax*j + i; + if (i >= 0) { + return nmax*j + i; + } } return -1; }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; int medium(int ireg) const { int j = ireg/nmax; @@ -147,54 +156,69 @@ class EGS_StackGeometry : public EGS_BaseGeometry { }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + if (ireg >= 0) { // inside the geometry. - int jg = ireg/nmax; int jl = ireg - jg*nmax; + int jg = ireg/nmax; + int jl = ireg - jg*nmax; // jg is the stack index, jl the local region index in jg. // see if we hit a boundary in jg. int inew = g[jg]->howfar(jl,x,u,t,newmed,normal); // inew>=0 implies that we either stay in the same local region // or enter a new region still inside of jg => simply calculate // the new gloabal region and return - if(inew >= 0) return jg*nmax + inew; + if (inew >= 0) { + return jg*nmax + inew; + } // inew < 0 implies that we have exited jg. // to prevent roundoff problems, we add eps to the path-length // to the boundary of jg. t += eps; - if( jg > 0 ) { + if (jg > 0) { // check if we enter the jg-1'th geometry in the stack. inew = g[jg-1]->howfar(-1,x,u,t,newmed,normal); - if( inew >= 0 ) return (jg-1)*nmax + inew; // yes, we do. + if (inew >= 0) { + return (jg-1)*nmax + inew; // yes, we do. + } } - if( jg < ng-1 ) { + if (jg < ng-1) { // check if we enter the jg+1'th geometry in the stack. inew = g[jg+1]->howfar(-1,x,u,t,newmed,normal); - if( inew >= 0 ) return (jg+1)*nmax + inew; // yes, we do + if (inew >= 0) { + return (jg+1)*nmax + inew; // yes, we do + } } // if here, we don't enter either of the "stack neighbours" // => we exit the geometry. - t -= eps; return -1; + t -= eps; + return -1; } int i1 = g[0]->howfar(-1,x,u,t,newmed,normal); int i2 = g[ng-1]->howfar(-1,x,u,t,newmed,normal); - if( i2 >= 0 ) return (ng-1)*nmax + i2; - if( i1 >= 0 ) return i1; + if (i2 >= 0) { + return (ng-1)*nmax + i2; + } + if (i1 >= 0) { + return i1; + } return -1; }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - int jg = ireg/nmax; return g[jg]->hownear(ireg-jg*nmax,x); + if (ireg >= 0) { + int jg = ireg/nmax; + return g[jg]->hownear(ireg-jg*nmax,x); } EGS_Float t1 = g[0]->hownear(-1,x); EGS_Float t2 = g[ng-1]->hownear(-1,x); - if( t2 < t1 ) return t2; + if (t2 < t1) { + return t2; + } return t1; }; bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( ireg >= 0 && ireg < nreg ) { + if (ireg >= 0 && ireg < nreg) { int jg = ireg/nmax; return g[jg]->hasBooleanProperty(ireg-jg*nmax,prop); } @@ -213,18 +237,23 @@ class EGS_StackGeometry : public EGS_BaseGeometry { setPropertError("addBooleanProperty()"); }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return 1; - int jg = ireg/nmax; return g[jg]->getRelativeRho(ireg-jg*nmax); + if (ireg < 0 || ireg >= nreg) { + return 1; + } + int jg = ireg/nmax; + return g[jg]->getRelativeRho(ireg-jg*nmax); }; void setRelativeRho(int start, int end, EGS_Float rho); void setRelativeRho(EGS_Input *); - virtual void getLabelRegions (const string &str, vector ®s); + virtual void getLabelRegions(const string &str, vector ®s); protected: @@ -242,7 +271,7 @@ class EGS_StackGeometry : public EGS_BaseGeometry { void setPropertError(const char *funcname) { egsFatal("EGS_StackGeometry::%s: don't use this method\n Define " - "properties in the constituent geometries instead\n"); + "properties in the constituent geometries instead\n"); }; diff --git a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp index 36a201e44..872afe94c 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.cpp @@ -40,77 +40,81 @@ #include "egs_functions.h" void EGS_TransformedGeometry::setMedia(EGS_Input *,int,const int *) { -egsWarning("EGS_TransformedGeometry::setMedia: don't use this method. Use the\n" -" setMedia() methods of the geometry objects that make up this geometry\n"); + egsWarning("EGS_TransformedGeometry::setMedia: don't use this method. Use the\n" + " setMedia() methods of the geometry objects that make up this geometry\n"); } -void EGS_TransformedGeometry::setRelativeRho(int start, int end, EGS_Float rho){ +void EGS_TransformedGeometry::setRelativeRho(int start, int end, EGS_Float rho) { setRelativeRho(0); } void EGS_TransformedGeometry::setRelativeRho(EGS_Input *) { egsWarning("EGS_TransformedGeometry::setRelativeRho(): don't use this " - "method. Use the \n setRelativeRho() methods of the underlying " - "geometry\n"); + "method. Use the \n setRelativeRho() methods of the underlying " + "geometry\n"); } extern "C" { -EGS_GTRANSFORMED_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - int error = 0; EGS_BaseGeometry *g = 0; - EGS_Input *ij = input->takeInputItem("geometry",false); - if( ij ) { - g = EGS_BaseGeometry::createSingleGeometry(ij); - delete ij; - if( !g ) { - egsWarning("createGeometry(gtransformed): got a null pointer" - " as a geometry?\n"); return 0; + EGS_GTRANSFORMED_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + int error = 0; + EGS_BaseGeometry *g = 0; + EGS_Input *ij = input->takeInputItem("geometry",false); + if (ij) { + g = EGS_BaseGeometry::createSingleGeometry(ij); + delete ij; + if (!g) { + egsWarning("createGeometry(gtransformed): got a null pointer" + " as a geometry?\n"); + return 0; + } } - } - if( !g ) { - string gname; - int err = input->getInput("my geometry",gname); - if( err ) { - egsWarning( - "createGeometry(gtransformed): my geometry must be defined\n" - " either inline or using 'my geometry = some_name'\n"); - return 0; + if (!g) { + string gname; + int err = input->getInput("my geometry",gname); + if (err) { + egsWarning( + "createGeometry(gtransformed): my geometry must be defined\n" + " either inline or using 'my geometry = some_name'\n"); + return 0; + } + g = EGS_BaseGeometry::getGeometry(gname); + if (!g) { + egsWarning("createGeometry(gtransformed): no geometry named %s" + " is defined\n",gname.c_str()); + return 0; + } } - g = EGS_BaseGeometry::getGeometry(gname); - if( !g ) { - egsWarning("createGeometry(gtransformed): no geometry named %s" - " is defined\n",gname.c_str()); return 0; + g->ref(); + EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); + EGS_BaseGeometry *result; + if (!t) { + egsWarning("createGeometry(gtransformed): null transformation." + " I hope you know what you are doing\n"); + result = new EGS_TransformedGeometry(g,EGS_AffineTransform()); } - } - g->ref(); - EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); - EGS_BaseGeometry *result; - if( !t ) { - egsWarning("createGeometry(gtransformed): null transformation." - " I hope you know what you are doing\n"); - result = new EGS_TransformedGeometry(g,EGS_AffineTransform()); - } else { - if( t->isI() ) egsWarning("createGeometry(gtransformed): " - "unity transformation. I hope you know what you are doing\n"); - result = new EGS_TransformedGeometry(g,*t); - delete t; - } - result->setName(input); - result->setLabels(input); - return result; + else { + if (t->isI()) egsWarning("createGeometry(gtransformed): " + "unity transformation. I hope you know what you are doing\n"); + result = new EGS_TransformedGeometry(g,*t); + delete t; + } + result->setName(input); + result->setLabels(input); + return result; -} + } -void EGS_TransformedGeometry::getLabelRegions (const string &str, vector ®s) { + void EGS_TransformedGeometry::getLabelRegions(const string &str, vector ®s) { - // label defined in the geometry being transformed - g->getLabelRegions(str, regs); + // label defined in the geometry being transformed + g->getLabelRegions(str, regs); - // label defined in self (transformation input block) - EGS_BaseGeometry::getLabelRegions(str, regs); + // label defined in self (transformation input block) + EGS_BaseGeometry::getLabelRegions(str, regs); -} + } } diff --git a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.h b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.h index dd67b122d..c8070fe3e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.h +++ b/HEN_HOUSE/egs++/geometry/egs_gtransformed/egs_gtransformed.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_GTRANSFORMED_DLL -#define EGS_GTRANSFORMED_EXPORT __declspec(dllexport) -#else -#define EGS_GTRANSFORMED_EXPORT __declspec(dllimport) -#endif -#define EGS_GTRANSFORMED_LOCAL + #ifdef BUILD_GTRANSFORMED_DLL + #define EGS_GTRANSFORMED_EXPORT __declspec(dllexport) + #else + #define EGS_GTRANSFORMED_EXPORT __declspec(dllimport) + #endif + #define EGS_GTRANSFORMED_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_GTRANSFORMED_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_GTRANSFORMED_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_GTRANSFORMED_EXPORT -#define EGS_GTRANSFORMED_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_GTRANSFORMED_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_GTRANSFORMED_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_GTRANSFORMED_EXPORT + #define EGS_GTRANSFORMED_LOCAL + #endif #endif @@ -99,7 +99,7 @@ Transformed geometries are used in the */ class EGS_GTRANSFORMED_EXPORT EGS_TransformedGeometry : - public EGS_BaseGeometry { + public EGS_BaseGeometry { protected: @@ -113,20 +113,29 @@ class EGS_GTRANSFORMED_EXPORT EGS_TransformedGeometry : transformed by \a t */ EGS_TransformedGeometry(EGS_BaseGeometry *G, const EGS_AffineTransform &t, - const string &Name = "") : EGS_BaseGeometry(Name), g(G), T(t) { - type = g->getType(); type += "T"; nreg = g->regions(); + const string &Name = "") : EGS_BaseGeometry(Name), g(G), T(t) { + type = g->getType(); + type += "T"; + nreg = g->regions(); is_convex = g->isConvex(); has_rho_scaling = g->hasRhoScaling(); }; - ~EGS_TransformedGeometry() { if( !g->deref() ) delete g; }; + ~EGS_TransformedGeometry() { + if (!g->deref()) { + delete g; + } + }; - void setTransformation(const EGS_AffineTransform &t) { T = t; }; + void setTransformation(const EGS_AffineTransform &t) { + T = t; + }; int computeIntersections(int ireg, int n, const EGS_Vector &x, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { + const EGS_Vector &u, EGS_GeometryIntersections *isections) { EGS_Vector xt(x), ut(u); - T.inverseTransform(xt); T.rotateInverse(ut); + T.inverseTransform(xt); + T.rotateInverse(ut); return g->computeIntersections(ireg,n,xt,ut,isections); //return g->computeIntersections(ireg,n,x*T,u*T.getRotation(),isections); }; @@ -134,41 +143,52 @@ class EGS_GTRANSFORMED_EXPORT EGS_TransformedGeometry : return g->isRealRegion(ireg); }; bool isInside(const EGS_Vector &x) { - EGS_Vector xt(x); T.inverseTransform(xt); + EGS_Vector xt(x); + T.inverseTransform(xt); return g->isInside(xt); //return g->isInside(x*T); }; int isWhere(const EGS_Vector &x) { - EGS_Vector xt(x); T.inverseTransform(xt); + EGS_Vector xt(x); + T.inverseTransform(xt); return g->isWhere(xt); //return g->isWhere(x*T); }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; - int medium(int ireg) const { return g->medium(ireg); }; + int medium(int ireg) const { + return g->medium(ireg); + }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { + const EGS_Vector &u) { return ireg >= 0 ? g->howfarToOutside(ireg,x*T,u*T.getRotation()) : 0; }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { EGS_Vector xt(x), ut(u); - T.inverseTransform(xt); T.rotateInverse(ut); + T.inverseTransform(xt); + T.rotateInverse(ut); int inew = g->howfar(ireg,xt,ut,t,newmed,normal); //int inew = g->howfar(ireg,x*T,u*T.getRotation(),t,newmed,normal); - if( inew != ireg && normal ) + if (inew != ireg && normal) { *normal = T.getRotation()*(*normal); + } return inew; }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - EGS_Vector xt(x); T.inverseTransform(xt); + EGS_Vector xt(x); + T.inverseTransform(xt); return g->hownear(ireg,xt); //return g->hownear(ireg,x*T); }; - int getMaxStep() const { return g->getMaxStep(); }; + int getMaxStep() const { + return g->getMaxStep(); + }; // Not sure about the following. // If I leave the implementation that way, all transformed copies of a @@ -192,7 +212,9 @@ class EGS_GTRANSFORMED_EXPORT EGS_TransformedGeometry : g->addBooleanProperty(bit,start,end,step); }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; EGS_Float getRelativeRho(int ireg) const { return g->getRelativeRho(ireg); @@ -201,7 +223,7 @@ class EGS_GTRANSFORMED_EXPORT EGS_TransformedGeometry : void setRelativeRho(EGS_Input *); - virtual void getLabelRegions (const string &str, vector ®s); + virtual void getLabelRegions(const string &str, vector ®s); protected: diff --git a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp index afb479cdf..8cb017527 100644 --- a/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_iplanes/egs_iplanes.cpp @@ -48,17 +48,28 @@ string EGS_IPlanes::type = "EGS_IPlanes"; string EGS_RadialRepeater::type = "EGS_RadialRepeater"; EGS_IPlanes::EGS_IPlanes(const EGS_Vector &Xo, const EGS_Vector &A, int np, - const EGS_Float *angles, const string &Name, bool degree) : + const EGS_Float *angles, const string &Name, bool degree) : EGS_BaseGeometry(Name), xo(Xo), axis(A) { nreg = 2*np; - a = new EGS_Vector[nreg]; d = new EGS_Float[nreg]; int j; + a = new EGS_Vector[nreg]; + d = new EGS_Float[nreg]; + int j; EGS_Float phi180 = M_PI; - if( degree ) phi180 = 180; + if (degree) { + phi180 = 180; + } EGS_RotationMatrix R(axis); - for(j=0; j= d[j-1] && aux < d[j] ) return j-1; + if (aux_old >= d[j-1] && aux < d[j]) { + return j-1; + } aux_old = aux; } return nreg-1; @@ -102,49 +124,70 @@ int EGS_IPlanes::isWhere(const EGS_Vector &x) { int EGS_IPlanes::inside(const EGS_Vector &x) { EGS_Float aux_old = a[0]*x; - for(int j=1; j= d[j-1] && aux < d[j] ) return j-1; + if (aux_old >= d[j-1] && aux < d[j]) { + return j-1; + } aux_old = aux; } return nreg-1; } int EGS_IPlanes::howfar(int ireg, const EGS_Vector &x, - const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal) { - if( ireg < 0 ) + const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal) { + if (ireg < 0) { egsFatal("EGS_IPlanes::howfar: ireg (%d) can not be negative\n",ireg); + } EGS_Float t1 = t, t2 = t; EGS_Float up = a[ireg]*u; int inew = ireg; - if( up < 0 ) { + if (up < 0) { t1 = (d[ireg] - a[ireg]*x)/up; - if( t1 <= t ) { - t = t1; inew = ireg-1; - if( inew < 0 ) inew = nreg-1; - if( newmed ) *newmed = medium(inew); - if( normal ) *normal = a[ireg]; + if (t1 <= t) { + t = t1; + inew = ireg-1; + if (inew < 0) { + inew = nreg-1; + } + if (newmed) { + *newmed = medium(inew); + } + if (normal) { + *normal = a[ireg]; + } } } int j = ireg+1; - if( j >= nreg ) j = 0; + if (j >= nreg) { + j = 0; + } up = a[j]*u; - if( up > 0 ) { + if (up > 0) { t2 = (d[j] - a[j]*x)/up; - if( t2 < t ) { - t = t2; inew = j; - if( newmed ) *newmed = medium(inew); - if( normal ) *normal = a[j]*(-1); + if (t2 < t) { + t = t2; + inew = j; + if (newmed) { + *newmed = medium(inew); + } + if (normal) { + *normal = a[j]*(-1); + } } } return inew; } EGS_Float EGS_IPlanes::hownear(int ireg, const EGS_Vector &x) { - if( ireg < 0 ) + if (ireg < 0) { egsFatal("EGS_IPlanes::hownear: ireg (%d) can not be negative\n",ireg); + } EGS_Float t1 = a[ireg]*x - d[ireg]; - int j = ireg+1; if( j >= nreg ) j = 0; + int j = ireg+1; + if (j >= nreg) { + j = 0; + } EGS_Float t2 = d[j] - a[j]*x; return min(t1,t2); } @@ -152,190 +195,221 @@ EGS_Float EGS_IPlanes::hownear(int ireg, const EGS_Vector &x) { void EGS_IPlanes::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" axis: Xo = (%g,%g,%g) a = (%g,%g,%g)\n",xo.x,xo.y,xo.z, - axis.x,axis.y,axis.z); + axis.x,axis.y,axis.z); egsInformation( - "\n=======================================================\n"); + "\n=======================================================\n"); } /***************************************************************************/ EGS_RadialRepeater::EGS_RadialRepeater(const EGS_Vector &Xo, - const EGS_Vector &A, int np, EGS_BaseGeometry *G, - EGS_Float first, const string &Name) : EGS_BaseGeometry(Name), g(G) { + const EGS_Vector &A, int np, EGS_BaseGeometry *G, + EGS_Float first, const string &Name) : EGS_BaseGeometry(Name), g(G) { EGS_Float dphi = 2*M_PI/np; iplanes = new EGS_IPlanes(Xo,A,np,first-dphi/2); //iplanes = new EGS_IPlanes(Xo,A,np,first); //iplanes = new EGS_IPlanes(Xo,A,np,(EGS_Float)0); - g->ref(); iplanes->ref(); - nrep = np; ng = g->regions(); nreg = nrep*ng + 1; + g->ref(); + iplanes->ref(); + nrep = np; + ng = g->regions(); + nreg = nrep*ng + 1; //EGS_Float dphi = 2*M_PI/np; R = new EGS_RotationMatrix [nrep]; EGS_RotationMatrix Ro(A); - for(int j=0; jderef() ) delete iplanes; - if( !g->deref() ) delete g; + if (!iplanes->deref()) { + delete iplanes; + } + if (!g->deref()) { + delete g; + } } void EGS_RadialRepeater::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation("%d uniformely rotated replicas of geometry %s with " - "phi_o=%g degrees\n",nrep,g->getName().c_str(), - phi_o*180./M_PI); + "phi_o=%g degrees\n",nrep,g->getName().c_str(), + phi_o*180./M_PI); EGS_Vector xo(iplanes->getAxisXo()), axis(iplanes->getAxisDirection()); egsInformation("Axis of rotation is xo=(%g,%g,%g) a=(%g,%g,%g)\n", - xo.x,xo.y,xo.z,axis.x,axis.y,axis.z); + xo.x,xo.y,xo.z,axis.x,axis.y,axis.z); const char *med_name = getMediumName(med); - if( med_name ) egsInformation("space is filled with %s\n",med_name); - else egsInformation("space is filled with vacuum\n"); + if (med_name) { + egsInformation("space is filled with %s\n",med_name); + } + else { + egsInformation("space is filled with vacuum\n"); + } egsInformation("Repeated geometry:\n"); g->printInfo(); } extern "C" { -EGS_IPLANES_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning("createGeometry(iplanes): null input?\n"); - return 0; - } - vector axis; - EGS_Vector xo, a(0,0,1); - int err = input->getInput("axis",axis); - if( !err && axis.size() == 6 ) { - xo = EGS_Vector(axis[0],axis[1],axis[2]); - a = EGS_Vector(axis[3],axis[4],axis[5]); - a.normalize(); - } else egsWarning("createGeometry(iplanes): wrong/missing axis input\n" - " using Xo=(0,0,0), a=(0,0,1)\n"); - string type; - err = input->getInput("type",type); - if( !err && (type == "EGS_RadialRepeater" || type == "repeater") ) { - int np; err = input->getInput("number of repetitions",np); - if( err || np < 2 ) { - egsWarning("createGeometry(iplanes): missing/wrong " - "'number of repetitions' input\n"); return 0; + EGS_IPLANES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning("createGeometry(iplanes): null input?\n"); + return 0; } - string gname; - err = input->getInput("repeated geometry",gname); - if( err ) { - egsWarning("createGeometry(iplanes): missing 'repeated geometry'" - " input\n"); return 0; + vector axis; + EGS_Vector xo, a(0,0,1); + int err = input->getInput("axis",axis); + if (!err && axis.size() == 6) { + xo = EGS_Vector(axis[0],axis[1],axis[2]); + a = EGS_Vector(axis[3],axis[4],axis[5]); + a.normalize(); } - EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(gname); - if( !g ) { - egsWarning("createGeometry(iplanes): no geometry named %s exists\n", - gname.c_str()); - return 0; + else egsWarning("createGeometry(iplanes): wrong/missing axis input\n" + " using Xo=(0,0,0), a=(0,0,1)\n"); + string type; + err = input->getInput("type",type); + if (!err && (type == "EGS_RadialRepeater" || type == "repeater")) { + int np; + err = input->getInput("number of repetitions",np); + if (err || np < 2) { + egsWarning("createGeometry(iplanes): missing/wrong " + "'number of repetitions' input\n"); + return 0; + } + string gname; + err = input->getInput("repeated geometry",gname); + if (err) { + egsWarning("createGeometry(iplanes): missing 'repeated geometry'" + " input\n"); + return 0; + } + EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(gname); + if (!g) { + egsWarning("createGeometry(iplanes): no geometry named %s exists\n", + gname.c_str()); + return 0; + } + EGS_Float phi_o = 0; + EGS_Float tmp1,tmp2; + err = input->getInput("first angle",tmp1); + int err1 = input->getInput("first angle in radians",tmp2); + if (!err) { + phi_o = tmp1*M_PI/180; + } + else if (!err1) { + phi_o = tmp2; + } + EGS_RadialRepeater *result = new EGS_RadialRepeater(xo,a,np,g,phi_o); + result->setName(input); + string medium; + err = input->getInput("medium",medium); + if (!err) { + result->setMedium(medium); + } + result->setRLabels(input); + result->setLabels(input); + return result; } - EGS_Float phi_o = 0; EGS_Float tmp1,tmp2; - err = input->getInput("first angle",tmp1); - int err1 = input->getInput("first angle in radians",tmp2); - if( !err ) phi_o = tmp1*M_PI/180; - else if( !err1 ) phi_o = tmp2; - EGS_RadialRepeater *result = new EGS_RadialRepeater(xo,a,np,g,phi_o); - result->setName(input); - string medium; - err = input->getInput("medium",medium); - if( !err ) result->setMedium(medium); - result->setRLabels(input); - result->setLabels(input); - return result; - } - vector angles; - err = input->getInput("angles",angles); - bool is_degree = true; EGS_Float max_angle = 180; - if( err ) { - err = input->getInput("angles in radian",angles); - if( err ) { - egsWarning("createGeometry(iplanes): wrong/missing 'angles' or " - "'angles in radian' input\n"); return 0; - } - is_degree = false; max_angle = M_PI; - } - EGS_Float *ang = new EGS_Float [angles.size()]; - for(int j=0; j max_angle ) { - egsWarning("createGeometry(iplanes): angle must be between 0 and " - "%g\n",max_angle); delete [] ang; return 0; + vector angles; + err = input->getInput("angles",angles); + bool is_degree = true; + EGS_Float max_angle = 180; + if (err) { + err = input->getInput("angles in radian",angles); + if (err) { + egsWarning("createGeometry(iplanes): wrong/missing 'angles' or " + "'angles in radian' input\n"); + return 0; + } + is_degree = false; + max_angle = M_PI; } - */ - if( j > 0 ) { - if( ang[j] <= ang[j-1] ) { - egsWarning("createGeometry(iplanes): angles must be ordered" - " in increasing order\n"); delete [] ang; return 0; + EGS_Float *ang = new EGS_Float [angles.size()]; + for (int j=0; j max_angle ) { + egsWarning("createGeometry(iplanes): angle must be between 0 and " + "%g\n",max_angle); delete [] ang; return 0; + } + */ + if (j > 0) { + if (ang[j] <= ang[j-1]) { + egsWarning("createGeometry(iplanes): angles must be ordered" + " in increasing order\n"); + delete [] ang; + return 0; + } } } + int nang = angles.size(); + EGS_Float ang_diff = ang[nang-1]-ang[0]; + if (ang_diff > max_angle) { + egsWarning("createGeometry(iplanes): difference between first and last" + " angle must be less then 180 degrees.\n"); + if (is_degree) + egsWarning(" Your input: first angle=%g, last angle=%g," + " difference=%g\n",ang[0],ang[nang-1],ang[nang-1]-ang[0]); + else + egsWarning(" Your input: first angle=%g, last angle=%g," + " difference=%g\n",ang[0]*180/M_PI,ang[nang-1]*180/M_PI, + (ang[nang-1]-ang[0])*180/M_PI); + delete [] ang; + return 0; + } + EGS_BaseGeometry *g = new EGS_IPlanes(xo,a,angles.size(),ang,"",is_degree); + delete [] ang; + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; } - int nang = angles.size(); - EGS_Float ang_diff = ang[nang-1]-ang[0]; - if( ang_diff > max_angle ) { - egsWarning("createGeometry(iplanes): difference between first and last" - " angle must be less then 180 degrees.\n"); - if( is_degree ) - egsWarning(" Your input: first angle=%g, last angle=%g," - " difference=%g\n",ang[0],ang[nang-1],ang[nang-1]-ang[0]); - else - egsWarning(" Your input: first angle=%g, last angle=%g," - " difference=%g\n",ang[0]*180/M_PI,ang[nang-1]*180/M_PI, - (ang[nang-1]-ang[0])*180/M_PI); - delete [] ang; return 0; - } - EGS_BaseGeometry *g = new EGS_IPlanes(xo,a,angles.size(),ang,"",is_degree); - delete [] ang; - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} -void EGS_RadialRepeater::setRLabels (EGS_Input *input) { + void EGS_RadialRepeater::setRLabels(EGS_Input *input) { - // radial repeater labels - string inp; - int err; - err = input->getInput("set repeater label", inp); - if (!err) iplanes->setLabels(inp); -} + // radial repeater labels + string inp; + int err; + err = input->getInput("set repeater label", inp); + if (!err) { + iplanes->setLabels(inp); + } + } -void EGS_RadialRepeater::getLabelRegions (const string &str, vector ®s) { + void EGS_RadialRepeater::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // label in repeated geometry - local_regs.clear(); - g->getLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; igetLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; iisWhere(x); @@ -233,45 +247,62 @@ class EGS_IPLANES_EXPORT EGS_RadialRepeater : public EGS_BaseGeometry { }; int medium(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return -1; - if( ireg == nreg-1 ) return med; - int ir = ireg/ng; int il = ireg - ir*ng; + if (ireg < 0 || ireg >= nreg) { + return -1; + } + if (ireg == nreg-1) { + return med; + } + int ir = ireg/ng; + int il = ireg - ir*ng; return g->medium(il); }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { - if( ireg < 0 ) { + if (ireg < 0) { egsFatal("\nEGS_RadialRepeater::howfar: position can not" - " be outside\n"); return ireg; + " be outside\n"); + return ireg; } //egsWarning("\nhowfar(ir=%d x=(%g,%g,%g) u=(%g,%g,%g) t=%g)\n", // ireg,x.x,x.y,x.z,u.x,u.y,u.z,t); - if( ireg < nreg-1 ) { // in the repeated geometry - int ir = ireg/ng; int il = ireg - ir*ng; + if (ireg < nreg-1) { // in the repeated geometry + int ir = ireg/ng; + int il = ireg - ir*ng; //EGS_Vector xp = x*R[ir], up = u*R[ir]; EGS_Vector xp = (x-xo)*R[ir], up = u*R[ir]; //egsWarning("In repetition %d: xp=(%g,%g,%g) up=(%g,%g,%g)\n", // ir,xp.x,xp.y,xp.z,up.x,up.y,up.z); int inew = g->howfar(il,xp,up,t,newmed,normal); //egsWarning("il=%d inew=%d t=%d\n",il,inew,t); - if( inew < 0 ) { - if( normal ) *normal = R[ir]*(*normal); - inew = nreg-1; if( newmed ) *newmed = med; + if (inew < 0) { + if (normal) { + *normal = R[ir]*(*normal); + } + inew = nreg-1; + if (newmed) { + *newmed = med; + } + } + else { + inew += ir*ng; } - else inew += ir*ng; return inew; } // outside of the replicas int ir = iplanes->isWhere(x); //egsWarning("outside repetions, ir=%d\n",ir); - EGS_Float t_left = t; EGS_Vector xtmp(x); + EGS_Float t_left = t; + EGS_Vector xtmp(x); EGS_Float ttot = 0; //EGS_Vector tmp_n; //EGS_Vector *norm = normal ? &tmp_n : 0; - while(1) { + while (1) { EGS_Float this_t = t_left; //EGS_Vector xp = xtmp*R[ir], up = u*R[ir]; EGS_Vector xp = (xtmp-xo)*R[ir], up = u*R[ir]; @@ -279,27 +310,36 @@ class EGS_IPLANES_EXPORT EGS_RadialRepeater : public EGS_BaseGeometry { //egsWarning("xp=(%g,%g,%g) up=(%g,%g,%g)\n",xp.x,xp.y,xp.z,up.x,up.y,up.z); int inew = g->howfar(-1,xp,up,this_t,newmed,normal); //egsWarning("inew=%d t=%g\n",inew,this_t); - if( inew >= 0 ) { + if (inew >= 0) { t = ttot + this_t; - if( normal ) *normal = R[ir]*(*normal); + if (normal) { + *normal = R[ir]*(*normal); + } return ir*ng + inew; } int next_ir = iplanes->howfar(ir,xtmp,u,this_t,0,0); //egsWarning("next sector: %d t=%g\n",next_ir,this_t); - if( next_ir == ir ) return ireg; - ttot += this_t; t_left -= this_t; xtmp += u*this_t; + if (next_ir == ir) { + return ireg; + } + ttot += this_t; + t_left -= this_t; + xtmp += u*this_t; ir = next_ir; } }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg < 0 ) { + if (ireg < 0) { egsFatal("EGS_RadialRepeater::hownear: position can not" - " be outside\n"); return 0; + " be outside\n"); + return 0; } - if( ireg < nreg-1 ) { // in the repeated geometry - int ir = ireg/ng; int il = ireg - ir*ng; - EGS_Vector xp = x*R[ir]; return g->hownear(il,xp); + if (ireg < nreg-1) { // in the repeated geometry + int ir = ireg/ng; + int il = ireg - ir*ng; + EGS_Vector xp = x*R[ir]; + return g->hownear(il,xp); } // outside of the replicas int ir = iplanes->isWhere(x); @@ -311,12 +351,14 @@ class EGS_IPLANES_EXPORT EGS_RadialRepeater : public EGS_BaseGeometry { return nrep*(g->getMaxStep() + 1); }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; - void setRLabels (EGS_Input *input); - virtual void getLabelRegions (const string &str, vector ®s); + void setRLabels(EGS_Input *input); + virtual void getLabelRegions(const string &str, vector ®s); protected: diff --git a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp index 620990ce9..0e1ab1196 100644 --- a/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_nd_geometry/egs_nd_geometry.cpp @@ -45,76 +45,107 @@ using namespace std; EGS_NDGeometry::EGS_NDGeometry(int ng, EGS_BaseGeometry **G, - const string &Name, bool O) : EGS_BaseGeometry(Name), N(ng), ortho(O) { - nreg = 1; setup(); - for(int j=0; jregions(); - if( !g[j]->isConvex() ) is_convex = false; + const string &Name, bool O) : EGS_BaseGeometry(Name), N(ng), ortho(O) { + nreg = 1; + setup(); + for (int j=0; jregions(); + if (!g[j]->isConvex()) { + is_convex = false; + } } n[N] = nreg; } EGS_NDGeometry::EGS_NDGeometry(vector &G, - const string &Name, bool O) : EGS_BaseGeometry(Name), N(G.size()), ortho(O){ - nreg = 1; setup(); - for(int j=0; jregions(); - if( !g[j]->isConvex() ) is_convex = false; + const string &Name, bool O) : EGS_BaseGeometry(Name), N(G.size()), ortho(O) { + nreg = 1; + setup(); + for (int j=0; jregions(); + if (!g[j]->isConvex()) { + is_convex = false; + } } n[N] = nreg; } EGS_NDGeometry::~EGS_NDGeometry() { - for(int j=0; jderef(); if( !ref ) delete g[j]; + for (int j=0; jderef(); + if (!ref) { + delete g[j]; + } } - delete [] n; delete [] g; + delete [] n; + delete [] g; } void EGS_NDGeometry::setup() { - n = new int [N+1]; g = new EGS_BaseGeometry* [N]; + n = new int [N+1]; + g = new EGS_BaseGeometry* [N]; } void EGS_NDGeometry::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" number of dimensions = %d\n",N); - for(int j=0; jgetName().c_str(),g[j]->getType().c_str()); + j+1,g[j]->getName().c_str(),g[j]->getType().c_str()); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } void EGS_NDGeometry::setMedia(EGS_Input *input, int nmed, const int *mind) { - EGS_Input *i; med = mind[0]; - while( (i = input->takeInputItem("set medium")) ) { + EGS_Input *i; + med = mind[0]; + while ((i = input->takeInputItem("set medium"))) { vector inp; - int err = i->getInput("set medium",inp); delete i; - if( !err ) { - if( inp.size() == 2 ) setMedium(inp[0],inp[0],mind[inp[1]]); - else if( inp.size() == 3 ) setMedium(inp[0],inp[1],mind[inp[2]]); - else if( inp.size() == 4 ) setMedium(inp[0],inp[1],mind[inp[2]], - inp[3]); - else if( inp.size() == 2*N+1 ) setM(0,0,inp,inp[2*N]); + int err = i->getInput("set medium",inp); + delete i; + if (!err) { + if (inp.size() == 2) { + setMedium(inp[0],inp[0],mind[inp[1]]); + } + else if (inp.size() == 3) { + setMedium(inp[0],inp[1],mind[inp[2]]); + } + else if (inp.size() == 4) setMedium(inp[0],inp[1],mind[inp[2]], + inp[3]); + else if (inp.size() == 2*N+1) { + setM(0,0,inp,inp[2*N]); + } else egsWarning("EGS_NDGeometry::setMedia(): found %dinputs\n" - "in a 'set medium' input. 2, 3, 4, or %d are allowed\n",2*N+1); + "in a 'set medium' input. 2, 3, 4, or %d are allowed\n",2*N+1); } else egsWarning("EGS_NDGeometry::setMedia(): wrong 'set medium'" - " input\n"); + " input\n"); } } void EGS_NDGeometry::setM(int ibase, int idim, - const vector &ranges, int medium) { + const vector &ranges, int medium) { int istart = ranges[2*idim], iend = ranges[2*idim+1]; - if( istart < 0 ) istart = 0; + if (istart < 0) { + istart = 0; + } int ndim = n[idim+1]; - for(int i=0; i<=idim; i++) ndim /= n[i]; - if( iend > ndim ) iend = ndim; - if( idim < N-1 ) for(int j=istart; j ndim) { + iend = ndim; + } + if (idim < N-1) for (int j=istart; jregions(); ny = yp->regions(); nz = zp->regions(); - nxy = nx*ny; nreg = nxy*nz; - xp->ref(); yp->ref(); zp->ref(); + EGS_PlanesZ *Zp, const string &Name) : EGS_BaseGeometry(Name), + xp(Xp), yp(Yp), zp(Zp) { + nx = xp->regions(); + ny = yp->regions(); + nz = zp->regions(); + nxy = nx*ny; + nreg = nxy*nz; + xp->ref(); + yp->ref(); + zp->ref(); xpos = xp->getPositions(); ypos = yp->getPositions(); zpos = zp->getPositions(); } EGS_XYZGeometry::~EGS_XYZGeometry() { - if( !xp->deref() ) delete xp; - if( !yp->deref() ) delete yp; - if( !zp->deref() ) delete zp; + if (!xp->deref()) { + delete xp; + } + if (!yp->deref()) { + delete yp; + } + if (!zp->deref()) { + delete zp; + } } void EGS_XYZGeometry::printInfo() const { EGS_BaseGeometry::printInfo(); - xp->printInfo(); yp->printInfo(); zp->printInfo(); + xp->printInfo(); + yp->printInfo(); + zp->printInfo(); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } void EGS_XYZGeometry::setMedia(EGS_Input *input, int nmed, const int *mind) { - EGS_Input *i; med = mind[0]; - while( (i = input->takeInputItem("set medium")) ) { + EGS_Input *i; + med = mind[0]; + while ((i = input->takeInputItem("set medium"))) { vector inp; - int err = i->getInput("set medium",inp); delete i; - if( !err ) { - if( inp.size() == 2 ) setMedium(inp[0],inp[0],mind[inp[1]]); - else if( inp.size() == 3 ) setMedium(inp[0],inp[1],mind[inp[2]]); - else if( inp.size() == 4 ) setMedium(inp[0],inp[1],mind[inp[2]], - inp[3]); - else if( inp.size() == 7 ) { + int err = i->getInput("set medium",inp); + delete i; + if (!err) { + if (inp.size() == 2) { + setMedium(inp[0],inp[0],mind[inp[1]]); + } + else if (inp.size() == 3) { + setMedium(inp[0],inp[1],mind[inp[2]]); + } + else if (inp.size() == 4) setMedium(inp[0],inp[1],mind[inp[2]], + inp[3]); + else if (inp.size() == 7) { int is = inp[0], ie = inp[1]; - if( is < 0 ) is = 0; if( ie > nx-1 ) ie = nx-1; + if (is < 0) { + is = 0; + } + if (ie > nx-1) { + ie = nx-1; + } int js = inp[2], je = inp[3]; - if( js < 0 ) js = 0; if( je > nxy/nx-1 ) je = nxy/nx-1; + if (js < 0) { + js = 0; + } + if (je > nxy/nx-1) { + je = nxy/nx-1; + } int ks = inp[4], ke = inp[5]; - if( ks < 0 ) ks = 0; if( ke > nreg/nxy-1 ) ke = nreg/nxy-1; + if (ks < 0) { + ks = 0; + } + if (ke > nreg/nxy-1) { + ke = nreg/nxy-1; + } //egsInformation("setting medium to %d between %d %d %d %d " // "%d %d\n",mind[inp[6]],is,ie,js,je,ks,ke); - for(int i=is; i<=ie; i++) { - for(int j=js; j<=je; j++) { - for(int k=ks; k<=ke; k++) { + for (int i=is; i<=ie; i++) { + for (int j=js; j<=je; j++) { + for (int k=ks; k<=ke; k++) { int ireg = i + j*nx + k*nxy; //egsWarning("set: %d %d %d %d %d\n", // i,j,k,ireg,mind[inp[6]]); @@ -175,21 +240,42 @@ void EGS_XYZGeometry::setMedia(EGS_Input *input, int nmed, const int *mind) { } } } - else if( inp.size() == 10 ) { + else if (inp.size() == 10) { int is = inp[0], ie = inp[1], idelta = inp[2]; - if( is < 0 ) is = 0; if( ie > nx-1 ) ie = nx-1; - if( idelta <= 0 ) idelta = 1; + if (is < 0) { + is = 0; + } + if (ie > nx-1) { + ie = nx-1; + } + if (idelta <= 0) { + idelta = 1; + } int js = inp[3], je = inp[4], jdelta = inp[5]; - if( js < 0 ) js = 0; if( je > nxy/nx-1 ) je = nxy/nx-1; - if( jdelta <= 0 ) jdelta = 1; + if (js < 0) { + js = 0; + } + if (je > nxy/nx-1) { + je = nxy/nx-1; + } + if (jdelta <= 0) { + jdelta = 1; + } int ks = inp[6], ke = inp[7], kdelta = inp[8]; - if( ks < 0 ) ks = 0; if( ke > nreg/nxy-1 ) ke = nreg/nxy-1; - if( kdelta <= 0 ) kdelta = 1; + if (ks < 0) { + ks = 0; + } + if (ke > nreg/nxy-1) { + ke = nreg/nxy-1; + } + if (kdelta <= 0) { + kdelta = 1; + } //egsInformation("setting medium to %d between %d %d %d %d " // "%d %d\n",mind[inp[6]],is,ie,js,je,ks,ke); - for(int i=is; i<=ie; i+=idelta) { - for(int j=js; j<=je; j+=jdelta) { - for(int k=ks; k<=ke; k+=kdelta) { + for (int i=is; i<=ie; i+=idelta) { + for (int j=js; j<=je; j+=jdelta) { + for (int k=ks; k<=ke; k+=kdelta) { int ireg = i + j*nx + k*nxy; //egsWarning("set: %d %d %d %d %d\n", // i,j,k,ireg,mind[inp[6]]); @@ -199,289 +285,453 @@ void EGS_XYZGeometry::setMedia(EGS_Input *input, int nmed, const int *mind) { } } else egsWarning("EGS_XYZGeometry::setMedia(): found %dinputs\n" - "in a 'set medium' input. 2, 3, 4, 7, or 10 are allowed\n"); + "in a 'set medium' input. 2, 3, 4, 7, or 10 are allowed\n"); } else egsWarning("EGS_XYZGeometry::setMedia(): wrong 'set medium'" - " input\n"); + " input\n"); } } -EGS_XYZGeometry* EGS_XYZGeometry::constructGeometry(const char *dens_file, +EGS_XYZGeometry *EGS_XYZGeometry::constructGeometry(const char *dens_file, const char *ramp_file, int dens_or_egsphant_or_interfile) { const static char *func = "EGS_XYZGeometry::constructGeometry"; - if( !dens_file || !ramp_file ) return 0; + if (!dens_file || !ramp_file) { + return 0; + } ifstream ramp(ramp_file); - if( !ramp ) { - egsWarning("%s: failed to open CT ramp file %s\n",func,ramp_file); return 0; + if (!ramp) { + egsWarning("%s: failed to open CT ramp file %s\n",func,ramp_file); + return 0; } - vector med_names; vector rho_min,rho_max,rho_def; + vector med_names; + vector rho_min,rho_max,rho_def; - if( dens_or_egsphant_or_interfile == 2 ) { + if (dens_or_egsphant_or_interfile == 2) { // interfile format of data - int meds; ramp >> meds; - for(int i=0; i < meds; i++) { - string medname; EGS_Float rmin,rmax,rdef; + int meds; + ramp >> meds; + for (int i=0; i < meds; i++) { + string medname; + EGS_Float rmin,rmax,rdef; ramp >> rmin >> rmax >> medname; rdef=(rmin+rmax) / 2.0; // is this correct definition of rdef ?? - if( ramp.eof() || ramp.fail() || !ramp.good() ) break; + if (ramp.eof() || ramp.fail() || !ramp.good()) { + break; + } egsInformation("Using medium %s for rho=%g...%g\n",medname.c_str(), - rmin,rmax); + rmin,rmax); med_names.push_back(medname); - rho_min.push_back(rmin); rho_max.push_back(rmax+1); + rho_min.push_back(rmin); + rho_max.push_back(rmax+1); rho_def.push_back(rdef); } - } else while(1) { - // other format of data - string medname; EGS_Float rmin,rmax,rdef; - ramp >> medname >> rmin >> rmax >> rdef; - if( ramp.eof() || ramp.fail() || !ramp.good() ) break; - egsInformation("Using medium %s for rho=%g...%g\n",medname.c_str(), - rmin,rmax); - med_names.push_back(medname); - rho_min.push_back(rmin); rho_max.push_back(rmax); - rho_def.push_back(rdef); } - if( med_names.size() < 1 ) { + else while (1) { + // other format of data + string medname; + EGS_Float rmin,rmax,rdef; + ramp >> medname >> rmin >> rmax >> rdef; + if (ramp.eof() || ramp.fail() || !ramp.good()) { + break; + } + egsInformation("Using medium %s for rho=%g...%g\n",medname.c_str(), + rmin,rmax); + med_names.push_back(medname); + rho_min.push_back(rmin); + rho_max.push_back(rmax); + rho_def.push_back(rdef); + } + if (med_names.size() < 1) { egsWarning("%s: no media defined in the CT ramp " - "file %s!\n",func,ramp_file); return 0; + "file %s!\n",func,ramp_file); + return 0; } - int Nx, Ny, Nz; EGS_Float *xx, *yy, *zz; float *rho; - if( dens_or_egsphant_or_interfile == 0 ) { + int Nx, Ny, Nz; + EGS_Float *xx, *yy, *zz; + float *rho; + if (dens_or_egsphant_or_interfile == 0) { int my_endian = egsGetEndian(); - if( my_endian < 0 ) egsFatal("%s: machine has an unknown" - " endianess!\n",func); + if (my_endian < 0) egsFatal("%s: machine has an unknown" + " endianess!\n",func); ifstream dens(dens_file,ios::binary); - if( !dens ) { + if (!dens) { egsWarning("%s: failed to open density matrix file " - "%s\n",func,dens_file); return 0; + "%s\n",func,dens_file); + return 0; } char their_endian; dens.read(&their_endian,1); - if( their_endian != 0 && their_endian != 1 ) + if (their_endian != 0 && their_endian != 1) egsFatal("%s: density data created on a machine with" - " unknown endianess!\n",func); + " unknown endianess!\n",func); bool swap = my_endian != their_endian; - dens.read((char *) &Nx,sizeof(int)); if( swap ) egsSwapBytes(&Nx); - dens.read((char *) &Ny,sizeof(int)); if( swap ) egsSwapBytes(&Ny); - dens.read((char *) &Nz,sizeof(int)); if( swap ) egsSwapBytes(&Nz); - if( Nx < 1 || Ny < 1 || Nz < 1 ) { + dens.read((char *) &Nx,sizeof(int)); + if (swap) { + egsSwapBytes(&Nx); + } + dens.read((char *) &Ny,sizeof(int)); + if (swap) { + egsSwapBytes(&Ny); + } + dens.read((char *) &Nz,sizeof(int)); + if (swap) { + egsSwapBytes(&Nz); + } + if (Nx < 1 || Ny < 1 || Nz < 1) { egsWarning("%s: invalid density matrix file: " - " Nx=%d Ny=%d Nz=%d\n",func,Nx,Ny,Nz); return 0; + " Nx=%d Ny=%d Nz=%d\n",func,Nx,Ny,Nz); + return 0; } float *x = new float [Nx+1]; float *y = new float [Ny+1]; float *z = new float [Nz+1]; dens.read((char *)x, (Nx+1)*sizeof(float)); - if( dens.eof() || dens.fail() || !dens.good() ) { + if (dens.eof() || dens.fail() || !dens.good()) { egsWarning("%s: error while reading %d x-planes from" - " file %s\n",func,Nx+1,dens_file); - delete [] x; delete [] y; delete [] z; return 0; + " file %s\n",func,Nx+1,dens_file); + delete [] x; + delete [] y; + delete [] z; + return 0; } dens.read((char *)y, (Ny+1)*sizeof(float)); - if( dens.eof() || dens.fail() || !dens.good() ) { + if (dens.eof() || dens.fail() || !dens.good()) { egsWarning("%s: error while reading %d y-planes from" - " file %s\n",func,Ny+1,dens_file); - delete [] x; delete [] y; delete [] z; return 0; + " file %s\n",func,Ny+1,dens_file); + delete [] x; + delete [] y; + delete [] z; + return 0; } dens.read((char *)z, (Nz+1)*sizeof(float)); - if( dens.eof() || dens.fail() || !dens.good() ) { + if (dens.eof() || dens.fail() || !dens.good()) { egsWarning("%s: error while reading %d z-planes from" - " file %s\n",func,Nz+1,dens_file); - delete [] x; delete [] y; delete [] z; return 0; + " file %s\n",func,Nz+1,dens_file); + delete [] x; + delete [] y; + delete [] z; + return 0; } - if( swap ) { + if (swap) { int j; - for(j=0; j> nmed; - if( data.fail() ) { - egsWarning("%s: failed reading number of media\n",func); return 0; + int nmed; + data >> nmed; + if (data.fail()) { + egsWarning("%s: failed reading number of media\n",func); + return 0; } - char buf [1024]; int imed; + char buf [1024]; + int imed; data.getline(buf,1023); - for(imed=0; imed\n",buf); } // ignore estepe - EGS_Float dum; for(imed=0; imed> dum; + EGS_Float dum; + for (imed=0; imed> dum; + } data >> Nx >> Ny >> Nz; - if( data.fail() ) { - egsWarning("%s: failed reading number of voxels\n",func); return 0; + if (data.fail()) { + egsWarning("%s: failed reading number of voxels\n",func); + return 0; } - xx = new EGS_Float [Nx+1]; yy = new EGS_Float [Ny+1]; zz = new EGS_Float [Nz+1]; + xx = new EGS_Float [Nx+1]; + yy = new EGS_Float [Ny+1]; + zz = new EGS_Float [Nz+1]; int j; - for(j=0; j<=Nx; ++j) data >> xx[j]; - if( data.fail() ) { + for (j=0; j<=Nx; ++j) { + data >> xx[j]; + } + if (data.fail()) { egsWarning("%s: failed reading x-planes\n",func); - delete [] xx; delete [] yy; delete [] zz; return 0; + delete [] xx; + delete [] yy; + delete [] zz; + return 0; } - for(j=0; j<=Ny; ++j) data >> yy[j]; - if( data.fail() ) { + for (j=0; j<=Ny; ++j) { + data >> yy[j]; + } + if (data.fail()) { egsWarning("%s: failed reading y-planes\n",func); - delete [] xx; delete [] yy; delete [] zz; return 0; + delete [] xx; + delete [] yy; + delete [] zz; + return 0; + } + for (j=0; j<=Nz; ++j) { + data >> zz[j]; } - for(j=0; j<=Nz; ++j) data >> zz[j]; - if( data.fail() ) { + if (data.fail()) { egsWarning("%s: failed reading z-planes\n",func); - delete [] xx; delete [] yy; delete [] zz; return 0; + delete [] xx; + delete [] yy; + delete [] zz; + return 0; } - int nr = Nx*Ny*Nz; int med; + int nr = Nx*Ny*Nz; + int med; //for(j=0; j> med; data.getline(buf,1023); - for(int iz=0; iz> rho[j]; - if( data.fail() ) { + for (j=0; j> rho[j]; + } + if (data.fail()) { egsWarning("%s: failed reading mass density matrix\n",func); - delete [] xx; delete [] yy; delete [] zz; delete [] rho; return 0; + delete [] xx; + delete [] yy; + delete [] zz; + delete [] rho; + return 0; } } EGS_PlanesX *xp = new EGS_PlanesX(Nx+1,xx,"",EGS_XProjector("x-planes")); EGS_PlanesY *yp = new EGS_PlanesY(Ny+1,yy,"",EGS_YProjector("y-planes")); EGS_PlanesZ *zp = new EGS_PlanesZ(Nz+1,zz,"",EGS_ZProjector("z-planes")); EGS_XYZGeometry *result = new EGS_XYZGeometry(xp,yp,zp); - EGS_Float rhomin=1e30,rhomax=0; int j; - for(j=0; j rhomax ) rhomax = rho[j]; - if( rho[j] < rhomin ) rhomin = rho[j]; + EGS_Float rhomin=1e30,rhomax=0; + int j; + for (j=0; j rhomax) { + rhomax = rho[j]; + } + if (rho[j] < rhomin) { + rhomin = rho[j]; + } } egsInformation("Min. density found: %g\n",rhomin); egsInformation("Max. density found: %g\n",rhomax); int nmed = med_names.size(); int *imed = new int [nmed]; - for(j=0; j= rho_min[i] && rho[j] < rho_max[i] ) break; + for (i=0; i= rho_min[i] && rho[j] < rho_max[i]) { + break; + } } - if( i >= nmed ) { + if (i >= nmed) { egsWarning("%s: no material defined for density %g, leaving voxel %d" - " as vacuum\n",func,rho[j],j); + " as vacuum\n",func,rho[j],j); result->setMedium(j,j,-1); } else { - if( imed[i] < -1 ) { + if (imed[i] < -1) { imed[i] = addMedium(med_names[i]); egsInformation("Using medium %s as mednum %d\n", - med_names[i].c_str(),imed[i]); + med_names[i].c_str(),imed[i]); } result->setMedium(j,j,imed[i]); - if( rho_def[i] > 0 ) { + if (rho_def[i] > 0) { EGS_Float rrho = rho[j]/rho_def[i]; - if( fabs(rrho-1) > 1e-4 ) + if (fabs(rrho-1) > 1e-4) { result->setRelativeRho(j,j,rrho); + } } } } - delete [] rho; delete [] imed; + delete [] rho; + delete [] imed; return result; } string EGS_DeformedXYZ::def_type = "EGS_DeformedXYZ"; char EGS_DeformedXYZ::tetrahedra[] = {0,2,3,6, 0,6,3,7, 0,4,6,7, - 7,0,1,3, 7,1,0,4, 7,5,1,4}; + 7,0,1,3, 7,1,0,4, 7,5,1,4 + }; char EGS_DeformedXYZ::plane_order[] = {0,1,2, 0,2,3, 0,3,1, 1,3,2}; @@ -492,64 +742,70 @@ char EGS_DeformedXYZ::enter_plane2[] = {0, 0, 2, 3, 2, 2}; char EGS_DeformedXYZ::tetra_data[] = { - 2,-1, 2, // plane 0 in tetrahedron 0 + 2,-1, 2, // plane 0 in tetrahedron 0 -1, 0, 1, // plane 1 in tetrahedron 0 - 0,-1, 3, // plane 2 in tetrahedron 0 - 1, 1, 4, // plane 3 in tetrahedron 0 + 0,-1, 3, // plane 2 in tetrahedron 0 + 1, 1, 4, // plane 3 in tetrahedron 0 //------------------------------------------------------------------ -1, 0, 0, // plane 0 in tetrahedron 1 -1, 0, 3, // plane 1 in tetrahedron 1 -1, 0, 2, // plane 2 in tetrahedron 1 - 1, 1, 5, // plane 3 in tetrahedron 1 + 1, 1, 5, // plane 3 in tetrahedron 1 //------------------------------------------------------------------ - 0,-1, 5, // plane 0 in tetrahedron 2 + 0,-1, 5, // plane 0 in tetrahedron 2 -1, 0, 1, // plane 1 in tetrahedron 2 -1, 0, 4, // plane 2 in tetrahedron 2 - 2, 1, 0, // plane 3 in tetrahedron 2 + 2, 1, 0, // plane 3 in tetrahedron 2 //------------------------------------------------------------------ -1, 0, 4, // plane 0 in tetrahedron 3 - 0, 1, 0, // plane 1 in tetrahedron 3 + 0, 1, 0, // plane 1 in tetrahedron 3 -1, 0, 1, // plane 2 in tetrahedron 3 - 2,-1, 5, // plane 3 in tetrahedron 3 + 2,-1, 5, // plane 3 in tetrahedron 3 //------------------------------------------------------------------ -1, 0, 3, // plane 0 in tetrahedron 4 -1, 0, 2, // plane 1 in tetrahedron 4 -1, 0, 5, // plane 2 in tetrahedron 4 - 1,-1, 0, // plane 3 in tetrahedron 4 + 1,-1, 0, // plane 3 in tetrahedron 4 //------------------------------------------------------------------ - 0, 1, 2, // plane 0 in tetrahedron 5 + 0, 1, 2, // plane 0 in tetrahedron 5 -1, 0, 4, // plane 1 in tetrahedron 5 - 2, 1, 3, // plane 2 in tetrahedron 5 - 1,-1, 1 // plane 3 in tetrahedron 5 + 2, 1, 3, // plane 2 in tetrahedron 5 + 1,-1, 1 // plane 3 in tetrahedron 5 }; EGS_DeformedXYZ::EGS_DeformedXYZ(EGS_PlanesX *Xp, EGS_PlanesY *Yp, - EGS_PlanesZ *Zp, const char *defFile, const string &Name) : + EGS_PlanesZ *Zp, const char *defFile, const string &Name) : EGS_XYZGeometry(Xp,Yp,Zp,Name), vectors(0) { setDeformations(defFile); - np[0] = nx; np[1] = ny; np[2] = nz; + np[0] = nx; + np[1] = ny; + np[2] = nz; nxyp1 = nx + ny + 1; } int EGS_DeformedXYZ::setDeformations(const char *defFile) { ifstream data(defFile,ios::binary); - if( !data ) { + if (!data) { egsWarning("Failed to open deformations file %s\n",defFile); return 1; } int nvec; data.read((char *)&nvec,sizeof(int)); int nneed = (nx+1)*(ny+1)*(nz+1); - if( nvec != nneed ) { + if (nvec != nneed) { egsWarning("Inconsistent deformations file: %d instead of %d vectors\n", - nvec,nneed); return 2; + nvec,nneed); + return 2; + } + if (!vectors) { + vectors = new EGS_Vector [nvec]; } - if( !vectors ) vectors = new EGS_Vector [nvec]; - float tmp[3]; int i,j,k; - for(j=0; jref(); g->ref(); - nxy = nx*ny; nxyz = nx*ny*nz; ng = g->regions(); + xyz->ref(); + g->ref(); + nxy = nx*ny; + nxyz = nx*ny*nz; + ng = g->regions(); nreg = nxyz*ng + 1; translation = new EGS_Vector [nxyz]; - for(int ix=0; ixderef() ) delete g; - if( !xyz->deref() ) delete xyz; + if (!g->deref()) { + delete g; + } + if (!xyz->deref()) { + delete xyz; + } delete [] translation; } void EGS_XYZRepeater::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation("%d repetitions between xmin=%g and xmax=%g\n", - nx,xyz->getXPositions()[0],xyz->getXPositions()[nx]); + nx,xyz->getXPositions()[0],xyz->getXPositions()[nx]); egsInformation("%d repetitions between ymin=%g and ymax=%g\n", - ny,xyz->getYPositions()[0],xyz->getYPositions()[ny]); + ny,xyz->getYPositions()[0],xyz->getYPositions()[ny]); egsInformation("%d repetitions between zmin=%g and zmax=%g\n", - nz,xyz->getZPositions()[0],xyz->getZPositions()[nz]); + nz,xyz->getZPositions()[0],xyz->getZPositions()[nz]); const char *med_name = getMediumName(med); - if( med_name ) egsInformation("box is filled with %s\n",med_name); - else egsInformation("box is filled with vacuum\n"); + if (med_name) { + egsInformation("box is filled with %s\n",med_name); + } + else { + egsInformation("box is filled with vacuum\n"); + } egsInformation("Repeated geometry:\n"); g->printInfo(); } @@ -639,58 +932,78 @@ void EGS_XYZRepeater::printInfo() const { void EGS_XYZGeometry::voxelizeGeometry(EGS_Input *input) { string gname; int err = input->getInput("voxelize geometry",gname); - if( err ) return; + if (err) { + return; + } egsInformation("\nEGS_XYZGeometry(%s)\n",name.c_str()); egsInformation(" setting media from geometry %s\n",gname.c_str()); EGS_BaseGeometry *geometry = EGS_BaseGeometry::getGeometry(gname); - if( !geometry ) { + if (!geometry) { egsInformation(" this geometry does not exist -> media will be not set.\n"); return; } EGS_AffineTransform *T = EGS_AffineTransform::getTransformation(input); - if( region_media ) delete [] region_media; - if( rhor ) { delete [] rhor; rhor = 0; } + if (region_media) { + delete [] region_media; + } + if (rhor) { + delete [] rhor; + rhor = 0; + } region_media = new short [nreg]; bool hrs = geometry->hasRhoScaling(); - if( hrs ) { - has_rho_scaling = true; rhor = new EGS_Float [nreg]; + if (hrs) { + has_rho_scaling = true; + rhor = new EGS_Float [nreg]; + } + else { + has_rho_scaling = false; } - else has_rho_scaling = false; EGS_Vector v1(xp->position(0),yp->position(0),zp->position(0)); EGS_Vector v2(xp->position(nx),yp->position(ny),zp->position(nz)); egsInformation(" top/left/front corner : (%g,%g,%g)\n",v1.x,v1.y,v1.z); egsInformation(" bottom/right/back corner: (%g,%g,%g)\n",v2.x,v2.y,v2.z); - if( T ) { + if (T) { egsInformation(" the above are transformed as follows before looking up media:\n"); - T->transform(v1); T->transform(v2); + T->transform(v1); + T->transform(v2); egsInformation(" top/left/front corner : (%g,%g,%g)\n",v1.x,v1.y,v1.z); egsInformation(" bottom/right/back corner: (%g,%g,%g)\n",v2.x,v2.y,v2.z); } - for(int ix=0; ixposition(ix)+xp->position(ix+1)), - 0.5*(yp->position(iy)+yp->position(iy+1)), - 0.5*(zp->position(iz)+zp->position(iz+1))); - if( T ) T->transform(v); - int ireg = geometry->isWhere(v); - if( ireg >= 0 ) { - region_media[ir] = geometry->medium(ireg); - if( hrs ) rhor[ir] = geometry->getRelativeRho(ir); - } else { - region_media[ir] = -1; - if( hrs ) rhor[ir] = 1; - } - } - vector options; options.push_back("no"); options.push_back("yes"); + for (int ix=0; ixposition(ix)+xp->position(ix+1)), + 0.5*(yp->position(iy)+yp->position(iy+1)), + 0.5*(zp->position(iz)+zp->position(iz+1))); + if (T) { + T->transform(v); + } + int ireg = geometry->isWhere(v); + if (ireg >= 0) { + region_media[ir] = geometry->medium(ireg); + if (hrs) { + rhor[ir] = geometry->getRelativeRho(ir); + } + } + else { + region_media[ir] = -1; + if (hrs) { + rhor[ir] = 1; + } + } + } + vector options; + options.push_back("no"); + options.push_back("yes"); bool delete_geometry = input->getInput("delete geometry",options,0); - if( delete_geometry ) { - if( geometry->deref() == -1 ) { + if (delete_geometry) { + if (geometry->deref() == -1) { egsInformation(" deleting geometry %s as requested\n",geometry->getName().c_str()); delete geometry; } else { egsInformation(" not deleting geometry %s as requested due to remaining references\n", - geometry->getName().c_str()); + geometry->getName().c_str()); geometry->ref(); } } @@ -705,413 +1018,481 @@ string EGS_NDGeometry::type = "EGS_NDGeometry"; extern "C" { -EGS_NDG_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { + EGS_NDG_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { #ifdef EXPLICIT_XYZ - const static char *func = "createGeometry(XYZ)"; - string type; - int is_xyz = input->getInput("type",type); - if( !is_xyz && input->compare("EGS_XYZRepeater",type) ) { - string base,medium; vector xr, yr, zr; - int err1 = input->getInput("repeated geometry",base); - int err2 = input->getInput("repeat x",xr); - int err3 = input->getInput("repeat y",yr); - int err4 = input->getInput("repeat z",zr); - int err5 = input->getInput("medium",medium); - EGS_BaseGeometry *g = 0; - if( err1 ) - egsWarning("%s: missing 'repeated geometry' input\n",err_msg1); - else { - g = EGS_BaseGeometry::getGeometry(base); - if( !g ) { - egsWarning("%s: no geometry named %s exists\n",err_msg1, - base.c_str()); err1 = 1; + const static char *func = "createGeometry(XYZ)"; + string type; + int is_xyz = input->getInput("type",type); + if (!is_xyz && input->compare("EGS_XYZRepeater",type)) { + string base,medium; + vector xr, yr, zr; + int err1 = input->getInput("repeated geometry",base); + int err2 = input->getInput("repeat x",xr); + int err3 = input->getInput("repeat y",yr); + int err4 = input->getInput("repeat z",zr); + int err5 = input->getInput("medium",medium); + EGS_BaseGeometry *g = 0; + if (err1) { + egsWarning("%s: missing 'repeated geometry' input\n",err_msg1); } - } - if( err2 || xr.size() != 3 ) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat x' input\n",err_msg1); - } - if( err3 || yr.size() != 3 ) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat y' input\n",err_msg1); - } - if( err4 || zr.size() != 3 ) { - err1 = 1; - egsWarning("%s: wrong/missing 'repeat z' input\n",err_msg1); - } - if( err1 ) return 0; - EGS_Float xmin = xr[0], xmax = xr[1]; int nx = (int) (xr[2]+0.1); - if( xmin >= xmax || nx < 1 ) { - egsWarning("%s: wrong 'repeat x' input xmin=%g xmax=%g nx=%d\n", - xmin,xmax,nx); err1 = 1; - } - EGS_Float ymin = yr[0], ymax = yr[1]; int ny = (int) (yr[2]+0.1); - if( ymin >= ymax || ny < 1 ) { - egsWarning("%s: wrong 'repeat y' input ymin=%g ymax=%g ny=%d\n", - ymin,ymax,ny); err1 = 1; - } - EGS_Float zmin = zr[0], zmax = zr[1]; int nz = (int) (zr[2]+0.1); - if( zmin >= zmax || nz < 1 ) { - egsWarning("%s: wrong 'repeat z' input zmin=%g zmax=%g nz=%d\n", - zmin,zmax,nz); err1 = 1; - } - if( err1 ) return 0; - - EGS_XYZRepeater *result = - new EGS_XYZRepeater(xmin,xmax,ymin,ymax,zmin,zmax,nx,ny,nz,g); - result->setName(input); - if( !err5 ) result->setMedium(medium); - result->setXYZLabels(input); - result->setLabels(input); - return result; - } - else if( !is_xyz && input->compare("EGS_XYZGeometry",type) ) { - string dens_file, ramp_file, egsphant_file, interfile_file; - int ierr1 = input->getInput("density matrix",dens_file); - int ierr2 = input->getInput("ct ramp",ramp_file); - int ierr3 = input->getInput("egsphant file",egsphant_file); - int ierr4 = input->getInput("interfile header",interfile_file); - int dens_or_egsphant_or_interfile = -1; - if( !ierr1 ) dens_or_egsphant_or_interfile = 0; - else if( !ierr3 ) { dens_or_egsphant_or_interfile = 1; dens_file = egsphant_file; } - else if( !ierr4 ) { dens_or_egsphant_or_interfile = 2; dens_file = interfile_file; } - if( dens_or_egsphant_or_interfile >= 0 || !ierr2 ) { - if( dens_or_egsphant_or_interfile < 0 ) { - egsWarning("%s: no 'density matrix', 'egsphant file' or 'interfile header' input\n",func); + else { + g = EGS_BaseGeometry::getGeometry(base); + if (!g) { + egsWarning("%s: no geometry named %s exists\n",err_msg1, + base.c_str()); + err1 = 1; + } + } + if (err2 || xr.size() != 3) { + err1 = 1; + egsWarning("%s: wrong/missing 'repeat x' input\n",err_msg1); + } + if (err3 || yr.size() != 3) { + err1 = 1; + egsWarning("%s: wrong/missing 'repeat y' input\n",err_msg1); + } + if (err4 || zr.size() != 3) { + err1 = 1; + egsWarning("%s: wrong/missing 'repeat z' input\n",err_msg1); + } + if (err1) { return 0; } - if( ierr2 ) { - egsWarning("%s: no 'ct ramp' input\n",func); + EGS_Float xmin = xr[0], xmax = xr[1]; + int nx = (int)(xr[2]+0.1); + if (xmin >= xmax || nx < 1) { + egsWarning("%s: wrong 'repeat x' input xmin=%g xmax=%g nx=%d\n", + xmin,xmax,nx); + err1 = 1; + } + EGS_Float ymin = yr[0], ymax = yr[1]; + int ny = (int)(yr[2]+0.1); + if (ymin >= ymax || ny < 1) { + egsWarning("%s: wrong 'repeat y' input ymin=%g ymax=%g ny=%d\n", + ymin,ymax,ny); + err1 = 1; + } + EGS_Float zmin = zr[0], zmax = zr[1]; + int nz = (int)(zr[2]+0.1); + if (zmin >= zmax || nz < 1) { + egsWarning("%s: wrong 'repeat z' input zmin=%g zmax=%g nz=%d\n", + zmin,zmax,nz); + err1 = 1; + } + if (err1) { return 0; } - EGS_XYZGeometry *result = - EGS_XYZGeometry::constructGeometry(dens_file.c_str(),ramp_file.c_str(),dens_or_egsphant_or_interfile); - result->setName(input); return result; - } - vector xpos, ypos, zpos, xslab, yslab, zslab; - int ix = input->getInput("x-planes",xpos); - int iy = input->getInput("y-planes",ypos); - int iz = input->getInput("z-planes",zpos); - int ix1 = input->getInput("x-slabs",xslab); - int iy1 = input->getInput("y-slabs",yslab); - int iz1 = input->getInput("z-slabs",zslab); - int nx, ny, nz; - if( !ix1 ) { - if( xslab.size() != 3 ) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'x-slabs' input method\n"); ix1 = 1; + + EGS_XYZRepeater *result = + new EGS_XYZRepeater(xmin,xmax,ymin,ymax,zmin,zmax,nx,ny,nz,g); + result->setName(input); + if (!err5) { + result->setMedium(medium); + } + result->setXYZLabels(input); + result->setLabels(input); + return result; + } + else if (!is_xyz && input->compare("EGS_XYZGeometry",type)) { + string dens_file, ramp_file, egsphant_file, interfile_file; + int ierr1 = input->getInput("density matrix",dens_file); + int ierr2 = input->getInput("ct ramp",ramp_file); + int ierr3 = input->getInput("egsphant file",egsphant_file); + int ierr4 = input->getInput("interfile header",interfile_file); + int dens_or_egsphant_or_interfile = -1; + if (!ierr1) { + dens_or_egsphant_or_interfile = 0; } - else { - nx = (int) (xslab[2]+0.1); - if( nx < 1 ) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); ix1 = 1; + else if (!ierr3) { + dens_or_egsphant_or_interfile = 1; + dens_file = egsphant_file; + } + else if (!ierr4) { + dens_or_egsphant_or_interfile = 2; + dens_file = interfile_file; + } + if (dens_or_egsphant_or_interfile >= 0 || !ierr2) { + if (dens_or_egsphant_or_interfile < 0) { + egsWarning("%s: no 'density matrix', 'egsphant file' or 'interfile header' input\n",func); + return 0; } - if( xslab[1] <= 0 ) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); ix1 = 1; + if (ierr2) { + egsWarning("%s: no 'ct ramp' input\n",func); + return 0; } + EGS_XYZGeometry *result = + EGS_XYZGeometry::constructGeometry(dens_file.c_str(),ramp_file.c_str(),dens_or_egsphant_or_interfile); + result->setName(input); + return result; } - } - if( ix && ix1 ) { - egsWarning("createGeometry(XYZ): wrong/missing 'x-planes' " - "and 'x-slabs' input\n"); return 0; - } - if( !iy1 ) { - if( yslab.size() != 3 ) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'y-slabs' input method\n"); iy1 = 1; + vector xpos, ypos, zpos, xslab, yslab, zslab; + int ix = input->getInput("x-planes",xpos); + int iy = input->getInput("y-planes",ypos); + int iz = input->getInput("z-planes",zpos); + int ix1 = input->getInput("x-slabs",xslab); + int iy1 = input->getInput("y-slabs",yslab); + int iz1 = input->getInput("z-slabs",zslab); + int nx, ny, nz; + if (!ix1) { + if (xslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'x-slabs' input method\n"); + ix1 = 1; + } + else { + nx = (int)(xslab[2]+0.1); + if (nx < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + ix1 = 1; + } + if (xslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + ix1 = 1; + } + } } - else { - ny = (int) (yslab[2]+0.1); - if( ny < 1 ) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); iy1 = 1; + if (ix && ix1) { + egsWarning("createGeometry(XYZ): wrong/missing 'x-planes' " + "and 'x-slabs' input\n"); + return 0; + } + if (!iy1) { + if (yslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'y-slabs' input method\n"); + iy1 = 1; } - if( yslab[1] <= 0 ) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); iy1 = 1; + else { + ny = (int)(yslab[2]+0.1); + if (ny < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + iy1 = 1; + } + if (yslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + iy1 = 1; + } } } - } - if( iy && iy1 ) { - egsWarning("createGeometry(XYZ): wrong/missing 'y-planes' " - "and 'y-slabs' input\n"); return 0; - } - if( !iz1 ) { - if( zslab.size() != 3 ) { - egsWarning("createGeometry(XYZ): exactly 3 inputs are required" - " when using 'z-slabs' input method\n"); iz1 = 1; + if (iy && iy1) { + egsWarning("createGeometry(XYZ): wrong/missing 'y-planes' " + "and 'y-slabs' input\n"); + return 0; } - else { - nz = (int) (zslab[2]+0.1); - if( nz < 1 ) { - egsWarning("createGeometry(XYZ): number of slabs must be" - " positive!\n"); iz1 = 1; + if (!iz1) { + if (zslab.size() != 3) { + egsWarning("createGeometry(XYZ): exactly 3 inputs are required" + " when using 'z-slabs' input method\n"); + iz1 = 1; } - if( zslab[1] <= 0 ) { - egsWarning("createGeometry(XYZ): slab thickness must be" - " positive!\n"); iz1 = 1; + else { + nz = (int)(zslab[2]+0.1); + if (nz < 1) { + egsWarning("createGeometry(XYZ): number of slabs must be" + " positive!\n"); + iz1 = 1; + } + if (zslab[1] <= 0) { + egsWarning("createGeometry(XYZ): slab thickness must be" + " positive!\n"); + iz1 = 1; + } } } + if (iz && iz1) { + egsWarning("createGeometry(XYZ): wrong/missing 'z-planes' " + "and 'z-slabs' input\n"); + return 0; + } + EGS_PlanesX *xp = !ix1 ? + new EGS_PlanesX(xslab[0],xslab[1],nx,"",EGS_XProjector("x-planes")) : + new EGS_PlanesX(xpos,"",EGS_XProjector("x-planes")); + EGS_PlanesY *yp = !iy1 ? + new EGS_PlanesY(yslab[0],yslab[1],ny,"",EGS_YProjector("y-planes")) : + new EGS_PlanesY(ypos,"",EGS_YProjector("y-planes")); + EGS_PlanesZ *zp = !iz1 ? + new EGS_PlanesZ(zslab[0],zslab[1],nz,"",EGS_ZProjector("z-planes")) : + new EGS_PlanesZ(zpos,"",EGS_ZProjector("z-planes")); + EGS_XYZGeometry *result = new EGS_XYZGeometry(xp,yp,zp); + + if (result) { + egsWarning("**********************************************\n"); + EGS_BaseGeometry *g = result; + result->setName(input); + g->setMedia(input); + result->voxelizeGeometry(input); + + // labels + result->setXYZLabels(input); + g->setLabels(input); + } + return result; } - if( iz && iz1 ) { - egsWarning("createGeometry(XYZ): wrong/missing 'z-planes' " - "and 'z-slabs' input\n"); return 0; - } - EGS_PlanesX *xp = !ix1 ? - new EGS_PlanesX(xslab[0],xslab[1],nx,"",EGS_XProjector("x-planes")) : - new EGS_PlanesX(xpos,"",EGS_XProjector("x-planes")); - EGS_PlanesY *yp = !iy1 ? - new EGS_PlanesY(yslab[0],yslab[1],ny,"",EGS_YProjector("y-planes")) : - new EGS_PlanesY(ypos,"",EGS_YProjector("y-planes")); - EGS_PlanesZ *zp = !iz1 ? - new EGS_PlanesZ(zslab[0],zslab[1],nz,"",EGS_ZProjector("z-planes")) : - new EGS_PlanesZ(zpos,"",EGS_ZProjector("z-planes")); - EGS_XYZGeometry *result = new EGS_XYZGeometry(xp,yp,zp); - - if( result ) { - egsWarning("**********************************************\n"); - EGS_BaseGeometry *g = result; - result->setName(input); - g->setMedia(input); - result->voxelizeGeometry(input); - - // labels - result->setXYZLabels(input); - g->setLabels(input); - } - return result; - } #endif - vector dims; - EGS_Input *ij; - int error = 0; - while( (ij = input->takeInputItem("geometry",false)) != 0 ) { - EGS_BaseGeometry *g = EGS_BaseGeometry::createSingleGeometry(ij); - if( g ) { dims.push_back(g); g->ref(); } - else error++; - delete ij; - } - vector gnames; - int err1 = input->getInput("dimensions",gnames); - if( !err1 ) { - for(unsigned int j=0; jref(); } + vector dims; + EGS_Input *ij; + int error = 0; + while ((ij = input->takeInputItem("geometry",false)) != 0) { + EGS_BaseGeometry *g = EGS_BaseGeometry::createSingleGeometry(ij); + if (g) { + dims.push_back(g); + g->ref(); + } else { - egsWarning("Geometry %s does not exist\n",gnames[j].c_str()); error++; } + delete ij; } - } - if( error ) { - egsWarning("createGeometry(ND_Geometry): %d errors while " - "creating/geting geometries defining individual dimensions\n",error); - return 0; - } - if( dims.size() < 2 ) { - egsWarning("createGeometry(ND_Geometry): why do you want to " - "construct a ND geometry with a single dimension?\n"); - input->print(0,cerr); - for(int j=0; jisConvex() ) n_concav++; - bool is_ok = true; - if( n_concav > 1 ) { - egsWarning("createGeometry(ND_Geometry): a ND geometry can not have " - " more than one non-convex dimension, yours has %d\n",n_concav); - is_ok = false; - } - else if( n_concav == 1 ) { - if( dims[dims.size()-1]->isConvex() ) { - egsWarning("createGeometry(ND_Geometry): the non-convex " - "dimension must be the last dimension\n"); + vector gnames; + int err1 = input->getInput("dimensions",gnames); + if (!err1) { + for (unsigned int j=0; jref(); + } + else { + egsWarning("Geometry %s does not exist\n",gnames[j].c_str()); + error++; + } + } + } + if (error) { + egsWarning("createGeometry(ND_Geometry): %d errors while " + "creating/geting geometries defining individual dimensions\n",error); + return 0; + } + if (dims.size() < 2) { + egsWarning("createGeometry(ND_Geometry): why do you want to " + "construct a ND geometry with a single dimension?\n"); + input->print(0,cerr); + for (int j=0; jisConvex()) { + n_concav++; + } + bool is_ok = true; + if (n_concav > 1) { + egsWarning("createGeometry(ND_Geometry): a ND geometry can not have " + " more than one non-convex dimension, yours has %d\n",n_concav); is_ok = false; } + else if (n_concav == 1) { + if (dims[dims.size()-1]->isConvex()) { + egsWarning("createGeometry(ND_Geometry): the non-convex " + "dimension must be the last dimension\n"); + is_ok = false; + } + } + if (!is_ok) { + for (int j=0; jderef()) { + delete dims[j]; + } + return 0; + } + int hn_method=0; + err1 = input->getInput("hownear method",hn_method); + EGS_BaseGeometry *result; + if (!err1 && hn_method == 1) { + result = new EGS_NDGeometry(dims,"",false); + } + else { + result = new EGS_NDGeometry(dims); + } + result->setName(input); + result->setMedia(input); + result->setLabels(input); + return result; } - if( !is_ok ) { - for(int j=0; jderef() ) delete dims[j]; - return 0; - } - int hn_method=0; err1 = input->getInput("hownear method",hn_method); - EGS_BaseGeometry *result; - if( !err1 && hn_method == 1 ) result = new EGS_NDGeometry(dims,"",false); - else result = new EGS_NDGeometry(dims); - result->setName(input); - result->setMedia(input); - result->setLabels(input); - return result; -} -void EGS_XYZGeometry::setXYZLabels (EGS_Input *input) { + void EGS_XYZGeometry::setXYZLabels(EGS_Input *input) { - // x,y,z labels - string inp; - int err; + // x,y,z labels + string inp; + int err; - err = input->getInput("set x label", inp); - if (!err) xp->setLabels(inp); + err = input->getInput("set x label", inp); + if (!err) { + xp->setLabels(inp); + } - err = input->getInput("set y label", inp); - if (!err) yp->setLabels(inp); + err = input->getInput("set y label", inp); + if (!err) { + yp->setLabels(inp); + } - err = input->getInput("set z label", inp); - if (!err) zp->setLabels(inp); -} + err = input->getInput("set z label", inp); + if (!err) { + zp->setLabels(inp); + } + } -int EGS_NDGeometry::ndRegions (int r, int dim, int dimk, int k, vector ®s) { + int EGS_NDGeometry::ndRegions(int r, int dim, int dimk, int k, vector ®s) { - // skip looping over selected dimension - if (dim == dimk) { - r += k*n[dimk]; - if (dim == N-1) regs.push_back(r); - else ndRegions(r, dim+1, dimk, k, regs); - } + // skip looping over selected dimension + if (dim == dimk) { + r += k*n[dimk]; + if (dim == N-1) { + regs.push_back(r); + } + else { + ndRegions(r, dim+1, dimk, k, regs); + } + } - // last dimension: end recursion and record global region number - else if (dim == N-1) { - for (int j=0; jregions(); j++) { - regs.push_back(r+j*n[dim]); + // last dimension: end recursion and record global region number + else if (dim == N-1) { + for (int j=0; jregions(); j++) { + regs.push_back(r+j*n[dim]); + } } - } - // keep collecting by recursion - else { - for (int j=0; jregions(); j++) { - ndRegions(r + j*n[dim], dim+1, dimk, k, regs); + // keep collecting by recursion + else { + for (int j=0; jregions(); j++) { + ndRegions(r + j*n[dim], dim+1, dimk, k, regs); + } } } -} -void EGS_NDGeometry::getLabelRegions (const string &str, vector ®s) { + void EGS_NDGeometry::getLabelRegions(const string &str, vector ®s) { - // label defined in the sub-geometries - vector local_regs; - for (int i=0; igetLabelRegions(str, local_regs); - if (local_regs.size() == 0) continue; + // label defined in the sub-geometries + vector local_regs; + for (int i=0; igetLabelRegions(str, local_regs); + } + if (local_regs.size() == 0) { + continue; + } - // recurse to collect all global regions comprised in each local region - for (int j=0; j ®s) { + void EGS_XYZGeometry::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // x plane labels - local_regs.clear(); - xp->getLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; igetLabelRegions(str, local_regs); - for (int j=0; jgetLabelRegions(str, local_regs); + for (int j=0; jgetLabelRegions(str, local_regs); - for (int k=0; kgetLabelRegions(str, local_regs); + for (int k=0; k ®s) { + void EGS_XYZRepeater::getLabelRegions(const string &str, vector ®s) { - vector local_regs; + vector local_regs; - // label in repeated geometry - local_regs.clear(); - g->getLabelRegions(str, local_regs); - for (int i=0; igetLabelRegions(str, local_regs); + for (int i=0; igetXLabelRegions(str, local_regs); - for (int i=0; igetXLabelRegions(str, local_regs); + for (int i=0; igetYLabelRegions(str, local_regs); - for (int j=0; jgetYLabelRegions(str, local_regs); + for (int j=0; jgetZLabelRegions(str, local_regs); - for (int k=0; kgetZLabelRegions(str, local_regs); + for (int k=0; k &G, const string &Name = "", - bool O=true); - - ~EGS_NDGeometry(); - - bool isInside(const EGS_Vector &x) { - for(int j=0; jisInside(x) ) return false; - return true; - }; - - int isWhere(const EGS_Vector &x) { - int ireg = 0; - for(int j=0; jisWhere(x); - if( ij < 0 ) return -1; - ireg += ij*n[j]; - } - return ireg; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - int itmp = ireg; EGS_Float d = 1e30; - for(int j=N-1; j>=0; j--) { - int l = itmp/n[j]; - EGS_Float t = g[j]->howfarToOutside(l,x,u); - if( t <= 0 ) return t; - if( t < d ) d = t; - } - return d; - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - int itmp = ireg; int inext = -1, idelta, lnew_j; - for(int j=N-1; j>=0; j--) { - int l = itmp/n[j]; - int lnew = g[j]->howfar(l,x,u,t,0,normal); - if( lnew != l ) { - inext = j; idelta = lnew - l; lnew_j = lnew; - } - itmp -= l*n[j]; - } - if( inext < 0 ) return ireg; - int inew = lnew_j >= 0 ? ireg + idelta*n[inext] : lnew_j; - //if( lnew_j < 0 ) return lnew_j; - //int inew = ireg + idelta*n[inext]; - if( newmed ) - *newmed = inew >= 0 ? medium(inew) : -1; - return inew; - } - for(int j=0; jisInside(x); - // Note: this logic fails if the geometry is not convex! - if( !is_in ) { - EGS_Vector nn, *np=0; - if( normal ) np = &nn; - int i = g[j]->howfar(ireg,x,u,tj,0,np); - if( i >= 0 ) { - EGS_Vector tmp(x + u*tj); - bool is_ok = true; - int res = 0; - for(int k=0; kisWhere(tmp); - if( check < 0 ) { is_ok = false; break; } - res += check*n[k]; - } - } - if( is_ok ) { - t = tj; res += i*n[j]; - if( newmed ) *newmed = medium(res); - if( normal ) *normal = nn; - return res; - } - } - } - // and so, to fix it, we do the following for non-convex - // dimensions. But this only works if and only if there - // is not more than 1 non-convex dimension and this - // dimension is last in the list. - else if( !g[j]->isConvex() ) { - EGS_Vector tmp(x); EGS_Float tleft = t; - int ii = g[j]->isWhere(x); - EGS_Float ttot = 0; - while(1) { - EGS_Float tt = tleft; - int inew = g[j]->howfar(ii,tmp,u,tt); - if( inew == ii ) break; - tleft -= tt; tmp += u*tt; ii = inew; ttot += tt; - //egsWarning(" inew = %d tt = %g ttot = %g tmp = (%g,%g,%g)\n",inew,tt,ttot,tmp.x,tmp.y,tmp.z); - if( ii < 0 ) break; - } - //egsWarning("doing non-convex part: x = (%g,%g,%g) ii = %d t = %g ttot = %g\n",x.x,x.y,x.z,ii,t,ttot); - if( ii < 0 ) { - EGS_Vector nn, *np = normal ? &nn : 0; - EGS_Float tt = tleft; - int inew = g[j]->howfar(ii,tmp,u,tt,0,np); - //egsWarning(" exited and tried to reenter: %d %g\n",inew,ttot+tt); - if( inew >= 0 ) { - tmp += u*tt; bool is_ok = true; int res = 0; - for(int k=0; kisWhere(tmp); - if( check < 0 ) { is_ok = false; break; } - res += check*n[k]; - } - } - if( is_ok ) { - t = ttot + tt; res += inew*n[j]; - if( newmed ) *newmed = medium(res); - if( normal ) *normal = nn; - return res; - } - } - } - } - } - return -1; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - EGS_Float tmin = 1e30; - if( ireg >= 0 ) { - int itmp = ireg; - for(int j=N-1; j>=0; j--) { - int l = itmp/n[j]; - EGS_Float t = g[j]->hownear(l,x); - if( t < tmin ) { - tmin = t; if( tmin <= 0 ) return 0; - } - itmp -= l*n[j]; - } - return tmin; - } - if( ortho ) { - int nc = 0; EGS_Float s1=0, s2=0; - for(int j=0; jisInside(x) ) { - EGS_Float t = g[j]->hownear(-1,x); - nc++; s1 += t; s2 += t*t; - } - } - if( nc == 1 ) return s1; - return sqrt(s2); - } else { - EGS_Float tmin = 1e30; - for(int j=0; jisWhere(x); - t = g[j]->hownear(i,x); - if( t < tmin ) { tmin = t; if( tmin <= 0 ) return 0; } - } - return tmin; - } - }; - - int getMaxStep() const { - int nstep = 1; - for(int j=0; jgetMaxStep(); - return nstep; - }; - - const string &getType() const { return type; }; - - void printInfo() const; - - virtual void getLabelRegions (const string &str, vector ®s); - int ndRegions (int r, int dim, int dimk, int k, vector ®s); + /*! Construct a N-dimensional geometry from the \a ng dimensions \a G. + */ + EGS_NDGeometry(int ng, EGS_BaseGeometry **G, const string &Name = "", + bool O=true); + + /*! Construct a N-dimensional the array of dimensions \a G. */ + EGS_NDGeometry(vector &G, const string &Name = "", + bool O=true); + + ~EGS_NDGeometry(); + + bool isInside(const EGS_Vector &x) { + for (int j=0; jisInside(x)) { + return false; + } + return true; + }; + + int isWhere(const EGS_Vector &x) { + int ireg = 0; + for (int j=0; jisWhere(x); + if (ij < 0) { + return -1; + } + ireg += ij*n[j]; + } + return ireg; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + int itmp = ireg; + EGS_Float d = 1e30; + for (int j=N-1; j>=0; j--) { + int l = itmp/n[j]; + EGS_Float t = g[j]->howfarToOutside(l,x,u); + if (t <= 0) { + return t; + } + if (t < d) { + d = t; + } + } + return d; + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + if (ireg >= 0) { + int itmp = ireg; + int inext = -1, idelta, lnew_j; + for (int j=N-1; j>=0; j--) { + int l = itmp/n[j]; + int lnew = g[j]->howfar(l,x,u,t,0,normal); + if (lnew != l) { + inext = j; + idelta = lnew - l; + lnew_j = lnew; + } + itmp -= l*n[j]; + } + if (inext < 0) { + return ireg; + } + int inew = lnew_j >= 0 ? ireg + idelta*n[inext] : lnew_j; + //if( lnew_j < 0 ) return lnew_j; + //int inew = ireg + idelta*n[inext]; + if (newmed) { + *newmed = inew >= 0 ? medium(inew) : -1; + } + return inew; + } + for (int j=0; jisInside(x); + // Note: this logic fails if the geometry is not convex! + if (!is_in) { + EGS_Vector nn, *np=0; + if (normal) { + np = &nn; + } + int i = g[j]->howfar(ireg,x,u,tj,0,np); + if (i >= 0) { + EGS_Vector tmp(x + u*tj); + bool is_ok = true; + int res = 0; + for (int k=0; kisWhere(tmp); + if (check < 0) { + is_ok = false; + break; + } + res += check*n[k]; + } + } + if (is_ok) { + t = tj; + res += i*n[j]; + if (newmed) { + *newmed = medium(res); + } + if (normal) { + *normal = nn; + } + return res; + } + } + } + // and so, to fix it, we do the following for non-convex + // dimensions. But this only works if and only if there + // is not more than 1 non-convex dimension and this + // dimension is last in the list. + else if (!g[j]->isConvex()) { + EGS_Vector tmp(x); + EGS_Float tleft = t; + int ii = g[j]->isWhere(x); + EGS_Float ttot = 0; + while (1) { + EGS_Float tt = tleft; + int inew = g[j]->howfar(ii,tmp,u,tt); + if (inew == ii) { + break; + } + tleft -= tt; + tmp += u*tt; + ii = inew; + ttot += tt; + //egsWarning(" inew = %d tt = %g ttot = %g tmp = (%g,%g,%g)\n",inew,tt,ttot,tmp.x,tmp.y,tmp.z); + if (ii < 0) { + break; + } + } + //egsWarning("doing non-convex part: x = (%g,%g,%g) ii = %d t = %g ttot = %g\n",x.x,x.y,x.z,ii,t,ttot); + if (ii < 0) { + EGS_Vector nn, *np = normal ? &nn : 0; + EGS_Float tt = tleft; + int inew = g[j]->howfar(ii,tmp,u,tt,0,np); + //egsWarning(" exited and tried to reenter: %d %g\n",inew,ttot+tt); + if (inew >= 0) { + tmp += u*tt; + bool is_ok = true; + int res = 0; + for (int k=0; kisWhere(tmp); + if (check < 0) { + is_ok = false; + break; + } + res += check*n[k]; + } + } + if (is_ok) { + t = ttot + tt; + res += inew*n[j]; + if (newmed) { + *newmed = medium(res); + } + if (normal) { + *normal = nn; + } + return res; + } + } + } + } + } + return -1; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + EGS_Float tmin = 1e30; + if (ireg >= 0) { + int itmp = ireg; + for (int j=N-1; j>=0; j--) { + int l = itmp/n[j]; + EGS_Float t = g[j]->hownear(l,x); + if (t < tmin) { + tmin = t; + if (tmin <= 0) { + return 0; + } + } + itmp -= l*n[j]; + } + return tmin; + } + if (ortho) { + int nc = 0; + EGS_Float s1=0, s2=0; + for (int j=0; jisInside(x)) { + EGS_Float t = g[j]->hownear(-1,x); + nc++; + s1 += t; + s2 += t*t; + } + } + if (nc == 1) { + return s1; + } + return sqrt(s2); + } + else { + EGS_Float tmin = 1e30; + for (int j=0; jisWhere(x); + t = g[j]->hownear(i,x); + if (t < tmin) { + tmin = t; + if (tmin <= 0) { + return 0; + } + } + } + return tmin; + } + }; + + int getMaxStep() const { + int nstep = 1; + for (int j=0; jgetMaxStep(); + } + return nstep; + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + virtual void getLabelRegions(const string &str, vector ®s); + int ndRegions(int r, int dim, int dimk, int k, vector ®s); protected: - int N; //!< Number of dimensions - EGS_BaseGeometry **g; //!< The dimensions - int *n; //!< Used for calculating region indeces - static string type; //!< The geometry type - bool ortho; //!< Is the geometry orthogonal ? + int N; //!< Number of dimensions + EGS_BaseGeometry **g; //!< The dimensions + int *n; //!< Used for calculating region indeces + static string type; //!< The geometry type + bool ortho; //!< Is the geometry orthogonal ? - void setup(); + void setup(); - /*! \brief Define media. + /*! \brief Define media. - This function is re-implemented to permit easier media definition - in a N-dimensional geometry. + This function is re-implemented to permit easier media definition + in a N-dimensional geometry. - */ - void setMedia(EGS_Input *inp, int nmed, const int *med_ind); + */ + void setMedia(EGS_Input *inp, int nmed, const int *med_ind); private: - void setM(int ib, int idim, const vector &ranges, int medium); + void setM(int ib, int idim, const vector &ranges, int medium); }; #ifdef EXPLICIT_XYZ @@ -539,371 +605,590 @@ class EGS_NDG_EXPORT EGS_XYZGeometry : public EGS_BaseGeometry { public: - EGS_XYZGeometry(EGS_PlanesX *Xp, EGS_PlanesY *Yp, EGS_PlanesZ *Zp, - const string &Name = ""); - - ~EGS_XYZGeometry(); - - bool isInside(const EGS_Vector &x) { - if( !xp->isInside(x) ) return false; - if( !yp->isInside(x) ) return false; - if( !zp->isInside(x) ) return false; - return true; - }; - - int isWhere(const EGS_Vector &x) { - int ix = xp->isWhere(x); if( ix < 0 ) return ix; - int iy = yp->isWhere(x); if( iy < 0 ) return iy; - int iz = zp->isWhere(x); if( iz < 0 ) return iz; - return ix + iy*nx + iz*nxy; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { - if( n < 1 ) return -1; - int ifirst = 0; EGS_Float t, t_ini = 0; EGS_Vector x(X); int imed; - if( ireg < 0 ) { - t = 1e30; ireg = howfar(ireg,x,u,t,&imed); - if( ireg < 0 ) return 0; - isections[0].t = t; isections[0].rhof = 1; - isections[0].ireg = -1; isections[0].imed = -1; - t_ini = t; ++ifirst; x += u*t; - } - else imed = medium(ireg); - EGS_Float *px = xp->getPositions(), - *py = yp->getPositions(), + EGS_XYZGeometry(EGS_PlanesX *Xp, EGS_PlanesY *Yp, EGS_PlanesZ *Zp, + const string &Name = ""); + + ~EGS_XYZGeometry(); + + bool isInside(const EGS_Vector &x) { + if (!xp->isInside(x)) { + return false; + } + if (!yp->isInside(x)) { + return false; + } + if (!zp->isInside(x)) { + return false; + } + return true; + }; + + int isWhere(const EGS_Vector &x) { + int ix = xp->isWhere(x); + if (ix < 0) { + return ix; + } + int iy = yp->isWhere(x); + if (iy < 0) { + return iy; + } + int iz = zp->isWhere(x); + if (iz < 0) { + return iz; + } + return ix + iy*nx + iz*nxy; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int computeIntersections(int ireg, int n, const EGS_Vector &X, + const EGS_Vector &u, EGS_GeometryIntersections *isections) { + if (n < 1) { + return -1; + } + int ifirst = 0; + EGS_Float t, t_ini = 0; + EGS_Vector x(X); + int imed; + if (ireg < 0) { + t = 1e30; + ireg = howfar(ireg,x,u,t,&imed); + if (ireg < 0) { + return 0; + } + isections[0].t = t; + isections[0].rhof = 1; + isections[0].ireg = -1; + isections[0].imed = -1; + t_ini = t; + ++ifirst; + x += u*t; + } + else { + imed = medium(ireg); + } + EGS_Float *px = xp->getPositions(), + *py = yp->getPositions(), *pz = zp->getPositions(); - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - EGS_Float uxi, uyi, uzi, nextx, nexty, nextz; - int dirx, icx, diry, icy, dirz, icz; - if( u.x > 0 ) { uxi = 1/u.x; dirx = 1; icx = 1; } - else if( u.x < 0 ) { uxi = 1/u.x; dirx = -1; icx = 0; } - else { uxi = 1e33; dirx = 1; icx = 1; } - if( u.y > 0 ) { uyi = 1/u.y; diry = 1; icy = 1; } - else if( u.y < 0 ) { uyi = 1/u.y; diry = -1; icy = 0; } - else { uyi = 1e33; diry = 1; icy = 1; } - if( u.z > 0 ) { uzi = 1/u.z; dirz = 1; icz = 1; } - else if( u.z < 0 ) { uzi = 1/u.z; dirz = -1; icz = 0; } - else { uzi = 1e33; dirz = 1; icz = 1; } - nextx = (px[ix+icx] - x.x)*uxi + t_ini; - nexty = (py[iy+icy] - x.y)*uyi + t_ini; - nextz = (pz[iz+icz] - x.z)*uzi + t_ini; - for(int j=ifirst; j= nx ) inew = -1; - else { - inew = ireg + dirx; nextx = (px[ix+icx] - x.x)*uxi + t_ini; - } - } - else if( nexty < nextz ) { - t = nexty; iy += diry; - if( iy < 0 || iy >= ny ) inew = -1; - else { - inew = ireg + nx*diry; nexty = (py[iy+icy] - x.y)*uyi + t_ini; - } - } - else { - t = nextz; iz += dirz; - if( iz < 0 || iz >= nz ) inew = -1; - else { - inew = ireg + nxy*dirz; nextz = (pz[iz+icz] - x.z)*uzi + t_ini; - } - } - isections[j].t = t; - if( inew < 0 ) return j+1; - ireg = inew; imed = medium(ireg); - } - return ireg >= 0 ? -1 : n; - }; - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - EGS_Float d = xp->howfarToOutside(ix,x,u); - EGS_Float ty = yp->howfarToOutside(iy,x,u); if( ty < d ) d = ty; - EGS_Float tz = zp->howfarToOutside(iz,x,u); if( tz < d ) d = tz; - return d; - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - int inew = ireg; - if( u.x > 0 ) { - EGS_Float d = (xpos[ix+1]-x.x)/u.x; - if( d <= t ) { - t = d; if( (++ix) < nx ) inew = ireg + 1; else inew = -1; - if( normal ) *normal = EGS_Vector(-1,0,0); - } - } - else if( u.x < 0 ) { - EGS_Float d = (xpos[ix]-x.x)/u.x; - if( d <= t ) { - t = d; if( (--ix) >= 0 ) inew = ireg - 1; else inew = -1; - if( normal ) *normal = EGS_Vector(1,0,0); - } - } - if( u.y > 0 ) { - EGS_Float d = (ypos[iy+1]-x.y)/u.y; - if( d <= t ) { - t = d; if( (++iy) < ny ) inew = ireg + nx; else inew = -1; - if( normal ) *normal = EGS_Vector(0,-1,0); - } - } - else if( u.y < 0 ) { - EGS_Float d = (ypos[iy]-x.y)/u.y; - if( d <= t ) { - t = d; if( (--iy) >= 0 ) inew = ireg - nx; else inew = -1; - if( normal ) *normal = EGS_Vector(0,1,0); - } - } - if( u.z > 0 ) { - EGS_Float d = (zpos[iz+1]-x.z)/u.z; - if( d <= t ) { - t = d; if( (++iz) < nz ) inew = ireg+nxy; else inew = -1; - if( normal ) *normal = EGS_Vector(0,0,-1); - } - } - else if( u.z < 0 ) { - EGS_Float d = (zpos[iz]-x.z)/u.z; - if( d <= t ) { - t = d; if( (--iz) >= 0 ) inew = ireg-nxy; else inew = -1; - if( normal ) *normal = EGS_Vector(0,0,1); - } - } - if( newmed && inew >= 0 ) *newmed = medium(inew); - return inew; - } - int face,ix,iy,iz; - int inew = howfarFromOut(x,u,t,ix,iy,iz,face,normal); - if( inew >= 0 && newmed ) *newmed = medium(inew); - return inew; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - EGS_Float t = xp->hownear(ix,x); - EGS_Float t1 = yp->hownear(iy,x); - if( t1 < t ) t = t1; - t1 = zp->hownear(iz,x); - if( t1 < t ) t = t1; - return t; - } - int nc = 0; EGS_Float s1=0, s2=0; - if( !xp->isInside(x) ) { - EGS_Float t = xp->hownear(-1,x); - nc++; s1 += t; s2 += t*t; - } - if( !yp->isInside(x) ) { - EGS_Float t = yp->hownear(-1,x); - nc++; s1 += t; s2 += t*t; - } - if( !zp->isInside(x) ) { - EGS_Float t = zp->hownear(-1,x); - nc++; s1 += t; s2 += t*t; - } - if( nc == 1 ) return s1; - return sqrt(s2); - }; - - - EGS_Float getMass(int ireg) { - if( ireg >= 0 ) { - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - EGS_Float vol = (xpos[ix+1]-xpos[ix])*(ypos[iy+1]-ypos[iy])* - (zpos[iz+1]-zpos[iz]); - EGS_Float dens = getRelativeRho(ireg); - EGS_Float mass = vol*dens; - return mass; - } - else { - return 1.0; - } - } - - EGS_Float getBound(int idir, int ind) { - EGS_Float bound; - if(idir == 0) { - if(ind>=0 && ind<=nx) bound = xpos[ind]; + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + EGS_Float uxi, uyi, uzi, nextx, nexty, nextz; + int dirx, icx, diry, icy, dirz, icz; + if (u.x > 0) { + uxi = 1/u.x; + dirx = 1; + icx = 1; + } + else if (u.x < 0) { + uxi = 1/u.x; + dirx = -1; + icx = 0; + } + else { + uxi = 1e33; + dirx = 1; + icx = 1; + } + if (u.y > 0) { + uyi = 1/u.y; + diry = 1; + icy = 1; + } + else if (u.y < 0) { + uyi = 1/u.y; + diry = -1; + icy = 0; + } + else { + uyi = 1e33; + diry = 1; + icy = 1; + } + if (u.z > 0) { + uzi = 1/u.z; + dirz = 1; + icz = 1; + } + else if (u.z < 0) { + uzi = 1/u.z; + dirz = -1; + icz = 0; + } + else { + uzi = 1e33; + dirz = 1; + icz = 1; + } + nextx = (px[ix+icx] - x.x)*uxi + t_ini; + nexty = (py[iy+icy] - x.y)*uyi + t_ini; + nextz = (pz[iz+icz] - x.z)*uzi + t_ini; + for (int j=ifirst; j= nx) { + inew = -1; + } + else { + inew = ireg + dirx; + nextx = (px[ix+icx] - x.x)*uxi + t_ini; + } + } + else if (nexty < nextz) { + t = nexty; + iy += diry; + if (iy < 0 || iy >= ny) { + inew = -1; + } + else { + inew = ireg + nx*diry; + nexty = (py[iy+icy] - x.y)*uyi + t_ini; + } + } else { - egsWarning("Error in getBound: Looking for X bound out of range %d\n" - "Will set this to zero.\n",ind); - bound = 0.0; + t = nextz; + iz += dirz; + if (iz < 0 || iz >= nz) { + inew = -1; + } + else { + inew = ireg + nxy*dirz; + nextz = (pz[iz+icz] - x.z)*uzi + t_ini; + } + } + isections[j].t = t; + if (inew < 0) { + return j+1; + } + ireg = inew; + imed = medium(ireg); + } + return ireg >= 0 ? -1 : n; + }; + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + EGS_Float d = xp->howfarToOutside(ix,x,u); + EGS_Float ty = yp->howfarToOutside(iy,x,u); + if (ty < d) { + d = ty; + } + EGS_Float tz = zp->howfarToOutside(iz,x,u); + if (tz < d) { + d = tz; + } + return d; + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + if (ireg >= 0) { + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + int inew = ireg; + if (u.x > 0) { + EGS_Float d = (xpos[ix+1]-x.x)/u.x; + if (d <= t) { + t = d; + if ((++ix) < nx) { + inew = ireg + 1; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(-1,0,0); + } + } + } + else if (u.x < 0) { + EGS_Float d = (xpos[ix]-x.x)/u.x; + if (d <= t) { + t = d; + if ((--ix) >= 0) { + inew = ireg - 1; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(1,0,0); + } + } + } + if (u.y > 0) { + EGS_Float d = (ypos[iy+1]-x.y)/u.y; + if (d <= t) { + t = d; + if ((++iy) < ny) { + inew = ireg + nx; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,-1,0); + } + } + } + else if (u.y < 0) { + EGS_Float d = (ypos[iy]-x.y)/u.y; + if (d <= t) { + t = d; + if ((--iy) >= 0) { + inew = ireg - nx; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,1,0); + } + } + } + if (u.z > 0) { + EGS_Float d = (zpos[iz+1]-x.z)/u.z; + if (d <= t) { + t = d; + if ((++iz) < nz) { + inew = ireg+nxy; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,0,-1); + } + } + } + else if (u.z < 0) { + EGS_Float d = (zpos[iz]-x.z)/u.z; + if (d <= t) { + t = d; + if ((--iz) >= 0) { + inew = ireg-nxy; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,0,1); + } + } + } + if (newmed && inew >= 0) { + *newmed = medium(inew); + } + return inew; + } + int face,ix,iy,iz; + int inew = howfarFromOut(x,u,t,ix,iy,iz,face,normal); + if (inew >= 0 && newmed) { + *newmed = medium(inew); + } + return inew; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + EGS_Float t = xp->hownear(ix,x); + EGS_Float t1 = yp->hownear(iy,x); + if (t1 < t) { + t = t1; + } + t1 = zp->hownear(iz,x); + if (t1 < t) { + t = t1; + } + return t; + } + int nc = 0; + EGS_Float s1=0, s2=0; + if (!xp->isInside(x)) { + EGS_Float t = xp->hownear(-1,x); + nc++; + s1 += t; + s2 += t*t; + } + if (!yp->isInside(x)) { + EGS_Float t = yp->hownear(-1,x); + nc++; + s1 += t; + s2 += t*t; + } + if (!zp->isInside(x)) { + EGS_Float t = zp->hownear(-1,x); + nc++; + s1 += t; + s2 += t*t; + } + if (nc == 1) { + return s1; + } + return sqrt(s2); + }; + + + EGS_Float getMass(int ireg) { + if (ireg >= 0) { + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + EGS_Float vol = (xpos[ix+1]-xpos[ix])*(ypos[iy+1]-ypos[iy])* + (zpos[iz+1]-zpos[iz]); + EGS_Float dens = getRelativeRho(ireg); + EGS_Float mass = vol*dens; + return mass; + } + else { + return 1.0; + } + } + + EGS_Float getBound(int idir, int ind) { + EGS_Float bound; + if (idir == 0) { + if (ind>=0 && ind<=nx) { + bound = xpos[ind]; } - } - else if(idir == 1) { - if(ind>=0 && ind<=ny) bound = ypos[ind]; else { - egsWarning("Error in getBound: Looking for Y bound out of range %d\n" - "Will set this to zero.\n",ind); - bound = 0.0; + egsWarning("Error in getBound: Looking for X bound out of range %d\n" + "Will set this to zero.\n",ind); + bound = 0.0; + } + } + else if (idir == 1) { + if (ind>=0 && ind<=ny) { + bound = ypos[ind]; } - } - else if(idir == 2) { - if(ind>=0 && ind<=nz) bound = zpos[ind]; else { - egsWarning("Error in getBound: Looking for Z bound out of range %d\n" - "Will set this to zero.\n",ind); - bound = 0.0; + egsWarning("Error in getBound: Looking for Y bound out of range %d\n" + "Will set this to zero.\n",ind); + bound = 0.0; } - } - else { + } + else if (idir == 2) { + if (ind>=0 && ind<=nz) { + bound = zpos[ind]; + } + else { + egsWarning("Error in getBound: Looking for Z bound out of range %d\n" + "Will set this to zero.\n",ind); + bound = 0.0; + } + } + else { egsWarning("Error in getBound: Dimension %d undefined in EGS_XYZGeometry.\n",idir); bound = 0.0; - } - return bound; - } - - int getNRegDir(int idir) { - if(idir==0) return nx; - else if(idir==1) return ny; - else if(idir==2) return nz; - else { + } + return bound; + } + + int getNRegDir(int idir) { + if (idir==0) { + return nx; + } + else if (idir==1) { + return ny; + } + else if (idir==2) { + return nz; + } + else { egsWarning("Error in getNregDir: Dimension %d undefined in EGS_XYZGeometry.\n", idir); return 0; - } - } + } + } - int getMaxStep() const { return nx+ny+nz+1; }; + int getMaxStep() const { + return nx+ny+nz+1; + }; - int getNx() const { return nx; }; - int getNy() const { return ny; }; - int getNz() const { return nz; }; + int getNx() const { + return nx; + }; + int getNy() const { + return ny; + }; + int getNz() const { + return nz; + }; - EGS_Float *getXPositions() { return xp->getPositions(); }; - EGS_Float *getYPositions() { return yp->getPositions(); }; - EGS_Float *getZPositions() { return zp->getPositions(); }; + EGS_Float *getXPositions() { + return xp->getPositions(); + }; + EGS_Float *getYPositions() { + return yp->getPositions(); + }; + EGS_Float *getZPositions() { + return zp->getPositions(); + }; - static int getDigits(int i); + static int getDigits(int i); - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; - void printInfo() const; + void printInfo() const; - static EGS_XYZGeometry* constructGeometry(const char *dens_or_egphant_file, - const char *ramp_file, int dens_or_egphant=0); - static EGS_XYZGeometry* constructCTGeometry(const char *dens_or_egphant_file); + static EGS_XYZGeometry *constructGeometry(const char *dens_or_egphant_file, + const char *ramp_file, int dens_or_egphant=0); + static EGS_XYZGeometry *constructCTGeometry(const char *dens_or_egphant_file); - void voxelizeGeometry(EGS_Input *input); + void voxelizeGeometry(EGS_Input *input); - void setXYZLabels (EGS_Input *input); + void setXYZLabels(EGS_Input *input); - virtual void getLabelRegions (const string &str, vector ®s); - void getXLabelRegions (const string &str, vector ®s) { xp->getLabelRegions(str, regs); } - void getYLabelRegions (const string &str, vector ®s) { yp->getLabelRegions(str, regs); } - void getZLabelRegions (const string &str, vector ®s) { zp->getLabelRegions(str, regs); } + virtual void getLabelRegions(const string &str, vector ®s); + void getXLabelRegions(const string &str, vector ®s) { + xp->getLabelRegions(str, regs); + } + void getYLabelRegions(const string &str, vector ®s) { + yp->getLabelRegions(str, regs); + } + void getZLabelRegions(const string &str, vector ®s) { + zp->getLabelRegions(str, regs); + } protected: - EGS_PlanesX *xp; - EGS_PlanesY *yp; - EGS_PlanesZ *zp; - EGS_Float *xpos; - EGS_Float *ypos; - EGS_Float *zpos; - int nx, ny, nz, nxy; - static string type; - - void setup(); - - void setMedia(EGS_Input *inp, int nmed, const int *med_ind); - - int howfarFromOut(const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int &ix, int &iy, int &iz, - int &face, EGS_Vector *normal=0) { - ix = -1; EGS_Float t1; - if( x.x <= xpos[0] && u.x > 0 ) { - t1 = (xpos[0]-x.x)/u.x; ix = 0; face = 0; - } - else if( x.x >= xpos[nx] && u.x < 0 ) { - t1 = (xpos[nx]-x.x)/u.x; ix = nx-1; face = 1; - } - if( ix >= 0 && t1 <= t ) { - EGS_Vector tmp(x + u*t1); - iy = yp->isWhere(tmp); - if( iy >= 0 ) { - iz = zp->isWhere(tmp); - if( iz >= 0 ) { - int inew = ix + iy*nx + iz*nxy; - if (t1 < epsilon) { - int itest = howfar(inew, tmp, u, t1); - if (itest == -1 && t1 < epsilon) return -1; - } - if( normal ) *normal = face == 0 ? EGS_Vector(-1,0,0) : - EGS_Vector( 1,0,0); - t = t1; - return inew; - } - } - } - iy = -1; - if( x.y <= ypos[0] && u.y > 0 ) { - t1 = (ypos[0]-x.y)/u.y; iy = 0; face = 2; - } - else if( x.y >= ypos[ny] && u.y < 0 ) { - t1 = (ypos[ny]-x.y)/u.y; iy = ny-1; face = 3; - } - if( iy >= 0 && t1 <= t ) { - EGS_Vector tmp(x + u*t1); - ix = xp->isWhere(tmp); - if( ix >= 0 ) { - iz = zp->isWhere(tmp); - if( iz >= 0 ) { - int inew = ix + iy*nx + iz*nxy; - if (t1 < epsilon) { - int itest = howfar(inew, tmp, u, t1); - if (itest == -1 && t1 < epsilon) return -1; - } - if( normal ) *normal = face == 2 ? EGS_Vector(0,-1,0) : - EGS_Vector(0, 1,0); - t = t1; - return inew; - } - } - } - iz = -1; - if( x.z <= zpos[0] && u.z > 0 ) { - t1 = (zpos[0]-x.z)/u.z; iz = 0; face = 4; - } - else if( x.z >= zpos[nz] && u.z < 0 ) { - t1 = (zpos[nz]-x.z)/u.z; iz = nz-1; face = 5; - } - if( iz >= 0 && t1 <= t ) { - EGS_Vector tmp(x + u*t1); - ix = xp->isWhere(tmp); - if( ix >= 0 ) { - iy = yp->isWhere(tmp); - if( iy >= 0 ) { - int inew = ix + iy*nx + iz*nxy; - if (t1 < epsilon) { - int itest = howfar(inew, tmp, u, t1); - if (itest == -1 && t1 < epsilon) return -1; - } - if( normal ) *normal = face == 4 ? EGS_Vector(0,0,-1) : - EGS_Vector(0,0, 1); - t = t1; - return inew; - } - } - } - return -1; - }; + EGS_PlanesX *xp; + EGS_PlanesY *yp; + EGS_PlanesZ *zp; + EGS_Float *xpos; + EGS_Float *ypos; + EGS_Float *zpos; + int nx, ny, nz, nxy; + static string type; + + void setup(); + + void setMedia(EGS_Input *inp, int nmed, const int *med_ind); + + int howfarFromOut(const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int &ix, int &iy, int &iz, + int &face, EGS_Vector *normal=0) { + ix = -1; + EGS_Float t1; + if (x.x <= xpos[0] && u.x > 0) { + t1 = (xpos[0]-x.x)/u.x; + ix = 0; + face = 0; + } + else if (x.x >= xpos[nx] && u.x < 0) { + t1 = (xpos[nx]-x.x)/u.x; + ix = nx-1; + face = 1; + } + if (ix >= 0 && t1 <= t) { + EGS_Vector tmp(x + u*t1); + iy = yp->isWhere(tmp); + if (iy >= 0) { + iz = zp->isWhere(tmp); + if (iz >= 0) { + int inew = ix + iy*nx + iz*nxy; + if (t1 < epsilon) { + int itest = howfar(inew, tmp, u, t1); + if (itest == -1 && t1 < epsilon) { + return -1; + } + } + if (normal) *normal = face == 0 ? EGS_Vector(-1,0,0) : + EGS_Vector(1,0,0); + t = t1; + return inew; + } + } + } + iy = -1; + if (x.y <= ypos[0] && u.y > 0) { + t1 = (ypos[0]-x.y)/u.y; + iy = 0; + face = 2; + } + else if (x.y >= ypos[ny] && u.y < 0) { + t1 = (ypos[ny]-x.y)/u.y; + iy = ny-1; + face = 3; + } + if (iy >= 0 && t1 <= t) { + EGS_Vector tmp(x + u*t1); + ix = xp->isWhere(tmp); + if (ix >= 0) { + iz = zp->isWhere(tmp); + if (iz >= 0) { + int inew = ix + iy*nx + iz*nxy; + if (t1 < epsilon) { + int itest = howfar(inew, tmp, u, t1); + if (itest == -1 && t1 < epsilon) { + return -1; + } + } + if (normal) *normal = face == 2 ? EGS_Vector(0,-1,0) : + EGS_Vector(0, 1,0); + t = t1; + return inew; + } + } + } + iz = -1; + if (x.z <= zpos[0] && u.z > 0) { + t1 = (zpos[0]-x.z)/u.z; + iz = 0; + face = 4; + } + else if (x.z >= zpos[nz] && u.z < 0) { + t1 = (zpos[nz]-x.z)/u.z; + iz = nz-1; + face = 5; + } + if (iz >= 0 && t1 <= t) { + EGS_Vector tmp(x + u*t1); + ix = xp->isWhere(tmp); + if (ix >= 0) { + iy = yp->isWhere(tmp); + if (iy >= 0) { + int inew = ix + iy*nx + iz*nxy; + if (t1 < epsilon) { + int itest = howfar(inew, tmp, u, t1); + if (itest == -1 && t1 < epsilon) { + return -1; + } + } + if (normal) *normal = face == 4 ? EGS_Vector(0,0,-1) : + EGS_Vector(0,0, 1); + t = t1; + return inew; + } + } + } + return -1; + }; }; /*! \brief A deformed XYZ-geometry @@ -925,27 +1210,32 @@ class EGS_NDG_EXPORT EGS_DeformedXYZ : public EGS_XYZGeometry { public: EGS_DeformedXYZ(EGS_PlanesX *Xp, EGS_PlanesY *Yp, EGS_PlanesZ *Zp, - const char *defFile, const string &Name = ""); + const char *defFile, const string &Name = ""); ~EGS_DeformedXYZ(); int isWhere(const EGS_Vector &x) { int ireg = EGS_XYZGeometry::isWhere(x); - if( ireg >= 0 ) egsFatal("EGS_DeformedXYZ::isWhere(): this geometry " - "does not allow the use of this method with position inside\n"); + if (ireg >= 0) egsFatal("EGS_DeformedXYZ::isWhere(): this geometry " + "does not allow the use of this method with position inside\n"); return ireg; }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; - int medium(int ireg) const { return EGS_XYZGeometry::medium(ireg/6); }; + int medium(int ireg) const { + return EGS_XYZGeometry::medium(ireg/6); + }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { + if (ireg >= 0) { int ir = ireg/6, tetra = ireg - 6*ir, tetra4 = 4*tetra; int ind[3]; - ind[2] = ir/nxy; ind[1] = (ir - ind[2]*nxy)/nx; + ind[2] = ir/nxy; + ind[1] = (ir - ind[2]*nxy)/nx; ind[0] = ir - ind[2]*nxy - ind[1]*nx; int edge = ir + ind[1] + ind[2]*nxyp1; EGS_Vector n0(vectors[edge+tnodes[tetra4]]), @@ -953,43 +1243,71 @@ class EGS_NDG_EXPORT EGS_DeformedXYZ : public EGS_XYZGeometry { n2(vectors[edge+tnodes[tetra4+2]]-n0), n3(vectors[edge+tnodes[tetra4+3]]-n0); EGS_Vector n0x(n0-x); - EGS_Float disti[4],dpi[4]; EGS_Vector normvec; - normvec = n1%n2; dpi[0]=normvec*u; disti[0]=normvec*n0x; - normvec = n3%n1; dpi[2]=normvec*u; disti[2]=normvec*n0x; - normvec = n2%n3; dpi[1]=normvec*u; disti[1]=normvec*n0x; + EGS_Float disti[4],dpi[4]; + EGS_Vector normvec; + normvec = n1%n2; + dpi[0]=normvec*u; + disti[0]=normvec*n0x; + normvec = n3%n1; + dpi[2]=normvec*u; + disti[2]=normvec*n0x; + normvec = n2%n3; + dpi[1]=normvec*u; + disti[1]=normvec*n0x; normvec = (n3-n1)%(n2-n1); - dpi[3] = normvec*u; disti[3] = normvec*(n0x+n1); - int nextplane = 4; EGS_Float mindist = t, mindp=1; - for(int i=0; i<4; ++i) { - if( dpi[i] > 0 && disti[i]*mindp < mindist*dpi[i] ) { - mindist = disti[i]; mindp=dpi[i]; nextplane=i; + dpi[3] = normvec*u; + disti[3] = normvec*(n0x+n1); + int nextplane = 4; + EGS_Float mindist = t, mindp=1; + for (int i=0; i<4; ++i) { + if (dpi[i] > 0 && disti[i]*mindp < mindist*dpi[i]) { + mindist = disti[i]; + mindp=dpi[i]; + nextplane=i; } } - if( nextplane == 4 ) return ireg; + if (nextplane == 4) { + return ireg; + } t = mindist/mindp; int j = 12*tetra + 3*nextplane; int next = tetra_data[j]; int irnew = ir; - if( next >= 0 ) { + if (next >= 0) { ind[next] += tetra_data[j+1]; - if( ind[next] < 0 || ind[next] >= np[next] ) return -1; + if (ind[next] < 0 || ind[next] >= np[next]) { + return -1; + } irnew = ind[0] + ind[1]*nx + ind[2]*nxy; } - if( newmed ) *newmed = EGS_XYZGeometry::medium(irnew); - if( normal ) { - switch(nextplane) { - case 0: *normal = n2%n1; break; - case 1: *normal = n1%n3; break; - case 2: *normal = n3%n2; break; - case 3: *normal = (n2-n1)%(n3-n1); + if (newmed) { + *newmed = EGS_XYZGeometry::medium(irnew); + } + if (normal) { + switch (nextplane) { + case 0: + *normal = n2%n1; + break; + case 1: + *normal = n1%n3; + break; + case 2: + *normal = n3%n2; + break; + case 3: + *normal = (n2-n1)%(n3-n1); } } return 6*irnew + tetra_data[j+2]; } int ix,iy,iz,face; int inew = howfarFromOut(x,u,t,ix,iy,iz,face,normal); - if( inew < 0 ) return inew; - if( newmed ) *newmed = EGS_XYZGeometry::medium(inew); + if (inew < 0) { + return inew; + } + if (newmed) { + *newmed = EGS_XYZGeometry::medium(inew); + } // need to determine the tetrahedron we are entering. int edge = inew + iy + iz*nxyp1; EGS_Vector tmp(x + u*t); @@ -997,26 +1315,33 @@ class EGS_NDG_EXPORT EGS_DeformedXYZ : public EGS_XYZGeometry { int node1 = tnodes[4*tetra1 + plane_order[3*plane1]], node2 = tnodes[4*tetra1 + plane_order[3*plane1+1]], node3 = tnodes[4*tetra1 + plane_order[3*plane1+2]]; - if( inTriangle(vectors[edge+node1],vectors[edge+node2], - vectors[edge+node3],tmp) ) return 6*inew + tetra1; + if (inTriangle(vectors[edge+node1],vectors[edge+node2], + vectors[edge+node3],tmp)) { + return 6*inew + tetra1; + } int tetra2 = enter_tetra2[face], plane2 = enter_plane2[face]; int node1a = tnodes[4*tetra2 + plane_order[3*plane2]], node2a = tnodes[4*tetra2 + plane_order[3*plane2+1]], node3a = tnodes[4*tetra2 + plane_order[3*plane2+2]]; - if( inTriangle(vectors[edge+node1a],vectors[edge+node2a], - vectors[edge+node3a],tmp) ) return 6*inew + tetra2; + if (inTriangle(vectors[edge+node1a],vectors[edge+node2a], + vectors[edge+node3a],tmp)) { + return 6*inew + tetra2; + } // roundoff problem egsWarning("deformed geometry: entering from face %d but inTriangle()" - " fails for both triangles\n",face); + " fails for both triangles\n",face); egsWarning("x_enter=(%16.10f,%16.10f,%16.10f)\n",tmp.x,tmp.y,tmp.z); return -1; }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg < 0 ) return EGS_XYZGeometry::hownear(ireg,x); + if (ireg < 0) { + return EGS_XYZGeometry::hownear(ireg,x); + } int ir = ireg/6, tetra = ireg - 6*ir, tetra4 = 4*tetra; int ind[3]; - ind[2] = ir/nxy; ind[1] = (ir - ind[2]*nxy)/nx; + ind[2] = ir/nxy; + ind[1] = (ir - ind[2]*nxy)/nx; ind[0] = ir - ind[2]*nxy - ind[1]*nx; int edge = ir + ind[1] + ind[2]*nxyp1; EGS_Vector n0(vectors[edge+tnodes[tetra4]]), @@ -1024,41 +1349,64 @@ class EGS_NDG_EXPORT EGS_DeformedXYZ : public EGS_XYZGeometry { n2(vectors[edge+tnodes[tetra4+2]]-n0), n3(vectors[edge+tnodes[tetra4+3]]-n0); EGS_Vector n0x(n0-x); - EGS_Float disti[4],dpi[4]; EGS_Vector normvec; - normvec = n1%n2; dpi[0]=normvec.length2(); disti[0]=normvec*n0x; - normvec = n3%n1; dpi[2]=normvec.length2(); disti[2]=normvec*n0x; - normvec = n2%n3; dpi[1]=normvec.length2(); disti[1]=normvec*n0x; + EGS_Float disti[4],dpi[4]; + EGS_Vector normvec; + normvec = n1%n2; + dpi[0]=normvec.length2(); + disti[0]=normvec*n0x; + normvec = n3%n1; + dpi[2]=normvec.length2(); + disti[2]=normvec*n0x; + normvec = n2%n3; + dpi[1]=normvec.length2(); + disti[1]=normvec*n0x; normvec = (n3-n1)%(n2-n1); - dpi[3] = normvec.length2(); disti[3] = normvec*(n0x+n1); + dpi[3] = normvec.length2(); + disti[3] = normvec*(n0x+n1); EGS_Float mindist = 1e30, mindp=1; - for(int i=0; i<4; ++i) { - if( disti[i]*mindp < mindist*dpi[i] ) { - mindist = disti[i]; mindp=dpi[i]; + for (int i=0; i<4; ++i) { + if (disti[i]*mindp < mindist*dpi[i]) { + mindist = disti[i]; + mindp=dpi[i]; } } return mindist/mindp; }; int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { + const EGS_Vector &u, EGS_GeometryIntersections *isections) { return EGS_BaseGeometry::computeIntersections(ireg,n,X,u,isections); }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } int ir = ireg/6; - int iz = ir/nxy; int ir1 = ir - iz*nxy; - int iy = ir1/nx; int ix = ir1 - iy*nx; + int iz = ir/nxy; + int ir1 = ir - iz*nxy; + int iy = ir1/nx; + int ix = ir1 - iy*nx; EGS_Float d = xp->howfarToOutside(ix,x,u); - EGS_Float ty = yp->howfarToOutside(iy,x,u); if( ty < d ) d = ty; - EGS_Float tz = zp->howfarToOutside(iz,x,u); if( tz < d ) d = tz; + EGS_Float ty = yp->howfarToOutside(iy,x,u); + if (ty < d) { + d = ty; + } + EGS_Float tz = zp->howfarToOutside(iz,x,u); + if (tz < d) { + d = tz; + } return d; }; - int getMaxStep() const { return 6*(nx+ny+nz) + 1; }; + int getMaxStep() const { + return 6*(nx+ny+nz) + 1; + }; - const string &getType() const { return def_type; }; + const string &getType() const { + return def_type; + }; void printInfo() const {}; @@ -1080,8 +1428,14 @@ class EGS_NDG_EXPORT EGS_DeformedXYZ : public EGS_XYZGeometry { EGS_Vector u1(n1-n0), u2(n2-n0), xp(x-n0); EGS_Float a=u1.length2(), b=u1*u2, c=u2.length2(), b1=xp*u1, b2=xp*u2; EGS_Float D=a*c-b*b; - EGS_Float u=b1*c-b2*b; if(u<0||u>D) return false; - EGS_Float v=b2*a-b1*b; if(v<0||u+v>D) return false; + EGS_Float u=b1*c-b2*b; + if (u<0||u>D) { + return false; + } + EGS_Float v=b2*a-b1*b; + if (v<0||u+v>D) { + return false; + } return true; }; @@ -1164,26 +1518,37 @@ class EGS_NDG_EXPORT EGS_XYZRepeater : public EGS_BaseGeometry { int isWhere(const EGS_Vector &x) { int cell = xyz->isWhere(x); //egsWarning("isInside(%g,%g,%g): cell=%d\n",x.x,x.y,x.z,cell); - if( cell < 0 ) return cell; + if (cell < 0) { + return cell; + } EGS_Vector xp(x - translation[cell]); int ir = g->isWhere(xp); //egsWarning("xp=(%g,%g,%g) ir=%d\n",xp.x,xp.y,xp.z,ir); return ir >= 0 ? cell*ng + ir : nreg-1; }; - bool isInside(const EGS_Vector &x) { return xyz->isInside(x); }; + bool isInside(const EGS_Vector &x) { + return xyz->isInside(x); + }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; int medium(int ireg) const { - if( ireg == nreg-1 ) return med; - int cell = ireg/ng; int ilocal = ireg - ng*cell; + if (ireg == nreg-1) { + return med; + } + int cell = ireg/ng; + int ilocal = ireg - ng*cell; return g->medium(ilocal); }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, const EGS_Vector &u) { - if( ireg < 0 ) return 0; + if (ireg < 0) { + return 0; + } return xyz->howfarToOutside(0,x,u); }; @@ -1191,85 +1556,124 @@ class EGS_NDG_EXPORT EGS_XYZRepeater : public EGS_BaseGeometry { EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { //egsWarning("\n***howfar(reg=%d,x=(%g,%g,%g),u=(%g,%g,%g),t=%g)\n", // ireg,x.x,x.y,x.z,u.x,u.y,u.z,t); - if( ireg < 0 ) { + if (ireg < 0) { // outside of the box. int cell = xyz->howfar(ireg,x,u,t,0,normal); //egsWarning("entering: cell=%d t=%g\n",cell,t); - if( cell >= 0 ) { - if( newmed ) *newmed = med; + if (cell >= 0) { + if (newmed) { + *newmed = med; + } return nreg-1; } return -1; } - if( ireg >= 0 ) { - if( ireg < nreg-1 ) { // in one of the repetitions - int cell = ireg/ng; int ilocal = ireg - cell*ng; + if (ireg >= 0) { + if (ireg < nreg-1) { // in one of the repetitions + int cell = ireg/ng; + int ilocal = ireg - cell*ng; EGS_Vector xp(x - translation[cell]); int inew = g->howfar(ilocal,xp,u,t,newmed,normal); //egsWarning("cell=%d il=%d inew=%d t=%g xp=(%g,%g,%g)\n", // cell,ilocal,inew,t,xp.x,xp.y,xp.z); - if( inew >= 0 ) return cell*ng + inew; - if( newmed ) *newmed = med; + if (inew >= 0) { + return cell*ng + inew; + } + if (newmed) { + *newmed = med; + } return nreg-1; } } // if here, we are in the box outside of all repetitions // find the cell we are in - int ix = (int) (x.x*dxi + ax); if( ix >= nx ) ix = nx-1; - int iy = (int) (x.y*dyi + ay); if( iy >= ny ) iy = ny-1; - int iz = (int) (x.z*dzi + az); if( iz >= nz ) iz = nz-1; + int ix = (int)(x.x*dxi + ax); + if (ix >= nx) { + ix = nx-1; + } + int iy = (int)(x.y*dyi + ay); + if (iy >= ny) { + iy = ny-1; + } + int iz = (int)(x.z*dzi + az); + if (iz >= nz) { + iz = nz-1; + } int cell = ix + iy*nx + iz*nxy; //egsWarning("in box: ix=%d iy=%d iz=%d\n",ix,iy,iz); - EGS_Float t_left = t; EGS_Vector xtmp(x); + EGS_Float t_left = t; + EGS_Vector xtmp(x); EGS_Float ttot = 0; - while(1) { + while (1) { EGS_Float this_t = t_left; EGS_Vector xp(xtmp - translation[cell]); int inew = g->howfar(-1,xp,u,this_t,newmed,normal); //egsWarning("cell=%d tleft=%g xp=(%g,%g,%g) inew=%d this_t=%g\n", // cell,t_left,xp.x,xp.y,xp.z,inew,this_t); - if( inew >= 0 ) { - t = ttot + this_t; return cell*ng + inew; + if (inew >= 0) { + t = ttot + this_t; + return cell*ng + inew; } int next_cell = xyz->howfar(cell,xtmp,u,this_t,0,normal); //egsWarning("next: %d %g\n",next_cell,this_t); - if( next_cell == cell ) return ireg; - if( next_cell < 0 ) { - t = ttot + this_t; return -1; + if (next_cell == cell) { + return ireg; + } + if (next_cell < 0) { + t = ttot + this_t; + return -1; } - ttot += this_t; t_left -= this_t; xtmp += u*this_t; + ttot += this_t; + t_left -= this_t; + xtmp += u*this_t; cell = next_cell; } }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg < 0 ) return xyz->hownear(ireg,x); - if( ireg < nreg-1 ) { - int cell = ireg/ng; int ilocal = ireg - cell*ng; + if (ireg < 0) { + return xyz->hownear(ireg,x); + } + if (ireg < nreg-1) { + int cell = ireg/ng; + int ilocal = ireg - cell*ng; EGS_Vector xp(x - translation[cell]); return g->hownear(ilocal,xp); } // if here, we are in the box outside of all repetitions // find the cell we are in - int ix = (int) (x.x*dxi + ax); if( ix >= nx ) ix = nx-1; - int iy = (int) (x.y*dyi + ay); if( iy >= ny ) iy = ny-1; - int iz = (int) (x.z*dzi + az); if( iz >= nz ) iz = nz-1; + int ix = (int)(x.x*dxi + ax); + if (ix >= nx) { + ix = nx-1; + } + int iy = (int)(x.y*dyi + ay); + if (iy >= ny) { + iy = ny-1; + } + int iz = (int)(x.z*dzi + az); + if (iz >= nz) { + iz = nz-1; + } int cell = ix + iy*nx + iz*nxy; EGS_Vector xp(x - translation[cell]); EGS_Float t = g->hownear(-1,xp); EGS_Float tcell = xyz->hownear(cell,x); - if( t < tcell ) return t; - for(int iix=ix-1; iix<=ix+1; ++iix) { - if( iix >= 0 && iix < nx ) { - for(int iiy=iy-1; iiy<=iy+1; ++iiy) { - if( iiy >= 0 && iiy < ny ) { - for(int iiz=iz-1; iiz<=iz+1; ++iiz) { - if( iiz >= 0 && iiz < nz ) { - if( iix != ix || iiy != iy || iiz != iz) { + if (t < tcell) { + return t; + } + for (int iix=ix-1; iix<=ix+1; ++iix) { + if (iix >= 0 && iix < nx) { + for (int iiy=iy-1; iiy<=iy+1; ++iiy) { + if (iiy >= 0 && iiy < ny) { + for (int iiz=iz-1; iiz<=iz+1; ++iiz) { + if (iiz >= 0 && iiz < nz) { + if (iix != ix || iiy != iy || iiz != iz) { int cell1 = iix+iiy*nx+iiz*nz; EGS_Vector tmp(x-translation[cell1]); EGS_Float t1 = g->hownear(-1,tmp); - if( t1 < t ) t = t1; + if (t1 < t) { + t = t1; + } } } } @@ -1284,13 +1688,17 @@ class EGS_NDG_EXPORT EGS_XYZRepeater : public EGS_BaseGeometry { return nxyz*(g->getMaxStep() + 1) + 1; }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; - void setXYZLabels(EGS_Input *input) {xyz->setXYZLabels(input); } + void setXYZLabels(EGS_Input *input) { + xyz->setXYZLabels(input); + } - virtual void getLabelRegions (const string &str, vector ®s); + virtual void getLabelRegions(const string &str, vector ®s); protected: diff --git a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp index 9cfa12157..72d23c66e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.cpp @@ -213,103 +213,125 @@ static char EGS_OCTREE_LOCAL eoctree_key6[] = "prune tree"; extern "C" { -EGS_OCTREE_EXPORT EGS_BaseGeometry *createGeometry (EGS_Input *input) { + EGS_OCTREE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { - EGS_Input *i; + EGS_Input *i; - // check that we have an input - if (!input) { egsWarning(eoctree_message1,eoctree_message2); return 0; } - - // read bounding boxes - vector vBox; - while (i = input->takeInputItem(eoctree_key0)) { - - // read the bounding box minimum - vector v; - int err = i->getInput(eoctree_key1, v); - if (err) { - egsWarning(eoctree_message1, eoctree_message5); return 0; + // check that we have an input + if (!input) { + egsWarning(eoctree_message1,eoctree_message2); + return 0; } - if (v.size() != 3) { - egsWarning(eoctree_message1, eoctree_message6); return 0; - } - EGS_Vector bboxMin(v[0],v[1],v[2]); - // read the bounding box maximum - err = i->getInput(eoctree_key2, v); - if (err) { - egsWarning(eoctree_message1, eoctree_message7); return 0; + // read bounding boxes + vector vBox; + while (i = input->takeInputItem(eoctree_key0)) { + + // read the bounding box minimum + vector v; + int err = i->getInput(eoctree_key1, v); + if (err) { + egsWarning(eoctree_message1, eoctree_message5); + return 0; + } + if (v.size() != 3) { + egsWarning(eoctree_message1, eoctree_message6); + return 0; + } + EGS_Vector bboxMin(v[0],v[1],v[2]); + + // read the bounding box maximum + err = i->getInput(eoctree_key2, v); + if (err) { + egsWarning(eoctree_message1, eoctree_message7); + return 0; + } + if (v.size() != 3) { + egsWarning(eoctree_message1, eoctree_message8); + return 0; + } + EGS_Vector bboxMax(v[0],v[1],v[2]); + + // read the bounding box resolution + vector bboxRes; + err = i->getInput(eoctree_key3, bboxRes); + if (err) { + egsWarning(eoctree_message1, eoctree_message9); + return 0; + } + if (bboxRes.size() != 3) { + egsWarning(eoctree_message1, eoctree_message10); + return 0; + } + + EGS_Octree_bbox box = EGS_Octree_bbox(bboxMin, bboxMax, bboxRes); + vBox.push_back(box); } - if (v.size() != 3) { - egsWarning(eoctree_message1, eoctree_message8); return 0; + if (vBox.size() < 1) { + egsWarning(eoctree_message1, eoctree_message15); + return 0; } - EGS_Vector bboxMax(v[0],v[1],v[2]); - // read the bounding box resolution - vector bboxRes; - err = i->getInput(eoctree_key3, bboxRes); - if (err) { - egsWarning(eoctree_message1, eoctree_message9); return 0; - } - if (bboxRes.size() != 3) { - egsWarning(eoctree_message1, eoctree_message10); return 0; + // read discard child option + bool discardChild = true; + string discard; + if (input->getInputItem(eoctree_key5)) { + int err = input->getInput(eoctree_key5, discard); + if (err) { + egsWarning(eoctree_message1, eoctree_message11); + return 0; + } + if (discard.find("yes")==string::npos && discard.find("no")==string::npos) { + egsWarning(eoctree_message1, eoctree_message12); + return 0; + } + if (discard.find("no")!=string::npos) { + discardChild = false; + } } - EGS_Octree_bbox box = EGS_Octree_bbox(bboxMin, bboxMax, bboxRes); - vBox.push_back(box); - } - if (vBox.size() < 1) { - egsWarning(eoctree_message1, eoctree_message15); return 0; - } - - // read discard child option - bool discardChild = true; - string discard; - if (input->getInputItem(eoctree_key5)) { - int err = input->getInput(eoctree_key5, discard); - if (err) { - egsWarning(eoctree_message1, eoctree_message11); return 0; - } - if (discard.find("yes")==string::npos && discard.find("no")==string::npos) { - egsWarning(eoctree_message1, eoctree_message12); return 0; + // read prune tree option + bool pruneTree = true; + string prune; + if (input->getInputItem(eoctree_key6)) { + int err = input->getInput(eoctree_key6, prune); + if (err) { + egsWarning(eoctree_message1, eoctree_message16); + return 0; + } + if (prune.find("yes")==string::npos && prune.find("no")==string::npos) { + egsWarning(eoctree_message1, eoctree_message17); + return 0; + } + if (prune.find("no")!=string::npos) { + pruneTree = false; + } } - if (discard.find("no")!=string::npos) discardChild = false; - } - // read prune tree option - bool pruneTree = true; - string prune; - if (input->getInputItem(eoctree_key6)) { - int err = input->getInput(eoctree_key6, prune); - if (err) { - egsWarning(eoctree_message1, eoctree_message16); return 0; + // read and load the child geometry + string gname; + { + int err = input->getInput(eoctree_key4, gname); + if (err) { + egsWarning(eoctree_message1, eoctree_message13); + return 0; + } } - if (prune.find("yes")==string::npos && prune.find("no")==string::npos) { - egsWarning(eoctree_message1, eoctree_message17); return 0; + EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(gname); + if (!g) { + egsWarning(eoctree_message1, eoctree_message14); + return 0; } - if (prune.find("no")!=string::npos) pruneTree = false; - } - // read and load the child geometry - string gname; - { - int err = input->getInput(eoctree_key4, gname); - if (err) { - egsWarning(eoctree_message1, eoctree_message13); return 0; + // create the octree geometry + EGS_Octree *octree = new EGS_Octree(vBox, pruneTree, g); + octree->setName(input); + octree->setLabels(input); + octree->printInfo(); + + if (discardChild) { + delete g; } + return octree; } - EGS_BaseGeometry *g = EGS_BaseGeometry::getGeometry(gname); - if (!g) { - egsWarning(eoctree_message1, eoctree_message14); return 0; - } - - // create the octree geometry - EGS_Octree *octree = new EGS_Octree (vBox, pruneTree, g); - octree->setName(input); - octree->setLabels(input); - octree->printInfo(); - - if (discardChild) delete g; - return octree; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.h b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.h index a16c8b3a0..2058ff127 100644 --- a/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.h +++ b/HEN_HOUSE/egs++/geometry/egs_octree/egs_octree.h @@ -179,22 +179,22 @@ criteria than bounding boxes? #ifdef WIN32 -#ifdef BUILD_OCTREE_DLL -#define EGS_OCTREE_EXPORT __declspec(dllexport) -#else -#define EGS_OCTREE_EXPORT __declspec(dllimport) -#endif -#define EGS_OCTREE_LOCAL + #ifdef BUILD_OCTREE_DLL + #define EGS_OCTREE_EXPORT __declspec(dllexport) + #else + #define EGS_OCTREE_EXPORT __declspec(dllimport) + #endif + #define EGS_OCTREE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_OCTREE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_OCTREE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_OCTREE_EXPORT -#define EGS_OCTREE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_OCTREE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_OCTREE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_OCTREE_EXPORT + #define EGS_OCTREE_LOCAL + #endif #endif @@ -208,7 +208,7 @@ class EGS_Octree_bbox { int nx, ny, nz; // constructor - EGS_Octree_bbox (const EGS_Vector &boxMin, const EGS_Vector &boxMax, vector &bboxRes) : + EGS_Octree_bbox(const EGS_Vector &boxMin, const EGS_Vector &boxMax, vector &bboxRes) : vmin(boxMin), vmax(boxMax), nx(bboxRes[0]), ny(bboxRes[1]), nz(bboxRes[2]) { maxlevel = 0; ixmin = iymin = izmin = 0; @@ -221,12 +221,24 @@ class EGS_Octree_bbox { EGS_Octree_bbox b1(*this); // set the b1 box limits to enclose the two boxes - if (b2.vmin.x < b1.vmin.x) b1.vmin.x = b2.vmin.x; - if (b2.vmin.y < b1.vmin.y) b1.vmin.y = b2.vmin.y; - if (b2.vmin.z < b1.vmin.z) b1.vmin.z = b2.vmin.z; - if (b2.vmax.x > b1.vmax.x) b1.vmax.x = b2.vmax.x; - if (b2.vmax.y > b1.vmax.y) b1.vmax.y = b2.vmax.y; - if (b2.vmax.z > b1.vmax.z) b1.vmax.z = b2.vmax.z; + if (b2.vmin.x < b1.vmin.x) { + b1.vmin.x = b2.vmin.x; + } + if (b2.vmin.y < b1.vmin.y) { + b1.vmin.y = b2.vmin.y; + } + if (b2.vmin.z < b1.vmin.z) { + b1.vmin.z = b2.vmin.z; + } + if (b2.vmax.x > b1.vmax.x) { + b1.vmax.x = b2.vmax.x; + } + if (b2.vmax.y > b1.vmax.y) { + b1.vmax.y = b2.vmax.y; + } + if (b2.vmax.z > b1.vmax.z) { + b1.vmax.z = b2.vmax.z; + } // calculate voxel sizes for the two boxes EGS_Float dx1 = (b1.vmax.x-b1.vmin.x)/b1.nx; @@ -237,9 +249,24 @@ class EGS_Octree_bbox { EGS_Float dz2 = (b2.vmax.z-b2.vmin.z)/b2.nz; // calculate the number of voxels in the overall box b1 (using the highest resolution of b1 and b2) - if (dx2 < dx1) b1.nx = (int) ((b1.vmax.x - b1.vmin.x + 0.5*dx2) / dx2); else b1.nx = (int)((b1.vmax.x - b1.vmin.x +0.5*dx1) / dx1); - if (dy2 < dy1) b1.ny = (int) ((b1.vmax.y - b1.vmin.y + 0.5*dy2) / dy2); else b1.ny = (int)((b1.vmax.y - b1.vmin.y +0.5*dy1) / dy1); - if (dz2 < dz1) b1.nz = (int) ((b1.vmax.z - b1.vmin.z + 0.5*dz2) / dz2); else b1.nz = (int)((b1.vmax.z - b1.vmin.z +0.5*dz1) / dz1); + if (dx2 < dx1) { + b1.nx = (int)((b1.vmax.x - b1.vmin.x + 0.5*dx2) / dx2); + } + else { + b1.nx = (int)((b1.vmax.x - b1.vmin.x +0.5*dx1) / dx1); + } + if (dy2 < dy1) { + b1.ny = (int)((b1.vmax.y - b1.vmin.y + 0.5*dy2) / dy2); + } + else { + b1.ny = (int)((b1.vmax.y - b1.vmin.y +0.5*dy1) / dy1); + } + if (dz2 < dz1) { + b1.nz = (int)((b1.vmax.z - b1.vmin.z + 0.5*dz2) / dz2); + } + else { + b1.nz = (int)((b1.vmax.z - b1.vmin.z +0.5*dz1) / dz1); + } // return the overall box b1 return b1; @@ -248,12 +275,24 @@ class EGS_Octree_bbox { EGS_Octree_bbox &operator+= (const EGS_Octree_bbox &b2) { // set the b1 box limits to enclose the two boxes - if (b2.vmin.x < vmin.x) vmin.x = b2.vmin.x; - if (b2.vmin.y < vmin.y) vmin.y = b2.vmin.y; - if (b2.vmin.z < vmin.z) vmin.z = b2.vmin.z; - if (b2.vmax.x > vmax.x) vmax.x = b2.vmax.x; - if (b2.vmax.y > vmax.y) vmax.y = b2.vmax.y; - if (b2.vmax.z > vmax.z) vmax.z = b2.vmax.z; + if (b2.vmin.x < vmin.x) { + vmin.x = b2.vmin.x; + } + if (b2.vmin.y < vmin.y) { + vmin.y = b2.vmin.y; + } + if (b2.vmin.z < vmin.z) { + vmin.z = b2.vmin.z; + } + if (b2.vmax.x > vmax.x) { + vmax.x = b2.vmax.x; + } + if (b2.vmax.y > vmax.y) { + vmax.y = b2.vmax.y; + } + if (b2.vmax.z > vmax.z) { + vmax.z = b2.vmax.z; + } // calculate voxel sizes for the two boxes EGS_Float dx1 = (vmax.x-vmin.x)/nx; @@ -264,9 +303,24 @@ class EGS_Octree_bbox { EGS_Float dz2 = (b2.vmax.z-b2.vmin.z)/b2.nz; // calculate the number of voxels in the overall box b1 (using the highest resolution of b1 and b2) - if (dx2 < dx1) nx = (int) ((vmax.x - vmin.x + 0.5*dx2) / dx2); else nx = (int)((vmax.x - vmin.x +0.5*dx1) / dx1); - if (dy2 < dy1) ny = (int) ((vmax.y - vmin.y + 0.5*dy2) / dy2); else ny = (int)((vmax.y - vmin.y +0.5*dy1) / dy1); - if (dz2 < dz1) nz = (int) ((vmax.z - vmin.z + 0.5*dz2) / dz2); else nz = (int)((vmax.z - vmin.z +0.5*dz1) / dz1); + if (dx2 < dx1) { + nx = (int)((vmax.x - vmin.x + 0.5*dx2) / dx2); + } + else { + nx = (int)((vmax.x - vmin.x +0.5*dx1) / dx1); + } + if (dy2 < dy1) { + ny = (int)((vmax.y - vmin.y + 0.5*dy2) / dy2); + } + else { + ny = (int)((vmax.y - vmin.y +0.5*dy1) / dy1); + } + if (dz2 < dz1) { + nz = (int)((vmax.z - vmin.z + 0.5*dz2) / dz2); + } + else { + nz = (int)((vmax.z - vmin.z +0.5*dz1) / dz1); + } // return the overall box return *this; @@ -284,7 +338,7 @@ class EGS_Octree_node { EGS_Octree_node *parent; ///< pointer to the parent node (only root node can have parent set to NULL) // constructor - EGS_Octree_node () { + EGS_Octree_node() { medium = -1; // set the medium to -1 by default region = -1; // set region to -1 by default level = 0; // set level to 0 (root) by default @@ -297,7 +351,9 @@ class EGS_Octree_node { void createChildren() { // create children to the this node if (!child) { // ensure there are no children already child = new EGS_Octree_node [8]; // allocate memory for 8 new children nodes - if (!child) egsFatal("EGS_Octree_node::createChildren(): Memory allocation error"); + if (!child) { + egsFatal("EGS_Octree_node::createChildren(): Memory allocation error"); + } for (int i=0; i<8; i++) { // loop over all 8 newly created children nodes child[i].level = level+1; // increase level by 1 compared to current level child[i].ix = (ix << 1) | (i>>0 & 0x1); // shift up ix by one, and set new bit to that of the child index's bit 0 (x position) @@ -309,20 +365,26 @@ class EGS_Octree_node { } // delete children (recursively) - void deleteChildren () { // delete children of this node + void deleteChildren() { // delete children of this node if (child) { // if this node has children, delete them - for (int i=0; i<8; i++) child[i].deleteChildren(); // recursive calls to delete all children branches + for (int i=0; i<8; i++) { + child[i].deleteChildren(); // recursive calls to delete all children branches + } delete [] child; // free the memory allocated for the 8 children child = NULL; // set children pointer to NULL to indicate that there are no children now } } // collapse node - int collapseChildren () { // collapse children in this node if they are all the same medium + int collapseChildren() { // collapse children in this node if they are all the same medium if (child) { // check that we indeed have children for (int i=0; i<8; i++) { // loop over each of the 8 children of this node - if (child[i].child) return 0; // bail out if there are nodes below the children (this could be made recursive) - if (child[i].medium!=child[0].medium) return 0; // bail out as soon as one children has a different medium + if (child[i].child) { + return 0; // bail out if there are nodes below the children (this could be made recursive) + } + if (child[i].medium!=child[0].medium) { + return 0; // bail out as soon as one children has a different medium + } } medium = child[0].medium; // set the medium of this node to that of the children deleteChildren(); // delete the children of this node @@ -332,35 +394,77 @@ class EGS_Octree_node { } // insideBBox - bool insideBBox (EGS_Octree_bbox &bbox) { + bool insideBBox(EGS_Octree_bbox &bbox) { int shift = bbox.maxlevel - level; int ii; - ii = (ix< bbox.ixmax) return false; - ii = (iy< bbox.iymax) return false; - ii = iz< bbox.izmax) return false; + ii = (ix< bbox.ixmax) { + return false; + } + ii = (iy< bbox.iymax) { + return false; + } + ii = iz< bbox.izmax) { + return false; + } return true; } // instersectBBox - bool intersectBBox (EGS_Octree_bbox &bbox) { + bool intersectBBox(EGS_Octree_bbox &bbox) { int shift = bbox.maxlevel - level; int iimin, iimax; - iimin = (ix< iimin) iimin = bbox.ixmin; - iimax = ~(~ix< iimin) { + iimin = bbox.ixmin; + } + iimax = ~(~ix< iimin) iimin = bbox.iymin; - iimax = ~(~iy< iimin) { + iimin = bbox.iymin; + } + iimax = ~(~iy< iimin) iimin = bbox.izmin; - iimax = ~(~iz< iimin) { + iimin = bbox.izmin; + } + iimax = ~(~iz< &vBox, bool pruneTree, EGS_BaseGeometry *g) : EGS_BaseGeometry(""), geom(g) { + EGS_Octree(vector &vBox, bool pruneTree, EGS_BaseGeometry *g) : EGS_BaseGeometry(""), geom(g) { // combine bounding boxes to get the overall bounding box EGS_Octree_bbox bbox(vBox[0]); - for (int i=1; i res) res = ny; - if (nz > res) res = nz; + if (ny > res) { + res = ny; + } + if (nz > res) { + res = nz; + } maxlevel = (int) ceil(log((EGS_Float)res)/0.6931471805599452862); // set octree cell count at maxlevel; @@ -471,24 +581,41 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { zmax = bbox.vmin.z + dz*n; // set cell indices range for each box; - {for (int i=0; iixmin = (int) ((box->vmin.x - xmin + 0.5*dx) * dxi); - box->iymin = (int) ((box->vmin.y - ymin + 0.5*dy) * dyi); - box->izmin = (int) ((box->vmin.z - zmin + 0.5*dz) * dzi); - box->nx = (int) ((box->vmax.x - box->vmin.x + 0.5*dx) * dxi); - box->ny = (int) ((box->vmax.y - box->vmin.y + 0.5*dy) * dyi); - box->nz = (int) ((box->vmax.z - box->vmin.z + 0.5*dz) * dzi); - box->ixmax = box->ixmin + box->nx - 1; - box->iymax = box->iymin + box->ny - 1; - box->izmax = box->izmin + box->nz - 1; - if (box->ixmin<0) box->ixmin = 0; if (box->ixmax>=n) box->ixmax = n-1; - if (box->iymin<0) box->iymin = 0; if (box->iymax>=n) box->iymax = n-1; - if (box->izmin<0) box->izmin = 0; if (box->izmax>=n) box->izmax = n-1; - box->nx = box->ixmax - box->ixmin + 1; - box->ny = box->iymax - box->iymin + 1; - box->nz = box->izmax - box->izmin + 1; - }} + { + for (int i=0; iixmin = (int)((box->vmin.x - xmin + 0.5*dx) * dxi); + box->iymin = (int)((box->vmin.y - ymin + 0.5*dy) * dyi); + box->izmin = (int)((box->vmin.z - zmin + 0.5*dz) * dzi); + box->nx = (int)((box->vmax.x - box->vmin.x + 0.5*dx) * dxi); + box->ny = (int)((box->vmax.y - box->vmin.y + 0.5*dy) * dyi); + box->nz = (int)((box->vmax.z - box->vmin.z + 0.5*dz) * dzi); + box->ixmax = box->ixmin + box->nx - 1; + box->iymax = box->iymin + box->ny - 1; + box->izmax = box->izmin + box->nz - 1; + if (box->ixmin<0) { + box->ixmin = 0; + } + if (box->ixmax>=n) { + box->ixmax = n-1; + } + if (box->iymin<0) { + box->iymin = 0; + } + if (box->iymax>=n) { + box->iymax = n-1; + } + if (box->izmin<0) { + box->izmin = 0; + } + if (box->izmax>=n) { + box->izmax = n-1; + } + box->nx = box->ixmax - box->ixmin + 1; + box->ny = box->iymax - box->iymin + 1; + box->nz = box->izmax - box->izmin + 1; + } + } // determine maxlevel in each defined bounding box @@ -504,21 +631,31 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // avoid indirections for overall bounding box parameters EGS_Octree_bbox *box = &(vBox.back()); - bbxmin = box->vmin.x; bbxmax = box->vmax.x; - bbymin = box->vmin.y; bbymax = box->vmax.y; - bbzmin = box->vmin.z; bbzmax = box->vmax.z; - ixmin = box->ixmin; ixmax = box->ixmax; - iymin = box->iymin; iymax = box->iymax; - izmin = box->izmin; izmax = box->izmax; + bbxmin = box->vmin.x; + bbxmax = box->vmax.x; + bbymin = box->vmin.y; + bbymax = box->vmax.y; + bbzmin = box->vmin.z; + bbzmax = box->vmax.z; + ixmin = box->ixmin; + ixmax = box->ixmax; + iymin = box->iymin; + iymax = box->iymax; + izmin = box->izmin; + izmax = box->izmax; // build octree - root = new EGS_Octree_node (); - growOctree (root, vBox, pruneTree); + root = new EGS_Octree_node(); + growOctree(root, vBox, pruneTree); // allocate memory to hold the region-indexed node pointers in a simple array, and free up the tmp vector nreg = tmp.size(); nodeReg = new EGS_Octree_node* [nreg]; - {for (int i=0; ideleteChildren(); delete root; @@ -539,9 +676,11 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // statOctree - void statOctree (EGS_Octree_node *node, vector &vBox) { + void statOctree(EGS_Octree_node *node, vector &vBox) { if (node->child) { - for (int i=0; i<8; i++) statOctree(node->child+i, vBox); + for (int i=0; i<8; i++) { + statOctree(node->child+i, vBox); + } } else if (node->insideBBox(vBox[vBox.size()-1]) && node->medium>=0) { int shift = maxlevel - node->level; @@ -552,7 +691,7 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // growOctree (recursive) - void growOctree (EGS_Octree_node *node, vector &vBox, bool prune) { + void growOctree(EGS_Octree_node *node, vector &vBox, bool prune) { // assume node needs no refinement bool refineNode = false; @@ -562,21 +701,31 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // check all bounding boxes to determine local refinement level (priority to boxes defined later) int level = 0; - {for (int i=0; iinsideBBox(vBox[i])) level = boxlevel; - }} + { + for (int i=0; iinsideBBox(vBox[i])) { + level = boxlevel; + } + } + } // node may still need refinement if it intersects a higher resolution bounding box - {for (int i=0; iinsideBBox(vBox[i]) && node->intersectBBox(vBox[i])) { - if (boxlevel > level) level = boxlevel; + { + for (int i=0; iinsideBBox(vBox[i]) && node->intersectBBox(vBox[i])) { + if (boxlevel > level) { + level = boxlevel; + } + } } - }} + } // if the level of this node is not sufficient, set it for refinement - if (node->level < level) refineNode = true; + if (node->level < level) { + refineNode = true; + } } // if this node needs refinement, grow children branches (recursively), and then try to collapse children @@ -612,7 +761,9 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { float yy = ymin+(iy+0.5)*dy; float zz = zmin+(iz+0.5)*dz; int ireg = geom->isWhere(EGS_Vector(xmin+(ix+0.5)*dx, ymin+(iy+0.5)*dy, zmin+(iz+0.5)*dz)); - if (ireg>=0) node->medium = geom->medium(ireg); + if (ireg>=0) { + node->medium = geom->medium(ireg); + } } node->region = tmp.size(); tmp.push_back(node); @@ -621,17 +772,27 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // getNeighborNodeX - EGS_Octree_node *getNeighborNodeX (EGS_Octree_node *node, int ixn, int iyn, int izn) { + EGS_Octree_node *getNeighborNodeX(EGS_Octree_node *node, int ixn, int iyn, int izn) { // check if neighbor index is in range - if (ixn < ixmin || ixn > ixmax) return NULL; + if (ixn < ixmin || ixn > ixmax) { + return NULL; + } // constrain neighbor indices in y and z int shift = maxlevel - node->level; - if (iyn < node->iy<iy< ~(~node->iy<iy<iz<iz< ~(~node->iz<iz<iy<iy< ~(~node->iy<iy<iz<iz< ~(~node->iz<iz<ix ^ (ixn>>shift); @@ -656,17 +817,27 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // getNeighborNodeY - EGS_Octree_node *getNeighborNodeY (EGS_Octree_node * node, int ixn, int iyn, int izn) { + EGS_Octree_node *getNeighborNodeY(EGS_Octree_node *node, int ixn, int iyn, int izn) { // check if neighbor index is in range - if (iyn < iymin || iyn > iymax) return NULL; + if (iyn < iymin || iyn > iymax) { + return NULL; + } // constrain neighbor indices in x and z int shift = maxlevel - node->level; - if (ixn < node->ix<ix< ~(~node->ix<ix<iz<iz< ~(~node->iz<iz<ix<ix< ~(~node->ix<ix<iz<iz< ~(~node->iz<iz<iy ^ (iyn>>shift); @@ -689,17 +860,27 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // getNeighborNodeZ - EGS_Octree_node *getNeighborNodeZ (EGS_Octree_node * node, int ixn, int iyn, int izn) { + EGS_Octree_node *getNeighborNodeZ(EGS_Octree_node *node, int ixn, int iyn, int izn) { // check if neighbor index is in range - if (izn < izmin || izn > izmax) return NULL; + if (izn < izmin || izn > izmax) { + return NULL; + } // constrain neighbor indices in x and y int shift = maxlevel - node->level; - if (ixn < node->ix<ix< ~(~node->ix<ix<iy<iy< ~(~node->iy<iy<ix<ix< ~(~node->ix<ix<iy<iy< ~(~node->iy<iy<iz ^ (izn>>shift); @@ -722,8 +903,10 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // getNode - EGS_Octree_node *getNode (int ix, int iy, int iz) { - if ((ixixmax) || (iyiymax) || (izizmax)) return NULL; + EGS_Octree_node *getNode(int ix, int iy, int iz) { + if ((ixixmax) || (iyiymax) || (izizmax)) { + return NULL; + } EGS_Octree_node *node = root; int shift = maxlevel; while (node->child) { @@ -739,28 +922,47 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // setIndices - void setIndices (const EGS_Vector &r, int &ix, int &iy, int &iz) { - ix = (int) ((r.x-xmin)*dxi); - iy = (int) ((r.y-ymin)*dyi); - iz = (int) ((r.z-zmin)*dzi); - if (ixixmax) ix=ixmax; - if (iyiymax) iy=iymax; - if (izizmax) iz=izmax; + void setIndices(const EGS_Vector &r, int &ix, int &iy, int &iz) { + ix = (int)((r.x-xmin)*dxi); + iy = (int)((r.y-ymin)*dyi); + iz = (int)((r.z-zmin)*dzi); + if (ixixmax) { + ix=ixmax; + } + if (iyiymax) { + iy=iymax; + } + if (izizmax) { + iz=izmax; + } } // isInside - bool isInside (const EGS_Vector &r) { + bool isInside(const EGS_Vector &r) { if (r.x >= bbxmin && r.x <= bbxmax && - r.y >= bbymin && r.y <= bbymax && - r.z >= bbzmin && r.z <= bbzmax ) return true; + r.y >= bbymin && r.y <= bbymax && + r.z >= bbzmin && r.z <= bbzmax) { + return true; + } return false; } // isWhere - int isWhere (const EGS_Vector &r) { - if (!isInside(r)) return -1; + int isWhere(const EGS_Vector &r) { + if (!isInside(r)) { + return -1; + } int ix, iy, iz; setIndices(r,ix,iy,iz); return getNode(ix,iy,iz)->region; @@ -768,14 +970,16 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // inside (deprecated) - int inside (const EGS_Vector &r) { + int inside(const EGS_Vector &r) { return isWhere(r); } // isWhereFast - int isWhereFast (const EGS_Vector &r) { - if (!isInside(r)) return -1; + int isWhereFast(const EGS_Vector &r) { + if (!isInside(r)) { + return -1; + } int ix, iy, iz; setIndices(r, ix, iy, iz); return getNode(ix,iy,iz)->region; @@ -783,18 +987,20 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // medium - int medium (int ireg) const { + int medium(int ireg) const { return nodeReg[ireg]->medium; } // howfarIn - int howfarIn (EGS_Octree_node *node, const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { + int howfarIn(EGS_Octree_node *node, const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { int ix, iy, iz, tmp; int crossed = -1; - if (!node) return -1; + if (!node) { + return -1; + } // set shift and local cell indices int shift = maxlevel - node->level; // how many levels missing between current level and full depth @@ -806,27 +1012,39 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { if (u.x > 0) { ix = ~(~ix<=ixmax) xBound = bbxmax; - else xBound = xmin + (ix+1)*dx; + if (ix>=ixmax) { + xBound = bbxmax; + } + else { + xBound = xmin + (ix+1)*dx; + } EGS_Float d = (xBound-r.x) / u.x; if (d <= t) { t = d; crossed = 0; ix++; - if (normal) *normal = EGS_Vector(-1,0,0); + if (normal) { + *normal = EGS_Vector(-1,0,0); + } } } else if (u.x < 0) { ix = ix< 0) { iy = ~(~iy<=iymax) yBound = bbymax; - else yBound = ymin + (iy+1)*dy; + if (iy>=iymax) { + yBound = bbymax; + } + else { + yBound = ymin + (iy+1)*dy; + } EGS_Float d = (yBound - r.y) / u.y; if (d <= t) { t = d; crossed = 1; iy++; - if (normal) *normal = EGS_Vector(0,-1,0); + if (normal) { + *normal = EGS_Vector(0,-1,0); + } } } else if (u.y < 0) { iy = iy< 0) { iz = ~(~iz<=izmax) zBound = bbzmax; - else zBound = zmin + (iz+1)*dz; + if (iz>=izmax) { + zBound = bbzmax; + } + else { + zBound = zmin + (iz+1)*dz; + } EGS_Float d = (zBound-r.z) / u.z; if (d <= t) { t = d; crossed = 2; iz++; - if (normal) *normal = EGS_Vector(0,0,-1); + if (normal) { + *normal = EGS_Vector(0,0,-1); + } } } else if (u.z < 0) { iz = iz<region; - else return -1; + if (node) { + return node->region; + } + else { + return -1; + } } // howfarOut - int howfarOut (const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { + int howfarOut(const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { int inew = -1, tmp; int ix, iy, iz; @@ -925,11 +1171,13 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { ix = ixmin; d = (bbxmin-r.x) / u.x; } - else if (r.x >= bbxmax && u.x < 0 ) { + else if (r.x >= bbxmax && u.x < 0) { ix = ixmax; d = (bbxmax-r.x) / u.x; } - else d = tlong; + else { + d = tlong; + } if (d <= t) { EGS_Float yy = r.y + u.y*d; EGS_Float zz = r.z + u.z*d; @@ -937,22 +1185,26 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { EGS_Vector rr(0,yy,zz); setIndices(rr, tmp, iy, iz); t = d; - if (normal) *normal = (ix == ixmin) ? EGS_Vector(-1,0,0) : EGS_Vector(1,0,0); + if (normal) { + *normal = (ix == ixmin) ? EGS_Vector(-1,0,0) : EGS_Vector(1,0,0); + } node = getNode(ix,iy,iz); return node->region; } } // y axis - if (r.y <= bbymin && u.y > 0 ) { + if (r.y <= bbymin && u.y > 0) { iy = iymin; d = (bbymin-r.y) / u.y; } - else if (r.y >= bbymax && u.y < 0 ) { + else if (r.y >= bbymax && u.y < 0) { iy = iymax; d = (bbymax-r.y) / u.y; } - else d = tlong; + else { + d = tlong; + } if (d <= t) { EGS_Float xx = r.x + u.x*d; EGS_Float zz = r.z + u.z*d; @@ -960,22 +1212,26 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { EGS_Vector rr(xx,0,zz); setIndices(rr, ix, tmp, iz); t = d; - if (normal) *normal = (iy == iymin) ? EGS_Vector(0,-1,0) : EGS_Vector(0,1,0); + if (normal) { + *normal = (iy == iymin) ? EGS_Vector(0,-1,0) : EGS_Vector(0,1,0); + } node = getNode(ix,iy,iz); return node->region; } - } + } // z axis if (r.z <= bbzmin && u.z > 0) { iz = izmin; d = (bbzmin-r.z) / u.z; } - else if (r.z >= bbzmax && u.z < 0 ) { + else if (r.z >= bbzmax && u.z < 0) { iz = izmax; d = (bbzmax-r.z) / u.z; } - else d = tlong; + else { + d = tlong; + } if (d <= t) { EGS_Float xx = r.x + u.x*d; EGS_Float yy = r.y + u.y*d; @@ -983,7 +1239,9 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { EGS_Vector rr(xx,yy,0); setIndices(rr, ix, iy, tmp); t = d; - if (normal) *normal = (iz == izmin) ? EGS_Vector(0,0,-1) : EGS_Vector(0,0,1); + if (normal) { + *normal = (iz == izmin) ? EGS_Vector(0,0,-1) : EGS_Vector(0,0,1); + } node = getNode(ix,iy,iz); return node->region; } @@ -994,24 +1252,28 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // howfar - int howfar (int ireg, const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal=0) { + int howfar(int ireg, const EGS_Vector &r, const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal=0) { int inew = ireg; // get new region number - if (ireg==-1) - inew = howfarOut (r, u, t, normal); - else - inew = howfarIn (nodeReg[ireg], r, u, t, normal); + if (ireg==-1) { + inew = howfarOut(r, u, t, normal); + } + else { + inew = howfarIn(nodeReg[ireg], r, u, t, normal); + } // set new medium - if (inew>=0 && newmed) *newmed = nodeReg[inew]->medium; + if (inew>=0 && newmed) { + *newmed = nodeReg[inew]->medium; + } return inew; } // hownearIn - EGS_Float hownearIn (int ireg, const EGS_Vector &r) { + EGS_Float hownearIn(int ireg, const EGS_Vector &r) { EGS_Octree_node *node = nodeReg[ireg]; int shift = maxlevel - node->level; EGS_Float t1, t2, tx, ty, tz; @@ -1020,38 +1282,52 @@ class EGS_OCTREE_EXPORT EGS_Octree : public EGS_BaseGeometry { // x imin = node->ix << shift; imax = ~(~node->ix << shift); - t1 = (r.x-xmin)-dx*imin; t2 = dx*(imax-imin+1)-t1; tx = t1 < t2 ? t1 : t2; + t1 = (r.x-xmin)-dx*imin; + t2 = dx*(imax-imin+1)-t1; + tx = t1 < t2 ? t1 : t2; // y imin = node->iy << shift; imax = ~(~node->iy << shift); - t1 = (r.y-ymin)-dy*imin; t2 = dy*(imax-imin+1)-t1; ty = t1 < t2 ? t1 : t2; + t1 = (r.y-ymin)-dy*imin; + t2 = dy*(imax-imin+1)-t1; + ty = t1 < t2 ? t1 : t2; // z imin = node->iz << shift; imax = ~(~node->iz << shift); - t1 = (r.z-zmin)-dz*imin; t2 = dz*(imax-imin+1)-t1; tz = t1 < t2 ? t1 : t2; + t1 = (r.z-zmin)-dz*imin; + t2 = dz*(imax-imin+1)-t1; + tz = t1 < t2 ? t1 : t2; return tx=0) return hownearIn(ireg, r); + EGS_Float hownear(int ireg, const EGS_Vector &r) { + if (ireg>=0) { + return hownearIn(ireg, r); + } int nc=0; EGS_Float s1=0, s2=0; if (r.x < bbxmin || r.x > bbxmax) { EGS_Float t = r.x < bbxmin ? bbxmin-r.x : r.x-bbxmax; - nc++; s1 += t; s2 += t*t; + nc++; + s1 += t; + s2 += t*t; } if (r.y < bbymin || r.y > bbymax) { EGS_Float t = r.y < bbymin ? bbymin-r.y : r.y-bbymax; - nc++; s1 += t; s2 += t*t; + nc++; + s1 += t; + s2 += t*t; } if (r.z < bbzmin || r.z > bbzmax) { EGS_Float t = r.z < bbzmin ? bbzmin-r.z : r.z-bbzmax; - nc++; s1 += t; s2 += t*t; + nc++; + s1 += t; + s2 += t*t; } return nc == 1 ? s1 : sqrt(s2); } diff --git a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp index 1bcc01a53..22acb3652 100644 --- a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.cpp @@ -50,29 +50,36 @@ const string EGS_PLANES_LOCAL proj_type("EGS_Planes"); string EGS_PlaneCollection::type = "EGS_PlaneCollection"; EGS_PlaneCollection::EGS_PlaneCollection(int Np, const EGS_Float *pos, - const EGS_Vector *norm, const string &Name) : EGS_BaseGeometry(Name) { - if( Np < 2 ) egsFatal("EGS_PlaneCollection::EGS_PlaneCollection: " - " you nead at least 2 planes\n"); - np = Np; nreg=np-1; + const EGS_Vector *norm, const string &Name) : EGS_BaseGeometry(Name) { + if (Np < 2) egsFatal("EGS_PlaneCollection::EGS_PlaneCollection: " + " you nead at least 2 planes\n"); + np = Np; + nreg=np-1; planes = new EGS_Planes* [np]; - for(int j=0; jref(); + EGS_Projector(norm[j],proj_type)); + planes[j]->ref(); } } EGS_PlaneCollection::~EGS_PlaneCollection() { egsWarning("Deleting ~EGS_PlaneCollection at 0x%x\n",this); - for(int j=0; jderef() ) delete planes[j]; + for (int j=0; jderef()) { + delete planes[j]; + } delete [] planes; } void EGS_PlaneCollection::printInfo() const { - EGS_BaseGeometry::printInfo(); int j; + EGS_BaseGeometry::printInfo(); + int j; egsInformation(" plane positions: "); - for(j=0; jposition(0)); + for (j=0; jposition(0)); + } egsInformation(" \nplane normals: "); - for(j=0; jnormal(); egsInformation(" (%g,%g,%g) ",a.x,a.y,a.z); } @@ -81,86 +88,92 @@ void EGS_PlaneCollection::printInfo() const { extern "C" { -EGS_PLANES_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - string type; int err = input->getInput("type",type); - if( err ) { - egsWarning("createGeometry(planes): missing type key\n"); - return 0; - } - EGS_Float first; vector thick; vector nthick; - vector pos; - int err_first = input->getInput("first plane",first); - int err_thick = input->getInput("slab thickness",thick); - int err_nthick = input->getInput("number of slabs",nthick); - if( !err_first && !err_thick && !err_nthick ) { - if( thick.size() != nthick.size() || !thick.size() ) { - egsWarning("createGeometry(planes): number of 'slab thickness' and" - "\n 'number of slabs' inputs must be the same and not zero\n"); - egsWarning(" got %d and %d inputs --> input ignored\n", - thick.size(),nthick.size()); + EGS_PLANES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(planes): missing type key\n"); + return 0; } - else { - pos.push_back(first); int j=0; - for(int i=0; i thick; + vector nthick; + vector pos; + int err_first = input->getInput("first plane",first); + int err_thick = input->getInput("slab thickness",thick); + int err_nthick = input->getInput("number of slabs",nthick); + if (!err_first && !err_thick && !err_nthick) { + if (thick.size() != nthick.size() || !thick.size()) { + egsWarning("createGeometry(planes): number of 'slab thickness' and" + "\n 'number of slabs' inputs must be the same and not zero\n"); + egsWarning(" got %d and %d inputs --> input ignored\n", + thick.size(),nthick.size()); + } + else { + pos.push_back(first); + int j=0; + for (int i=0; igetInput("positions",pos); - if( err ) { - egsWarning("createGeometry(planes): missing/wrong 'positions' " - "input and missing/wrong multiple plane input\n"); - return 0; + if (!pos.size()) { + err = input->getInput("positions",pos); + if (err) { + egsWarning("createGeometry(planes): missing/wrong 'positions' " + "input and missing/wrong multiple plane input\n"); + return 0; + } } - } - EGS_BaseGeometry *g; - if( type == "EGS_Xplanes" ) g = new EGS_PlanesX(pos,"", - EGS_XProjector(xproj_type)); - else if( type == "EGS_Yplanes" ) g = new EGS_PlanesY(pos,"", - EGS_YProjector(yproj_type)); - else if( type == "EGS_Zplanes" ) g = new EGS_PlanesZ(pos,"", - EGS_ZProjector(zproj_type)); - else if( type == "EGS_Planes" ) { - vector a; - err = input->getInput("normal",a); - if( err || a.size() != 3 ) { - egsWarning("createGeometry(planes): missing/wrong normal input\n"); - return 0; + EGS_BaseGeometry *g; + if (type == "EGS_Xplanes") g = new EGS_PlanesX(pos,"", + EGS_XProjector(xproj_type)); + else if (type == "EGS_Yplanes") g = new EGS_PlanesY(pos,"", + EGS_YProjector(yproj_type)); + else if (type == "EGS_Zplanes") g = new EGS_PlanesZ(pos,"", + EGS_ZProjector(zproj_type)); + else if (type == "EGS_Planes") { + vector a; + err = input->getInput("normal",a); + if (err || a.size() != 3) { + egsWarning("createGeometry(planes): missing/wrong normal input\n"); + return 0; + } + g = new EGS_Planes(pos,"",EGS_Projector(EGS_Vector(a[0],a[1],a[2]), + proj_type)); } - g = new EGS_Planes(pos,"",EGS_Projector(EGS_Vector(a[0],a[1],a[2]), - proj_type)); - } - else if( type == "EGS_PlaneCollection" ) { - vector a; - err = input->getInput("normals",a); - if( err || a.size() < 6 ) { - egsWarning("createGeometry(planes): missing/wrong normal input\n"); - return 0; + else if (type == "EGS_PlaneCollection") { + vector a; + err = input->getInput("normals",a); + if (err || a.size() < 6) { + egsWarning("createGeometry(planes): missing/wrong normal input\n"); + return 0; + } + int np = a.size()/3; + if (np != pos.size()) { + egsWarning("createGeometry(planes): number of plane normals (%d)\n" + " is not the same as number of plane positions (%d) for a" + " plane collection\n",np,pos.size()); + return 0; + } + EGS_Float *p = new EGS_Float [np]; + EGS_Vector *normal = new EGS_Vector [np]; + for (int j=0; jsetName(input); + g->setMedia(input); + g->setLabels(input); + return g; } - else { - egsWarning("createGeometry(planes): unknown type %s\n",type.c_str()); - return 0; - } - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.h b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.h index f8f0a7592..df3066cea 100644 --- a/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.h +++ b/HEN_HOUSE/egs++/geometry/egs_planes/egs_planes.h @@ -46,22 +46,22 @@ using std::vector; #ifdef WIN32 -#ifdef BUILD_PLANES_DLL -#define EGS_PLANES_EXPORT __declspec(dllexport) -#else -#define EGS_PLANES_EXPORT __declspec(dllimport) -#endif -#define EGS_PLANES_LOCAL + #ifdef BUILD_PLANES_DLL + #define EGS_PLANES_EXPORT __declspec(dllexport) + #else + #define EGS_PLANES_EXPORT __declspec(dllimport) + #endif + #define EGS_PLANES_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_PLANES_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_PLANES_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_PLANES_EXPORT -#define EGS_PLANES_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_PLANES_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_PLANES_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_PLANES_EXPORT + #define EGS_PLANES_LOCAL + #endif #endif @@ -135,63 +135,87 @@ class EGS_PLANES_EXPORT EGS_PlanesT : public EGS_BaseGeometry { //int last_ir, last_irnew; void checkIfUniform() { - is_uniform = true; - if( nreg == 1 ) { dp = p_last - p[0]; return; } - dp = p[1] - p[0]; - for(int j=1; j 2e-5 ) { - is_uniform = false; break; - } - } - }; + is_uniform = true; + if (nreg == 1) { + dp = p_last - p[0]; + return; + } + dp = p[1] - p[0]; + for (int j=1; j 2e-5) { + is_uniform = false; + break; + } + } + }; public: /*! Destructor. */ ~EGS_PlanesT() { - if( nreg ) delete [] p; + if (nreg) { + delete [] p; + } }; /*! \brief Construct a parallel plane set with \a np planes at positions \a pos. */ EGS_PlanesT(int np, const EGS_Float *pos, const string &Name, - const T &A) : EGS_BaseGeometry(Name), a(A) { - if( np > 0 ) { + const T &A) : EGS_BaseGeometry(Name), a(A) { + if (np > 0) { p = new EGS_Float [np]; - for(int j=0; j 0 ) { - if( p[j] < p[j-1] ) egsFatal("EGS_PlanesT::EGS_PlanesT: " - " plane positions must be in increasing order\n"); + if (j > 0) { + if (p[j] < p[j-1]) egsFatal("EGS_PlanesT::EGS_PlanesT: " + " plane positions must be in increasing order\n"); } } - if( np > 1 ) { nreg = np-1; p_last = p[nreg]; n_plane = np-1; } - else { nreg = 1; p_last = 1e15; n_plane = 0; } - } else egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct a " - "plane set with %d plane positions\n",np); + if (np > 1) { + nreg = np-1; + p_last = p[nreg]; + n_plane = np-1; + } + else { + nreg = 1; + p_last = 1e15; + n_plane = 0; + } + } + else egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct a " + "plane set with %d plane positions\n",np); checkIfUniform(); }; /*! \brief Construct a parallel plane set from the positions given by \a pos */ EGS_PlanesT(const vector &pos, const string &Name, const T &A) : - EGS_BaseGeometry(Name), a(A) { + EGS_BaseGeometry(Name), a(A) { int np = pos.size(); - if( np > 0 ) { + if (np > 0) { p = new EGS_Float [np]; - for(int j=0; j 0 ) { - if( p[j] < p[j-1] ) egsFatal("EGS_PlanesT::EGS_PlanesT: " - " plane positions must be in increasing order\n"); + if (j > 0) { + if (p[j] < p[j-1]) egsFatal("EGS_PlanesT::EGS_PlanesT: " + " plane positions must be in increasing order\n"); } } - if( np > 1 ) { nreg = np-1; p_last = p[nreg]; n_plane = np-1; } - else { nreg = 1; p_last = 1e15; n_plane = 0; } - } else egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct a " - "plane set with %d plane positions\n",np); + if (np > 1) { + nreg = np-1; + p_last = p[nreg]; + n_plane = np-1; + } + else { + nreg = 1; + p_last = 1e15; + n_plane = 0; + } + } + else egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct a " + "plane set with %d plane positions\n",np); checkIfUniform(); }; /*! \brief Construct a parallel plane set starting at \a xo with @@ -199,56 +223,81 @@ class EGS_PLANES_EXPORT EGS_PlanesT : public EGS_BaseGeometry { */ EGS_PlanesT(EGS_Float xo, EGS_Float dx, int np, const string &Name, const T &A) : EGS_BaseGeometry(Name), a(A) { - if( np < 1 ) egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct" - " a plane set with %d plane positions\n",np); - if( dx <= 0 ) egsFatal("EGS_PlanesT::EGS_PlanesT: attempt to construct" - " a plane set with a non-positive slice thickness %g\n",dx); - p = new EGS_Float [np+1]; p[0] = xo; - for(int j=0; j p_last ) return false; + if (xp < p[0] || xp > p_last) { + return false; + } return true; }; int isWhere(const EGS_Vector &x) { EGS_Float xp = a*x; - if( xp < p[0] || xp > p_last ) return -1; - if( nreg == 1 ) return 0; + if (xp < p[0] || xp > p_last) { + return -1; + } + if (nreg == 1) { + return 0; + } //if( is_uniform ) { int res = (int) ((xp-p[0])/dp); return res; } return findRegion(xp,nreg,p); }; - int inside(const EGS_Vector &x) { return isWhere(x); }; + int inside(const EGS_Vector &x) { + return isWhere(x); + }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } double xp = a*x, up = a*u; EGS_Float t = 1e30; - if( up > 0 ) t = (p_last-xp)/up; - else if( up < 0 ) t = (p[0]-xp)/up; + if (up > 0) { + t = (p_last-xp)/up; + } + else if (up < 0) { + t = (p[0]-xp)/up; + } return t; }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { //EGS_Float d = 1e30; int res=ireg; //EGS_Float xp = a*x, up = a*u; - double d = 1e35; int res=ireg; + double d = 1e35; + int res=ireg; double xp = a*x, up = a*u; - if( ireg >= 0 ) { - int dir = 0; bool warn=false; EGS_Float dist; - if( up > 0 && ireg < n_plane ) { + if (ireg >= 0) { + int dir = 0; + bool warn=false; + EGS_Float dist; + if (up > 0 && ireg < n_plane) { d = (p[ireg+1]-xp)/up; //if( xp <= p[ireg+1] ) d = (p[ireg+1]-xp)/up; //else { @@ -257,7 +306,7 @@ class EGS_PLANES_EXPORT EGS_PlanesT : public EGS_BaseGeometry { //} dir = 1; } - else if( up < 0 ) { + else if (up < 0) { d = (p[ireg]-xp)/up; //if( xp >= p[ireg] ) d = (p[ireg]-xp)/up; //else { @@ -276,73 +325,120 @@ class EGS_PLANES_EXPORT EGS_PlanesT : public EGS_BaseGeometry { xp,up,ireg,dist); } */ - if( d > t ) res = ireg; + if (d > t) { + res = ireg; + } else { - t = d; res = ireg + dir; - if( res >= nreg ) res = -1; - if( newmed ) { - if( res >= 0 ) *newmed = medium(res); else *newmed=-1; + t = d; + res = ireg + dir; + if (res >= nreg) { + res = -1; + } + if (newmed) { + if (res >= 0) { + *newmed = medium(res); + } + else { + *newmed=-1; + } + } + if (normal) { + *normal = a.normal()*(-dir); } - if( normal ) { *normal = a.normal()*(-dir); } } return res; } - if( xp <= p[0] && up > 0 ) { d = (p[0] - xp)/up; res = 0; } - else if( xp >= p_last && up < 0 ) { - d = (p_last - xp)/up; res = nreg-1; + if (xp <= p[0] && up > 0) { + d = (p[0] - xp)/up; + res = 0; } - else if( xp > p[0] && xp < p_last ) { + else if (xp >= p_last && up < 0) { + d = (p_last - xp)/up; + res = nreg-1; + } + else if (xp > p[0] && xp < p_last) { // we think we are outside but we are inside. // hopefully a truncation problem with a particle // backscattered at a boundary - if( xp-p[0] < 3e-5 && up > 0 ) { d = 0; res = 0; } - else if( p_last-xp < 3e-5 && up < 0 ) { d = 0; res = nreg-1; } + if (xp-p[0] < 3e-5 && up > 0) { + d = 0; + res = 0; + } + else if (p_last-xp < 3e-5 && up < 0) { + d = 0; + res = nreg-1; + } + } + if (d <= t) { + t = d; + if (newmed) { + *newmed = medium(res); + } + if (normal) if (up > 0) { + *normal = a.normal()*(-1.); + } + else { + *normal = a.normal(); + } } - if( d <= t ) { - t = d; if( newmed ) *newmed = medium(res); - if( normal ) if( up > 0 ) *normal = a.normal()*(-1.); - else *normal = a.normal(); + else { + res = -1; } - else res = -1; return res; }; EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float xp = a*x; - if( ireg >= 0 ) { + if (ireg >= 0) { EGS_Float t = xp - p[ireg]; - if( ireg+1 <= n_plane ) { + if (ireg+1 <= n_plane) { EGS_Float t2 = p[ireg+1] - xp; - if( t2 < t ) t = t2; + if (t2 < t) { + t = t2; + } } return t; } - if( xp <= p[0] ) return p[0] - xp; - if( xp >= p_last ) return xp - p_last; + if (xp <= p[0]) { + return p[0] - xp; + } + if (xp >= p_last) { + return xp - p_last; + } return 0; // this should not happen. }; - const string &getType() const { return a.getType(); }; + const string &getType() const { + return a.getType(); + }; void printInfo() const { EGS_BaseGeometry::printInfo(); a.printInfo(); - if( is_uniform ) + if (is_uniform) egsInformation(" first plane at %g, %d slices of %g thickness\n", - p[0],nreg,dp); + p[0],nreg,dp); else { egsInformation(" plane positions = "); - for(int j=0; jisInside(x) && !planes[np-1]->isInside(x)); }; int isWhere(const EGS_Vector &x) { - if( !planes[0]->isInside(x) ) return -1; - if( planes[np-1]->isInside(x) ) return -1; - for(int j=0; jisInside(x) && !planes[j+1]->isInside(x) ) + if (!planes[0]->isInside(x)) { + return -1; + } + if (planes[np-1]->isInside(x)) { + return -1; + } + for (int j=0; jisInside(x) && !planes[j+1]->isInside(x)) { return j; + } return -1; // this should not happen. }; - int inside(const EGS_Vector &x) { return isInside(x); }; + int inside(const EGS_Vector &x) { + return isInside(x); + }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - int m1, m2; EGS_Vector n1, n2; - EGS_Float t1 = t; int i1=planes[ireg]->howfar(0,x,u,t1,&m1,&n1); - EGS_Float t2 = t; int i2=planes[ireg+1]->howfar(-1,x,u,t2,&m2,&n2); + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + if (ireg >= 0) { + int m1, m2; + EGS_Vector n1, n2; + EGS_Float t1 = t; + int i1=planes[ireg]->howfar(0,x,u,t1,&m1,&n1); + EGS_Float t2 = t; + int i2=planes[ireg+1]->howfar(-1,x,u,t2,&m2,&n2); int res = ireg; - if( i1 == -1 && i2 == 0 ) { - if( t1 < t2 ) { - t = t1; res = ireg-1; if( normal ) *normal = n1; + if (i1 == -1 && i2 == 0) { + if (t1 < t2) { + t = t1; + res = ireg-1; + if (normal) { + *normal = n1; + } } else { - t = t2; res = ireg+1; if(res > nreg-1) res = -1; - if( normal ) *normal = n2; + t = t2; + res = ireg+1; + if (res > nreg-1) { + res = -1; + } + if (normal) { + *normal = n2; + } } } - else if( i1 == -1 ) { - t = t1; res = ireg-1; if( normal ) *normal = n1; + else if (i1 == -1) { + t = t1; + res = ireg-1; + if (normal) { + *normal = n1; + } } - else if( i2 == 0 ) { - t = t2; res=ireg+1; if(res > nreg-1) res = -1; - if( normal ) *normal = n2; + else if (i2 == 0) { + t = t2; + res=ireg+1; + if (res > nreg-1) { + res = -1; + } + if (normal) { + *normal = n2; + } } - if( newmed && res != ireg ) { - if(res >= 0) *newmed = medium(res); else *newmed = -1; + if (newmed && res != ireg) { + if (res >= 0) { + *newmed = medium(res); + } + else { + *newmed = -1; + } } return res; } - if( !planes[0]->isInside(x) ) { + if (!planes[0]->isInside(x)) { int iaux = planes[0]->howfar(-1,x,u,t,newmed,normal); return iaux; } int i1 = planes[nreg]->howfar(0,x,u,t,newmed,normal); - if( i1 < 0 ) return nreg-1; + if (i1 < 0) { + return nreg-1; + } return -1; }; EGS_Float hownear(int ireg,const EGS_Vector &x) { - if( ireg >= 0 ) { + if (ireg >= 0) { EGS_Float t1 = planes[ireg]->hownear(0,x); EGS_Float t2 = planes[ireg+1]->hownear(-1,x); - if( t1 < t2 ) return t1; else return t2; + if (t1 < t2) { + return t1; + } + else { + return t2; + } } - if( !planes[0]->isInside(x) ) + if (!planes[0]->isInside(x)) { return planes[0]->hownear(-1,x); + } return planes[np-1]->hownear(0,x); }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; diff --git a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp index 45d7f116d..809524f4f 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.cpp @@ -47,93 +47,112 @@ static EGS_PRISM_LOCAL string __prism("EGS_Prism"); extern "C" { -EGS_PRISM_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { + EGS_PRISM_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning("createGeometry(prism): null input?\n"); - return 0; - } - string type; - int err = input->getInput("type",type); - if( err ) { - egsWarning("createGeometry(prism): missing 'type' input\n"); - return 0; - } - EGS_BaseGeometry *g; - vector p; - err = input->getInput("points",p); - if( err ) { - egsWarning("createGeometry(prism): missing 'points' input\n"); - return 0; - } - bool open = true; - vector tmp; - err = input->getInput("closed",tmp); - if( !err && tmp.size() == 2 ) open = false; - bool p_open = false; int itmp; - err = input->getInput("open triangle",itmp); - if( !err && itmp == 1 ) p_open = true; - if( input->compare(type,__prismX) || input->compare(type,__prismY) - || input->compare(type,__prismZ) ) { - int np = p.size()/2; - if( np < 3 ) { - egsWarning("createGeometry(prism): at least 3 points are required " - "to construct a prism\n"); return 0; + if (!input) { + egsWarning("createGeometry(prism): null input?\n"); + return 0; } - vector points; - for(int j=0; jcompare(type,__prismX) ) - g=new EGS_PrismX(new EGS_PolygonYZ(points, - EGS_XProjector(__prismX),p_open)); - else if( input->compare(type,__prismY) ) - g=new EGS_PrismY(new EGS_PolygonXZ(points, - EGS_YProjector(__prismY),p_open)); - else - g=new EGS_PrismZ(new EGS_PolygonXY(points, - EGS_ZProjector(__prismZ),p_open)); + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(prism): missing 'type' input\n"); + return 0; } - else { - if( input->compare(type,__prismX) ) - g=new EGS_PrismX(new EGS_PolygonYZ(points, - EGS_XProjector(__prismX),p_open),tmp[0],tmp[1]); - else if( input->compare(type,__prismY) ) - g=new EGS_PrismY(new EGS_PolygonXZ(points, - EGS_YProjector(__prismY),p_open),tmp[0],tmp[1]); - else - g=new EGS_PrismZ(new EGS_PolygonXY(points, - EGS_ZProjector(__prismZ),p_open),tmp[0],tmp[1]); + EGS_BaseGeometry *g; + vector p; + err = input->getInput("points",p); + if (err) { + egsWarning("createGeometry(prism): missing 'points' input\n"); + return 0; } - } - else { - int np = p.size()/3; - if( np < 3 ) { - egsWarning("createGeometry(prism): at least 3 points are required" - " to construct a prism\n"); return 0; + bool open = true; + vector tmp; + err = input->getInput("closed",tmp); + if (!err && tmp.size() == 2) { + open = false; } - vector points; - for(int j=0; j 1e-6 ) points.push_back(points[0]); - np = points.size(); - EGS_Projector pro(points[0],points[1],points[np-2],__prism); - vector p2; - {for(int j=0; j 1e-6 ) { - egsWarning("createGeometry(prism): " - "points are not on a plane\n"); return 0; + bool p_open = false; + int itmp; + err = input->getInput("open triangle",itmp); + if (!err && itmp == 1) { + p_open = true; + } + if (input->compare(type,__prismX) || input->compare(type,__prismY) + || input->compare(type,__prismZ)) { + int np = p.size()/2; + if (np < 3) { + egsWarning("createGeometry(prism): at least 3 points are required " + "to construct a prism\n"); + return 0; + } + vector points; + for (int j=0; jcompare(type,__prismX)) + g=new EGS_PrismX(new EGS_PolygonYZ(points, + EGS_XProjector(__prismX),p_open)); + else if (input->compare(type,__prismY)) + g=new EGS_PrismY(new EGS_PolygonXZ(points, + EGS_YProjector(__prismY),p_open)); + else + g=new EGS_PrismZ(new EGS_PolygonXY(points, + EGS_ZProjector(__prismZ),p_open)); } - }} - if( open ) g = new EGS_Prism(new EGS_Polygon(p2,pro,p_open)); - else g = new EGS_Prism(new EGS_Polygon(p2,pro,p_open),tmp[0],tmp[1]); + else { + if (input->compare(type,__prismX)) + g=new EGS_PrismX(new EGS_PolygonYZ(points, + EGS_XProjector(__prismX),p_open),tmp[0],tmp[1]); + else if (input->compare(type,__prismY)) + g=new EGS_PrismY(new EGS_PolygonXZ(points, + EGS_YProjector(__prismY),p_open),tmp[0],tmp[1]); + else + g=new EGS_PrismZ(new EGS_PolygonXY(points, + EGS_ZProjector(__prismZ),p_open),tmp[0],tmp[1]); + } + } + else { + int np = p.size()/3; + if (np < 3) { + egsWarning("createGeometry(prism): at least 3 points are required" + " to construct a prism\n"); + return 0; + } + vector points; + for (int j=0; j 1e-6) { + points.push_back(points[0]); + } + np = points.size(); + EGS_Projector pro(points[0],points[1],points[np-2],__prism); + vector p2; + { + for (int j=0; j 1e-6) { + egsWarning("createGeometry(prism): " + "points are not on a plane\n"); + return 0; + } + } + } + if (open) { + g = new EGS_Prism(new EGS_Polygon(p2,pro,p_open)); + } + else { + g = new EGS_Prism(new EGS_Polygon(p2,pro,p_open),tmp[0],tmp[1]); + } + } + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; } - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.h b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.h index 6deb60266..4c7399626 100644 --- a/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.h +++ b/HEN_HOUSE/egs++/geometry/egs_prism/egs_prism.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_PRISM_DLL -#define EGS_PRISM_EXPORT __declspec(dllexport) -#else -#define EGS_PRISM_EXPORT __declspec(dllimport) -#endif -#define EGS_PRISM_LOCAL + #ifdef BUILD_PRISM_DLL + #define EGS_PRISM_EXPORT __declspec(dllexport) + #else + #define EGS_PRISM_EXPORT __declspec(dllimport) + #endif + #define EGS_PRISM_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_PRISM_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_PRISM_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_PRISM_EXPORT -#define EGS_PRISM_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_PRISM_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_PRISM_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_PRISM_EXPORT + #define EGS_PRISM_LOCAL + #endif #endif @@ -109,8 +109,8 @@ class EGS_PRISM_EXPORT EGS_PrismT : public EGS_BaseGeometry { T *p; //!< The base polygon EGS_Vector a; //!< The normal vector to the base plane EGS_Float - d1, //!< Distance of the top plane to the base (for closed prisms) - d2; //!< Distance of the bottom plane to the base (for closed prisms) + d1, //!< Distance of the top plane to the base (for closed prisms) + d2; //!< Distance of the bottom plane to the base (for closed prisms) bool open; //!< Is the prism open ? @@ -135,72 +135,125 @@ class EGS_PRISM_EXPORT EGS_PrismT : public EGS_BaseGeometry { EGS_PrismT(T *P, EGS_Float D1, EGS_Float D2, const string &Name="") : EGS_BaseGeometry(Name), p(P), a(p->getNormal()), d1(D1), d2(D2), open(false) { - if( d1 > d2 ) { d1 = D2; d2 = D1; } + if (d1 > d2) { + d1 = D2; + d2 = D1; + } is_convex = p->isConvex(); }; /*! \brief Desctructor, deletes the base polygon */ - ~EGS_PrismT() { delete p; }; + ~EGS_PrismT() { + delete p; + }; bool isInside(const EGS_Vector &x) { - if( !open ) { + if (!open) { EGS_Float d = p->distance(x); - if( d < d1 || d > d2 ) return false; + if (d < d1 || d > d2) { + return false; + } } return p->isInside2D(x); }; int isWhere(const EGS_Vector &x) { - if( isInside(x) ) return 0; else return -1; + if (isInside(x)) { + return 0; + } + else { + return -1; + } + }; + int inside(const EGS_Vector &x) { + return isWhere(x); }; - int inside(const EGS_Vector &x) { return isWhere(x); }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { EGS_2DVector v; EGS_2DVector *pv = normal ? &v : 0; - if( open ) { + if (open) { bool hit = p->howfar2D(ireg == 0 ? true : false,x,u,t,pv); - if( !hit ) return ireg; - if( newmed ) *newmed = !ireg ? -1 : med; - if( normal ) *normal = p->getNormal(v); + if (!hit) { + return ireg; + } + if (newmed) { + *newmed = !ireg ? -1 : med; + } + if (normal) { + *normal = p->getNormal(v); + } return !ireg ? -1 : 0; } EGS_Float up = a*u, d = p->distance(x); - if( !ireg ) { // inside - EGS_Float tt = 1e30; int inew = ireg; - if( up > 0 ) tt = (d2 - d)/up; else tt = (d1 - d)/up; - if( tt <= t ) { - t = tt; inew = -1; - if( normal ) *normal = up>0 ? a*(-1) : a; - if( newmed ) *newmed = -1; + if (!ireg) { // inside + EGS_Float tt = 1e30; + int inew = ireg; + if (up > 0) { + tt = (d2 - d)/up; + } + else { + tt = (d1 - d)/up; + } + if (tt <= t) { + t = tt; + inew = -1; + if (normal) { + *normal = up>0 ? a*(-1) : a; + } + if (newmed) { + *newmed = -1; + } } bool hit = p->howfar2D(true,x,u,t,pv); - if( !hit ) return inew; - if( newmed ) *newmed = -1; - if( normal ) *normal = p->getNormal(v); + if (!hit) { + return inew; + } + if (newmed) { + *newmed = -1; + } + if (normal) { + *normal = p->getNormal(v); + } return -1; } - if( d < d1 || d > d2 ) { + if (d < d1 || d > d2) { EGS_Float tt = 1e30; - if( d < d1 && up > 0 ) tt = (d1 - d)/up; - else if( d > d2 && up < 0 ) tt = (d2 - d)/up; - if( tt < t ) { + if (d < d1 && up > 0) { + tt = (d1 - d)/up; + } + else if (d > d2 && up < 0) { + tt = (d2 - d)/up; + } + if (tt < t) { EGS_Vector xp(x + u*tt); - if( p->isInside2D(xp) ) { - t = tt; if( newmed ) *newmed = med; - if( normal ) *normal = up>0 ? a*(-1) : a; + if (p->isInside2D(xp)) { + t = tt; + if (newmed) { + *newmed = med; + } + if (normal) { + *normal = up>0 ? a*(-1) : a; + } return 0; } } } EGS_Float tt = t; bool hit = p->howfar2D(false,x,u,tt,pv); - if( !hit ) return ireg; + if (!hit) { + return ireg; + } d = p->distance(x+u*tt); - if( d >= d1 && d <= d2 ) { - t = tt; if( newmed ) *newmed = med; - if( normal ) *normal = p->getNormal(v); + if (d >= d1 && d <= d2) { + t = tt; + if (newmed) { + *newmed = med; + } + if (normal) { + *normal = p->getNormal(v); + } return 0; } return ireg; @@ -208,32 +261,54 @@ class EGS_PRISM_EXPORT EGS_PrismT : public EGS_BaseGeometry { EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float tperp = p->hownear2D(ireg == 0 ? true : false,x); - if( open ) return tperp; + if (open) { + return tperp; + } EGS_Float d = p->distance(x); - if( !ireg ) { // inside + if (!ireg) { // inside EGS_Float t = d2 - d; - if( t < tperp ) tperp = t; + if (t < tperp) { + tperp = t; + } t = d - d1; - if( t < tperp ) tperp = t; + if (t < tperp) { + tperp = t; + } } else { EGS_Float t; - if( d < d1 ) t = d1 - d; - else if( d > d2 ) t = d - d2; - else return tperp; - if( p->isInside2D(x) ) tperp = t; - else tperp = sqrt(tperp*tperp + t*t); + if (d < d1) { + t = d1 - d; + } + else if (d > d2) { + t = d - d2; + } + else { + return tperp; + } + if (p->isInside2D(x)) { + tperp = t; + } + else { + tperp = sqrt(tperp*tperp + t*t); + } } return tperp; }; //const string &getType() const { return type; }; - const string &getType() const { return p->getType(); }; + const string &getType() const { + return p->getType(); + }; void printInfo() const { EGS_BaseGeometry::printInfo(); - if( open ) egsInformation(" open\n"); - else egsInformation(" closed with planes at %g and %g\n",d1,d2); + if (open) { + egsInformation(" open\n"); + } + else { + egsInformation(" closed with planes at %g and %g\n",d1,d2); + } egsInformation("===================================================\n"); }; diff --git a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp index abc2c5110..310bd3743 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.cpp @@ -48,33 +48,41 @@ static EGS_PYRAMID_LOCAL string __pyr = "EGS_Pyramid"; template EGS_PyramidT::EGS_PyramidT(T *P, const EGS_Vector &Xo, bool O, - const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo), + const string &Name) : EGS_BaseGeometry(Name), p(P), xo(Xo), a(p->getNormal()), open(O) { nreg = 1; - d = p->distance(xo); xop = p->getProjection(xo); - if( fabs(d) < 1e-7 ) egsFatal("%s: the tip is too close to" - " the base (%g)\n",getType().c_str(),fabs(d)); - if( d < 0 ) { a *= (-1); d *= (-1); } + d = p->distance(xo); + xop = p->getProjection(xo); + if (fabs(d) < 1e-7) egsFatal("%s: the tip is too close to" + " the base (%g)\n",getType().c_str(),fabs(d)); + if (d < 0) { + a *= (-1); + d *= (-1); + } EGS_Vector v2 = p->getPoint(0), v1; - n = p->getN(); s = new EGS_Polygon * [n]; + n = p->getN(); + s = new EGS_Polygon * [n]; vector aux; - for(int j=0; jgetN(); j++) { - v1 = v2; v2 = p->getPoint(j+1); + for (int j=0; jgetN(); j++) { + v1 = v2; + v2 = p->getPoint(j+1); EGS_Vector aj = p->getNormal(j); EGS_Projector *pro = new EGS_Projector(v1,xo,v2,""); EGS_Vector n = pro->normal(); - if( n*aj < 0 ) { - delete pro; pro = new EGS_Projector(v2,xo,v1,""); + if (n*aj < 0) { + delete pro; + pro = new EGS_Projector(v2,xo,v1,""); n = pro->normal(); - if( n*aj < 0 ) + if (n*aj < 0) egsFatal("%s: n*aj < 0 for both normal orientations?\n", - getType().c_str()); + getType().c_str()); } aux.push_back(pro->getProjection(v1)); aux.push_back(pro->getProjection(xo)); aux.push_back(pro->getProjection(v2)); s[j] = new EGS_Polygon(aux,*pro,open); - aux.clear(); delete pro; + aux.clear(); + delete pro; } is_convex = p->isConvex(); } @@ -86,87 +94,99 @@ void EGS_PyramidT::printInfo() const { extern "C" { -EGS_PYRAMID_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { + EGS_PYRAMID_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning("createGeometry(pyramid): null input?\n"); - return 0; - } - string type; - int err = input->getInput("type",type); - if( err ) { - egsWarning("createGeometry(pyramid): missing 'type' input\n"); - return 0; - } - EGS_BaseGeometry *g; - vector p; - err = input->getInput("points",p); - if( err ) { - egsWarning("createGeometry(pyramid): missing 'points' input\n"); - return 0; - } - vector tip; - err = input->getInput("tip",tip); - if( err || tip.size() != 3 ) { - egsWarning("createGeometry(pyramid): wrong/missing 'tip' input\n"); - return 0; - } - bool o = true; - int is_closed; - err = input->getInput("closed",is_closed); - if( !err && is_closed == 1 ) o = false; - egsWarning("%s: open = %d\n",type.c_str(),o); - if( input->compare(type,__pyrX) || input->compare(type,__pyrY) || - input->compare(type,__pyrZ) ) { - int np = p.size()/2; - if( np < 3 ) { - egsWarning("createGeometry(pyramid): at least 3 points are " - "required to construct a pyramid\n"); return 0; + if (!input) { + egsWarning("createGeometry(pyramid): null input?\n"); + return 0; } - vector points; - for(int j=0; jcompare(type,__pyrX) ) - g=new EGS_PyramidX(new - EGS_PolygonYZ(points,EGS_XProjector(__pyrX)), - EGS_Vector(tip[0],tip[1],tip[2]),o); - else if( input->compare(type,__pyrY) ) - g=new EGS_PyramidY(new EGS_PolygonXZ(points, - EGS_YProjector(__pyrY)), - EGS_Vector(tip[0],tip[1],tip[2]),o); - else - g=new EGS_PyramidZ(new - EGS_PolygonXY(points,EGS_ZProjector(__pyrZ)), - EGS_Vector(tip[0],tip[1],tip[2]),o); - } - else { - int np = p.size()/3; - if( np < 3 ) { - egsWarning("createGeometry(pyramid): at least 3 points are required" - " to construct a pyramid\n"); return 0; + string type; + int err = input->getInput("type",type); + if (err) { + egsWarning("createGeometry(pyramid): missing 'type' input\n"); + return 0; + } + EGS_BaseGeometry *g; + vector p; + err = input->getInput("points",p); + if (err) { + egsWarning("createGeometry(pyramid): missing 'points' input\n"); + return 0; + } + vector tip; + err = input->getInput("tip",tip); + if (err || tip.size() != 3) { + egsWarning("createGeometry(pyramid): wrong/missing 'tip' input\n"); + return 0; + } + bool o = true; + int is_closed; + err = input->getInput("closed",is_closed); + if (!err && is_closed == 1) { + o = false; } - vector points; - for(int j=0; j 1e-6 ) points.push_back(points[0]); - np = points.size(); - EGS_Projector pro(points[0],points[1],points[np-2],__pyr); - vector p2; - {for(int j=0; j 1e-6 ) { - egsWarning("createGeometry(pyramid): " - "points are not on a plane\n"); return 0; + egsWarning("%s: open = %d\n",type.c_str(),o); + if (input->compare(type,__pyrX) || input->compare(type,__pyrY) || + input->compare(type,__pyrZ)) { + int np = p.size()/2; + if (np < 3) { + egsWarning("createGeometry(pyramid): at least 3 points are " + "required to construct a pyramid\n"); + return 0; } - }} - g = new EGS_Pyramid(new EGS_Polygon(p2,pro), - EGS_Vector(tip[0],tip[1],tip[2]),o); + vector points; + for (int j=0; jcompare(type,__pyrX)) + g=new EGS_PyramidX(new + EGS_PolygonYZ(points,EGS_XProjector(__pyrX)), + EGS_Vector(tip[0],tip[1],tip[2]),o); + else if (input->compare(type,__pyrY)) + g=new EGS_PyramidY(new EGS_PolygonXZ(points, + EGS_YProjector(__pyrY)), + EGS_Vector(tip[0],tip[1],tip[2]),o); + else + g=new EGS_PyramidZ(new + EGS_PolygonXY(points,EGS_ZProjector(__pyrZ)), + EGS_Vector(tip[0],tip[1],tip[2]),o); + } + else { + int np = p.size()/3; + if (np < 3) { + egsWarning("createGeometry(pyramid): at least 3 points are required" + " to construct a pyramid\n"); + return 0; + } + vector points; + for (int j=0; j 1e-6) { + points.push_back(points[0]); + } + np = points.size(); + EGS_Projector pro(points[0],points[1],points[np-2],__pyr); + vector p2; + { + for (int j=0; j 1e-6) { + egsWarning("createGeometry(pyramid): " + "points are not on a plane\n"); + return 0; + } + } + } + g = new EGS_Pyramid(new EGS_Polygon(p2,pro), + EGS_Vector(tip[0],tip[1],tip[2]),o); + } + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; } - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.h b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.h index 774a99049..9dd2dade4 100644 --- a/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.h +++ b/HEN_HOUSE/egs++/geometry/egs_pyramid/egs_pyramid.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_PYRAMID_DLL -#define EGS_PYRAMID_EXPORT __declspec(dllexport) -#else -#define EGS_PYRAMID_EXPORT __declspec(dllimport) -#endif -#define EGS_PYRAMID_LOCAL + #ifdef BUILD_PYRAMID_DLL + #define EGS_PYRAMID_EXPORT __declspec(dllexport) + #else + #define EGS_PYRAMID_EXPORT __declspec(dllimport) + #endif + #define EGS_PYRAMID_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_PYRAMID_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_PYRAMID_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_PYRAMID_EXPORT -#define EGS_PYRAMID_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_PYRAMID_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_PYRAMID_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_PYRAMID_EXPORT + #define EGS_PYRAMID_LOCAL + #endif #endif @@ -130,87 +130,123 @@ class EGS_PYRAMID_EXPORT EGS_PyramidT : public EGS_BaseGeometry { ~EGS_PyramidT() { delete p; - for(int j=0; j 0 ) return false; + EGS_Vector xp(x-xo); + EGS_Float axp = a*xp; + if (axp > 0) { + return false; + } //if( axp > -1e-10 ) return true; - if( !open && d + axp < 0 ) return false; + if (!open && d + axp < 0) { + return false; + } EGS_Float t = -d/axp; //return p->isInside2D(xop+p->getProjection(xp)*t); return p->isInside2D(p->getProjection(xo + t*xp)); }; int isWhere(const EGS_Vector &x) { - if( isInside(x) ) return 0; else return -1; + if (isInside(x)) { + return 0; + } + else { + return -1; + } + }; + int inside(const EGS_Vector &x) { + return isWhere(x); }; - int inside(const EGS_Vector &x) { return isWhere(x); }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { int jhit=-1; - if( ireg == 0 ) { + if (ireg == 0) { int convex = p->isConvex(); - for(int j=0; jisInside2D(x) ) { - if(s[j]->isInside(x)) - if( s[j]->howfar(true,x,u,t) ) jhit = j; + for (int j=0; jisInside2D(x)) { + if (s[j]->isInside(x)) + if (s[j]->howfar(true,x,u,t)) { + jhit = j; + } + } + } + if (!open) { + if (p->howfar(true,x,u,t)) { + jhit = n; } } - if( !open ) { - if( p->howfar(true,x,u,t) ) jhit = n; + if (jhit < 0) { + return ireg; } - if( jhit < 0 ) return ireg; - if( newmed ) *newmed = -1; - if( normal ) *normal = jhit < n ? s[jhit]->getNormal() : - p->getNormal(); + if (newmed) { + *newmed = -1; + } + if (normal) *normal = jhit < n ? s[jhit]->getNormal() : + p->getNormal(); return -1; } - for(int j=0; jisInside(x) && s[j]->isInside2D(x); EGS_Float up = u*s[j]->getNormal(), xp = s[j]->distance(x); - if( up > 0 && xp < 0 ) { + if (up > 0 && xp < 0) { EGS_Float tt = -xp/up; - if( tt <= t && s[j]->isInside2D(x+u*tt) ) { - t = tt; jhit = j; + if (tt <= t && s[j]->isInside2D(x+u*tt)) { + t = tt; + jhit = j; } } } - if( !open ) { + if (!open) { EGS_Float up = u*p->getNormal(), xp = p->distance(x); - if( up > 0 && xp < 0 ) { + if (up > 0 && xp < 0) { EGS_Float tt = -xp/up; - if( tt <= t && p->isInside2D(x+u*tt) ) { - t = tt; jhit = n; + if (tt <= t && p->isInside2D(x+u*tt)) { + t = tt; + jhit = n; } } } - if( jhit < 0 ) return ireg; - if( newmed ) *newmed = med; - if( normal ) *normal = jhit < n ? s[jhit]->getNormal()*(-1) : - p->getNormal()*(-1); + if (jhit < 0) { + return ireg; + } + if (newmed) { + *newmed = med; + } + if (normal) *normal = jhit < n ? s[jhit]->getNormal()*(-1) : + p->getNormal()*(-1); return 0; }; // TODO: optimize. this implementation is waaaay too slow. EGS_Float hownear(int ireg, const EGS_Vector &x) { EGS_Float tperp = 1e30; - for(int j=0; jhownear(true,x); - if( t < tperp ) { - if( t <= 0 ) return 0; tperp = t; + if (t < tperp) { + if (t <= 0) { + return 0; + } + tperp = t; } } - if( !open ) { + if (!open) { EGS_Float t = p->hownear(true,x); - if( t < tperp ) tperp = t; + if (t < tperp) { + tperp = t; + } } return tperp; }; - const string &getType() const { return p->getType(); }; + const string &getType() const { + return p->getType(); + }; void printInfo() const; diff --git a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp index 6736bc8b4..37651b1bd 100644 --- a/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_smart_envelope/egs_smart_envelope.cpp @@ -65,8 +65,8 @@ using namespace std; string EGS_SMART_ENVELOPE_LOCAL EGS_SmartEnvelope::type = "EGS_SmartEnvelope"; void EGS_SmartEnvelope::setMedia(EGS_Input *,int,const int *) { - egsWarning("EGS_SmartEnvelope::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + egsWarning("EGS_SmartEnvelope::setMedia: don't use this method. Use the\n" + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_SmartEnvelope::setRelativeRho(int start, int end, EGS_Float rho) { @@ -75,8 +75,8 @@ void EGS_SmartEnvelope::setRelativeRho(int start, int end, EGS_Float rho) { void EGS_SmartEnvelope::setRelativeRho(EGS_Input *) { egsWarning("EGS_SmartEnvelope::setRelativeRho(): don't use this method." - " Use the\n setRelativeRho methods of the geometry objects that make up" - " this geometry\n"); + " Use the\n setRelativeRho methods of the geometry objects that make up" + " this geometry\n"); } struct EGS_SMART_ENVELOPE_LOCAL SmartEnvelopeAux { @@ -86,51 +86,72 @@ struct EGS_SMART_ENVELOPE_LOCAL SmartEnvelopeAux { int nreg; int *regs; SmartEnvelopeAux() : g(0), ireg(-1), type(0), nreg(0) {}; - ~SmartEnvelopeAux() { if(nreg>0) delete [] regs; }; + ~SmartEnvelopeAux() { + if (nreg>0) { + delete [] regs; + } + }; }; EGS_SmartEnvelope::EGS_SmartEnvelope(EGS_BaseGeometry *G, - const vector &fgeoms, const string &Name) : - EGS_BaseGeometry(Name), geometries(0), gindex(0), - reg_to_inscr(0), reg_to_base(0), local_start(0), itype(0) { - if( !G ) egsFatal("EGS_SmartEnvelope: base geometry must not be null\n"); - g = G; g->ref(); + const vector &fgeoms, const string &Name) : + EGS_BaseGeometry(Name), geometries(0), gindex(0), + reg_to_inscr(0), reg_to_base(0), local_start(0), itype(0) { + if (!G) { + egsFatal("EGS_SmartEnvelope: base geometry must not be null\n"); + } + g = G; + g->ref(); n_in = fgeoms.size(); - if( !n_in ) egsFatal("EGS_SmartEnvelope: no inscribed geometries!\n"); + if (!n_in) { + egsFatal("EGS_SmartEnvelope: no inscribed geometries!\n"); + } geometries = new EGS_BaseGeometry * [n_in]; nbase = g->regions(); - gindex = new int [nbase]; itype = new char [fgeoms.size()]; int j; - for(j=0; jg; geometries[j]->ref(); + int nreg_inscribed = 0; + bool ok = true; + for (j=0; jg; + geometries[j]->ref(); int i = fgeoms[j]->ireg; - if( gindex[i] >= 0 ) { + if (gindex[i] >= 0) { egsWarning("EGS_SmartEnvelope:" - " There can only be a single geometry inscribed in a region\n"); + " There can only be a single geometry inscribed in a region\n"); egsWarning(" You are trying to inscribe %s into region %d but\n", - geometries[j]->getName().c_str(),i); + geometries[j]->getName().c_str(),i); egsWarning(" geometry %s is already inscribed in this region\n", - geometries[gindex[i]]->getName().c_str()); + geometries[gindex[i]]->getName().c_str()); ok = false; } else { - gindex[i] = j; itype[j] = fgeoms[j]->type; + gindex[i] = j; + itype[j] = fgeoms[j]->type; //egsInformation("inscribing %d into %d with type %d\n",j,i,itype[j]); nreg_inscribed += geometries[j]->regions(); } } - if( !ok ) egsFatal("EGS_SmartEnvelope: errors during definition\n"); + if (!ok) { + egsFatal("EGS_SmartEnvelope: errors during definition\n"); + } nreg = nbase + nreg_inscribed; local_start = new int [fgeoms.size()]; reg_to_inscr = new int [nreg_inscribed]; reg_to_base = new int [nreg_inscribed]; int nr = 0; - for(j=0; jregions(); - for(int i=nr; iregions(); + for (int i=nr; iireg; } @@ -138,39 +159,56 @@ EGS_SmartEnvelope::EGS_SmartEnvelope(EGS_BaseGeometry *G, } is_convex = g->isConvex(); has_rho_scaling = g->hasRhoScaling(); - if( !has_rho_scaling ) { - for(int j=0; jhasRhoScaling() ) { - has_rho_scaling = true; break; + if (!has_rho_scaling) { + for (int j=0; jhasRhoScaling()) { + has_rho_scaling = true; + break; } } } } EGS_SmartEnvelope::~EGS_SmartEnvelope() { - if( !g->deref() ) delete g; - for(int j=0; jderef() ) delete geometries[j]; + if (!g->deref()) { + delete g; + } + for (int j=0; jderef()) { + delete geometries[j]; + } + } + if (geometries) { + delete [] geometries; + } + if (gindex) { + delete [] gindex; + } + if (reg_to_inscr) { + delete [] reg_to_inscr; + } + if (reg_to_base) { + delete [] reg_to_base ; + } + if (local_start) { + delete [] local_start; + } + if (itype) { + delete itype; } - if( geometries) delete [] geometries; - if( gindex ) delete [] gindex; - if( reg_to_inscr ) delete [] reg_to_inscr; - if( reg_to_base ) delete [] reg_to_base ; - if( local_start ) delete [] local_start; - if( itype ) delete itype; } void EGS_SmartEnvelope::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" base geometry = %s (type %s)\n",g->getName().c_str(), - g->getType().c_str()); + g->getType().c_str()); egsInformation(" inscribed geometries:\n"); - for(int j=0; jgetName().c_str(),geometries[j]->getType().c_str(), - reg_to_base[j],(int)itype[j]); + for (int j=0; jgetName().c_str(),geometries[j]->getType().c_str(), + reg_to_base[j],(int)itype[j]); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } @@ -197,103 +235,115 @@ static char EGS_SMART_ENVELOPE_LOCAL eeg_keyword3[] = "inscribed geometries"; extern "C" { -EGS_SMART_ENVELOPE_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning(eeg_message1,eeg_message2); - return 0; - } - // - // *** Base geometry - // - EGS_Input *i = input->takeInputItem(eeg_keyword1); - if( !i ) { - egsWarning(eeg_message1,eeg_message3); return 0; - } - EGS_Input *ig = i->takeInputItem(eeg_keyword2); - EGS_BaseGeometry *g; - if( ig ) { // defined inline - g = EGS_BaseGeometry::createSingleGeometry(ig); - delete ig; - if( !g ) { - egsWarning(eeg_message1,eeg_message4); - delete i; return 0; + EGS_SMART_ENVELOPE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning(eeg_message1,eeg_message2); + return 0; } - } - else { // defined via a name of a previously defined geometry - string bgname; - int err = i->getInput(eeg_keyword1,bgname); - delete i; - if( err ) { - egsWarning(eeg_message1,eeg_message5); return 0; + // + // *** Base geometry + // + EGS_Input *i = input->takeInputItem(eeg_keyword1); + if (!i) { + egsWarning(eeg_message1,eeg_message3); + return 0; } - g = EGS_BaseGeometry::getGeometry(bgname); - if( !g ) { - egsWarning(eeg_message6,bgname.c_str()); return 0; + EGS_Input *ig = i->takeInputItem(eeg_keyword2); + EGS_BaseGeometry *g; + if (ig) { // defined inline + g = EGS_BaseGeometry::createSingleGeometry(ig); + delete ig; + if (!g) { + egsWarning(eeg_message1,eeg_message4); + delete i; + return 0; + } } - } - vector fgeoms; - int nbase = g->regions(); - EGS_Input *ix; - while( (ix = input->takeInputItem("inscribe geometry")) != 0 ) { - vector values; - ix->getInput("inscribe geometry",values); - if( values.size() < 2 ) egsWarning("createGeometry(smart envelope):" - " %d inputs for 'inscribe geometry'? 2 or more are needed\n",values.size()); - else { - EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(values[0]); - if( !gj ) egsWarning(eeg_message6,values[0].c_str()); + else { // defined via a name of a previously defined geometry + string bgname; + int err = i->getInput(eeg_keyword1,bgname); + delete i; + if (err) { + egsWarning(eeg_message1,eeg_message5); + return 0; + } + g = EGS_BaseGeometry::getGeometry(bgname); + if (!g) { + egsWarning(eeg_message6,bgname.c_str()); + return 0; + } + } + vector fgeoms; + int nbase = g->regions(); + EGS_Input *ix; + while ((ix = input->takeInputItem("inscribe geometry")) != 0) { + vector values; + ix->getInput("inscribe geometry",values); + if (values.size() < 2) egsWarning("createGeometry(smart envelope):" + " %d inputs for 'inscribe geometry'? 2 or more are needed\n",values.size()); else { - SmartEnvelopeAux *aux = new SmartEnvelopeAux; - aux->g = gj; - aux->ireg = atoi(values[1].c_str()); - aux->type = values.size() == 3 ? atoi(values[2].c_str()) : 0; - //egsInformation("set geometr: %s %d %d\n",values[0].c_str(),aux->ireg,aux->type); - if( aux->ireg < 0 || aux->ireg >= nbase ) { - egsWarning("createGeometry(smart envelope): wrong " - "region index %d for inscribed geometry %s\n", - aux->ireg,gj->getName().c_str()); - delete aux; + EGS_BaseGeometry *gj = EGS_BaseGeometry::getGeometry(values[0]); + if (!gj) { + egsWarning(eeg_message6,values[0].c_str()); + } + else { + SmartEnvelopeAux *aux = new SmartEnvelopeAux; + aux->g = gj; + aux->ireg = atoi(values[1].c_str()); + aux->type = values.size() == 3 ? atoi(values[2].c_str()) : 0; + //egsInformation("set geometr: %s %d %d\n",values[0].c_str(),aux->ireg,aux->type); + if (aux->ireg < 0 || aux->ireg >= nbase) { + egsWarning("createGeometry(smart envelope): wrong " + "region index %d for inscribed geometry %s\n", + aux->ireg,gj->getName().c_str()); + delete aux; + } + else { + fgeoms.push_back(aux); + } } - else fgeoms.push_back(aux); } + delete ix; + } + EGS_BaseGeometry *result = new EGS_SmartEnvelope(g,fgeoms,""); + result->setName(input); + result->setLabels(input); + for (int j=0; jsetName(input); - result->setLabels(input); - for(int j=0; j ®s) { -void EGS_SmartEnvelope::getLabelRegions (const string &str, vector ®s) { + // label defined in the envelope geometry + g->getLabelRegions(str, regs); - // label defined in the envelope geometry - g->getLabelRegions(str, regs); + // label defined in the inscribed geometries + vector gregs; + int shift=0; + for (int i=0; igetLabelRegions(str, gregs); + } - // label defined in the inscribed geometries - vector gregs; - int shift=0; - for (int i=0; igetLabelRegions(str, gregs); + // add regions to the list + regs.insert(regs.end(), gregs.begin(), gregs.end()); - // shift region numbers according to indexing style - for (int j=0; j &fgeoms, const string &Name = ""); - - ~EGS_SmartEnvelope(); - - bool isInside(const EGS_Vector &x) { - return g->isInside(x); - }; - - int isWhere(const EGS_Vector &x) { - int ibase = g->isWhere(x); - if( ibase < 0 ) return ibase; - int j = gindex[ibase]; - if( j >= 0 ) { - int i = geometries[j]->isWhere(x); - if( i >= 0 ) ibase = local_start[j] + i; - } - return ibase; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - bool isRealRegion(int ireg) const { - if( ireg < nbase ) return g->isRealRegion(ireg); - int i = ireg - nbase; int j = reg_to_inscr[i]; - return geometries[j]->isRealRegion(ireg-local_start[j]); - }; - - int medium(int ireg) const { - if( ireg < nbase ) return g->medium(ireg); - int i = ireg - nbase; - int j = reg_to_inscr[i]; - return geometries[j]->medium(ireg-local_start[j]); - }; - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - int ibase = ireg < nbase ? ireg : reg_to_base[ireg-nbase]; - return g->howfarToOutside(ibase,x,u); - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { - if( ireg >= 0 ) { - // inside. - if( ireg < nbase ) { - // in one of the regions of the base geometry - // check if we hit a boundary in the base geometry. - // if we do, newmed and normal get set accordingly. - int ibase = g->howfar(ireg,x,u,t,newmed,normal); - int j = gindex[ireg]; - if( j >= 0 ) { - // there is an inscribed geometry in this region - // => check if we will enter - int inscr = geometries[j]->howfar(-1,x,u,t,newmed,normal); - if( inscr >= 0 ) - // yes, we do. - return local_start[j] + inscr; - } - if( ibase == ireg || ibase < 0 ) return ibase; - // if here, we enter a new base geometry region. - j = gindex[ibase]; - if( j >= 0 && itype[j] ) { - // geometry inscribed in the new base region - // using inscription type 1 => check if already - // inside the inscribed - int inscr = geometries[j]->isWhere(x+u*t); - if( inscr >= 0 ) { - if( newmed ) *newmed = geometries[j]->medium(inscr); - return local_start[j] + inscr; - } - } - return ibase; - } - // if here, we are in an inscribed geometry. - int i = ireg-nbase; - int ibase = reg_to_base[i]; - int j = reg_to_inscr[i]; - int ilocal = ireg-local_start[j]; - int inew = geometries[j]->howfar(ilocal,x,u,t,newmed,normal); - if( itype[j] ) { - int ibase_new = g->howfar(ibase,x,u,t,newmed,normal); - if( ibase_new != ibase ) { - if( ibase_new < 0 ) return ibase_new; - j = gindex[ibase_new]; - if( j >= 0 && itype[j] ) { - int inscr = geometries[j]->isWhere(x+u*t); - if( inscr >= 0 ) { - if( newmed ) *newmed = geometries[j]->medium(inscr); - return local_start[j] + inscr; - } - } - return ibase_new; - } - } - if( inew < 0 ) { - if( newmed ) *newmed = g->medium(ibase); - return ibase; - } - return local_start[j] + inew; - } - // if here, we are outside the base geometry. - // check to see if we will enter. - int ibase = g->howfar(ireg,x,u,t,newmed,normal); - if( ibase >= 0 ) { - int j = gindex[ibase]; - if( j >= 0 && itype[j] ) { - int inscr = geometries[j]->isWhere(x+u*t); - if( inscr >= 0 ) { - if( newmed ) *newmed = geometries[j]->medium(inscr); - return local_start[j] + inscr; - } - } - } - return ibase; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - EGS_Float tmin; - if( ireg < nbase ) { // in one of the regions of the base geom. - tmin = g->hownear(ireg,x); - if( tmin <= 0 ) return tmin; - int j = gindex[ireg]; - if( j >= 0 ) { - EGS_Float ti = geometries[j]->hownear(-1,x); - if( ti < tmin ) tmin = ti; - } - return tmin; - } - int i = ireg-nbase; - int j = reg_to_inscr[i]; - int ilocal = ireg-local_start[j]; - tmin = geometries[j]->hownear(ilocal,x); - if( itype[j] ) { - int ibase = reg_to_base[i]; - EGS_Float tbase = g->hownear(ibase,x); - if( tbase < tmin ) tmin = tbase; - } - return tmin; - } - return g->hownear(ireg,x); - }; - - int getMaxStep() const { - int nstep = g->getMaxStep() + n_in; - for(int j=0; jgetMaxStep(); - return nstep; - }; - - bool hasBooleanProperty(int ireg, EGS_BPType prop) const { - if( ireg >= 0 && ireg < nreg ) { - if( ireg < nbase ) return g->hasBooleanProperty(ireg,prop); - int i = ireg-nbase, j = reg_to_inscr[i]; - return geometries[j]->hasBooleanProperty(ireg-local_start[j],prop); - } - return false; - }; - void setBooleanProperty(EGS_BPType) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int) { - setPropertyError("addBooleanProperty()"); - }; - void setBooleanProperty(EGS_BPType,int,int,int step=1) { - setPropertyError("setBooleanProperty()"); - }; - void addBooleanProperty(int,int,int,int step=1) { - setPropertyError("addBooleanProperty()"); - }; - - const string &getType() const { return type; }; - - void printInfo() const; - - void setRelativeRho(int start, int end, EGS_Float rho); - void setRelativeRho(EGS_Input *); - EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return 1; - if( ireg < nbase ) return g->getRelativeRho(ireg); - int i = ireg-nbase; int j = reg_to_inscr[i]; - return geometries[j]->getRelativeRho(ireg-local_start[j]); - }; - - virtual void getLabelRegions (const string &str, vector ®s); + EGS_SmartEnvelope(EGS_BaseGeometry *G, + const vector &fgeoms, const string &Name = ""); + + ~EGS_SmartEnvelope(); + + bool isInside(const EGS_Vector &x) { + return g->isInside(x); + }; + + int isWhere(const EGS_Vector &x) { + int ibase = g->isWhere(x); + if (ibase < 0) { + return ibase; + } + int j = gindex[ibase]; + if (j >= 0) { + int i = geometries[j]->isWhere(x); + if (i >= 0) { + ibase = local_start[j] + i; + } + } + return ibase; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + bool isRealRegion(int ireg) const { + if (ireg < nbase) { + return g->isRealRegion(ireg); + } + int i = ireg - nbase; + int j = reg_to_inscr[i]; + return geometries[j]->isRealRegion(ireg-local_start[j]); + }; + + int medium(int ireg) const { + if (ireg < nbase) { + return g->medium(ireg); + } + int i = ireg - nbase; + int j = reg_to_inscr[i]; + return geometries[j]->medium(ireg-local_start[j]); + }; + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + int ibase = ireg < nbase ? ireg : reg_to_base[ireg-nbase]; + return g->howfarToOutside(ibase,x,u); + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed = 0, EGS_Vector *normal = 0) { + if (ireg >= 0) { + // inside. + if (ireg < nbase) { + // in one of the regions of the base geometry + // check if we hit a boundary in the base geometry. + // if we do, newmed and normal get set accordingly. + int ibase = g->howfar(ireg,x,u,t,newmed,normal); + int j = gindex[ireg]; + if (j >= 0) { + // there is an inscribed geometry in this region + // => check if we will enter + int inscr = geometries[j]->howfar(-1,x,u,t,newmed,normal); + if (inscr >= 0) + // yes, we do. + { + return local_start[j] + inscr; + } + } + if (ibase == ireg || ibase < 0) { + return ibase; + } + // if here, we enter a new base geometry region. + j = gindex[ibase]; + if (j >= 0 && itype[j]) { + // geometry inscribed in the new base region + // using inscription type 1 => check if already + // inside the inscribed + int inscr = geometries[j]->isWhere(x+u*t); + if (inscr >= 0) { + if (newmed) { + *newmed = geometries[j]->medium(inscr); + } + return local_start[j] + inscr; + } + } + return ibase; + } + // if here, we are in an inscribed geometry. + int i = ireg-nbase; + int ibase = reg_to_base[i]; + int j = reg_to_inscr[i]; + int ilocal = ireg-local_start[j]; + int inew = geometries[j]->howfar(ilocal,x,u,t,newmed,normal); + if (itype[j]) { + int ibase_new = g->howfar(ibase,x,u,t,newmed,normal); + if (ibase_new != ibase) { + if (ibase_new < 0) { + return ibase_new; + } + j = gindex[ibase_new]; + if (j >= 0 && itype[j]) { + int inscr = geometries[j]->isWhere(x+u*t); + if (inscr >= 0) { + if (newmed) { + *newmed = geometries[j]->medium(inscr); + } + return local_start[j] + inscr; + } + } + return ibase_new; + } + } + if (inew < 0) { + if (newmed) { + *newmed = g->medium(ibase); + } + return ibase; + } + return local_start[j] + inew; + } + // if here, we are outside the base geometry. + // check to see if we will enter. + int ibase = g->howfar(ireg,x,u,t,newmed,normal); + if (ibase >= 0) { + int j = gindex[ibase]; + if (j >= 0 && itype[j]) { + int inscr = geometries[j]->isWhere(x+u*t); + if (inscr >= 0) { + if (newmed) { + *newmed = geometries[j]->medium(inscr); + } + return local_start[j] + inscr; + } + } + } + return ibase; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + EGS_Float tmin; + if (ireg < nbase) { // in one of the regions of the base geom. + tmin = g->hownear(ireg,x); + if (tmin <= 0) { + return tmin; + } + int j = gindex[ireg]; + if (j >= 0) { + EGS_Float ti = geometries[j]->hownear(-1,x); + if (ti < tmin) { + tmin = ti; + } + } + return tmin; + } + int i = ireg-nbase; + int j = reg_to_inscr[i]; + int ilocal = ireg-local_start[j]; + tmin = geometries[j]->hownear(ilocal,x); + if (itype[j]) { + int ibase = reg_to_base[i]; + EGS_Float tbase = g->hownear(ibase,x); + if (tbase < tmin) { + tmin = tbase; + } + } + return tmin; + } + return g->hownear(ireg,x); + }; + + int getMaxStep() const { + int nstep = g->getMaxStep() + n_in; + for (int j=0; jgetMaxStep(); + } + return nstep; + }; + + bool hasBooleanProperty(int ireg, EGS_BPType prop) const { + if (ireg >= 0 && ireg < nreg) { + if (ireg < nbase) { + return g->hasBooleanProperty(ireg,prop); + } + int i = ireg-nbase, j = reg_to_inscr[i]; + return geometries[j]->hasBooleanProperty(ireg-local_start[j],prop); + } + return false; + }; + void setBooleanProperty(EGS_BPType) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int) { + setPropertyError("addBooleanProperty()"); + }; + void setBooleanProperty(EGS_BPType,int,int,int step=1) { + setPropertyError("setBooleanProperty()"); + }; + void addBooleanProperty(int,int,int,int step=1) { + setPropertyError("addBooleanProperty()"); + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + void setRelativeRho(int start, int end, EGS_Float rho); + void setRelativeRho(EGS_Input *); + EGS_Float getRelativeRho(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return 1; + } + if (ireg < nbase) { + return g->getRelativeRho(ireg); + } + int i = ireg-nbase; + int j = reg_to_inscr[i]; + return geometries[j]->getRelativeRho(ireg-local_start[j]); + }; + + virtual void getLabelRegions(const string &str, vector ®s); protected: - EGS_BaseGeometry *g; //!< The envelope geometry - EGS_BaseGeometry **geometries; //!< The inscribed geometries - int *gindex; //!< Index of inscribed geometries - int* reg_to_inscr; //!< Region to inscribed geometry conversion - int* reg_to_base; //!< Region to base region conversion - int* local_start; //!< First region for each inscribed geometry - char *itype; - int n_in; //!< Number of inscribed geometries - int nbase; //!< Number of regions in the base geometry + EGS_BaseGeometry *g; //!< The envelope geometry + EGS_BaseGeometry **geometries; //!< The inscribed geometries + int *gindex; //!< Index of inscribed geometries + int *reg_to_inscr; //!< Region to inscribed geometry conversion + int *reg_to_base; //!< Region to base region conversion + int *local_start; //!< First region for each inscribed geometry + char *itype; + int n_in; //!< Number of inscribed geometries + int nbase; //!< Number of regions in the base geometry - static string type; //!< Geometry type + static string type; //!< Geometry type - /*! \brief Don't set media for an envelope geometry + /*! \brief Don't set media for an envelope geometry - This function is re-implemented to warn the user to not set media - in the envelope geometry. Instead, media should be set for the envelope - and in the inscribed geometries. - */ - void setMedia(EGS_Input *,int,const int *); + This function is re-implemented to warn the user to not set media + in the envelope geometry. Instead, media should be set for the envelope + and in the inscribed geometries. + */ + void setMedia(EGS_Input *,int,const int *); private: - void setPropertyError(const char *funcname) { - egsFatal("EGS_SmartEnvelope::%s: don't use this method\n Define " - "properties in the constituent geometries instead\n", - funcname); - }; + void setPropertyError(const char *funcname) { + egsFatal("EGS_SmartEnvelope::%s: don't use this method\n Define " + "properties in the constituent geometries instead\n", + funcname); + }; }; diff --git a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp index 2d1ed8729..e2f48a2b0 100644 --- a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.cpp @@ -41,12 +41,12 @@ string EGS_Space::type = "EGS_Space"; extern "C" { -EGS_SPACE_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - EGS_Space *g = new EGS_Space(""); - g->setName(input); - g->setMedia(input); - g->setLabels(input); - return g; -} + EGS_SPACE_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + EGS_Space *g = new EGS_Space(""); + g->setName(input); + g->setMedia(input); + g->setLabels(input); + return g; + } } diff --git a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.h b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.h index c3fd5c6ec..d801b1a11 100644 --- a/HEN_HOUSE/egs++/geometry/egs_space/egs_space.h +++ b/HEN_HOUSE/egs++/geometry/egs_space/egs_space.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_SPACE_DLL -#define EGS_SPACE_EXPORT __declspec(dllexport) -#else -#define EGS_SPACE_EXPORT __declspec(dllimport) -#endif -#define EGS_SPACE_LOCAL + #ifdef BUILD_SPACE_DLL + #define EGS_SPACE_EXPORT __declspec(dllexport) + #else + #define EGS_SPACE_EXPORT __declspec(dllimport) + #endif + #define EGS_SPACE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_SPACE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_SPACE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_SPACE_EXPORT -#define EGS_SPACE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_SPACE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_SPACE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_SPACE_EXPORT + #define EGS_SPACE_LOCAL + #endif #endif @@ -88,30 +88,44 @@ class EGS_SPACE_EXPORT EGS_Space : public EGS_BaseGeometry { public: - EGS_Space(const string &Name) : EGS_BaseGeometry(Name) { nreg=1; }; + EGS_Space(const string &Name) : EGS_BaseGeometry(Name) { + nreg=1; + }; - bool isInside(const EGS_Vector &x) { return true; }; + bool isInside(const EGS_Vector &x) { + return true; + }; - int isWhere(const EGS_Vector &x) { return 0; }; + int isWhere(const EGS_Vector &x) { + return 0; + }; - int inside(const EGS_Vector &x) { return 0; }; + int inside(const EGS_Vector &x) { + return 0; + }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { return 1e30; }; + const EGS_Vector &u) { + return 1e30; + }; int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { return ireg; }; - EGS_Float hownear(int ireg, const EGS_Vector &x) { return 1e30; }; + EGS_Float hownear(int ireg, const EGS_Vector &x) { + return 1e30; + }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation( - "=======================================================\n"); + "=======================================================\n"); }; }; diff --git a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp index 10963fb20..91a65189e 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.cpp @@ -46,16 +46,18 @@ string EGS_cSpheres::type = "EGS_cSpheres"; // generate the concentric spheres EGS_cSpheres::EGS_cSpheres(int ns, const EGS_Float *radius, - const EGS_Vector &position, const string &Name) : - EGS_BaseGeometry(Name), xo(position) { + const EGS_Vector &position, const string &Name) : + EGS_BaseGeometry(Name), xo(position) { - if(ns>0) { + if (ns>0) { - R2=new EGS_Float [ns]; R=new EGS_Float [ns]; + R2=new EGS_Float [ns]; + R=new EGS_Float [ns]; // ... and sphere radii - for(int i=0;iR2[nreg-1]) return false; + EGS_Vector tmp(x-xo); + EGS_Float r_sq=tmp.length2(); + if (r_sq>R2[nreg-1]) { + return false; + } return true; } int EGS_cSpheres::isWhere(const EGS_Vector &x) { - EGS_Vector tmp(x-xo); EGS_Float r_sq=tmp.length2(); - if(r_sq>R2[nreg-1]) return -1; - if(r_sqR2[nreg-1]) { + return -1; + } + if (r_sqR2[nreg-1]) return -1; + // are we outside off all spheres? If so return that region number + if (r_sq>R2[nreg-1]) { + return -1; + } -/* - * algorithm below fails for particle in central sphere ...ugh! - */if(r_sq1) { - ms=(is+os)/2; - if(r_sq<=R2[ms]) os=ms; else is=ms; - } - return os; + /* + * algorithm below fails for particle in central sphere ...ugh! + */if (r_sq1) { + ms=(is+os)/2; + if (r_sq<=R2[ms]) { + os=ms; + } + else { + is=ms; + } + } + return os; } // howfar is particle trajectory from sphere boundary @@ -105,186 +124,226 @@ int EGS_cSpheres::inside(const EGS_Vector &x) { */ #ifdef SPHERES_DEBUG -EGS_Vector last_x, last_u; -int last_ireg; -EGS_Float last_d,last_t,last_aa,last_bb2,last_R2b2,last_tmp; + EGS_Vector last_x, last_u; + int last_ireg; + EGS_Float last_d,last_t,last_aa,last_bb2,last_R2b2,last_tmp; #endif EGS_Float EGS_cSpheres::howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } EGS_Vector xp(x - xo); EGS_Float aa = xp*u, aa2 = aa*aa; EGS_Float bb2 = xp.length2(); EGS_Float R2b2 = R2[nreg-1] - bb2; - if( R2b2 <= 0 ) return 0; // outside within precision + if (R2b2 <= 0) { + return 0; // outside within precision + } EGS_Float tmp = sqrt(aa2 + R2b2); return aa > 0 ? R2b2/(tmp + aa) : tmp - aa; } int EGS_cSpheres::howfar(int ireg, const EGS_Vector &x, - const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal) -{ - int direction_flag=-1; /* keep track of direction entering or exiting a + const EGS_Vector &u, EGS_Float &t, int *newmed, EGS_Vector *normal) { + int direction_flag=-1; /* keep track of direction entering or exiting a sphere boundary */ - double d=1e35; // set a maximum distance from a boundary - - EGS_Vector xp(x - xo); - double aa = xp*u, aa2 = aa*aa; - double bb2 = xp.length2(); - - double rad, R2b2, tmp; - - // check if we are inside of any regions at all? ... - if(ireg>=0) { - - /* check if particle is moving towards or away from the sphere(s) centre. - * we loose here if the particle is in the centre sphere as we don't need - * to check this condition. see next 'if' statement - */ - if( aa >= 0 || !ireg ) { - - /* ie. particle moving away from center of - spheres, OR it is IN the innermost sphere - => we must check the outer sphere only - */ - R2b2 = R2[ireg] - bb2; - if( R2b2 <= 0 && aa > 0 ) d = 1e-15; // hopefully a truncation problem - else { - tmp = aa2 + R2b2; - if( tmp > 0 ) tmp = sqrt(tmp); - else { - if( tmp < -1e-2 ) { - egsWarning("EGS_cSpheres::howfar: something is wrong\n"); - egsWarning(" we think we are in region %d, but R2b2=%g", - ireg,R2b2); - } - tmp = 0; - } - d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa; - // the above reduces roundoff, which is significant - // when aa2 is large compared to R2b2 and aa>0 - } - rad = -R[ireg]; - direction_flag=ireg+1; - if( direction_flag >= nreg ) direction_flag = -1; - } - else { - - /* so now we know the particle is moving towards the centre of the - * spheres. check to see if its trajectory will intersect the nested - * sphere - we are guaranteed there is one - we checked that already! - */ - R2b2 = R2[ireg-1] - bb2; - tmp = aa2 + R2b2; - if( tmp <= 0 ) { // we will not intersect the nested sphere - R2b2 = R2[ireg] - bb2; - tmp = aa2 + R2b2; - if( tmp > 0 ) d = sqrt(tmp) - aa; - else d = -aa; - rad = -R[ireg]; - direction_flag=ireg+1; - if( direction_flag >= nreg ) direction_flag = -1; - } - else { - // we're hitting the inner sphere (from the outside) - tmp = sqrt(tmp); - d = -R2b2/(tmp - aa); - direction_flag=ireg-1; - rad = R[direction_flag]; - } - } - } - else { - // we are not inside any of the spherical regions of interest - if(aa<0) { // we _might_ intersect the largest sphere - R2b2 = R2[nreg-1] - bb2; - tmp = aa2 + R2b2; - if( tmp > 0 ) { // we *will* intersect the largest sphere - d = -R2b2/(sqrt(tmp) - aa); - direction_flag=nreg-1; - rad = R[direction_flag]; - } - } - } + double d=1e35; // set a maximum distance from a boundary + + EGS_Vector xp(x - xo); + double aa = xp*u, aa2 = aa*aa; + double bb2 = xp.length2(); + + double rad, R2b2, tmp; + + // check if we are inside of any regions at all? ... + if (ireg>=0) { + + /* check if particle is moving towards or away from the sphere(s) centre. + * we loose here if the particle is in the centre sphere as we don't need + * to check this condition. see next 'if' statement + */ + if (aa >= 0 || !ireg) { + + /* ie. particle moving away from center of + spheres, OR it is IN the innermost sphere + => we must check the outer sphere only + */ + R2b2 = R2[ireg] - bb2; + if (R2b2 <= 0 && aa > 0) { + d = 1e-15; // hopefully a truncation problem + } + else { + tmp = aa2 + R2b2; + if (tmp > 0) { + tmp = sqrt(tmp); + } + else { + if (tmp < -1e-2) { + egsWarning("EGS_cSpheres::howfar: something is wrong\n"); + egsWarning(" we think we are in region %d, but R2b2=%g", + ireg,R2b2); + } + tmp = 0; + } + d = aa > 0 ? R2b2/(tmp + aa) : tmp - aa; + // the above reduces roundoff, which is significant + // when aa2 is large compared to R2b2 and aa>0 + } + rad = -R[ireg]; + direction_flag=ireg+1; + if (direction_flag >= nreg) { + direction_flag = -1; + } + } + else { + + /* so now we know the particle is moving towards the centre of the + * spheres. check to see if its trajectory will intersect the nested + * sphere - we are guaranteed there is one - we checked that already! + */ + R2b2 = R2[ireg-1] - bb2; + tmp = aa2 + R2b2; + if (tmp <= 0) { // we will not intersect the nested sphere + R2b2 = R2[ireg] - bb2; + tmp = aa2 + R2b2; + if (tmp > 0) { + d = sqrt(tmp) - aa; + } + else { + d = -aa; + } + rad = -R[ireg]; + direction_flag=ireg+1; + if (direction_flag >= nreg) { + direction_flag = -1; + } + } + else { + // we're hitting the inner sphere (from the outside) + tmp = sqrt(tmp); + d = -R2b2/(tmp - aa); + direction_flag=ireg-1; + rad = R[direction_flag]; + } + } + } + else { + // we are not inside any of the spherical regions of interest + if (aa<0) { // we _might_ intersect the largest sphere + R2b2 = R2[nreg-1] - bb2; + tmp = aa2 + R2b2; + if (tmp > 0) { // we *will* intersect the largest sphere + d = -R2b2/(sqrt(tmp) - aa); + direction_flag=nreg-1; + rad = R[direction_flag]; + } + } + } #ifdef SPHERES_DEBUG - if( isnan(d) ) { - egsWarning("\nGot nan\n"); - } - - if( d < -1e-4 ) { - egsWarning("\nNegative step?: %g\n",d); - egsWarning("ireg=%d inew=%d aa=%g bb2=%g\n",ireg,direction_flag,aa,bb2); - //exit(1); - } - - last_x = x; last_u = u; last_ireg = ireg; last_d = d; last_t = t; - last_aa = aa; last_bb2 = bb2; last_R2b2 = R2b2; last_tmp = tmp; + if (isnan(d)) { + egsWarning("\nGot nan\n"); + } + + if (d < -1e-4) { + egsWarning("\nNegative step?: %g\n",d); + egsWarning("ireg=%d inew=%d aa=%g bb2=%g\n",ireg,direction_flag,aa,bb2); + //exit(1); + } + + last_x = x; + last_u = u; + last_ireg = ireg; + last_d = d; + last_t = t; + last_aa = aa; + last_bb2 = bb2; + last_R2b2 = R2b2; + last_tmp = tmp; #endif - // check desired step size against this d - if(d<=t) { - t=d; - if( newmed ) if( direction_flag >= 0 ) *newmed = medium(direction_flag); - else *newmed = -1; - if( normal ) { - EGS_Vector n(xp + u*d); *normal = n*(1/rad); - } - return direction_flag; - } - return ireg; + // check desired step size against this d + if (d<=t) { + t=d; + if (newmed) if (direction_flag >= 0) { + *newmed = medium(direction_flag); + } + else { + *newmed = -1; + } + if (normal) { + EGS_Vector n(xp + u*d); + *normal = n*(1/rad); + } + return direction_flag; + } + return ireg; } // hownear - closest perpendicular distance to sphere surface -EGS_Float EGS_cSpheres::hownear(int ireg, const EGS_Vector &x) -{ - EGS_Vector xp(x-xo); - EGS_Float r=xp.length(); - //EGS_Float r_sq=x.x*x.x+x.y*x.y+x.z*x.z; - EGS_Float d; - - if(ireg>=0) { - d=R[ireg]-r; - if(ireg) { EGS_Float dd=r-R[ireg-1]; if(dd=0) { + d=R[ireg]-r; + if (ireg) { + EGS_Float dd=r-R[ireg-1]; + if (dd Xo; - int err = input->getInput("midpoint",Xo); - if( !err && Xo.size() == 3 ) xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); - vector radii; - err = input->getInput("radii",radii); - if( err ) { - egsWarning("createGeometry(spheres): wrong/missing 'radii' input\n"); - return 0; + EGS_SPHERES_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + if (!input) { + egsWarning("createGeometry(spheres): null input?\n"); + return 0; + } + EGS_Vector xo; + vector Xo; + int err = input->getInput("midpoint",Xo); + if (!err && Xo.size() == 3) { + xo = EGS_Vector(Xo[0],Xo[1],Xo[2]); + } + vector radii; + err = input->getInput("radii",radii); + if (err) { + egsWarning("createGeometry(spheres): wrong/missing 'radii' input\n"); + return 0; + } + EGS_Float *r = new EGS_Float [radii.size()]; + for (int j=0; jsetName(input); + result->setMedia(input); + result->setLabels(input); + return result; } - EGS_Float *r = new EGS_Float [radii.size()]; - for(int j=0; jsetName(input); - result->setMedia(input); - result->setLabels(input); - return result; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.h b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.h index ca93fd6d4..8a6cf71e6 100644 --- a/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.h +++ b/HEN_HOUSE/egs++/geometry/egs_spheres/egs_spheres.h @@ -41,22 +41,22 @@ #ifdef WIN32 -#ifdef BUILD_SPHERES_DLL -#define EGS_SPHERES_EXPORT __declspec(dllexport) -#else -#define EGS_SPHERES_EXPORT __declspec(dllimport) -#endif -#define EGS_SPHERES_LOCAL + #ifdef BUILD_SPHERES_DLL + #define EGS_SPHERES_EXPORT __declspec(dllexport) + #else + #define EGS_SPHERES_EXPORT __declspec(dllimport) + #endif + #define EGS_SPHERES_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_SPHERES_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_SPHERES_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_SPHERES_EXPORT -#define EGS_SPHERES_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_SPHERES_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_SPHERES_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_SPHERES_EXPORT + #define EGS_SPHERES_LOCAL + #endif #endif @@ -92,12 +92,13 @@ class EGS_SPHERES_EXPORT EGS_cSpheres : public EGS_BaseGeometry { // construct some CONCENTRIC spheres EGS_cSpheres(int ns, const EGS_Float *radius, const EGS_Vector &position, - const string &Name = ""); + const string &Name = ""); // destruct spheres from memory ~EGS_cSpheres() { - if(nreg) { - delete [] R2; delete [] R; + if (nreg) { + delete [] R2; + delete [] R; } } @@ -108,17 +109,21 @@ class EGS_SPHERES_EXPORT EGS_cSpheres : public EGS_BaseGeometry { int isWhere(const EGS_Vector &x); EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u); + const EGS_Vector &u); // howfar is particle trajectory from sphere boundry int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0); + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0); // hownear - closest perpendicular distance to sphere surface EGS_Float hownear(int ireg, const EGS_Vector &x); - int getMaxStep() const { return 2*nreg; }; + int getMaxStep() const { + return 2*nreg; + }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; void printInfo() const; diff --git a/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp index d81fcd292..bc1653084 100644 --- a/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_union/egs_union_geometry.cpp @@ -43,8 +43,8 @@ using namespace std; string EGS_UNIONG_LOCAL EGS_UnionGeometry::type = "EGS_UnionGeometry"; void EGS_UnionGeometry::setMedia(EGS_Input *,int,const int *) { - egsWarning("EGS_UnionGeometry::setMedia: don't use this method. Use the\n" - " setMedia() methods of the geometry objects that make up this geometry\n"); + egsWarning("EGS_UnionGeometry::setMedia: don't use this method. Use the\n" + " setMedia() methods of the geometry objects that make up this geometry\n"); } void EGS_UnionGeometry::setRelativeRho(int start, int end, EGS_Float rho) { @@ -53,61 +53,79 @@ void EGS_UnionGeometry::setRelativeRho(int start, int end, EGS_Float rho) { void EGS_UnionGeometry::setRelativeRho(EGS_Input *) { egsWarning("EGS_UnionGeometry::setRelativeRho(): don't use this method. " - "Use the\n setRelativeRho() methods of the geometry objects that make " - "up this geometry\n"); + "Use the\n setRelativeRho() methods of the geometry objects that make " + "up this geometry\n"); } EGS_UnionGeometry::EGS_UnionGeometry(const vector &geoms, - const int *priorities, const string &Name) : - EGS_BaseGeometry(Name) { + const int *priorities, const string &Name) : + EGS_BaseGeometry(Name) { ng = geoms.size(); - if( ng <= 0 ) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: attempt " - " to construct a union geometry from zero geometries\n"); + if (ng <= 0) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: attempt " + " to construct a union geometry from zero geometries\n"); is_convex = false; - if( ng == 1 ) egsWarning("EGS_UnionGeometry::EGS_UnionGeometry: why " - "do you want to make a union out of a single geometry?\n"); - g = new EGS_BaseGeometry* [ng]; nmax = 0; int j; + if (ng == 1) egsWarning("EGS_UnionGeometry::EGS_UnionGeometry: why " + "do you want to make a union out of a single geometry?\n"); + g = new EGS_BaseGeometry* [ng]; + nmax = 0; + int j; int *order = new int [ng]; - if( priorities ) { + if (priorities) { // user has definied priorities // order them using a very simplistic algorithm bool *is_used = new bool [ng]; - for(j=0; j pmax ) { - imax = i; pmax = priorities[i]; + for (int i=0; i pmax) { + imax = i; + pmax = priorities[i]; } } - order[j] = imax; is_used[imax] = true; + order[j] = imax; + is_used[imax] = true; } delete [] is_used; } else { // user has not definied priorities - for(j=0; jref(); int n = g[i]->regions(); if( n > nmax ) nmax = n; - if( !has_rho_scaling ) has_rho_scaling = g[i]->hasRhoScaling(); + g[i]->ref(); + int n = g[i]->regions(); + if (n > nmax) { + nmax = n; + } + if (!has_rho_scaling) { + has_rho_scaling = g[i]->hasRhoScaling(); + } } delete [] order; - if( !nmax ) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: all geometries" - " have zero regions?\n"); + if (!nmax) egsFatal("EGS_UnionGeometry::EGS_UnionGeometry: all geometries" + " have zero regions?\n"); nreg = nmax*ng; } EGS_UnionGeometry::~EGS_UnionGeometry() { - for(int j=0; jderef() ) delete g[j]; + for (int j=0; jderef()) { + delete g[j]; + } } delete [] g; } @@ -115,78 +133,87 @@ EGS_UnionGeometry::~EGS_UnionGeometry() { void EGS_UnionGeometry::printInfo() const { EGS_BaseGeometry::printInfo(); egsInformation(" geometries:\n"); - for(int j=0; jgetName().c_str(),g[j]->getType().c_str()); + for (int j=0; jgetName().c_str(),g[j]->getType().c_str()); egsInformation( - "=======================================================\n"); + "=======================================================\n"); } extern "C" { -EGS_UNIONG_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - if( !input ) { - egsWarning("createGeometry(union): null input?\n"); - return 0; - } - vector geoms; vector gnames; - int err = input->getInput("geometries",gnames); - if( err || gnames.size() < 1 ) { - egsWarning("createGeometry(union): missing/wrong 'geometries' input\n"); - return 0; - } - for(unsigned int j=0; j pri; - err = input->getInput("priorities",pri); - int *p = 0; - if( !err ) { - if( pri.size() == geoms.size() ) { - p = new int [pri.size()]; - for(int i=0; i geoms; + vector gnames; + int err = input->getInput("geometries",gnames); + if (err || gnames.size() < 1) { + egsWarning("createGeometry(union): missing/wrong 'geometries' input\n"); + return 0; + } + for (unsigned int j=0; j ignoring\n", - pri.size(),geoms.size()); + if (geoms.size() < 1) { + egsWarning("createGeometry(union): must have at least one geometry\n"); + return 0; + } + vector pri; + err = input->getInput("priorities",pri); + int *p = 0; + if (!err) { + if (pri.size() == geoms.size()) { + p = new int [pri.size()]; + for (int i=0; i ignoring\n", + pri.size(),geoms.size()); + } + EGS_BaseGeometry *result = new EGS_UnionGeometry(geoms,p); + result->setName(input); + result->setLabels(input); + if (p) { + delete [] p; + } + return result; } - EGS_BaseGeometry *result = new EGS_UnionGeometry(geoms,p); - result->setName(input); - result->setLabels(input); - if( p ) delete [] p; - return result; -} -void EGS_UnionGeometry::getLabelRegions (const string &str, vector ®s) { + void EGS_UnionGeometry::getLabelRegions(const string &str, vector ®s) { - // label defined in the sub-geometries - vector gregs; - int shift=0; - for (int i=0; i gregs; + int shift=0; + for (int i=0; igetLabelRegions(str, gregs); + // add regions from set geometries + gregs.clear(); + if (g[i]) { + g[i]->getLabelRegions(str, gregs); + } - // shift region numbers according to indexing style - for (int j=0; j &geoms, - const int *priorities = 0, const string &Name = ""); - - ~EGS_UnionGeometry(); - - bool isRealRegion(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return false; - int j = ireg/nmax; return g[j]->isRealRegion(ireg-j*nmax); - }; - - bool isInside(const EGS_Vector &x) { - for(int j=0; jisInside(x) ) return true; - return false; - }; - - int isWhere(const EGS_Vector &x) { - for(int j=0; jisWhere(x); - if( ij >= 0 ) return ij + j*nmax; - } - return -1; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int medium(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return -1; - int j = ireg/nmax; - return g[j]->medium(ireg-j*nmax); - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t,int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - // we are inside, set current geometry - int jg = ireg/nmax; - // distance to boundary and new region in this geometry. - int inew = g[jg]->howfar(ireg-jg*nmax,x,u,t,newmed,normal); - // jgnew is the geometry after the step - int jgnew = inew >= 0 ? jg : -1; - // geometries are now ordered in decreasing priorities. - // Then, - // - if the particle remains in the current geometry, - // we only need to check geometries up to jg-1 - // For these geometries the particle must be outside, - // otherwise it would have been in one of them - // - if the particle exits the current geometry, then - // we must also check jg+1...ng-1 - for(int j=0; jhowfar(-1,x,u,t,newmed,normal); - if( ii >= 0 ) { - jgnew = j; inew = ii; - } - } - if( inew < 0 ) { - // the particle didn't enter any of the higher priority - // geometries but exits the current one. - // => we need to check if the particle is in one - // of the lower priority geometries at the exit point. - EGS_Vector xnew(x+u*t); - for(int j=jg+1; jisWhere(xnew); - if( ii >= 0 ) { - // when exiting jg, particle is in region ii of geometry j - // we don't need to check other geometries because they - // have a lower priority. - jgnew = j; inew = ii; break; - } - } - } - if( inew < 0 ) return inew; - if( newmed ) *newmed = g[jgnew]->medium(inew); - return inew + jgnew*nmax; - } - // if here, we are currently outside of all geometries in the union. - int jg, inew=-1; - for(int j=0; jhowfar(-1,x,u,t,newmed,normal); - if( ii >= 0 ) { jg = j; inew = ii;} - } - return inew < 0 ? -1 : inew + jg*nmax; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - int jg = ireg/nmax; - EGS_Float tmin = g[jg]->hownear(ireg-jg*nmax,x); - if( tmin <= 0 ) return 0; - // tmin is now the perpendicular distance to a boundary - // in the current geometry. - // we need to check all geometries with higher priorities - // i.e., all geometries between 0 and jg-1. - // as their priorities are higher, we know that we are - // outside of such geometries. - for(int j=jg-1; j>=0; --j) { - EGS_Float t = g[j]->hownear(-1,x); - if( t < tmin ) { - tmin = t; if( tmin <= 0 ) return 0; - } - } - return tmin; - } - // if here, we are outside of all geomtries in the union. - EGS_Float tmin = 1e30; - for(int j=ng-1; j>=0; j--) { - EGS_Float t = g[j]->hownear(-1,x); - if( t < tmin ) tmin = t; - if( tmin <= 0 ) return 0; - } - return tmin; - }; - - int getMaxStep() const { - int nstep = 1; - for(int j=0; jgetMaxStep(); - return nstep; - }; - - const string &getType() const { return type; }; - - void printInfo() const; - - EGS_Float getRelativeRho(int ireg) const { - if( ireg < 0 || ireg >= nreg ) return 1; - int jg = ireg/nmax; - return g[jg]->getRelativeRho(ireg-jg*nmax); - }; - void setRelativeRho(int start, int end, EGS_Float rho); - void setRelativeRho(EGS_Input *); - - virtual void getLabelRegions (const string &str, vector ®s); + /*! \brief Construct a geometry union from the vector of geometries + \a geom. + */ + EGS_UnionGeometry(const vector &geoms, + const int *priorities = 0, const string &Name = ""); + + ~EGS_UnionGeometry(); + + bool isRealRegion(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return false; + } + int j = ireg/nmax; + return g[j]->isRealRegion(ireg-j*nmax); + }; + + bool isInside(const EGS_Vector &x) { + for (int j=0; jisInside(x)) { + return true; + } + return false; + }; + + int isWhere(const EGS_Vector &x) { + for (int j=0; jisWhere(x); + if (ij >= 0) { + return ij + j*nmax; + } + } + return -1; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int medium(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return -1; + } + int j = ireg/nmax; + return g[j]->medium(ireg-j*nmax); + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t,int *newmed=0, EGS_Vector *normal=0) { + if (ireg >= 0) { + // we are inside, set current geometry + int jg = ireg/nmax; + // distance to boundary and new region in this geometry. + int inew = g[jg]->howfar(ireg-jg*nmax,x,u,t,newmed,normal); + // jgnew is the geometry after the step + int jgnew = inew >= 0 ? jg : -1; + // geometries are now ordered in decreasing priorities. + // Then, + // - if the particle remains in the current geometry, + // we only need to check geometries up to jg-1 + // For these geometries the particle must be outside, + // otherwise it would have been in one of them + // - if the particle exits the current geometry, then + // we must also check jg+1...ng-1 + for (int j=0; jhowfar(-1,x,u,t,newmed,normal); + if (ii >= 0) { + jgnew = j; + inew = ii; + } + } + if (inew < 0) { + // the particle didn't enter any of the higher priority + // geometries but exits the current one. + // => we need to check if the particle is in one + // of the lower priority geometries at the exit point. + EGS_Vector xnew(x+u*t); + for (int j=jg+1; jisWhere(xnew); + if (ii >= 0) { + // when exiting jg, particle is in region ii of geometry j + // we don't need to check other geometries because they + // have a lower priority. + jgnew = j; + inew = ii; + break; + } + } + } + if (inew < 0) { + return inew; + } + if (newmed) { + *newmed = g[jgnew]->medium(inew); + } + return inew + jgnew*nmax; + } + // if here, we are currently outside of all geometries in the union. + int jg, inew=-1; + for (int j=0; jhowfar(-1,x,u,t,newmed,normal); + if (ii >= 0) { + jg = j; + inew = ii; + } + } + return inew < 0 ? -1 : inew + jg*nmax; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + int jg = ireg/nmax; + EGS_Float tmin = g[jg]->hownear(ireg-jg*nmax,x); + if (tmin <= 0) { + return 0; + } + // tmin is now the perpendicular distance to a boundary + // in the current geometry. + // we need to check all geometries with higher priorities + // i.e., all geometries between 0 and jg-1. + // as their priorities are higher, we know that we are + // outside of such geometries. + for (int j=jg-1; j>=0; --j) { + EGS_Float t = g[j]->hownear(-1,x); + if (t < tmin) { + tmin = t; + if (tmin <= 0) { + return 0; + } + } + } + return tmin; + } + // if here, we are outside of all geomtries in the union. + EGS_Float tmin = 1e30; + for (int j=ng-1; j>=0; j--) { + EGS_Float t = g[j]->hownear(-1,x); + if (t < tmin) { + tmin = t; + } + if (tmin <= 0) { + return 0; + } + } + return tmin; + }; + + int getMaxStep() const { + int nstep = 1; + for (int j=0; jgetMaxStep(); + } + return nstep; + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + EGS_Float getRelativeRho(int ireg) const { + if (ireg < 0 || ireg >= nreg) { + return 1; + } + int jg = ireg/nmax; + return g[jg]->getRelativeRho(ireg-jg*nmax); + }; + void setRelativeRho(int start, int end, EGS_Float rho); + void setRelativeRho(EGS_Input *); + + virtual void getLabelRegions(const string &str, vector ®s); protected: - EGS_BaseGeometry **g; //!< the geometries that form the union. - int ng; //!< number of geometries. - int nmax; //!< max. number of regions in all of the geoms. - static string type; //!< the geometry type + EGS_BaseGeometry **g; //!< the geometries that form the union. + int ng; //!< number of geometries. + int nmax; //!< max. number of regions in all of the geoms. + static string type; //!< the geometry type - /*! \brief Don't set media when defining the union. + /*! \brief Don't set media when defining the union. - This function is re-implemented to warn the user that media should be - defined for each individual geometry participating in the union, not - in the union itself. - */ - void setMedia(EGS_Input *,int,const int *); + This function is re-implemented to warn the user that media should be + defined for each individual geometry participating in the union, not + in the union itself. + */ + void setMedia(EGS_Input *,int,const int *); }; diff --git a/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.cpp b/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.cpp index 81f9fc14d..742242cb4 100644 --- a/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.cpp +++ b/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.cpp @@ -55,73 +55,104 @@ #include #include #ifndef NO_SSTREAM -#include -#define S_STREAM std::istringstream + #include + #define S_STREAM std::istringstream #else -#include -#define S_STREAM std::istrstream + #include + #define S_STREAM std::istrstream #endif using namespace std; #ifndef SKIP_DOXYGEN -EGS_VoxelInfo* EGS_VoxelGeometry::v = 0; +EGS_VoxelInfo *EGS_VoxelGeometry::v = 0; int EGS_VoxelGeometry::nv = 0; VHP_OrganData::VHP_OrganData(const char *fname, int slice_min, int slice_max) : nslice(0), ok(false) { ifstream data(fname,ios::binary); - if( !data ) { + if (!data) { egsWarning("VHP_OrganData: failed to open file %s for reading\n", - fname); return; + fname); + return; } - char endian; data.read(&endian,sizeof(endian)); + char endian; + data.read(&endian,sizeof(endian)); char my_endian = egsGetEndian(); - if( endian != my_endian ) { + if (endian != my_endian) { egsWarning("VHP_OrganData: wrong endianess. \n" - "This machine has endianess %d, data was written on %d\n" - "This requires byte swaping, which has not been implemented yet\n", - (int)my_endian,(int)endian); return; + "This machine has endianess %d, data was written on %d\n" + "This requires byte swaping, which has not been implemented yet\n", + (int)my_endian,(int)endian); + return; } data.read((char *)&dx, sizeof(dx)); data.read((char *)&dy, sizeof(dy)); data.read((char *)&dz, sizeof(dz)); - data.read((char*)&nslice,sizeof(nslice)); - if( slice_min < 0 ) slice_min = 0; - if( slice_max > nslice ) slice_max = nslice; + data.read((char *)&nslice,sizeof(nslice)); + if (slice_min < 0) { + slice_min = 0; + } + if (slice_max > nslice) { + slice_max = nslice; + } int nwant = slice_max - slice_min; slices = new VHP_SliceInfo [nwant]; - nx = 0, ny = 0; int is = 0; - for(int islice=0; islice= slice_min ) { + nx = 0, ny = 0; + int is = 0; + for (int islice=0; islice= slice_min) { slices[is].readData(data); - int ni, nj; slices[is++].getSliceDimensions(ni,nj); - if( ni > nx ) nx = ni; - if( nj > ny ) ny = nj; + int ni, nj; + slices[is++].getSliceDimensions(ni,nj); + if (ni > nx) { + nx = ni; + } + if (nj > ny) { + ny = nj; + } } else { - VHP_SliceInfo tmp; tmp.readData(data); + VHP_SliceInfo tmp; + tmp.readData(data); + } + if (islice == slice_max - 1) { + break; } - if( islice == slice_max - 1 ) break; } - nxy = nx*ny; nslice = slice_max - slice_min; - if( data.fail() ) + nxy = nx*ny; + nslice = slice_max - slice_min; + if (data.fail()) { egsWarning("VHP_OrganData: I/O error while reading data\n"); - else ok = true; + } + else { + ok = true; + } } -VHP_OrganData::~VHP_OrganData() { if( nslice ) delete [] slices; } +VHP_OrganData::~VHP_OrganData() { + if (nslice) { + delete [] slices; + } +} void VHP_RowInfo::readData(istream &in) { unsigned short n; in.read((char *)&n,sizeof(n)); - if( n != nbin ) { - if( nbin > 0 ) { delete [] pix; delete [] org; nbin = 0; } + if (n != nbin) { + if (nbin > 0) { + delete [] pix; + delete [] org; + nbin = 0; + } + } + if (n < 1) { + return; } - if( n < 1 ) return; - if( !nbin ) { - nbin = n; pix = new unsigned short [nbin+1]; + if (!nbin) { + nbin = n; + pix = new unsigned short [nbin+1]; org = new unsigned char [nbin]; } in.read((char *)pix,(nbin+1)*sizeof(unsigned short)); @@ -129,193 +160,247 @@ void VHP_RowInfo::readData(istream &in) { } void VHP_SliceInfo::readData(istream &in) { - if( rinfo ) { delete [] rinfo; rinfo = 0; } + if (rinfo) { + delete [] rinfo; + rinfo = 0; + } in.read((char *)&firstr,sizeof(firstr)); in.read((char *)&lastr,sizeof(lastr)); int nrow = lastr-firstr+1; - if( nrow > 0 ) { + if (nrow > 0) { rinfo = new VHP_RowInfo [nrow]; - for(int j=0; jisOK() ) { + if (!organs->isOK()) { egsWarning("EGS_VHPGeometry: failed to construct organ data\n"); - delete organs; organs = 0; return; + delete organs; + organs = 0; + return; } ifstream med_data(media_file); - if( !med_data ) { + if (!med_data) { egsWarning("EGS_VHPGeometry: failed to open media data file %s\n", - media_file); - delete organs; organs = 0; return; + media_file); + delete organs; + organs = 0; + return; } - int norg; med_data >> norg; - if( norg < 1 ) { + int norg; + med_data >> norg; + if (norg < 1) { egsWarning("EGS_VHPGeometry: %d organs in media data file %s?\n", - norg,media_file); - delete organs; organs = 0; return; + norg,media_file); + delete organs; + organs = 0; + return; } int j; - for(j=0; j<256; ++j) { - organ_media[j] = -1; organ_names[j] = "Undefined"; + for (j=0; j<256; ++j) { + organ_media[j] = -1; + organ_names[j] = "Undefined"; organ_micro[j] = -1; } - char buf[1024]; med_data.getline(buf,1023); - for(j=0; j> iorg >> imed >> c; + char buf[1024]; + med_data.getline(buf,1023); + for (j=0; j> iorg >> imed >> c; med_data.getline(buf,1023); - if( iorg < 0 || iorg > 255 ) + if (iorg < 0 || iorg > 255) egsWarning("EGS_VHPGeometry: bad organ number %d on line %d\n", - iorg,j+2); - else organ_media[iorg] = imed; - organ_names[iorg] = c; organ_names[iorg] += buf; + iorg,j+2); + else { + organ_media[iorg] = imed; + } + organ_names[iorg] = c; + organ_names[iorg] += buf; } - int nmed; med_data >> nmed; med_data.getline(buf,1023); + int nmed; + med_data >> nmed; + med_data.getline(buf,1023); vector media_names; vector media_indeces; - for(j=0; j= 0 ) { - if( organ_media[j] >= nmed ) { + for (j=0; j<256; ++j) { + if (organ_media[j] >= 0) { + if (organ_media[j] >= nmed) { egsWarning("EGS_VHPGeometry: invalid medium index %d\n", - organ_media[j]); + organ_media[j]); + } + else { + organ_media[j] = media_indeces[organ_media[j]]; } - else organ_media[j] = media_indeces[organ_media[j]]; } } - EGS_Float dx, dy, dz; int nx, ny, nz; - organs->getVoxelSizes(dx,dy,dz); organs->getPhantomDimensions(nx,ny,nz); + EGS_Float dx, dy, dz; + int nx, ny, nz; + organs->getVoxelSizes(dx,dy,dz); + organs->getPhantomDimensions(nx,ny,nz); vg = new EGS_VoxelGeometry(nx,ny,nz,dx,dy,dz); - nreg = nx*ny*nz; nmacro = nreg; + nreg = nx*ny*nz; + nmacro = nreg; egsInformation("Phantom size in voxels: x=%d y=%d z=%d\n",nx,ny,nz); egsInformation("Voxel sizes: dx=%g dy=%g dz=%g\n",dx,dy,dz); } void EGS_VHPGeometry::setMicros(EGS_Input *input) { - if( !vg || !organs ) { + if (!vg || !organs) { egsWarning("EGS_VHPGeometry::setMicros: called for an invalid " - "VHP geometry\n"); return; + "VHP geometry\n"); + return; } - if( !input->getInputItem("micro matrix") ) { + if (!input->getInputItem("micro matrix")) { egsWarning("EGS_VHPGeometry::setMicros: no micro matrix definitions\n"); return; } vector mv; - string dir; input->getInput("micro matrix folder",dir); - EGS_Float t_bsc; bool ok = true; + string dir; + input->getInput("micro matrix folder",dir); + EGS_Float t_bsc; + bool ok = true; const static char *err_msg = "EGS_VHPGeometry::setMicros: wrong/missing '%s' input\n"; int err = input->getInput("BSC thickness",t_bsc); - if( err || t_bsc < 0 ) { - egsWarning(err_msg,"BSC thickness"); ok = false; + if (err || t_bsc < 0) { + egsWarning(err_msg,"BSC thickness"); + ok = false; } string tb_medium, bm_medium; err = input->getInput("TB medium",tb_medium); - if( err ) { - egsWarning(err_msg,"TB medium"); ok = false; + if (err) { + egsWarning(err_msg,"TB medium"); + ok = false; } err = input->getInput("BM medium",bm_medium); - if( err ) { - egsWarning(err_msg,"BM medium"); ok = false; + if (err) { + egsWarning(err_msg,"BM medium"); + ok = false; } - if( !ok ) { + if (!ok) { egsWarning("EGS_VHPGeometry::setMicros: wrong/missing inputs found\n" - " => no micro matrices set for use\n"); + " => no micro matrices set for use\n"); return; } int tb_med = addMedium(tb_medium), bm_med = addMedium(bm_medium); vector minput; - while( !input->getInput("micro matrix",minput) ) { + while (!input->getInput("micro matrix",minput)) { delete input->takeInputItem("micro matrix"); - if( minput.size() < 2 ) { + if (minput.size() < 2) { egsWarning("EGS_VHPGeometry::setMicros: 'micro matrix' input" - " requires at least two inputs => ignored\n"); + " requires at least two inputs => ignored\n"); continue; } string fname = dir.size() ? egsJoinPath(dir,minput[0]) : minput[0]; EGS_MicroMatrixCluster *mcluster = new EGS_MicroMatrixCluster( - vg->dx,vg->dy,vg->dz,t_bsc,tb_med,bm_med,fname.c_str()); - if( !mcluster->isValid() ) { + vg->dx,vg->dy,vg->dz,t_bsc,tb_med,bm_med,fname.c_str()); + if (!mcluster->isValid()) { egsWarning("failed to construct micro cluster from %s\n", - fname.c_str()); delete mcluster; + fname.c_str()); + delete mcluster; } else { - bool ok = true; vector orgs; - for(int i=1; i> org; - if( s.fail() ) { + bool ok = true; + vector orgs; + for (int i=1; i> org; + if (s.fail()) { egsWarning("EGS_VHPGeometry::setMicros: invalid input %s " - "for micro matrix %s\n",minput[i].c_str(), - minput[0].c_str()); ok = false; + "for micro matrix %s\n",minput[i].c_str(), + minput[0].c_str()); + ok = false; } else { - if( org < 0 || org > 255 ) { + if (org < 0 || org > 255) { egsWarning("EGS_VHPGeometry::setMicros: invalid input" - " %d for micro matrix %s\n",org,minput[0].c_str()); + " %d for micro matrix %s\n",org,minput[0].c_str()); ok = false; } - else orgs.push_back(org); + else { + orgs.push_back(org); + } } } - if( ok ) { + if (ok) { mv.push_back(mcluster); egsInformation("Using micro matrix data from\n %s\nfor" - " organs:",fname.c_str()); - for(int i=0; i 0 ) { - if( nmicro > 0 ) { - for(int i=0; i 0) { + if (nmicro > 0) { + for (int i=0; inxy*micros[i]->nz; int nm = micros[i]->mxy*micros[i]->mz; - if( nm*nr > nmax ) nmax = nm*nr; + if (nm*nr > nmax) { + nmax = nm*nr; + } } nmacro = vg->nxy*vg->nz; - EGS_I64 ntot = nmax; ntot *= nmicro; ntot += nmacro; - if( ntot > 2147483647 ) egsFatal("EGS_VHPGeometry::setMicros: " - "too many micro regions\n"); + EGS_I64 ntot = nmax; + ntot *= nmicro; + ntot += nmacro; + if (ntot > 2147483647) egsFatal("EGS_VHPGeometry::setMicros: " + "too many micro regions\n"); nreg = nmacro + nmax*nmicro; egsInformation("Using regions 0...%d to identify macro voxels\n", - nmacro-1); + nmacro-1); egsInformation("Using regions %d...%d to identify micro voxels\n", - nmacro,nreg-1); + nmacro,nreg-1); } } EGS_VHPGeometry::~EGS_VHPGeometry() { - if( organs ) delete organs; - if( vg ) delete vg; - if( nmicro > 0 ) { - for(int j=0; j 0) { + for (int j=0; jdx,vg->dy,vg->dz); egsInformation(" phantom size: %d %d %d\n",vg->nx,vg->ny,vg->nz); } - else egsInformation(" undefined VHP geometry\n"); + else { + egsInformation(" undefined VHP geometry\n"); + } } string EGS_VHPGeometry::type = "EGS_VHPGeometry"; @@ -342,16 +429,17 @@ VHPBox EGS_MicroMatrixCluster::bm_boxes[64]; bool EGS_MicroMatrixCluster::bm_boxes_initialized = false; EGS_MicroMatrixCluster::EGS_MicroMatrixCluster( - EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_thickness, - int tb_med, int bm_med, const char *micro_file) : micros(0), vg(0), - med_tb(tb_med), med_bm(bm_med) { + EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_thickness, + int tb_med, int bm_med, const char *micro_file) : micros(0), vg(0), + med_tb(tb_med), med_bm(bm_med) { // // *** open micro-matrix file // ifstream in(micro_file,ios::binary); - if( !in ) { + if (!in) { egsWarning("EGS_MicroMatrixCluster: failed to open file %s\n", - micro_file); return; + micro_file); + return; } // @@ -361,29 +449,47 @@ EGS_MicroMatrixCluster::EGS_MicroMatrixCluster( in.read((char *)&Mx,sizeof(Mx)); in.read((char *)&My,sizeof(My)); in.read((char *)&Mz,sizeof(Mz)); - mx = Mx; my = My; mz = Mz; - mxy = mx*my; nmic = mxy*mz; - micros = new unsigned char* [nmic]; + mx = Mx; + my = My; + mz = Mz; + mxy = mx*my; + nmic = mxy*mz; + micros = new unsigned char *[nmic]; in.read((char *)&Mx,sizeof(Mx)); in.read((char *)&My,sizeof(My)); in.read((char *)&Mz,sizeof(Mz)); - nx = Mx; ny = My; nz = Mz; nxy = nx*ny; int nxyz = nxy*nz, j; nreg = nxyz; - {for(int j=0; j= mx ) ixp = 0; - int iym = iy-1; if( iym < 0 ) iym = my-1; - int iyp = iy+1; if( iyp >= my ) iyp = 0; - int izm = iz-1; if( izm < 0 ) izm = mz-1; - int izp = iz+1; if( izp >= mz ) izp = 0; + for (j=0; j= mx) { + ixp = 0; + } + int iym = iy-1; + if (iym < 0) { + iym = my-1; + } + int iyp = iy+1; + if (iyp >= my) { + iyp = 0; + } + int izm = iz-1; + if (izm < 0) { + izm = mz-1; + } + int izp = iz+1; + if (izp >= mz) { + izp = 0; + } EGS_Float bsc_vol = 0, bm_vol = 0, tb_vol = 0; - for(int jx=0; jx 0 ? micros[j][ireg-1] : - micros[ixm+iy*mx+iz*mxy][nx-1+jy*nx+jz*nxy]); + micros[ixm+iy*mx+iz*mxy][nx-1+jy*nx+jz*nxy]); int micxp = !(jx < nx-1 ? micros[j][ireg+1] : - micros[ixp+iy*mx+iz*mxy][jy*nx+jz*nxy]); + micros[ixp+iy*mx+iz*mxy][jy*nx+jz*nxy]); int micym = !(jy > 0 ? micros[j][ireg-nx] : - micros[ix+iym*mx+iz*mxy][jx+(ny-1)*nx+jz*nxy]); + micros[ix+iym*mx+iz*mxy][jx+(ny-1)*nx+jz*nxy]); int micyp = !(jy < ny-1 ? micros[j][ireg+nx] : - micros[ix+iyp*mx+iz*mxy][jx+jz*nxy]); + micros[ix+iyp*mx+iz*mxy][jx+jz*nxy]); int miczm = !(jz > 0 ? micros[j][ireg-nxy] : - micros[ix+iy*mx+izm*mxy][jx+jy*nx+(nz-1)*nxy]); + micros[ix+iy*mx+izm*mxy][jx+jy*nx+(nz-1)*nxy]); int miczp = !(jz < nz-1 ? micros[j][ireg+nxy] : - micros[ix+iy*mx+izp*mxy][jx+jy*nx]); - if( (micxm && micxp && 2*bsc_thickness>ddx) || - (micym && micyp && 2*bsc_thickness>ddy) || - (miczm && miczp && 2*bsc_thickness>ddz) ) { + micros[ix+iy*mx+izp*mxy][jx+jy*nx]); + if ((micxm && micxp && 2*bsc_thickness>ddx) || + (micym && micyp && 2*bsc_thickness>ddy) || + (miczm && miczp && 2*bsc_thickness>ddz)) { micros[j][ireg] = 1; // i.e. all BSC bsc_vol += 1; } @@ -477,18 +603,23 @@ EGS_MicroMatrixCluster::EGS_MicroMatrixCluster( int ibox=micxm+2*micxp+4*micym+8*micyp+ 16*miczm+32*miczp; micros[j][ireg] = ibox + 2; - if( !ibox ) bm_vol += 1; + if (!ibox) { + bm_vol += 1; + } else { double v = (bm_boxes[ibox].xmax-bm_boxes[ibox].xmin)* (bm_boxes[ibox].ymax-bm_boxes[ibox].ymin)* (bm_boxes[ibox].zmax-bm_boxes[ibox].zmin); v /= (ddx*ddy*ddz); - bm_vol += v; bsc_vol += 1 - v; + bm_vol += v; + bsc_vol += 1 - v; } } } - else tb_vol += 1; + else { + tb_vol += 1; + } } } } @@ -500,7 +631,9 @@ EGS_MicroMatrixCluster::EGS_MicroMatrixCluster( v_tb[j] = tb_vol*ddx*ddy*ddz; v_bm[j] = bm_vol*ddx*ddy*ddz; v_bsc[j] = bsc_vol*ddx*ddy*ddz; - tot_tb += tb_vol; tot_bm += bm_vol; tot_bsc += bsc_vol; + tot_tb += tb_vol; + tot_bm += bm_vol; + tot_bsc += bsc_vol; } egsInformation("Average volume fractions:\n"); egsInformation(" TB volume fraction: %g\n",tot_tb/(nmic*nxyz)); @@ -513,8 +646,8 @@ EGS_MicroMatrixCluster::~EGS_MicroMatrixCluster() { #endif EGS_TestMicro::EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, - EGS_Float bsc_t,int tb_med, int bm_med,const char *micro_file, - const string &Name) : EGS_BaseGeometry(Name) { + EGS_Float bsc_t,int tb_med, int bm_med,const char *micro_file, + const string &Name) : EGS_BaseGeometry(Name) { micro = new EGS_MicroMatrixCluster(Dx,Dy,Dz,bsc_t,tb_med,bm_med,micro_file); vg = new EGS_VoxelGeometry(micro->mx,micro->my,micro->mz,Dx,Dy,Dz); nr = micro->nx*micro->ny*micro->nz; @@ -523,8 +656,8 @@ EGS_TestMicro::EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, void EGS_TestMicro::setMedia(EGS_Input *, int , const int *) { egsFatal("EGS_TestMicro::setMedia(EGS_Input*,int,const int *):\n" - " Don't use this method. Media are only set via the micro matrix" - " data\n"); + " Don't use this method. Media are only set via the micro matrix" + " data\n"); } EGS_TestMicro::~EGS_TestMicro() { @@ -533,66 +666,84 @@ EGS_TestMicro::~EGS_TestMicro() { string EGS_TestMicro::type = "EGS_TestMicro"; const static EGS_VHP_LOCAL char *vhp_error_msg1 = - "createGeometry(VHP): wrong/missing %s input for micro_test geometry\n"; + "createGeometry(VHP): wrong/missing %s input for micro_test geometry\n"; extern "C" { -EGS_VHP_EXPORT EGS_BaseGeometry* createGeometry(EGS_Input *input) { - string type; - int err = input->getInput("type",type); - if( !err && type == "micro_test" ) { - bool ok = true; - vector vs; - err = input->getInput("voxel sizes",vs); - if( err || vs.size() != 3 ) { - egsWarning(vhp_error_msg1,"'voxel sizes'"); ok = false; + EGS_VHP_EXPORT EGS_BaseGeometry *createGeometry(EGS_Input *input) { + string type; + int err = input->getInput("type",type); + if (!err && type == "micro_test") { + bool ok = true; + vector vs; + err = input->getInput("voxel sizes",vs); + if (err || vs.size() != 3) { + egsWarning(vhp_error_msg1,"'voxel sizes'"); + ok = false; + } + EGS_Float bsc_t; + err = input->getInput("BSC thickness",bsc_t); + if (err) { + egsWarning(vhp_error_msg1,"'BSC thickness'"); + ok = false; + } + string tb_medium, bm_medium; + int err1 = input->getInput("TB medium",tb_medium); + int err2 = input->getInput("BM medium",bm_medium); + if (err1) { + egsWarning(vhp_error_msg1,"'TB medium'"); + } + if (err2) { + egsWarning(vhp_error_msg1,"'BM medium'"); + } + if (err1 || err2) { + ok = false; + } + string micro_data; + err = input->getInput("micro data file",micro_data); + if (err) { + egsWarning(vhp_error_msg1,"'micro data file'"); + ok = false; + } + if (!ok) { + return 0; + } + int tb_med = EGS_BaseGeometry::addMedium(tb_medium); + int bm_med = EGS_BaseGeometry::addMedium(bm_medium); + EGS_TestMicro *result = new EGS_TestMicro(vs[0],vs[1],vs[2],bsc_t, + tb_med,bm_med,micro_data.c_str()); + result->setName(input); + result->setLabels(input); + return result; + } + string phantom, media; + int err1 = input->getInput("phantom data",phantom); + int err2 = input->getInput("media data",media); + if (err1) egsWarning("createGeometry(EGS_VHPGeometry): " + "missing 'phantom data' input\n"); + if (err2) egsWarning("createGeometry(EGS_VHPGeometry): " + "missing 'media data' input\n"); + if (err1 || err2) { + return 0; } - EGS_Float bsc_t; - err = input->getInput("BSC thickness",bsc_t); - if( err ) { - egsWarning(vhp_error_msg1,"'BSC thickness'"); ok = false; + vector srange; + err1 = input->getInput("slice range",srange); + EGS_VHPGeometry *result; + if (!err1 && srange.size() == 2 && srange[1] > srange[0]) result = + new EGS_VHPGeometry(phantom.c_str(),media.c_str(),srange[0],srange[1]); + else { + result = new EGS_VHPGeometry(phantom.c_str(),media.c_str()); + } + if (!result->isOK()) { + egsWarning("createGeometry(EGS_VHPGeometry): failed to construct " + "geometry"); + delete result; + return 0; } - string tb_medium, bm_medium; - int err1 = input->getInput("TB medium",tb_medium); - int err2 = input->getInput("BM medium",bm_medium); - if( err1 ) egsWarning(vhp_error_msg1,"'TB medium'"); - if( err2 ) egsWarning(vhp_error_msg1,"'BM medium'"); - if( err1 || err2 ) ok = false; - string micro_data; - err = input->getInput("micro data file",micro_data); - if( err ) { egsWarning(vhp_error_msg1,"'micro data file'"); ok = false;} - if( !ok ) return 0; - int tb_med = EGS_BaseGeometry::addMedium(tb_medium); - int bm_med = EGS_BaseGeometry::addMedium(bm_medium); - EGS_TestMicro *result = new EGS_TestMicro(vs[0],vs[1],vs[2],bsc_t, - tb_med,bm_med,micro_data.c_str()); result->setName(input); + result->setMicros(input); result->setLabels(input); return result; } - string phantom, media; - int err1 = input->getInput("phantom data",phantom); - int err2 = input->getInput("media data",media); - if( err1 ) egsWarning("createGeometry(EGS_VHPGeometry): " - "missing 'phantom data' input\n"); - if( err2 ) egsWarning("createGeometry(EGS_VHPGeometry): " - "missing 'media data' input\n"); - if( err1 || err2 ) return 0; - vector srange; - err1 = input->getInput("slice range",srange); - EGS_VHPGeometry *result; - if( !err1 && srange.size() == 2 && srange[1] > srange[0] ) result = - new EGS_VHPGeometry(phantom.c_str(),media.c_str(),srange[0],srange[1]); - else result = new EGS_VHPGeometry(phantom.c_str(),media.c_str()); - if( !result->isOK() ) { - egsWarning("createGeometry(EGS_VHPGeometry): failed to construct " - "geometry"); - delete result; return 0; - } - result->setName(input); - result->setMicros(input); - result->setLabels(input); - return result; -} } diff --git a/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.h b/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.h index 7114ae752..0b03b61f4 100644 --- a/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.h +++ b/HEN_HOUSE/egs++/geometry/egs_vhp_geometry/egs_vhp_geometry.h @@ -54,22 +54,22 @@ #ifdef WIN32 -#ifdef BUILD_VHP_DLL -#define EGS_VHP_EXPORT __declspec(dllexport) -#else -#define EGS_VHP_EXPORT __declspec(dllimport) -#endif -#define EGS_VHP_LOCAL + #ifdef BUILD_VHP_DLL + #define EGS_VHP_EXPORT __declspec(dllexport) + #else + #define EGS_VHP_EXPORT __declspec(dllimport) + #endif + #define EGS_VHP_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_VHP_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_VHP_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_VHP_EXPORT -#define EGS_VHP_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_VHP_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_VHP_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_VHP_EXPORT + #define EGS_VHP_LOCAL + #endif #endif @@ -92,12 +92,22 @@ struct EGS_VHP_LOCAL VHP_RowInfo { unsigned short *pix; unsigned char *org; VHP_RowInfo() : nbin(0) {}; - ~VHP_RowInfo() { if( nbin > 0 ) { delete [] pix; delete [] org; } }; + ~VHP_RowInfo() { + if (nbin > 0) { + delete [] pix; + delete [] org; + } + }; int getBin(int i) const { int ml=0, mu=nbin; - while( mu - ml > 1 ) { + while (mu - ml > 1) { int mav = (ml+mu)/2; - if( i < pix[mav] ) mu = mav; else ml = mav; + if (i < pix[mav]) { + mu = mav; + } + else { + ml = mav; + } } return mu-1; }; @@ -107,8 +117,8 @@ struct EGS_VHP_LOCAL VHP_RowInfo { int getSize() const { int result = sizeof(nbin) + sizeof(unsigned short *) + sizeof(unsigned char *); - if( nbin > 0 ) result += nbin*sizeof(unsigned char) + - (nbin+1)*sizeof(unsigned short); + if (nbin > 0) result += nbin*sizeof(unsigned char) + + (nbin+1)*sizeof(unsigned short); return result; }; void readData(istream &in); @@ -125,25 +135,34 @@ struct EGS_VHP_LOCAL VHP_SliceInfo { unsigned short lastr; VHP_RowInfo *rinfo; VHP_SliceInfo() : rinfo(0) {}; - ~VHP_SliceInfo() { if( rinfo ) delete [] rinfo; }; + ~VHP_SliceInfo() { + if (rinfo) { + delete [] rinfo; + } + }; void getSliceDimensions(int &nx, int &ny) { - ny = lastr+1; nx = 0; + ny = lastr+1; + nx = 0; int nrow = lastr - firstr + 1; - for(int j=0; j nx ) nx = ni; + if (ni > nx) { + nx = ni; + } } }; int getOrgan(int row, int pixel) const { return rinfo && row >= firstr && row <= lastr ? - rinfo[row-firstr].getOrgan(pixel) : 0; + rinfo[row-firstr].getOrgan(pixel) : 0; }; int getSize() const { int result = sizeof(firstr) + sizeof(lastr) + - sizeof(VHP_RowInfo*); - if( rinfo ) { + sizeof(VHP_RowInfo *); + if (rinfo) { int nrow = lastr-firstr+1; - for(int j=0; j= 0 && islice < nslice ? - slices[islice].getOrgan(i,j) : 0; + slices[islice].getOrgan(i,j) : 0; + }; + const VHP_SliceInfo &getVHP_SliceInfo(int j) const { + return slices[j]; + }; + const VHP_SliceInfo &operator[](int j) const { + return slices[j]; }; - const VHP_SliceInfo &getVHP_SliceInfo(int j) const { return slices[j]; }; - const VHP_SliceInfo &operator[](int j) const { return slices[j]; }; int getSize() const { - int result = sizeof(nslice) + sizeof(VHP_SliceInfo*); - if( nslice > 0 ) { - for(int j=0; j 0) { + for (int j=0; j= nslice ) return 0; + if (k < 0 || k >= nslice) { + return 0; + } int jj = ireg - k*nx*ny; - int j = jj/nx; int i = jj - j*nx; + int j = jj/nx; + int i = jj - j*nx; return getOrgan(k,j,i); }; - bool isOK() const { return ok; }; + bool isOK() const { + return ok; + }; protected: double dx, dy, dz; @@ -219,300 +255,483 @@ class EGS_VHP_LOCAL EGS_VoxelGeometry { public: - EGS_Float dx, dxi, xmin, xmax; - EGS_Float dy, dyi, ymin, ymax; - EGS_Float dz, dzi, zmin, zmax; - int nx, ny, nz, nxy; - int ix, iy, iz; - - static EGS_VoxelInfo *v; - static int nv; - - EGS_VoxelGeometry(int Nx, int Ny, int Nz, - EGS_Float Dx, EGS_Float Dy, EGS_Float Dz) : - dx(Dx), dxi(1/Dx), xmin(0), xmax(Dx*Nx), - dy(Dy), dyi(1/Dy), ymin(0), ymax(Dy*Ny), - dz(Dz), dzi(1/Dz), zmin(0), zmax(Dz*Nz), - nx(Nx), ny(Ny), nz(Nz), nxy(nx*ny) {}; - - ~EGS_VoxelGeometry() { if(v) { delete [] v; v = 0; nv = 0; } }; - - bool isInside(const EGS_Vector &x) { - return (x.x >= xmin && x.x <= xmax && - x.y >= ymin && x.y <= ymax && - x.z >= zmin && x.z <= zmax ) ? true : false; - }; - - void setIndeces(const EGS_Vector &x) { - ix = (int) (x.x*dxi); if( ix >= nx ) ix = nx-1; - iy = (int) (x.y*dyi); if( iy >= ny ) iy = ny-1; - iz = (int) (x.z*dzi); if( iz >= nz ) iz = nz-1; - }; - - int isWhere(const EGS_Vector &x) { - if( !isInside(x) ) return -1; - setIndeces(x); - return ix + iy*nx + iz*nxy; - }; - - int isWhereFast(const EGS_Vector &x) { - setIndeces(x); - return ix + iy*nx + iz*nxy; - }; - - int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { - if( n < 1 ) return -1; - if( nv < n ) { - if( nv > 0 ) delete [] v; - v = new EGS_VoxelInfo [n]; nv = n; - } - int ifirst = 0; EGS_Float t, ttot = 0; EGS_Vector x(X); int imed; - if( ireg < 0 ) { - t = 1e30; ireg = howfar(ireg,x,u,t); - if( ireg < 0 ) return 0; - isections[0].t = t; isections[0].rhof = 1; - isections[0].ireg = -1; isections[0].imed = -1; - ttot = t; ++ifirst; x += u*t; - } - int iz = ireg/nxy; int ir = ireg - iz*nxy; - int iy = ir/nx; int ix = ir - iy*nx; - EGS_Float uxi, uyi, uzi, nextx, nexty, nextz, sx, sy, sz; - int dirx, icx, diry, icy, dirz, icz; - if( u.x > 0 ) { - uxi = 1/u.x; dirx = 1; nextx = (dx*(ix+1)-x.x)*uxi; sx = uxi*dx; - } - else if( u.x < 0 ) { - uxi = 1/u.x; dirx = -1; nextx = (dx*ix-x.x)*uxi; sx = -uxi*dx; - } - else { dirx = 1; nextx = 1e33; sx = 1e33; } - if( u.y > 0 ) { - uyi = 1/u.y; diry = 1; nexty = (dy*(iy+1)-x.y)*uyi; sy = uyi*dy; - } - else if( u.y < 0 ) { - uyi = 1/u.y; diry = -1; nexty = (dy*iy-x.y)*uyi; sy = -uyi*dy; - } - else { diry = 1; nexty = 1e33; sy = 1e33; } - if( u.z > 0 ) { - uzi = 1/u.z; dirz = 1; nextz = (dz*(iz+1)-x.z)*uzi; sz = uzi*dz; - } - else if( u.z < 0 ) { - uzi = 1/u.z; dirz = -1; nextz = (dz*iz-x.z)*uzi; sz = -uzi*dz; - } - else { dirz = 1; nextz = 1e33; sz = 1e33; } - for(int j=ifirst; j= nx ) inew = -1; - else { - inew = ireg + dirx; nextx += sx; - } - } - else if( nexty < nextz ) { - t = nexty; iy += diry; - if( iy < 0 || iy >= ny ) inew = -1; - else { - inew = ireg + nx*diry; nexty += sy; - } - } - else { - t = nextz; iz += dirz; - if( iz < 0 || iz >= nz ) inew = -1; - else { - inew = ireg + nxy*dirz; nextz += sz; - } - } - isections[j].t = t; - if( inew < 0 ) return j+1; - } - return ireg >= 0 ? -1 : n; - }; - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - if( ireg < 0 ) return 0; - EGS_Float tx = u.x > 0 ? (xmax-x.x)/u.x : - u.x < 0 ? (xmin-x.x)/u.x : 1e35; - EGS_Float ty = u.y > 0 ? (ymax-x.y)/u.y : - u.y < 0 ? (ymin-x.y)/u.y : 1e35; - EGS_Float tz = u.z > 0 ? (zmax-x.z)/u.z : - u.z < 0 ? (zmin-x.z)/u.z : 1e35; - return tx < ty && tx < tz ? tx : ty < tz ? ty : tz; - }; - - void setIndeces(int ireg) { - iz = ireg/nxy; int ir = ireg - iz*nxy; - iy = ir/nx; ix = ir - iy*nx; - }; - - //int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - // EGS_Float &t, EGS_Vector *normal=0) { - // setIndeces(ireg); - // return howfar(ireg,ix,iy,iz,x,u,t,normal); - //}; - int howfarIn(int ireg, int Ix, int Iy, int Iz, const EGS_Vector &x, - const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { - ix = Ix; iy = Iy; iz = Iz; - return howfarIn(ireg,x,u,t,normal); - }; - - int howfarIn(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, EGS_Vector *normal=0) { - int ixs = ix, iys = iy, izs = iz; - int inew = ireg; - if( u.x > 0 ) { - EGS_Float d = (dx*(ix+1)-x.x)/u.x; - if( d <= t ) { - t = d; if( (++ix) < nx ) inew = ireg + 1; else inew = -1; - if( normal ) *normal = EGS_Vector(-1,0,0); - } - } - else if( u.x < 0 ) { - EGS_Float d = (dx*ix-x.x)/u.x; - if( d <= t ) { - t = d; if( (--ix) >= 0 ) inew = ireg - 1; else inew = -1; - if( normal ) *normal = EGS_Vector(1,0,0); - } - } - if( u.y > 0 ) { - EGS_Float d = (dy*(iy+1)-x.y)/u.y; - if( d <= t ) { - ix = ixs; - t = d; if( (++iy) < ny ) inew = ireg + nx; else inew = -1; - if( normal ) *normal = EGS_Vector(0,-1,0); - } - } - else if( u.y < 0 ) { - EGS_Float d = (dy*iy-x.y)/u.y; - if( d <= t ) { - ix = ixs; - t = d; if( (--iy) >= 0 ) inew = ireg - nx; else inew = -1; - if( normal ) *normal = EGS_Vector(0,1,0); - } - } - if( u.z > 0 ) { - EGS_Float d = (dz*(iz+1)-x.z)/u.z; - if( d <= t ) { - ix = ixs; iy = iys; - t = d; if( (++iz) < nz ) inew = ireg+nxy; else inew = -1; - if( normal ) *normal = EGS_Vector(0,0,-1); - } - } - else if( u.z < 0 ) { - EGS_Float d = (dz*iz-x.z)/u.z; - if( d <= t ) { - ix = ixs; iy = iys; - t = d; if( (--iz) >= 0 ) inew = ireg-nxy; else inew = -1; - if( normal ) *normal = EGS_Vector(0,0,1); - } - } - return inew; - }; - - int howfarOut(const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, EGS_Vector *normal=0) { - EGS_Float tlong = 2*t, d; int inew = -1; - if( x.x <= xmin && u.x > 0 ) { - ix = 0; d = (xmin-x.x)/u.x; - } - else if( x.x >= xmax && u.x < 0 ) { - ix = nx-1; d = (xmax-x.x)/u.x; - } - else d = tlong; - if( d <= t ) { - EGS_Float yy = x.y + u.y*d, zz = x.z + u.z*d; - if( yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax ) { - t = d; - iy = (int) (yy*dyi); if( iy > ny-1 ) iy = ny-1; - iz = (int) (zz*dzi); if( iz > nz-1 ) iz = nz-1; - if( normal ) *normal = ix == 0 ? EGS_Vector(-1,0,0) : - EGS_Vector(1,0,0); - return ix + iy*nx + iz*nxy; - } - } - if( x.y <= ymin && u.y > 0 ) { - iy = 0; d = (ymin-x.y)/u.y; - } - else if( x.y >= ymax && u.y < 0 ) { - iy = ny-1; d = (ymax-x.y)/u.y; - } - else d = tlong; - if( d <= t ) { - EGS_Float xx = x.x + u.x*d, zz = x.z + u.z*d; - if( xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax ) { - t = d; - ix = (int) (xx*dxi); if( ix > nx-1 ) ix = nx-1; - iz = (int) (zz*dzi); if( iz > nz-1 ) iz = nz-1; - if( normal ) *normal = iy == 0 ? EGS_Vector(0,-1,0) : - EGS_Vector(0,1,0); - return ix + iy*nx + iz*nxy; - } - } - if( x.z <= zmin && u.z > 0 ) { - iz = 0; d = (zmin-x.z)/u.z; - } - else if( x.z >= zmax && u.z < 0 ) { - iz = nz-1; d = (zmax-x.z)/u.z; - } - else d = tlong; - if( d <= t ) { - EGS_Float xx = x.x + u.x*d, yy = x.y + u.y*d; - if( xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax ) { - t = d; - ix = (int) (xx*dxi); if( ix > nx-1 ) ix = nx-1; - iy = (int) (yy*dyi); if( iy > ny-1 ) iy = ny-1; - if( normal ) *normal = iz == 0 ? EGS_Vector(0,0,-1) : - EGS_Vector(0,0,1); - return ix + iy*nx + iz*nxy; - } - } - return -1; - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float dx, dxi, xmin, xmax; + EGS_Float dy, dyi, ymin, ymax; + EGS_Float dz, dzi, zmin, zmax; + int nx, ny, nz, nxy; + int ix, iy, iz; + + static EGS_VoxelInfo *v; + static int nv; + + EGS_VoxelGeometry(int Nx, int Ny, int Nz, + EGS_Float Dx, EGS_Float Dy, EGS_Float Dz) : + dx(Dx), dxi(1/Dx), xmin(0), xmax(Dx*Nx), + dy(Dy), dyi(1/Dy), ymin(0), ymax(Dy*Ny), + dz(Dz), dzi(1/Dz), zmin(0), zmax(Dz*Nz), + nx(Nx), ny(Ny), nz(Nz), nxy(nx*ny) {}; + + ~EGS_VoxelGeometry() { + if (v) { + delete [] v; + v = 0; + nv = 0; + } + }; + + bool isInside(const EGS_Vector &x) { + return (x.x >= xmin && x.x <= xmax && + x.y >= ymin && x.y <= ymax && + x.z >= zmin && x.z <= zmax) ? true : false; + }; + + void setIndeces(const EGS_Vector &x) { + ix = (int)(x.x*dxi); + if (ix >= nx) { + ix = nx-1; + } + iy = (int)(x.y*dyi); + if (iy >= ny) { + iy = ny-1; + } + iz = (int)(x.z*dzi); + if (iz >= nz) { + iz = nz-1; + } + }; + + int isWhere(const EGS_Vector &x) { + if (!isInside(x)) { + return -1; + } + setIndeces(x); + return ix + iy*nx + iz*nxy; + }; + + int isWhereFast(const EGS_Vector &x) { + setIndeces(x); + return ix + iy*nx + iz*nxy; + }; + + int computeIntersections(int ireg, int n, const EGS_Vector &X, + const EGS_Vector &u, EGS_GeometryIntersections *isections) { + if (n < 1) { + return -1; + } + if (nv < n) { + if (nv > 0) { + delete [] v; + } + v = new EGS_VoxelInfo [n]; + nv = n; + } + int ifirst = 0; + EGS_Float t, ttot = 0; + EGS_Vector x(X); + int imed; + if (ireg < 0) { + t = 1e30; + ireg = howfar(ireg,x,u,t); + if (ireg < 0) { + return 0; + } + isections[0].t = t; + isections[0].rhof = 1; + isections[0].ireg = -1; + isections[0].imed = -1; + ttot = t; + ++ifirst; + x += u*t; + } + int iz = ireg/nxy; + int ir = ireg - iz*nxy; + int iy = ir/nx; + int ix = ir - iy*nx; + EGS_Float uxi, uyi, uzi, nextx, nexty, nextz, sx, sy, sz; + int dirx, icx, diry, icy, dirz, icz; + if (u.x > 0) { + uxi = 1/u.x; + dirx = 1; + nextx = (dx*(ix+1)-x.x)*uxi; + sx = uxi*dx; + } + else if (u.x < 0) { + uxi = 1/u.x; + dirx = -1; + nextx = (dx*ix-x.x)*uxi; + sx = -uxi*dx; + } + else { + dirx = 1; + nextx = 1e33; + sx = 1e33; + } + if (u.y > 0) { + uyi = 1/u.y; + diry = 1; + nexty = (dy*(iy+1)-x.y)*uyi; + sy = uyi*dy; + } + else if (u.y < 0) { + uyi = 1/u.y; + diry = -1; + nexty = (dy*iy-x.y)*uyi; + sy = -uyi*dy; + } + else { + diry = 1; + nexty = 1e33; + sy = 1e33; + } + if (u.z > 0) { + uzi = 1/u.z; + dirz = 1; + nextz = (dz*(iz+1)-x.z)*uzi; + sz = uzi*dz; + } + else if (u.z < 0) { + uzi = 1/u.z; + dirz = -1; + nextz = (dz*iz-x.z)*uzi; + sz = -uzi*dz; + } + else { + dirz = 1; + nextz = 1e33; + sz = 1e33; + } + for (int j=ifirst; j= nx) { + inew = -1; + } + else { + inew = ireg + dirx; + nextx += sx; + } + } + else if (nexty < nextz) { + t = nexty; + iy += diry; + if (iy < 0 || iy >= ny) { + inew = -1; + } + else { + inew = ireg + nx*diry; + nexty += sy; + } + } + else { + t = nextz; + iz += dirz; + if (iz < 0 || iz >= nz) { + inew = -1; + } + else { + inew = ireg + nxy*dirz; + nextz += sz; + } + } + isections[j].t = t; + if (inew < 0) { + return j+1; + } + } + return ireg >= 0 ? -1 : n; + }; + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + if (ireg < 0) { + return 0; + } + EGS_Float tx = u.x > 0 ? (xmax-x.x)/u.x : + u.x < 0 ? (xmin-x.x)/u.x : 1e35; + EGS_Float ty = u.y > 0 ? (ymax-x.y)/u.y : + u.y < 0 ? (ymin-x.y)/u.y : 1e35; + EGS_Float tz = u.z > 0 ? (zmax-x.z)/u.z : + u.z < 0 ? (zmin-x.z)/u.z : 1e35; + return tx < ty && tx < tz ? tx : ty < tz ? ty : tz; + }; + + void setIndeces(int ireg) { + iz = ireg/nxy; + int ir = ireg - iz*nxy; + iy = ir/nx; + ix = ir - iy*nx; + }; + + //int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + // EGS_Float &t, EGS_Vector *normal=0) { + // setIndeces(ireg); + // return howfar(ireg,ix,iy,iz,x,u,t,normal); + //}; + int howfarIn(int ireg, int Ix, int Iy, int Iz, const EGS_Vector &x, + const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { + ix = Ix; + iy = Iy; + iz = Iz; + return howfarIn(ireg,x,u,t,normal); + }; + + int howfarIn(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - setIndeces(ireg); - return howfarIn(ireg,x,u,t,normal); - } - return howfarOut(x,u,t,normal); - }; - - EGS_Float hownearIn(int Ix, int Iy, int Iz, const EGS_Vector &x) { - ix = Ix; iy = Iy; iz = Iz; - return hownearIn(x); - }; - - EGS_Float hownearIn(const EGS_Vector &x) { - EGS_Float t1,t2,tx,ty,tz; - t1 = x.x-dx*ix; t2 = dx - t1; tx = t1 < t2 ? t1 : t2; - t1 = x.y-dy*iy; t2 = dy - t1; ty = t1 < t2 ? t1 : t2; - t1 = x.z-dz*iz; t2 = dz - t1; tz = t1 < t2 ? t1 : t2; - return tx < ty && tx < tz ? tx : ty < tz ? ty : tz; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg >= 0 ) { - setIndeces(ireg); return hownearIn(x); - } - int nc = 0; EGS_Float s1=0, s2=0; - if( x.x < xmin || x.x > xmax ) { - EGS_Float t = x.x < xmin ? xmin-x.x : x.x-xmax; - nc++; s1 += t; s2 += t*t; - } - if( x.y < ymin || x.y > ymax ) { - EGS_Float t = x.y < ymin ? ymin-x.y : x.y-ymax; - nc++; s1 += t; s2 += t*t; - } - if( x.z < zmin || x.z > zmax ) { - EGS_Float t = x.z < zmin ? zmin-x.z : x.z-zmax; - nc++; s1 += t; s2 += t*t; - } - return nc == 1 ? s1 : sqrt(s2); - }; + int ixs = ix, iys = iy, izs = iz; + int inew = ireg; + if (u.x > 0) { + EGS_Float d = (dx*(ix+1)-x.x)/u.x; + if (d <= t) { + t = d; + if ((++ix) < nx) { + inew = ireg + 1; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(-1,0,0); + } + } + } + else if (u.x < 0) { + EGS_Float d = (dx*ix-x.x)/u.x; + if (d <= t) { + t = d; + if ((--ix) >= 0) { + inew = ireg - 1; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(1,0,0); + } + } + } + if (u.y > 0) { + EGS_Float d = (dy*(iy+1)-x.y)/u.y; + if (d <= t) { + ix = ixs; + t = d; + if ((++iy) < ny) { + inew = ireg + nx; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,-1,0); + } + } + } + else if (u.y < 0) { + EGS_Float d = (dy*iy-x.y)/u.y; + if (d <= t) { + ix = ixs; + t = d; + if ((--iy) >= 0) { + inew = ireg - nx; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,1,0); + } + } + } + if (u.z > 0) { + EGS_Float d = (dz*(iz+1)-x.z)/u.z; + if (d <= t) { + ix = ixs; + iy = iys; + t = d; + if ((++iz) < nz) { + inew = ireg+nxy; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,0,-1); + } + } + } + else if (u.z < 0) { + EGS_Float d = (dz*iz-x.z)/u.z; + if (d <= t) { + ix = ixs; + iy = iys; + t = d; + if ((--iz) >= 0) { + inew = ireg-nxy; + } + else { + inew = -1; + } + if (normal) { + *normal = EGS_Vector(0,0,1); + } + } + } + return inew; + }; + + int howfarOut(const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, EGS_Vector *normal=0) { + EGS_Float tlong = 2*t, d; + int inew = -1; + if (x.x <= xmin && u.x > 0) { + ix = 0; + d = (xmin-x.x)/u.x; + } + else if (x.x >= xmax && u.x < 0) { + ix = nx-1; + d = (xmax-x.x)/u.x; + } + else { + d = tlong; + } + if (d <= t) { + EGS_Float yy = x.y + u.y*d, zz = x.z + u.z*d; + if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) { + t = d; + iy = (int)(yy*dyi); + if (iy > ny-1) { + iy = ny-1; + } + iz = (int)(zz*dzi); + if (iz > nz-1) { + iz = nz-1; + } + if (normal) *normal = ix == 0 ? EGS_Vector(-1,0,0) : + EGS_Vector(1,0,0); + return ix + iy*nx + iz*nxy; + } + } + if (x.y <= ymin && u.y > 0) { + iy = 0; + d = (ymin-x.y)/u.y; + } + else if (x.y >= ymax && u.y < 0) { + iy = ny-1; + d = (ymax-x.y)/u.y; + } + else { + d = tlong; + } + if (d <= t) { + EGS_Float xx = x.x + u.x*d, zz = x.z + u.z*d; + if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) { + t = d; + ix = (int)(xx*dxi); + if (ix > nx-1) { + ix = nx-1; + } + iz = (int)(zz*dzi); + if (iz > nz-1) { + iz = nz-1; + } + if (normal) *normal = iy == 0 ? EGS_Vector(0,-1,0) : + EGS_Vector(0,1,0); + return ix + iy*nx + iz*nxy; + } + } + if (x.z <= zmin && u.z > 0) { + iz = 0; + d = (zmin-x.z)/u.z; + } + else if (x.z >= zmax && u.z < 0) { + iz = nz-1; + d = (zmax-x.z)/u.z; + } + else { + d = tlong; + } + if (d <= t) { + EGS_Float xx = x.x + u.x*d, yy = x.y + u.y*d; + if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) { + t = d; + ix = (int)(xx*dxi); + if (ix > nx-1) { + ix = nx-1; + } + iy = (int)(yy*dyi); + if (iy > ny-1) { + iy = ny-1; + } + if (normal) *normal = iz == 0 ? EGS_Vector(0,0,-1) : + EGS_Vector(0,0,1); + return ix + iy*nx + iz*nxy; + } + } + return -1; + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, EGS_Vector *normal=0) { + if (ireg >= 0) { + setIndeces(ireg); + return howfarIn(ireg,x,u,t,normal); + } + return howfarOut(x,u,t,normal); + }; + + EGS_Float hownearIn(int Ix, int Iy, int Iz, const EGS_Vector &x) { + ix = Ix; + iy = Iy; + iz = Iz; + return hownearIn(x); + }; + + EGS_Float hownearIn(const EGS_Vector &x) { + EGS_Float t1,t2,tx,ty,tz; + t1 = x.x-dx*ix; + t2 = dx - t1; + tx = t1 < t2 ? t1 : t2; + t1 = x.y-dy*iy; + t2 = dy - t1; + ty = t1 < t2 ? t1 : t2; + t1 = x.z-dz*iz; + t2 = dz - t1; + tz = t1 < t2 ? t1 : t2; + return tx < ty && tx < tz ? tx : ty < tz ? ty : tz; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg >= 0) { + setIndeces(ireg); + return hownearIn(x); + } + int nc = 0; + EGS_Float s1=0, s2=0; + if (x.x < xmin || x.x > xmax) { + EGS_Float t = x.x < xmin ? xmin-x.x : x.x-xmax; + nc++; + s1 += t; + s2 += t*t; + } + if (x.y < ymin || x.y > ymax) { + EGS_Float t = x.y < ymin ? ymin-x.y : x.y-ymax; + nc++; + s1 += t; + s2 += t*t; + } + if (x.z < zmin || x.z > zmax) { + EGS_Float t = x.z < zmin ? zmin-x.z : x.z-zmax; + nc++; + s1 += t; + s2 += t*t; + } + return nc == 1 ? s1 : sqrt(s2); + }; }; #endif @@ -525,48 +744,100 @@ struct VHPBox { EGS_Float xmin, xmax; EGS_Float ymin, ymax; EGS_Float zmin, zmax; - bool isInside(const EGS_Vector &x) { return - (x.x>=xmin&&x.x<=xmax&&x.y>=ymin&&ymax<=ymin&&x.z>=zmin&&x.z<=zmax); + bool isInside(const EGS_Vector &x) { + return + (x.x>=xmin&&x.x<=xmax&&x.y>=ymin&&ymax<=ymin&&x.z>=zmin&&x.z<=zmax); }; bool willEnter(const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t) { EGS_Float tlong = 2*t, d; - if( x.x <= xmin && u.x > 0 ) d = (xmin-x.x)/u.x; - else if( x.x >= xmax && u.x < 0 ) d = (xmax-x.x)/u.x; - else d = tlong; - if( d <= t ) { + if (x.x <= xmin && u.x > 0) { + d = (xmin-x.x)/u.x; + } + else if (x.x >= xmax && u.x < 0) { + d = (xmax-x.x)/u.x; + } + else { + d = tlong; + } + if (d <= t) { EGS_Float yy = x.y + u.y*d, zz = x.z + u.z*d; - if( yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax ) { - t = d; return true; + if (yy >= ymin && yy <= ymax && zz >= zmin && zz <= zmax) { + t = d; + return true; } } - if( x.y <= ymin && u.y > 0 ) d = (ymin-x.y)/u.y; - else if( x.y >= ymax && u.y < 0 ) d = (ymax-x.y)/u.y; - else d = tlong; - if( d <= t ) { + if (x.y <= ymin && u.y > 0) { + d = (ymin-x.y)/u.y; + } + else if (x.y >= ymax && u.y < 0) { + d = (ymax-x.y)/u.y; + } + else { + d = tlong; + } + if (d <= t) { EGS_Float xx = x.x + u.x*d, zz = x.z + u.z*d; - if( xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax ) { - t = d; return true; + if (xx >= xmin && xx <= xmax && zz >= zmin && zz <= zmax) { + t = d; + return true; } } - if( x.z <= zmin && u.z > 0 ) d = (zmin-x.z)/u.z; - else if( x.z >= zmax && u.z < 0 ) d = (zmax-x.z)/u.z; - else d = tlong; - if( d <= t ) { + if (x.z <= zmin && u.z > 0) { + d = (zmin-x.z)/u.z; + } + else if (x.z >= zmax && u.z < 0) { + d = (zmax-x.z)/u.z; + } + else { + d = tlong; + } + if (d <= t) { EGS_Float xx = x.x + u.x*d, yy = x.y + u.y*d; - if( xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax ) { - t = d; return true; + if (xx >= xmin && xx <= xmax && yy >= ymin && yy <= ymax) { + t = d; + return true; } } return false; }; EGS_Float howfarToOut(const EGS_Vector &x, const EGS_Vector &u) { EGS_Float t = 1e35, t1; - if ( u.x > 0 ) { t1 = (xmax-x.x)/u.x; if( t1 < t ) t = t1; } - else if( u.x < 0 ) { t1 = (xmin-x.x)/u.x; if( t1 < t ) t = t1; } - if ( u.y > 0 ) { t1 = (ymax-x.y)/u.y; if( t1 < t ) t = t1; } - else if( u.y < 0 ) { t1 = (ymin-x.y)/u.y; if( t1 < t ) t = t1; } - if ( u.z > 0 ) { t1 = (zmax-x.z)/u.z; if( t1 < t ) t = t1; } - else if( u.z < 0 ) { t1 = (zmin-x.z)/u.z; if( t1 < t ) t = t1; } + if (u.x > 0) { + t1 = (xmax-x.x)/u.x; + if (t1 < t) { + t = t1; + } + } + else if (u.x < 0) { + t1 = (xmin-x.x)/u.x; + if (t1 < t) { + t = t1; + } + } + if (u.y > 0) { + t1 = (ymax-x.y)/u.y; + if (t1 < t) { + t = t1; + } + } + else if (u.y < 0) { + t1 = (ymin-x.y)/u.y; + if (t1 < t) { + t = t1; + } + } + if (u.z > 0) { + t1 = (zmax-x.z)/u.z; + if (t1 < t) { + t = t1; + } + } + else if (u.z < 0) { + t1 = (zmin-x.z)/u.z; + if (t1 < t) { + t = t1; + } + } return t; }; }; @@ -589,22 +860,56 @@ class EGS_VHP_LOCAL EGS_MicroMatrixCluster { int howfar(int imic, int ireg, int &lax, int &lay, int &laz, int &newmic, - const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { int inew = vg->howfar(ireg,x,u,t,normal); newmic = imic; - if( inew < 0 ) { - int iz = imic/(mx*my); int itmp = imic - iz*mx*my; - int iy = itmp/mx; int ix = itmp - mx*iy; - if ( vg->ix < 0 ) { --lax; if( (--ix) < 0 ) ix = mx-1; } - else if( vg->ix >= vg->nx ) { ++lax; if( (++ix) >= mx ) ix = 0; } - else if( vg->iy < 0 ) { --lay; if( (--iy) < 0 ) iy = my-1; } - else if( vg->iy >= vg->ny ) { ++lay; if( (++iy) >= my ) iy = 0; } - else if( vg->iz < 0 ) { --laz; if( (--iz) < 0 ) iz = mz-1; } - else if( vg->iz >= vg->nz ) { ++laz; if( (++iz) >= mz ) iz = 0; } + if (inew < 0) { + int iz = imic/(mx*my); + int itmp = imic - iz*mx*my; + int iy = itmp/mx; + int ix = itmp - mx*iy; + if (vg->ix < 0) { + --lax; + if ((--ix) < 0) { + ix = mx-1; + } + } + else if (vg->ix >= vg->nx) { + ++lax; + if ((++ix) >= mx) { + ix = 0; + } + } + else if (vg->iy < 0) { + --lay; + if ((--iy) < 0) { + iy = my-1; + } + } + else if (vg->iy >= vg->ny) { + ++lay; + if ((++iy) >= my) { + iy = 0; + } + } + else if (vg->iz < 0) { + --laz; + if ((--iz) < 0) { + iz = mz-1; + } + } + else if (vg->iz >= vg->nz) { + ++laz; + if ((++iz) >= mz) { + iz = 0; + } + } newmic = ix + iy*mx + iz*mx*my; } - if( newmed ) *newmed = micros[newmic][inew] ? med_bm : med_tb; + if (newmed) { + *newmed = micros[newmic][inew] ? med_bm : med_tb; + } return inew; }; @@ -617,45 +922,62 @@ class EGS_VHP_LOCAL EGS_MicroMatrixCluster { }; int medium(int ireg) const { - int imic = ireg/nreg; ireg -= imic*nreg; + int imic = ireg/nreg; + ireg -= imic*nreg; return medium(imic,ireg); }; int isWhere(int &imic, const EGS_Vector &x) { - int ix = (int) (x.x*dxi), iy = (int) (x.y*dyi), iz = (int) (x.z*dzi); + int ix = (int)(x.x*dxi), iy = (int)(x.y*dyi), iz = (int)(x.z*dzi); EGS_Vector x1(x - EGS_Vector(dx*ix, dy*iy, dz*iz)); - ix = ix%mx; iy = iy%my; iz = iz%mz; + ix = ix%mx; + iy = iy%my; + iz = iz%mz; imic = ix + iy*mx + iz*mz; return vg->isWhere(x1); }; void getIndeces(int ireg, int &imic, int &ix, int &iy, int &iz) { - imic = ireg/nreg; ireg -= imic*nreg; - iz = ireg/nxy; iy = (ireg - iz*nxy)/nx; ix = ireg - iz*nxy - iy*nx; + imic = ireg/nreg; + ireg -= imic*nreg; + iz = ireg/nxy; + iy = (ireg - iz*nxy)/nx; + ix = ireg - iz*nxy - iy*nx; }; int isWhere(int jx, int jy, int jz, const EGS_Vector &x1, int *newmed=0) { int ix = jx%mx, iy = jy%my, iz = jz%mz; int imic = ix + iy*mx + iz*mz; int iloc = vg->isWhereFast(x1); - if( newmed ) *newmed = medium(imic,iloc); + if (newmed) { + *newmed = medium(imic,iloc); + } return imic*nreg + iloc; }; - bool isValid() const { return (vg && micros); }; + bool isValid() const { + return (vg && micros); + }; void getStepFractions(int imic, int ireg, - const EGS_Vector &xi, const EGS_Vector &xf, - EGS_Float &bsc_step, EGS_Float &bm_step ) { - bsc_step = 0; bm_step = 0; int mict = micros[imic][ireg]; - if( mict ) { + const EGS_Vector &xi, const EGS_Vector &xf, + EGS_Float &bsc_step, EGS_Float &bm_step) { + bsc_step = 0; + bm_step = 0; + int mict = micros[imic][ireg]; + if (mict) { // a BM voxel => check step fractions - if( mict == 1 ) bsc_step = 1; // all BSC - else if( mict == 2 ) bm_step = 1; // all BM + if (mict == 1) { + bsc_step = 1; // all BSC + } + else if (mict == 2) { + bm_step = 1; // all BM + } else { mict -= 2; // get positions in bm_boxes co-ordinate system - int jz = ireg/nxy; int jy = (ireg-jz*nxy)/nx; + int jz = ireg/nxy; + int jy = (ireg-jz*nxy)/nx; int jx = ireg-jz*nxy-jy*nx; EGS_Vector xcorner(vg->dx*jx,vg->dy*jy,vg->dz*jz); EGS_Vector Xi(xi-xcorner), Xf(xf-xcorner); @@ -663,26 +985,34 @@ class EGS_VHP_LOCAL EGS_MicroMatrixCluster { f_inside = bm_boxes[mict].isInside(Xf); // if both positions are inside the BM box, the entire step // is in the BM box - if( i_inside && f_inside ) bm_step = 1; + if (i_inside && f_inside) { + bm_step = 1; + } else { // we have a fraction in BM and remainder in BSC EGS_Vector u(Xf-Xi); - EGS_Float t = u.length(); EGS_Float ti = 1/t; u *= ti; - if( !i_inside ) { + EGS_Float t = u.length(); + EGS_Float ti = 1/t; + u *= ti; + if (!i_inside) { // initial position outside of BM box => find entry EGS_Float tt = t; - if( !bm_boxes[mict].willEnter(Xi,u,tt) ) { + if (!bm_boxes[mict].willEnter(Xi,u,tt)) { // line Xi->Xf does not intersect BM box - bsc_step = 1; return; + bsc_step = 1; + return; } // move to entry point - bsc_step = tt; Xi += u*tt; + bsc_step = tt; + Xi += u*tt; } - if( f_inside ) { + if (f_inside) { // final position inside BM box. This implies initial // position was outside. Because we already computed // distance to BM box entry, the remainder goes to BM - bsc_step *= ti; bm_step = 1 - bsc_step; return; + bsc_step *= ti; + bm_step = 1 - bsc_step; + return; } // final position outside. this means that either the // initial position was inside or that we moved to the @@ -695,7 +1025,9 @@ class EGS_VHP_LOCAL EGS_MicroMatrixCluster { }; void getVolumes(int imic, EGS_Float &tb, EGS_Float &bm, EGS_Float &bsc) { - tb = v_tb[imic]; bm = v_bm[imic]; bsc = v_bsc[imic]; + tb = v_tb[imic]; + bm = v_bm[imic]; + bsc = v_bsc[imic]; }; @@ -735,14 +1067,21 @@ class EGS_VHP_EXPORT EGS_TestMicro : public EGS_BaseGeometry { public: EGS_TestMicro(EGS_Float Dx, EGS_Float Dy, EGS_Float Dz, EGS_Float bsc_t, - int tb_med, int bm_med,const char *micro_file, const string &Name=""); + int tb_med, int bm_med,const char *micro_file, const string &Name=""); ~EGS_TestMicro(); - int inside(const EGS_Vector &x) { return isWhere(x); }; - bool isInside(const EGS_Vector &x) { return vg->isInside(x); } + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + bool isInside(const EGS_Vector &x) { + return vg->isInside(x); + } int isWhere(const EGS_Vector &x) { - int ireg = vg->isWhere(x); if( ireg < 0 ) return ireg; + int ireg = vg->isWhere(x); + if (ireg < 0) { + return ireg; + } EGS_Vector x1(x-EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); int ix = vg->ix%micro->mx, iy = vg->iy%micro->my, @@ -754,67 +1093,96 @@ class EGS_VHP_EXPORT EGS_TestMicro : public EGS_BaseGeometry { int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( ireg >= 0 ) { - int voxel = ireg/nr; int ilocal = ireg - voxel*nr; + if (ireg >= 0) { + int voxel = ireg/nr; + int ilocal = ireg - voxel*nr; vg->setIndeces(voxel); EGS_Vector x1(x-EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); int inew = micro->vg->howfar(ilocal,x1,u,t,normal); - if( inew == ilocal ) return ireg; - if( inew < 0 ) { - if( micro->vg->ix < 0 ) { - if( (--vg->ix) < 0 ) return -1; + if (inew == ilocal) { + return ireg; + } + if (inew < 0) { + if (micro->vg->ix < 0) { + if ((--vg->ix) < 0) { + return -1; + } micro->vg->ix = micro->vg->nx-1; } - else if( micro->vg->ix >= micro->vg->nx ) { - if( (++vg->ix) >= vg->nx ) return -1; + else if (micro->vg->ix >= micro->vg->nx) { + if ((++vg->ix) >= vg->nx) { + return -1; + } micro->vg->ix = 0; } - else if( micro->vg->iy < 0 ) { - if( (--vg->iy) < 0 ) return -1; + else if (micro->vg->iy < 0) { + if ((--vg->iy) < 0) { + return -1; + } micro->vg->iy = micro->vg->ny-1; } - else if( micro->vg->iy >= micro->vg->ny ) { - if( (++vg->iy) >= vg->ny ) return -1; + else if (micro->vg->iy >= micro->vg->ny) { + if ((++vg->iy) >= vg->ny) { + return -1; + } micro->vg->iy = 0; } - else if( micro->vg->iz < 0 ) { - if( (--vg->iz) < 0 ) return -1; + else if (micro->vg->iz < 0) { + if ((--vg->iz) < 0) { + return -1; + } micro->vg->iz = micro->vg->nz-1; } - else if( micro->vg->iz >= micro->vg->nz ) { - if( (++vg->iz) >= vg->nz ) return -1; + else if (micro->vg->iz >= micro->vg->nz) { + if ((++vg->iz) >= vg->nz) { + return -1; + } micro->vg->iz = 0; } inew = micro->vg->ix + micro->vg->iy*micro->vg->nx + micro->vg->iz*micro->vg->nxy; } voxel = vg->ix + vg->iy*vg->nx + vg->iz*vg->nxy; - if( newmed ) *newmed = micro->medium(voxel,inew); + if (newmed) { + *newmed = micro->medium(voxel,inew); + } return voxel*nr + inew; } int voxel = vg->howfar(ireg,x,u,t,normal); - if( voxel < 0 ) return voxel; + if (voxel < 0) { + return voxel; + } EGS_Vector x1(x + u*t); x1 -= EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz); int ilocal = micro->vg->isWhereFast(x1); - if( ilocal < 0 ) egsFatal("x=(%g,%g,%g) x+u*t=(%g,%g,%g) x1=(%g,%g,%g)\n",x.x,x.y,x.z,(x+u*t).x,(x+u*t).y,(x+u*t).z,x1.x,x1.y,x1.z); - if( newmed ) *newmed = micro->medium(voxel,ilocal); + if (ilocal < 0) { + egsFatal("x=(%g,%g,%g) x+u*t=(%g,%g,%g) x1=(%g,%g,%g)\n",x.x,x.y,x.z,(x+u*t).x,(x+u*t).y,(x+u*t).z,x1.x,x1.y,x1.z); + } + if (newmed) { + *newmed = micro->medium(voxel,ilocal); + } return voxel*nr + ilocal; }; EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { return vg->howfarToOutside(ireg,x,u); }; + const EGS_Vector &u) { + return vg->howfarToOutside(ireg,x,u); + }; EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg < 0 ) return vg->hownear(ireg,x); - int voxel = ireg/nr; int ilocal = ireg - voxel*nr; + if (ireg < 0) { + return vg->hownear(ireg,x); + } + int voxel = ireg/nr; + int ilocal = ireg - voxel*nr; vg->setIndeces(voxel); EGS_Vector x1(x-EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); return micro->vg->hownear(ilocal,x1); }; int medium(int ireg) const { - int voxel = ireg/nr; int ilocal = ireg - voxel*nr; + int voxel = ireg/nr; + int ilocal = ireg - voxel*nr; return micro->medium(voxel,ilocal); }; @@ -823,7 +1191,9 @@ class EGS_VHP_EXPORT EGS_TestMicro : public EGS_BaseGeometry { micro->mz*micro->nz + 1; }; - const string &getType() const { return type; }; + const string &getType() const { + return type; + }; protected: @@ -935,269 +1305,369 @@ class EGS_VHP_EXPORT EGS_VHPGeometry : public EGS_BaseGeometry { public: - EGS_VHPGeometry(const char *phantom_file, const char *media_file, - int slice_min=0, int slice_max=1000000, const string &Name=""); - - ~EGS_VHPGeometry(); - - bool isInside(const EGS_Vector &x) { - return vg->isInside(x); - }; - - int isWhere(const EGS_Vector &x) { - int ireg = vg->isWhere(x); - if( !nmicro ) return ireg; - int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); - int mict = organ_micro[iorg]; - if( mict < 0 ) return ireg; // i.e., no micros in this macro voxel - EGS_Vector x1(x - EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); - int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1); - return nmax*mict + micr + nmacro; - }; - - int inside(const EGS_Vector &x) { return isWhere(x); }; - - int medium(int ireg) const { - if( ireg < nmacro ) - return organ_media[organs->getOrgan(ireg)]; - ireg -= nmacro; int mict = ireg/nmax; - int iloc = ireg - mict*nmax; - return micros[mict]->medium(iloc); - }; - - int computeIntersections(int ireg, int n, const EGS_Vector &X, - const EGS_Vector &u, EGS_GeometryIntersections *isections) { - // fix the following - if( nmicro > 0 ) return EGS_BaseGeometry::computeIntersections(ireg, - n,X,u,isections); - if( n < 1 ) return -1; - int result = vg->computeIntersections(ireg,n,X,u,isections); - if( !result ) return result; // no intersections - int nloop = result > 0 ? result : n; - int first = isections[0].ireg >= 0 ? 0 : 1; - EGS_VoxelInfo *v = vg->v; - for(int j=first; jgetOrgan(v[j].iz,v[j].iy,v[j].ix)]; - return result; - }; - - EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, - const EGS_Vector &u) { - return vg->howfarToOutside(ireg,x,u); - }; - - int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, - EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { - if( nmicro < 1 ) { // no micro matrices - int inew = vg->howfar(ireg,x,u,t,normal); - if( newmed && inew >= 0 && inew != ireg ) - *newmed = organ_media[organs->getOrgan(vg->iz,vg->iy,vg->ix)]; - return inew; - } - if( ireg >= 0 && ireg < nmacro ) { - // in macro matrix - int inew = vg->howfar(ireg,x,u,t,normal); - if( t < 0 ) { - if( t < -1e-5 ) { - egsWarning("negative step %g in macro voxel\n",t); - egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n",x.x,x.y,x.z, - u.x,u.y,u.z); - egsWarning("ix=%d iy=%d iz=%d\n",vg->ix,vg->iy,vg->iz); - egsFatal("quitting\n"); - } - t = 1e-15; - } - if( inew < 0 || inew == ireg ) return inew; - // i.e., exits macro geometry or stays in same macro voxel - int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); - int mict = organ_micro[iorg]; - if( mict < 0 ) { // no micro matrix in the new macro voxel - if( newmed ) *newmed = organ_media[iorg]; return inew; - } - // if here, enters micro matrix. - EGS_Vector x1(x + u*t - - EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); - int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1,newmed); - return nmax*mict + micr + nmacro; - } - if( ireg >= 0 ) { - // in a micro matrix. - int ireg1 = ireg - nmacro; int mict = ireg1/nmax; - int iloc = ireg1 - mict*nmax; - //return micros[mict]->medium(iloc); - int imic, ix, iy, iz; - EGS_MicroMatrixCluster *micro = micros[mict]; - micro->getIndeces(iloc,imic,ix,iy,iz); - int ilocal = iloc - imic*micros[mict]->nreg; - // now we have to figure out the macro voxel indeces - // in principle one could simply use vg->isWhere(x), but - // this is bound to get us in trouble with roundoff errors. - // we therefore treat the special case where x is in an edge - // voxel of the micro matrix in a special way - int lax, lay, laz; - EGS_Float aux = x.x*vg->dxi; - if( ix > 0 && ix < micros[mict]->vg->nx-1 ) lax = (int) aux; - else if( ix == 0 ) lax = (int) (aux+0.5); - else lax = (int) (aux-0.5); - aux = x.y*vg->dyi; - if( iy > 0 && iy < micros[mict]->vg->ny-1 ) lay = (int) aux; - else if( iy == 0 ) lay = (int) (aux+0.5); - else lay = (int) (aux-0.5); - aux = x.z*vg->dzi; - if( iz > 0 && iz < micros[mict]->vg->nz-1 ) laz = (int) aux; - else if( iz == 0 ) laz = (int) (aux+0.5); - else laz = (int) (aux-0.5); - EGS_Vector x1(x - EGS_Vector(vg->dx*lax,vg->dy*lay,vg->dz*laz)); - int inew = micro->vg->howfarIn(ilocal,ix,iy,iz,x1,u,t,normal); - if( t < 0 ) { - if( t < -1e-5 ) { - egsWarning("negative step %g in micro matrix\n",t); - egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n",x.x,x.y,x.z, - u.x,u.y,u.z); - egsWarning("ix=%d iy=%d iz=%d\n",ix,iy,iz); - egsWarning("lax=%d lay=%d laz=%d\n",lax,lay,laz); - egsWarning("x1=(%g,%g,%g)\n",x1.x,x1.y,x1.z); - egsFatal("quitting\n"); - } - t = 0; - } - if( inew == ilocal ) return ireg; - if( inew < 0 ) { - // exiting current micro matrix => entering new - // macro voxel. - // 1. find which one and set new micro region - if( micro->vg->ix < 0 ) { - if( (--lax) < 0 ) return -1; - micro->vg->ix = micro->vg->nx-1; - } - else if( micro->vg->ix >= micro->vg->nx ) { - if( (++lax) >= vg->nx ) return -1; - micro->vg->ix = 0; - } - else if( micro->vg->iy < 0 ) { - if( (--lay) < 0 ) return -1; - micro->vg->iy = micro->vg->ny-1; - } - else if( micro->vg->iy >= micro->vg->ny ) { - if( (++lay) >= vg->ny ) return -1; - micro->vg->iy = 0; - } - else if( micro->vg->iz < 0 ) { - if( (--laz) < 0 ) return -1; - micro->vg->iz = micro->vg->nz-1; - } - else if( micro->vg->iz >= micro->vg->nz ) { - if( (++laz) >= vg->nz ) return -1; - micro->vg->iz = 0; - } - // 2. micro matrix in new macro voxel? - int iorg = organs->getOrgan(laz,lay,lax); - mict = organ_micro[iorg]; - if( mict < 0 ) { // no. - if( newmed ) *newmed = organ_media[iorg]; - return lax + lay*vg->nx + laz*vg->nxy; - } - inew = micro->vg->ix + micro->vg->iy*micro->vg->nx + - micro->vg->iz*micro->vg->nxy; - int lix = lax%micros[mict]->mx; - int liy = lay%micros[mict]->my; - int liz = laz%micros[mict]->mz; - imic = lix + micros[mict]->mx*liy + micros[mict]->mxy*liz; - } - if( newmed ) *newmed = micros[mict]->medium(imic,inew); - return nmax*mict + inew + nmacro; - } - // outside - int imac = vg->howfarOut(x,u,t,normal); - if( imac < 0 ) return imac; - int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); - int mict = organ_micro[iorg]; - if( mict < 0 ) { - if( newmed ) *newmed = organ_media[iorg]; - return imac; - } - EGS_Vector x1(x + u*t); - x1 -= EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz); - int ilocal = micros[mict]->vg->isWhereFast(x1); - int ix=vg->ix%micros[mict]->mx, - iy=vg->iy%micros[mict]->my, - iz=vg->iz%micros[mict]->mz; - int imic = ix + iy*micros[mict]->mx + iz*micros[mict]->mxy; - if( newmed ) *newmed = micros[mict]->medium(imic,ilocal); - return nmax*mict + imic*micros[mict]->nreg + ilocal + nmacro; - }; - - EGS_Float hownear(int ireg, const EGS_Vector &x) { - if( ireg < nmacro ) return vg->hownear(ireg,x); - ireg -= nmacro; int mict = ireg/nmax; - int iloc = ireg - mict*nmax; - int imic, ix, iy, iz; - EGS_MicroMatrixCluster *micro = micros[mict]; - micro->getIndeces(iloc,imic,ix,iy,iz); - int ilocal = iloc - imic*micro->nreg; - // now we have to figure out the macro voxel indeces - // in principle one could simply use vg->isWhere(x), but - // this is bound to get us in trouble with roundoff errors. - // we therefore treat the special case where x is in an edge - // voxel of the micro matrix in a special way - int lax, lay, laz; - EGS_Float aux = x.x*vg->dxi; - if( ix > 0 && ix < micro->vg->nx-1 ) lax = (int) aux; - else if( ix == 0 ) lax = (int) (aux+0.5); - else lax = (int) (aux-0.5); - aux = x.y*vg->dyi; - if( iy > 0 && iy < micro->vg->ny-1 ) lay = (int) aux; - else if( iy == 0 ) lay = (int) (aux+0.5); - else lay = (int) (aux-0.5); - aux = x.z*vg->dzi; - if( iz > 0 && iz < micro->vg->nz-1 ) laz = (int) aux; - else if( iz == 0 ) laz = (int) (aux+0.5); - else laz = (int) (aux-0.5); - EGS_Vector x1(x - EGS_Vector(vg->dx*lax,vg->dy*lay,vg->dz*laz)); - return micro->vg->hownearIn(ix,iy,iz,x1); - }; - - int getMaxStep() const { - if( !nmicro ) return vg->nx+vg->ny+vg->nz+1; - int nmx=0, nmy=0, nmz=0; - for(int mict=0; mictnx > nmx ) nmx = micros[mict]->nx; - if( micros[mict]->ny > nmy ) nmy = micros[mict]->ny; - if( micros[mict]->nx > nmz ) nmx = micros[mict]->nz; - } - return vg->nx*nmx+vg->ny*nmy+vg->nz*nmz+1; - }; - - bool isOK() const { return (vg && organs); }; - - int getNx() const { return vg->nx; }; - int getNy() const { return vg->ny; }; - int getNz() const { return vg->nz; }; - - const string &getType() const { return type; }; - - void printInfo() const; - - //static EGS_VHPGeometry* createGeometry(EGS_Input *); - void setMicros(EGS_Input *); + EGS_VHPGeometry(const char *phantom_file, const char *media_file, + int slice_min=0, int slice_max=1000000, const string &Name=""); + + ~EGS_VHPGeometry(); + + bool isInside(const EGS_Vector &x) { + return vg->isInside(x); + }; + + int isWhere(const EGS_Vector &x) { + int ireg = vg->isWhere(x); + if (!nmicro) { + return ireg; + } + int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); + int mict = organ_micro[iorg]; + if (mict < 0) { + return ireg; // i.e., no micros in this macro voxel + } + EGS_Vector x1(x - EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); + int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1); + return nmax*mict + micr + nmacro; + }; + + int inside(const EGS_Vector &x) { + return isWhere(x); + }; + + int medium(int ireg) const { + if (ireg < nmacro) { + return organ_media[organs->getOrgan(ireg)]; + } + ireg -= nmacro; + int mict = ireg/nmax; + int iloc = ireg - mict*nmax; + return micros[mict]->medium(iloc); + }; + + int computeIntersections(int ireg, int n, const EGS_Vector &X, + const EGS_Vector &u, EGS_GeometryIntersections *isections) { + // fix the following + if (nmicro > 0) return EGS_BaseGeometry::computeIntersections(ireg, + n,X,u,isections); + if (n < 1) { + return -1; + } + int result = vg->computeIntersections(ireg,n,X,u,isections); + if (!result) { + return result; // no intersections + } + int nloop = result > 0 ? result : n; + int first = isections[0].ireg >= 0 ? 0 : 1; + EGS_VoxelInfo *v = vg->v; + for (int j=first; jgetOrgan(v[j].iz,v[j].iy,v[j].ix)]; + return result; + }; + + EGS_Float howfarToOutside(int ireg, const EGS_Vector &x, + const EGS_Vector &u) { + return vg->howfarToOutside(ireg,x,u); + }; + + int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u, + EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) { + if (nmicro < 1) { // no micro matrices + int inew = vg->howfar(ireg,x,u,t,normal); + if (newmed && inew >= 0 && inew != ireg) { + *newmed = organ_media[organs->getOrgan(vg->iz,vg->iy,vg->ix)]; + } + return inew; + } + if (ireg >= 0 && ireg < nmacro) { + // in macro matrix + int inew = vg->howfar(ireg,x,u,t,normal); + if (t < 0) { + if (t < -1e-5) { + egsWarning("negative step %g in macro voxel\n",t); + egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n",x.x,x.y,x.z, + u.x,u.y,u.z); + egsWarning("ix=%d iy=%d iz=%d\n",vg->ix,vg->iy,vg->iz); + egsFatal("quitting\n"); + } + t = 1e-15; + } + if (inew < 0 || inew == ireg) { + return inew; + } + // i.e., exits macro geometry or stays in same macro voxel + int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); + int mict = organ_micro[iorg]; + if (mict < 0) { // no micro matrix in the new macro voxel + if (newmed) { + *newmed = organ_media[iorg]; + } + return inew; + } + // if here, enters micro matrix. + EGS_Vector x1(x + u*t - + EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz)); + int micr = micros[mict]->isWhere(vg->ix,vg->iy,vg->iz,x1,newmed); + return nmax*mict + micr + nmacro; + } + if (ireg >= 0) { + // in a micro matrix. + int ireg1 = ireg - nmacro; + int mict = ireg1/nmax; + int iloc = ireg1 - mict*nmax; + //return micros[mict]->medium(iloc); + int imic, ix, iy, iz; + EGS_MicroMatrixCluster *micro = micros[mict]; + micro->getIndeces(iloc,imic,ix,iy,iz); + int ilocal = iloc - imic*micros[mict]->nreg; + // now we have to figure out the macro voxel indeces + // in principle one could simply use vg->isWhere(x), but + // this is bound to get us in trouble with roundoff errors. + // we therefore treat the special case where x is in an edge + // voxel of the micro matrix in a special way + int lax, lay, laz; + EGS_Float aux = x.x*vg->dxi; + if (ix > 0 && ix < micros[mict]->vg->nx-1) { + lax = (int) aux; + } + else if (ix == 0) { + lax = (int)(aux+0.5); + } + else { + lax = (int)(aux-0.5); + } + aux = x.y*vg->dyi; + if (iy > 0 && iy < micros[mict]->vg->ny-1) { + lay = (int) aux; + } + else if (iy == 0) { + lay = (int)(aux+0.5); + } + else { + lay = (int)(aux-0.5); + } + aux = x.z*vg->dzi; + if (iz > 0 && iz < micros[mict]->vg->nz-1) { + laz = (int) aux; + } + else if (iz == 0) { + laz = (int)(aux+0.5); + } + else { + laz = (int)(aux-0.5); + } + EGS_Vector x1(x - EGS_Vector(vg->dx*lax,vg->dy*lay,vg->dz*laz)); + int inew = micro->vg->howfarIn(ilocal,ix,iy,iz,x1,u,t,normal); + if (t < 0) { + if (t < -1e-5) { + egsWarning("negative step %g in micro matrix\n",t); + egsWarning("x=(%g,%g,%g) u=(%g,%g,%g)\n",x.x,x.y,x.z, + u.x,u.y,u.z); + egsWarning("ix=%d iy=%d iz=%d\n",ix,iy,iz); + egsWarning("lax=%d lay=%d laz=%d\n",lax,lay,laz); + egsWarning("x1=(%g,%g,%g)\n",x1.x,x1.y,x1.z); + egsFatal("quitting\n"); + } + t = 0; + } + if (inew == ilocal) { + return ireg; + } + if (inew < 0) { + // exiting current micro matrix => entering new + // macro voxel. + // 1. find which one and set new micro region + if (micro->vg->ix < 0) { + if ((--lax) < 0) { + return -1; + } + micro->vg->ix = micro->vg->nx-1; + } + else if (micro->vg->ix >= micro->vg->nx) { + if ((++lax) >= vg->nx) { + return -1; + } + micro->vg->ix = 0; + } + else if (micro->vg->iy < 0) { + if ((--lay) < 0) { + return -1; + } + micro->vg->iy = micro->vg->ny-1; + } + else if (micro->vg->iy >= micro->vg->ny) { + if ((++lay) >= vg->ny) { + return -1; + } + micro->vg->iy = 0; + } + else if (micro->vg->iz < 0) { + if ((--laz) < 0) { + return -1; + } + micro->vg->iz = micro->vg->nz-1; + } + else if (micro->vg->iz >= micro->vg->nz) { + if ((++laz) >= vg->nz) { + return -1; + } + micro->vg->iz = 0; + } + // 2. micro matrix in new macro voxel? + int iorg = organs->getOrgan(laz,lay,lax); + mict = organ_micro[iorg]; + if (mict < 0) { // no. + if (newmed) { + *newmed = organ_media[iorg]; + } + return lax + lay*vg->nx + laz*vg->nxy; + } + inew = micro->vg->ix + micro->vg->iy*micro->vg->nx + + micro->vg->iz*micro->vg->nxy; + int lix = lax%micros[mict]->mx; + int liy = lay%micros[mict]->my; + int liz = laz%micros[mict]->mz; + imic = lix + micros[mict]->mx*liy + micros[mict]->mxy*liz; + } + if (newmed) { + *newmed = micros[mict]->medium(imic,inew); + } + return nmax*mict + inew + nmacro; + } + // outside + int imac = vg->howfarOut(x,u,t,normal); + if (imac < 0) { + return imac; + } + int iorg = organs->getOrgan(vg->iz,vg->iy,vg->ix); + int mict = organ_micro[iorg]; + if (mict < 0) { + if (newmed) { + *newmed = organ_media[iorg]; + } + return imac; + } + EGS_Vector x1(x + u*t); + x1 -= EGS_Vector(vg->dx*vg->ix,vg->dy*vg->iy,vg->dz*vg->iz); + int ilocal = micros[mict]->vg->isWhereFast(x1); + int ix=vg->ix%micros[mict]->mx, + iy=vg->iy%micros[mict]->my, + iz=vg->iz%micros[mict]->mz; + int imic = ix + iy*micros[mict]->mx + iz*micros[mict]->mxy; + if (newmed) { + *newmed = micros[mict]->medium(imic,ilocal); + } + return nmax*mict + imic*micros[mict]->nreg + ilocal + nmacro; + }; + + EGS_Float hownear(int ireg, const EGS_Vector &x) { + if (ireg < nmacro) { + return vg->hownear(ireg,x); + } + ireg -= nmacro; + int mict = ireg/nmax; + int iloc = ireg - mict*nmax; + int imic, ix, iy, iz; + EGS_MicroMatrixCluster *micro = micros[mict]; + micro->getIndeces(iloc,imic,ix,iy,iz); + int ilocal = iloc - imic*micro->nreg; + // now we have to figure out the macro voxel indeces + // in principle one could simply use vg->isWhere(x), but + // this is bound to get us in trouble with roundoff errors. + // we therefore treat the special case where x is in an edge + // voxel of the micro matrix in a special way + int lax, lay, laz; + EGS_Float aux = x.x*vg->dxi; + if (ix > 0 && ix < micro->vg->nx-1) { + lax = (int) aux; + } + else if (ix == 0) { + lax = (int)(aux+0.5); + } + else { + lax = (int)(aux-0.5); + } + aux = x.y*vg->dyi; + if (iy > 0 && iy < micro->vg->ny-1) { + lay = (int) aux; + } + else if (iy == 0) { + lay = (int)(aux+0.5); + } + else { + lay = (int)(aux-0.5); + } + aux = x.z*vg->dzi; + if (iz > 0 && iz < micro->vg->nz-1) { + laz = (int) aux; + } + else if (iz == 0) { + laz = (int)(aux+0.5); + } + else { + laz = (int)(aux-0.5); + } + EGS_Vector x1(x - EGS_Vector(vg->dx*lax,vg->dy*lay,vg->dz*laz)); + return micro->vg->hownearIn(ix,iy,iz,x1); + }; + + int getMaxStep() const { + if (!nmicro) { + return vg->nx+vg->ny+vg->nz+1; + } + int nmx=0, nmy=0, nmz=0; + for (int mict=0; mictnx > nmx) { + nmx = micros[mict]->nx; + } + if (micros[mict]->ny > nmy) { + nmy = micros[mict]->ny; + } + if (micros[mict]->nx > nmz) { + nmx = micros[mict]->nz; + } + } + return vg->nx*nmx+vg->ny*nmy+vg->nz*nmz+1; + }; + + bool isOK() const { + return (vg && organs); + }; + + int getNx() const { + return vg->nx; + }; + int getNy() const { + return vg->ny; + }; + int getNz() const { + return vg->nz; + }; + + const string &getType() const { + return type; + }; + + void printInfo() const; + + //static EGS_VHPGeometry* createGeometry(EGS_Input *); + void setMicros(EGS_Input *); protected: - EGS_VoxelGeometry *vg; - VHP_OrganData *organs; + EGS_VoxelGeometry *vg; + VHP_OrganData *organs; - int organ_media[256]; - int organ_micro[256]; - string organ_names[256]; - EGS_MicroMatrixCluster **micros; - int nmicro; - int nmax, nmacro; + int organ_media[256]; + int organ_micro[256]; + string organ_names[256]; + EGS_MicroMatrixCluster **micros; + int nmicro; + int nmax, nmacro; - static string type; + static string type; - void setup(); + void setup(); - void setMedia(EGS_Input *inp, int nmed, const int *med_ind); + void setMedia(EGS_Input *inp, int nmed, const int *med_ind); }; diff --git a/HEN_HOUSE/egs++/missing.h b/HEN_HOUSE/egs++/missing.h index c22fd7c4d..699508413 100644 --- a/HEN_HOUSE/egs++/missing.h +++ b/HEN_HOUSE/egs++/missing.h @@ -39,103 +39,103 @@ #define MISSING_H_ #ifndef __CHAR_BIT__ -#define __CHAR_BIT__ 8 + #define __CHAR_BIT__ 8 #endif #ifndef __SCHAR_MAX__ -#define __SCHAR_MAX__ 127 + #define __SCHAR_MAX__ 127 #endif #ifndef __SHRT_MAX__ -#define __SHRT_MAX__ 32767 + #define __SHRT_MAX__ 32767 #endif #ifndef __INT_MAX__ -#define __INT_MAX__ 2147483647 + #define __INT_MAX__ 2147483647 #endif #ifndef __LONG_MAX__ -#define __LONG_MAX__ 2147483647L + #define __LONG_MAX__ 2147483647L #endif #ifndef __FLT_MANT_DIG__ -#define __FLT_MANT_DIG__ 24 + #define __FLT_MANT_DIG__ 24 #endif #ifndef __FLT_DIG__ -#define __FLT_DIG__ 6 + #define __FLT_DIG__ 6 #endif #ifndef __FLT_MIN_EXP__ -#define __FLT_MIN_EXP__ (-125) + #define __FLT_MIN_EXP__ (-125) #endif #ifndef __FLT_MAX_EXP__ -#define __FLT_MAX_EXP__ 128 + #define __FLT_MAX_EXP__ 128 #endif #ifndef __FLT_MIN_10_EXP__ -#define __FLT_MIN_10_EXP__ (-125) + #define __FLT_MIN_10_EXP__ (-125) #endif #ifndef __FLT_MAX_10_EXP__ -#define __FLT_MAX_10_EXP__ 128 + #define __FLT_MAX_10_EXP__ 128 #endif #ifndef __FLT_RADIX__ -#define __FLT_RADIX__ 2 + #define __FLT_RADIX__ 2 #endif #ifndef __FLT_MIN__ -#define __FLT_MIN__ 1.17549435e-38F + #define __FLT_MIN__ 1.17549435e-38F #endif #ifndef __FLT_MAX__ -#define __FLT_MAX__ 3.40282347e+38F + #define __FLT_MAX__ 3.40282347e+38F #endif #ifndef __FLT_RADIX__ -#define __FLT_RADIX__ 2 + #define __FLT_RADIX__ 2 #endif #ifndef __FLT_EPSILON__ -#define __FLT_EPSILON__ 1.19209290e-7F + #define __FLT_EPSILON__ 1.19209290e-7F #endif #ifndef __DBL_MANT_DIG__ -#define __DBL_MANT_DIG__ 53 + #define __DBL_MANT_DIG__ 53 #endif #ifndef __DBL_DIG__ -#define __DBL_DIG__ 15 + #define __DBL_DIG__ 15 #endif #ifndef __DBL_MIN_EXP__ -#define __DBL_MIN_EXP__ (-1021) + #define __DBL_MIN_EXP__ (-1021) #endif #ifndef __DBL_MAX_EXP__ -#define __DBL_MAX_EXP__ 1024 + #define __DBL_MAX_EXP__ 1024 #endif #ifndef __DBL_MIN_10_EXP__ -#define __DBL_MIN_10_EXP__ (-1021) + #define __DBL_MIN_10_EXP__ (-1021) #endif #ifndef __DBL_MAX_10_EXP__ -#define __DBL_MAX_10_EXP__ 1024 + #define __DBL_MAX_10_EXP__ 1024 #endif #ifndef __DBL_MIN__ -#define __DBL_MIN__ 2.2250738585072014e-308 + #define __DBL_MIN__ 2.2250738585072014e-308 #endif #ifndef __DBL_MAX__ -#define __DBL_MAX__ 1.7976931348623157e+308 + #define __DBL_MAX__ 1.7976931348623157e+308 #endif #ifndef __DBL_EPSILON__ -#define __DBL_EPSILON__ 2.2204460492503131e-16 + #define __DBL_EPSILON__ 2.2204460492503131e-16 #endif #endif diff --git a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp index 76b655107..2bd369d39 100644 --- a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.cpp @@ -40,32 +40,44 @@ extern "C" { -EGS_CIRCLE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(circle): null input?\n"); return 0; - } - EGS_Float radius; - int err = input->getInput("radius",radius); - if( err ) { - egsWarning("createShape(circle): no 'radius' input\n"); return 0; - } - EGS_Float Ro; err = input->getInput("inner radius",Ro); - if( err ) Ro = 0; - vector pos; - err = input->getInput("midpoint",pos); - if( err ) { pos.clear(); pos.push_back(0); pos.push_back(0); } - else { - if( pos.size() != 2 ) { - egsWarning("createShape(circle): 2 instead of %d inputs expected" - " for keyword 'midpoint'. Reseting midpoint to (0,0)\n", - pos.size()); - pos.clear(); pos.push_back(0); pos.push_back(0); + EGS_CIRCLE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(circle): null input?\n"); + return 0; + } + EGS_Float radius; + int err = input->getInput("radius",radius); + if (err) { + egsWarning("createShape(circle): no 'radius' input\n"); + return 0; + } + EGS_Float Ro; + err = input->getInput("inner radius",Ro); + if (err) { + Ro = 0; } + vector pos; + err = input->getInput("midpoint",pos); + if (err) { + pos.clear(); + pos.push_back(0); + pos.push_back(0); + } + else { + if (pos.size() != 2) { + egsWarning("createShape(circle): 2 instead of %d inputs expected" + " for keyword 'midpoint'. Reseting midpoint to (0,0)\n", + pos.size()); + pos.clear(); + pos.push_back(0); + pos.push_back(0); + } + } + EGS_CircleShape *shape = new EGS_CircleShape(pos[0],pos[1],radius,Ro,"",f); + shape->setName(input); + shape->setTransformation(input); + return shape; } - EGS_CircleShape *shape = new EGS_CircleShape(pos[0],pos[1],radius,Ro,"",f); - shape->setName(input); shape->setTransformation(input); - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.h b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.h index bacc2a1fa..39516014c 100644 --- a/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.h +++ b/HEN_HOUSE/egs++/shapes/egs_circle/egs_circle.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_CIRCLE_DLL -#define EGS_CIRCLE_EXPORT __declspec(dllexport) -#else -#define EGS_CIRCLE_EXPORT __declspec(dllimport) -#endif -#define EGS_CIRCLE_LOCAL + #ifdef BUILD_CIRCLE_DLL + #define EGS_CIRCLE_EXPORT __declspec(dllexport) + #else + #define EGS_CIRCLE_EXPORT __declspec(dllimport) + #endif + #define EGS_CIRCLE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_CIRCLE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_CIRCLE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_CIRCLE_EXPORT -#define EGS_CIRCLE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_CIRCLE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_CIRCLE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_CIRCLE_EXPORT + #define EGS_CIRCLE_LOCAL + #endif #endif @@ -91,16 +91,20 @@ class EGS_CIRCLE_EXPORT EGS_CircleShape : public EGS_SurfaceShape { /*! \brief Conctruct a circle with midpoint given by \a Xo and \a Yo, radius \a R and innder radius \a R_i */ EGS_CircleShape(EGS_Float Xo, EGS_Float Yo, EGS_Float R, EGS_Float R_i = 0, - const string &Name="",EGS_ObjectFactory *f=0) : + const string &Name="",EGS_ObjectFactory *f=0) : EGS_SurfaceShape(Name,f), xo(Xo), yo(Yo), ro(R_i), dr(R-R_i) { otype = "circle"; - if( dr < 0 ) { ro = R; dr = R_i - R; } + if (dr < 0) { + ro = R; + dr = R_i - R; + } A = M_PI*dr*(dr + 2*ro); }; ~EGS_CircleShape() {}; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Float r = ro + dr*sqrt(rndm->getUniform()); - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); return EGS_Vector(xo + r*cphi, yo + r*sphi, 0); }; diff --git a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp index ae9d1f5e1..b675e2903 100644 --- a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.cpp @@ -40,35 +40,45 @@ extern "C" { -EGS_ELLIPSE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(ellipse): null input?\n"); return 0; - } - vector axis; - int err = input->getInput("halfaxis",axis); - if( err ) { - egsWarning("createShape(ellipse): no 'halfaxis' input\n"); return 0; - } - if( axis.size() != 2 ) { - egsWarning("createShape(ellipse): 2 instead of %d inputs expected" - " for keyword 'halfaxis'.\n",axis.size()); return 0; - } - vector pos; - err = input->getInput("midpoint",pos); - if( err ) { pos.clear(); pos.push_back(0); pos.push_back(0); } - else { - if( pos.size() != 2 ) { + EGS_ELLIPSE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(ellipse): null input?\n"); + return 0; + } + vector axis; + int err = input->getInput("halfaxis",axis); + if (err) { + egsWarning("createShape(ellipse): no 'halfaxis' input\n"); + return 0; + } + if (axis.size() != 2) { egsWarning("createShape(ellipse): 2 instead of %d inputs expected" - " for keyword 'midpoint'. Reseting midpoint to (0,0)\n", - pos.size()); - pos.clear(); pos.push_back(0); pos.push_back(0); + " for keyword 'halfaxis'.\n",axis.size()); + return 0; + } + vector pos; + err = input->getInput("midpoint",pos); + if (err) { + pos.clear(); + pos.push_back(0); + pos.push_back(0); } + else { + if (pos.size() != 2) { + egsWarning("createShape(ellipse): 2 instead of %d inputs expected" + " for keyword 'midpoint'. Reseting midpoint to (0,0)\n", + pos.size()); + pos.clear(); + pos.push_back(0); + pos.push_back(0); + } + } + EGS_EllipseShape *shape = new EGS_EllipseShape(pos[0],pos[1], + axis[0],axis[1],"",f); + shape->setName(input); + shape->setTransformation(input); + return shape; } - EGS_EllipseShape *shape = new EGS_EllipseShape(pos[0],pos[1], - axis[0],axis[1],"",f); - shape->setName(input); shape->setTransformation(input); - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.h b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.h index 109705595..240e1521d 100644 --- a/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.h +++ b/HEN_HOUSE/egs++/shapes/egs_ellipse/egs_ellipse.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_ELLIPSE_DLL -#define EGS_ELLIPSE_EXPORT __declspec(dllexport) -#else -#define EGS_ELLIPSE_EXPORT __declspec(dllimport) -#endif -#define EGS_ELLIPSE_LOCAL + #ifdef BUILD_ELLIPSE_DLL + #define EGS_ELLIPSE_EXPORT __declspec(dllexport) + #else + #define EGS_ELLIPSE_EXPORT __declspec(dllimport) + #endif + #define EGS_ELLIPSE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_ELLIPSE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_ELLIPSE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_ELLIPSE_EXPORT -#define EGS_ELLIPSE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_ELLIPSE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_ELLIPSE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_ELLIPSE_EXPORT + #define EGS_ELLIPSE_LOCAL + #endif #endif @@ -90,14 +90,16 @@ class EGS_ELLIPSE_EXPORT EGS_EllipseShape : public EGS_SurfaceShape { /*! \brief Construct an ellipse with midpoint at \a Xo,\a Yo and half axis \a A and \a B. */ EGS_EllipseShape(EGS_Float Xo, EGS_Float Yo, EGS_Float A, EGS_Float B, - const string &Name="",EGS_ObjectFactory *f=0) : + const string &Name="",EGS_ObjectFactory *f=0) : EGS_SurfaceShape(Name,f), xo(Xo), yo(Yo), a(A), b(B) { - otype = "ellipse"; A = M_PI*a*b; + otype = "ellipse"; + A = M_PI*a*b; }; ~EGS_EllipseShape() {}; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Float r = sqrt(rndm->getUniform()); - EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); + EGS_Float cphi, sphi; + rndm->getAzimuth(cphi,sphi); return EGS_Vector(xo + r*a*cphi, yo + r*b*sphi, 0); }; diff --git a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp index fd9d7b717..42ff2b75e 100644 --- a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.cpp @@ -40,38 +40,44 @@ extern "C" { -EGS_EXTENDED_SHAPE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(extended shape): null input?\n"); return 0; - } - vector h; - int err = input->getInput("extension",h); - if( err || h.size() != 2 ) { - egsWarning("createShape(extended shape): wrong/missing " - "'extension' input\n"); return 0; - } - EGS_Input *ishape = input->takeInputItem("shape",false); - EGS_BaseShape *shape; - if( ishape ) { - shape = EGS_BaseShape::createShape(ishape); delete ishape; - } - if( !shape ) { - string shape_name; int err = input->getInput("shape name",shape_name); - if( err ) { - egsWarning("createShape(extended shape): no inline shape definition" - " and no 'shape name' keyword\n"); return 0; + EGS_EXTENDED_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(extended shape): null input?\n"); + return 0; } - shape = EGS_BaseShape::getShape(shape_name); - if( !shape ) { - egsWarning("createShape(extended shape): no shape named %s " - "exists\n",shape_name.c_str()); + vector h; + int err = input->getInput("extension",h); + if (err || h.size() != 2) { + egsWarning("createShape(extended shape): wrong/missing " + "'extension' input\n"); return 0; } + EGS_Input *ishape = input->takeInputItem("shape",false); + EGS_BaseShape *shape; + if (ishape) { + shape = EGS_BaseShape::createShape(ishape); + delete ishape; + } + if (!shape) { + string shape_name; + int err = input->getInput("shape name",shape_name); + if (err) { + egsWarning("createShape(extended shape): no inline shape definition" + " and no 'shape name' keyword\n"); + return 0; + } + shape = EGS_BaseShape::getShape(shape_name); + if (!shape) { + egsWarning("createShape(extended shape): no shape named %s " + "exists\n",shape_name.c_str()); + return 0; + } + } + EGS_ExtendedShape *s = new EGS_ExtendedShape(shape,h[0],h[1],"",f); + s->setName(input); + s->setTransformation(input); + return s; } - EGS_ExtendedShape *s = new EGS_ExtendedShape(shape,h[0],h[1],"",f); - s->setName(input); s->setTransformation(input); - return s; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.h b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.h index 1a15f877d..b90ded841 100644 --- a/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.h +++ b/HEN_HOUSE/egs++/shapes/egs_extended_shape/egs_extended_shape.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_EXTENDED_SHAPE_DLL -#define EGS_EXTENDED_SHAPE_EXPORT __declspec(dllexport) -#else -#define EGS_EXTENDED_SHAPE_EXPORT __declspec(dllimport) -#endif -#define EGS_EXTENDED_SHAPE_LOCAL + #ifdef BUILD_EXTENDED_SHAPE_DLL + #define EGS_EXTENDED_SHAPE_EXPORT __declspec(dllexport) + #else + #define EGS_EXTENDED_SHAPE_EXPORT __declspec(dllimport) + #endif + #define EGS_EXTENDED_SHAPE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_EXTENDED_SHAPE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_EXTENDED_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_EXTENDED_SHAPE_EXPORT -#define EGS_EXTENDED_SHAPE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_EXTENDED_SHAPE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_EXTENDED_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_EXTENDED_SHAPE_EXPORT + #define EGS_EXTENDED_SHAPE_LOCAL + #endif #endif @@ -89,12 +89,16 @@ class EGS_EXTENDED_SHAPE_EXPORT EGS_ExtendedShape : public EGS_BaseShape { public: EGS_ExtendedShape(EGS_BaseShape *Shape, EGS_Float H1, EGS_Float H2, - const string &Name="",EGS_ObjectFactory *f=0) : + const string &Name="",EGS_ObjectFactory *f=0) : EGS_BaseShape(Name,f), shape(Shape), h1(H1), h2(H2), dh(h2-h1) { - if( shape ) { + if (shape) { shape->ref(); - otype = "Extended "; otype += shape->getObjectType(); - } else otype = "Invalid ExtendedShape"; + otype = "Extended "; + otype += shape->getObjectType(); + } + else { + otype = "Invalid ExtendedShape"; + } }; ~EGS_ExtendedShape() { EGS_Object::deleteObject(shape); diff --git a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp index 93d1f6dd8..810b89a34 100644 --- a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.cpp @@ -40,43 +40,52 @@ extern "C" { -EGS_GAUSSIAN_SHAPE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(circle): null input?\n"); return 0; - } - vector sigma; - int err = input->getInput("sigma",sigma); - if( err ) { - egsWarning("createShape(gaussian shape): no 'sigma' input\n"); return 0; - } - EGS_Input *ishape = input->takeInputItem("shape",false); - EGS_BaseShape *shape = 0; - if( ishape ) { - shape = EGS_BaseShape::createShape(ishape); delete ishape; - } - if( !shape ) { - string shape_name; int err = input->getInput("shape name",shape_name); - if( err ) { - egsWarning("createShape(gaussian shape): no inline shape definition" - " and no 'shape name' keyword\n"); return 0; + EGS_GAUSSIAN_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(circle): null input?\n"); + return 0; } - shape = EGS_BaseShape::getShape(shape_name); - if( !shape ) { - egsWarning("createShape(gaussian shape): no shape named %s " - "exists\n",shape_name.c_str()); + vector sigma; + int err = input->getInput("sigma",sigma); + if (err) { + egsWarning("createShape(gaussian shape): no 'sigma' input\n"); return 0; } + EGS_Input *ishape = input->takeInputItem("shape",false); + EGS_BaseShape *shape = 0; + if (ishape) { + shape = EGS_BaseShape::createShape(ishape); + delete ishape; + } + if (!shape) { + string shape_name; + int err = input->getInput("shape name",shape_name); + if (err) { + egsWarning("createShape(gaussian shape): no inline shape definition" + " and no 'shape name' keyword\n"); + return 0; + } + shape = EGS_BaseShape::getShape(shape_name); + if (!shape) { + egsWarning("createShape(gaussian shape): no shape named %s " + "exists\n",shape_name.c_str()); + return 0; + } + } + EGS_GaussianShape *s; + if (sigma.size() == 1) { + s = new EGS_GaussianShape(shape,sigma[0],0,0,"",f); + } + else if (sigma.size() == 2) { + s = new EGS_GaussianShape(shape,sigma[0],sigma[1],0,"",f); + } + else { + s = new EGS_GaussianShape(shape,sigma[0],sigma[1],sigma[2],"",f); + } + s->setName(input); + s->setTransformation(input); + return s; } - EGS_GaussianShape *s; - if( sigma.size() == 1 ) - s = new EGS_GaussianShape(shape,sigma[0],0,0,"",f); - else if( sigma.size() == 2 ) - s = new EGS_GaussianShape(shape,sigma[0],sigma[1],0,"",f); - else - s = new EGS_GaussianShape(shape,sigma[0],sigma[1],sigma[2],"",f); - s->setName(input); s->setTransformation(input); - return s; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.h b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.h index a91d395b6..440853ec3 100644 --- a/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.h +++ b/HEN_HOUSE/egs++/shapes/egs_gaussian_shape/egs_gaussian_shape.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_GAUSSIAN_SHAPE_DLL -#define EGS_GAUSSIAN_SHAPE_EXPORT __declspec(dllexport) -#else -#define EGS_GAUSSIAN_SHAPE_EXPORT __declspec(dllimport) -#endif -#define EGS_GAUSSIAN_SHAPE_LOCAL + #ifdef BUILD_GAUSSIAN_SHAPE_DLL + #define EGS_GAUSSIAN_SHAPE_EXPORT __declspec(dllexport) + #else + #define EGS_GAUSSIAN_SHAPE_EXPORT __declspec(dllimport) + #endif + #define EGS_GAUSSIAN_SHAPE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_GAUSSIAN_SHAPE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_GAUSSIAN_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_GAUSSIAN_SHAPE_EXPORT -#define EGS_GAUSSIAN_SHAPE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_GAUSSIAN_SHAPE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_GAUSSIAN_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_GAUSSIAN_SHAPE_EXPORT + #define EGS_GAUSSIAN_SHAPE_LOCAL + #endif #endif @@ -90,34 +90,56 @@ class EGS_GAUSSIAN_SHAPE_EXPORT EGS_GaussianShape : public EGS_BaseShape { public: EGS_GaussianShape(EGS_BaseShape *Shape, EGS_Float sx, EGS_Float sy, - EGS_Float sz, const string &Name="",EGS_ObjectFactory *f=0) : + EGS_Float sz, const string &Name="",EGS_ObjectFactory *f=0) : EGS_BaseShape(Name,f), shape(Shape), sig_x(sx), sig_y(sy), sig_z(sz) { - if( shape ) { - shape->ref(); otype = shape->getObjectType(); + if (shape) { + shape->ref(); + otype = shape->getObjectType(); otype += "with Gaussian ditribution"; - if( sig_x < 0 ) sig_x = -sig_x*0.4246609; - if( sig_y < 0 ) sig_y = -sig_y*0.4246609; - if( sig_z < 0 ) sig_z = -sig_z*0.4246609; - } else otype = "Invalid GaussianShape"; + if (sig_x < 0) { + sig_x = -sig_x*0.4246609; + } + if (sig_y < 0) { + sig_y = -sig_y*0.4246609; + } + if (sig_z < 0) { + sig_z = -sig_z*0.4246609; + } + } + else { + otype = "Invalid GaussianShape"; + } }; ~EGS_GaussianShape() { EGS_Object::deleteObject(shape); }; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Vector v(shape->getPoint(rndm)); - if( sig_x > 0 ) v.x += sig_x*rndm->getGaussian(); - if( sig_y > 0 ) v.y += sig_y*rndm->getGaussian(); - if( sig_z > 0 ) v.z += sig_z*rndm->getGaussian(); + if (sig_x > 0) { + v.x += sig_x*rndm->getGaussian(); + } + if (sig_y > 0) { + v.y += sig_y*rndm->getGaussian(); + } + if (sig_z > 0) { + v.z += sig_z*rndm->getGaussian(); + } return v; }; - bool supportsDirectionMethod() const { return true; }; + bool supportsDirectionMethod() const { + return true; + }; void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; EGS_Vector x = getPoint(rndm); - u = x - xo; EGS_Float d2i = 1/u.length2(), di = sqrt(d2i); - u *= di; wt = 1; //wt = A*fabs(u.z)*d2i; - if( T ) T->rotate(u); + u = x - xo; + EGS_Float d2i = 1/u.length2(), di = sqrt(d2i); + u *= di; + wt = 1; //wt = A*fabs(u.z)*d2i; + if (T) { + T->rotate(u); + } }; protected: diff --git a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp index e3baf7d7d..47349105a 100644 --- a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.cpp @@ -39,46 +39,57 @@ #include "egs_functions.h" EGS_LineShape::EGS_LineShape(const vector &points, - const string &Name, EGS_ObjectFactory *f) : EGS_BaseShape(Name,f) { - int np = points.size(); n = np/2; - if( n <= 1 ) { n = 0; return; } - x = new EGS_Float[n]; y = new EGS_Float[n]; + const string &Name, EGS_ObjectFactory *f) : EGS_BaseShape(Name,f) { + int np = points.size(); + n = np/2; + if (n <= 1) { + n = 0; + return; + } + x = new EGS_Float[n]; + y = new EGS_Float[n]; EGS_Float *w = new EGS_Float [n-1]; - for(int j=0; j 0 ) { + for (int j=0; j 0) { EGS_Float ax = x[j]-x[j-1], ay = y[j]-y[j-1]; w[j-1] = sqrt(ax*ax+ay*ay); } } - table = new EGS_AliasTable(n-1,x,w,0); otype = "line"; + table = new EGS_AliasTable(n-1,x,w,0); + otype = "line"; } extern "C" { -EGS_LINE_SHAPE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(line): null input?\n"); return 0; - } - vector points; - int err = input->getInput("points",points); - if( err ) { - egsWarning("createShape(line): no 'points' input\n"); return 0; - } - int np = points.size(); - if( (np%2) != 0 ) { - egsWarning("createShape(line): you must input an even number of" - " floating numbers\n"); return 0; - } - if( np < 4 ) { - egsWarning("createShape(line): you must input at least 2 2D points" - " to form a line\n"); - return 0; + EGS_LINE_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(line): null input?\n"); + return 0; + } + vector points; + int err = input->getInput("points",points); + if (err) { + egsWarning("createShape(line): no 'points' input\n"); + return 0; + } + int np = points.size(); + if ((np%2) != 0) { + egsWarning("createShape(line): you must input an even number of" + " floating numbers\n"); + return 0; + } + if (np < 4) { + egsWarning("createShape(line): you must input at least 2 2D points" + " to form a line\n"); + return 0; + } + EGS_LineShape *shape = new EGS_LineShape(points,"",f); + shape->setName(input); + shape->setTransformation(input); + return shape; } - EGS_LineShape *shape = new EGS_LineShape(points,"",f); - shape->setName(input); shape->setTransformation(input); - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.h b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.h index 84bb362ef..b78bc298e 100644 --- a/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.h +++ b/HEN_HOUSE/egs++/shapes/egs_line_shape/egs_line_shape.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_LINE_SHAPE_DLL -#define EGS_LINE_SHAPE_EXPORT __declspec(dllexport) -#else -#define EGS_LINE_SHAPE_EXPORT __declspec(dllimport) -#endif -#define EGS_LINE_SHAPE_LOCAL + #ifdef BUILD_LINE_SHAPE_DLL + #define EGS_LINE_SHAPE_EXPORT __declspec(dllexport) + #else + #define EGS_LINE_SHAPE_EXPORT __declspec(dllimport) + #endif + #define EGS_LINE_SHAPE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_LINE_SHAPE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_LINE_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_LINE_SHAPE_EXPORT -#define EGS_LINE_SHAPE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_LINE_SHAPE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_LINE_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_LINE_SHAPE_EXPORT + #define EGS_LINE_SHAPE_LOCAL + #endif #endif @@ -85,15 +85,18 @@ class EGS_LINE_SHAPE_EXPORT EGS_LineShape : public EGS_BaseShape { public: EGS_LineShape(const vector &points, const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); ~EGS_LineShape() { - if( n > 0 ) { - delete table; delete [] x; delete [] y; + if (n > 0) { + delete table; + delete [] x; + delete [] y; } }; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { int j = table->sampleBin(rndm); - EGS_Float eta = rndm->getUniform(); EGS_Float eta1 = 1 - eta; + EGS_Float eta = rndm->getUniform(); + EGS_Float eta1 = 1 - eta; return EGS_Vector(x[j]*eta+x[j+1]*eta1,y[j]*eta+y[j+1]*eta1,0); }; diff --git a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp index fe8fcad34..7c6059f61 100644 --- a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.cpp @@ -41,103 +41,138 @@ #include "egs_math.h" EGS_TriangleShape::EGS_TriangleShape(const vector &points, - const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { - xo = points[0]; yo = points[1]; - ax = points[2] - xo; ay = points[3] - yo; - bx = points[4] - xo; by = points[5] - yo; + const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { + xo = points[0]; + yo = points[1]; + ax = points[2] - xo; + ay = points[3] - yo; + bx = points[4] - xo; + by = points[5] - yo; A = 0.5*fabs(ax*by-ay*bx); } EGS_TriangleShape::EGS_TriangleShape(const EGS_Float *points, - const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { - xo = points[0]; yo = points[1]; - ax = points[2] - xo; ay = points[3] - yo; - bx = points[4] - xo; by = points[5] - yo; + const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { + xo = points[0]; + yo = points[1]; + ax = points[2] - xo; + ay = points[3] - yo; + bx = points[4] - xo; + by = points[5] - yo; A = 0.5*fabs(ax*by-ay*bx); } EGS_PolygonShape::EGS_PolygonShape(const vector &points, - const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { - int np = points.size(); n = np/2; + const string &Name, EGS_ObjectFactory *f) : EGS_SurfaceShape(Name,f) { + int np = points.size(); + n = np/2; EGS_Float auxx = points[np-2] - points[0]; EGS_Float auxy = points[np-1] - points[1]; EGS_Float *xc, *yc; - if( auxx*auxx + auxy*auxy > 1e-8 ) n++; - xc = new EGS_Float [n]; yc = new EGS_Float [n]; + if (auxx*auxx + auxy*auxy > 1e-8) { + n++; + } + xc = new EGS_Float [n]; + yc = new EGS_Float [n]; vector p1; - for(int j=0; j np/2 ) { - xc[n-1] = points[0]; yc[n-1] = points[1]; + if (n > np/2) { + xc[n-1] = points[0]; + yc[n-1] = points[1]; p1.push_back(EGS_2DVector(xc[n-1],yc[n-1])); } EGS_2DPolygon pol(p1); - int ntr = 0; triangle = new EGS_TriangleShape* [n-3]; np = n; + int ntr = 0; + triangle = new EGS_TriangleShape* [n-3]; + np = n; EGS_Float p_tmp[6]; - while ( np > 3 ) { - for(int i=0; i 3) { + for (int i=0; i p2; - for(int k=0; k<3; k++) { - p_tmp[2*k] = xc[i+k]; p_tmp[2*k+1] = yc[i+k]; + if (pol.isInside(aux)) { + bool is_ok = true; + vector p2; + for (int k=0; k<3; k++) { + p_tmp[2*k] = xc[i+k]; + p_tmp[2*k+1] = yc[i+k]; p2.push_back(EGS_2DVector(xc[i+k],yc[i+k])); } EGS_2DPolygon tri(p2); - for(int j=0; j i+2 ) { + for (int j=0; j i+2) { EGS_2DVector tmp(xc[j],yc[j]); - if( tri.isInside(tmp) ) { is_ok = false; break; } + if (tri.isInside(tmp)) { + is_ok = false; + break; + } } } - if( is_ok ) { + if (is_ok) { EGS_TriangleShape *t = new EGS_TriangleShape(p_tmp); triangle[ntr++] = t; - for(int j=i+1; jarea(); A += yc[i]; } + for (int i=0; iarea(); + A += yc[i]; + } table = new EGS_AliasTable(ntr,xc,yc,0); - delete [] xc; delete [] yc; + delete [] xc; + delete [] yc; } extern "C" { -EGS_POLYGON_SHAPE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(polygon): null input?\n"); return 0; - } - vector points; - int err = input->getInput("points",points); - if( err ) { - egsWarning("createShape(polygon): no 'points' input\n"); return 0; - } - int np = points.size(); - if( (np%2) != 0 ) { - egsWarning("createShape(polygon): you must input an even number of" - " floating numbers\n"); return 0; - } - if( np < 6 ) { - egsWarning("createShape(polygon): you must input at least 3 2D points" - " to form a polygon\n"); - return 0; + EGS_POLYGON_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(polygon): null input?\n"); + return 0; + } + vector points; + int err = input->getInput("points",points); + if (err) { + egsWarning("createShape(polygon): no 'points' input\n"); + return 0; + } + int np = points.size(); + if ((np%2) != 0) { + egsWarning("createShape(polygon): you must input an even number of" + " floating numbers\n"); + return 0; + } + if (np < 6) { + egsWarning("createShape(polygon): you must input at least 3 2D points" + " to form a polygon\n"); + return 0; + } + EGS_BaseShape *shape; + if (np == 6) { + shape = new EGS_TriangleShape(points,"",f); + } + else { + shape = new EGS_PolygonShape(points,"",f); + } + shape->setName(input); + shape->setTransformation(input); + return shape; } - EGS_BaseShape *shape; - if( np == 6 ) shape = new EGS_TriangleShape(points,"",f); - else shape = new EGS_PolygonShape(points,"",f); - shape->setName(input); shape->setTransformation(input); - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.h b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.h index 6917fcdc8..fd6315fe2 100644 --- a/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.h +++ b/HEN_HOUSE/egs++/shapes/egs_polygon_shape/egs_polygon_shape.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_POLYGON_SHAPE_DLL -#define EGS_POLYGON_SHAPE_EXPORT __declspec(dllexport) -#else -#define EGS_POLYGON_SHAPE_EXPORT __declspec(dllimport) -#endif -#define EGS_POLYGON_SHAPE_LOCAL + #ifdef BUILD_POLYGON_SHAPE_DLL + #define EGS_POLYGON_SHAPE_EXPORT __declspec(dllexport) + #else + #define EGS_POLYGON_SHAPE_EXPORT __declspec(dllimport) + #endif + #define EGS_POLYGON_SHAPE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_POLYGON_SHAPE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_POLYGON_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_POLYGON_SHAPE_EXPORT -#define EGS_POLYGON_SHAPE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_POLYGON_SHAPE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_POLYGON_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_POLYGON_SHAPE_EXPORT + #define EGS_POLYGON_SHAPE_LOCAL + #endif #endif @@ -75,13 +75,14 @@ class EGS_POLYGON_SHAPE_EXPORT EGS_TriangleShape : public EGS_SurfaceShape { public: EGS_TriangleShape(const vector &points, const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); EGS_TriangleShape(const EGS_Float *points, const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); ~EGS_TriangleShape() {}; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Float eta_a = sqrt(rndm->getUniform()); - EGS_Float eta_b = eta_a*rndm->getUniform(); eta_a = 1 - eta_a; + EGS_Float eta_b = eta_a*rndm->getUniform(); + eta_a = 1 - eta_a; return EGS_Vector(xo + ax*eta_a + bx*eta_b, yo + ay*eta_a + by*eta_b, 0); @@ -118,10 +119,12 @@ class EGS_POLYGON_SHAPE_EXPORT EGS_PolygonShape : public EGS_SurfaceShape { public: EGS_PolygonShape(const vector &points, const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); ~EGS_PolygonShape() { - if( n > 0 ) { - for(int j=0; j 0) { + for (int j=0; j xmax ) { tmp = xmax; xmax = xmin; xmin = tmp; } - if( ymin > ymax ) { tmp = ymax; ymax = ymin; ymin = tmp; } - if( xmin_i > xmax_i ) { tmp = xmax_i; xmax_i = xmin_i; xmin_i = tmp; } - if( ymin_i > ymax_i ) { tmp = ymax_i; ymax_i = ymin_i; ymin_i = tmp; } - if( xmin_i < xmin || ymin_i < ymin || xmax_i > xmax || ymax_i > ymax ) { - valid = false; return; + if (xmin > xmax) { + tmp = xmax; + xmax = xmin; + xmin = tmp; + } + if (ymin > ymax) { + tmp = ymax; + ymax = ymin; + ymin = tmp; + } + if (xmin_i > xmax_i) { + tmp = xmax_i; + xmax_i = xmin_i; + xmin_i = tmp; + } + if (ymin_i > ymax_i) { + tmp = ymax_i; + ymax_i = ymin_i; + ymin_i = tmp; + } + if (xmin_i < xmin || ymin_i < ymin || xmax_i > xmax || ymax_i > ymax) { + valid = false; + return; } r[0] = new EGS_RectangleShape(xmin,xmin_i,ymin,ymax); r[1] = new EGS_RectangleShape(xmax_i,xmax,ymin,ymax); @@ -59,7 +76,9 @@ EGS_RectangularRing::EGS_RectangularRing(EGS_Float xmin, EGS_Float xmax, p[2] = (xmax_i - xmin_i)*(ymin_i - ymin); p[3] = (xmax_i - xmin_i)*(ymax - ymax_i); A = p[0] + p[1] + p[2] + p[3]; - p[0] /= A; p[1] = p[1]/A + p[0]; p[2] = p[2]/A + p[1]; + p[0] /= A; + p[1] = p[1]/A + p[0]; + p[2] = p[2]/A + p[1]; p[3] = 1.1; otype = "rectangular ring"; @@ -67,41 +86,57 @@ EGS_RectangularRing::EGS_RectangularRing(EGS_Float xmin, EGS_Float xmax, } EGS_RectangularRing::~EGS_RectangularRing() { - if( valid ) { delete r[0]; delete r[1]; delete r[2]; delete r[3]; }; + if (valid) { + delete r[0]; + delete r[1]; + delete r[2]; + delete r[3]; + }; } extern "C" { -EGS_RECTANGLE_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(rectangle): null input?\n"); return 0; + EGS_RECTANGLE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + if (!input) { + egsWarning("createShape(rectangle): null input?\n"); + return 0; + } + vector pos; + int err = input->getInput("rectangle",pos); + if (err) { + egsWarning("createShape(rectangle): no 'rectangle' input\n"); + return 0; + } + if (pos.size() != 4) { + egsWarning("createShape(rectangle): found only %d inputs instead" + " of 4\n"); + return 0; + } + EGS_BaseShape *shape; + vector posi; + err = input->getInput("inner rectangle",posi); + if (!err && posi.size() == 4) { + EGS_RectangularRing *s = new EGS_RectangularRing(pos[0],pos[2],pos[1], + pos[3],posi[0],posi[2],posi[1],posi[3],"",f); + if (!s->isValid()) { + egsWarning("createShape(rectangle): your input did not result in" + " a valid \"rectangular ring\"\n"); + delete s; + } + else { + shape = s; + } + } + else { + shape = new EGS_RectangleShape(pos[0],pos[2],pos[1],pos[3],"",f); + } + if (shape) { + shape->setName(input); + shape->setTransformation(input); + } + return shape; } - vector pos; - int err = input->getInput("rectangle",pos); - if( err ) { - egsWarning("createShape(rectangle): no 'rectangle' input\n"); return 0; - } - if( pos.size() != 4 ) { - egsWarning("createShape(rectangle): found only %d inputs instead" - " of 4\n"); return 0; - } - EGS_BaseShape *shape; - vector posi; - err = input->getInput("inner rectangle",posi); - if( !err && posi.size() == 4 ) { - EGS_RectangularRing *s = new EGS_RectangularRing(pos[0],pos[2],pos[1], - pos[3],posi[0],posi[2],posi[1],posi[3],"",f); - if( !s->isValid() ) { - egsWarning("createShape(rectangle): your input did not result in" - " a valid \"rectangular ring\"\n"); - delete s; - } else shape = s; - } - else shape = new EGS_RectangleShape(pos[0],pos[2],pos[1],pos[3],"",f); - if( shape ) { shape->setName(input); shape->setTransformation(input); } - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.h b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.h index 3db5a41f3..73b0afd0a 100644 --- a/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.h +++ b/HEN_HOUSE/egs++/shapes/egs_rectangle/egs_rectangle.h @@ -42,22 +42,22 @@ #ifdef WIN32 -#ifdef BUILD_RECTANGLE_DLL -#define EGS_RECTANGLE_EXPORT __declspec(dllexport) -#else -#define EGS_RECTANGLE_EXPORT __declspec(dllimport) -#endif -#define EGS_RECTANGLE_LOCAL + #ifdef BUILD_RECTANGLE_DLL + #define EGS_RECTANGLE_EXPORT __declspec(dllexport) + #else + #define EGS_RECTANGLE_EXPORT __declspec(dllimport) + #endif + #define EGS_RECTANGLE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_RECTANGLE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_RECTANGLE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_RECTANGLE_EXPORT -#define EGS_RECTANGLE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_RECTANGLE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_RECTANGLE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_RECTANGLE_EXPORT + #define EGS_RECTANGLE_LOCAL + #endif #endif @@ -89,14 +89,24 @@ class EGS_RECTANGLE_EXPORT EGS_RectangleShape : public EGS_SurfaceShape { public: EGS_RectangleShape(EGS_Float Xmin, EGS_Float Xmax, EGS_Float Ymin, - EGS_Float Ymax, const string &Name="",EGS_ObjectFactory *f=0) : + EGS_Float Ymax, const string &Name="",EGS_ObjectFactory *f=0) : EGS_SurfaceShape(Name,f), xmin(Xmin), xmax(Xmax), ymin(Ymin), ymax(Ymax) { EGS_Float tmp; - if( xmin > xmax ) { tmp = xmax; xmax = xmin; xmin = tmp; } - if( ymin > ymax ) { tmp = ymax; ymax = ymin; ymin = tmp; } - dx = xmax - xmin; dy = ymax - ymin; - otype = "rectangle"; A = dx*dy; + if (xmin > xmax) { + tmp = xmax; + xmax = xmin; + xmin = tmp; + } + if (ymin > ymax) { + tmp = ymax; + ymax = ymin; + ymin = tmp; + } + dx = xmax - xmin; + dy = ymax - ymin; + otype = "rectangle"; + A = dx*dy; }; ~EGS_RectangleShape() {}; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { @@ -122,19 +132,24 @@ class EGS_RECTANGLE_EXPORT EGS_RectangularRing : public EGS_SurfaceShape { public: EGS_RectangularRing(EGS_Float Xmin, EGS_Float Xmax, EGS_Float Ymin, - EGS_Float Ymax, EGS_Float Xmin_i, EGS_Float Xmax_i, EGS_Float Ymin_i, - EGS_Float Ymax_i, const string &Name="",EGS_ObjectFactory *f=0); + EGS_Float Ymax, EGS_Float Xmin_i, EGS_Float Xmax_i, EGS_Float Ymin_i, + EGS_Float Ymax_i, const string &Name="",EGS_ObjectFactory *f=0); ~EGS_RectangularRing(); - bool isValid() const { return valid; }; + bool isValid() const { + return valid; + }; EGS_Vector getPoint(EGS_RandomGenerator *rndm) { EGS_Float eta = rndm->getUniform(); - int j=0; while( eta > p[j] ) j++; + int j=0; + while (eta > p[j]) { + j++; + } return r[j]->getPoint(rndm); }; protected: - EGS_RectangleShape* r[4]; + EGS_RectangleShape *r[4]; EGS_Float p[4]; bool valid; diff --git a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp index b3e488db9..3775bbc22 100644 --- a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.cpp @@ -39,80 +39,94 @@ #include "egs_functions.h" EGS_ShapeCollection::EGS_ShapeCollection(const vector &Shapes, - const vector &Probs, const string &Name, EGS_ObjectFactory *f) : + const vector &Probs, const string &Name, EGS_ObjectFactory *f) : EGS_BaseShape(Name,f), nshape(0) { int n1 = Shapes.size(), n2 = Probs.size(); - if( n1 < 2 || n2 < 2 || n1 != n2 ) { + if (n1 < 2 || n2 < 2 || n1 != n2) { egsWarning("EGS_ShapeCollection::EGS_ShapeCollection: invalid input\n"); return; } nshape = n1; shapes = new EGS_BaseShape* [nshape]; EGS_Float *dum = new EGS_Float [nshape], *p = new EGS_Float [nshape]; - for(int j=0; jref(); p[j] = Probs[j]; dum[j] = 1; + for (int j=0; jref(); + p[j] = Probs[j]; + dum[j] = 1; } table = new EGS_AliasTable(nshape,dum,p,0); - delete [] dum; delete [] p; + delete [] dum; + delete [] p; } extern "C" { -EGS_SHAPE_COLLECTION_EXPORT EGS_BaseShape* createShape(EGS_Input *input, - EGS_ObjectFactory *f) { - if( !input ) { - egsWarning("createShape(shape collection): null input?\n"); return 0; - } - vector shapes; - vector probs; - EGS_Input *ishape; - while( (ishape = input->takeInputItem("shape",false)) ) { - EGS_BaseShape *shape = EGS_BaseShape::createShape(ishape); - if( !shape ) - egsWarning("createShape(shape collection): got null shape\n"); - else shapes.push_back(shape); - delete ishape; - } - vector snames; int err = input->getInput("shape names",snames); - if( !err && snames.size() > 0 ) { - for(unsigned int j=0; jgetInput("probabilities",probs); - bool ok = true; - if( err ) { - egsWarning("createShape(shape collection): no 'probabilities' input\n"); - ok = false; - } - if( shapes.size() < 2 ) { - egsWarning("createShape(shape collection): at least 2 shapes are " - "needed for a shape collection, you defined %s\n",shapes.size()); - ok = false; - } - if( shapes.size() != probs.size() ) { - egsWarning("createShape(shape collection): the number of shapes (%d)" - " is not the same as the number of input probabilities (%d)\n"); - ok = false; - } - for(unsigned int i=0; i shapes; + vector probs; + EGS_Input *ishape; + while ((ishape = input->takeInputItem("shape",false))) { + EGS_BaseShape *shape = EGS_BaseShape::createShape(ishape); + if (!shape) { + egsWarning("createShape(shape collection): got null shape\n"); + } + else { + shapes.push_back(shape); + } + delete ishape; } + vector snames; + int err = input->getInput("shape names",snames); + if (!err && snames.size() > 0) { + for (unsigned int j=0; jgetInput("probabilities",probs); + bool ok = true; + if (err) { + egsWarning("createShape(shape collection): no 'probabilities' input\n"); + ok = false; + } + if (shapes.size() < 2) { + egsWarning("createShape(shape collection): at least 2 shapes are " + "needed for a shape collection, you defined %s\n",shapes.size()); + ok = false; + } + if (shapes.size() != probs.size()) { + egsWarning("createShape(shape collection): the number of shapes (%d)" + " is not the same as the number of input probabilities (%d)\n"); + ok = false; + } + for (unsigned int i=0; isetName(input); + s->setTransformation(input); + return s; } - if( !ok ) { - for(unsigned int j=0; jsetName(input); s->setTransformation(input); - return s; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.h b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.h index 33db15821..9c655c45e 100644 --- a/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.h +++ b/HEN_HOUSE/egs++/shapes/egs_shape_collection/egs_shape_collection.h @@ -43,22 +43,22 @@ #ifdef WIN32 -#ifdef BUILD_SHAPE_COLLECTION_DLL -#define EGS_SHAPE_COLLECTION_EXPORT __declspec(dllexport) -#else -#define EGS_SHAPE_COLLECTION_EXPORT __declspec(dllimport) -#endif -#define EGS_SHAPE_COLLECTION_LOCAL + #ifdef BUILD_SHAPE_COLLECTION_DLL + #define EGS_SHAPE_COLLECTION_EXPORT __declspec(dllexport) + #else + #define EGS_SHAPE_COLLECTION_EXPORT __declspec(dllimport) + #endif + #define EGS_SHAPE_COLLECTION_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_SHAPE_COLLECTION_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_SHAPE_COLLECTION_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_SHAPE_COLLECTION_EXPORT -#define EGS_SHAPE_COLLECTION_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_SHAPE_COLLECTION_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_SHAPE_COLLECTION_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_SHAPE_COLLECTION_EXPORT + #define EGS_SHAPE_COLLECTION_LOCAL + #endif #endif @@ -97,12 +97,15 @@ class EGS_SHAPE_COLLECTION_EXPORT EGS_ShapeCollection : public EGS_BaseShape { public: EGS_ShapeCollection(const vector &Shapes, - const vector &Probs, const string &Name="", - EGS_ObjectFactory *f=0); + const vector &Probs, const string &Name="", + EGS_ObjectFactory *f=0); ~EGS_ShapeCollection() { - if( nshape > 0 ) { - for(int j=0; j 0) { + for (int j=0; jsupportsDirectionMethod() ) return false; + for (int j=0; jsupportsDirectionMethod()) { + return false; + } } return true; }; EGS_Float area() const { EGS_Float A = 0; - for(int j=0; jarea(); + for (int j=0; jarea(); + } return A; }; void getPointSourceDirection(const EGS_Vector &Xo, - EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { + EGS_RandomGenerator *rndm, EGS_Vector &u, EGS_Float &wt) { EGS_Vector xo = T ? Xo*(*T) : Xo; int j = table->sampleBin(rndm); shapes[j]->getPointSourceDirection(xo,rndm,u,wt); - if( T ) T->rotate(u); + if (T) { + T->rotate(u); + } }; protected: diff --git a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp index f1a422c76..35c81e8b3 100644 --- a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp +++ b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.cpp @@ -42,100 +42,143 @@ using namespace std; void EGS_VoxelizedShape::EGS_VoxelizedShapeFormat0(const char *fname, - const string &Name,EGS_ObjectFactory *f) { - prob=0; xpos=0; ypos=0; zpos=0; map=0; nx=0; ny=0; nz=0; nxy=0; nreg=0; type=-1; + const string &Name,EGS_ObjectFactory *f) { + prob=0; + xpos=0; + ypos=0; + zpos=0; + map=0; + nx=0; + ny=0; + nz=0; + nxy=0; + nreg=0; + type=-1; const static char *func = "EGS_VoxelizedShape::EGS_VoxelizedShape"; otype = "voxelized_shape"; - if( !fname ) return; + if (!fname) { + return; + } ifstream data(fname,ios::binary); - if( !data ) { + if (!data) { egsWarning("%s: failed to open file %s\n",func,fname); return; } char endian, form; - data.read(&endian,1); data.read(&form,1); - if( data.fail() ) { + data.read(&endian,1); + data.read(&form,1); + if (data.fail()) { egsWarning("%s: failed to read endianess and format from %s\n",func,fname); return; } - if( form < 0 || form > 1 ) { + if (form < 0 || form > 1) { egsWarning("%s: unknwon format %d found in file %s\n",func,(int)form,fname); return; } - if( endian != egsGetEndian() ) { + if (endian != egsGetEndian()) { egsWarning("%s: data in %s from a machine with different endianess.\n" - " Byte swaping not implemented yet.\n",func,fname); + " Byte swaping not implemented yet.\n",func,fname); return; } short snx, sny, snz; data.read((char *)&snx,sizeof(short)); data.read((char *)&sny,sizeof(short)); data.read((char *)&snz,sizeof(short)); - if( data.fail() ) { + if (data.fail()) { egsWarning("%s: failed to read number of voxels from %s\n",func,fname); return; } - if( snx < 1 || snx > 10000 || sny < 1 || sny > 10000 || snz < 1 || snz > 10000 ) { + if (snx < 1 || snx > 10000 || sny < 1 || sny > 10000 || snz < 1 || snz > 10000) { egsWarning("%s: number of voxels seems strange: nx=%d, ny=%d, nz=%d\n", - func,snx,sny,snz); + func,snx,sny,snz); return; } - nx = snx; ny = sny; nz = snz; - nxy = nx*ny; nreg = nxy*nz; + nx = snx; + ny = sny; + nz = snz; + nxy = nx*ny; + nreg = nxy*nz; egsInformation("Distribution has %d x %d x %d voxels\n",nx,ny,nz); float *x = new float [nx+1], *y = new float [ny+1], *z = new float [nz+1]; data.read((char *)x, (nx+1)*sizeof(float)); data.read((char *)y, (ny+1)*sizeof(float)); data.read((char *)z, (nz+1)*sizeof(float)); - if( data.fail() ) { + if (data.fail()) { egsWarning("%s: failed to read voxel boundaries\n",func); - delete [] x; delete [] y; delete [] z; return; + delete [] x; + delete [] y; + delete [] z; + return; } - int nmap; float *p; - if( form == 0 ) { + int nmap; + float *p; + if (form == 0) { p = new float [nreg]; egsInformation("Format 0, reading %d values\n",nreg); data.read((char *)p, nreg*sizeof(float)); - if( data.fail() ) { + if (data.fail()) { egsWarning("%s: failed to read probabilities\n",func); - delete [] p; delete [] x; delete [] y; delete [] z; return; + delete [] p; + delete [] x; + delete [] y; + delete [] z; + return; } nmap = nreg; } else { egsInformation("Format 1, reading data\n"); data.read((char *)&nmap, sizeof(int)); - if( data.fail() || nmap < 1 ) { + if (data.fail() || nmap < 1) { egsWarning("%s: failed to read nmap\n",func); - delete [] x; delete [] y; delete [] z; return; + delete [] x; + delete [] y; + delete [] z; + return; } map = new int [nmap]; p = new float [nmap]; data.read((char *)map, nmap*sizeof(int)); data.read((char *)p, nmap*sizeof(float)); - if( data.fail() ) { + if (data.fail()) { egsWarning("%s: failed to read probabilities and bin numbers\n",func); - delete [] p; delete [] map; delete [] x; delete [] y; delete [] z; return; + delete [] p; + delete [] map; + delete [] x; + delete [] y; + delete [] z; + return; } } - EGS_Float *p1 = new EGS_Float [nmap]; int j; - for(j=0; j continue otype = "voxelized_shape"; - if( !fname ) return; + if (!fname) { + return; + } ifstream h_file(fname); - if( !h_file ) { + if (!h_file) { egsWarning("%s: failed to open file %s\n",func,fname); return; } @@ -160,118 +205,193 @@ EGS_VoxelizedShape::EGS_VoxelizedShape(int file_format, const char *fname, int data_type = -1; int Nx, Ny, Nz; float scale_x=0.0, scale_y=0.0, scale_z=0.0; - while(1) { - string line, key, value; size_t pos; + while (1) { + string line, key, value; + size_t pos; getline(h_file, line); - if( h_file.eof() || h_file.fail() || !h_file.good() ) break; + if (h_file.eof() || h_file.fail() || !h_file.good()) { + break; + } pos = line.find(":="); - if( pos == string::npos ) continue; + if (pos == string::npos) { + continue; + } key = line.substr(0, int(pos)); value = line.substr(int(pos)+2); - while ((key[0] == '!') || (key[0] == ' ')) key.erase(0,1); - while (key[key.length()-1] == ' ') key.erase(key.length()-1, 1); - while (value[0] == ' ') value.erase(0,1); - while (value[value.length()-1] == ' ') value.erase(value.length()-1, 1); - if ( key == "matrix size [1]" ) { sscanf(value.c_str(), "%u", &Nx); } - else if ( key == "matrix size [2]" ) { sscanf(value.c_str(), "%u", &Ny); } - else if ( ( key == "number of slices" ) || (key == "number of images") ) { sscanf(value.c_str(), "%u", &Nz); } - else if ( key == "scaling factor (mm/pixel) [1]" ) { sscanf(value.c_str(), "%f", &scale_x); } - else if ( key == "scaling factor (mm/pixel) [2]" ) { sscanf(value.c_str(), "%f", &scale_y); } - else if ( key == "slice thickness (pixels)" ) { sscanf(value.c_str(), "%f", &scale_z); } // ???????????????? - else if ( key == "name of data file" ) { data_file = value; } - else if ( key == "number format" ) { - if( (value == "float") || (value == "FLOAT") ) data_type = 0; - else if( (value == "unsigned integer") || (value == "UNSIGNED INTEGER") ) data_type = 1; - else if( (value == "signed integer") || (value == "SIGNED INTEGER")) data_type = 2; - else egsWarning("%s: unrecognised 'number format' type: %s \n",func,value.c_str()); + while ((key[0] == '!') || (key[0] == ' ')) { + key.erase(0,1); + } + while (key[key.length()-1] == ' ') { + key.erase(key.length()-1, 1); + } + while (value[0] == ' ') { + value.erase(0,1); + } + while (value[value.length()-1] == ' ') { + value.erase(value.length()-1, 1); + } + if (key == "matrix size [1]") { + sscanf(value.c_str(), "%u", &Nx); + } + else if (key == "matrix size [2]") { + sscanf(value.c_str(), "%u", &Ny); + } + else if ((key == "number of slices") || (key == "number of images")) { + sscanf(value.c_str(), "%u", &Nz); + } + else if (key == "scaling factor (mm/pixel) [1]") { + sscanf(value.c_str(), "%f", &scale_x); + } + else if (key == "scaling factor (mm/pixel) [2]") { + sscanf(value.c_str(), "%f", &scale_y); + } + else if (key == "slice thickness (pixels)") { + sscanf(value.c_str(), "%f", &scale_z); // ???????????????? + } + else if (key == "name of data file") { + data_file = value; + } + else if (key == "number format") { + if ((value == "float") || (value == "FLOAT")) { + data_type = 0; + } + else if ((value == "unsigned integer") || (value == "UNSIGNED INTEGER")) { + data_type = 1; + } + else if ((value == "signed integer") || (value == "SIGNED INTEGER")) { + data_type = 2; + } + else { + egsWarning("%s: unrecognised 'number format' type: %s \n",func,value.c_str()); + } } } - if( Nx < 1 || Ny < 1 || Nz < 1 || scale_x <= 0.0 || scale_y <= 0.0 || scale_z <= 0.0 || data_file == "" || data_type == -1) { + if (Nx < 1 || Ny < 1 || Nz < 1 || scale_x <= 0.0 || scale_y <= 0.0 || scale_z <= 0.0 || data_file == "" || data_type == -1) { egsWarning("%s: invalid interfile header information: " - "Nx=%d Ny=%d Nz=%d scale_x=%f scale_y=%f scale_z=%f " - "data_file='%s' number_format=%d\n",func,Nx,Ny,Nz,scale_x,scale_y,scale_z,data_file.c_str(),data_type); + "Nx=%d Ny=%d Nz=%d scale_x=%f scale_y=%f scale_z=%f " + "data_file='%s' number_format=%d\n",func,Nx,Ny,Nz,scale_x,scale_y,scale_z,data_file.c_str(),data_type); return; } - nx = Nx; ny = Ny; nz = Nz; - nxy = nx*ny; nreg = nxy*nz; + nx = Nx; + ny = Ny; + nz = Nz; + nxy = nx*ny; + nreg = nxy*nz; egsInformation("Distribution has %d x %d x %d voxels\n",nx,ny,nz); float *x = new float [nx+1], *y = new float [ny+1], *z = new float [nz+1]; - scale_x /= 10.0; scale_y /= 10.0; scale_z /= 10.0; // convert to cm + scale_x /= 10.0; + scale_y /= 10.0; + scale_z /= 10.0; // convert to cm { int j; - for(j=0; j<=nx; j++) x[j] = -(float)nx*scale_x/2.0 + j*scale_x; - for(j=0; j<=ny; j++) y[j] = -(float)ny*scale_y/2.0 + j*scale_y; - for(j=0; j<=nz; j++) z[j] = -(float)nz*scale_z/2.0 + j*scale_z; + for (j=0; j<=nx; j++) { + x[j] = -(float)nx*scale_x/2.0 + j*scale_x; + } + for (j=0; j<=ny; j++) { + y[j] = -(float)ny*scale_y/2.0 + j*scale_y; + } + for (j=0; j<=nz; j++) { + z[j] = -(float)nz*scale_z/2.0 + j*scale_z; + } } ifstream i_file(data_file.c_str(),ios::binary); - if( !i_file ) { + if (!i_file) { egsWarning("%s: failed to open interfile data " - "%s\n",func,data_file.c_str()); return; + "%s\n",func,data_file.c_str()); + return; } int nmap = nreg; float *p = new float [nreg]; if (data_type == 0) { i_file.read((char *)p, nreg*sizeof(float)); - } else if (data_type == 1) { + } + else if (data_type == 1) { unsigned short int *p_tmp = new unsigned short int [nreg]; i_file.read((char *)p_tmp, nreg*sizeof(unsigned short int)); - for (int cc = 0; ccgetInput("file name",fname); - int file_format; int err2 = input->getInput("file format",file_format); - if( err ) { - egsWarning("%s: missing 'file name' input\n",func); return 0; - } - if( err2 ) { - egsInformation("%s: 'file format' input missing. Using default 'binary'" - "file format \n",func); - file_format = 0; - } - EGS_VoxelizedShape *shape = new EGS_VoxelizedShape(file_format, fname.c_str()); - if( !shape->isValid() ) { - delete shape; return 0; + EGS_VOXELIZED_SHAPE_EXPORT EGS_BaseShape *createShape(EGS_Input *input, + EGS_ObjectFactory *f) { + static const char *func = "createShape(voxelized shape)"; + if (!input) { + egsWarning("%s: null input?\n",func); + return 0; + } + string fname; + int err = input->getInput("file name",fname); + int file_format; + int err2 = input->getInput("file format",file_format); + if (err) { + egsWarning("%s: missing 'file name' input\n",func); + return 0; + } + if (err2) { + egsInformation("%s: 'file format' input missing. Using default 'binary'" + "file format \n",func); + file_format = 0; + } + EGS_VoxelizedShape *shape = new EGS_VoxelizedShape(file_format, fname.c_str()); + if (!shape->isValid()) { + delete shape; + return 0; + } + shape->setName(input); + shape->setTransformation(input); + return shape; } - shape->setName(input); shape->setTransformation(input); - return shape; -} } diff --git a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.h b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.h index 7139365da..9d3770909 100644 --- a/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.h +++ b/HEN_HOUSE/egs++/shapes/egs_voxelized_shape/egs_voxelized_shape.h @@ -44,22 +44,22 @@ #ifdef WIN32 -#ifdef BUILD_VOXELIZED_SHAPE_DLL -#define EGS_VOXELIZED_SHAPE_EXPORT __declspec(dllexport) -#else -#define EGS_VOXELIZED_SHAPE_EXPORT __declspec(dllimport) -#endif -#define EGS_VOXELIZED_SHAPE_LOCAL + #ifdef BUILD_VOXELIZED_SHAPE_DLL + #define EGS_VOXELIZED_SHAPE_EXPORT __declspec(dllexport) + #else + #define EGS_VOXELIZED_SHAPE_EXPORT __declspec(dllimport) + #endif + #define EGS_VOXELIZED_SHAPE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_VOXELIZED_SHAPE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_VOXELIZED_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_VOXELIZED_SHAPE_EXPORT -#define EGS_VOXELIZED_SHAPE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_VOXELIZED_SHAPE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_VOXELIZED_SHAPE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_VOXELIZED_SHAPE_EXPORT + #define EGS_VOXELIZED_SHAPE_LOCAL + #endif #endif @@ -104,14 +104,16 @@ class EGS_VOXELIZED_SHAPE_EXPORT EGS_VoxelizedShape : public EGS_BaseShape { \c fname */ EGS_VoxelizedShape(int file_format, const char *fname,const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); ~EGS_VoxelizedShape(); void EGS_VoxelizedShapeFormat0(const char *fname,const string &Name="", - EGS_ObjectFactory *f=0); + EGS_ObjectFactory *f=0); EGS_Vector getPoint(EGS_RandomGenerator *rndm) { int bin = prob->sample(rndm); int voxel = type == 0 ? bin : map[bin]; - int iz = voxel/nxy; voxel -= iz*nxy; int iy = voxel/nx; + int iz = voxel/nxy; + voxel -= iz*nxy; + int iy = voxel/nx; int ix = voxel - iy*nx; EGS_Float eta_x = rndm->getUniform(), eta_y = rndm->getUniform(), @@ -121,7 +123,9 @@ class EGS_VOXELIZED_SHAPE_EXPORT EGS_VoxelizedShape : public EGS_BaseShape { zpos[iz]*(1-eta_z) + zpos[iz+1]*eta_z); }; - bool isValid() const { return (type == 0 || type == 1); }; + bool isValid() const { + return (type == 0 || type == 1); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp index 652bedd2d..455ceae83 100644 --- a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.cpp @@ -39,33 +39,38 @@ #include "egs_math.h" EGS_AngularSpreadSource::EGS_AngularSpreadSource(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), sigma(0) { + EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), sigma(0) { EGS_Input *isource = input->takeInputItem("source",false); - if( isource ) { - source = EGS_BaseSource::createSource(isource); delete isource; + if (isource) { + source = EGS_BaseSource::createSource(isource); + delete isource; } - if( !source ) { - string sname; int err = input->getInput("source name",sname); - if( err ) + if (!source) { + string sname; + int err = input->getInput("source name",sname); + if (err) egsWarning("EGS_AngularSpreadSource: missing/wrong inline source " - "definition and missing wrong 'source name' input\n"); + "definition and missing wrong 'source name' input\n"); else { source = EGS_BaseSource::getSource(sname); - if( !source ) egsWarning("EGS_AngularSpreadSource: a source named %s" - " does not exist\n"); + if (!source) egsWarning("EGS_AngularSpreadSource: a source named %s" + " does not exist\n"); } } int err = input->getInput("sigma",sigma); - if( !err ) { - if( sigma < 0 ) sigma = -0.4246609001440095285*sigma; - sigma *= M_PI/180; sigma *= sigma; + if (!err) { + if (sigma < 0) { + sigma = -0.4246609001440095285*sigma; + } + sigma *= M_PI/180; + sigma *= sigma; } setUp(); } void EGS_AngularSpreadSource::setUp() { otype = "EGS_AngularSpreadSource"; - if( !isValid() ) { + if (!isValid()) { description = "Invalid angular spread source"; return; } @@ -76,9 +81,10 @@ void EGS_AngularSpreadSource::setUp() { extern "C" { -EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { return - createSourceTemplate(input,f,"angular spread source"); -} + EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"angular spread source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.h b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.h index b7cfcc3fe..195033dfe 100644 --- a/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.h +++ b/HEN_HOUSE/egs++/sources/egs_angular_spread/egs_angular_spread_source.h @@ -45,22 +45,22 @@ #ifdef WIN32 -#ifdef BUILD_ANGULAR_SPREAD_SOURCE_DLL -#define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_ANGULAR_SPREAD_SOURCE_LOCAL + #ifdef BUILD_ANGULAR_SPREAD_SOURCE_DLL + #define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_ANGULAR_SPREAD_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_ANGULAR_SPREAD_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_ANGULAR_SPREAD_SOURCE_EXPORT -#define EGS_ANGULAR_SPREAD_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_ANGULAR_SPREAD_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_ANGULAR_SPREAD_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_ANGULAR_SPREAD_SOURCE_EXPORT + #define EGS_ANGULAR_SPREAD_SOURCE_LOCAL + #endif #endif @@ -86,7 +86,7 @@ in degrees, if negative, the FWHM of the distribution. */ class EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_AngularSpreadSource : - public EGS_BaseSource { + public EGS_BaseSource { public: @@ -96,12 +96,16 @@ class EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_AngularSpreadSource : }; EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u) { + int &q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u) { EGS_I64 c = source->getNextParticle(rndm,q,latch,E,wt,x,u); //egsInformation("\nGot u=(%g,%g,%g)\n",u.x,u.y,u.z); - if( sigma > 0 ) { - EGS_Float cost; do { cost = 1 + sigma*log(1 - rndm->getUniform()); } while (cost <= -1); + if (sigma > 0) { + EGS_Float cost; + do { + cost = 1 + sigma*log(1 - rndm->getUniform()); + } + while (cost <= -1); EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); EGS_Float sint = sqrt(1-cost*cost); @@ -110,14 +114,28 @@ class EGS_ANGULAR_SPREAD_SOURCE_EXPORT EGS_AngularSpreadSource : } return c; }; - EGS_Float getEmax() const { return source->getEmax(); }; - EGS_Float getFluence() const { return source->getFluence(); }; - bool storeState(ostream &data) const { return source->storeState(data); }; - bool setState(istream &data) { return source->setState(data); }; - bool addState(istream &data_in) { return source->addState(data_in); }; - void resetCounter() { source->resetCounter(); }; - - bool isValid() const { return (source != 0); }; + EGS_Float getEmax() const { + return source->getEmax(); + }; + EGS_Float getFluence() const { + return source->getFluence(); + }; + bool storeState(ostream &data) const { + return source->storeState(data); + }; + bool setState(istream &data) { + return source->setState(data); + }; + bool addState(istream &data_in) { + return source->addState(data_in); + }; + void resetCounter() { + source->resetCounter(); + }; + + bool isValid() const { + return (source != 0); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp index 0f76f8efc..f00cdd99c 100644 --- a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.cpp @@ -51,150 +51,222 @@ EGS_BeamSource::EGS_BeamSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f) { - n_reuse_photon = 0; n_reuse_electron = 0; - i_reuse_photon = 0; i_reuse_electron = 0; - is_valid = false; lib = 0; - Xmin = -1e30; Xmax = 1e30; Ymin = -1e30; Ymax = 1e30; - wmin = -1e30; wmax = 1e30; - string beam_code; int err1 = input->getInput("beam code",beam_code); - string pegs_file; int err2 = input->getInput("pegs file",pegs_file); - string input_file; int err3 = input->getInput("input file",input_file); - if( err1 ) egsWarning("EGS_BeamSource: no 'beam code' input\n"); - if( err2 ) egsWarning("EGS_BeamSource: no 'pegs file' input\n"); - if( err3 ) egsWarning("EGS_BeamSource: no 'input file' input\n"); - if( err1 || err2 || err3 ) return; + n_reuse_photon = 0; + n_reuse_electron = 0; + i_reuse_photon = 0; + i_reuse_electron = 0; + is_valid = false; + lib = 0; + Xmin = -1e30; + Xmax = 1e30; + Ymin = -1e30; + Ymax = 1e30; + wmin = -1e30; + wmax = 1e30; + string beam_code; + int err1 = input->getInput("beam code",beam_code); + string pegs_file; + int err2 = input->getInput("pegs file",pegs_file); + string input_file; + int err3 = input->getInput("input file",input_file); + if (err1) { + egsWarning("EGS_BeamSource: no 'beam code' input\n"); + } + if (err2) { + egsWarning("EGS_BeamSource: no 'pegs file' input\n"); + } + if (err3) { + egsWarning("EGS_BeamSource: no 'input file' input\n"); + } + if (err1 || err2 || err3) { + return; + } char *egs_home = getenv("EGS_HOME"); - if( !egs_home ) { - egsWarning("EGS_BeamSource: EGS_HOME is not defined\n"); return; + if (!egs_home) { + egsWarning("EGS_BeamSource: EGS_HOME is not defined\n"); + return; } char *hen_house = getenv("HEN_HOUSE"); - if( !hen_house ) { - egsWarning("EGS_BeamSource: HEN_HOUSE is not defined\n"); return; + if (!hen_house) { + egsWarning("EGS_BeamSource: HEN_HOUSE is not defined\n"); + return; } - string path = egs_home; path += "bin/"; path += CONFIG_NAME; + string path = egs_home; + path += "bin/"; + path += CONFIG_NAME; lib = new EGS_Library(beam_code.c_str(),path.c_str()); InitFunction init = (InitFunction) - lib->resolve(F77_NAME_(beamlib_init,BEAMLIB_INIT)); + lib->resolve(F77_NAME_(beamlib_init,BEAMLIB_INIT)); finish = (FinishFunction) - lib->resolve(F77_NAME_(beamlib_finish,BEAMLIB_FINISH)); + lib->resolve(F77_NAME_(beamlib_finish,BEAMLIB_FINISH)); sample = (SampleFunction) - lib->resolve(F77_NAME_(beamlib_sample,BEAMLIB_SAMPLE)); + lib->resolve(F77_NAME_(beamlib_sample,BEAMLIB_SAMPLE)); MaxEnergyFunction maxenergy = (MaxEnergyFunction) - lib->resolve(F77_NAME_(beamlib_max_energy,BEAMLIB_MAX_ENERGY)); - if( !init ) + lib->resolve(F77_NAME_(beamlib_max_energy,BEAMLIB_MAX_ENERGY)); + if (!init) { egsWarning("EGS_BeamSource: failed to resolve the init function\n"); - if( !sample ) + } + if (!sample) { egsWarning("EGS_BeamSource: failed to resolve the sample function\n"); - if( !finish ) + } + if (!finish) { egsWarning("EGS_BeamSource: failed to resolve the finish function\n"); - if( !maxenergy ) - egsWarning("EGS_BeamSource: failed to resolve the max. energy function\n"); - if( !init || !sample || !finish || !maxenergy ) return; + } + if (!maxenergy) { + egsWarning("EGS_BeamSource: failed to resolve the max. energy function\n"); + } + if (!init || !sample || !finish || !maxenergy) { + return; + } int ipar=0, ilog=6; EGS_Application *app = EGS_Application::activeApplication(); - if( app ) ipar = app->getIparallel(); + if (app) { + ipar = app->getIparallel(); + } init(&ipar,&ilog,hen_house,egs_home,beam_code.c_str(), - pegs_file.c_str(),input_file.c_str(), - strlen(hen_house), strlen(egs_home), - beam_code.size(),pegs_file.size(),input_file.size()); + pegs_file.c_str(),input_file.c_str(), + strlen(hen_house), strlen(egs_home), + beam_code.size(),pegs_file.size(),input_file.size()); maxenergy(&Emax); is_valid = true; vector cutout; int err = input->getInput("cutout",cutout); - if( !err && cutout.size() == 4 ) + if (!err && cutout.size() == 4) { setCutout(cutout[0],cutout[1],cutout[2],cutout[3]); + } vector ptype; - ptype.push_back("electrons"); ptype.push_back("photons"); - ptype.push_back("positrons"); ptype.push_back("all"); + ptype.push_back("electrons"); + ptype.push_back("photons"); + ptype.push_back("positrons"); + ptype.push_back("all"); ptype.push_back("charged"); particle_type = input->getInput("particle type",ptype,3)-1; vector wwindow; err = input->getInput("weight window",wwindow); - if( !err && wwindow.size() == 2 ) { - wmin = wwindow[0]; wmax = wwindow[1]; + if (!err && wwindow.size() == 2) { + wmin = wwindow[0]; + wmax = wwindow[1]; } int ntmp; err = input->getInput("reuse photons",ntmp); - if( !err && ntmp > 1 ) n_reuse_photon = ntmp; + if (!err && ntmp > 1) { + n_reuse_photon = ntmp; + } err = input->getInput("reuse electrons",ntmp); - if( !err && ntmp > 1 ) n_reuse_electron = ntmp; + if (!err && ntmp > 1) { + n_reuse_electron = ntmp; + } - description = beam_code; description += "("; - description += input_file; description += ") simulation source"; + description = beam_code; + description += "("; + description += input_file; + description += ") simulation source"; } EGS_I64 EGS_BeamSource::getNextParticle(EGS_RandomGenerator *, int &q, - int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { - if( n_reuse_photon > 0 && i_reuse_photon < n_reuse_photon ) { - q = q_save; latch = latch_save; E = E_save; wt = wt_save; - x = x_save; u = u_save; ++i_reuse_photon; + int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { + if (n_reuse_photon > 0 && i_reuse_photon < n_reuse_photon) { + q = q_save; + latch = latch_save; + E = E_save; + wt = wt_save; + x = x_save; + u = u_save; + ++i_reuse_photon; return count; } - if( n_reuse_electron > 0 && i_reuse_electron < n_reuse_electron) { - q = q_save; latch = latch_save; E = E_save; wt = wt_save; - x = x_save; u = u_save; ++i_reuse_electron; + if (n_reuse_electron > 0 && i_reuse_electron < n_reuse_electron) { + q = q_save; + latch = latch_save; + E = E_save; + wt = wt_save; + x = x_save; + u = u_save; + ++i_reuse_electron; return count; } EGS_Float te,tx,ty,tz,tu,tv,tw,twt; - int tq,tlatch,tiphat; bool ok; + int tq,tlatch,tiphat; + bool ok; do { sample(&te,&tx,&ty,&tz,&tu,&tv,&tw,&twt,&tq,&tlatch,&count,&tiphat); //egsInformation("EGS_BeamSource::getNextParticle: Got E=%g q=%d wt=%g" // " x=(%g,%g,%g) latch=%d count=%lld\n",te,tq,twt,tx,ty,tz, // tlatch,count); - if(tq) te -= 0.5110034; + if (tq) { + te -= 0.5110034; + } ok = true; - if( te > Emax ) { ok = false; } //egsInformation("Emax rejection\n"); } - if( particle_type < 2 && tq != particle_type ) { - ok = false; } // egsInformation("charge rejection"); } - if( particle_type == 3 && !tq ) ok = false; - if( tx < Xmin || tx > Xmax || ty < Ymin || ty > Ymax ) { - ok = false; } // egsInformation("cutout rejection\n"); } - if( twt < wmin || twt > wmax ) { + if (te > Emax) { + ok = false; + } //egsInformation("Emax rejection\n"); } + if (particle_type < 2 && tq != particle_type) { + ok = false; + } // egsInformation("charge rejection"); } + if (particle_type == 3 && !tq) { + ok = false; + } + if (tx < Xmin || tx > Xmax || ty < Ymin || ty > Ymax) { + ok = false; + } // egsInformation("cutout rejection\n"); } + if (twt < wmin || twt > wmax) { ok = false; // egsInformation("weight rejection\n"); } - } while ( !ok ); + } + while (!ok); i_reuse_electron = n_reuse_electron; i_reuse_photon = n_reuse_photon; //egsInformation("returning particle\n"); - E = te; q = tq; + E = te; + q = tq; latch = 0; //latch = tlatch; bool save_it = false; - if( n_reuse_photon > 1 && !tq ) { - twt /= n_reuse_photon; i_reuse_photon = 1; save_it = true; + if (n_reuse_photon > 1 && !tq) { + twt /= n_reuse_photon; + i_reuse_photon = 1; + save_it = true; } - if( n_reuse_electron > 1 && tq ) { - twt /= n_reuse_electron; i_reuse_electron = 1; save_it = true; + if (n_reuse_electron > 1 && tq) { + twt /= n_reuse_electron; + i_reuse_electron = 1; + save_it = true; } wt = twt; - x = EGS_Vector(tx,ty,tz); u = EGS_Vector(tu,tv,tw); - if( save_it ) { - q_save = tq; latch_save = 0; - E_save = E; wt_save = twt; - x_save = x; u_save = u; + x = EGS_Vector(tx,ty,tz); + u = EGS_Vector(tu,tv,tw); + if (save_it) { + q_save = tq; + latch_save = 0; + E_save = E; + wt_save = twt; + x_save = x; + u_save = u; } return count; } EGS_BeamSource::~EGS_BeamSource() { - if( lib ) { - if( is_valid ) finish(); + if (lib) { + if (is_valid) { + finish(); + } delete lib; } } extern "C" { -EGS_BEAM_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { return - createSourceTemplate(input,f,"beam source"); -} + EGS_BEAM_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"beam source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.h b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.h index e1cdc696c..2ab3515f3 100644 --- a/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.h +++ b/HEN_HOUSE/egs++/sources/egs_beam_source/egs_beam_source.h @@ -48,22 +48,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_BEAM_SOURCE_DLL -#define EGS_BEAM_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_BEAM_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_BEAM_SOURCE_LOCAL + #ifdef BUILD_BEAM_SOURCE_DLL + #define EGS_BEAM_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_BEAM_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_BEAM_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_BEAM_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_BEAM_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_BEAM_SOURCE_EXPORT -#define EGS_BEAM_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_BEAM_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_BEAM_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_BEAM_SOURCE_EXPORT + #define EGS_BEAM_SOURCE_LOCAL + #endif #endif @@ -73,8 +73,8 @@ typedef void (*InitFunction)(const int *, const int *, const char *, const char *, int,int,int,int,int); typedef void (*FinishFunction)(); typedef void (*SampleFunction)(EGS_Float *, EGS_Float *, EGS_Float *, - EGS_Float *, EGS_Float *, EGS_Float *, EGS_Float *, EGS_Float *, - EGS_I32 *, EGS_I32 *, EGS_I64 *, EGS_I32 *); + EGS_Float *, EGS_Float *, EGS_Float *, EGS_Float *, EGS_Float *, + EGS_I32 *, EGS_I32 *, EGS_I64 *, EGS_I32 *); typedef void (*MaxEnergyFunction)(EGS_Float *); /*! \brief A BEAM simulation source @@ -120,10 +120,14 @@ class EGS_BEAM_SOURCE_EXPORT EGS_BeamSource : public EGS_BaseSource { ~EGS_BeamSource(); EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u); - EGS_Float getEmax() const { return Emax; }; - EGS_Float getFluence() const { return count; }; + int &q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u); + EGS_Float getEmax() const { + return Emax; + }; + EGS_Float getFluence() const { + return count; + }; bool storeState(ostream &data) const { return egsStoreI64(data,count); }; @@ -132,15 +136,24 @@ class EGS_BEAM_SOURCE_EXPORT EGS_BeamSource : public EGS_BaseSource { }; bool addState(istream &data) { EGS_I64 tmp; - bool res = egsGetI64(data,tmp); count += tmp; return res; + bool res = egsGetI64(data,tmp); + count += tmp; + return res; + }; + void resetCounter() { + count = 0; }; - void resetCounter() { count = 0; }; - bool isValid() const { return is_valid; }; + bool isValid() const { + return is_valid; + }; void setCutout(EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, - EGS_Float ymax) { - Xmin = xmin; Xmax = xmax; Ymin = ymin; Ymax = ymax; + EGS_Float ymax) { + Xmin = xmin; + Xmax = xmax; + Ymin = ymin; + Ymax = ymax; }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp index ae0bc6d83..9f49ff8b8 100644 --- a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.cpp @@ -38,55 +38,64 @@ #include "egs_input.h" EGS_CollimatedSource::EGS_CollimatedSource(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), + EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), source_shape(0), target_shape(0), dist(1), ctry(0) { EGS_Input *ishape = input->takeInputItem("source shape"); - if( ishape ) { - source_shape = EGS_BaseShape::createShape(ishape); delete ishape; + if (ishape) { + source_shape = EGS_BaseShape::createShape(ishape); + delete ishape; } - if( !source_shape ) { - string sname; int err = input->getInput("source shape name",sname); - if( err ) + if (!source_shape) { + string sname; + int err = input->getInput("source shape name",sname); + if (err) egsWarning("EGS_CollimatedSource: missing/wrong inline source " - "shape definition and missing wrong 'source shape name' input\n"); + "shape definition and missing wrong 'source shape name' input\n"); else { source_shape = EGS_BaseShape::getShape(sname); - if( !source_shape ) + if (!source_shape) egsWarning("EGS_CollimatedSource: a shape named %s" - " does not exist\n",sname.c_str()); + " does not exist\n",sname.c_str()); } } ishape = input->takeInputItem("target shape"); - if( ishape ) { - target_shape = EGS_BaseShape::createShape(ishape); delete ishape; + if (ishape) { + target_shape = EGS_BaseShape::createShape(ishape); + delete ishape; } - if( !target_shape ) { - string sname; int err = input->getInput("target shape name",sname); - if( err ) + if (!target_shape) { + string sname; + int err = input->getInput("target shape name",sname); + if (err) egsWarning("EGS_CollimatedSource: missing/wrong inline target" - "shape definition and missing wrong 'target shape name' input\n"); + "shape definition and missing wrong 'target shape name' input\n"); else { target_shape = EGS_BaseShape::getShape(sname); - if( !source_shape ) + if (!source_shape) egsWarning("EGS_CollimatedSource: a shape named %s" - " does not exist\n",sname.c_str()); + " does not exist\n",sname.c_str()); } } - if( target_shape ) { - if( !target_shape->supportsDirectionMethod() ) + if (target_shape) { + if (!target_shape->supportsDirectionMethod()) egsWarning("EGS_CollimatedSource: the target shape %s, which is" - " of type %s, does not support the getPointSourceDirection()" - " method\n",target_shape->getObjectName().c_str(), - target_shape->getObjectType().c_str()); + " of type %s, does not support the getPointSourceDirection()" + " method\n",target_shape->getObjectName().c_str(), + target_shape->getObjectType().c_str()); }; - EGS_Float auxd; int errd = input->getInput("distance",auxd); - if( !errd ) dist = auxd; + EGS_Float auxd; + int errd = input->getInput("distance",auxd); + if (!errd) { + dist = auxd; + } setUp(); } void EGS_CollimatedSource::setUp() { otype = "EGS_CollimatedSource"; - if( !isValid() ) description = "Invalid collimated source"; + if (!isValid()) { + description = "Invalid collimated source"; + } else { description = "Collimated source from a shape of type "; description += source_shape->getObjectType(); @@ -94,18 +103,27 @@ void EGS_CollimatedSource::setUp() { description += target_shape->getObjectType(); description += " with "; description += s->getType(); - if( q == -1 ) description += ", electrons"; - else if( q == 0 ) description += ", photons"; - else if( q == 1 ) description += ", positrons"; - else description += ", unknown particle type"; + if (q == -1) { + description += ", electrons"; + } + else if (q == 0) { + description += ", photons"; + } + else if (q == 1) { + description += ", positrons"; + } + else { + description += ", unknown particle type"; + } } } extern "C" { -EGS_COLLIMATED_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { return - createSourceTemplate(input,f,"collimated source"); -} + EGS_COLLIMATED_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"collimated source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.h b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.h index c69268135..799285216 100644 --- a/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.h +++ b/HEN_HOUSE/egs++/sources/egs_collimated_source/egs_collimated_source.h @@ -46,22 +46,22 @@ #ifdef WIN32 -#ifdef BUILD_COLLIMATED_SOURCE_DLL -#define EGS_COLLIMATED_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_COLLIMATED_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_COLLIMATED_SOURCE_LOCAL + #ifdef BUILD_COLLIMATED_SOURCE_DLL + #define EGS_COLLIMATED_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_COLLIMATED_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_COLLIMATED_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_COLLIMATED_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_COLLIMATED_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_COLLIMATED_SOURCE_EXPORT -#define EGS_COLLIMATED_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_COLLIMATED_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_COLLIMATED_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_COLLIMATED_SOURCE_EXPORT + #define EGS_COLLIMATED_SOURCE_LOCAL + #endif #endif @@ -120,7 +120,7 @@ reproduced with the collimated source from the EGSnrc C++ class library. */ class EGS_COLLIMATED_SOURCE_EXPORT EGS_CollimatedSource : - public EGS_BaseSimpleSource { + public EGS_BaseSimpleSource { public: @@ -130,10 +130,12 @@ class EGS_COLLIMATED_SOURCE_EXPORT EGS_CollimatedSource : source shape \a sshape and target shape \a tshape. */ EGS_CollimatedSource(int Q, EGS_BaseSpectrum *Spec, - EGS_BaseShape *sshape, EGS_BaseShape *tshape, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSimpleSource(Q,Spec,Name,f), source_shape(sshape), - target_shape(tshape), dist(1), ctry(0) { setUp(); }; + EGS_BaseShape *sshape, EGS_BaseShape *tshape, + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSimpleSource(Q,Spec,Name,f), source_shape(sshape), + target_shape(tshape), dist(1), ctry(0) { + setUp(); + }; /*! Constructor @@ -146,27 +148,29 @@ class EGS_COLLIMATED_SOURCE_EXPORT EGS_CollimatedSource : }; void getPositionDirection(EGS_RandomGenerator *rndm, - EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { + EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { //x = source_shape->getPoint(rndm); x = source_shape->getRandomPoint(rndm); int ntry = 0; do { target_shape->getPointSourceDirection(x,rndm,u,wt); ntry++; - if( ntry > 10000 ) + if (ntry > 10000) egsFatal("EGS_CollimatedSource::getPositionDirection:\n" - " my target shape %s, which is of type %s, failed to\n" - " return a positive weight after 10000 attempts\n", - target_shape->getObjectName().c_str(), - target_shape->getObjectType().c_str()); - } while ( wt <= 0 ); + " my target shape %s, which is of type %s, failed to\n" + " return a positive weight after 10000 attempts\n", + target_shape->getObjectName().c_str(), + target_shape->getObjectType().c_str()); + } + while (wt <= 0); //egsInformation("got x=(%g,%g,%g) u=(%g,%g,%g) wt = %g ntry = %d\n", // x.x,x.y,x.z,u.x,u.y,u.z,wt,ntry); ctry += ntry; }; EGS_Float getFluence() const { - double res = ctry; return res/(dist*dist); + double res = ctry; + return res/(dist*dist); }; bool storeFluenceState(ostream &data) const { @@ -178,17 +182,23 @@ class EGS_COLLIMATED_SOURCE_EXPORT EGS_CollimatedSource : }; bool addFluenceData(istream &data) { - EGS_I64 tmp; bool ok = egsGetI64(data,tmp); - if( !ok ) return false; - ctry += tmp; return true; + EGS_I64 tmp; + bool ok = egsGetI64(data,tmp); + if (!ok) { + return false; + } + ctry += tmp; + return true; }; bool isValid() const { return (s != 0 && source_shape != 0 && target_shape != 0 && - target_shape->supportsDirectionMethod() ); + target_shape->supportsDirectionMethod()); }; - void resetFluenceCounter() {ctry = 0; }; + void resetFluenceCounter() { + ctry = 0; + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp index 07973ffb0..772d14b7c 100644 --- a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.cpp @@ -39,32 +39,34 @@ #include "egs_math.h" EGS_IsotropicSource::EGS_IsotropicSource(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), geom(0), + EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), geom(0), regions(0), min_theta(0), max_theta(M_PI), min_phi(0), max_phi(2*M_PI), gc(IncludeAll) { vector pos; EGS_Input *ishape = input->takeInputItem("shape"); - if( ishape ) { + if (ishape) { egsWarning("EGS_IsotropicSource: trying to construct the shape\n"); - shape = EGS_BaseShape::createShape(ishape); delete ishape; + shape = EGS_BaseShape::createShape(ishape); + delete ishape; } - if( !shape ) { - string sname; int err = input->getInput("shape name",sname); - if( err ) + if (!shape) { + string sname; + int err = input->getInput("shape name",sname); + if (err) egsWarning("EGS_IsotropicSource: missing/wrong inline shape " - "definition and missing wrong 'shape name' input\n"); + "definition and missing wrong 'shape name' input\n"); else { shape = EGS_BaseShape::getShape(sname); - if( !shape ) egsWarning("EGS_IsotropicSource: a shape named %s" - " does not exist\n"); + if (!shape) egsWarning("EGS_IsotropicSource: a shape named %s" + " does not exist\n"); } } string geom_name; int err = input->getInput("geometry",geom_name); - if( !err ) { + if (!err) { geom = EGS_BaseGeometry::getGeometry(geom_name); - if( !geom ) egsWarning("EGS_IsotropicSource: no geometry named %s\n", - geom_name.c_str()); + if (!geom) egsWarning("EGS_IsotropicSource: no geometry named %s\n", + geom_name.c_str()); else { vector reg_options; reg_options.push_back("IncludeAll"); @@ -72,60 +74,85 @@ EGS_IsotropicSource::EGS_IsotropicSource(EGS_Input *input, reg_options.push_back("IncludeSelected"); reg_options.push_back("ExcludeSelected"); gc = (GeometryConfinement) input->getInput("region selection",reg_options,0); - if( gc == IncludeSelected || gc == ExcludeSelected ) { + if (gc == IncludeSelected || gc == ExcludeSelected) { vector regs; err = input->getInput("selected regions",regs); - if( err || regs.size() < 1 ) { + if (err || regs.size() < 1) { egsWarning("EGS_IsotropicSource: region selection %d used " - "but no 'selected regions' input found\n",gc); + "but no 'selected regions' input found\n",gc); gc = gc == IncludeSelected ? IncludeAll : ExcludeAll; egsWarning(" using %d\n",gc); } - nrs = regs.size(); regions = new int [nrs]; - for(int j=0; jgetInput("min theta", tmp_theta); - if(!err) min_theta = tmp_theta/180.0*M_PI; + if (!err) { + min_theta = tmp_theta/180.0*M_PI; + } err = input->getInput("max theta", tmp_theta); - if(!err) max_theta = tmp_theta/180.0*M_PI; + if (!err) { + max_theta = tmp_theta/180.0*M_PI; + } err = input->getInput("min phi", tmp_theta); - if(!err) min_phi = tmp_theta/180.0*M_PI; + if (!err) { + min_phi = tmp_theta/180.0*M_PI; + } err = input->getInput("max phi", tmp_theta); - if(!err) max_phi = tmp_theta/180.0*M_PI; + if (!err) { + max_phi = tmp_theta/180.0*M_PI; + } - buf_1 = cos(min_theta); buf_2 = cos(max_theta); + buf_1 = cos(min_theta); + buf_2 = cos(max_theta); setUp(); } void EGS_IsotropicSource::setUp() { otype = "EGS_IsotropicSource"; - if( !isValid() ) description = "Invalid isotropic source"; + if (!isValid()) { + description = "Invalid isotropic source"; + } else { description = "Isotropic source from a shape of type "; description += shape->getObjectType(); description += " with "; description += s->getType(); - if( q == -1 ) description += ", electrons"; - else if( q == 0 ) description += ", photons"; - else if( q == 1 ) description += ", positrons"; - else description += ", unknown particle type"; + if (q == -1) { + description += ", electrons"; + } + else if (q == 0) { + description += ", photons"; + } + else if (q == 1) { + description += ", positrons"; + } + else { + description += ", unknown particle type"; + } - if( geom ) geom->ref(); + if (geom) { + geom->ref(); + } } } extern "C" { -EGS_ISOTROPIC_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { return - createSourceTemplate(input,f,"isotropic source"); -} + EGS_ISOTROPIC_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"isotropic source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.h b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.h index 899c193f3..939d8a5cc 100644 --- a/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.h +++ b/HEN_HOUSE/egs++/sources/egs_isotropic_source/egs_isotropic_source.h @@ -47,22 +47,22 @@ #ifdef WIN32 -#ifdef BUILD_ISOTROPIC_SOURCE_DLL -#define EGS_ISOTROPIC_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_ISOTROPIC_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_ISOTROPIC_SOURCE_LOCAL + #ifdef BUILD_ISOTROPIC_SOURCE_DLL + #define EGS_ISOTROPIC_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_ISOTROPIC_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_ISOTROPIC_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_ISOTROPIC_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_ISOTROPIC_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_ISOTROPIC_SOURCE_EXPORT -#define EGS_ISOTROPIC_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_ISOTROPIC_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_ISOTROPIC_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_ISOTROPIC_SOURCE_EXPORT + #define EGS_ISOTROPIC_SOURCE_LOCAL + #endif #endif @@ -95,7 +95,7 @@ the isotropic source from the EGSnrc C++ class library. */ class EGS_ISOTROPIC_SOURCE_EXPORT EGS_IsotropicSource : - public EGS_BaseSimpleSource { + public EGS_BaseSimpleSource { public: @@ -113,12 +113,14 @@ class EGS_ISOTROPIC_SOURCE_EXPORT EGS_IsotropicSource : and emitting particles from the shape \a Shape */ EGS_IsotropicSource(int Q, EGS_BaseSpectrum *Spec, EGS_BaseShape *Shape, - EGS_BaseGeometry *geometry, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSimpleSource(Q,Spec,Name,f), shape(Shape), - min_theta(85.), max_theta(95.), min_phi(0), max_phi(2*M_PI), - buf_1(1), buf_2(-1), - geom(geometry), regions(0), nrs(0), gc(IncludeAll) { setUp(); }; + EGS_BaseGeometry *geometry, + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSimpleSource(Q,Spec,Name,f), shape(Shape), + min_theta(85.), max_theta(95.), min_phi(0), max_phi(2*M_PI), + buf_1(1), buf_2(-1), + geom(geometry), regions(0), nrs(0), gc(IncludeAll) { + setUp(); + }; /*! \brief Constructor @@ -128,57 +130,89 @@ class EGS_ISOTROPIC_SOURCE_EXPORT EGS_IsotropicSource : ~EGS_IsotropicSource() { egsWarning("destructing point source\n"); EGS_Object::deleteObject(shape); - if( geom ) { - if( !geom->deref() ) delete geom; + if (geom) { + if (!geom->deref()) { + delete geom; + } + } + if (nrs > 0 && regions) { + delete [] regions; } - if( nrs > 0 && regions ) delete [] regions; }; void getPositionDirection(EGS_RandomGenerator *rndm, - EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { + EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { bool ok = true; do { x = shape->getRandomPoint(rndm); - if( geom ) { - if( gc == IncludeAll ) ok = geom->isInside(x); - else if( gc == ExcludeAll ) ok = !geom->isInside(x); - else if( gc == IncludeSelected ) { - ok = false; int ireg = geom->isWhere(x); - for(int j=0; jisInside(x); + } + else if (gc == ExcludeAll) { + ok = !geom->isInside(x); + } + else if (gc == IncludeSelected) { + ok = false; + int ireg = geom->isWhere(x); + for (int j=0; jisWhere(x); - for(int j=0; jisWhere(x); + for (int j=0; jgetUniform()*(buf_1 - buf_2) - buf_1; //u.z = 2*rndm->getUniform()-1; EGS_Float sinz = 1-u.z*u.z; - if( sinz > 1e-15 ) { - sinz = sqrt(sinz); EGS_Float cphi, sphi; + if (sinz > 1e-15) { + sinz = sqrt(sinz); + EGS_Float cphi, sphi; //rndm->getAzimuth(cphi,sphi); // sample phi, slower than rndm->getAzimuth EGS_Float phi = min_phi +(max_phi - min_phi)*rndm->getUniform(); - cphi = cos(phi); sphi = sin(phi); - u.x = sinz*cphi; u.y = sinz*sphi; - } else { u.x = 0; u.y = 0; } + cphi = cos(phi); + sphi = sin(phi); + u.x = sinz*cphi; + u.y = sinz*sphi; + } + else { + u.x = 0; + u.y = 0; + } wt = 1; }; - EGS_Float getFluence() const { return count; }; + EGS_Float getFluence() const { + return count; + }; - bool storeFluenceState(ostream &) const { return true; }; + bool storeFluenceState(ostream &) const { + return true; + }; - bool setFluenceState(istream &) { return true; }; + bool setFluenceState(istream &) { + return true; + }; - bool isValid() const { return (s != 0 && shape != 0); }; + bool isValid() const { + return (s != 0 && shape != 0); + }; protected: @@ -189,7 +223,7 @@ class EGS_ISOTROPIC_SOURCE_EXPORT EGS_IsotropicSource : void setUp(); EGS_Float min_theta, max_theta; - EGS_Float buf_1, buf_2; //! avoid multi-calculating cos(min_theta) and cos(max_theta) + EGS_Float buf_1, buf_2; //! avoid multi-calculating cos(min_theta) and cos(max_theta) EGS_Float min_phi, max_phi; int nrs; GeometryConfinement gc; diff --git a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp index 994cddfa3..396c93000 100644 --- a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp +++ b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.cpp @@ -38,36 +38,45 @@ #include "egs_input.h" EGS_ParallelBeam::EGS_ParallelBeam(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), uo(0,0,1) { + EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), shape(0), uo(0,0,1) { vector dir; - if( !input->getInput("direction",dir) ) { - if( dir.size() != 3 ) egsWarning("EGS_ParallelBeam: you must input" - " 3 numbers in the 'direction' input\n" - " but I got %d => ignoring the input\n",dir.size()); + if (!input->getInput("direction",dir)) { + if (dir.size() != 3) egsWarning("EGS_ParallelBeam: you must input" + " 3 numbers in the 'direction' input\n" + " but I got %d => ignoring the input\n",dir.size()); else { - uo.x = dir[0]; uo.y = dir[1]; uo.z = dir[2]; + uo.x = dir[0]; + uo.y = dir[1]; + uo.z = dir[2]; EGS_Float norm = uo.length(); - if( norm < 1e-6 ) { + if (norm < 1e-6) { egsWarning("EGS_ParallelBeam: the length of the direction" - " vector can not be zero => ignoring your input\n"); - uo.x = 0; uo.y = 0; uo.z = 1; - } else uo *= (1./norm); + " vector can not be zero => ignoring your input\n"); + uo.x = 0; + uo.y = 0; + uo.z = 1; + } + else { + uo *= (1./norm); + } } } EGS_Input *ishape = input->takeInputItem("shape"); - if( ishape ) { + if (ishape) { //egsWarning("EGS_ParallelBeam: trying to construct the shape\n"); - shape = EGS_BaseShape::createShape(ishape); delete ishape; + shape = EGS_BaseShape::createShape(ishape); + delete ishape; } - if( !shape ) { - string sname; int err = input->getInput("shape name",sname); - if( err ) + if (!shape) { + string sname; + int err = input->getInput("shape name",sname); + if (err) egsWarning("EGS_ParallelBeam: missing/wrong inline shape " - "definition and missing wrong 'shape name' input\n"); + "definition and missing wrong 'shape name' input\n"); else { shape = EGS_BaseShape::getShape(sname); - if( !shape ) egsWarning("EGS_ParallelBeam: a shape named %s" - " does not exist\n"); + if (!shape) egsWarning("EGS_ParallelBeam: a shape named %s" + " does not exist\n"); } } setUp(); @@ -75,24 +84,34 @@ EGS_ParallelBeam::EGS_ParallelBeam(EGS_Input *input, void EGS_ParallelBeam::setUp() { otype = "EGS_ParallelBeam"; - if( !isValid() ) description = "Invalid parallel beam"; + if (!isValid()) { + description = "Invalid parallel beam"; + } else { description = "Parallel beam from a shape of type "; description += shape->getObjectType(); description += " with "; description += s->getType(); - if( q == -1 ) description += ", electrons"; - else if( q == 0 ) description += ", photons"; - else if( q == 1 ) description += ", positrons"; - else description += ", unknown particle type"; + if (q == -1) { + description += ", electrons"; + } + else if (q == 0) { + description += ", photons"; + } + else if (q == 1) { + description += ", positrons"; + } + else { + description += ", unknown particle type"; + } } } extern "C" { -EGS_PARALLEL_BEAM_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { - return createSourceTemplate(input,f,"parallel beam"); -} + EGS_PARALLEL_BEAM_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return createSourceTemplate(input,f,"parallel beam"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.h b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.h index b9be29b57..4b6a03965 100644 --- a/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.h +++ b/HEN_HOUSE/egs++/sources/egs_parallel_beam/egs_parallel_beam.h @@ -45,22 +45,22 @@ #ifdef WIN32 -#ifdef BUILD_PARALLEL_BEAM_DLL -#define EGS_PARALLEL_BEAM_EXPORT __declspec(dllexport) -#else -#define EGS_PARALLEL_BEAM_EXPORT __declspec(dllimport) -#endif -#define EGS_PARALLEL_BEAM_LOCAL + #ifdef BUILD_PARALLEL_BEAM_DLL + #define EGS_PARALLEL_BEAM_EXPORT __declspec(dllexport) + #else + #define EGS_PARALLEL_BEAM_EXPORT __declspec(dllimport) + #endif + #define EGS_PARALLEL_BEAM_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_PARALLEL_BEAM_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_PARALLEL_BEAM_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_PARALLEL_BEAM_EXPORT -#define EGS_PARALLEL_BEAM_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_PARALLEL_BEAM_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_PARALLEL_BEAM_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_PARALLEL_BEAM_EXPORT + #define EGS_PARALLEL_BEAM_LOCAL + #endif #endif @@ -97,7 +97,7 @@ the parallel beam source from the EGSnrc C++ class library. */ class EGS_PARALLEL_BEAM_EXPORT EGS_ParallelBeam : - public EGS_BaseSimpleSource { + public EGS_BaseSimpleSource { public: @@ -107,9 +107,10 @@ class EGS_PARALLEL_BEAM_EXPORT EGS_ParallelBeam : a shape \a Shape */ EGS_ParallelBeam(int Q, EGS_BaseSpectrum *Spec, EGS_BaseShape *Shape, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSimpleSource(Q,Spec,Name,f), shape(Shape), uo(0,0,1) { - setUp(); }; + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSimpleSource(Q,Spec,Name,f), shape(Shape), uo(0,0,1) { + setUp(); + }; /*! \brief Constructor @@ -121,17 +122,27 @@ class EGS_PARALLEL_BEAM_EXPORT EGS_ParallelBeam : }; void getPositionDirection(EGS_RandomGenerator *rndm, - EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { - x = shape->getRandomPoint(rndm); u = uo; wt = 1; + EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { + x = shape->getRandomPoint(rndm); + u = uo; + wt = 1; }; - EGS_Float getFluence() const { return count/shape->area(); }; + EGS_Float getFluence() const { + return count/shape->area(); + }; - bool storeFluenceState(ostream &) const { return true; }; + bool storeFluenceState(ostream &) const { + return true; + }; - bool setFluenceState(istream &) { return true; }; + bool setFluenceState(istream &) { + return true; + }; - bool isValid() const { return (s != 0 && shape != 0); }; + bool isValid() const { + return (s != 0 && shape != 0); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp index d1e7686d6..5fcb35354 100644 --- a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.cpp @@ -40,134 +40,209 @@ #include "egs_functions.h" EGS_PhspSource::EGS_PhspSource(const string &phsp_file, - const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { - init(); openFile(phsp_file); + const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { + init(); + openFile(phsp_file); } void EGS_PhspSource::init() { otype = "EGS_PhspSource"; - recl = 0; Xmin = -1e30; Xmax = 1e30; Ymin = -1e30; Ymax = 1e30; - is_valid = false; record = 0; mode2 = false; swap_bytes = false; - the_file_name = "no file"; filter_type = -1; particle_type = 2; + recl = 0; + Xmin = -1e30; + Xmax = 1e30; + Ymin = -1e30; + Ymax = 1e30; + is_valid = false; + record = 0; + mode2 = false; + swap_bytes = false; + the_file_name = "no file"; + filter_type = -1; + particle_type = 2; description = "Invalid phase space source"; - Nread = 0; count = 0; Nrecycle = 0; - Npos = 0; Nlast = 0; - wmin = -1e30; wmax = 1e30; - Nreuse_g = 1; Nreuse_e = 1; Nreuse = 1; Nuse = 2; first = true; + Nread = 0; + count = 0; + Nrecycle = 0; + Npos = 0; + Nlast = 0; + wmin = -1e30; + wmax = 1e30; + Nreuse_g = 1; + Nreuse_e = 1; + Nreuse = 1; + Nuse = 2; + first = true; } void EGS_PhspSource::openFile(const string &phsp_file) { - if( the_file.is_open() ) the_file.close(); - the_file_name = "no file"; is_valid = false; recl = 0; - if( record ) { delete [] record; record = 0; } + if (the_file.is_open()) { + the_file.close(); + } + the_file_name = "no file"; + is_valid = false; + recl = 0; + if (record) { + delete [] record; + record = 0; + } the_file.open(phsp_file.c_str(),ios::binary | ios::in); - if( !the_file.is_open() ) { + if (!the_file.is_open()) { egsWarning("EGS_PhspSource::openFile: failed to open binary file %s" - " for reading\n",phsp_file.c_str()); return; + " for reading\n",phsp_file.c_str()); + return; } - string cmode; char auxc; - for(int i=0; i<5; i++) { + string cmode; + char auxc; + for (int i=0; i<5; i++) { the_file.get(auxc); - if( the_file.eof() || !the_file.good() ) { + if (the_file.eof() || !the_file.good()) { egsWarning("EGS_PhspSource::openFile: an I/O error occured " - "while reading the first record of %s\n",phsp_file.c_str()); + "while reading the first record of %s\n",phsp_file.c_str()); return; } cmode += auxc; } - if( cmode == "MODE0" ) { mode2 = false; recl = 28; } - else if( cmode == "MODE2" ) { mode2 = true; recl = 32; } + if (cmode == "MODE0") { + mode2 = false; + recl = 28; + } + else if (cmode == "MODE2") { + mode2 = true; + recl = 32; + } else { egsWarning("EGS_PhspSource::openFile: the file %s is not a MODE0 or" - " MODE2 file\n",phsp_file.c_str()); return; + " MODE2 file\n",phsp_file.c_str()); + return; } record = new char [recl]; - int n, n_photon; float emax, emin, pinc; + int n, n_photon; + float emax, emin, pinc; the_file.read((char *) &n, sizeof(int)); the_file.read((char *) &n_photon, sizeof(int)); the_file.read((char *) &emax, sizeof(float)); the_file.read((char *) &emin, sizeof(float)); the_file.read((char *) &pinc, sizeof(float)); - if( the_file.eof() || !the_file.good() ) { + if (the_file.eof() || !the_file.good()) { egsWarning("EGS_PhspSource::openFile: an I/O error occured " - "while reading the first record of %s\n",phsp_file.c_str()); - recl = 0; return; + "while reading the first record of %s\n",phsp_file.c_str()); + recl = 0; + return; } swap_bytes = false; - if( n <= 0 || n_photon < 0 || n_photon > n || emin < 0 || emax < 0 || - emax < emin || pinc < 0 ) { + if (n <= 0 || n_photon < 0 || n_photon > n || emin < 0 || emax < 0 || + emax < emin || pinc < 0) { swap_bytes = true; - egsSwapBytes(&n); egsSwapBytes(&n_photon); egsSwapBytes(&emin); - egsSwapBytes(&emax); egsSwapBytes(&pinc); - if( n <= 0 || n_photon < 0 || n_photon > n || emin < 0 || emax < 0 || - emax < emin || pinc < 0 ) { + egsSwapBytes(&n); + egsSwapBytes(&n_photon); + egsSwapBytes(&emin); + egsSwapBytes(&emax); + egsSwapBytes(&pinc); + if (n <= 0 || n_photon < 0 || n_photon > n || emin < 0 || emax < 0 || + emax < emin || pinc < 0) { egsWarning("EGS_PhspSource::openFile: phase space file header" - " contains meaningless values with and without byte swaping:\n"); - if( n <= 0 ) egsWarning(" number of particles: %d\n",n); - if( n_photon < 0 ) egsWarning(" number of photons: %d\n",n_photon); - if( n_photon > n ) egsWarning(" number of photons (%d) is " - "greater than number of particles (%d)\n",n_photon,n); - if( emin < 0 ) egsWarning(" minimum energy: %g\n",emin); - if( emax < 0 ) egsWarning(" maximum energy: %g\n",emax); - if( emin > emax ) egsWarning(" emin > emax: %g %g\n",emin,emax); - if( pinc < 0 ) egsWarning(" incident particles: %g\n",pinc); - recl = 0; return; + " contains meaningless values with and without byte swaping:\n"); + if (n <= 0) { + egsWarning(" number of particles: %d\n",n); + } + if (n_photon < 0) { + egsWarning(" number of photons: %d\n",n_photon); + } + if (n_photon > n) egsWarning(" number of photons (%d) is " + "greater than number of particles (%d)\n",n_photon,n); + if (emin < 0) { + egsWarning(" minimum energy: %g\n",emin); + } + if (emax < 0) { + egsWarning(" maximum energy: %g\n",emax); + } + if (emin > emax) { + egsWarning(" emin > emax: %g %g\n",emin,emax); + } + if (pinc < 0) { + egsWarning(" incident particles: %g\n",pinc); + } + recl = 0; + return; } } // at this points we have passed a set of checks and think that // we have some meaningful information about number of particles, etc. // to be completely sure, it is a good idea to read the last particle // in the file and check for errors. - istream::off_type nend = n; nend = nend*recl; + istream::off_type nend = n; + nend = nend*recl; //the_file.seekg(recl*n,ios::beg); the_file.seekg(nend,ios::beg); the_file.read(record,recl*sizeof(char)); - if( the_file.bad() || the_file.fail() ) { + if (the_file.bad() || the_file.fail()) { egsWarning("EGS_PhspSource::openFile: failed to read the last" - " particle in the file, this indicates some unknown error condition\n"); - recl = 0; return; + " particle in the file, this indicates some unknown error condition\n"); + recl = 0; + return; } - the_file.clear(); the_file.seekg(recl,ios::beg); - Npos = 0; Nlast = n; Nfirst = 1; + the_file.clear(); + the_file.seekg(recl,ios::beg); + Npos = 0; + Nlast = n; + Nfirst = 1; // at this point the position should be at the first particle in the file - Emax = emax; Emin = emin; Pinc = pinc; Nparticle = n; Nphoton = n_photon; - is_valid = true; the_file_name = phsp_file; + Emax = emax; + Emin = emin; + Pinc = pinc; + Nparticle = n; + Nphoton = n_photon; + is_valid = true; + the_file_name = phsp_file; } EGS_PhspSource::EGS_PhspSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f) { init(); - string fname; int err = input->getInput("phase space file",fname); - if( err ) { + string fname; + int err = input->getInput("phase space file",fname); + if (err) { egsWarning("EGS_PhspSource: no 'phase space file' input\n"); return; } openFile(fname); - if( !isValid() ) { + if (!isValid()) { egsWarning("EGS_PhspSource: errors while opening the phase space file" - " %s\n",fname.c_str()); return; + " %s\n",fname.c_str()); + return; } vector cutout; err = input->getInput("cutout",cutout); - if( !err && cutout.size() == 4 ) + if (!err && cutout.size() == 4) { setCutout(cutout[0],cutout[1],cutout[2],cutout[3]); + } vector ptype; - ptype.push_back("electrons"); ptype.push_back("photons"); - ptype.push_back("positrons"); ptype.push_back("all"); + ptype.push_back("electrons"); + ptype.push_back("photons"); + ptype.push_back("positrons"); + ptype.push_back("all"); ptype.push_back("charged"); particle_type = input->getInput("particle type",ptype,3)-1; - vector the_filter; vector the_latch; + vector the_filter; + vector the_latch; err = input->getInput("filter type",the_filter); int err1 = input->getInput("latch setting",the_latch); - if( !err && !err1 ) { - if( the_filter[0] >= 0 && the_filter[0] <= 3 ) { - int nbit1 = the_latch[0].size(); int nbit2 = 0; - if( !the_filter[0] ) nbit2 = the_latch[1].size(); - if( nbit1 + nbit2 > 0 ) { + if (!err && !err1) { + if (the_filter[0] >= 0 && the_filter[0] <= 3) { + int nbit1 = the_latch[0].size(); + int nbit2 = 0; + if (!the_filter[0]) { + nbit2 = the_latch[1].size(); + } + if (nbit1 + nbit2 > 0) { int *the_bits = new int [nbit1+nbit2]; - for(int j=0; j wwindow; err = input->getInput("weight window",wwindow); - if( !err && wwindow.size() == 2 ) { - wmin = wwindow[0]; wmax = wwindow[1]; + if (!err && wwindow.size() == 2) { + wmin = wwindow[0]; + wmax = wwindow[1]; + } + int ntmp; + err = input->getInput("reuse photons",ntmp); + if (!err && ntmp > 0) { + Nreuse_g = ntmp; } - int ntmp; err = input->getInput("reuse photons",ntmp); - if( !err && ntmp > 0 ) Nreuse_g = ntmp; err = input->getInput("reuse electrons",ntmp); - if( !err && ntmp > 0 ) Nreuse_e = ntmp; - description = "Phase space source from "; description += the_file_name; + if (!err && ntmp > 0) { + Nreuse_e = ntmp; + } + description = "Phase space source from "; + description += the_file_name; } EGS_I64 EGS_PhspSource::getNextParticle(EGS_RandomGenerator *, int &q, - int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { - if( !recl ) egsFatal("EGS_PhspSource::readParticle(): the file is not " - "open yet\n"); + int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { + if (!recl) egsFatal("EGS_PhspSource::readParticle(): the file is not " + "open yet\n"); /* if( Nuse >= Nreuse ) { do { readParticle(); } while ( rejectParticle() ); } */ - if( Nuse >= Nreuse ) readParticle(); - x.x = p.x; x.y = p.y; x.z = 0; - u.x = p.u; u.y = p.v; + if (Nuse >= Nreuse) { + readParticle(); + } + x.x = p.x; + x.y = p.y; + x.z = 0; + u.x = p.u; + u.y = p.v; EGS_Float aux = p.u*p.u+p.v*p.v; - if( aux < 1 ) aux = sqrt(1-aux); else aux = 0; - if( p.wt > 0 ) { u.z = aux; wt = p.wt; } else { u.z = -aux; wt = -p.wt; } - if( rejectParticle() ) wt = 0; - E = p.E; q = p.q; latch = 0; //latch = p.latch; + if (aux < 1) { + aux = sqrt(1-aux); + } + else { + aux = 0; + } + if (p.wt > 0) { + u.z = aux; + wt = p.wt; + } + else { + u.z = -aux; + wt = -p.wt; + } + if (rejectParticle()) { + wt = 0; + } + E = p.E; + q = p.q; + latch = 0; //latch = p.latch; ++Nuse; return count; } @@ -220,107 +323,176 @@ union __egs_data32 { #endif void EGS_PhspSource::setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun) { - if( nstart < 0 || nrun < 1 || nstart + nrun > Nparticle ) { + if (nstart < 0 || nrun < 1 || nstart + nrun > Nparticle) { egsWarning("EGS_PhspSource::setSimulationChunk(): illegal attempt " - "to set the simulation chunk between %lld and %lld ignored\n", - nstart+1,nstart+nrun); return; + "to set the simulation chunk between %lld and %lld ignored\n", + nstart+1,nstart+nrun); + return; } - Nfirst = nstart+1; Nlast = nstart + nrun; Npos = nstart; + Nfirst = nstart+1; + Nlast = nstart + nrun; + Npos = nstart; istream::off_type pos = Nfirst*recl; the_file.seekg(pos,ios::beg); egsInformation("EGS_PhspSource: using phsp portion between %lld and %lld\n", - Nfirst,Nlast); + Nfirst,Nlast); } void EGS_PhspSource::readParticle() { - if( (++Npos) > Nlast ) { + if ((++Npos) > Nlast) { egsWarning("EGS_PhspSource::readParticle(): reached the end of the " - "phase space file chunk (%lld)\n will start from the beginning " - "of the chunk (%lld) but this " - "implies that uncertainty estimates will be inaccurate\n", - Nlast,Nfirst); - the_file.seekg(recl,ios::beg); Nrecycle++; Npos = Nfirst; - } - the_file.read(record,recl*sizeof(char)); ++Nread; - if( the_file.eof() || !the_file.good() ) + "phase space file chunk (%lld)\n will start from the beginning " + "of the chunk (%lld) but this " + "implies that uncertainty estimates will be inaccurate\n", + Nlast,Nfirst); + the_file.seekg(recl,ios::beg); + Nrecycle++; + Npos = Nfirst; + } + the_file.read(record,recl*sizeof(char)); + ++Nread; + if (the_file.eof() || !the_file.good()) egsFatal("EGS_PhspSource::readParticle(): I/O error while reading " - "phase space file\n"); + "phase space file\n"); __egs_data32 *data; - data = (__egs_data32 *) &record[0]; p.latch = data->i; - data = (__egs_data32 *) &record[4]; p.E = data->f; - data = (__egs_data32 *) &record[8]; p.x = data->f; - data = (__egs_data32 *) &record[12]; p.y = data->f; - data = (__egs_data32 *) &record[16]; p.u = data->f; - data = (__egs_data32 *) &record[20]; p.v = data->f; - data = (__egs_data32 *) &record[24]; p.wt = data->f; - if( swap_bytes ) { - egsSwapBytes(&p.latch); egsSwapBytes(&p.E); egsSwapBytes(&p.wt); - egsSwapBytes(&p.x); egsSwapBytes(&p.y); - egsSwapBytes(&p.u); egsSwapBytes(&p.v); - } - if( p.latch & 1073741824 ) p.q = -1; - else if( p.latch & 536870912 ) p.q = 1; - else p.q = 0; - if( p.E < 0 ) { count++; p.E = -p.E; } - else if( first ) ++count; + data = (__egs_data32 *) &record[0]; + p.latch = data->i; + data = (__egs_data32 *) &record[4]; + p.E = data->f; + data = (__egs_data32 *) &record[8]; + p.x = data->f; + data = (__egs_data32 *) &record[12]; + p.y = data->f; + data = (__egs_data32 *) &record[16]; + p.u = data->f; + data = (__egs_data32 *) &record[20]; + p.v = data->f; + data = (__egs_data32 *) &record[24]; + p.wt = data->f; + if (swap_bytes) { + egsSwapBytes(&p.latch); + egsSwapBytes(&p.E); + egsSwapBytes(&p.wt); + egsSwapBytes(&p.x); + egsSwapBytes(&p.y); + egsSwapBytes(&p.u); + egsSwapBytes(&p.v); + } + if (p.latch & 1073741824) { + p.q = -1; + } + else if (p.latch & 536870912) { + p.q = 1; + } + else { + p.q = 0; + } + if (p.E < 0) { + count++; + p.E = -p.E; + } + else if (first) { + ++count; + } first = false; - if( p.q ) { p.E -= 0.5110034; Nreuse = Nreuse_e; } - else Nreuse = Nreuse_g; - Nuse = 0; p.wt /= Nreuse; + if (p.q) { + p.E -= 0.5110034; + Nreuse = Nreuse_e; + } + else { + Nreuse = Nreuse_g; + } + Nuse = 0; + p.wt /= Nreuse; } bool EGS_PhspSource::rejectParticle() const { - if( particle_type < 2 && p.q != particle_type ) return true; - if( particle_type == 3 && !p.q ) return true; - if( p.x < Xmin || p.x > Xmax || p.y < Ymin || p.y > Ymax ) return true; - if( p.wt < wmin || p.wt > wmax ) return true; - if( p.latch & 2147483648UL ) return true; - if( filter_type < 0 ) return false; - if( filter_type == 0 ) { - bool r1; if( filter1 ) r1 = !(p.latch & filter1); else r1 = false; + if (particle_type < 2 && p.q != particle_type) { + return true; + } + if (particle_type == 3 && !p.q) { + return true; + } + if (p.x < Xmin || p.x > Xmax || p.y < Ymin || p.y > Ymax) { + return true; + } + if (p.wt < wmin || p.wt > wmax) { + return true; + } + if (p.latch & 2147483648UL) { + return true; + } + if (filter_type < 0) { + return false; + } + if (filter_type == 0) { + bool r1; + if (filter1) { + r1 = !(p.latch & filter1); + } + else { + r1 = false; + } bool r2 = (p.latch & filter2); return (r1 || r2); } - if( filter_type == 1 ) return (p.latch & filter1); - int l = p.latch >> 24; bool res = l & filter1; + if (filter_type == 1) { + return (p.latch & filter1); + } + int l = p.latch >> 24; + bool res = l & filter1; return filter_type == 3 ? res : !res; } -void EGS_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits){ - if( type < 0 || type > 3 ) { +void EGS_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits) { + if (type < 0 || type > 3) { egsWarning("EGS_PhspSource::setFilter: invalid filter type %d\n",type); return; } - int ntot = nbit1; if( type == 0 ) ntot += nbit2; - if( ntot > 29 ) { + int ntot = nbit1; + if (type == 0) { + ntot += nbit2; + } + if (ntot > 29) { egsWarning("EGS_PhspSource::setFilter: maximum number of bits is " - "limited to 29, you requested %d\n",ntot); + "limited to 29, you requested %d\n",ntot); + return; + } + if (!ntot) { return; } - if( !ntot ) return; filter_type = type; - if ( filter_type == 0 ) { - int i; filter1 = 0; filter2 = 0; - for(i=0; i(input,f,"phsp source"); -} + EGS_PHSP_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"phsp source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.h b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.h index a2470439c..5aea0dd3e 100644 --- a/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.h +++ b/HEN_HOUSE/egs++/sources/egs_phsp_source/egs_phsp_source.h @@ -47,22 +47,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_PHSP_SOURCE_DLL -#define EGS_PHSP_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_PHSP_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_PHSP_SOURCE_LOCAL + #ifdef BUILD_PHSP_SOURCE_DLL + #define EGS_PHSP_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_PHSP_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_PHSP_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_PHSP_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_PHSP_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_PHSP_SOURCE_EXPORT -#define EGS_PHSP_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_PHSP_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_PHSP_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_PHSP_SOURCE_EXPORT + #define EGS_PHSP_SOURCE_LOCAL + #endif #endif @@ -113,7 +113,7 @@ class EGS_PHSP_SOURCE_EXPORT EGS_PhspSource : public EGS_BaseSource { BEAMnrc phase-space file \a phsp_file. */ EGS_PhspSource(const string &phsp_file, - const string &Name="", EGS_ObjectFactory *f=0); + const string &Name="", EGS_ObjectFactory *f=0); /*! \brief Constructor @@ -123,45 +123,89 @@ class EGS_PHSP_SOURCE_EXPORT EGS_PhspSource : public EGS_BaseSource { ~EGS_PhspSource() { }; EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u); + int &q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u); void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun); - EGS_Float getEmax() const { return Emax; }; + EGS_Float getEmax() const { + return Emax; + }; EGS_Float getFluence() const { double aux = ((double) Nread)/((double) Nparticle); return Pinc*aux; }; bool storeState(ostream &data) const { data << endl; - bool res = egsStoreI64(data,Nread); if( !res ) return res; data << " "; - res = egsStoreI64(data,Nfirst); if( !res ) return res; data << " "; - res = egsStoreI64(data,Nlast); if( !res ) return res; data << " "; - res = egsStoreI64(data,Npos); if( !res ) return res; data << " "; - res = egsStoreI64(data,count); if( !res ) return res; data << " "; + bool res = egsStoreI64(data,Nread); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Nfirst); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Nlast); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Npos); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,count); + if (!res) { + return res; + } + data << " "; return res; }; bool setState(istream &data) { first = false; - bool res = egsGetI64(data,Nread); if( !res ) return res; - res = egsGetI64(data,Nfirst); if( !res ) return res; - res = egsGetI64(data,Nlast); if( !res ) return res; - res = egsGetI64(data,Npos); if( !res ) return res; + bool res = egsGetI64(data,Nread); + if (!res) { + return res; + } + res = egsGetI64(data,Nfirst); + if (!res) { + return res; + } + res = egsGetI64(data,Nlast); + if (!res) { + return res; + } + res = egsGetI64(data,Npos); + if (!res) { + return res; + } the_file.seekg((Npos+1)*recl,ios::beg); - res = egsGetI64(data,count); return res; + res = egsGetI64(data,count); + return res; }; bool addState(istream &data) { EGS_I64 tmp_Nread = Nread, tmp_count = count; bool res = setState(data); - Nread += tmp_Nread; count += tmp_count; + Nread += tmp_Nread; + count += tmp_count; return res; }; - void resetCounter() { Nread = 0; count = 0; }; + void resetCounter() { + Nread = 0; + count = 0; + }; - bool isValid() const { return is_valid; }; + bool isValid() const { + return is_valid; + }; void setCutout(EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, - EGS_Float ymax) { - Xmin = xmin; Xmax = xmax; Ymin = ymin; Ymax = ymax; + EGS_Float ymax) { + Xmin = xmin; + Xmax = xmax; + Ymin = ymin; + Ymax = ymax; }; void setFilter(int, int, int, const int *); @@ -174,7 +218,7 @@ class EGS_PHSP_SOURCE_EXPORT EGS_PhspSource : public EGS_BaseSource { bool mode2; //!< \c true, if a MODE2 file bool swap_bytes; /*!< \c true, if phase-space file was generated on a CPU with different endianness */ - char* record; //!< Memory to read a particle into + char *record; //!< Memory to read a particle into EGS_Float Emax, //!< Maximum energy (obtained from the phsp file) Emin, //!< Minimum energy (obtained from the phsp file) Pinc; //!< Number of incident particles that created the file diff --git a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp index f17d6563d..d99501c6b 100644 --- a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.cpp @@ -41,7 +41,9 @@ EGS_PointSource::EGS_PointSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSimpleSource(input,f), xo(), valid(true) { vector pos; int err = input->getInput("position",pos); - if( !err && pos.size() == 3 ) xo = EGS_Vector(pos[0],pos[1],pos[2]); + if (!err && pos.size() == 3) { + xo = EGS_Vector(pos[0],pos[1],pos[2]); + } else { egsWarning("EGS_PointSource: missing/wrong 'position' input\n"); valid = false; @@ -51,23 +53,33 @@ EGS_PointSource::EGS_PointSource(EGS_Input *input, EGS_ObjectFactory *f) : void EGS_PointSource::setUp() { otype = "EGS_PointSource"; - if( !isValid() ) description = "Invalid point source"; + if (!isValid()) { + description = "Invalid point source"; + } else { description = "Point source with "; description += s->getType(); - if( q == -1 ) description += ", electrons"; - else if( q == 0 ) description += ", photons"; - else if( q == 1 ) description += ", positrons"; - else description += ", unknown particle type"; + if (q == -1) { + description += ", electrons"; + } + else if (q == 0) { + description += ", photons"; + } + else if (q == 1) { + description += ", positrons"; + } + else { + description += ", unknown particle type"; + } } } extern "C" { -EGS_POINT_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { - return createSourceTemplate(input,f,"point source"); -} + EGS_POINT_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return createSourceTemplate(input,f,"point source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.h b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.h index 7e4bdcc67..607736f6d 100644 --- a/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.h +++ b/HEN_HOUSE/egs++/sources/egs_point_source/egs_point_source.h @@ -44,22 +44,22 @@ #ifdef WIN32 -#ifdef BUILD_POINT_SOURCE_DLL -#define EGS_POINT_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_POINT_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_POINT_SOURCE_LOCAL + #ifdef BUILD_POINT_SOURCE_DLL + #define EGS_POINT_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_POINT_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_POINT_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_POINT_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_POINT_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_POINT_SOURCE_EXPORT -#define EGS_POINT_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_POINT_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_POINT_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_POINT_SOURCE_EXPORT + #define EGS_POINT_SOURCE_LOCAL + #endif #endif @@ -100,9 +100,10 @@ class EGS_POINT_SOURCE_EXPORT EGS_PointSource : public EGS_BaseSimpleSource { position \a Xo. The source object takes ownership of the spectrum. */ EGS_PointSource(int Q, EGS_BaseSpectrum *Spec, const EGS_Vector &Xo, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSimpleSource(Q,Spec,Name,f), xo(Xo), valid(true) { - setUp(); }; + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSimpleSource(Q,Spec,Name,f), xo(Xo), valid(true) { + setUp(); + }; /*! \brief Constructor @@ -112,24 +113,39 @@ class EGS_POINT_SOURCE_EXPORT EGS_PointSource : public EGS_BaseSimpleSource { ~EGS_PointSource() {}; void getPositionDirection(EGS_RandomGenerator *rndm, - EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { + EGS_Vector &x, EGS_Vector &u, EGS_Float &wt) { x = xo; - u.z = 2*rndm->getUniform()-1; EGS_Float sinz = 1-u.z*u.z; - if( sinz > 1e-15 ) { - sinz = sqrt(sinz); EGS_Float cphi, sphi; + u.z = 2*rndm->getUniform()-1; + EGS_Float sinz = 1-u.z*u.z; + if (sinz > 1e-15) { + sinz = sqrt(sinz); + EGS_Float cphi, sphi; rndm->getAzimuth(cphi,sphi); - u.x = sinz*cphi; u.y = sinz*sphi; - } else { u.x = 0; u.y = 0; } + u.x = sinz*cphi; + u.y = sinz*sphi; + } + else { + u.x = 0; + u.y = 0; + } wt = 1; }; - EGS_Float getFluence() const { return count; }; + EGS_Float getFluence() const { + return count; + }; - bool storeFluenceState(ostream &) const { return true; }; + bool storeFluenceState(ostream &) const { + return true; + }; - bool setFluenceState(istream &) { return true; }; + bool setFluenceState(istream &) { + return true; + }; - bool isValid() const { return (valid && s != 0); }; + bool isValid() const { + return (valid && s != 0); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp index 4ea5e8f12..5b235aa6f 100644 --- a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp +++ b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.cpp @@ -38,82 +38,108 @@ #include "egs_input.h" EGS_SourceCollection::EGS_SourceCollection(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSource(input,f), nsource(0), count(0) { + EGS_ObjectFactory *f) : EGS_BaseSource(input,f), nsource(0), count(0) { vector s; egsInformation("EGS_BaseSource::EGS_BaseSource: input is:\n"); input->print(0,cout); EGS_Input *isource; - while( (isource = input->takeInputItem("source",false)) ) { + while ((isource = input->takeInputItem("source",false))) { egsInformation("EGS_SourceCollection: got input\n"); EGS_BaseSource *this_source = EGS_BaseSource::createSource(isource); - if(!this_source) egsWarning("EGS_SourceCollection: got null source\n"); - else s.push_back(this_source); + if (!this_source) { + egsWarning("EGS_SourceCollection: got null source\n"); + } + else { + s.push_back(this_source); + } delete isource; } vector snames; int err = input->getInput("source names",snames); - if( !err ) { - for(unsigned int j=0; j prob; err = input->getInput("weights",prob); - if( err ) { + if (err) { egsWarning("EGS_SourceCollection: missing 'weights' input\n"); return; } - if( prob.size() != s.size() ) { + if (prob.size() != s.size()) { egsWarning("EGS_SourceCollection: the number of sources (%d) is not" - " the same as the number of input probabilities (%d)\n", - s.size(),prob.size()); return; + " the same as the number of input probabilities (%d)\n", + s.size(),prob.size()); + return; } setUp(s,prob); } void EGS_SourceCollection::setUp(const vector &S, - const vector &prob) { + const vector &prob) { otype = "EGS_SourceCollection"; nsource = S.size(); - if( prob.size() < nsource ) nsource = prob.size(); + if (prob.size() < nsource) { + nsource = prob.size(); + } description = "Invalid source collection"; - if( isValid() ) { - p = new EGS_Float [nsource]; EGS_Float *dum = new EGS_Float [nsource]; + if (isValid()) { + p = new EGS_Float [nsource]; + EGS_Float *dum = new EGS_Float [nsource]; sources = new EGS_BaseSource* [nsource]; Emax = 0; - for(int j=0; jref(); + dum[j] = 1; + sources[j]->ref(); EGS_Float e = sources[j]->getEmax(); - if( e > Emax ) Emax = e; + if (e > Emax) { + Emax = e; + } } table = new EGS_AliasTable(nsource,dum,p,0); delete [] dum; description = "Source collection"; last_cases = new EGS_I64 [ nsource ]; - for(int i=0; i(input,f,"source collection"); -} + EGS_SOURCE_COLLECTION_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"source collection"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.h b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.h index c027ccd50..dcce1a029 100644 --- a/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.h +++ b/HEN_HOUSE/egs++/sources/egs_source_collection/egs_source_collection.h @@ -44,22 +44,22 @@ #ifdef WIN32 -#ifdef BUILD_SOURCE_COLLECTION_DLL -#define EGS_SOURCE_COLLECTION_EXPORT __declspec(dllexport) -#else -#define EGS_SOURCE_COLLECTION_EXPORT __declspec(dllimport) -#endif -#define EGS_SOURCE_COLLECTION_LOCAL + #ifdef BUILD_SOURCE_COLLECTION_DLL + #define EGS_SOURCE_COLLECTION_EXPORT __declspec(dllexport) + #else + #define EGS_SOURCE_COLLECTION_EXPORT __declspec(dllimport) + #endif + #define EGS_SOURCE_COLLECTION_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_SOURCE_COLLECTION_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_SOURCE_COLLECTION_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_SOURCE_COLLECTION_EXPORT -#define EGS_SOURCE_COLLECTION_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_SOURCE_COLLECTION_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_SOURCE_COLLECTION_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_SOURCE_COLLECTION_EXPORT + #define EGS_SOURCE_COLLECTION_LOCAL + #endif #endif @@ -81,7 +81,7 @@ A source collection is defined using \endverbatim */ class EGS_SOURCE_COLLECTION_EXPORT EGS_SourceCollection : - public EGS_BaseSource { + public EGS_BaseSource { public: @@ -91,10 +91,11 @@ class EGS_SOURCE_COLLECTION_EXPORT EGS_SourceCollection : probabilities \a prob. */ EGS_SourceCollection(const vector &S, - const vector &prob, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSource(Name,f), nsource(0), count(0) { - setUp(S,prob); }; + const vector &prob, + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSource(Name,f), nsource(0), count(0) { + setUp(S,prob); + }; /*! \brief Constructor @@ -102,43 +103,75 @@ class EGS_SOURCE_COLLECTION_EXPORT EGS_SourceCollection : */ EGS_SourceCollection(EGS_Input *, EGS_ObjectFactory *f=0); ~EGS_SourceCollection() { - if( nsource > 0 ) { - for(int j=0; j 0) { + for (int j=0; jsampleBin(rndm); EGS_I64 this_case = sources[j]->getNextParticle(rndm,q,latch,E,wt,x,u); count += this_case - last_cases[j]; last_cases[j] = this_case; return count; }; - EGS_Float getEmax() const { return Emax; }; + EGS_Float getEmax() const { + return Emax; + }; EGS_Float getFluence() const { EGS_Float flu = 0; - for(int j=0; jgetFluence(); + for (int j=0; jgetFluence(); + } return flu; }; bool storeState(ostream &data) const { - bool res = EGS_BaseSource::storeState(data); if( !res ) return res; - res = egsStoreI64(data,count); if( !res ) return res; data << " "; - for(int j=0; jstoreState(data) ) return false; + bool res = EGS_BaseSource::storeState(data); + if (!res) { + return res; + } + res = egsStoreI64(data,count); + if (!res) { + return res; + } + data << " "; + for (int j=0; jstoreState(data)) { + return false; + } } return true; }; bool setState(istream &data) { - bool res = EGS_BaseSource::setState(data); if( !res ) return res; - res = egsGetI64(data,count); if( !res ) return res; - for(int j=0; jsetState(data) ) return false; + bool res = EGS_BaseSource::setState(data); + if (!res) { + return res; + } + res = egsGetI64(data,count); + if (!res) { + return res; + } + for (int j=0; jsetState(data)) { + return false; + } } return true; } @@ -146,22 +179,39 @@ class EGS_SOURCE_COLLECTION_EXPORT EGS_SourceCollection : void resetCounter() { EGS_BaseSource::resetCounter(); count = 0; - for(int j=0; jresetCounter(); } + for (int j=0; jresetCounter(); + } }; virtual bool addState(istream &data_in) { EGS_I64 tmp; - bool res = EGS_BaseSource::addState(data_in); if( !res ) return res; - res = egsGetI64(data_in,tmp); if( !res ) return res; count += tmp; - for(int j=0; jaddState(data_in) ) return false; + if (!sources[j]->addState(data_in)) { + return false; + } } return true; }; - bool isValid() const { return (nsource > 0); }; + bool isValid() const { + return (nsource > 0); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp index 5f777e353..752378241 100644 --- a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp +++ b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.cpp @@ -38,30 +38,35 @@ #include "egs_input.h" EGS_TransformedSource::EGS_TransformedSource(EGS_Input *input, - EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), T(0) { + EGS_ObjectFactory *f) : EGS_BaseSource(input,f), source(0), T(0) { EGS_Input *isource = input->takeInputItem("source",false); - if( isource ) { - source = EGS_BaseSource::createSource(isource); delete isource; + if (isource) { + source = EGS_BaseSource::createSource(isource); + delete isource; } - if( !source ) { - string sname; int err = input->getInput("source name",sname); - if( err ) + if (!source) { + string sname; + int err = input->getInput("source name",sname); + if (err) egsWarning("EGS_TransformedSource: missing/wrong inline source " - "definition and missing wrong 'source name' input\n"); + "definition and missing wrong 'source name' input\n"); else { source = EGS_BaseSource::getSource(sname); - if( !source ) egsWarning("EGS_TransformedSource: a source named %s" - " does not exist\n"); + if (!source) egsWarning("EGS_TransformedSource: a source named %s" + " does not exist\n"); } } EGS_AffineTransform *t = EGS_AffineTransform::getTransformation(input); - setUp(t); delete t; + setUp(t); + delete t; } void EGS_TransformedSource::setUp(EGS_AffineTransform *t) { setTransformation(t); otype = "EGS_TransformedSource"; - if( !isValid() ) description = "Invalid transformed source"; + if (!isValid()) { + description = "Invalid transformed source"; + } else { description = "Transformed "; description += source->getSourceDescription(); @@ -71,9 +76,10 @@ void EGS_TransformedSource::setUp(EGS_AffineTransform *t) { extern "C" { -EGS_TRANSFORMED_SOURCE_EXPORT EGS_BaseSource* createSource(EGS_Input *input, - EGS_ObjectFactory *f) { return - createSourceTemplate(input,f,"transformed source"); -} + EGS_TRANSFORMED_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"transformed source"); + } } diff --git a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.h b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.h index 2a99a4793..1e1acae22 100644 --- a/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.h +++ b/HEN_HOUSE/egs++/sources/egs_transformed_source/egs_transformed_source.h @@ -45,22 +45,22 @@ #ifdef WIN32 -#ifdef BUILD_TRANSFORMED_SOURCE_DLL -#define EGS_TRANSFORMED_SOURCE_EXPORT __declspec(dllexport) -#else -#define EGS_TRANSFORMED_SOURCE_EXPORT __declspec(dllimport) -#endif -#define EGS_TRANSFORMED_SOURCE_LOCAL + #ifdef BUILD_TRANSFORMED_SOURCE_DLL + #define EGS_TRANSFORMED_SOURCE_EXPORT __declspec(dllexport) + #else + #define EGS_TRANSFORMED_SOURCE_EXPORT __declspec(dllimport) + #endif + #define EGS_TRANSFORMED_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define EGS_TRANSFORMED_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define EGS_TRANSFORMED_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define EGS_TRANSFORMED_SOURCE_EXPORT -#define EGS_TRANSFORMED_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define EGS_TRANSFORMED_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define EGS_TRANSFORMED_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define EGS_TRANSFORMED_SOURCE_EXPORT + #define EGS_TRANSFORMED_SOURCE_LOCAL + #endif #endif @@ -88,7 +88,7 @@ on the definition of an affine transformation. */ class EGS_TRANSFORMED_SOURCE_EXPORT EGS_TransformedSource : - public EGS_BaseSource { + public EGS_BaseSource { public: @@ -96,37 +96,64 @@ class EGS_TRANSFORMED_SOURCE_EXPORT EGS_TransformedSource : source and \a t as the transformation */ EGS_TransformedSource(EGS_BaseSource *Source, - EGS_AffineTransform *t, - const string &Name="", EGS_ObjectFactory *f=0) : - EGS_BaseSource(Name,f), source(Source), T(0) { - setUp(t); }; + EGS_AffineTransform *t, + const string &Name="", EGS_ObjectFactory *f=0) : + EGS_BaseSource(Name,f), source(Source), T(0) { + setUp(t); + }; /*! \brief Construct a transformed source from the input \a inp */ EGS_TransformedSource(EGS_Input *, EGS_ObjectFactory *f=0); void setTransformation(EGS_AffineTransform *t) { - if( T ) { delete T; T = 0; } - if( t ) T = new EGS_AffineTransform(*t); + if (T) { + delete T; + T = 0; + } + if (t) { + T = new EGS_AffineTransform(*t); + } + }; + const EGS_AffineTransform *getTransform() const { + return T; }; - const EGS_AffineTransform *getTransform() const { return T; }; ~EGS_TransformedSource() { EGS_Object::deleteObject(source); - if( T ) delete T; + if (T) { + delete T; + } }; EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u) { + int &q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u) { EGS_I64 c = source->getNextParticle(rndm,q,latch,E,wt,x,u); - if( T ) { T->rotate(u); T->transform(x); } + if (T) { + T->rotate(u); + T->transform(x); + } return c; }; - EGS_Float getEmax() const { return source->getEmax(); }; - EGS_Float getFluence() const { return source->getFluence(); }; - bool storeState(ostream &data) const { return source->storeState(data); }; - bool setState(istream &data) { return source->setState(data); }; - bool addState(istream &data_in) { return source->addState(data_in); }; - void resetCounter() { source->resetCounter(); }; - - bool isValid() const { return (source != 0); }; + EGS_Float getEmax() const { + return source->getEmax(); + }; + EGS_Float getFluence() const { + return source->getFluence(); + }; + bool storeState(ostream &data) const { + return source->storeState(data); + }; + bool setState(istream &data) { + return source->setState(data); + }; + bool addState(istream &data_in) { + return source->addState(data_in); + }; + void resetCounter() { + source->resetCounter(); + }; + + bool isValid() const { + return (source != 0); + }; protected: diff --git a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp index 8a616f3d0..16326114c 100644 --- a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp +++ b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.cpp @@ -40,59 +40,78 @@ #include "egs_functions.h" IAEA_PhspSource::IAEA_PhspSource(const string &phsp_file, - const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { - init(); openFile(phsp_file); + const string &Name, EGS_ObjectFactory *f) : EGS_BaseSource(Name,f) { + init(); + openFile(phsp_file); } void IAEA_PhspSource::init() { otype = "IAEA_PhspSource"; - Xmin = -1e30; Xmax = 1e30; Ymin = -1e30; Ymax = 1e30; - is_valid = false; mode2 = false; swap_bytes = false; - the_file_name = "no file"; filter_type = -1; particle_type = 2; + Xmin = -1e30; + Xmax = 1e30; + Ymin = -1e30; + Ymax = 1e30; + is_valid = false; + mode2 = false; + swap_bytes = false; + the_file_name = "no file"; + filter_type = -1; + particle_type = 2; description = "Invalid IAEA phase space source"; - Nread = 0; count = 0; Nrecycle = 0; - Npos = 0; Nlast = 0; - wmin = -1e30; wmax = 1e30; - Nreuse_g = 1; Nreuse_e = 1; Nreuse = 1; Nuse = 2; first = true; + Nread = 0; + count = 0; + Nrecycle = 0; + Npos = 0; + Nlast = 0; + wmin = -1e30; + wmax = 1e30; + Nreuse_g = 1; + Nreuse_e = 1; + Nreuse = 1; + Nuse = 2; + first = true; } void IAEA_PhspSource::openFile(const string &phsp_file) { - the_file_name = "no file"; is_valid = false; + the_file_name = "no file"; + is_valid = false; int rwmode=1; //read only iaea_fileid=0; //this is just an array index for the iaea routines, not an actual - //unit no., as in Fortran, so it can really be any integer value - //not above MAX_NUM_SOURCES (30) + //unit no., as in Fortran, so it can really be any integer value + //not above MAX_NUM_SOURCES (30) //below is required because iaea opening routine gets file name as char array int len = phsp_file.length(); char phsp_name_tmp[len+1]; phsp_file.copy(phsp_name_tmp,len,0); //now put a null character on the end - phsp_name_tmp[len]='\0'; + phsp_name_tmp[len]='\0'; //use iaea function for opening phase space file iaea_new_source(&iaea_fileid,phsp_name_tmp,&rwmode,&iaea_iostat,len); if (iaea_iostat==105) { egsWarning("IAEA_PhspSource::openFile: no header file name supplied.\n"); - return; + return; } - else if( iaea_iostat==-96 ) { + else if (iaea_iostat==-96) { egsWarning("IAEA_PhspSource::openFile: failed to open header file %s.IAEAheader\n" - " for reading\n",phsp_file.c_str()); return; + " for reading\n",phsp_file.c_str()); + return; } - else if( iaea_iostat==-94 ) { + else if (iaea_iostat==-94) { egsWarning("IAEA_PhspSource::openFile: failed to open phase space file %s.IAEAphsp\n" - " for reading\n",phsp_file.c_str()); return; + " for reading\n",phsp_file.c_str()); + return; } - else if( iaea_iostat==-1 ) { + else if (iaea_iostat==-1) { egsWarning("IAEA_PhspSource::openFile: failed to initialize phase space source %s\n",phsp_file.c_str()); return; } - else if( iaea_iostat==-91 ) { + else if (iaea_iostat==-91) { egsWarning("IAEA_PhspSource::openFile: failed to get record contents from header file %s.IAEAheader\n",phsp_file.c_str()); return; } - else if( iaea_iostat <0 ) { + else if (iaea_iostat <0) { egsWarning("IAEA_PhspSource::openFile: I/O error ocurred on opening phase space file %s\n",phsp_file.c_str()); return; } @@ -102,108 +121,140 @@ void IAEA_PhspSource::openFile(const string &phsp_file) { swap_bytes = false; iaea_check_file_size_byte_order(&iaea_fileid,&iaea_iostat); if (iaea_iostat==-1) { - egsWarning("IAEA_PhspSource::openFile: error reading file size/byte order from header %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: error reading file size/byte order from header %s.IAEAheader\n",phsp_file.c_str()); + return; } else if (iaea_iostat==-4) { - egsWarning("IAEA_PhspSource::openFile: byte mismatch between phase space file and machine. Will swap bytes.\n"); - swap_bytes = true; + egsWarning("IAEA_PhspSource::openFile: byte mismatch between phase space file and machine. Will swap bytes.\n"); + swap_bytes = true; } else if (iaea_iostat==-3 || iaea_iostat==-5) { - egsWarning("IAEA_PhspSource::openFile: mismatch between file size in header and actual file size of %s\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: mismatch between file size in header and actual file size of %s\n",phsp_file.c_str()); + return; } //now get some info from the header - EGS_I64 n, n_photon, pinc; float emax, zposn; + EGS_I64 n, n_photon, pinc; + float emax, zposn; int iaea_type=-1; //for getting no. of particles iaea_get_max_particles(&iaea_fileid,&iaea_type,&n); if (n<0) { - egsWarning("IAEA_PhspSource::openFile: failed to get total no. of particles from %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get total no. of particles from %s.IAEAheader\n",phsp_file.c_str()); + return; } iaea_type=1; //for getting no. of photons iaea_get_max_particles(&iaea_fileid,&iaea_type,&n_photon); if (n_photon<0) { - egsWarning("IAEA_PhspSource::openFile: failed to get no. of photons from %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get no. of photons from %s.IAEAheader\n",phsp_file.c_str()); + return; } //now get max. energy iaea_get_maximum_energy(&iaea_fileid,&emax); if (emax<0) { - egsWarning("IAEA_PhspSource::openFile: failed to get max. energy from %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get max. energy from %s.IAEAheader\n",phsp_file.c_str()); + return; } //no. of particles incident from original source iaea_get_total_original_particles(&iaea_fileid,&pinc); if (pinc<0) { - egsWarning("IAEA_PhspSource::openFile: failed to get no. of original particles from %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get no. of original particles from %s.IAEAheader\n",phsp_file.c_str()); + return; } //get number of extra float and extra long variables so we can set array dimensions iaea_get_extra_numbers(&iaea_fileid,&n_extra_floats,&n_extra_longs); if (n_extra_floats==-1 || n_extra_longs==-1) { - egsWarning("IAEA_PhspSource::openFile: failed to get no. of extra floats and longs stored in %s.IAEAphsp\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get no. of extra floats and longs stored in %s.IAEAphsp\n",phsp_file.c_str()); + return; } //determine if Zlast is stored in the file and, if so, its array index, i_zlast int extrafloat_types[n_extra_floats], extralong_types[n_extra_longs]; iaea_get_type_extra_variables(&iaea_fileid,&iaea_iostat,extralong_types,extrafloat_types); if (iaea_iostat==-1) { - egsWarning("IAEA_PhspSource::openFile: failed to get Mode of data %s.IAEAheader\n",phsp_file.c_str()); - return; + egsWarning("IAEA_PhspSource::openFile: failed to get Mode of data %s.IAEAheader\n",phsp_file.c_str()); + return; } mode2=false; - for (int i=0; i< n_extra_floats; i++) { if (extrafloat_types[i]==3) { mode2=true; i_zlast=i; break; } } + for (int i=0; i< n_extra_floats; i++) { + if (extrafloat_types[i]==3) { + mode2=true; + i_zlast=i; + break; + } + } //determine array index of latch latch_stored=false; - for (int i=0; i< n_extra_longs; i++) { if (extralong_types[i]==2) { latch_stored=true; i_latch=i; break; } } + for (int i=0; i< n_extra_longs; i++) { + if (extralong_types[i]==2) { + latch_stored=true; + i_latch=i; + break; + } + } if (!latch_stored) { - egsWarning("IAEA_PhspSource::openFile: LATCH is not stored in data in %s.IAEAphsp\n",phsp_file.c_str()); + egsWarning("IAEA_PhspSource::openFile: LATCH is not stored in data in %s.IAEAphsp\n",phsp_file.c_str()); } - Npos = 0; Nlast = n; Nfirst = 1; + Npos = 0; + Nlast = n; + Nfirst = 1; // at this point the position should be at the first particle in the file - Emax = emax; Pinc = pinc; Nparticle = n; Nphoton = n_photon; - is_valid = true; the_file_name = phsp_file; + Emax = emax; + Pinc = pinc; + Nparticle = n; + Nphoton = n_photon; + is_valid = true; + the_file_name = phsp_file; } IAEA_PhspSource::IAEA_PhspSource(EGS_Input *input, EGS_ObjectFactory *f) : EGS_BaseSource(input,f) { init(); - string fname; int err = input->getInput("iaea phase space file",fname); - if( err ) { + string fname; + int err = input->getInput("iaea phase space file",fname); + if (err) { egsWarning("IAEA_PhspSource: no 'iaea phase space file' input\n"); return; } openFile(fname); - if( !isValid() ) { + if (!isValid()) { egsWarning("IAEA_PhspSource: errors while opening the phase space file" - " %s\n",fname.c_str()); return; + " %s\n",fname.c_str()); + return; } vector cutout; err = input->getInput("cutout",cutout); - if( !err && cutout.size() == 4 ) + if (!err && cutout.size() == 4) { setCutout(cutout[0],cutout[1],cutout[2],cutout[3]); + } vector ptype; - ptype.push_back("electrons"); ptype.push_back("photons"); - ptype.push_back("positrons"); ptype.push_back("all"); + ptype.push_back("electrons"); + ptype.push_back("photons"); + ptype.push_back("positrons"); + ptype.push_back("all"); ptype.push_back("charged"); particle_type = input->getInput("particle type",ptype,3)-1; - vector the_filter; vector the_latch; + vector the_filter; + vector the_latch; err = input->getInput("filter type",the_filter); int err1 = input->getInput("latch setting",the_latch); - if( !err && !err1 ) { - if( the_filter[0] >= 0 && the_filter[0] <= 3 ) { - int nbit1 = the_latch[0].size(); int nbit2 = 0; - if( !the_filter[0] ) nbit2 = the_latch[1].size(); - if( nbit1 + nbit2 > 0 ) { + if (!err && !err1) { + if (the_filter[0] >= 0 && the_filter[0] <= 3) { + int nbit1 = the_latch[0].size(); + int nbit2 = 0; + if (!the_filter[0]) { + nbit2 = the_latch[1].size(); + } + if (nbit1 + nbit2 > 0) { int *the_bits = new int [nbit1+nbit2]; - for(int j=0; j wwindow; err = input->getInput("weight window",wwindow); - if( !err && wwindow.size() == 2 ) { - wmin = wwindow[0]; wmax = wwindow[1]; + if (!err && wwindow.size() == 2) { + wmin = wwindow[0]; + wmax = wwindow[1]; + } + int ntmp; + err = input->getInput("reuse photons",ntmp); + if (!err && ntmp > 0) { + Nreuse_g = ntmp; } - int ntmp; err = input->getInput("reuse photons",ntmp); - if( !err && ntmp > 0 ) Nreuse_g = ntmp; err = input->getInput("reuse electrons",ntmp); - if( !err && ntmp > 0 ) Nreuse_e = ntmp; - description = "IAEA phase space source from "; description += the_file_name; + if (!err && ntmp > 0) { + Nreuse_e = ntmp; + } + description = "IAEA phase space source from "; + description += the_file_name; } EGS_I64 IAEA_PhspSource::getNextParticle(EGS_RandomGenerator *, int &q, - int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { + int &latch, EGS_Float &E, EGS_Float &wt, EGS_Vector &x, EGS_Vector &u) { /* if( Nuse >= Nreuse ) { do { readParticle(); } while ( rejectParticle() ); @@ -231,58 +289,91 @@ EGS_I64 IAEA_PhspSource::getNextParticle(EGS_RandomGenerator *, int &q, */ int nstat,extrainttemp[n_extra_longs]; float extrafloattemp[n_extra_floats]; - if( Nuse >= Nreuse ) { //get a new particle - if( (++Npos) > Nlast ) { - egsWarning("IAEA_PhspSource::getNextParticle(): reached the end of the " - "phase space file chunk (%lld)\n will start from the beginning " - "of the chunk (%lld) but this " - "implies that uncertainty estimates will be inaccurate\n", - Nlast,Nfirst); - iaea_set_record(&iaea_fileid,&Nfirst,&iaea_iostat); - if(iaea_iostat<0) { - egsFatal("IAEA_PhspSource::getNextParticle(): error restarting phase space chunk\n"); + if (Nuse >= Nreuse) { //get a new particle + if ((++Npos) > Nlast) { + egsWarning("IAEA_PhspSource::getNextParticle(): reached the end of the " + "phase space file chunk (%lld)\n will start from the beginning " + "of the chunk (%lld) but this " + "implies that uncertainty estimates will be inaccurate\n", + Nlast,Nfirst); + iaea_set_record(&iaea_fileid,&Nfirst,&iaea_iostat); + if (iaea_iostat<0) { + egsFatal("IAEA_PhspSource::getNextParticle(): error restarting phase space chunk\n"); + } + Nrecycle++; + Npos = Nfirst; + } + iaea_get_particle(&iaea_fileid,&nstat,&p.q,&p.E,&p.wt,&p.x,&p.y,&p.z,&p.u,&p.v,&p.w,extrafloattemp,extrainttemp); + ++Nread; + if (latch_stored) { + p.latch = extrainttemp[i_latch]; + } + if (mode2) { + p.zlast = extrafloattemp[i_zlast]; + } + if (swap_bytes) { + egsSwapBytes(&p.q); + egsSwapBytes(&nstat); + egsSwapBytes(&p.zlast); + egsSwapBytes(&p.latch); + egsSwapBytes(&p.E); + egsSwapBytes(&p.wt); + egsSwapBytes(&p.x); + egsSwapBytes(&p.y); + egsSwapBytes(&p.z); + egsSwapBytes(&p.u); + egsSwapBytes(&p.v); + egsSwapBytes(&p.w); + } + //do check here because we need the swapped version of nstat + if (nstat<0) { + egsFatal("IAEA_PhspSource::getNextParticle(): error reading particle number %i\n",Npos); } - Nrecycle++; Npos = Nfirst; - } - iaea_get_particle(&iaea_fileid,&nstat,&p.q,&p.E,&p.wt,&p.x,&p.y,&p.z,&p.u,&p.v,&p.w,extrafloattemp,extrainttemp); - ++Nread; - if(latch_stored) p.latch = extrainttemp[i_latch]; - if(mode2) p.zlast = extrafloattemp[i_zlast]; - if(swap_bytes) { - egsSwapBytes(&p.q); egsSwapBytes(&nstat); egsSwapBytes(&p.zlast); - egsSwapBytes(&p.latch); egsSwapBytes(&p.E); egsSwapBytes(&p.wt); - egsSwapBytes(&p.x); egsSwapBytes(&p.y); egsSwapBytes(&p.z); - egsSwapBytes(&p.u); egsSwapBytes(&p.v); egsSwapBytes(&p.w); - } - //do check here because we need the swapped version of nstat - if(nstat<0){ - egsFatal("IAEA_PhspSource::getNextParticle(): error reading particle number %i\n",Npos); - } - //convert charge from iaea type - if(p.q==1) p.q=0; - else if(p.q==2) p.q=-1; - else if(p.q==3) p.q=1; - else { - egsFatal("IAEA_PhspSource::getNextParticle: unknown charge on particle\n"); - } - if(!latch_stored) p.latch = 0; //need some non-nonsense value in case there is a LATCH filter - //note: we don't have to convert to p.E to K.E. because that's what IAEA format stores - if(first || nstat>0) count++; //increment primary history counter - first= false; - //store Nreuse - if(p.q) Nreuse = Nreuse_e; - else Nreuse = Nreuse_g; - //reset Nuse - Nuse = 0; - p.wt /= Nreuse; + //convert charge from iaea type + if (p.q==1) { + p.q=0; + } + else if (p.q==2) { + p.q=-1; + } + else if (p.q==3) { + p.q=1; + } + else { + egsFatal("IAEA_PhspSource::getNextParticle: unknown charge on particle\n"); + } + if (!latch_stored) { + p.latch = 0; //need some non-nonsense value in case there is a LATCH filter + } + //note: we don't have to convert to p.E to K.E. because that's what IAEA format stores + if (first || nstat>0) { + count++; //increment primary history counter + } + first= false; + //store Nreuse + if (p.q) { + Nreuse = Nreuse_e; + } + else { + Nreuse = Nreuse_g; + } + //reset Nuse + Nuse = 0; + p.wt /= Nreuse; } //energy, wt, position and direction cosines - x.x = p.x; x.y = p.y; x.z = p.z; - u.x = p.u; u.y = p.v, u.z = p.w; + x.x = p.x; + x.y = p.y; + x.z = p.z; + u.x = p.u; + u.y = p.v, u.z = p.w; wt=p.wt; - if( rejectParticle() ) wt = 0; - E=p.E; q=p.q; + if (rejectParticle()) { + wt = 0; + } + E=p.E; + q=p.q; //latch = 0; latch= p.latch; //rejectParticle uses BeamParticle, p @@ -303,73 +394,111 @@ union __egs_data32 { #endif void IAEA_PhspSource::setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun) { - if( nstart < 0 || nrun < 1 || nstart + nrun > Nparticle ) { + if (nstart < 0 || nrun < 1 || nstart + nrun > Nparticle) { egsWarning("IAEA_PhspSource::setSimulationChunk(): illegal attempt " - "to set the simulation chunk between %lld and %lld ignored\n", - nstart+1,nstart+nrun); return; + "to set the simulation chunk between %lld and %lld ignored\n", + nstart+1,nstart+nrun); + return; } - Nfirst = nstart+1; Nlast = nstart + nrun; Npos = nstart; + Nfirst = nstart+1; + Nlast = nstart + nrun; + Npos = nstart; iaea_set_record(&iaea_fileid,&Nfirst,&iaea_iostat); - if(iaea_iostat<0) { - egsWarning("IAEA_PhspSource::setSimulationChunk(): error setting phase space chunk\n"); - return; + if (iaea_iostat<0) { + egsWarning("IAEA_PhspSource::setSimulationChunk(): error setting phase space chunk\n"); + return; } egsInformation("IAEA_PhspSource: using phsp portion between %lld and %lld\n", - Nfirst,Nlast); + Nfirst,Nlast); } bool IAEA_PhspSource::rejectParticle() const { - if( particle_type < 2 && p.q != particle_type ) return true; - if( particle_type == 3 && !p.q ) return true; - if( p.x < Xmin || p.x > Xmax || p.y < Ymin || p.y > Ymax ) return true; - if( p.wt < wmin || p.wt > wmax ) return true; - if( p.latch & 2147483648UL ) return true; - if( filter_type < 0 ) return false; - if( filter_type == 1 ) { - bool r1; if( filter1 ) r1 = !(p.latch & filter1); else r1 = false; + if (particle_type < 2 && p.q != particle_type) { + return true; + } + if (particle_type == 3 && !p.q) { + return true; + } + if (p.x < Xmin || p.x > Xmax || p.y < Ymin || p.y > Ymax) { + return true; + } + if (p.wt < wmin || p.wt > wmax) { + return true; + } + if (p.latch & 2147483648UL) { + return true; + } + if (filter_type < 0) { + return false; + } + if (filter_type == 1) { + bool r1; + if (filter1) { + r1 = !(p.latch & filter1); + } + else { + r1 = false; + } bool r2 = (p.latch & filter2); return (r1 || r2); } - if( filter_type == 1 ) return (p.latch & filter1); - int l = p.latch >> 24; bool res = l & filter1; + if (filter_type == 1) { + return (p.latch & filter1); + } + int l = p.latch >> 24; + bool res = l & filter1; return filter_type == 3 ? res : !res; } -void IAEA_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits){ - if( type < 0 || type > 3 ) { +void IAEA_PhspSource::setFilter(int type, int nbit1, int nbit2, const int *bits) { + if (type < 0 || type > 3) { egsWarning("IAEA_PhspSource::setFilter: invalid filter type %d\n",type); return; } - int ntot = nbit1; if( type == 0 ) ntot += nbit2; - if( ntot > 29 ) { + int ntot = nbit1; + if (type == 0) { + ntot += nbit2; + } + if (ntot > 29) { egsWarning("IAEA_PhspSource::setFilter: maximum number of bits is " - "limited to 29, you requested %d\n",ntot); + "limited to 29, you requested %d\n",ntot); + return; + } + if (!ntot) { return; } - if( !ntot ) return; filter_type = type; - if ( filter_type == 0 ) { - int i; filter1 = 0; filter2 = 0; - for(i=0; i(input,f,"iaea phsp source"); -} + IAEA_PHSP_SOURCE_EXPORT EGS_BaseSource *createSource(EGS_Input *input, + EGS_ObjectFactory *f) { + return + createSourceTemplate(input,f,"iaea phsp source"); + } } diff --git a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.h b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.h index 20e092d4a..6bafdcd82 100644 --- a/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.h +++ b/HEN_HOUSE/egs++/sources/iaea_phsp_source/iaea_phsp_source.h @@ -47,22 +47,22 @@ using namespace std; #ifdef WIN32 -#ifdef BUILD_IAEA_PHSP_SOURCE_DLL -#define IAEA_PHSP_SOURCE_EXPORT __declspec(dllexport) -#else -#define IAEA_PHSP_SOURCE_EXPORT __declspec(dllimport) -#endif -#define IAEA_PHSP_SOURCE_LOCAL + #ifdef BUILD_IAEA_PHSP_SOURCE_DLL + #define IAEA_PHSP_SOURCE_EXPORT __declspec(dllexport) + #else + #define IAEA_PHSP_SOURCE_EXPORT __declspec(dllimport) + #endif + #define IAEA_PHSP_SOURCE_LOCAL #else -#ifdef HAVE_VISIBILITY -#define IAEA_PHSP_SOURCE_EXPORT __attribute__ ((visibility ("default"))) -#define IAEA_PHSP_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define IAEA_PHSP_SOURCE_EXPORT -#define IAEA_PHSP_SOURCE_LOCAL -#endif + #ifdef HAVE_VISIBILITY + #define IAEA_PHSP_SOURCE_EXPORT __attribute__ ((visibility ("default"))) + #define IAEA_PHSP_SOURCE_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define IAEA_PHSP_SOURCE_EXPORT + #define IAEA_PHSP_SOURCE_LOCAL + #endif #endif @@ -118,7 +118,7 @@ class IAEA_PHSP_SOURCE_EXPORT IAEA_PhspSource : public EGS_BaseSource { IAEA format phase-space file \a phsp_file. */ IAEA_PhspSource(const string &phsp_file, - const string &Name="", EGS_ObjectFactory *f=0); + const string &Name="", EGS_ObjectFactory *f=0); /*! \brief Constructor @@ -128,46 +128,90 @@ class IAEA_PHSP_SOURCE_EXPORT IAEA_PhspSource : public EGS_BaseSource { ~IAEA_PhspSource() { }; EGS_I64 getNextParticle(EGS_RandomGenerator *rndm, - int &q, int &latch, EGS_Float &E, EGS_Float &wt, - EGS_Vector &x, EGS_Vector &u); + int &q, int &latch, EGS_Float &E, EGS_Float &wt, + EGS_Vector &x, EGS_Vector &u); void setSimulationChunk(EGS_I64 nstart, EGS_I64 nrun); - EGS_Float getEmax() const { return Emax; }; + EGS_Float getEmax() const { + return Emax; + }; EGS_Float getFluence() const { double aux = ((double) Nread)/((double) Nparticle); return Pinc*aux; }; bool storeState(ostream &data) const { data << endl; - bool res = egsStoreI64(data,Nread); if( !res ) return res; data << " "; - res = egsStoreI64(data,Nfirst); if( !res ) return res; data << " "; - res = egsStoreI64(data,Nlast); if( !res ) return res; data << " "; - res = egsStoreI64(data,Npos); if( !res ) return res; data << " "; - res = egsStoreI64(data,count); if( !res ) return res; data << " "; + bool res = egsStoreI64(data,Nread); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Nfirst); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Nlast); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,Npos); + if (!res) { + return res; + } + data << " "; + res = egsStoreI64(data,count); + if (!res) { + return res; + } + data << " "; return res; }; bool setState(istream &data) { first = false; - bool res = egsGetI64(data,Nread); if( !res ) return res; - res = egsGetI64(data,Nfirst); if( !res ) return res; - res = egsGetI64(data,Nlast); if( !res ) return res; - res = egsGetI64(data,Npos); if( !res ) return res; + bool res = egsGetI64(data,Nread); + if (!res) { + return res; + } + res = egsGetI64(data,Nfirst); + if (!res) { + return res; + } + res = egsGetI64(data,Nlast); + if (!res) { + return res; + } + res = egsGetI64(data,Npos); + if (!res) { + return res; + } Npos++; iaea_set_record(&iaea_fileid,&Npos,&iaea_iostat); - res = egsGetI64(data,count); return res; + res = egsGetI64(data,count); + return res; }; bool addState(istream &data) { EGS_I64 tmp_Nread = Nread, tmp_count = count; bool res = setState(data); - Nread += tmp_Nread; count += tmp_count; + Nread += tmp_Nread; + count += tmp_count; return res; }; - void resetCounter() { Nread = 0; count = 0; }; + void resetCounter() { + Nread = 0; + count = 0; + }; - bool isValid() const { return is_valid; }; + bool isValid() const { + return is_valid; + }; void setCutout(EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, - EGS_Float ymax) { - Xmin = xmin; Xmax = xmax; Ymin = ymin; Ymax = ymax; + EGS_Float ymax) { + Xmin = xmin; + Xmax = xmax; + Ymin = ymin; + Ymax = ymax; }; void setFilter(int, int, int, const int *); diff --git a/HEN_HOUSE/egs++/test_geometry.cpp b/HEN_HOUSE/egs++/test_geometry.cpp index 925d8c2f1..3318053fc 100644 --- a/HEN_HOUSE/egs++/test_geometry.cpp +++ b/HEN_HOUSE/egs++/test_geometry.cpp @@ -48,12 +48,17 @@ using namespace std; int main(int argc, char **argv) { - if( argc < 2 ) egsFatal("Usage: %s input_file\n",argv[0]); + if (argc < 2) { + egsFatal("Usage: %s input_file\n",argv[0]); + } - EGS_Input input; input.setContentFromFile(argv[1]); + EGS_Input input; + input.setContentFromFile(argv[1]); //input.print(0,cout); EGS_BaseGeometry *g = EGS_BaseGeometry::createGeometry(&input); - if( !g ) egsFatal("\nGot a null geometry? Check your input file\n\n"); + if (!g) { + egsFatal("\nGot a null geometry? Check your input file\n\n"); + } EGS_BaseGeometry::describeGeometries(); EGS_GeometryTester *tester = EGS_GeometryTester::getGeometryTester(&input); diff --git a/HEN_HOUSE/egs++/test_source.cpp b/HEN_HOUSE/egs++/test_source.cpp index 9ba2e2a5b..3606b0400 100644 --- a/HEN_HOUSE/egs++/test_source.cpp +++ b/HEN_HOUSE/egs++/test_source.cpp @@ -36,24 +36,33 @@ int main(int argc, char **argv) { - if( argc < 2 ) egsFatal("Usage: %s input_file\n",argv[0]); + if (argc < 2) { + egsFatal("Usage: %s input_file\n",argv[0]); + } - EGS_Input input; input.setContentFromFile(argv[1]); + EGS_Input input; + input.setContentFromFile(argv[1]); EGS_ObjectFactory *factory = new EGS_ObjectFactory("egs++/dso/gcc"); EGS_Object *o = factory->createObjects(&input,"source input", - "source","main source","createSource"); + "source","main source","createSource"); - if( !o ) egsFatal("Got null object\n"); + if (!o) { + egsFatal("Got null object\n"); + } EGS_BaseSource *s = dynamic_cast(o); - if( !s ) egsFatal("This is not a source object\n"); + if (!s) { + egsFatal("This is not a source object\n"); + } egsInformation("Source description: %s\n",s->getSourceDescription()); EGS_RandomGenerator *rndm = EGS_RandomGenerator::defaultRNG(); - int q, latch; EGS_Float E, wt; EGS_Vector x,u; - for(int j=0; j<10000; j++) { + int q, latch; + EGS_Float E, wt; + EGS_Vector x,u; + for (int j=0; j<10000; j++) { s->getNextParticle(rndm,q,latch,E,wt,x,u); egsWarning("%g %g %g\n",x.x,x.y,x.z); } diff --git a/HEN_HOUSE/egs++/test_spectrum.cpp b/HEN_HOUSE/egs++/test_spectrum.cpp index 0a10c6d1e..0ea2f83fc 100644 --- a/HEN_HOUSE/egs++/test_spectrum.cpp +++ b/HEN_HOUSE/egs++/test_spectrum.cpp @@ -35,25 +35,36 @@ int main(int argc, char **argv) { - if( argc < 2 ) egsFatal("Usage: %s input_file\n",argv[0]); + if (argc < 2) { + egsFatal("Usage: %s input_file\n",argv[0]); + } - EGS_Input input; input.setContentFromFile(argv[1]); + EGS_Input input; + input.setContentFromFile(argv[1]); EGS_BaseSpectrum *spec = EGS_BaseSpectrum::createSpectrum(&input); - if( !spec ) egsFatal("Got null source\n"); + if (!spec) { + egsFatal("Got null source\n"); + } egsInformation("Got spectrum of type %s\n",spec->getType().c_str()); EGS_RandomGenerator *rndm = EGS_RandomGenerator::defaultRNG(); - int ncase; int err = input.getInput("ncase",ncase); - if( err ) ncase = 1000000; + int ncase; + int err = input.getInput("ncase",ncase); + if (err) { + ncase = 1000000; + } EGS_Timer t; - for(int j=0; jsampleEnergy(rndm); + for (int j=0; jsampleEnergy(rndm); + } EGS_Float cpu = t.time(); egsInformation("CPU time: %g\n",cpu); spec->reportAverageEnergy(); - delete spec; delete rndm; + delete spec; + delete rndm; return 0; } diff --git a/HEN_HOUSE/egs++/view/clippingplanes.cpp b/HEN_HOUSE/egs++/view/clippingplanes.cpp new file mode 100644 index 000000000..85798a0e0 --- /dev/null +++ b/HEN_HOUSE/egs++/view/clippingplanes.cpp @@ -0,0 +1,109 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer clipping planes extensions +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Iwan Kawrakow, 2005 +# +# Contributors: Manuel Stoeckl, Ernesto Mainegra-Hing +# +############################################################################### +*/ + +#include "clippingplanes.h" + +#include "egs_libconfig.h" + +#include +#include + +#ifdef VIEW_DEBUG + extern void (* egsWarning)(const char *, ...); +#endif + +ClippingPlanesWidget::ClippingPlanesWidget(QWidget *parent, const char *name) + : QWidget(parent) { + setObjectName(name); + setupUi(this); + planeTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); +} + +ClippingPlanesWidget::~ClippingPlanesWidget() { +} + +void ClippingPlanesWidget::applyClicked() { + emit clippingPlanesChanged(); +} + + +void ClippingPlanesWidget::helpClicked() { +#ifdef VIEW_DEBUG + egsWarning("In ClippingPlanesWidget::helpClicked()\n"); +#endif +} + + +int ClippingPlanesWidget::numPlanes() { + return planeTable->rowCount(); +} + + +bool ClippingPlanesWidget::getPlane(int j, EGS_Vector &a, EGS_Float &d) { + // check if all row items exist and are selected. + QTableWidgetItem *itemAx = planeTable->item(j,0), + *itemAy = planeTable->item(j,1), + *itemAz = planeTable->item(j,2), + *itemD = planeTable->item(j,3); + if (!itemAx || !itemAy || !itemAz || !itemD) { + return false; + } + if (!itemAx->isSelected() || !itemAy->isSelected() || + !itemAz->isSelected() || !itemD->isSelected()) { + return false; + } + + // transfer values from table + bool ok; + double ax = itemAx->text().toDouble(&ok); + if (!ok) { + return false; + } + double ay = itemAy->text().toDouble(&ok); + if (!ok) { + return false; + } + double az = itemAz->text().toDouble(&ok); + if (!ok) { + return false; + } + double nd = itemD->text().toDouble(&ok); + if (!ok) { + return false; + } + + // commit values only if all are valid + a.x = ax; + a.y = ay; + a.z = az; + d = nd; + return true; +} + diff --git a/HEN_HOUSE/egs++/view/clippingplanes.h b/HEN_HOUSE/egs++/view/clippingplanes.h new file mode 100644 index 000000000..e9ec9fb58 --- /dev/null +++ b/HEN_HOUSE/egs++/view/clippingplanes.h @@ -0,0 +1,66 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer clipping planes extensions +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Iwan Kawrakow, 2005 +# +# Contributors: Manuel Stoeckl +# +############################################################################### +*/ + +#ifndef CLIPPINGPLANESWIDGET_H +#define CLIPPINGPLANESWIDGET_H + +#include "ui_clippingplanes.h" + +#include + +class ClippingPlanesWidget : public QWidget, public Ui::ClippingPlanesWidget { + Q_OBJECT + +public: + + ClippingPlanesWidget(QWidget *parent = 0, const char *name = 0); + ~ClippingPlanesWidget(); + + virtual int numPlanes(); + virtual bool getPlane(int j, EGS_Vector &a, EGS_Float &d); + +public slots: + + virtual void helpClicked(); + +signals: + + void clippingPlanesChanged(); + +protected slots: + + virtual void languageChange() { + retranslateUi(this); + } + virtual void applyClicked(); + +}; + +#endif // CLIPPINGPLANESWIDGET_H \ No newline at end of file diff --git a/HEN_HOUSE/egs++/view/clippingplanes.ui b/HEN_HOUSE/egs++/view/clippingplanes.ui index 0b7e99ced..69722e266 100644 --- a/HEN_HOUSE/egs++/view/clippingplanes.ui +++ b/HEN_HOUSE/egs++/view/clippingplanes.ui @@ -1,4 +1,4 @@ - + ############################################################################### # # EGSnrc egs++ geometry viewer clipping planes user interface @@ -23,246 +23,192 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: +# Contributors: Ernesto Mainegra-Hing # ############################################################################### -ClippingPlanesWidget - - - ClippingPlanesWidget - - - - 0 - 0 - 492 - 325 - - - - Form1 - - - - unnamed + ClippingPlanesWidget + + + + 0 + 0 + 475 + 325 + + + + Form1 + + + + + + Clipping planes + + + + + + 10 - - - groupBox1 - - - Clipping planes - - - - unnamed - - - - - ax - - - - - - - - ay - - - - - - - - az - - - - - - - - d - - - - - - - - 1 - - - - - - - - 2 - - - - - - - - 3 - - - - - - - - 4 - - - - - - - - 5 - - - - - - - - 6 - - - - - - - - 7 - - - - - - - - 8 - - - - - - - - 9 - - - - - - - - 10 - - - - - - - planeTable - - - 10 - - - 4 - - - - - layout2 - - - - unnamed - - - - pushButton2 - - - &Help - - - Alt+H - - - - - spacer1 - - - Horizontal - - - Expanding - - - - 211 - 31 - - - - - - pushButton1 - - - &Apply - - - Alt+A - - - - - - - - - - - pushButton1 - clicked() - ClippingPlanesWidget - applyClicked() - - - pushButton2 - clicked() - ClippingPlanesWidget - helpClicked() - - - - egs_vector.h - clippingplanes.ui.h - - - clippingPlanesChanged() - - - applyClicked() - helpClicked() - - - numPlanes() - getPlane( int j, EGS_Vector & a, EGS_Float & d ) - - - - + + 4 + + + + 1 + + + + + 2 + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + ax + + + + + ay + + + + + az + + + + + d + + + + + + + + + + &Help + + + Alt+H + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 211 + 31 + + + + + + + + &Apply + + + Alt+A + + + + + + + + + + + + + egs_vector.h + + + + + pushButton1 + clicked() + ClippingPlanesWidget + applyClicked() + + + 20 + 20 + + + 20 + 20 + + + + + pushButton2 + clicked() + ClippingPlanesWidget + helpClicked() + + + 20 + 20 + + + 20 + 20 + + + + + diff --git a/HEN_HOUSE/egs++/view/clippingplanes.ui.h b/HEN_HOUSE/egs++/view/clippingplanes.ui.h deleted file mode 100644 index 2409bdea6..000000000 --- a/HEN_HOUSE/egs++/view/clippingplanes.ui.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -############################################################################### -# -# EGSnrc egs++ geometry viewer clipping planes extensions -# Copyright (C) 2015 National Research Council Canada -# -# This file is part of EGSnrc. -# -# EGSnrc is free software: you can redistribute it and/or modify it under -# the terms of the GNU Affero General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for -# more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with EGSnrc. If not, see . -# -############################################################################### -# -# Author: Iwan Kawrakow, 2005 -# -# Contributors: -# -############################################################################### -# -# ui.h extension file, included from the uic-generated form implementation. -# -# If you want to add, delete, or rename functions or slots, use Qt Designer -# to update this file, preserving your code. -# -# You should not define a constructor or destructor in this file. Instead, -# write your code in functions called init() and destroy(). These will -# automatically be called by the form's constructor and destructor. -# -############################################################################### -*/ - - -#include "egs_libconfig.h" - -#include - -void ClippingPlanesWidget::applyClicked() { - emit clippingPlanesChanged(); -} - - -void ClippingPlanesWidget::helpClicked() { -#ifdef VIEW_DEBUG - egsWarning("In ClippingPlanesWidget::helpClicked()\n"); -#endif -} - - -int ClippingPlanesWidget::numPlanes() { - return planeTable->numRows(); -} - - -bool ClippingPlanesWidget::getPlane( int j, EGS_Vector &a, EGS_Float &d ) { - if( !planeTable->isRowSelected(j,true) ) return false; - QString tmp = planeTable->text(j,0); - if( tmp.isEmpty() ) return false; - bool ok; double aux = tmp.toDouble(&ok); - if( !ok ) return false; a.x = aux; - tmp = planeTable->text(j,1); if( tmp.isEmpty() ) return false; - aux = tmp.toDouble(&ok); if( !ok ) return false; a.y = aux; - tmp = planeTable->text(j,2); if( tmp.isEmpty() ) return false; - aux = tmp.toDouble(&ok); if( !ok ) return false; a.z = aux; - tmp = planeTable->text(j,3); if( tmp.isEmpty() ) return false; - aux = tmp.toDouble(&ok); if( !ok ) return false; d = aux; - return true; -} diff --git a/HEN_HOUSE/egs++/view/egs_light.h b/HEN_HOUSE/egs++/view/egs_light.h index 5438c3ce0..ff2719baa 100644 --- a/HEN_HOUSE/egs++/view/egs_light.h +++ b/HEN_HOUSE/egs++/view/egs_light.h @@ -45,8 +45,9 @@ class EGS_Light { // the color d. EGS_Vector getColor(const EGS_Vector &x, const EGS_Vector &n, const EGS_Vector &d_color) { - EGS_Vector L(xl-x); EGS_Float Lxn = L*n; - if( Lxn > 0 ) { + EGS_Vector L(xl-x); + EGS_Float Lxn = L*n; + if (Lxn > 0) { Lxn /= L.length(); return diffuse_c.getScaled(d_color)*Lxn; } @@ -72,7 +73,7 @@ class EGS_MaterialColor { d(d_color), alpha(Alpha) {}; EGS_Vector d; // material color as a r,g,b triplet, should be - // clamped between 0 and 1. + // clamped between 0 and 1. EGS_Float alpha; }; diff --git a/HEN_HOUSE/egs++/view/egs_track_view.cpp b/HEN_HOUSE/egs++/view/egs_track_view.cpp index b31f2bf6e..8f104ee21 100644 --- a/HEN_HOUSE/egs++/view/egs_track_view.cpp +++ b/HEN_HOUSE/egs++/view/egs_track_view.cpp @@ -43,12 +43,15 @@ double det(EGS_Vector v1, EGS_Vector v2, EGS_Vector v3) { EGS_TrackView::EGS_TrackView(const char *filename) { m_trspFile = NULL; int err = readDataFile(filename); - if ( err ) return; + if (err) { + return; + } m_maxE = 0; for (int i = 0; i < m_nTracks; i++) { for (int j = 0; j < m_buffer[i]->getNumVertices(); j++) { - if (m_buffer[i]->getVertex(j)->e > m_maxE) + if (m_buffer[i]->getVertex(j)->e > m_maxE) { m_maxE = m_buffer[i]->getVertex(j)->e; + } } } } @@ -57,7 +60,7 @@ EGS_TrackView::~EGS_TrackView() { // nothing to do -> pass execution to parent Destructor } -void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { +bool EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image, int *abort_location) { EGS_Vector tmpv(0,0,0), tmpv2(0,0,0), tmpv3(0,0,0); int di, xxx1, xxx2, yyy1, yyy2; double e1, e2, dst1, dst2; @@ -65,22 +68,36 @@ void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { for (int i = 0; i < m_nTracks; i++) { + if (abort_location && *abort_location) { + return false; + } + // no reason to render the track if it has less than 2 vertices - if (m_buffer[i]->getNumVertices() < 2) continue; + if (m_buffer[i]->getNumVertices() < 2) { + continue; + } EGS_ParticleTrack::ParticleInfo *pInfo = m_buffer[i]->getParticleInfo(); // check if the user wants to see this type of particles - if (pInfo->q == 0 && !m_vis_particle[1]) continue; - else if (pInfo->q == -1 && !m_vis_particle[2]) continue; - else if (pInfo->q == 1 && !m_vis_particle[3]) continue; - else if ((pInfo->q > 1 || pInfo->q < -1) && !m_vis_particle[4]) continue; + if (pInfo->q == 0 && !m_vis_particle[1]) { + continue; + } + else if (pInfo->q == -1 && !m_vis_particle[2]) { + continue; + } + else if (pInfo->q == 1 && !m_vis_particle[3]) { + continue; + } + else if ((pInfo->q > 1 || pInfo->q < -1) && !m_vis_particle[4]) { + continue; + } // get initial vertex of the track - begining EGS_ParticleTrack::Vertex *v1 = m_buffer[i]->getVertex(0); // calculate distance from camera to projection plane along (v1-xo) s1 = (1 - m_scr_a*xo.x - m_scr_b*xo.y - m_scr_c*xo.z) / - (m_scr_a*(v1->x.x-xo.x)+m_scr_b*(v1->x.y-xo.y)+m_scr_c*(v1->x.z-xo.z)); + (m_scr_a*(v1->x.x-xo.x)+m_scr_b*(v1->x.y-xo.y)+m_scr_c*(v1->x.z-xo.z)); // calculate coordinates of the projection point tmpv = (xo + ((v1->x-xo)*s1) - x_screen); @@ -103,17 +120,25 @@ void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { 3.0 = positron = blue 4.0 = unknown = white */ - if (pInfo->q == 0) { tmpv2.x = 1.0; } - else if (pInfo->q == -1) { tmpv2.x = 2.0; } - else if (pInfo->q == 1) { tmpv2.x = 3.0; } - else tmpv2.x = 4.0; + if (pInfo->q == 0) { + tmpv2.x = 1.0; + } + else if (pInfo->q == -1) { + tmpv2.x = 2.0; + } + else if (pInfo->q == 1) { + tmpv2.x = 3.0; + } + else { + tmpv2.x = 4.0; + } for (int j = 1; j < m_buffer[i]->getNumVertices(); j++) { // get the next vertex along the current track EGS_ParticleTrack::Vertex *v2 = m_buffer[i]->getVertex(j); s2 = (1 - m_scr_a*xo.x - m_scr_b*xo.y - m_scr_c*xo.z) / - (m_scr_a*(v2->x.x-xo.x)+m_scr_b*(v2->x.y-xo.y)+m_scr_c*(v2->x.z-xo.z)); + (m_scr_a*(v2->x.x-xo.x)+m_scr_b*(v2->x.y-xo.y)+m_scr_c*(v2->x.z-xo.z)); // double myw = (v2->x.x*v2->x.x + v2->x.y*v2->x.y) / (1.0*v2->x.z*v2->x.z); // if (myw > 1) break; @@ -144,7 +169,9 @@ void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { de = (e2 - e1); gd = dst1; ge = e1; - if (dx == 0.0000 && dy == 0.0000) continue; + if (dx == 0.0000 && dy == 0.0000) { + continue; + } // iterate along the longer side if (abs(dx) > abs(dy)) { @@ -162,19 +189,28 @@ void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { // grab what's already in the image buffer at this location tmpv3 = image[cx + ((int)(cy))*nx]; if (tmpv3.z < 0) { // there is already a track there - if (-gd > tmpv3.z) tmpv3.z = -gd; // current track is closer - if (tmpv2.x > tmpv3.x) tmpv3.x = tmpv2.x; // put "important" particles in front + if (-gd > tmpv3.z) { + tmpv3.z = -gd; // current track is closer + } + if (tmpv2.x > tmpv3.x) { + tmpv3.x = tmpv2.x; // put "important" particles in front + } tmpv3.y += (1-tmpv3.y)*e2; // compound transparency values } else { - tmpv3.x = tmpv2.x; tmpv3.y=e2; tmpv3.z=-gd; // just update with current track info + tmpv3.x = tmpv2.x; + tmpv3.y=e2; + tmpv3.z=-gd; // just update with current track info } // write new values to image buffer image[cx + ((int)(cy))*nx] = tmpv3; } - cy += dy; gd += dd; ge += de; + cy += dy; + gd += dd; + ge += de; } - } else { + } + else { di = (yyy1 > yyy2) ? -1 : 1; cx = xxx1; dx = dx / abs(dy); @@ -189,29 +225,44 @@ void EGS_TrackView::renderTracks(int nx, int ny, EGS_Vector *image) { // grab what's already in the image buffer at this location tmpv3 = image[(int)(cx) + cy*nx]; if (tmpv3.z < 0) { // there is already a track there - if (-gd > tmpv3.z) tmpv3.z = -gd; // current track is closer - if (tmpv2.x > tmpv3.x) tmpv3.x = tmpv2.x; // put "important" particles in front + if (-gd > tmpv3.z) { + tmpv3.z = -gd; // current track is closer + } + if (tmpv2.x > tmpv3.x) { + tmpv3.x = tmpv2.x; // put "important" particles in front + } tmpv3.y += (1-tmpv3.y)*e2; // compound transparency values } else { - tmpv3.x = tmpv2.x; tmpv3.y=e2; tmpv3.z=-gd; // just update with current track info + tmpv3.x = tmpv2.x; + tmpv3.y=e2; + tmpv3.z=-gd; // just update with current track info } // write new values to image buffer image[(int)(cx) + cy*nx] = tmpv3; } - cx += dx; gd += dd; ge += de; + cx += dx; + gd += dd; + ge += de; } } // save already calculated data for the next segment - v1 = v2; s1 = s2; xx1 = xx2; yy1 = yy2; - xxx1 = xxx2; yyy1 = yyy2; e1 = e2; dst1 = dst2; + v1 = v2; + s1 = s2; + xx1 = xx2; + yy1 = yy2; + xxx1 = xxx2; + yyy1 = yyy2; + e1 = e2; + dst1 = dst2; } } + return true; } void EGS_TrackView::setProjection(EGS_Vector pxo, EGS_Vector px_screen, EGS_Vector pv1_screen, - EGS_Vector pv2_screen, EGS_Float psx, EGS_Float psy) { + EGS_Vector pv2_screen, EGS_Float psx, EGS_Float psy) { // set camera and screen variables xo = pxo; @@ -229,21 +280,32 @@ void EGS_TrackView::setProjection(EGS_Vector pxo, EGS_Vector px_screen, EGS_Vect EGS_Vector ps2(x_screen + v1_screen); EGS_Vector ps3(x_screen + v2_screen); double d = det(ps1, ps2, ps3); - EGS_Vector a1 = ps1; a1.x = 1; - EGS_Vector a2 = ps2; a2.x = 1; - EGS_Vector a3 = ps3; a3.x = 1; + EGS_Vector a1 = ps1; + a1.x = 1; + EGS_Vector a2 = ps2; + a2.x = 1; + EGS_Vector a3 = ps3; + a3.x = 1; double d1 = det(a1, a2, a3); - EGS_Vector b1 = ps1; b1.y = 1; - EGS_Vector b2 = ps2; b2.y = 1; - EGS_Vector b3 = ps3; b3.y = 1; + EGS_Vector b1 = ps1; + b1.y = 1; + EGS_Vector b2 = ps2; + b2.y = 1; + EGS_Vector b3 = ps3; + b3.y = 1; double d2 = det(b1, b2, b3); - EGS_Vector c1 = ps1; c1.z = 1; - EGS_Vector c2 = ps2; c2.z = 1; - EGS_Vector c3 = ps3; c3.z = 1; + EGS_Vector c1 = ps1; + c1.z = 1; + EGS_Vector c2 = ps2; + c2.z = 1; + EGS_Vector c3 = ps3; + c3.z = 1; double d3 = det(c1, c2, c3); // avoid seg faults - if (d == 0.0000) d += 0.001; + if (d == 0.0000) { + d += 0.001; + } m_scr_a = d1/d; m_scr_b = d2/d; m_scr_c = d3/d; diff --git a/HEN_HOUSE/egs++/view/egs_track_view.h b/HEN_HOUSE/egs++/view/egs_track_view.h index daf1c3803..e9fc2ee75 100644 --- a/HEN_HOUSE/egs++/view/egs_track_view.h +++ b/HEN_HOUSE/egs++/view/egs_track_view.h @@ -48,17 +48,21 @@ class EGS_TrackView : public EGS_ParticleTrackContainer { ~EGS_TrackView(); - void renderTracks(int nx, int ny, EGS_Vector *image); + bool renderTracks(int nx, int ny, EGS_Vector *image, int *abort_location=NULL); void setProjection(EGS_Vector pxo, EGS_Vector px_screen, EGS_Vector pv1_screen, - EGS_Vector pv2_screen, EGS_Float psx, EGS_Float psy); + EGS_Vector pv2_screen, EGS_Float psx, EGS_Float psy); void setParticleVisibility(int p, bool vis) { - if (p < 1 || p > 4) return; + if (p < 1 || p > 4) { + return; + } m_vis_particle[p] = vis; } - EGS_Float getMaxE() { return m_maxE; } + EGS_Float getMaxE() { + return m_maxE; + } protected: diff --git a/HEN_HOUSE/egs++/view/egs_visualizer.cpp b/HEN_HOUSE/egs++/view/egs_visualizer.cpp index 52c7e7edb..7b9aaa617 100644 --- a/HEN_HOUSE/egs++/view/egs_visualizer.cpp +++ b/HEN_HOUSE/egs++/view/egs_visualizer.cpp @@ -41,16 +41,18 @@ class EGS_PrivateVisualizer { nlight(0), ntot(0), nmat(0), nclip(0), nclip_t(0), m_tracks(NULL) {}; ~EGS_PrivateVisualizer(); - void loadTracksData(const char* fname) { - if (m_tracks) delete m_tracks; + void loadTracksData(const char *fname) { + if (m_tracks) { + delete m_tracks; + } m_tracks = new EGS_TrackView(fname); } void setProjection(const EGS_Vector &camera_pos, - const EGS_Vector &camera_look_at, EGS_Float distance, - EGS_Float size_x, EGS_Float size_y); + const EGS_Vector &camera_look_at, EGS_Float distance, + EGS_Float size_x, EGS_Float size_y); void setProjection(const EGS_Vector &camera_pos, - const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, - const EGS_Vector &V2_screen,EGS_Float size_x, EGS_Float size_y); + const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, + const EGS_Vector &V2_screen,EGS_Float size_x, EGS_Float size_y); void setGlobalAmbientLight(const EGS_Vector &light) { global_ambient_light = light; }; @@ -58,17 +60,26 @@ class EGS_PrivateVisualizer { setLight(ilight,new EGS_Light(pos,color)); }; void setLight(int ilight, EGS_Light *light) { - if( ilight < nlight ) { - delete lights[ilight]; lights[ilight] = light; + if (ilight < nlight) { + delete lights[ilight]; + lights[ilight] = light; + } + else { + addLight(light); } - else addLight(light); }; void addLight(EGS_Light *light) { - if( nlight == ntot ) { - int nnew = ntot + 10; EGS_Light **l = new EGS_Light * [nnew]; - for(int j=0; j 0 ) delete [] lights; - ntot = nnew; lights = l; + if (nlight == ntot) { + int nnew = ntot + 10; + EGS_Light **l = new EGS_Light * [nnew]; + for (int j=0; j 0) { + delete [] lights; + } + ntot = nnew; + lights = l; } lights[nlight++] = light; }; @@ -76,11 +87,16 @@ class EGS_PrivateVisualizer { addLight(new EGS_Light(pos,color)); }; void addClippingPlane(EGS_ClippingPlane *p) { - if( nclip >= nclip_t ) { + if (nclip >= nclip_t) { EGS_ClippingPlane **tmp = new EGS_ClippingPlane * [nclip_t + 5]; - for(int j=0; j 0 ) delete [] clip; - clip = tmp; nclip_t += 5; + for (int j=0; j 0) { + delete [] clip; + } + clip = tmp; + nclip_t += 5; } clip[nclip++] = p; }; @@ -91,16 +107,21 @@ class EGS_PrivateVisualizer { nclip = 0; }; void setMaterialColor(int imed, const EGS_MaterialColor &Mat) { - if( imed >= nmat ) { + if (imed >= nmat) { EGS_MaterialColor *m = new EGS_MaterialColor [imed + 5]; - for(int j=0; j 0 ) delete [] mat; - mat = m; nmat = imed+5; + for (int j=0; j 0) { + delete [] mat; + } + mat = m; + nmat = imed+5; } mat[imed] = Mat; }; void setMaterialColor(int imed, const EGS_Vector &d_color, - EGS_Float Alpha=1) { + EGS_Float Alpha=1) { setMaterialColor(imed,EGS_MaterialColor(d_color,Alpha)); }; @@ -109,21 +130,23 @@ class EGS_PrivateVisualizer { // get the color for the screen point x. EGS_Vector getColor(const EGS_Vector &x, EGS_BaseGeometry *g, - const EGS_Float track_distance, const EGS_Float track_alpha, const bool track_clip, bool debug=false, - EGS_Vector bCol=EGS_Vector(1,1,1)); + const EGS_Float track_distance, const EGS_Float track_alpha, const bool track_clip, bool debug=false, + EGS_Vector bCol=EGS_Vector(1,1,1)); void getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, int *regions, EGS_Vector *colors, int maxreg); // render the entire image - bool renderImage(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image); + bool renderImage(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image, int *abort_location=NULL); // render the particle tracks - bool renderTracks(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image); + bool renderTracks(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image, int *abort_location=NULL); // pick region void regionPick(int x, int y); void setParticleVisibility(int particle, bool vis) { - if(m_tracks) m_tracks->setParticleVisibility(particle, vis); + if (m_tracks) { + m_tracks->setParticleVisibility(particle, vis); + } } EGS_Vector xo; // camera position @@ -150,7 +173,9 @@ EGS_GeometryVisualizer::EGS_GeometryVisualizer() { p = new EGS_PrivateVisualizer; } -EGS_GeometryVisualizer::~EGS_GeometryVisualizer() { delete p; } +EGS_GeometryVisualizer::~EGS_GeometryVisualizer() { + delete p; +} void EGS_GeometryVisualizer::loadTracksData(const char *fname) { if (p) { @@ -165,8 +190,8 @@ void EGS_GeometryVisualizer::setProjection(const EGS_Vector &camera_pos, } void EGS_GeometryVisualizer::setProjection(const EGS_Vector &camera_pos, - const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, - const EGS_Vector &V2_screen, EGS_Float size_x, EGS_Float size_y) { + const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, + const EGS_Vector &V2_screen, EGS_Float size_x, EGS_Float size_y) { p->setProjection(camera_pos,Xo_screen,V1_screen,V2_screen,size_x,size_y); } @@ -175,21 +200,27 @@ void EGS_GeometryVisualizer::setGlobalAmbientLight(const EGS_Vector &light) { } void EGS_GeometryVisualizer::addLight(const EGS_Vector &pos, - const EGS_Vector &color) { p->addLight(pos,color); } + const EGS_Vector &color) { + p->addLight(pos,color); +} void EGS_GeometryVisualizer::addLight(EGS_Light *l) { p->addLight(l); } void EGS_GeometryVisualizer::setLight(int j, const EGS_Vector &pos, - const EGS_Vector &color) { p->setLight(j,pos,color); } + const EGS_Vector &color) { + p->setLight(j,pos,color); +} void EGS_GeometryVisualizer::setLight(int j, EGS_Light *l) { p->setLight(j,l); } void EGS_GeometryVisualizer::setMaterialColor(int imed, - const EGS_MaterialColor &Mat) { p->setMaterialColor(imed,Mat); } + const EGS_MaterialColor &Mat) { + p->setMaterialColor(imed,Mat); +} void EGS_GeometryVisualizer::setMaterialColor(int imed, const EGS_Vector &d_color, EGS_Float Alpha) { @@ -200,15 +231,19 @@ void EGS_GeometryVisualizer::addClippingPlane(EGS_ClippingPlane *plane) { p->addClippingPlane(plane); } -void EGS_GeometryVisualizer::addClippingPlane(const EGS_Vector &A, EGS_Float D){ +void EGS_GeometryVisualizer::addClippingPlane(const EGS_Vector &A, EGS_Float D) { p->addClippingPlane(new EGS_ClippingPlane(A,D)); } bool EGS_GeometryVisualizer::renderImage(EGS_BaseGeometry *g, int nx, int ny, - EGS_Vector *image) { return p->renderImage(g,nx,ny,image); } + EGS_Vector *image, int *abort_location) { + return p->renderImage(g,nx,ny,image,abort_location); +} bool EGS_GeometryVisualizer::renderTracks(EGS_BaseGeometry *g, int nx, int ny, - EGS_Vector *image) { return p->renderTracks(g,nx,ny,image); } + EGS_Vector *image, int *abort_location) { + return p->renderTracks(g,nx,ny,image,abort_location); +} EGS_Vector EGS_GeometryVisualizer::getColor(const EGS_Vector &x, EGS_BaseGeometry *g, const EGS_Float track_distance, const EGS_Float track_alpha, const bool track_clip) { return p->getColor(x,g,track_distance, track_alpha, track_clip); @@ -233,7 +268,8 @@ void EGS_PrivateVisualizer::getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, // to the screen point given by x. EGS_Vector u(x-xo); - EGS_Float t = u.length(); u *= (1./t); + EGS_Float t = u.length(); + u *= (1./t); EGS_Vector xs(xo); EGS_Float tleft = t; EGS_Float tclip = 0; @@ -255,7 +291,10 @@ void EGS_PrivateVisualizer::getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, if (clip[j]->isInside(xo)) { EGS_Float tt = t; if (clip[j]->howfar(xo,u,tt)) { - if (tt > tclip) {tclip = tt; jclip = j;} + if (tt > tclip) { + tclip = tt; + jclip = j; + } } } @@ -263,29 +302,37 @@ void EGS_PrivateVisualizer::getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, else { EGS_Float tt = t; if (clip[j]->howfar(xo,u,tt)) { - if (tt= 0 ) { - if( tclip <= tleft ) { + if (jclip >= 0) { + if (tclip <= tleft) { xs += u*tclip; ireg = g->isWhere(xs); tleft -= tclip; t -= tclip; - if( ireg >= 0 ) { + if (ireg >= 0) { imed = g->medium(ireg); - if( imed >= 0 ) c = mat[imed].d*mat[imed].alpha; + if (imed >= 0) { + c = mat[imed].d*mat[imed].alpha; + } // save region regions[regcount]=ireg; colors[regcount]=c; regcount++; - if (regcount>=maxreg) return; + if (regcount>=maxreg) { + return; + } } } - else return; + else { + return; + } } } @@ -294,40 +341,46 @@ void EGS_PrivateVisualizer::getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, c = EGS_Vector(0,0,0); t = tleft; int inew = g->howfar(ireg,xs,u,t,&imed,0); - if( inew == ireg ) { + if (inew == ireg) { regions[regcount]=-1; return; } ireg = inew; - if( ireg >= 0) { + if (ireg >= 0) { tleft -= t; xs += u*t; - if (imed >= 0) c = mat[imed].d*mat[imed].alpha; + if (imed >= 0) { + c = mat[imed].d*mat[imed].alpha; + } regions[regcount]=ireg; colors[regcount]=c; regcount++; - if (regcount>=maxreg) return; + if (regcount>=maxreg) { + return; + } } else { regions[regcount]=-1; return; } - } while (ireg >= 0); + } + while (ireg >= 0); } //============================================================================= // EGS_PrivateVisualizer::getColor //============================================================================= -EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, - EGS_BaseGeometry *g, - const EGS_Float track_distance, - const EGS_Float track_alpha, - const bool track_clip, - const bool debug, - const EGS_Vector track_color) { +EGS_Vector EGS_PrivateVisualizer::getColor(const EGS_Vector &x, + EGS_BaseGeometry *g, + const EGS_Float track_distance, + const EGS_Float track_alpha, + const bool track_clip, + const bool debug, + const EGS_Vector track_color) { EGS_Vector u(x-xo); // vector from camera to screen point - EGS_Float t = u.length(); u *= (1./t); // normalize direction vector + EGS_Float t = u.length(); + u *= (1./t); // normalize direction vector EGS_Float ttrack = track_distance; // distance to track EGS_Vector xs(xo); // screen position EGS_Float tleft = t; // remaining distance @@ -339,8 +392,8 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, EGS_Vector cTrack = track_color*track_alpha; // track color - if( debug ) egsWarning("getColor(xo=(%g,%g,%g),u=(%g,%g,%g),axis_distance=%g\n", - xo.x,xo.y,xo.z,u.x,u.y,u.z,track_distance); + if (debug) egsWarning("getColor(xo=(%g,%g,%g),u=(%g,%g,%g),axis_distance=%g\n", + xo.x,xo.y,xo.z,u.x,u.y,u.z,track_distance); // handle clipping planes if (nclip > 0) { @@ -357,13 +410,17 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, } } else { - if (ttrack>0) return cTrack; // don't forget the axis! + if (ttrack>0) { + return cTrack; // don't forget the axis! + } return c; } } else { // we are outside clipping plane - if (clip[j]->howfar(xo,u,t)) tleft = t; // remaining distance is that of the clipping plane + if (clip[j]->howfar(xo,u,t)) { + tleft = t; // remaining distance is that of the clipping plane + } } } @@ -394,15 +451,20 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, a1 = mat[imed].alpha;; c1 = global_ambient_light.getScaled(mat[imed].d); EGS_Vector n = clip[j_clip]->getNormal(); - for(int j=0; jgetColor(xs,n,mat[imed].d); + } c += c1*a1*a; a = a*(1-a1); - if (a < 0.001) return c; + if (a < 0.001) { + return c; + } } } } - else return c; + else { + return c; + } } } @@ -410,26 +472,33 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, if (ireg < 0) { EGS_Vector n; int inew = g->howfar(ireg,xs,u,t,&imed,&n); - if( debug ) egsWarning("enter: inew=%d t=%g imed=%d n=(%g,%g,%g)\n", inew,t,imed,n.x,n.y,n.z); + if (debug) { + egsWarning("enter: inew=%d t=%g imed=%d n=(%g,%g,%g)\n", inew,t,imed,n.x,n.y,n.z); + } // hitting a track first if (ttrack>0 && (t>=ttrack || inew<0)) { c = track_color*track_alpha*a; a = a*(1-track_alpha); - if (a < 0.001) return c; + if (a < 0.001) { + return c; + } } // hitting a surface if (inew >= 0) { xs += u*t; - if( imed >= 0 ) { + if (imed >= 0) { a1 = mat[imed].alpha;; c1 = global_ambient_light.getScaled(mat[imed].d); - for (int j=0; jgetColor(xs,n,mat[imed].d); + } c += c1*a1*a; a = a*(1-a1); - if (a < 0.001) return c; + if (a < 0.001) { + return c; + } } // update region index and distances @@ -438,10 +507,14 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, ttrack -= t; } } - if (ireg < 0) return c; + if (ireg < 0) { + return c; + } // translucent points - if( debug ) egsWarning("c=(%g,%g,%g) a=%g\n",c.x,c.y,c.z,a); + if (debug) { + egsWarning("c=(%g,%g,%g) a=%g\n",c.x,c.y,c.z,a); + } do { EGS_Vector n; int imed_new; @@ -456,7 +529,9 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, } // avoid getting stuck - if (inew == ireg) break; + if (inew == ireg) { + break; + } EGS_Vector c1; xs += u*t; @@ -465,11 +540,14 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, if (inew >= 0 && imed_new >= 0 && imed_new != imed) { a1 = mat[imed_new].alpha; c1 = global_ambient_light.getScaled(mat[imed_new].d); - for (int j=0; jgetColor(xs,n,mat[imed_new].d); + } c += c1*a*a1; a = a*(1-a1); - if( a < 0.001 ) break; + if (a < 0.001) { + break; + } } // update region index and distances @@ -478,71 +556,112 @@ EGS_Vector EGS_PrivateVisualizer::getColor ( const EGS_Vector &x, tleft -= t; ttrack -= t; - } while ( ireg >= 0 ); + } + while (ireg >= 0); - if (ttrack>0) return c+(cTrack)*a; // draw the axis if not hit before + if (ttrack>0) { + return c+(cTrack)*a; // draw the axis if not hit before + } return c; } -bool EGS_PrivateVisualizer::renderImage(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image) { +bool EGS_PrivateVisualizer::renderImage(EGS_BaseGeometry *g, int nx, int ny, EGS_Vector *image, int *abort_location) { EGS_Float dx = sx/nx, dy = sx/ny; EGS_Float rmax=1, gmax=1, bmax=1; EGS_Float ttrack=0, track_alpha = 1; bool debug = image ? false : true; - if( debug ) egsWarning("\n*** renderImage(%d,%d)\n",nx,ny); + if (debug) { + egsWarning("\n*** renderImage(%d,%d)\n",nx,ny); + } // render geometry in image buffer - for(int j=0; j 0) || (image[idx].y > 0) && m_tracks) { + if (((image[idx].x > 0) || (image[idx].y > 0)) && m_tracks) { track_alpha = 0.2+0.8*image[idx].y; - if (image[idx].x == 1.0) { bCol.x=1; bCol.y=1; bCol.z=0.0; } - if (image[idx].x == 2.0) { bCol.x=1.0; bCol.y=0.0; bCol.z=0; } - if (image[idx].x == 3.0) { bCol.x=0; bCol.y=0.0; bCol.z=1.0; } - if (image[idx].x == 4.0) { bCol.x=1; bCol.y=1; bCol.z=1; } - if (image[idx].x == 100.0) { bCol.x=1; bCol.y=1; bCol.z=1; } + if (image[idx].x == 1.0) { + bCol.x=1; + bCol.y=1; + bCol.z=0.0; + } + if (image[idx].x == 2.0) { + bCol.x=1.0; + bCol.y=0.0; + bCol.z=0; + } + if (image[idx].x == 3.0) { + bCol.x=0; + bCol.y=0.0; + bCol.z=1.0; + } + if (image[idx].x == 4.0) { + bCol.x=1; + bCol.y=1; + bCol.z=1; + } + if (image[idx].x == 100.0) { + bCol.x=1; + bCol.y=1; + bCol.z=1; + } } image[idx] = EGS_Vector(0,0,0); } } EGS_Vector v = getColor(xp,g,ttrack,track_alpha,0,debug,bCol); - if( debug ) egsWarning("ix=%d iy=%d v=(%g,%g,%g)\n",i,j,v.x,v.y,v.z); - if( v.x > rmax ) rmax = v.x; - if( v.y > gmax ) gmax = v.y; - if( v.z > bmax ) bmax = v.z; - if( image ) image[i+j*nx] = v; + if (debug) { + egsWarning("ix=%d iy=%d v=(%g,%g,%g)\n",i,j,v.x,v.y,v.z); + } + if (v.x > rmax) { + rmax = v.x; + } + if (v.y > gmax) { + gmax = v.y; + } + if (v.z > bmax) { + bmax = v.z; + } + if (image) { + image[i+j*nx] = v; + } } } // normalizeImage(image,nx*ny); return image; - if( image ) { - if( rmax > 1 || gmax > 1 || bmax > 1 ) { + if (image) { + if (rmax > 1 || gmax > 1 || bmax > 1) { EGS_Vector aux(1/rmax,1/gmax,1/bmax); - for(int j=0; jrenderTracks(nx, ny, image); + return m_tracks->renderTracks(nx, ny, image, abort_location); } return true; } @@ -556,45 +675,66 @@ void EGS_PrivateVisualizer::regionPick(int x, int y) { void EGS_PrivateVisualizer::normalizeImage(EGS_Vector *image, int n) { EGS_Float rmax=1, gmax=1, bmax=1; - for(int j=0; j rmax ) rmax = image[j].x; - if( image[j].y > gmax ) gmax = image[j].y; - if( image[j].z > bmax ) bmax = image[j].z; + for (int j=0; j rmax) { + rmax = image[j].x; + } + if (image[j].y > gmax) { + gmax = image[j].y; + } + if (image[j].z > bmax) { + bmax = image[j].z; + } } - if( rmax > 1 || gmax > 1 || bmax > 1 ) { + if (rmax > 1 || gmax > 1 || bmax > 1) { EGS_Vector aux(1/rmax,1/gmax,1/bmax); - for(int j=0; j 0 ) { - for(int j=0; j 0) { + for (int j=0; j 0 ) delete [] mat; - if( nclip_t > 0 ) { - for(int j=0; j 0) { + delete [] mat; + } + if (nclip_t > 0) { + for (int j=0; jsetProjection(xo, x_screen, v1_screen, v2_screen, sx, sy); } @@ -611,7 +751,7 @@ static void egs_png_warning(png_structp, png_const_charp message) { } static void egs_png_write_func(png_structp png_ptr, png_bytep data, - png_size_t length) { + png_size_t length) { png_ostream->write((char *)data,length); //if( nw != length ) // png_error( png_ptr, "write error" ); @@ -624,45 +764,55 @@ static void egs_png_flush_func(png_structp png_ptr) { bool EGS_GeometryVisualizer::makePngImage(EGS_BaseGeometry *g, int xsize, int ysize, const char *fname) { // checks - if( !fname ) { + if (!fname) { egsWarning("EGS_GeometryVisualizer::makePngImage: file name must" - " not be null\n"); return false; + " not be null\n"); + return false; } png_ostream = new std::ofstream(fname, std::ios::binary | std::ios::trunc); - if( !png_ostream ) { + if (!png_ostream) { egsWarning("EGS_GeometryVisualizer::makePngImage: " - "failed to open file %s for writing\n",fname); return false; + "failed to open file %s for writing\n",fname); + return false; } - if( xsize <= 0 || ysize <= 0 ) { + if (xsize <= 0 || ysize <= 0) { egsWarning("EGS_GeometryVisualizer::makePngImage: " - "image size must be greater than zero\n"); return false; + "image size must be greater than zero\n"); + return false; } // render the image EGS_Vector *image = new EGS_Vector [xsize*ysize]; - if( !p->renderTracks(g,xsize,ysize,image) ) { - egsWarning("Error while rendering particle tracks\n"); return false; + if (!p->renderTracks(g,xsize,ysize,image)) { + egsWarning("Error while rendering particle tracks\n"); + return false; } - if( !p->renderImage(g,xsize,ysize,image) ) { - egsWarning("Error while rendering image\n"); return false; + if (!p->renderImage(g,xsize,ysize,image)) { + egsWarning("Error while rendering image\n"); + return false; } // initialize png - png_structp png_ptr; png_infop info_ptr; + png_structp png_ptr; + png_infop info_ptr; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); - if (!png_ptr) return false; + if (!png_ptr) { + return false; + } png_set_error_fn(png_ptr, 0, 0, egs_png_warning); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, 0); return false; + png_destroy_write_struct(&png_ptr, 0); + return false; } if (setjmp(png_ptr->jmpbuf)) { - png_destroy_write_struct(&png_ptr, &info_ptr); return false; + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; } //png_set_compression_level(png_ptr,Z_BEST_COMPRESSION); - png_set_write_fn(png_ptr, (void*)this, egs_png_write_func, - egs_png_flush_func); + png_set_write_fn(png_ptr, (void *)this, egs_png_write_func, + egs_png_flush_func); info_ptr->channels = 3; png_set_IHDR(png_ptr, info_ptr, xsize, ysize, 8, PNG_COLOR_TYPE_RGB, 0,0,0); info_ptr->sig_bit.red = 8; @@ -679,13 +829,13 @@ bool EGS_GeometryVisualizer::makePngImage(EGS_BaseGeometry *g, png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); // fill the image - unsigned int **rows = new unsigned int* [ysize]; + unsigned int **rows = new unsigned int *[ysize]; unsigned int rgb = 0xff << 24; - for(int j=0; jclose(); delete png_ostream; - for(int j=0; jclose(); + delete png_ostream; + for (int j=0; j= d); }; - bool isInside(const EGS_Vector &x) const { return (x*a >= d); }; bool howfar(const EGS_Vector &x, const EGS_Vector &u, EGS_Float &t) const { EGS_Float xp = a*x, up = a*u; - if( (xp >= d && up < 0) || (xp < d && up > 0) ) { + if ((xp >= d && up < 0) || (xp < d && up > 0)) { EGS_Float tt = (d-xp)/up; - if( tt <= t ) { t = tt; return true; } + if (tt <= t) { + t = tt; + return true; + } } return false; }; EGS_Float hownear(const EGS_Vector &x) const { return fabs(x*a-d); }; - const EGS_Vector &getNormal() const { return a; }; + const EGS_Vector &getNormal() const { + return a; + }; }; @@ -77,11 +86,11 @@ class EGS_GeometryVisualizer { void loadTracksData(const char *fname); void setProjection(const EGS_Vector &camera_pos, - const EGS_Vector &camera_look_at, EGS_Float distance, - EGS_Float size_x, EGS_Float size_y); + const EGS_Vector &camera_look_at, EGS_Float distance, + EGS_Float size_x, EGS_Float size_y); void setProjection(const EGS_Vector &camera_pos, - const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, - const EGS_Vector &V2_screen, EGS_Float size_x, EGS_Float size_y); + const EGS_Vector &Xo_screen, const EGS_Vector &V1_screen, + const EGS_Vector &V2_screen, EGS_Float size_x, EGS_Float size_y); void setGlobalAmbientLight(const EGS_Vector &light); @@ -99,8 +108,8 @@ class EGS_GeometryVisualizer { EGS_Float Alpha=1); //EGS_Vector *renderImage(EGS_BaseGeometry *, int xsize, int ysize); - bool renderImage(EGS_BaseGeometry *, int nx, int ny, EGS_Vector *image); - bool renderTracks(EGS_BaseGeometry *, int nx, int ny, EGS_Vector *image); + bool renderImage(EGS_BaseGeometry *, int nx, int ny, EGS_Vector *image, int *abort_location=NULL); + bool renderTracks(EGS_BaseGeometry *, int nx, int ny, EGS_Vector *image, int *abort_location=NULL); EGS_Vector getColor(const EGS_Vector &x, EGS_BaseGeometry *g, const EGS_Float axis_distance, const EGS_Float track_alpha, const bool track_clip); void getRegions(const EGS_Vector &x, EGS_BaseGeometry *g, int *regions, EGS_Vector *colors, int maxreg); diff --git a/HEN_HOUSE/egs++/view/geometryview.ui.h b/HEN_HOUSE/egs++/view/geometryview.ui.h index c2e835808..c23e517a6 100644 --- a/HEN_HOUSE/egs++/view/geometryview.ui.h +++ b/HEN_HOUSE/egs++/view/geometryview.ui.h @@ -49,21 +49,21 @@ void GeometryView::updateView() { } -void GeometryView::xRotation( int rot ) { +void GeometryView::xRotation(int rot) { #ifdef VIEW_DEBUG egsWarning("In GeometryView::xRotation(%d)\n",rot); #endif } -void GeometryView::yRotation( int rot ) { +void GeometryView::yRotation(int rot) { #ifdef VIEW_DEBUG egsWarning("In GeometryView::yRotation(%d)\n",rot); #endif } -void GeometryView::zRotation( int rot ) { +void GeometryView::zRotation(int rot) { #ifdef VIEW_DEBUG egsWarning("In GeometryView::zRotation(%d)\n",rot); #endif diff --git a/HEN_HOUSE/egs++/view/image_window.cpp b/HEN_HOUSE/egs++/view/image_window.cpp new file mode 100644 index 000000000..b85e8e8df --- /dev/null +++ b/HEN_HOUSE/egs++/view/image_window.cpp @@ -0,0 +1,611 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer image window headers +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Iwan Kawrakow, 2005 +# +# Contributors: Frederic Tessier +# Manuel Stoeckl +# +############################################################################### +*/ + +#include "image_window.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// The below shim exists to ensure that QThread by default +// runs an event loop for older Qt versions. +#if QT_VERSION < 0x040400 +class Thread : public QThread { +public: + Thread() : QThread() {} + void run() { + exec(); + } +}; +#else +typedef QThread Thread; +#endif + + + +ImageWindow::ImageWindow(QWidget *parent, const char *name) : + QWidget(parent,Qt::Window) { + setObjectName(name); + + navigationTimer = new QTimer(this); + navigationTimer->setSingleShot(true); + connect(navigationTimer, SIGNAL(timeout()), this, SLOT(endTransformation())); + + navigating=false; + setMouseTracking(true); + rerenderRequested = false; + + renderState = WorkerIdle; + lastResult.elapsedTime = -1.; + + lastRequestGeo = NULL; + saveProgress = NULL; + regionsDisplayed = true; + + vis = new EGS_GeometryVisualizer; + + // register types so they can be transfered accross thread + qRegisterMetaType("RenderParameters"); + qRegisterMetaType("RenderResults"); + + // Initialize render worker and put it in a thread + restartWorker(); + + // disable Qt's background refill for the Widget, so we can paint + // over our existing buffer when picking regions + setAttribute(Qt::WA_OpaquePaintEvent); +} + +ImageWindow::~ImageWindow() { + stopWorker(); + delete navigationTimer; + delete vis; +}; + +/* no longer in Qt4. What was this supposed to do? + void polish() { + //QDialog::polish(); + QWidget::polish(); + QWidget *topl = topLevelWidget(); + //egsWarning("In polish: position: %d %d\n",pos().x(),pos().y()); + //if( !topl ) egsWarning("Null top level widget!\n"); + QWidget *parent = parentWidget(); + if( !parent ) parent = topl; + //egsWarning("parent: %s\n",parent->name()); + if( parent ) { + QPoint point = parent->mapToGlobal(QPoint(0,0)); + //egsWarning("parent: %d %d\n",point.x(),point.y()); + //QRect my_frame = frameGeometry(); + //egsWarning("my geometry: %d %d %d %d\n",my_frame.left(), + // my_frame.right(),my_frame.top(),my_frame.bottom()); + int gview_x = point.x(); + int gview_y = point.y() + parent->height(); + //egsWarning("moving to %d %d\n",gview_x,gview_y); + move(gview_x,gview_y); + //my_frame = frameGeometry(); + //egsWarning("my geometry: %d %d %d %d\n",my_frame.left(), + // my_frame.right(),my_frame.top(),my_frame.bottom()); + } + }; + */ + +void ImageWindow::render(EGS_BaseGeometry *geo, bool transform) { + if (transform) { + startTransformation(); + } + if (navigating) { + pars.requestType = Transformation; + } + else { + pars.requestType = FullDetail; + } + rerender(geo); +} + +void ImageWindow::rerender(EGS_BaseGeometry *geo) { + if (!thread) { + // Don't bother if the thread has been disabled + return; + } + + lastRequestGeo = geo; + + // Determine scaling depending on if the request is to + // draw at full detail or to be interactive. This flag _should_ be local + + if (pars.requestType == FullDetail) { + pars.nx = this->width(); + pars.ny = this->height(); + pars.nxr = 1; + pars.nyr = 1; + } + else if (pars.requestType == Transformation) { + // Dynamically select a good render mode + int nx=this->width(),ny=this->height(); + int nxr=nx,nyr=ny; + if (lastResult.elapsedTime > 0) { + // Cut out the track time because that is a fixed overhead. + // Otherwise, when you have a few hundred megabytes of tracks, + // the view decays to a single pixel and you _still_ get lag. + // The proper fix is some sort of track level-of-detail mechanism. + EGS_Float timePerPixel = (lastResult.elapsedTime - lastResult.trackTime) / (lastRequest.nx * lastRequest.ny); + EGS_Float target = 30.0; // msecs per frame + EGS_Float scale = nx*ny * timePerPixel / target; + + if (scale > 1) { + scale = 1./sqrt(scale); + int nnx = (int)(scale*nx), nny = (int)(scale*ny); + if (nnx < 1) { + nnx = 1; + } + if (nny < 1) { + nny = 1; + } + nxr = nx/nnx; + if (nxr*nnx != nx) { + nxr++; + } + nyr = ny/nny; + if (nyr*nny != ny) { + nyr++; + } + nnx = nx/nxr; + nny = ny/nyr; + if (nnx*nxr < nx) { + nnx++; + } + if (nny*nyr < ny) { + nny++; + } +#ifdef VIEW_DEBUG + egsWarning(" nx=%d ny=%d nnx=%d nny=%d nxr=%d nyr=%d\n", + nx,ny,nnx,nny,nxr,nyr); +#endif + nx = nnx; + ny = nny; + } + else { + nxr = 1; + nyr = 1; + } + } + else { + // First-time scale values. + nxr = 4; + nyr = 4; + int nnx = nx/nxr, nny = ny/nyr; + if (nnx*nxr < nx) { + nx = nnx+1; + } + else { + nx = nnx; + } + if (nny*nyr < ny) { + ny = nny+1; + } + else { + ny = nny; + } + } + pars.nx = nx; + pars.ny = ny; + pars.nxr = nxr; + pars.nyr = nyr; + } + else { + // sizes subject to external control. + } + + // TODO: need some fast-abort method for the worker, to cancel + // old jobs IFF they are of lower priority than the current one + + if (renderState == WorkerIdle) { + activeRequestType = pars.requestType; + emit requestRender(lastRequestGeo,pars); + renderState = WorkerCalculating; + } + else if (renderState == WorkerCalculating) { + // abort only to interrupt a full-detail calculation by a transformation + // since the latter makes the former invalid. + if (activeRequestType == FullDetail && pars.requestType == Transformation) { + worker->abort_location = 1; + } + renderState = WorkerBackordered; + } +} + +void ImageWindow::loadTracks(QString name) { + emit requestLoadTracks(name); +} + + +void ImageWindow::saveView(EGS_BaseGeometry *geo, int nx, int ny, QString name, QString ext) { + saveName = name; + saveExtension = ext; + // Temporarily change parameters to render at new resolution + int oldnx = pars.nx; + int oldny = pars.ny; + RenderRequestType oldrq = pars.requestType; + pars.nx = nx; + pars.ny = ny; + pars.requestType = SavedImage; + rerender(geo); + pars.nx = oldnx; + pars.ny = oldny; + pars.requestType = oldrq; + saveProgress = new QProgressDialog("Saving image", "&Cancel", 0, 2, this); + saveProgress->setMinimumDuration(500); +} + +void ImageWindow::stopWorker() { + if (thread) { + // stop the present task + worker->abort_location = 1; + thread->quit(); + thread->wait(); + delete thread; + delete worker; + lastRequestGeo = NULL; + worker = NULL; + thread = NULL; + } +} + + +void ImageWindow::restartWorker() { + worker = new RenderWorker(); + thread = new Thread(); + worker->moveToThread(thread); + connect(this, SIGNAL(requestRender(EGS_BaseGeometry *,RenderParameters)), + worker, SLOT(render(EGS_BaseGeometry *,RenderParameters))); + connect(this, SIGNAL(requestLoadTracks(QString)), worker, SLOT(loadTracks(QString))); + connect(worker, SIGNAL(rendered(RenderResults,RenderParameters)), this, SLOT(drawResults(RenderResults,RenderParameters))); + connect(worker, SIGNAL(aborted()), this, SLOT(handleAbort())); + thread->start(); +} + +void ImageWindow::startTransformation() { + navigationTimer->stop(); + navigationTimer->start(500); + navigating = true; +} + +void ImageWindow::endTransformation() { + navigationTimer->stop(); + navigating = false; + if (lastRequestGeo) { + render(lastRequestGeo, false); + } +} + +void ImageWindow::resizeEvent(QResizeEvent *e) { +#ifdef VIEW_DEBUG + egsWarning("In resizeEvent(): size is %d %d old size is: %d %d" " shown: %d\n",width(),height(),e->oldSize().width(), e->oldSize().height(),isVisible()); +#endif + QWidget::resizeEvent(e); + + if (e->size() != e->oldSize() && lastRequestGeo) { + // treat this as a transformation, since more resizes tend to follow + startTransformation(); + render(lastRequestGeo, false); + } +}; + +void ImageWindow::paintBackground(QPainter &p) { + const RenderParameters &q = lastRequest; + const RenderResults &r = lastResult; + if (q.nxr == 1 && q.nyr == 1) { + p.drawImage(QPoint(0,0),r.img); + } + else { + p.drawImage(QRect(0,0,q.nxr * q.nx, q.nyr * q.ny),r.img); + } + + if (q.draw_axeslabels) { + p.setPen(QColor(255,255,255)); + p.drawText((int)(q.nxr*r.axeslabelsX.x-3),q.nyr*q.ny-(int)(q.nyr*r.axeslabelsX.y-3),"x"); + p.drawText((int)(q.nxr*r.axeslabelsY.x-3),q.nyr*q.ny-(int)(q.nyr*r.axeslabelsY.y-3),"y"); + p.drawText((int)(q.nxr*r.axeslabelsZ.x-3),q.nyr*q.ny-(int)(q.nyr*r.axeslabelsZ.y-3),"z"); + } +} + +void ImageWindow::paintEvent(QPaintEvent *) { + if (!thread) { + // in geometry change period + return; + } + + const RenderParameters &q = lastRequest; + const RenderResults &r = lastResult; + // only draw if there was already a request + if (r.img.isNull() || lastRequestGeo == NULL) { + return; + } + + bool wasRerenderRequested = rerenderRequested; + rerenderRequested = false; + if (wasRerenderRequested) { + QPainter p(this); + paintBackground(p); + p.end(); + } + + if (!navigating) { + // Don't recalculate an identical point, unless + // the rerender wiped everything. + if (!wasRerenderRequested && xyMouse == lastMouse) { + return; + } + lastMouse = xyMouse; + + int w = (q.nx*q.nxr); + int h = (q.ny*q.nyr); + EGS_Float xscreen, yscreen; + xscreen = (xyMouse.x()-w/2)*q.projection_x/w; + yscreen = -(xyMouse.y()-h/2)*q.projection_y/h; + EGS_Vector xp(q.screen_xo + q.screen_v2*yscreen + q.screen_v1*xscreen); + + int maxreg=N_REG_MAX; + int regions[N_REG_MAX]; + EGS_Vector colors[N_REG_MAX]; + vis->getRegions(xp, lastRequestGeo, regions, colors, maxreg); + if (!wasRerenderRequested && memcmp(regions, lastRegions, sizeof(lastRegions)) == 0) { + return; + } + memcpy(lastRegions, regions, sizeof(lastRegions)); + + int x0 = 10; + int y0 = 20; + int s = 10; + int dy = 15; + QPainter p(this); + QRect coveredRegion(0,0,64,h); + p.setClipRect(coveredRegion); + + // The below code is very CPU-inefficient. Please optimize! + if (regions[0]>=0) { + p.fillRect(coveredRegion,QColor(0,0,0)); + p.setPen(QColor(255,255,255)); + p.drawText(x0-1,y0,"Regions"); + y0+=10; + regionsDisplayed=true; + } + else { + if (regionsDisplayed) { + regionsDisplayed=false; + // repaint just the eclipsed region (painter has clip) + paintBackground(p); + } + p.end(); + return; + } + + QFont font(p.font()); + + // Numbers *should* be rendered in tabular format, + // so we need only iterate on the longest number. + // If that assumption proves wrong, then we can + // iterate on the longest string, since point sizes + // shouldn't change that. + int mxval = 0; + for (int j=0; j mxval) { + mxval = regions[j]; + } + } + QString mxstring = QString::number(mxval); + + while (1) { + int wmax = p.fontMetrics().width(mxstring); + if (wmax < 41) { + break; + } + int npix = font.pixelSize(), npoint = font.pointSize(); + if (npix > 0) { + font.setPixelSize(npix-1); + //qWarning("Reducing font size to %d pixels",npix-1); + } + else { + font.setPointSize(npoint-1); + //qWarning("Reducing font size to %d points",npoint-1); + } + p.setFont(font); + } + + for (int reg = 0; reg < maxreg && regions[reg] >= 0; reg++) { + p.fillRect(x0, y0+reg*dy, s, s, + QColor((int)(255*colors[reg].x), (int)(255*colors[reg].y), + (int)(255*colors[reg].z))); + p.setPen(QColor(255,255,255)); + p.drawRect(x0, y0+reg*dy, s, s); + p.drawText(x0+s+3,y0+reg*dy+s,QString::number(regions[reg])); + if (reg+1 == maxreg) { + p.drawText(x0,y0+(reg+1)*dy+s,"..."); + } + } + p.end(); + } +} + +void ImageWindow::mouseReleaseEvent(QMouseEvent *event) { +#ifdef VIEW_DEBUG + egsWarning("In mouseReleaseEvent(): mouse location = (%d, %d)\n", event->x(), event->y()); + egsWarning(" Mouse buttons: %0x\n", event->button()); +#endif + // 500 msec before returning to full resolution (after button released) + if (navigating) { + navigationTimer->start(500); + navigating=false; + } + else if (event->button() == Qt::LeftButton) { + egsWarning("release event at %d %d\n",event->x(),event->y()); + emit leftMouseClick(event->x(),event->y()); + } +} + +void ImageWindow::mouseMoveEvent(QMouseEvent *event) { + int dx = event->x()-xyMouse.x(); + int dy = event->y()-xyMouse.y(); + xyMouse = event->pos(); + + // set up navigation + if (event->buttons() & (Qt::LeftButton|Qt::MidButton)) { + // Keep the timer off so long holds with depressed button work + navigating = true; + navigationTimer->stop(); + } + + // navigate + if (event->buttons() & Qt::LeftButton) { + // camera roll + if (event->modifiers() & Qt::ShiftModifier) { + emit cameraRolling(dx); + } + // camera translate + else if (event->modifiers() & Qt::ControlModifier) { + emit cameraTranslating(dx, dy); + } + // camera rotate + else { + emit cameraRotation(dx, dy); + } + } + else if (event->buttons() & Qt::MidButton) { + // camera zoom + emit cameraZooming(-dy); + } + else { + // picking + this->update(); + } +}; + +void ImageWindow::wheelEvent(QWheelEvent *event) { +#ifdef VIEW_DEBUG + egsWarning("In wheelEvent(): mouse location = (%d, %d)\n", event->x(), event->y()); + egsWarning(" Buttons: %0x\n", event->buttons()); +#endif + startTransformation(); + emit cameraZooming(event->delta()/20); +}; + +void ImageWindow::keyPressEvent(QKeyEvent *event) { +#ifdef VIEW_DEBUG + egsWarning("In keyPressEvent()\n"); +#endif + if (event->key() == Qt::Key_Home) { + if (event->modifiers() & Qt::AltModifier) { + emit cameraHomeDefining(); + } + else { + emit(cameraHoming()); + } + } + else if (event->key() == Qt::Key_X) { + emit putCameraOnAxis('x'); + } + else if (event->key() == Qt::Key_Y) { + emit putCameraOnAxis('y'); + } + else if (event->key() == Qt::Key_Z) { + emit putCameraOnAxis('z'); + } +// else if (event->key() == Qt::Key_D) emit renderAndDebug(); + else { + (event->ignore()); + } +}; + +void ImageWindow::drawResults(RenderResults r, RenderParameters q) { + lastResult = r; + lastRequest = q; + + // update the render thread status and queue next image if necessary + switch (renderState) { + case WorkerBackordered: + renderState = WorkerIdle; + rerender(lastRequestGeo); + break; + case WorkerCalculating: + renderState = WorkerIdle; + break; + case WorkerIdle: + qCritical("Yikes! Unexpected request fulfillment."); + break; + } + + if (lastRequest.requestType == SavedImage) { + if (saveProgress) { + if (!saveProgress->wasCanceled()) { + lastResult.img.save(saveName, saveExtension.toLatin1().constData()); + } + delete saveProgress; + saveProgress = NULL; + } + } + else { + if (saveProgress) { + saveProgress->setValue(1); + } + + rerenderRequested = true; + if (!this->isVisible()) { + this->show(); + } + + // Synchronize the local visualizer precisely with + // what is currently on screen. + applyParameters(vis, lastRequest); + + repaint(); + } +} + +void ImageWindow::handleAbort() { + // Clear abort flag on worker. + if (worker) { + worker->abort_location = 0; + if (renderState == WorkerBackordered) { + // i.e., another task to run + renderState = WorkerIdle; + rerender(lastRequestGeo); + } + } +} diff --git a/HEN_HOUSE/egs++/view/image_window.h b/HEN_HOUSE/egs++/view/image_window.h index 7f5eb1ece..185064b17 100644 --- a/HEN_HOUSE/egs++/view/image_window.h +++ b/HEN_HOUSE/egs++/view/image_window.h @@ -24,6 +24,7 @@ # Author: Iwan Kawrakow, 2005 # # Contributors: Frederic Tessier +# Manuel Stoeckl # ############################################################################### */ @@ -32,193 +33,106 @@ #ifndef IMAGE_WINDOW_ #define IMAGE_WINDOW_ +#include "renderworker.h" + #include "egs_libconfig.h" #include "egs_functions.h" +#include "egs_visualizer.h" + +#include +#include -#include -#include +class QTimer; +class QThread; +class QProgressDialog; -// #include "egs_functions.h" -// #define VIEW_DEBUG +// Maximum number of regions displayed +#define N_REG_MAX 30 -//class ImageWindow : public QDialog { class ImageWindow : public QWidget { Q_OBJECT - public: - //ImageWindow(QWidget *parent = 0, const char *name = 0, bool modal = FALSE, - // WFlags f = 0 ) : QDialog(parent,name,modal,f), resizing(false) { }; - ImageWindow(QWidget *parent=0, const char *name=0, WFlags f=0 ) : QWidget(parent,name,f), resizing(false) { - navigationTimer = new QTimer(this); - connect (navigationTimer, SIGNAL(timeout()), parent, SLOT(endTransformation())); - navigating=false; - setMouseTracking(true);} - ~ImageWindow() {}; - void polish() { - //QDialog::polish(); - QWidget::polish(); - QWidget *topl = topLevelWidget(); - //egsWarning("In polish: position: %d %d\n",pos().x(),pos().y()); - //if( !topl ) egsWarning("Null top level widget!\n"); - QWidget *parent = parentWidget(); - if( !parent ) parent = topl; - //egsWarning("parent: %s\n",parent->name()); - if( parent ) { - QPoint point = parent->mapToGlobal(QPoint(0,0)); - //egsWarning("parent: %d %d\n",point.x(),point.y()); - //QRect my_frame = frameGeometry(); - //egsWarning("my geometry: %d %d %d %d\n",my_frame.left(), - // my_frame.right(),my_frame.top(),my_frame.bottom()); - int gview_x = point.x(); - int gview_y = point.y() + parent->height(); - //egsWarning("moving to %d %d\n",gview_x,gview_y); - move(gview_x,gview_y); - //my_frame = frameGeometry(); - //egsWarning("my geometry: %d %d %d %d\n",my_frame.left(), - // my_frame.right(),my_frame.top(),my_frame.bottom()); - } - }; - - int xMouse, yMouse; + struct RenderParameters pars; + + ImageWindow(QWidget *parent=0, const char *name=0); + ~ImageWindow(); + +public slots: + + void render(EGS_BaseGeometry *geo, bool transform); + void loadTracks(QString name); + void saveView(EGS_BaseGeometry *geo, int nx, int ny, QString name, QString ext); + + void stopWorker(); + void restartWorker(); + + void startTransformation(); + void endTransformation(); protected: - void resizeEvent(QResizeEvent *e) { -#ifdef VIEW_DEBUG - egsWarning("In resizeEvent(): size is %d %d old size is: %d %d" " shown: %d\n",width(),height(),e->oldSize().width(), e->oldSize().height(),isShown()); -#endif - resizing = isShown(); - //QDialog::resizeEvent(e); - QWidget::resizeEvent(e); - }; - - void paintEvent (QPaintEvent *) { - #ifdef VIEW_DEBUG - egsWarning("In paintEvent(): size is %d %d resizing is %d\n", width(),height(),resizing); - #endif - emit needRepaint(false); - resizing = false; - }; - - void mouseReleaseEvent (QMouseEvent *event) { -#ifdef VIEW_DEBUG - egsWarning("In mouseReleaseEvent(): mouse location = (%d, %d)\n", event->x(), event->y()); - egsWarning(" Mouse buttons: %0x\n", event->button()); -#endif - // 500 msec before returning to full resolution (after button released) - if (navigating) { - navigationTimer->start(500, TRUE); - emit regionPicking(xMouse, yMouse); - navigating=false; - } - else if( event->button() == Qt::LeftButton ) { - egsWarning("release event at %d %d\n",event->x(),event->y()); - emit leftMouseClick(event->x(),event->y()); - } - } - - //virtual void mousePressEvent ( QMouseEvent * e ) - //virtual void mouseReleaseEvent ( QMouseEvent * e ) - - void mouseMoveEvent (QMouseEvent *event) { - int dx = event->x()-xMouse; - int dy = event->y()-yMouse; - xMouse = event->x(); - yMouse = event->y(); - - // set up navigation - if (event->state() & (Qt::LeftButton|Qt::MidButton)) { - if (!navigating) { - emit startTransformation(); - navigationTimer->stop(); - navigating=true; - } - } - - // navigate - if (event->state() & Qt::LeftButton) { - // camera roll - if (event->state() & Qt::ShiftButton) { - emit cameraRolling(dx); - } - // camera translate - else if (event->state() & Qt::ControlButton) { - emit cameraTranslating(dx, dy); - } - // camera rotate - else { - emit cameraRotation(dx, dy); - } - } - else if (event->state() & Qt::MidButton) { - // camera zoom - emit cameraZooming(-dy); - } - else { - // picking - emit regionPicking(xMouse, yMouse); - } - }; - - void wheelEvent (QWheelEvent *event) { - #ifdef VIEW_DEBUG - egsWarning("In wheelEvent(): mouse location = (%d, %d)\n", event->x(), event->y()); - egsWarning(" Buttons: %0x\n", event->state()); - #endif - emit startTransformation(); - emit cameraZooming(event->delta()/20); - // 500 msec before returning to full resolution (after wheel events) - navigationTimer->start(500, TRUE); - emit regionPicking(xMouse, yMouse); - }; - - void keyPressEvent (QKeyEvent *event) { - #ifdef VIEW_DEBUG - egsWarning("In keyPressEvent()\n"); - #endif - if (event->key() == Qt::Key_Home) { - if (event->state() & Qt::AltButton) { - emit cameraHomeDefining(); - } - else { - emit (cameraHoming()); - } - } - else if (event->key() == Qt::Key_X) emit putCameraOnAxis('x'); - else if (event->key() == Qt::Key_Y) emit putCameraOnAxis('y'); - else if (event->key() == Qt::Key_Z) emit putCameraOnAxis('z'); - else if (event->key() == Qt::Key_D) emit renderAndDebug(); - else (event->ignore()); - }; + void rerender(EGS_BaseGeometry *geo); + + void resizeEvent(QResizeEvent *e); + void paintEvent(QPaintEvent *); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + void keyPressEvent(QKeyEvent *event); + +protected slots: + + void drawResults(RenderResults,RenderParameters); + void handleAbort(); signals: void changedSize(int w, int h); - void needRepaint(bool); - void cameraRotation(int dx, int dy); - void cameraZooming(int dy); + void cameraRotation(int dx, int dy); + void cameraZooming(int dy); void cameraRolling(int dx); void cameraTranslating(int dx, int dy); void cameraHoming(); void cameraHomeDefining(); - void startTransformation(); - void endTransformation(); void putCameraOnAxis(char axis); - void regionPicking(int x, int y); void leftMouseClick(int x, int y); - void renderAndDebug(); + // for render thread + void requestRender(EGS_BaseGeometry *,RenderParameters); + void requestLoadTracks(QString); private: + void paintBackground(QPainter &p); - bool resizing; + // Navigation/Control QTimer *navigationTimer; bool navigating; - + bool rerenderRequested; + + // regionPicking synchronized with image on screen + EGS_GeometryVisualizer *vis; + bool regionsDisplayed; + QPoint xyMouse; + QPoint lastMouse; + int lastRegions[N_REG_MAX]; + + // Worker thread handling + QThread *thread; + RenderWorker *worker; + RenderResults lastResult; + RenderParameters lastRequest; + enum {WorkerIdle, WorkerCalculating, WorkerBackordered} renderState; + EGS_BaseGeometry *lastRequestGeo; + RenderRequestType activeRequestType; + + // Image saving + QString saveName; + QString saveExtension; + QProgressDialog *saveProgress; }; #endif diff --git a/HEN_HOUSE/egs++/view/main.cpp b/HEN_HOUSE/egs++/view/main.cpp index 8acfac338..e3c10cfac 100644 --- a/HEN_HOUSE/egs++/view/main.cpp +++ b/HEN_HOUSE/egs++/view/main.cpp @@ -54,38 +54,41 @@ std::ofstream debug_output("view_debug"); static char mybuf[8192]; void my_fatal_function(const char *msg,...) { - va_list ap; va_start( ap, msg ); + va_list ap; + va_start(ap, msg); vsprintf(mybuf,msg,ap); va_end(ap); - debug_output << mybuf; exit(1); + debug_output << mybuf; + exit(1); } void my_info_function(const char *msg,...) { - va_list ap; va_start( ap, msg ); + va_list ap; + va_start(ap, msg); vsprintf(mybuf,msg,ap); va_end(ap); debug_output << mybuf; } #endif -int main( int argc, char ** argv ) -{ +int main(int argc, char **argv) { - QApplication a( argc, argv ); - QString input_file = argc >= 2 ? argv[1] : - QFileDialog::getOpenFileName(QString::null,QString::null,0,0, - "Select geometry definition file"); + QApplication a(argc, argv); + QString input_file = argc >= 2 ? QString(argv[1]) : + QFileDialog::getOpenFileName(NULL,"Select geometry definition file"); QString tracks_file = argc >= 3 ? argv[2] : ""; //if( argc < 2 ) egsFatal("\nUsage: %s geometry_file\n\n",argv[0]); //QFile file(argv[1]); #ifdef VDEBUG - debug_output << "Using " << input_file.latin1() << "\n"; + debug_output << "Using " << input_file.toLatin1().data() << "\n"; egsSetInfoFunction(Information,my_info_function); egsSetInfoFunction(Warning,my_info_function); egsSetInfoFunction(Fatal,my_fatal_function); #endif QFile file(input_file); - if( !file.exists() ) egsFatal("\nFile %s does not exist\n\n",argv[1]); + if (!file.exists()) { + egsFatal("\nFile %s does not exist\n\n",argv[1]); + } #ifdef VDEBUG debug_output << "About to construct EGS_Input object\n"; @@ -96,7 +99,7 @@ int main( int argc, char ** argv ) #endif //input.setContentFromFile(argv[1]); - input.setContentFromFile(input_file.latin1()); + input.setContentFromFile(input_file.toUtf8().constData()); #ifdef VDEBUG debug_output << "Finished parsing\n"; #endif @@ -108,39 +111,58 @@ int main( int argc, char ** argv ) #ifdef VDEBUG debug_output << "Got geometry\n"; #endif - if( !g ) egsFatal("\nThe input file %s seems to not define a valid" - " geometry\n\n",argv[1]); + if (!g) egsFatal("\nThe input file %s seems to not define a valid" + " geometry\n\n",argv[1]); EGS_Float xmin = -50, xmax = 50; EGS_Float ymin = -50, ymax = 50; EGS_Float zmin = -50, zmax = 50; EGS_Input *vc = input.takeInputItem("view control"); std::vector user_colors; - if( vc ) { + if (vc) { EGS_Float tmp; - if( !vc->getInput("xmin",tmp) ) xmin = tmp; - if( !vc->getInput("xmax",tmp) ) xmax = tmp; - if( !vc->getInput("ymin",tmp) ) ymin = tmp; - if( !vc->getInput("ymax",tmp) ) ymax = tmp; - if( !vc->getInput("zmin",tmp) ) zmin = tmp; - if( !vc->getInput("zmax",tmp) ) zmax = tmp; + if (!vc->getInput("xmin",tmp)) { + xmin = tmp; + } + if (!vc->getInput("xmax",tmp)) { + xmax = tmp; + } + if (!vc->getInput("ymin",tmp)) { + ymin = tmp; + } + if (!vc->getInput("ymax",tmp)) { + ymax = tmp; + } + if (!vc->getInput("zmin",tmp)) { + zmin = tmp; + } + if (!vc->getInput("zmax",tmp)) { + zmax = tmp; + } EGS_Input *uc; - while( (uc = vc->takeInputItem("set color")) != 0 ) { + while ((uc = vc->takeInputItem("set color")) != 0) { vector inp; int err = uc->getInput("set color",inp); - if( !err && (inp.size() == 4 || inp.size() == 5) ) { + if (!err && (inp.size() == 4 || inp.size() == 5)) { qDebug("found color input %s %s %s %s",inp[0].c_str(),inp[1].c_str(),inp[2].c_str(),inp[3].c_str()); - EGS_UserColor ucolor; ucolor.medname = inp[0]; + EGS_UserColor ucolor; + ucolor.medname = inp[0]; sscanf(inp[1].c_str(),"%d",&ucolor.red); sscanf(inp[2].c_str(),"%d",&ucolor.green); sscanf(inp[3].c_str(),"%d",&ucolor.blue); - if( inp.size() == 5 ) sscanf(inp[4].c_str(),"%d",&ucolor.alpha); - else ucolor.alpha = 255; + if (inp.size() == 5) { + sscanf(inp[4].c_str(),"%d",&ucolor.alpha); + } + else { + ucolor.alpha = 255; + } qDebug("Using rgb=(%d,%d,%d %d) for medium %s",ucolor.red,ucolor.green,ucolor.blue, - ucolor.alpha,ucolor.medname.c_str()); + ucolor.alpha,ucolor.medname.c_str()); user_colors.push_back(ucolor); } - else qWarning("Wrong 'set color' input"); + else { + qWarning("Wrong 'set color' input"); + } delete uc; } delete vc; @@ -150,9 +172,11 @@ int main( int argc, char ** argv ) w.show(); w.setFilename(input_file); w.setTracksFilename(tracks_file); - if( w.setGeometry(g,user_colors,xmin,xmax,ymin,ymax,zmin,zmax,0) ) return 1; + if (w.setGeometry(g,user_colors,xmin,xmax,ymin,ymax,zmin,zmax,0)) { + return 1; + } - a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) ); + a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); return a.exec(); } diff --git a/HEN_HOUSE/egs++/view/renderworker.cpp b/HEN_HOUSE/egs++/view/renderworker.cpp new file mode 100644 index 000000000..766a2b257 --- /dev/null +++ b/HEN_HOUSE/egs++/view/renderworker.cpp @@ -0,0 +1,230 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer render control +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Manuel Stoeckl, 2015 +# +############################################################################### +*/ + +#include "renderworker.h" +#include "egs_visualizer.h" + +#include "qdatetime.h" + +RenderWorker::RenderWorker() { + vis = new EGS_GeometryVisualizer; + image = NULL; + nx_last = -1; + ny_last = -1; + abort_location = 0; +} +RenderWorker::~RenderWorker() { + delete vis; + if (image) { + delete[] image; + } +} + +void RenderWorker::loadTracks(QString fileName) { + vis->loadTracksData(fileName.toUtf8().constData()); +} + +void RenderWorker::drawAxes(const RenderParameters &p) { + EGS_Vector axes[4]; + + EGS_Vector v2_screen = p.camera_v2; + EGS_Vector v1_screen = p.camera_v1; + EGS_Float sx = p.projection_x; + EGS_Float sy = p.projection_y; + int nx = p.nx; + int ny = p.ny; + EGS_Float dx = sx/p.nx; + EGS_Float dy = sx/p.ny; + EGS_Vector v0 = (p.screen_xo-p.camera); + EGS_Float r = v0.length(); + EGS_Float taxis=0; + v0.normalize(); + EGS_Vector vp; + + // origin + vp = EGS_Vector(0,0,0) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axes[0].x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axes[0].y = ((vp*v2_screen+sy/2.0)/dy-0.5); + + // x axis + vp = EGS_Vector(p.axesmax.x,0,0) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axes[1].x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axes[1].y = ((vp*v2_screen+sy/2.0)/dy-0.5); + vp = EGS_Vector(p.axesmax.x+0.1*p.size, 0, 0) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axeslabelsX.x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axeslabelsX.y = ((vp*v2_screen+sy/2.0)/dy-0.5); + + // y axis + vp = EGS_Vector(0,p.axesmax.y,0) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axes[2].x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axes[2].y = ((vp*v2_screen+sy/2.0)/dy-0.5); + vp = EGS_Vector(0, p.axesmax.y+0.1*p.size, 0) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axeslabelsY.x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axeslabelsY.y = ((vp*v2_screen+sy/2.0)/dy-0.5); + + // z axis + vp = EGS_Vector(0,0,p.axesmax.z) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axes[3].x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axes[3].y = ((vp*v2_screen+sy/2.0)/dy-0.5); + vp = EGS_Vector(0, 0, p.axesmax.z+0.1*p.size) - p.camera; + vp.normalize(); + vp = vp*(r/(v0*vp)); + axeslabelsZ.x = ((vp*v1_screen+sx/2.0)/dx-0.5); + axeslabelsZ.y = ((vp*v2_screen+sy/2.0)/dy-0.5); + + // flag axis pixels with the (negative) distance to the axis, in z component (blue) + int i0 = (int) axes[0].x; + int j0 = (int) axes[0].y; + EGS_Float deltax, deltay; + // loop over axes + for (int k=1; k<=3; k++) { + int i1 = (int) axes[k].x; + int j1 = (int) axes[k].y; + int n = abs(i1-i0); + if (abs(j1-j0)>n) { + n = abs(j1-j0); + } + // more than one axis pixel: loop over axis pixels + if (n>0) { + deltax = (i1-i0)/(float)n; + deltay = (j1-j0)/(float)n; + for (int t=0; t<=n; t++) { + i1 = (int)(i0+t*deltax); + j1 = (int)(j0+t*deltay); + if (k==1) { + taxis = EGS_Vector(EGS_Vector(t*p.axesmax.x/n,0,0) - p.camera).length(); + } + if (k==2) { + taxis = EGS_Vector(EGS_Vector(0,t*p.axesmax.y/n,0) - p.camera).length(); + } + if (k==3) { + taxis = EGS_Vector(EGS_Vector(0,0,t*p.axesmax.z/n) - p.camera).length(); + } + if (i1>=0 && i1=0 && j1=0 && i1=0 && j1setProjection(p.camera,p.screen_xo,p.screen_v1,p.screen_v2,p.projection_x,p.projection_y); + // set lights, planes, materials. + for (size_t i=0; isetLight(i,new EGS_Light(p.lights[i])); + } + vis->clearClippingPlanes(); + for (size_t i=0; iaddClippingPlane(new EGS_ClippingPlane(p.clipping_planes[i])); + } + for (size_t i=0; isetMaterialColor(i,p.material_colors[i]); + } + vis->setGlobalAmbientLight(p.global_ambient_light); +} + +void RenderWorker::render(EGS_BaseGeometry *g, struct RenderParameters p) { + // wall-clock time, not CPU time; to optimize response + QTime itime = QTime::currentTime(); + + applyParameters(vis, p); + + // create image buffer, if new + if (p.nx != nx_last || p.ny != ny_last) { + delete[] image; + image = new EGS_Vector[p.nx*p.ny]; + nx_last = p.nx; + ny_last = p.ny; + } + + // modifies image and sets axeslabels + if (p.draw_axes) { + drawAxes(p); + } + + QTime pretracktime = QTime::currentTime(); + // render tracks + if (p.draw_tracks) { + vis->setParticleVisibility(1,p.show_photons); + vis->setParticleVisibility(2,p.show_electrons); + vis->setParticleVisibility(3,p.show_positrons); + vis->setParticleVisibility(4,p.show_other); + if (!vis->renderTracks(g,p.nx,p.ny,image,&abort_location)) { + emit aborted(); + return; + } + } + QTime posttracktime = QTime::currentTime(); + + // render main geometry + if (!vis->renderImage(g,p.nx,p.ny,image,&abort_location)) { + emit aborted(); + return; + } + + // transfer to image + QImage img(p.nx, p.ny, QImage::Format_ARGB32); + for (int j=0; j. +# +############################################################################### +# +# Author: Manuel Stoeckl, 2015 +# +############################################################################### +*/ + +#ifndef RENDERWORKER_H +#define RENDERWORKER_H + +#include "egs_visualizer.h" +#include "egs_light.h" + +#include +#include + +#include + +using std::vector; + +typedef enum { + Transformation, FullDetail, SavedImage +} RenderRequestType; + +// This struct is designed to be passed by value. +struct RenderParameters { + // Desired image size + int nx; + int ny; + int nxr; + int nyr; + // Clipping planes + vector clipping_planes; + // material colors + vector material_colors; + // lights + vector lights; + EGS_Vector global_ambient_light; + // track rendering + bool draw_tracks; + bool show_photons; + bool show_electrons; + bool show_positrons; + bool show_other; + // viewport + EGS_Vector camera; + EGS_Vector camera_v1; + EGS_Vector camera_v2; + EGS_Vector screen_xo; + EGS_Vector screen_v1; + EGS_Vector screen_v2; + EGS_Float projection_x; + EGS_Float projection_y; + // drawing axes (labels are offthread) + bool draw_axes; + bool draw_axeslabels; + EGS_Vector axesmax; + EGS_Float size; + // passthrough: request type. Does this belong in the struct? + RenderRequestType requestType; +}; + +struct RenderResults { + QImage img; + // scaling rules + EGS_Vector axeslabelsX; + EGS_Vector axeslabelsY; + EGS_Vector axeslabelsZ; + // misc info + EGS_Float elapsedTime; + EGS_Float trackTime; +}; + +void applyParameters(EGS_GeometryVisualizer *, const struct RenderParameters &); + +class RenderWorker : public QObject { + Q_OBJECT + +public: + + RenderWorker(); + virtual ~RenderWorker(); + + // Set this to a nonzero value to make all renders fail asap. + int abort_location; + +public slots: + + void loadTracks(QString fileName); + + void render(EGS_BaseGeometry *g, struct RenderParameters params); + +signals: + + void aborted(); + void rendered(struct RenderResults, struct RenderParameters params); + +private: + void drawAxes(const struct RenderParameters &); + + EGS_GeometryVisualizer *vis; + EGS_Vector *image; + EGS_Vector axeslabelsX; + EGS_Vector axeslabelsY; + EGS_Vector axeslabelsZ; + int nx_last; + int ny_last; +}; + +#endif // RENDERWORKER_H diff --git a/HEN_HOUSE/egs++/view/saveimage.ui.h b/HEN_HOUSE/egs++/view/saveimage.cpp similarity index 53% rename from HEN_HOUSE/egs++/view/saveimage.ui.h rename to HEN_HOUSE/egs++/view/saveimage.cpp index ec9975e27..e07f845ac 100644 --- a/HEN_HOUSE/egs++/view/saveimage.ui.h +++ b/HEN_HOUSE/egs++/view/saveimage.cpp @@ -23,36 +23,51 @@ # # Author: Iwan Kawrakow, 2005 # -# Contributors: -# -############################################################################### -# -# ui.h extension file, included from the uic-generated form implementation. -# -# If you want to add, delete, or rename functions or slots, use Qt Designer -# to update this file, preserving your code. -# -# You should not define a constructor or destructor in this file. Instead, -# write your code in functions called init() and destroy(). These will -# automatically be called by the form's constructor and destructor. +# Contributors: Manuel Stoeckl # ############################################################################### */ - #include "egs_libconfig.h" +#include "saveimage.h" #include #include #include #include +#include -void SaveImage::saveImage() { +#ifdef VIEW_DEBUG + extern void (* egsWarning)(const char *, ...); +#endif + +SaveImage::SaveImage(QWidget *parent, const char *name) + : QDialog(parent) { + setObjectName(name); + setModal(false); + setupUi(this); + + QList blist = QImageWriter::supportedImageFormats(); + int ind = -1; + for (int i=0; iaddItem(blist[i]); + if (QString(blist[i]).toUpper() == "PNG") { + ind = i; + } + } + if (ind >= 0) { + formatCB->setCurrentIndex(ind); + } +} + +SaveImage::~SaveImage() { + // Qt handles child _widget_ deletion } void SaveImage::getImageSize(int *nx, int *ny) { - *nx = xsizeSB->value(); *ny = ysizeSB->value(); + *nx = xsizeSB->value(); + *ny = ysizeSB->value(); } QString SaveImage::getImageFormat() { @@ -62,50 +77,52 @@ QString SaveImage::getImageFormat() { QString SaveImage::getImageFileName() { QString fname = fileName->text(), format = "."; format += formatCB->currentText(); - if( !fname.endsWith(format,false) ) fname += format.lower(); + if (!fname.endsWith(format,Qt::CaseInsensitive)) { + fname += format.toLower(); + } return fname; } void SaveImage::selectFileName() { QString filter = "Images("; - for(int j=0; jcount(); j++) { - filter += "*."; filter += formatCB->text(j).lower(); filter += " "; + for (int j=0; jcount(); j++) { + filter += "*."; + filter += formatCB->itemText(j).toLower(); + filter += " "; } filter += ")"; - QString s = QFileDialog::getSaveFileName(QString::null,filter, - this, - "save file dialog", - "Select a filename" ); - if( !s.isEmpty() ) { + QString s = QFileDialog::getSaveFileName(this, "Select a filename", QString(), filter); + if (!s.isEmpty()) { fileName->setText(s); - for(int j=0; jcount(); j++) { - if( s.endsWith(formatCB->text(j),false) ) - formatCB->setCurrentItem(j); + for (int j=0; jcount(); j++) { + if (s.endsWith(formatCB->itemText(j),Qt::CaseInsensitive)) { + formatCB->setCurrentIndex(j); + } } } } - -void SaveImage::init() { - QStringList list = QImage::outputFormatList(); - formatCB->insertStringList(list); - int ind = list.findIndex("PNG"); - if( ind >= 0 ) formatCB->setCurrentItem(ind); -} - void SaveImage::enableOkButton() { #ifdef VIEW_DEBUG egsWarning("In SaveImage::enableOkButton()\n"); #endif - if( !fileName->text().isEmpty() ) okButton->setEnabled(true); - else okButton->setEnabled(false); + if (!fileName->text().isEmpty()) { + okButton->setEnabled(true); + } + else { + okButton->setEnabled(false); + } } void SaveImage::fnameTextChanged(const QString &text) { #ifdef VIEW_DEBUG - egsWarning("SaveImage::fnameTextChanged(%s)\n",text.latin1()); + egsWarning("SaveImage::fnameTextChanged(%s)\n",text.toUtf8().constData()); #endif - if( text.isEmpty() ) okButton->setEnabled(false); - else okButton->setEnabled(true); -} + if (text.isEmpty()) { + okButton->setEnabled(false); + } + else { + okButton->setEnabled(true); + } +} \ No newline at end of file diff --git a/HEN_HOUSE/egs++/view/saveimage.h b/HEN_HOUSE/egs++/view/saveimage.h new file mode 100644 index 000000000..c9af6a213 --- /dev/null +++ b/HEN_HOUSE/egs++/view/saveimage.h @@ -0,0 +1,67 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer save image extensions +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Iwan Kawrakow, 2005 +# +# Contributors: Manuel Stoeckl +# +############################################################################### +*/ + +#ifndef SAVEIMAGE_H +#define SAVEIMAGE_H + +#include + +#include "ui_saveimage.h" // for Ui::SaveImage + +class SaveImage : public QDialog, public Ui::SaveImage { + Q_OBJECT + +public: + + SaveImage(QWidget *parent=0, const char *name=0); + virtual ~SaveImage(); + + virtual void getImageSize(int *, int *); + virtual QString getImageFormat(); + virtual QString getImageFileName(); + +public slots: + + virtual void selectFileName(); + virtual void enableOkButton(); + virtual void fnameTextChanged(const QString &); + +signals: + + void saveFileSelected(const QString &fname, const QString &format); + +protected slots: + + virtual void languageChange() { + retranslateUi(this); + } +}; + +#endif // SAVEIMAGE_H \ No newline at end of file diff --git a/HEN_HOUSE/egs++/view/saveimage.ui b/HEN_HOUSE/egs++/view/saveimage.ui index 96f715fd9..697a7673d 100644 --- a/HEN_HOUSE/egs++/view/saveimage.ui +++ b/HEN_HOUSE/egs++/view/saveimage.ui @@ -1,4 +1,5 @@ - + + ############################################################################### # # EGSnrc egs++ geometry viewer save image user interface @@ -27,219 +28,211 @@ # ############################################################################### -SaveImage - - - SaveImage - - - - 0 - 0 - 321 - 201 - - - - Save image - - - - unnamed + SaveImage + + + + 0 + 0 + 362 + 250 + + + + Save image + + + + + + + + Image size + + + + + + 4096 + + + 512 + + + + + + + 4096 + + + 512 + + + + + + + + + + Format + + + + + + + + + + + + + + File name + + + + + + + + + ... - - - layout9 - - - - unnamed - - - - groupBox11 - - - Image size - - - - unnamed - - - - xsizeSB - - - 4096 - - - 512 - - - - - ysizeSB - - - 4096 - - - 512 - - - - - - - groupBox12 - - - Format - - - - unnamed - - - - formatCB - - - - - - - - - groupBox13 - - - File name - - - - unnamed - - - - fileName - - - - - pushButton9 - - - ... - - - - - - - layout8 - - - - unnamed - - - - pushButton11 - - - &Cancel - - - Alt+C - - - - - spacer6 - - - Horizontal - - - Expanding - - - - 111 - 21 - - - - - - okButton - - - false - - - &OK - - - Alt+O - - - - - - - - - pushButton11 - clicked() - SaveImage - reject() - - - okButton - clicked() - SaveImage - accept() - - - pushButton9 - clicked() - SaveImage - selectFileName() - - - fileName - lostFocus() - SaveImage - enableOkButton() - - - fileName - textChanged(const QString&) - SaveImage - fnameTextChanged(const QString&) - - - - saveimage.ui.h - - - saveFileSelected(const QString &fname, const QString &format) - - - saveImage() - selectFileName() - enableOkButton() - fnameTextChanged( const QString & ) - - - init() - getImageSize(int *, int *) - getImageFormat() - getImageFileName() - - - - + + + + + + + + + + + &Cancel + + + Alt+C + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 111 + 21 + + + + + + + + false + + + &OK + + + Alt+O + + + + + + + + + + + + pushButton11 + clicked() + SaveImage + reject() + + + 20 + 20 + + + 20 + 20 + + + + + okButton + clicked() + SaveImage + accept() + + + 20 + 20 + + + 20 + 20 + + + + + pushButton9 + clicked() + SaveImage + selectFileName() + + + 20 + 20 + + + 20 + 20 + + + + + fileName + lostFocus() + SaveImage + enableOkButton() + + + 20 + 20 + + + 20 + 20 + + + + + fileName + textChanged(QString) + SaveImage + fnameTextChanged(QString) + + + 20 + 20 + + + 20 + 20 + + + + + diff --git a/HEN_HOUSE/egs++/view/view.pro b/HEN_HOUSE/egs++/view/view.pro index a1e779160..afa5c8b15 100644 --- a/HEN_HOUSE/egs++/view/view.pro +++ b/HEN_HOUSE/egs++/view/view.pro @@ -27,19 +27,21 @@ # ############################################################################### - TEMPLATE = app LANGUAGE = C++ INCLUDEPATH += . .. ../../lib/$$my_machine HEADERS += egs_visualizer.h image_window.h egs_light.h \ - clippingplanes.ui.h viewcontrol.ui.h geometryview.ui.h \ - saveimage.ui.h egs_user_color.h egs_track_view.h + clippingplanes.h viewcontrol.h geometryview.ui.h \ + saveimage.h egs_user_color.h egs_track_view.h \ + renderworker.h -SOURCES += main.cpp egs_visualizer.cpp egs_track_view.cpp +SOURCES += main.cpp egs_visualizer.cpp egs_track_view.cpp \ + saveimage.cpp clippingplanes.cpp viewcontrol.cpp \ + renderworker.cpp image_window.cpp -FORMS = viewcontrol.ui saveimage.ui clippingplanes.ui +FORMS = saveimage.ui clippingplanes.ui viewcontrol.ui win32 { CONFIG += qt warn_off release windows exceptions_off thread @@ -47,7 +49,8 @@ win32 { DEFINES += VDEBUG RC_FILE = egs_view.rc LIBS += ../dso/$$my_machine/egspp.lib - TARGET = ../dso/$$my_machine/egs_view + DESTDIR = ../dso/$$my_machine + TARGET = egs_view } unix { @@ -57,8 +60,6 @@ unix { TARGET = ../../bin/$$my_machine/egs_view } !macx { - #LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp - LIBS += -L$$hhouse/egs++//dso/$$my_machine -legspp DESTDIR = ../../bin/$$my_machine/ !contains( CONFIG, static ){ message( "Dynamic build..." ) @@ -68,7 +69,8 @@ unix { contains( CONFIG, static ){ message( "Static build ..." ) DESTDIR = ../../pieces/linux - LIBS += -L$$hhouse/egs++//dso/$$my_machine -legspp + #LIBS += -L../dso/$$my_machine -Wl,-rpath,$$hhouse/egs++/dso/$$my_machine -legspp # Fixes path to library + LIBS += -L$$hhouse/egs++/dso/$$my_machine -legspp # Relies on LD_LIBRARY_PATH UNAME = $$system(getconf LONG_BIT) contains( UNAME, 64 ){ message( "-> 64 bit ($$SNAME)" ) @@ -83,8 +85,14 @@ unix { } } +# Debug options #DEFINES += VIEW_DEBUG +#QMAKE_CXXFLAGS+="-fsanitize=address -fno-omit-frame-pointer" +#QMAKE_CXXFLAGS+="-ggdb3" +#QMAKE_LFLAGS+="-fsanitize=address" UI_DIR = .ui/$$my_machine MOC_DIR = .moc/$$my_machine OBJECTS_DIR = .obj/$$my_machine + + diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui.h b/HEN_HOUSE/egs++/view/viewcontrol.cpp similarity index 51% rename from HEN_HOUSE/egs++/view/viewcontrol.ui.h rename to HEN_HOUSE/egs++/view/viewcontrol.cpp index 6beeed5eb..d29938226 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui.h +++ b/HEN_HOUSE/egs++/view/viewcontrol.cpp @@ -25,34 +25,24 @@ # # Contributors: Frederic Tessier # Ernesto Mainegra-Hing -# -############################################################################### -# -# ui.h extension file, included from the uic-generated form implementation. -# -# If you want to add, delete, or rename functions or slots, use Qt Designer -# to update this file, preserving your code. -# -# You should not define a constructor or destructor in this file. Instead, -# write your code in functions called init() and destroy(). These will -# automatically be called by the form's constructor and destructor. +# Manuel Stoeckl # ############################################################################### */ +#include "image_window.h" +#include "saveimage.h" +#include "clippingplanes.h" +#include "viewcontrol.h" #include "egs_libconfig.h" #include "egs_functions.h" #include "egs_base_geometry.h" #include "egs_visualizer.h" #include "egs_timer.h" -#include "image_window.h" -#include "saveimage.h" -#include "clippingplanes.h" #include "egs_input.h" #include -#include #include #include #include @@ -61,6 +51,7 @@ #include #include #include +#include #include #include @@ -68,7 +59,7 @@ using namespace std; #ifndef M_PI -#define M_PI 3.14159265358979323846 + #define M_PI 3.14159265358979323846 #endif /* @@ -89,14 +80,17 @@ static char* standard_colors[] = { */ static unsigned char standard_red[] = { - 255, 0, 0, 0, 255, 255, 128, 0, 0, 0, 128, 128, 191, 80, - 0, 0, 0, 0, 85, 255, 192, 128}; + 255, 0, 0, 0, 255, 255, 128, 0, 0, 0, 128, 128, 191, 80, + 0, 0, 0, 0, 85, 255, 192, 128 +}; static unsigned char standard_green[] = { - 0, 255, 0, 255, 0, 255, 0, 128, 0, 128, 0, 128, 0, 0, - 191, 80, 0, 0, 170, 170, 192, 128}; + 0, 255, 0, 255, 0, 255, 0, 128, 0, 128, 0, 128, 0, 0, + 191, 80, 0, 0, 170, 170, 192, 128 +}; static unsigned char standard_blue[] = { - 0, 0, 255, 255, 255, 0, 0, 0, 128, 128, 128, 0, 0, 0, - 0, 0, 191, 80, 127, 127, 192, 128}; + 0, 0, 255, 255, 255, 0, 0, 0, 128, 128, 128, 0, 0, 0, + 0, 0, 191, 80, 127, 127, 192, 128 +}; // // EMH commented out since NOT in use anywhere !!! // @@ -107,82 +101,203 @@ static unsigned char standard_blue[] = { // "very dark blue","nameless1","nameless2","lightgray","darkgray"}; -void GeometryViewControl::reloadInput () { +GeometryViewControl::GeometryViewControl(QWidget *parent, const char *name) + : QDialog(parent) { + setObjectName(name); + setupUi(this); + +#ifdef VIEW_DEBUG + egsWarning("In init()\n"); +#endif + g = 0; + theta = 0; + c_theta = cos(theta); + s_theta = sin(theta); + phi = 0; + c_phi = cos(phi); + s_phi = sin(phi); + a_light = 0.25; + int ilight = (int)(a_light*ambientLight->maximum()); + ambientLight->blockSignals(true); + ambientLight->setValue(ilight); + ambientLight->blockSignals(false); + distance = 25; + //dCourse->setValue(0); +// dFine->setValue(25); + dfine = 250; + projection_scale = 1; + look_at = EGS_Vector(); + setLookAtLineEdit(); + projection_x = 15; + projection_y = 15; + setProjectionLineEdit(); + p_light = EGS_Vector(0,0,distance); + setLightLineEdit(); + camera = p_light; + screen_xo = EGS_Vector(); + screen_v1 = EGS_Vector(1,0,0); + screen_v2 = EGS_Vector(0,1,0); + + // various state variables + showAxes = this->showAxesCheckbox->isChecked(); + showAxesLabels = this->showAxesLabelsCheckbox->isChecked(); + showRegions = this->showRegionsCheckbox->isChecked(); + showTracks = this->showTracksCheckbox->isChecked(); + showPhotonTracks = this->showPhotonsCheckbox->isChecked(); + showElectronTracks = this->showElectronsCheckbox->isChecked(); + showPositronTracks = this->showPositronsCheckbox->isChecked(); + showOtherTracks = this->showOthersCheckbox->isChecked(); + + // camera orientation vectors (same as the screen vectors) + camera_v1 = screen_v1; + camera_v2 = screen_v2; + + // camera home position + camera_home = camera; + camera_home_v1 = camera_v1; + camera_home_v2 = camera_v2; + dfine_home = dfine; + + m_colors = 0; + nmed = 0; + + gview = new ImageWindow(this,"gview"); + gview->resize(512,512); + + // connect signals and slots for mouse navigation + connect(gview, SIGNAL(cameraRotation(int, int)), this, SLOT(cameraRotate(int, int))); + connect(gview, SIGNAL(cameraZooming(int)), this, SLOT(cameraZoom(int))); + connect(gview, SIGNAL(cameraHoming()), this, SLOT(cameraHome())); + connect(gview, SIGNAL(cameraHomeDefining()), this, SLOT(cameraHomeDefine())); + connect(gview, SIGNAL(cameraTranslating(int, int)), this, SLOT(cameraTranslate(int, int))); + connect(gview, SIGNAL(cameraRolling(int)), this, SLOT(cameraRoll(int))); + connect(gview, SIGNAL(putCameraOnAxis(char)), this, SLOT(cameraOnAxis(char))); + connect(gview, SIGNAL(leftMouseClick(int,int)), this, SLOT(reportViewSettings(int,int))); + + save_image = new SaveImage(this,"save image"); + + cplanes = new ClippingPlanesWidget; + setExtension(cplanes); + connect(cplanes,SIGNAL(clippingPlanesChanged()), + this,SLOT(setClippingPlanes())); + + // set the widget to show near the left-upper corner of the screen + move(QPoint(25,25)); + +} + + +GeometryViewControl::~GeometryViewControl() { +} + +void GeometryViewControl::reloadInput() { // check that the file (still) exists QFile file(filename); - if( !file.exists() ) { - egsWarning("\nFile %s does not exist anymore!\n\n",filename.latin1()); + if (!file.exists()) { + egsWarning("\nFile %s does not exist anymore!\n\n",filename.toUtf8().constData()); return; } // read the input file again EGS_Input input; - input.setContentFromFile(filename); + input.setContentFromFile(filename.toUtf8().constData()); // clear the current geometry - if( g ) { delete g; g = 0; } + gview->stopWorker(); + // Don't accept any more reload requests during this reload + reloadButton->blockSignals(true); + qApp->processEvents(); + // delete geometry + if (g) { + delete g; + g = 0; + } EGS_BaseGeometry::clearGeometries(); // restart from scratch (copied from main.cpp) EGS_BaseGeometry *newGeom = EGS_BaseGeometry::createGeometry(&input); - if( !newGeom ) egsFatal("\nThe input file %s seems to not define a valid" - " geometry\n\n",filename.latin1()); + if (!newGeom) egsFatal("\nThe input file %s seems to not define a valid" + " geometry\n\n",filename.toUtf8().constData()); EGS_Float xmin = -50, xmax = 50; EGS_Float ymin = -50, ymax = 50; EGS_Float zmin = -50, zmax = 50; EGS_Input *vc = input.takeInputItem("view control"); std::vector user_colors; - if( vc ) { + if (vc) { EGS_Float tmp; - if( !vc->getInput("xmin",tmp) ) xmin = tmp; - if( !vc->getInput("xmax",tmp) ) xmax = tmp; - if( !vc->getInput("ymin",tmp) ) ymin = tmp; - if( !vc->getInput("ymax",tmp) ) ymax = tmp; - if( !vc->getInput("zmin",tmp) ) zmin = tmp; - if( !vc->getInput("zmax",tmp) ) zmax = tmp; + if (!vc->getInput("xmin",tmp)) { + xmin = tmp; + } + if (!vc->getInput("xmax",tmp)) { + xmax = tmp; + } + if (!vc->getInput("ymin",tmp)) { + ymin = tmp; + } + if (!vc->getInput("ymax",tmp)) { + ymax = tmp; + } + if (!vc->getInput("zmin",tmp)) { + zmin = tmp; + } + if (!vc->getInput("zmax",tmp)) { + zmax = tmp; + } EGS_Input *uc; - while( (uc = vc->takeInputItem("set color")) != 0 ) { + while ((uc = vc->takeInputItem("set color")) != 0) { vector inp; int err = uc->getInput("set color",inp); - if( !err && (inp.size() == 4 || inp.size() == 5) ) { - EGS_UserColor ucolor; ucolor.medname = inp[0]; + if (!err && (inp.size() == 4 || inp.size() == 5)) { + EGS_UserColor ucolor; + ucolor.medname = inp[0]; sscanf(inp[1].c_str(),"%d",&ucolor.red); sscanf(inp[2].c_str(),"%d",&ucolor.green); sscanf(inp[3].c_str(),"%d",&ucolor.blue); - if( inp.size() == 5 ) sscanf(inp[4].c_str(),"%d",&ucolor.alpha); - else ucolor.alpha = 255; + if (inp.size() == 5) { + sscanf(inp[4].c_str(),"%d",&ucolor.alpha); + } + else { + ucolor.alpha = 255; + } user_colors.push_back(ucolor); } - else qWarning("Wrong 'set color' input"); + else { + qWarning("Wrong 'set color' input"); + } delete uc; } delete vc; } + // Start loading process + gview->restartWorker(); setGeometry(newGeom,user_colors,xmin,xmax,ymin,ymax,zmin,zmax,1); + reloadButton->blockSignals(false); } -void GeometryViewControl::setFilename (QString str) { +void GeometryViewControl::setFilename(QString str) { filename = str; } -void GeometryViewControl::setTracksFilename (QString str) { +void GeometryViewControl::setTracksFilename(QString str) { filename_tracks = str; } void GeometryViewControl::checkboxAxes(bool toggle) { this->showAxesLabelsCheckbox->setEnabled(toggle); showAxes = toggle; - if (toggle==false) + if (toggle==false) { showAxesLabels = false; - else + } + else { showAxesLabels = showAxesLabelsCheckbox->isChecked(); - renderImage(); + } + updateView(); } void GeometryViewControl::checkboxAxesLabels(bool toggle) { showAxesLabels = toggle; - renderImage(); + updateView(); } void GeometryViewControl::checkboxShowRegions(bool toggle) { @@ -191,91 +306,9 @@ void GeometryViewControl::checkboxShowRegions(bool toggle) { void GeometryViewControl::checkboxShowTracks(bool toggle) { showTracks = toggle; - renderImage(); -} - - -void GeometryViewControl::regionPick(int x, int y) { - - if (!showRegions) return; - - // convert mouse coordinates to screen coordinate - int w=gview->width(); - int h=gview->height(); - EGS_Float xscreen, yscreen; - xscreen = (x-w/2)*projection_x/w; - yscreen = -(y-h/2)*projection_y/h; - EGS_Vector xp(screen_xo + screen_v2*yscreen + screen_v1*xscreen); - - // get regions and colors list -#define N_REG_MAX 30 - int maxreg=N_REG_MAX; - int reg, regions[N_REG_MAX]; - EGS_Vector colors[N_REG_MAX]; - vis->getRegions(xp, g, regions, colors, maxreg); - - // draw regions list - int x0 = 10; - int y0 = 20; - int s = 10; - int dy = 15; - QString str; - QPainter p(gview); - reg=0; - if (regions[reg]>=0) { - p.fillRect(0,0,64,h,QColor(0,0,0)); - p.setPen(QColor(255,255,255)); - p.drawText(x0-1,y0,"Regions"); - y0+=10; - regionsDisplayed=true; - } - else if (regionsDisplayed){ - doRepaint(false); - regionsDisplayed=false; - } - if( regions[0] < 0 ) { p.end(); return; } - - // adjust font size if necessary - QFont font(p.font()); - while(1) { - int wmax = 0; - for(int j=0; j wmax ) wmax = wj; - } - if( wmax < 41 ) break; - int npix = font.pixelSize(), npoint = font.pointSize(); - if( npix > 0 ) { - font.setPixelSize(npix-1); - //qWarning("Reducing font size to %d pixels",npix-1); - } - else { - font.setPointSize(npoint-1); - //qWarning("Reducing font size to %d points",npoint-1); - } - p.setFont(font); - } - - // draw regions - while (regions[reg]>=0 && reg a_scale; -static vector a_size; -int dfine_max = 1000; + static vector a_scale; + static vector a_size; + int dfine_max = 1000; //Last step zooming in for current scale -if (dfine+dy <= 1) {// negative dy - a_scale.push_back(projection_scale);a_size.push_back(size); - dfine = dfine_max; size = projection_x; - projection_scale = size/EGS_Float(dfine); -} + if (dfine+dy <= 1) {// negative dy + a_scale.push_back(projection_scale); + a_size.push_back(size); + dfine = dfine_max; + size = projection_x; + projection_scale = size/EGS_Float(dfine); + } //Last step zooming out for current scale -else if ( dfine > dfine_max - dy ){ - if (a_scale.size()){ - projection_scale = a_scale.back(); size = a_size.back(); - dfine = int(projection_x/projection_scale); - a_scale.pop_back();a_size.pop_back(); - } - else{}//do nothing ... -} -else{ + else if (dfine > dfine_max - dy) { + if (a_scale.size()) { + projection_scale = a_scale.back(); + size = a_size.back(); + dfine = int(projection_x/projection_scale); + a_scale.pop_back(); + a_size.pop_back(); + } + else {} //do nothing ... + } + else { // 1 pixel mouse motion in y = 1 unit change in dfine - dfine += dy; -} -projection_x = projection_scale*dfine; -projection_y = projection_scale*dfine; + dfine += dy; + } + projection_x = projection_scale*dfine; + projection_y = projection_scale*dfine; // debug information #ifdef VIEW_DEBUG @@ -477,7 +526,7 @@ projection_y = projection_scale*dfine; #endif // render -renderImage(); + updateView(); } // void GeometryViewControl::cameraZoom(int dy) { @@ -488,7 +537,7 @@ renderImage(); // if (dfine>1000) dfine = 1000; // projection_x = projection_scale*dfine; // projection_y = projection_scale*dfine; -// // dFine->setValue((int)dfine); +// // dFine->setValue((int)dfine); // // // debug information // #ifdef VIEW_DEBUG @@ -501,22 +550,24 @@ renderImage(); // renderImage(); // } -void GeometryViewControl::thetaRotation( int Theta) { +void GeometryViewControl::thetaRotation(int Theta) { #ifdef VIEW_DEBUG egsWarning("In thetaRotation(%d)\n",Theta); #endif theta = Theta*M_PI/180; - c_theta = cos(theta); s_theta = sin(theta); + c_theta = cos(theta); + s_theta = sin(theta); setCameraPosition(); } -void GeometryViewControl::phiRotation( int Phi ) { +void GeometryViewControl::phiRotation(int Phi) { #ifdef VIEW_DEBUG egsWarning("In phiRotation(%d)\n",Phi); #endif phi = Phi*M_PI/180; - c_phi = cos(phi); s_phi = sin(phi); + c_phi = cos(phi); + s_phi = sin(phi); setCameraPosition(); } @@ -526,38 +577,20 @@ void GeometryViewControl::setCameraPosition() { // camera = look_at + EGS_Vector(s_theta*s_phi,s_theta*c_phi,c_theta)*3*distance; // screen_xo = look_at - EGS_Vector(s_theta*s_phi,s_theta*c_phi,c_theta)*distance; - #ifdef VIEW_DEBUG +#ifdef VIEW_DEBUG egsWarning("camera: (%g,%g,%g) screen: (%g,%g,%g)\n",camera.x,camera.y,camera.z,screen_xo.x,screen_xo.y,screen_xo.z); - #endif +#endif screen_v1 = camera_v1; screen_v2 = camera_v2; - if( moveLight->isChecked() ) { + if (moveLight->isChecked()) { p_light = camera; setLightLineEdit(); } - renderImage(); -} - -void GeometryViewControl::startTransformation() { -#ifdef VIEW_DEBUG - egsWarning("In startTransformation()\n"); -#endif - in_transformation = true; + updateView(); } - -void GeometryViewControl::endTransformation() { -#ifdef VIEW_DEBUG - egsWarning("In endTransformation()\n"); -#endif - in_transformation = false; - renderImage(); - regionPick(gview->xMouse, gview->yMouse); -} - - -void GeometryViewControl::changeDfine( int newdfine ) { +void GeometryViewControl::changeDfine(int newdfine) { #ifdef VIEW_DEBUG egsWarning("In changeDfine(%d)\n",newdfine); #endif @@ -566,7 +599,7 @@ void GeometryViewControl::changeDfine( int newdfine ) { projection_y = projection_scale*newdfine; dfine = newdfine; //egsWarning("dfine = %d projection_x = %g\n",projection_x,dfine); - renderImage(); + updateView(); //distance = dfine + dCourse->value(); //setCameraPosition(); } @@ -581,33 +614,37 @@ void GeometryViewControl::changeDfine( int newdfine ) { // } -void GeometryViewControl::changeAmbientLight( int alight ) { +void GeometryViewControl::changeAmbientLight(int alight) { #ifdef VIEW_DEBUG egsWarning("In changeAmbientLight(%d)\n",alight); #endif a_light = alight; - renderImage(); + updateView(true); } -void GeometryViewControl::changeTransperancy( int t ) { - int med = materialCB->currentItem(); +void GeometryViewControl::changeTransparency(int t) { + int med = materialCB->currentIndex(); QRgb c = m_colors[med]; - m_colors[med] = qRgba( qRed(c), qGreen(c), qBlue(c), t); + m_colors[med] = qRgba(qRed(c), qGreen(c), qBlue(c), t); #ifdef VIEW_DEBUG egsWarning("In changeTransperancy(%d): set color to %d\n",t,m_colors[med]); #endif setMaterialColor(med); - renderImage(); + updateView(true); } -void GeometryViewControl::moveLightChanged( int toggle ) { +void GeometryViewControl::moveLightChanged(int toggle) { #ifdef VIEW_DEBUG egsWarning("In moveLightChanged(%d)\n",toggle); #endif - if( !toggle ) lightPosGroup->setEnabled(true); - else lightPosGroup->setEnabled(false); + if (!toggle) { + lightPosGroup->setEnabled(true); + } + else { + lightPosGroup->setEnabled(false); + } } @@ -619,13 +656,27 @@ void GeometryViewControl::setLightPosition() { EGS_Float xx = lightX->text().toDouble(&ok_x), yy = lightY->text().toDouble(&ok_y), zz = lightZ->text().toDouble(&ok_z); - if( ok_x ) p_light.x = xx; - else lightX->setText(QString("%1").arg((double)p_light.x,0,'g',4)); - if( ok_y ) p_light.y = yy; - else lightY->setText(QString("%1").arg((double)p_light.y,0,'g',4)); - if( ok_z ) p_light.z = zz; - else lightZ->setText(QString("%1").arg((double)p_light.z,0,'g',4)); - if( ok_x || ok_y || ok_z ) renderImage(); + if (ok_x) { + p_light.x = xx; + } + else { + lightX->setText(QString("%1").arg((double)p_light.x,0,'g',4)); + } + if (ok_y) { + p_light.y = yy; + } + else { + lightY->setText(QString("%1").arg((double)p_light.y,0,'g',4)); + } + if (ok_z) { + p_light.z = zz; + } + else { + lightZ->setText(QString("%1").arg((double)p_light.z,0,'g',4)); + } + if (ok_x || ok_y || ok_z) { + updateView(); + } } @@ -637,13 +688,25 @@ void GeometryViewControl::setLookAt() { EGS_Float xx = lookX->text().toDouble(&ok_x), yy = lookY->text().toDouble(&ok_y), zz = lookZ->text().toDouble(&ok_z); - if( ok_x ) look_at.x = xx; - else lookX->setText(QString("%1").arg((double)look_at.x,0,'g',4)); - if( ok_y ) look_at.y = yy; - else lookY->setText(QString("%1").arg((double)look_at.y,0,'g',4)); - if( ok_z ) look_at.z = zz; - else lookZ->setText(QString("%1").arg((double)look_at.z,0,'g',4)); - if( ok_x || ok_y || ok_z ) { + if (ok_x) { + look_at.x = xx; + } + else { + lookX->setText(QString("%1").arg((double)look_at.x,0,'g',4)); + } + if (ok_y) { + look_at.y = yy; + } + else { + lookY->setText(QString("%1").arg((double)look_at.y,0,'g',4)); + } + if (ok_z) { + look_at.z = zz; + } + else { + lookZ->setText(QString("%1").arg((double)look_at.z,0,'g',4)); + } + if (ok_x || ok_y || ok_z) { // camera pointing vector EGS_Vector v0 = look_at-camera; @@ -664,14 +727,12 @@ void GeometryViewControl::loadTracksDialog() { #ifdef VIEW_DEBUG egsWarning("In loadTracksDialog()\n"); #endif - filename_tracks = QFileDialog::getOpenFileName( - QString::null,QString::null,0,0, + filename_tracks = QFileDialog::getOpenFileName(this, "Select geometry definition file"); - if ( !filename_tracks ) return; - if (strcmp(filename_tracks.latin1(), "")) { - vis->loadTracksData(filename_tracks.latin1()); - renderImage(); + if (filename_tracks.isEmpty()) { + return; } + gview->loadTracks(filename_tracks); } void GeometryViewControl::setProjectionSize() { @@ -684,110 +745,23 @@ void GeometryViewControl::viewAllMaterials() { #endif } -void GeometryViewControl::init() { -#ifdef VIEW_DEBUG - egsWarning("In init()\n"); -#endif - g = 0; - theta = 0; c_theta = cos(theta); s_theta = sin(theta); - phi = 0; c_phi = cos(phi); s_phi = sin(phi); - a_light = 0.25; - int ilight = (int) (a_light*ambientLight->maxValue()); - ambientLight->setValue(ilight); - distance = 25; - //dCourse->setValue(0); -// dFine->setValue(25); - dfine = 250; - projection_scale = 1; - look_at = EGS_Vector(); setLookAtLineEdit(); - projection_x = 15; projection_y = 15; - setProjectionLineEdit(); - p_light = EGS_Vector(0,0,distance); - setLightLineEdit(); - camera = p_light; - screen_xo = EGS_Vector(); - screen_v1 = EGS_Vector(1,0,0); - screen_v2 = EGS_Vector(0,1,0); - - // various state variables - regionsDisplayed=false; - showAxes = this->showAxesCheckbox->isChecked(); - showAxesLabels = this->showAxesLabelsCheckbox->isChecked(); - showRegions = this->showRegionsCheckbox->isChecked(); - showTracks = this->showTracksCheckbox->isChecked(); - showPhotonTracks = this->showPhotonsCheckbox->isChecked(); - showElectronTracks = this->showElectronsCheckbox->isChecked(); - showPositronTracks = this->showPositronsCheckbox->isChecked(); - showOtherTracks = this->showOthersCheckbox->isChecked(); - - // camera orientation vectors (same as the screen vectors) - camera_v1 = screen_v1; - camera_v2 = screen_v2; - - // camera home position - camera_home = camera; - camera_home_v1 = camera_v1; - camera_home_v2 = camera_v2; - dfine_home = dfine; - - m_colors = 0; nmed = 0; - - vis = new EGS_GeometryVisualizer; - - //gview = new ImageWindow(this,"gview"); - gview = new ImageWindow(this,"gview",Qt::WType_TopLevel); - nx_last = 512; ny_last = 512; - gview->resize(nx_last,ny_last); - image = new EGS_Vector [nx_last*ny_last]; - - //connect(gview,SIGNAL(changedSize(int,int)),this, SLOT(changeImageSize(int,int))); - connect(gview,SIGNAL(needRepaint(bool)),this, SLOT(doRepaint(bool))); - - // connect signals and slots for mouse navigation - connect(gview, SIGNAL(startTransformation()), this, SLOT(startTransformation())); - connect(gview, SIGNAL(endTransformation()), this, SLOT(endTransformation())); - connect(gview, SIGNAL(cameraRotation(int, int)), this, SLOT(cameraRotate(int, int))); - connect(gview, SIGNAL(cameraZooming(int)), this, SLOT(cameraZoom(int))); - connect(gview, SIGNAL(cameraHoming()), this, SLOT(cameraHome())); - connect(gview, SIGNAL(cameraHomeDefining()), this, SLOT(cameraHomeDefine())); - connect(gview, SIGNAL(cameraTranslating(int, int)), this, SLOT(cameraTranslate(int, int))); - connect(gview, SIGNAL(cameraRolling(int)), this, SLOT(cameraRoll(int))); - connect(gview, SIGNAL(putCameraOnAxis(char)), this, SLOT(cameraOnAxis(char))); - connect(gview, SIGNAL(regionPicking(int, int)), this, SLOT(regionPick(int, int))); - connect(gview, SIGNAL(leftMouseClick(int,int)), this, SLOT(reportViewSettings(int,int))); - connect(gview, SIGNAL(renderAndDebug()), this, SLOT(renderAndDebugImage())); - - in_transformation = false; rendering = false; - - render_time = 0; - - save_image = new SaveImage(this,"save image"); - - cplanes = new ClippingPlanesWidget; - setExtension(cplanes); - connect(cplanes,SIGNAL(clippingPlanesChanged()), - this,SLOT(setClippingPlanes())); - - // set the widget to show near the left-upper corner of the screen - move(QPoint(25,25)); - -} - void GeometryViewControl::reportViewSettings(int x,int y) { // convert mouse coordinates to screen coordinate int w=gview->width(); int h=gview->height(); EGS_Float xscreen, yscreen; - xscreen = (x-w/2)*projection_x/w; + xscreen = (x-w/2)*projection_x/w; yscreen = -(y-h/2)*projection_y/h; EGS_Vector xp(screen_xo + screen_v2*yscreen + screen_v1*xscreen); egsWarning("In reportViewSettings(%d,%d): xp=(%g,%g,%g)\n",x,y,xp.x,xp.y,xp.z); - EGS_Vector u(xp-camera); u.normalize(); + EGS_Vector u(xp-camera); + u.normalize(); egsWarning(" camera=(%15.10f,%15.10f,%15.10f), u=(%14.10f,%14.10f,%14.10f)\n",camera.x,camera.y,camera.z,u.x,u.y,u.z); } void GeometryViewControl::quitApplication() { - delete gview; close(); + delete gview; + close(); } void GeometryViewControl::setProjectionLineEdit() { @@ -811,26 +785,27 @@ void GeometryViewControl::updateLookAtLineEdit() { lookZ->repaint(); } -void GeometryViewControl::setMaterialColor(int j) { - EGS_Float r = ((EGS_Float) qRed(m_colors[j]))/255.; - EGS_Float g = ((EGS_Float) qGreen(m_colors[j]))/255.; - EGS_Float b = ((EGS_Float) qBlue(m_colors[j]))/255.; - EGS_Float alpha = ((EGS_Float) qAlpha(m_colors[j]))/255.; - vis->setMaterialColor(j,EGS_Vector(r,g,b),alpha); +void GeometryViewControl::setMaterialColor(int /*j*/) { +// EGS_Float r = ((EGS_Float) qRed(m_colors[j]))/255.; +// EGS_Float g = ((EGS_Float) qGreen(m_colors[j]))/255.; +// EGS_Float b = ((EGS_Float) qBlue(m_colors[j]))/255.; +// EGS_Float alpha = ((EGS_Float) qAlpha(m_colors[j]))/255.; +// vis->setMaterialColor(j,EGS_Vector(r,g,b),alpha); } -int GeometryViewControl::setGeometry ( - EGS_BaseGeometry *geom, - const std::vector &ucolors, - EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, EGS_Float ymax, - EGS_Float zmin, EGS_Float zmax, int justReloading ) -{ - if( !geom ) { egsWarning("setGeometry(): got null geometry\n"); return 1; } +int GeometryViewControl::setGeometry( + EGS_BaseGeometry *geom, + const std::vector &ucolors, + EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, EGS_Float ymax, + EGS_Float zmin, EGS_Float zmax, int justReloading) { + if (!geom) { + egsWarning("setGeometry(): got null geometry\n"); + return 1; + } g = geom; - // load the tracks data - if (strcmp(filename_tracks.latin1(), "")) { - vis->loadTracksData(filename_tracks.latin1()); + if (!filename_tracks.isEmpty()) { + gview->loadTracks(filename_tracks); } #ifdef VIEW_DEBUG @@ -845,12 +820,14 @@ int GeometryViewControl::setGeometry ( if (justReloading && m_colors) { for (int i=0; itext(i); + saveName[i] = materialCB->itemText(i); } } // delete m_colors - if( m_colors && nmed > 0 ) delete [] m_colors; + if (m_colors && nmed > 0) { + delete [] m_colors; + } #ifdef VIEW_DEBUG egsWarning("In setGeometry(), geometry name is %s\n",g->getName().c_str()); @@ -858,9 +835,9 @@ int GeometryViewControl::setGeometry ( // get number of media from geometry nmed = g->nMedia(); - if( nmed < 1 ) { + if (nmed < 1) { QMessageBox::critical(this,"Geometry error", - "The geometry defines no media",QMessageBox::Ok,0,0); + "The geometry defines no media",QMessageBox::Ok,0,0); return 1; } @@ -868,20 +845,28 @@ int GeometryViewControl::setGeometry ( materialCB->clear(); m_colors = new QRgb [nmed]; for (int j=0; jinsertItem(g->getMediumName(j),j); + materialCB->insertItem(j, g->getMediumName(j)); } int nstandard = sizeof(standard_red)/sizeof(unsigned char); int js = 0; - {for(int j=0; jgetMediumName(j); unsigned int i; - for(i=0; i= nstandard ) js = 0; + { + for (int j=0; jgetMediumName(j); + unsigned int i; + for (i=0; i= nstandard) { + js = 0; + } + } } - }} + } /* if( nmed <= nstandard ) { @@ -897,72 +882,93 @@ int GeometryViewControl::setGeometry ( */ // copy user's saved setting (for media names that were defined before the reload) - materialCB->setCurrentItem(0); + materialCB->setCurrentIndex(0); if (justReloading) { for (int j=0; jgetMediumName(j); for (int k=0; ktext(j) == saveName[k]) { + if (materialCB->itemText(j) == saveName[k]) { m_colors[j] = saveColors[k]; } } - if (materialCB->text(j) == saveCurrent) { - materialCB->setCurrentItem(j); + if (materialCB->itemText(j) == saveCurrent) { + materialCB->setCurrentIndex(j); } } } // add swatches in the combo box QPixmap pixmap(10,10); - {for (int j=0; jchangeItem(pixmap, materialCB->text(j), j); - }} + { + for (int j=0; jsetItemIcon(j,pixmap); + } + } // clean up saved settings delete [] saveColors; delete [] saveName; //showColor->setPaletteBackgroundColor(QColor(m_colors[materialCB->currentItem()])); - {for(int j=0; jisWhere(xo); // egsInformation("for (0,0,0) ireg=%d\n",ireg); - if( ireg >= 0 ) { found = true; progress.setProgress(100); } + if (ireg >= 0) { + found = true; + progress.setValue(100); + } else { - progress.setTotalSteps(130); + progress.setMaximum(130); // look for an inside point. - for(int k=0; k<100; k++) { - progress.setProgress(k); + for (int k=0; k<100; k++) { + progress.setValue(k); qApp->processEvents(); - if ( progress.wasCancelled() ) return 2; + if (progress.wasCanceled()) { + return 2; + } xo.z = zmin + dz*(k+0.5); - for(int i=0; i<100; i++) { + for (int i=0; i<100; i++) { xo.x = xmin + dx*(i+0.5); - for(int j=0; j<100; j++) { + for (int j=0; j<100; j++) { xo.y = ymin + dy*(j+0.5); ireg = g->isWhere(xo); - if( ireg >= 0 ) { found = true; break; } + if (ireg >= 0) { + found = true; + break; + } + } + if (found) { + break; } - if( found ) break; } - if( found ) break; + if (found) { + break; + } } - if( !found ) { - progress.setProgress(132); + if (!found) { + progress.setValue(132); qApp->processEvents(); QMessageBox::critical(this,"Geometry error", - "Failed to find a point that is inside the geometry", - QMessageBox::Ok,0,0); + "Failed to find a point that is inside the geometry", + QMessageBox::Ok,0,0); return 3; } - progress.setProgress(100); + progress.setValue(100); qApp->processEvents(); - if ( progress.wasCancelled() ) return 2; + if (progress.wasCanceled()) { + return 2; + } #ifdef VIEW_DEBUG egsWarning("found xo = (%g,%g,%g)\n",xo.x,xo.y,xo.z); #endif @@ -970,62 +976,95 @@ int GeometryViewControl::setGeometry ( EGS_Vector pmin(1e10,1e10,1e10), pmax(-1e10,-1e10,-1e10); //egsWarning("xo = (%g,%g,%g)\n",xo.x,xo.y,xo.z); - for(int isize=0; isize<6; isize++) { - progress.setProgress(100+5*isize); + for (int isize=0; isize<6; isize++) { + progress.setValue(100+5*isize); qApp->processEvents(); - if ( progress.wasCancelled() ) return 2; + if (progress.wasCanceled()) { + return 2; + } //egsWarning("================ side %d\n",isize); int max_step = g->getMaxStep(); - for(int i=0; i<100; i++) { - for(int j=0; j<100; j++) { + for (int i=0; i<100; i++) { + for (int j=0; j<100; j++) { EGS_Vector u; - if( isize == 0 ) + if (isize == 0) { u = EGS_Vector(xmin+dx*i,ymin+dy*j,zmin); - else if( isize == 1 ) + } + else if (isize == 1) { u = EGS_Vector(xmin+dx*i,ymin+dy*j,zmax); - else if( isize == 2 ) + } + else if (isize == 2) { u = EGS_Vector(xmin,ymin+dy*j,zmin+dz*i); - else if( isize == 3 ) + } + else if (isize == 3) { u = EGS_Vector(xmax,ymin+dy*j,zmin+dz*i); - else if( isize == 4 ) + } + else if (isize == 4) { u = EGS_Vector(xmin+dx*i,ymin,zmin+dz*j); - else + } + else { u = EGS_Vector(xmin+dx*i,ymax,zmin+dz*j); + } u -= xo; - u.normalize(); EGS_Vector x(xo); int ir = ireg; + u.normalize(); + EGS_Vector x(xo); + int ir = ireg; int nstep = 0; do { EGS_Float t = 1e30; int inew = g->howfar(ir,x,u,t); - if( inew == ir ) break; - if( ++nstep > max_step ) { - if( nstep == max_step+1 ) { + if (inew == ir) { + break; + } + if (++nstep > max_step) { + if (nstep == max_step+1) { egsWarning("\nMore than %d steps through geometry?\n",max_step); egsWarning("u = (%g,%g,%g)\n",u.x,u.y,u.z); } egsWarning("ir=%d inew=%d x=(%g,%g,%g) t=%g\n",ir,inew,x.x,x.y,x.z,t); - if( nstep > max_step + 50 ) { + if (nstep > max_step + 50) { egsWarning("\nToo many steps, ignoring ray\n"); - x = xo; break; + x = xo; + break; } } - x += u*t; ir = inew; - } while ( ir >= 0 ); + x += u*t; + ir = inew; + } + while (ir >= 0); //egsWarning("u = (%g,%g,%g) xf = (%g,%g,%g)\n",u.x,u.y,u.z, // x.x,x.y,x.z); - if( x.x < pmin.x ) pmin.x = x.x; - if( x.x > pmax.x ) pmax.x = x.x; - if( x.y < pmin.y ) pmin.y = x.y; - if( x.y > pmax.y ) pmax.y = x.y; - if( x.z < pmin.z ) pmin.z = x.z; - if( x.z > pmax.z ) pmax.z = x.z; + if (x.x < pmin.x) { + pmin.x = x.x; + } + if (x.x > pmax.x) { + pmax.x = x.x; + } + if (x.y < pmin.y) { + pmin.y = x.y; + } + if (x.y > pmax.y) { + pmax.y = x.y; + } + if (x.z < pmin.z) { + pmin.z = x.z; + } + if (x.z > pmax.z) { + pmax.z = x.z; + } } } } center = (pmin + pmax)*0.5; - if( fabs(center.x) < 0.001 ) center.x = 0; - if( fabs(center.y) < 0.001 ) center.y = 0; - if( fabs(center.z) < 0.001 ) center.z = 0; + if (fabs(center.x) < 0.001) { + center.x = 0; + } + if (fabs(center.y) < 0.001) { + center.y = 0; + } + if (fabs(center.z) < 0.001) { + center.z = 0; + } #ifdef VIEW_DEBUG egsWarning(" center: (%g,%g,%g)\n",center.x,center.y,center.z); egsWarning(" xmin: (%g,%g,%g)\n",pmin.x,pmin.y,pmin.z); @@ -1035,8 +1074,12 @@ int GeometryViewControl::setGeometry ( EGS_Float ysize = (pmax.y - pmin.y)/2; EGS_Float zsize = (pmax.z - pmin.z)/2; size = xsize; - if( ysize > size ) size = ysize; - if( zsize > size ) size = zsize; + if (ysize > size) { + size = ysize; + } + if (zsize > size) { + size = zsize; + } axesmax = pmax + EGS_Vector(size, size, size)*0.3; if (!justReloading) { @@ -1044,24 +1087,27 @@ int GeometryViewControl::setGeometry ( look_at = center; look_at_home = look_at; setLookAtLineEdit(); - if( distance > 60000 ) { - egsWarning("too big: %g\n",size); distance = 9999; - projection_x = 100; projection_y = 100; + if (distance > 60000) { + egsWarning("too big: %g\n",size); + distance = 9999; + projection_x = 100; + projection_y = 100; } else { //projection_x = 7*size; projection_y = 7*size; - projection_x = 5*size; projection_y = 5*size; + projection_x = 5*size; + projection_y = 5*size; EGS_Float proj_max = 2*projection_x; #ifdef VIEW_DEBUG egsWarning(" projection: %d max. projection: %d\n",(int) projection_x, - (int) proj_max+1); + (int) proj_max+1); #endif int dfine_max = 1000;//dFine->maxValue(); //dFine->setMaxValue((int) proj_max+1); //dFine->setValue((int) projection_x); projection_scale = proj_max/dfine_max; //dFine->setValue((int) (projection_x/projection_scale)); - dfine = (int) (projection_x/projection_scale); + dfine = (int)(projection_x/projection_scale); } setProjectionLineEdit(); //p_light = look_at+EGS_Vector(s_theta*s_phi,s_theta*s_phi,c_theta)*distance; @@ -1083,14 +1129,63 @@ int GeometryViewControl::setGeometry ( dfine_home = dfine; } - renderImage(); + updateView(); return 0; } +void GeometryViewControl::updateView(bool transform) { + // transfer + RenderParameters &rp = gview->pars; + rp.axesmax = axesmax; + rp.camera = camera; + rp.camera_v1 = camera_v1; + rp.camera_v2 = camera_v2; + //r.clipping_planes + rp.draw_axes = showAxes; + rp.draw_axeslabels = showAxesLabels; + rp.draw_tracks = showTracks; + float a = 0.01 * a_light; + rp.global_ambient_light = EGS_Vector(a,a,a); + + rp.lights = vector(); + rp.lights.push_back(EGS_Light(p_light, EGS_Vector(1,1,1))); + + rp.material_colors = vector(); + for (int j=0; j(); + for (int j=0; jnumPlanes(); j++) { + EGS_Vector a; + EGS_Float d; + if (cplanes->getPlane(j,a,d)) { + rp.clipping_planes.push_back(EGS_ClippingPlane(a,d)); + } + } + + rp.projection_x = projection_x; + rp.projection_y = projection_y; + rp.screen_v1 = screen_v1; + rp.screen_v2 = screen_v2; + rp.screen_xo = screen_xo; + rp.show_electrons = showElectronTracks; + rp.show_other = showOtherTracks; + rp.show_photons = showPhotonTracks; + rp.show_positrons = showPositronTracks; + rp.size = size; + + gview->render(g, transform); +} + void GeometryViewControl::updateColorLabel(int med) { // showColor->setPaletteBackgroundColor(QColor(m_colors[med])); - transperancy->setValue( qAlpha(m_colors[med]) ); + transparency->setValue(qAlpha(m_colors[med])); } void GeometryViewControl::changeColor() { @@ -1098,313 +1193,48 @@ void GeometryViewControl::changeColor() { egsWarning("In changeColor()\n"); egsWarning(" widget size = %d %d\n",width(),height()); #endif - int med = materialCB->currentItem(); + int med = materialCB->currentIndex(); bool ok; QRgb newc = QColorDialog::getRgba(m_colors[med],&ok,this); - if( ok ) { + if (ok) { m_colors[med] = newc; // showColor->setPaletteBackgroundColor(QColor(newc)); QPixmap pixmap(10,10); pixmap.fill(m_colors[med]); - materialCB->changeItem(pixmap, materialCB->text(med), med); - transperancy->setValue( qAlpha(newc) ); + materialCB->setItemIcon(med, pixmap); + transparency->setValue(qAlpha(newc)); setMaterialColor(med); - renderImage(); + updateView(); } } -void GeometryViewControl::doRepaint(bool resizing) { -#ifdef VIEW_DEBUG - egsWarning("In doRepaint(%d)\n",resizing); -#endif - //in_transformation = resizing; - //renderImage(); - if( gview->width() != nx_last || gview->height() != ny_last ) { - in_transformation = resizing; renderImage(); - } - else { - QPainter p(gview); - for(int j=0; jwidth(), - gview->height()); -#endif - if( !g ) return; - EGS_Timer *t = 0; - if( !in_transformation ) t = new EGS_Timer; - vis->setProjection(camera,screen_xo,screen_v1,screen_v2,projection_x, - projection_y); - vis->setLight(0,p_light,EGS_Vector(1,1,1)); - EGS_Float a = 0.01*a_light; - vis->setGlobalAmbientLight(EGS_Vector(a,a,a)); - int nx = gview->width(), ny = gview->height(); - int nxr=nx, nyr=ny; - bool full_image = true; - if( in_transformation ) { - if( render_time > 0 ) { - EGS_Float scale = 16*render_time; - if( scale > 1 ) { - scale = 1./sqrt(scale); - int nnx = (int) (scale*nx), nny = (int) (scale*ny); - if( nnx < 1 ) nnx = 1; if( nny < 1 ) nny = 1; - nxr = nx/nnx; if( nxr*nnx != nx ) nxr++; - nyr = ny/nny; if( nyr*nny != ny ) nyr++; - nnx = nx/nxr; nny = ny/nyr; - if( nnx*nxr < nx ) nnx++; - if( nny*nyr < ny ) nny++; -#ifdef VIEW_DEBUG - egsWarning(" nx=%d ny=%d nnx=%d nny=%d nxr=%d nyr=%d\n", - nx,ny,nnx,nny,nxr,nyr); -#endif - nx = nnx; ny = nny; - if( nxr > 1 || nyr > 1 ) full_image = false; - } - } - else { - nxr = 4; nyr = 4; - int nnx = nx/nxr, nny = ny/nyr; - if( nnx*nxr < nx ) nx = nnx+1; else nx = nnx; - if( nny*nyr < ny ) ny = nny+1; else ny = nny; - full_image = false; - } - } - if( full_image && !t ) t = new EGS_Timer; -#ifdef VIEW_DEBUG - egsWarning(" rendering %dx%d image\n",nx,ny); -#endif - if( nx != nx_last || ny != ny_last ) { - delete image; image = new EGS_Vector [nx*ny]; - nx_last = nx; ny_last = ny; - } - - // "render" coordinate axes - if (showAxes) drawAxes(nx,ny); - - // render the particle tracks - if (showTracks) { - vis->setParticleVisibility(1, showPhotonTracks); - vis->setParticleVisibility(2, showElectronTracks); - vis->setParticleVisibility(3, showPositronTracks); - vis->setParticleVisibility(4, showOtherTracks); - vis->renderTracks(g, nx, ny, image); - } - - // render the image - if( !vis->renderImage(g,nx,ny,image) ) - egsWarning("Error while rendering image\n"); - - // paint the image on screen - QPainter p(gview); - for(int j=0; jisShown() ) { - /* - //egsWarning("shown: %d\n",isShown()); - //QRect rect = frameGeometry(); - QPoint point = mapToGlobal(QPoint(0,0)); - int gview_x = point.x(); - //int gview_y = point.y() + rect.bottom() - rect.top(); - int gview_y = point.y() + height(); - gview->show(); - gview->move(gview_x,gview_y); - point = gview->pos(); - egsWarning("position after show and move: %d %d\n",point.x(),point.y()); - */ - gview->show(); - } - if( full_image ) { - render_time = t->time(); -#ifdef VIEW_DEBUG - egsWarning(" time to render the image: %g\n",render_time); -#endif - delete t; - } -} - -void GeometryViewControl::drawAxes(int nx, int ny) { - - #ifdef VIEW_DEBUG - egsWarning(" drawing axes\n"); - #endif - - // render object coordinate axes - EGS_Vector v2_screen = camera_v2; - EGS_Vector v1_screen = camera_v1; - EGS_Float sx = projection_x; - EGS_Float sy = projection_y; - EGS_Float dx = sx/nx; - EGS_Float dy = sx/ny; - EGS_Vector v0 = (screen_xo-camera); - EGS_Float r = v0.length(); - EGS_Float taxis=0; - v0.normalize(); - EGS_Vector vp; - - // origin - vp = EGS_Vector(0,0,0) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axes[0].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axes[0].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - - // x axis - vp = EGS_Vector(axesmax.x,0,0) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axes[1].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axes[1].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - vp = EGS_Vector(axesmax.x+0.1*size, 0, 0) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axeslabels[1].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axeslabels[1].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - - // y axis - vp = EGS_Vector(0,axesmax.y,0) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axes[2].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axes[2].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - vp = EGS_Vector(0, axesmax.y+0.1*size, 0) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axeslabels[2].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axeslabels[2].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - - // z axis - vp = EGS_Vector(0,0,axesmax.z) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axes[3].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axes[3].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - vp = EGS_Vector(0, 0, axesmax.z+0.1*size) - camera; - vp.normalize(); - vp = vp*(r/(v0*vp)); - axeslabels[3].x = ((vp*v1_screen+sx/2.0)/dx-0.5); - axeslabels[3].y = ((vp*v2_screen+sy/2.0)/dy-0.5); - - // flag axis pixels with the (negative) distance to the axis, in z component (blue) - int i0 = (int) axes[0].x; - int j0 = (int) axes[0].y; - EGS_Float deltax, deltay; - // loop over axes - for (int k=1; k<=3; k++) { - int i1 = (int) axes[k].x; - int j1 = (int) axes[k].y; - int n = abs(i1-i0); - if (abs(j1-j0)>n) n = abs(j1-j0); - // more than one axis pixel: loop over axis pixels - if (n>0) { - deltax = (i1-i0)/(float)n; - deltay = (j1-j0)/(float)n; - for (int t=0; t<=n; t++) { - i1 = (int) (i0+t*deltax); - j1 = (int) (j0+t*deltay); - if (k==1) taxis = EGS_Vector(EGS_Vector(t*axesmax.x/n,0,0) - camera).length(); - if (k==2) taxis = EGS_Vector(EGS_Vector(0,t*axesmax.y/n,0) - camera).length(); - if (k==3) taxis = EGS_Vector(EGS_Vector(0,0,t*axesmax.z/n) - camera).length(); - if (i1>=0 && i1=0 && j1=0 && i1=0 && j1exec(); #ifdef VIEW_DEBUG egsWarning("GeometryViewControl::saveImage(): got %d\n",res); #endif - if( !res ) return; + if (!res) { + return; + } int nx, ny; save_image->getImageSize(&nx,&ny); QString format = save_image->getImageFormat(); QString fname = save_image->getImageFileName(); #ifdef VIEW_DEBUG egsWarning("\nAbout to save %dx%d image into file %s in format %s\n\n", - nx,ny,fname.latin1(),format.latin1()); + nx,ny,fname.toUtf8().constData(),format.toUtf8().constData()); #endif - EGS_Vector *cimage = image; bool delete_it = false; - if( nx != nx_last || ny != ny_last ) { - delete_it = true; cimage = new EGS_Vector [nx*ny]; - vis->renderImage(g,nx,ny,cimage); - } - QImage im(nx,ny,32); int rgb = 0xff << 24; - for(int j=0; jsaveView(g,nx,ny,fname,format); } void GeometryViewControl::showHideOptions() { #ifdef VIEW_DEBUG egsWarning("In showHideOptions(): shown = %d\n", - cplanes->isShown()); + cplanes->isVisible()); #endif - showExtension(moreButton->isOn()); -// if( !cplanes->isShown() ) { + showExtension(moreButton->isChecked()); +// if( !cplanes->isVisible() ) { // showExtension(true); //moreButton->setText("Hide"); // } // else { @@ -1416,47 +1246,45 @@ void GeometryViewControl::setClippingPlanes() { #ifdef VIEW_DEBUG egsWarning("In GeometryViewControl::setClippingPlanes():\n"); #endif - vis->clearClippingPlanes(); - for(int j=0; jnumPlanes(); j++) { - EGS_Vector a; EGS_Float d; - if( cplanes->getPlane(j,a,d) ) { -#ifdef VIEW_DEBUG - egsWarning(" got plane (%g,%g,%g) %g\n",a.x,a.y,a.z,d); -#endif - vis->addClippingPlane(a,d); - } - } - renderImage(); -} - -void GeometryViewControl::renderAndDebugImage() { - egsWarning("In renderAndDebugImage()\n"); - vis->renderImage(g,gview->width(),gview->height(),0); +// vis->clearClippingPlanes(); +// for(int j=0; jnumPlanes(); j++) { +// EGS_Vector a; EGS_Float d; +// if( cplanes->getPlane(j,a,d) ) { +//#ifdef VIEW_DEBUG +// egsWarning(" got plane (%g,%g,%g) %g\n",a.x,a.y,a.z,d); +//#endif +//// vis->addClippingPlane(a,d); +// } +// } + updateView(); } - -void GeometryViewControl::showPhotonsCheckbox_toggled( bool toggle ) -{ +void GeometryViewControl::showPhotonsCheckbox_toggled(bool toggle) { showPhotonTracks = toggle; - renderImage(); + updateView(); } -void GeometryViewControl::showElectronsCheckbox_toggled( bool toggle ) -{ +void GeometryViewControl::showElectronsCheckbox_toggled(bool toggle) { showElectronTracks = toggle; - renderImage(); + updateView(); } -void GeometryViewControl::showPositronsCheckbox_toggled( bool toggle ) -{ +void GeometryViewControl::showPositronsCheckbox_toggled(bool toggle) { showPositronTracks = toggle; - renderImage(); + updateView(); } -void GeometryViewControl::showOthersCheckbox_toggled( bool toggle ) -{ +void GeometryViewControl::showOthersCheckbox_toggled(bool toggle) { showOtherTracks = toggle; - renderImage(); + updateView(); +} + +void GeometryViewControl::startTransformation() { + gview->startTransformation(); +} + +void GeometryViewControl::endTransformation() { + gview->endTransformation(); } diff --git a/HEN_HOUSE/egs++/view/viewcontrol.h b/HEN_HOUSE/egs++/view/viewcontrol.h new file mode 100644 index 000000000..e3b13aac1 --- /dev/null +++ b/HEN_HOUSE/egs++/view/viewcontrol.h @@ -0,0 +1,173 @@ +/* +############################################################################### +# +# EGSnrc egs++ geometry viewer view control extensions +# Copyright (C) 2015 National Research Council Canada +# +# This file is part of EGSnrc. +# +# EGSnrc is free software: you can redistribute it and/or modify it under +# the terms of the GNU Affero General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for +# more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with EGSnrc. If not, see . +# +############################################################################### +# +# Author: Iwan Kawrakow, 2005 +# +# Contributors: Frederic Tessier +# Ernesto Mainegra-Hing +# Manuel Stoeckl +# +############################################################################### +*/ + +#ifndef GEOMETRYVIEWCONTROL_H +#define GEOMETRYVIEWCONTROL_H + +#include "ui_viewcontrol.h" + +#include +#include "egs_user_color.h" +#include "egs_vector.h" + +#include + +class EGS_BaseGeometry; +class EGS_GeometryVisualizer; +class ImageWindow; +class QLabel; +class QImage; +class SaveImage; +class ClippingPlanesWidget; + + +class GeometryViewControl : public QDialog, public Ui::GeometryViewControl { + Q_OBJECT + +public: + + GeometryViewControl(QWidget *parent = 0, const char *name = 0); + virtual ~GeometryViewControl(); + + virtual void setFilename(QString str); + virtual void setTracksFilename(QString str); + virtual void setCameraPosition(); + virtual void setProjectionLineEdit(); + virtual void setLightLineEdit(); + virtual void setLookAtLineEdit(); + virtual void updateLookAtLineEdit(); + virtual void setMaterialColor(int j); + virtual int setGeometry(EGS_BaseGeometry *geom, const std::vector &ucolors, EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, EGS_Float ymax, EGS_Float zmin, EGS_Float zmax, int justReloading); + virtual void updateView(bool transform = false); + +public slots: + + virtual void reloadInput(); + virtual void checkboxAxes(bool toggle); + virtual void checkboxAxesLabels(bool toggle); + virtual void checkboxShowRegions(bool toggle); + virtual void checkboxShowTracks(bool toggle); + virtual void cameraHome(); + virtual void cameraOnAxis(char axis); + virtual void camera_x(); + virtual void camera_y(); + virtual void camera_z(); + virtual void camera_mx(); + virtual void camera_my(); + virtual void camera_mz(); + virtual void cameraHomeDefine(); + virtual void cameraTranslate(int dx, int dy); + virtual void cameraRotate(int dx, int dy); + virtual void cameraRoll(int dx); + virtual void cameraZoom(int dy); + virtual void thetaRotation(int Theta); + virtual void phiRotation(int Phi); + virtual void changeDfine(int newdfine); + virtual void changeAmbientLight(int alight); + virtual void changeTransparency(int t); + virtual void moveLightChanged(int toggle); + virtual void setLightPosition(); + virtual void setLookAt(); + virtual void loadTracksDialog(); + virtual void setProjectionSize(); + virtual void viewAllMaterials(); + virtual void reportViewSettings(int x, int y); + virtual void quitApplication(); + virtual void updateColorLabel(int med); + virtual void changeColor(); + virtual void saveImage(); + virtual void showHideOptions(); + virtual void setClippingPlanes(); + virtual void showPhotonsCheckbox_toggled(bool toggle); + virtual void showElectronsCheckbox_toggled(bool toggle); + virtual void showPositronsCheckbox_toggled(bool toggle); + virtual void showOthersCheckbox_toggled(bool toggle); + virtual void startTransformation(); + virtual void endTransformation(); + +private: + + ClippingPlanesWidget *cplanes; + ImageWindow *gview; + SaveImage *save_image; + + QString filename; + QString filename_tracks; + int nmed; + QRgb *m_colors; + int dfine_home; + int dfine; + EGS_Float a_light; + EGS_Float s_phi; + EGS_Float c_phi; + EGS_Float phi; + EGS_Float s_theta; + EGS_Float c_theta; + EGS_Float theta; + EGS_Float projection_scale; + EGS_Float projection_y; + EGS_Float projection_x; + EGS_Float distance; + EGS_Float size; + EGS_Vector axesmax; + EGS_Vector center; + EGS_Vector camera_home_v2; + EGS_Vector camera_home_v1; + EGS_Vector camera_home; + EGS_Vector camera_v2; + EGS_Vector camera_v1; + EGS_Vector camera; + EGS_Vector screen_v2; + EGS_Vector screen_v1; + EGS_Vector screen_xo; + EGS_Vector p_light; + EGS_Vector look_at_home; + EGS_Vector look_at; + EGS_BaseGeometry *g; + bool showAxes; + bool showAxesLabels; + bool showRegions; + bool showTracks; + bool showPhotonTracks; + bool showElectronTracks; + bool showPositronTracks; + bool showOtherTracks; + +protected slots: + + virtual void languageChange() { + retranslateUi(this); + } + +}; + +#endif // GEOMETRYVIEWCONTROL_H diff --git a/HEN_HOUSE/egs++/view/viewcontrol.ui b/HEN_HOUSE/egs++/view/viewcontrol.ui index 49954a5ae..74e6cb589 100644 --- a/HEN_HOUSE/egs++/view/viewcontrol.ui +++ b/HEN_HOUSE/egs++/view/viewcontrol.ui @@ -1,4 +1,5 @@ - + + ############################################################################### # # EGSnrc egs++ geometry viewer view control user interface @@ -28,1024 +29,1150 @@ # ############################################################################### -GeometryViewControl - - - GeometryViewControl - - - - 0 - 0 - 570 - 445 - - - - View Controls - - - - unnamed - - - - layout5 - - - - unnamed + GeometryViewControl + + + + 0 + 0 + 694 + 466 + + + + + 16777215 + 466 + + + + View Controls + + + + + + + + + + + 329 + 291 + + + + + 329 + 16777215 + + + + Light + + + + + + + + + 311 + 0 + + + + + 311 + 16777215 + + + + Move Light with viewer + + + true + + + + + + + false + + + + 315 + 16777215 + + + + Light position + + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 16 + 20 + + + + + + + + Apply + + + + + + + + + + + 301 + 0 + + + + + 301 + 16777215 + + + + Ambient light + + + + + + 100 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 10 + + + + + + + + + + Qt::Vertical + + + + 17 + 18 + + + + + + + + + + + + + + 331 + 16777215 + + + + Material colors + + + + + + + + + + + 120 + 0 + + + + + + + + + 0 + 0 + - - - groupBox18 + + Color... + + + + + + + + + Transparency + + + + + + 255 + + + 255 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 25 + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 28 + + + + + + + + + + + + + 321 + 16777215 + + + + View + + + + + + + + + + + + + + + 0 + 0 + - - Light + + x - - - unnamed - - - - moveLight - - - Move Light with viewer - - - true - - - - - lightPosGroup - - - false - - - Light position - - - - unnamed - - - - lightX - - - - - lightY - - - - - lightZ - - - - - spacer6 - - - Horizontal - - - Expanding - - - - 16 - 20 - - - - - - applyLight - - - Apply - - - - - - - groupBox17 - - - Ambient light - - - - unnamed - - - - ambientLight - - - 100 - - - Horizontal - - - Below - - - 10 - - - - - - - - - groupBox20 + + - - Material colors + + + + + + + 0 + 0 + - - - unnamed - - - - layout9 - - - - unnamed - - - - materialCB - - - - 120 - 0 - - - - - - pickColor - - - - 0 - 0 - 0 - 0 - - - - Color... - - - - - - - groupBox19 - - - Transparency - - - - unnamed - - - - transperancy - - - 255 - - - 255 - - - Horizontal - - - Below - - - 25 - - - - - - - - - - - layout139 - - - - unnamed - - - - groupBox15 + + y - - View + + - - - unnamed - - - - layout138 - - - - unnamed - - - - layout19 - - - - unnamed - - - - layout17 - - - - unnamed - - - - layout16 - - - - unnamed - - - - xButton - - - - 4 - 0 - 0 - 0 - - - - x - - - - - - - - yButton - - - - 4 - 0 - 0 - 0 - - - - y - - - - - - - - zButton - - - - 4 - 0 - 0 - 0 - - - - z - - - - - - - - - - layout15 - - - - unnamed - - - - mxButton - - - - 4 - 0 - 0 - 0 - - - - - x - - - - - - - - myButton - - - - 4 - 0 - 0 - 0 - - - - - y - - - - - - - - mzButton - - - - 4 - 0 - 0 - 0 - - - - - z - - - - - - - - - - - - layout18 - - - - unnamed - - - - homeButton - - - Home - - - - - setHomeButton - - - Set Home - - - - - - - - - groupBox9 - - - Look at - - - - unnamed - - - - lookX - - - - - lookY - - - - - lookZ - - - - - spacer4 - - - Horizontal - - - Expanding - - - - 16 - 21 - - - - - - applyLook - - - Apply - - - - - - - groupBox10 - - - Particle Tracks - - - - unnamed - - - - showPhotonsCheckbox - - - Photons - - - true - - - - - showPositronsCheckbox - - - Positrons - - - true - - - - - showTracksCheckbox - - - Show tracks - - - false - - - - - spacer5 - - - Horizontal - - - Expanding - - - - 20 - 21 - - - - - - showOthersCheckbox - - - Other - - - true - - - - - showElectronsCheckbox - - - Electrons - - - true - - - - - loadTracks - - - Load tracks - - - - - - - layout13 - - - - unnamed - - - - showAxesCheckbox - - - Show axes - - - true - - - - - showAxesLabelsCheckbox - - - Show axes labels - - - true - - - - - showRegionsCheckbox - - - Show regions - - - true - - - - - - - moreButton - - - Clipping planes... - - - true - - - - - - - - - spacer4_2 + + + + + + + 0 + 0 + - - Vertical + + z - - Expanding + + - - - 20 - 20 - + + + + + + + + + + + 0 + 0 + - - - - layout137 + + - x + + + + + + + + + + + 0 + 0 + + + + - y + + + - - - unnamed - - - - reloadButton - - - Reload - - - - - pushButton5 - - - Save image - - - - - pushButton6 - - - Close - - - + + + + + + + 0 + 0 + + + + - z + + + + + + + + + + + + + + + + Home + + + + + + + Set Home + + + + + + + + + + + Look at + + + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 16 + 21 + + + + + + + + Apply + + + + + + + + + + Particle Tracks + + + + + + Photons + + + true + + + + + + + Positrons + + + true + + + + + + + Show tracks + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 20 + 21 + + + + + + + + Other + + + true + - + + + + + Electrons + + + true + + + + + + + Load tracks + + + + + + + + + + + + Show axes + + + true + + + + + + + Show axes labels + + + true + + + + + + + Show regions + + + true + + + + + + + + + Clipping planes... + + + true + + + + + + - - - - - materialCB - activated(int) - GeometryViewControl - updateColorLabel(int) - - - transperancy - sliderPressed() - GeometryViewControl - startTransformation() - - - transperancy - sliderReleased() - GeometryViewControl - endTransformation() - - - transperancy - sliderMoved(int) - GeometryViewControl - changeTransperancy(int) - - - ambientLight - sliderPressed() - GeometryViewControl - startTransformation() - - - ambientLight - sliderReleased() - GeometryViewControl - endTransformation() - - - ambientLight - sliderMoved(int) - GeometryViewControl - changeAmbientLight(int) - - - moveLight - stateChanged(int) - GeometryViewControl - moveLightChanged(int) - - - applyLook - clicked() - GeometryViewControl - setLookAt() - - - loadTracks - clicked() - GeometryViewControl - loadTracksDialog() - - - pickColor - clicked() - GeometryViewControl - changeColor() - - - applyLight - clicked() - GeometryViewControl - setLightPosition() - - - pushButton6 - clicked() - GeometryViewControl - quitApplication() - - - pushButton5 - clicked() - GeometryViewControl - saveImage() - - - moreButton - clicked() - GeometryViewControl - showHideOptions() - - - homeButton - released() - GeometryViewControl - cameraHome() - - - setHomeButton - released() - GeometryViewControl - cameraHomeDefine() - - - xButton - released() - GeometryViewControl - camera_x() - - - yButton - released() - GeometryViewControl - camera_y() - - - zButton - released() - GeometryViewControl - camera_z() - - - mxButton - released() - GeometryViewControl - camera_mx() - - - myButton - released() - GeometryViewControl - camera_my() - - - mzButton - released() - GeometryViewControl - camera_mz() - - - showAxesCheckbox - toggled(bool) - GeometryViewControl - checkboxAxes(bool) - - - showAxesLabelsCheckbox - toggled(bool) - GeometryViewControl - checkboxAxesLabels(bool) - - - showRegionsCheckbox - toggled(bool) - GeometryViewControl - checkboxShowRegions(bool) - - - showTracksCheckbox - toggled(bool) - GeometryViewControl - checkboxShowTracks(bool) - - - reloadButton - clicked() - GeometryViewControl - reloadInput() - - - showPhotonsCheckbox - toggled(bool) - GeometryViewControl - showPhotonsCheckbox_toggled(bool) - - - showElectronsCheckbox - toggled(bool) - GeometryViewControl - showElectronsCheckbox_toggled(bool) - - - showPositronsCheckbox - toggled(bool) - GeometryViewControl - showPositronsCheckbox_toggled(bool) - - - showOthersCheckbox - toggled(bool) - GeometryViewControl - showOthersCheckbox_toggled(bool) - - - - egs_vector.h - egs_visualizer.h - image_window.h - viewcontrol.ui.h - egs_user_color.h - vector - - - class EGS_BaseGeometry; - class EGS_GeometryVisualizer; - class ImageWindow; - class QLabel; - class QImage; - class SaveImage; - class ClippingPlanesWidget; - - - QString filename; - QString filename_tracks; - ClippingPlanesWidget *cplanes; - SaveImage *save_image; - bool regionsDisplayed; - bool in_transformation; - EGS_Float render_time; - int ny_last; - int nx_last; - bool rendering; - EGS_Vector *image; - QLabel *gview_image; - ImageWindow *gview; - int nmed; - QRgb *m_colors; - int dfine_home; - int dfine; - EGS_Float a_light; - EGS_Float s_phi; - EGS_Float c_phi; - EGS_Float phi; - EGS_Float s_theta; - EGS_Float c_theta; - EGS_Float theta; - EGS_Float projection_scale; - EGS_Float projection_y; - EGS_Float projection_x; - EGS_Float distance; - EGS_Float size; - EGS_Vector axeslabels[4]; - EGS_Vector axes[4]; - EGS_Vector axesmax; - EGS_Vector center; - EGS_Vector camera_home_v2; - EGS_Vector camera_home_v1; - EGS_Vector camera_home; - EGS_Vector camera_v2; - EGS_Vector camera_v1; - EGS_Vector camera; - EGS_Vector screen_v2; - EGS_Vector screen_v1; - EGS_Vector screen_xo; - EGS_Vector p_light; - EGS_Vector look_at_home; - EGS_Vector look_at; - EGS_GeometryVisualizer *vis; - EGS_BaseGeometry *g; - bool showAxes; - bool showAxesLabels; - bool showRegions; - bool showTracks; - bool showPhotonTracks; - bool showElectronTracks; - bool showPositronTracks; - bool showOtherTracks; - - - reloadInput() - checkboxAxes( bool toggle ) - checkboxAxesLabels( bool toggle ) - checkboxShowRegions( bool toggle ) - checkboxShowTracks( bool toggle ) - regionPick( int x, int y ) - cameraHome() - cameraOnAxis( char axis ) - camera_x() - camera_y() - camera_z() - camera_mx() - camera_my() - camera_mz() - cameraHomeDefine() - cameraTranslate( int dx, int dy ) - cameraRotate( int dx, int dy ) - cameraRoll( int dx ) - cameraZoom( int dy ) - thetaRotation( int Theta ) - phiRotation( int Phi ) - startTransformation() - endTransformation() - changeDfine( int newdfine ) - changeAmbientLight( int alight ) - changeTransperancy( int t ) - moveLightChanged( int toggle ) - setLightPosition() - setLookAt() - loadTracksDialog() - setProjectionSize() - viewAllMaterials() - init() - reportViewSettings( int x, int y ) - quitApplication() - updateColorLabel( int med ) - changeColor() - doRepaint( bool resizing ) - renderImage() - drawAxes( int nx, int ny ) - saveImage() - showHideOptions() - setClippingPlanes() - renderAndDebugImage() - showPhotonsCheckbox_toggled( bool toggle ) - showElectronsCheckbox_toggled( bool toggle ) - showPositronsCheckbox_toggled( bool toggle ) - showOthersCheckbox_toggled( bool toggle ) - - - setFilename( QString str ) - setTracksFilename( QString str ) - setCameraPosition() - setProjectionLineEdit() - setLightLineEdit() - setLookAtLineEdit() - updateLookAtLineEdit() - setMaterialColor( int j ) - setGeometry( EGS_BaseGeometry * geom, const std::vector<EGS_UserColor> & ucolors, EGS_Float xmin, EGS_Float xmax, EGS_Float ymin, EGS_Float ymax, EGS_Float zmin, EGS_Float zmax, int justReloading ) - - - - + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 20 + + + + + + + + + + Reload + + + + + + + Save image + + + + + + + Close + + + + + + + + + + + + + + egs_vector.h + egs_user_color.h + vector + + + + + applyLook + clicked() + GeometryViewControl + setLookAt() + + + 20 + 20 + + + 20 + 20 + + + + + loadTracks + clicked() + GeometryViewControl + loadTracksDialog() + + + 20 + 20 + + + 20 + 20 + + + + + pushButton6 + clicked() + GeometryViewControl + quitApplication() + + + 20 + 20 + + + 20 + 20 + + + + + pushButton5 + clicked() + GeometryViewControl + saveImage() + + + 20 + 20 + + + 20 + 20 + + + + + moreButton + clicked() + GeometryViewControl + showHideOptions() + + + 20 + 20 + + + 20 + 20 + + + + + homeButton + released() + GeometryViewControl + cameraHome() + + + 20 + 20 + + + 20 + 20 + + + + + setHomeButton + released() + GeometryViewControl + cameraHomeDefine() + + + 20 + 20 + + + 20 + 20 + + + + + xButton + released() + GeometryViewControl + camera_x() + + + 20 + 20 + + + 20 + 20 + + + + + yButton + released() + GeometryViewControl + camera_y() + + + 20 + 20 + + + 20 + 20 + + + + + zButton + released() + GeometryViewControl + camera_z() + + + 20 + 20 + + + 20 + 20 + + + + + mxButton + released() + GeometryViewControl + camera_mx() + + + 20 + 20 + + + 20 + 20 + + + + + myButton + released() + GeometryViewControl + camera_my() + + + 20 + 20 + + + 20 + 20 + + + + + mzButton + released() + GeometryViewControl + camera_mz() + + + 20 + 20 + + + 20 + 20 + + + + + showAxesCheckbox + toggled(bool) + GeometryViewControl + checkboxAxes(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showAxesLabelsCheckbox + toggled(bool) + GeometryViewControl + checkboxAxesLabels(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showRegionsCheckbox + toggled(bool) + GeometryViewControl + checkboxShowRegions(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showTracksCheckbox + toggled(bool) + GeometryViewControl + checkboxShowTracks(bool) + + + 20 + 20 + + + 20 + 20 + + + + + reloadButton + clicked() + GeometryViewControl + reloadInput() + + + 20 + 20 + + + 20 + 20 + + + + + showPhotonsCheckbox + toggled(bool) + GeometryViewControl + showPhotonsCheckbox_toggled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showElectronsCheckbox + toggled(bool) + GeometryViewControl + showElectronsCheckbox_toggled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showPositronsCheckbox + toggled(bool) + GeometryViewControl + showPositronsCheckbox_toggled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + showOthersCheckbox + toggled(bool) + GeometryViewControl + showOthersCheckbox_toggled(bool) + + + 20 + 20 + + + 20 + 20 + + + + + transparancy + sliderReleased() + GeometryViewControl + endTransformation() + + + 20 + 20 + + + 20 + 20 + + + + + transparency + sliderPressed() + GeometryViewControl + startTransformation() + + + 20 + 20 + + + 20 + 20 + + + + + transparency + valueChanged(int) + GeometryViewControl + changeTransparency(int) + + + 20 + 20 + + + 20 + 20 + + + + + ambientLight + sliderPressed() + GeometryViewControl + startTransformation() + + + 20 + 20 + + + 20 + 20 + + + + + ambientLight + sliderReleased() + GeometryViewControl + endTransformation() + + + 20 + 20 + + + 20 + 20 + + + + + ambientLight + valueChanged(int) + GeometryViewControl + changeAmbientLight(int) + + + 20 + 20 + + + 20 + 20 + + + + + moveLight + stateChanged(int) + GeometryViewControl + moveLightChanged(int) + + + 20 + 20 + + + 20 + 20 + + + + + pickColor + clicked() + GeometryViewControl + changeColor() + + + 20 + 20 + + + 20 + 20 + + + + + applyLight + clicked() + GeometryViewControl + setLightPosition() + + + 20 + 20 + + + 20 + 20 + + + + + materialCB + activated(int) + GeometryViewControl + updateColorLabel(int) + + + 20 + 20 + + + 20 + 20 + + + + + diff --git a/HEN_HOUSE/gui/egs_gui/pegs_page.ui b/HEN_HOUSE/gui/egs_gui/pegs_page.ui index 4e2b911df..ff2d140e1 100644 --- a/HEN_HOUSE/gui/egs_gui/pegs_page.ui +++ b/HEN_HOUSE/gui/egs_gui/pegs_page.ui @@ -554,7 +554,6 @@ - qPixmapFromMimeSource diff --git a/HEN_HOUSE/gui/egs_gui/pegs_runoutput.ui b/HEN_HOUSE/gui/egs_gui/pegs_runoutput.ui index 746624015..99233cad0 100644 --- a/HEN_HOUSE/gui/egs_gui/pegs_runoutput.ui +++ b/HEN_HOUSE/gui/egs_gui/pegs_runoutput.ui @@ -74,7 +74,6 @@ - qPixmapFromMimeSource diff --git a/HEN_HOUSE/gui/egs_inprz/ui/executiondialog.ui b/HEN_HOUSE/gui/egs_inprz/ui/executiondialog.ui index e9075e6ac..1811e2e60 100644 --- a/HEN_HOUSE/gui/egs_inprz/ui/executiondialog.ui +++ b/HEN_HOUSE/gui/egs_inprz/ui/executiondialog.ui @@ -408,7 +408,6 @@ - qPixmapFromMimeSource diff --git a/HEN_HOUSE/gui/egs_inprz/ui/inputRZ.ui b/HEN_HOUSE/gui/egs_inprz/ui/inputRZ.ui index d23392e29..bc64753cf 100644 --- a/HEN_HOUSE/gui/egs_inprz/ui/inputRZ.ui +++ b/HEN_HOUSE/gui/egs_inprz/ui/inputRZ.ui @@ -11462,7 +11462,6 @@ - qPixmapFromMimeSource TitleEdit cavrzRadioButton diff --git a/HEN_HOUSE/omega/beamnrc/CMs/SYNCMLCE_cm.mortran b/HEN_HOUSE/omega/beamnrc/CMs/SYNCMLCE_cm.mortran index 35179f64c..13f49e9fd 100644 --- a/HEN_HOUSE/omega/beamnrc/CMs/SYNCMLCE_cm.mortran +++ b/HEN_HOUSE/omega/beamnrc/CMs/SYNCMLCE_cm.mortran @@ -461,14 +461,10 @@ "V>$GEO_SHIFT_1_(#) "V>============= "V>{p1} the value to compare with ustep -"V> if {p1}+1.0e-5 < ustep shift it, otherwise no shift +"V> if {p1}+1.0e-5 < ustep shift it by 1.0e-5, otherwise use USTEP ; REPLACE {$GEO_SHIFT_1_(#)} WITH { - ;IF({P1}~=0.00 ) [ - IF({P1}+1.0E-5< USTEP) [{P1}={P1}+1.0E-5;] - ] - ELSE [{P1}={P1}+1.0E-5;]; - + ;{P1}=MIN(USTEP,{P1}+1.0e-5); } ;IMPLICIT NONE; diff --git a/HEN_HOUSE/omega/beamnrc/beamnrc.mortran b/HEN_HOUSE/omega/beamnrc/beamnrc.mortran index cb827f54f..b7d840638 100644 --- a/HEN_HOUSE/omega/beamnrc/beamnrc.mortran +++ b/HEN_HOUSE/omega/beamnrc/beamnrc.mortran @@ -2853,9 +2853,9 @@ REPLACE {;COMIN/USER-CS-ENHANCEMENT/;} WITH {; REPLACE {;COMIN/USER-BCSE/;} WITH {; COMMON/BCSE/ BCSE_FACTOR_C,BCSE_POWER_N,BCSE_FACTOR,ENPOLD_ORGNL, is_bcse_medium($MXMED), - MED_BCSE,NBRSPL_ORGNL,USE_BCSE; + MED_BCSE,NBRSPL_ORGNL,nmed_enhance,USE_BCSE; $LOGICAL USE_BCSE,is_bcse_medium; - $INTEGER MED_BCSE,NBRSPL_ORGNL; + $INTEGER MED_BCSE,NBRSPL_ORGNL,nmed_enhance; $REAL BCSE_FACTOR_C,BCSE_POWER_N,BCSE_FACTOR,ENPOLD_ORGNL; }; @@ -7610,7 +7610,7 @@ IF(IBRSPL = 1 | IBRSPL=2)[ WRITE(IOUTLIST,101)$MAXBRSPLIT,NBRSPL; 101 FORMAT(//' ***WARNING***'/ ' NBRSPL > $MAXBRSPLIT '/ - ' NBRSPL reduced to ',I10,' from ',I10//); + ' NBRSPL reduced to max = ',I10,' from ',I10//); NBRSPL=$MAXBRSPLIT; ] IF($MXSTACK<4*NBRSPL)[ @@ -8250,7 +8250,7 @@ $IMPLICIT-NONE; "T>**************************** "T> ;INTEGER - I,I1,I2,I3,J,JJ, "T>DO loop indices + I,I1,I2,I3,J,JJ,kk, "T>DO loop indices I3MAX, "T>limit of number of media for listing IOUT, "T>output unit number IRL, "T>region number" @@ -8344,6 +8344,30 @@ ELSEIF(IBRSPL = 2)[ ] ] ] + +IF(USE_BCSE) [ + WRITE(IOUTLIST,:new2:) nmed_enhance; + :new2: FORMAT(/T20,'Brem. cross section enhancement WILL be used'/ + T20,' The following ',I2,' media will be enhanced:'); + DO i=1,$MXMED [ + IF( is_bcse_medium(i) ) [ + WRITE(IOUTLIST,'(T20,24a1)') (media(kk,i),kk=1,24); + ] + ] + IF( BCSE_POWER_N > 0 ) [ + WRITE(IOUTLIST,:new3:) BCSE_FACTOR_C,BCSE_POWER_N; + :new3: FORMAT(T20,' Enhancement factor will be 1 + C*E**N WITH C = ', + 1PE14.6,' N = ',0PF9.2); + ] + ELSE [ + WRITE(IOUTLIST,:new4:) BCSE_FACTOR_C; + :new4: FORMAT(T20,' Constant enhancement factor =',F12.2); + ] +]"end of using BCSE block" +ELSE [ WRITE(IOUTLIST,:new1:); + :new1: FORMAT(T20,'Brem. cross section enhancement WILL NOT be used'); +] + IF(IBRSPL=1)[ IF(IRRLTT >= 1)[WRITE(IOUTLIST,2282);] ELSE [WRITE(IOUTLIST,2283);] ] @@ -13500,7 +13524,7 @@ IF( error_flags(ival-1) = 0 & error_flags(ival) = 0 ) [ IF( cs_enhance(i) > 1 ) [ use_cs_enhance = .true.; EXIT; ] ] IF( use_cs_enhance ) [ - OUTPUT; (//'********** Cross section enhancement will be used', + OUTPUT; (//'********** Photon cross section enhancement will be used', ' in the following CMs: ******'); DO i=1,$MAX_CMs [ IF( cs_enhance(i) > 1 ) [ @@ -13513,7 +13537,7 @@ IF( error_flags(ival-1) = 0 & error_flags(ival) = 0 ) [ ] ] ] -OUTPUT; (//'************* Cross section enhancement will not be used'//); +OUTPUT; (//'************* Photon cross section enhancement will not be used'//); return; end; @@ -13616,7 +13640,7 @@ SUBROUTINE GET_BCSE_PARAMETERS; IMPLICIT NONE; -;COMIN/MEDIA,ELECIN,GetInput, +;COMIN/MEDIA,ELECIN,GetInput,IO_INFO, USER-BCSE,USER-SPLITTING,EGS-VARIANCE-REDUCTION,EGS-IO/; $REAL EIL, @@ -13626,7 +13650,7 @@ $REAL EIL, SIGE_I,SIGE_II,SIGP_I,SIGP_II,EDEDX,PDEDX; $LOGICAL is_ok; -$INTEGER I,k,MEDIUM,egs_add_medium,nmed_i,nmed_enhance,lnblnk1,nlen; +$INTEGER I,k,MEDIUM,egs_add_medium,nmed_i,lnblnk1,nlen; DO I=1,$MXMED [ is_bcse_medium(i) = .false.; ] diff --git a/HEN_HOUSE/omega/progs/gui/beamnrc/beamnrc_gui.tcl b/HEN_HOUSE/omega/progs/gui/beamnrc/beamnrc_gui.tcl index 79a3e77ab..25209638f 100755 --- a/HEN_HOUSE/omega/progs/gui/beamnrc/beamnrc_gui.tcl +++ b/HEN_HOUSE/omega/progs/gui/beamnrc/beamnrc_gui.tcl @@ -451,13 +451,13 @@ set rooty [expr ($height/2) - 300] wm geometry . +$rootx+$rooty font create myDefaultFont -family Helvetica -size 11 -weight bold -option add *font myDefaultFont +#option add *font myDefaultFont #define a main menubar -frame .mbar -relief raised -bd 1 -menubutton .mbar.file -text "File" -menu .mbar.file.menu -menu .mbar.file.menu +frame .mbar -relief raised -bd 1 +menubutton .mbar.file -text "File" -menu .mbar.file.menu -font myDefaultFont +menu .mbar.file.menu -font myDefaultFont .mbar.file.menu add command -label "Load a previous accelerator" \ -command "load_old_module" .mbar.file.menu add command -label "Specify a new accelerator" \ @@ -475,26 +475,26 @@ menu .mbar.file.menu .mbar.file.menu add separator .mbar.file.menu add command -label "Exit" -command "exit_prompt" -menubutton .mbar.preview -text "Preview" -menu .mbar.preview.menu -menu .mbar.preview.menu +menubutton .mbar.preview -text "Preview" -menu .mbar.preview.menu -font myDefaultFont +menu .mbar.preview.menu -font myDefaultFont .mbar.preview.menu add command -label "Preview accelerator" -command "draw_accel" .mbar.preview.menu add command -label "Change colour scheme"\ -command "change_color_scheme" -menubutton .mbar.run -text "Execute" -menu .mbar.run.menu -menu .mbar.run.menu +menubutton .mbar.run -text "Execute" -menu .mbar.run.menu -font myDefaultFont +menu .mbar.run.menu -font myDefaultFont .mbar.run.menu add command -label "Compile" -command "compile_accel" .mbar.run.menu add command -label "Run"\ -command "run" -menubutton .mbar.about -text "About" -menu .mbar.about.menu -menu .mbar.about.menu +menubutton .mbar.about -text "About" -menu .mbar.about.menu -font myDefaultFont +menu .mbar.about.menu -font myDefaultFont .mbar.about.menu add command -label "About BEAMnrc" -command "about_BEAM" .mbar.about.menu add command -label "About the BEAMnrc GUI" \ -command "about_BEAM_GUI" -menubutton .mbar.help -text "Help" -menu .mbar.help.menu -menu .mbar.help.menu +menubutton .mbar.help -text "Help" -menu .mbar.help.menu -font myDefaultFont +menu .mbar.help.menu -font myDefaultFont #.mbar.help.menu add command -label "BEAMnrc Help" .mbar.help.menu add command -label "GUI Help" \ -command {help_dialog .help "GUI Help" $GUI_help_text info 0 Close} diff --git a/HEN_HOUSE/omega/progs/gui/dosxyznrc/dosxyznrc_gui.tcl b/HEN_HOUSE/omega/progs/gui/dosxyznrc/dosxyznrc_gui.tcl index 4cf03f701..76c7d2d2a 100755 --- a/HEN_HOUSE/omega/progs/gui/dosxyznrc/dosxyznrc_gui.tcl +++ b/HEN_HOUSE/omega/progs/gui/dosxyznrc/dosxyznrc_gui.tcl @@ -417,12 +417,12 @@ wm geometry . +$rootx+$rooty #define a main menubar font create myDefaultFont -family Helvetica -size 11 -weight bold -option add *font myDefaultFont +#option add *font myDefaultFont frame .mbar -relief raised -bd 1 -menubutton .mbar.file -text "File" -menu .mbar.file.menu -menu .mbar.file.menu +menubutton .mbar.file -text "File" -menu .mbar.file.menu -font myDefaultFont +menu .mbar.file.menu -font myDefaultFont .mbar.file.menu add command -label "Start a new input file" \ -command "reset_parameters; edit_parameters" .mbar.file.menu add command -label "Load a previous input file" \ @@ -439,20 +439,20 @@ menu .mbar.file.menu .mbar.file.menu add separator .mbar.file.menu add command -label "Exit" -command "exit_prompt" -menubutton .mbar.about -text "About" -menu .mbar.about.menu -menu .mbar.about.menu +menubutton .mbar.about -text "About" -menu .mbar.about.menu -font myDefaultFont +menu .mbar.about.menu -font myDefaultFont .mbar.about.menu add command -label "About DOSXYZnrc" -command "about_XYZ" .mbar.about.menu add command -label "About the DOSXYZnrc GUI" \ -command "about_XYZ_GUI" -menubutton .mbar.run -text "Run" -menu .mbar.run.menu -menu .mbar.run.menu +menubutton .mbar.run -text "Run" -menu .mbar.run.menu -font myDefaultFont +menu .mbar.run.menu -font myDefaultFont .mbar.run.menu add command -label "Compile" -command "compile_accel" .mbar.run.menu add command -label "Run"\ -command "run" -menubutton .mbar.help -text "Help" -menu .mbar.help.menu -menu .mbar.help.menu +menubutton .mbar.help -text "Help" -menu .mbar.help.menu -font myDefaultFont +menu .mbar.help.menu -font myDefaultFont #.mbar.help.menu add command -label "DOSXYZnrc Help" .mbar.help.menu add command -label "GUI Help" \ -command {help_dialog .help "GUI Help" $GUI_help_text info 0 Close} diff --git a/HEN_HOUSE/scripts/configure b/HEN_HOUSE/scripts/configure index 6b04dc8ac..aaf9aba01 100755 --- a/HEN_HOUSE/scripts/configure +++ b/HEN_HOUSE/scripts/configure @@ -653,8 +653,6 @@ Please report this problem, including - Operating system (e.g., the output from 'Checking system type' above) - Compiler name and version - Compilation flags -in your e-mail. You should also attach the file 'configure.log' in the -HEN_HOUSE/log directory. EOF exit 1 @@ -2614,11 +2612,11 @@ egs_config="$HEN_HOUSE/specs/$egs_config" # move configuration log to log directory if $as_file $my_dir/configure.log && $as_directory $HEN_HOUSE/log; then - mv $my_dir/configure.log $HEN_HOUSE/log/ + mv $my_dir/configure.log $HEN_HOUSE/log/configure-$conf_name.log echo >&2 printf $format "EGSnrc system configuration log saved in:" >&2 echo >&2 - echo "$HEN_HOUSE/log/configure.log" >&2 + echo "$HEN_HOUSE/log/configure-$conf_name.log" >&2 fi cd $my_dir diff --git a/HEN_HOUSE/scripts/configure_c++ b/HEN_HOUSE/scripts/configure_c++ index f4ae6e406..b8b6b4be3 100755 --- a/HEN_HOUSE/scripts/configure_c++ +++ b/HEN_HOUSE/scripts/configure_c++ @@ -99,12 +99,12 @@ EOF exit 1 fi -my_machine=$( cat $egs_config | grep "my_machine =" | sed "s/my_machine = //g" ) -canonical_system=$( cat $egs_config | grep "canonical_system =" | sed "s/canonical_system = //g" ) -make_prog=$( cat $egs_config | grep "make_prog =" | sed "s/make_prog = //g" ) -hen_house=$( cat $egs_config | grep "HEN_HOUSE =" | sed "s/HEN_HOUSE = //g" ) -F77=$( cat $egs_config | grep "F77 =" | sed "s/F77 = //g" ) -dlopen_lib=$( cat $egs_config | grep "BEAMLIB_EXTRA_LIBS =" | sed 's/BEAMLIB_EXTRA_LIBS = //g' | sed 's/\$(IAEA_LIB)//g' ) +my_machine=$( cat $egs_config | grep "my_machine =" | sed "s/my_machine = *//g" ) +canonical_system=$( cat $egs_config | grep "canonical_system =" | sed "s/canonical_system = *//g" ) +make_prog=$( cat $egs_config | grep "make_prog =" | sed "s/make_prog = *//g" ) +hen_house=$( cat $egs_config | grep "HEN_HOUSE =" | sed "s/HEN_HOUSE = *//g" ) +F77=$( cat $egs_config | grep "F77 =" | sed "s/F77 = *//g" ) +dlopen_lib=$( cat $egs_config | grep "BEAMLIB_EXTRA_LIBS =" | sed 's/BEAMLIB_EXTRA_LIBS = *//g' | sed 's/\$(IAEA_LIB)//g' ) is_ok=yes if test "x$my_machine" = x; then @@ -255,7 +255,7 @@ printf $format "Determining Fortran libraries for $CXX linking ..." >&2 fortran_libs=$( $hen_house/scripts/get_f77_libs1 $F77 $CXX ) if test $? -eq 0; then echo "OK" >&2 - f_libs=$( echo $fortran_libs | sed "s/fortran_libs = //g" ) + f_libs=$( echo $fortran_libs | sed "s/fortran_libs = *//g" ) else echo "Failed" >&2 f_libs="" diff --git a/HEN_HOUSE/scripts/egs_style_standard b/HEN_HOUSE/scripts/egs_style_standard new file mode 100644 index 000000000..b19d0b4cf --- /dev/null +++ b/HEN_HOUSE/scripts/egs_style_standard @@ -0,0 +1,12 @@ +### usage: +### astyle --options=$HEN_HOUSE/scripts/egs_coding_standard "*.cpp" "*.h" + +--convert-tabs # convert all tabs to spaces +--indent=spaces=4 # indent is 4 spaces +--style=attach # attach opening bracket at end of line +--unpad-paren # remove extra space padding around parenthesis on the inside and outside +--pad-header # space padding between a header and the following parenthesis +--align-pointer=name # attach pointer or reference to variable name +--break-closing-brackets # breaks closing headers from their immediately preceding closing brackets +--add-brackets # add brackets to unbracketed one line conditional statements +--indent-preproc-block # indent preprocessor blocks diff --git a/HEN_HOUSE/scripts/egsnrc_cshrc_additions b/HEN_HOUSE/scripts/egsnrc_cshrc_additions index 0ea911872..b52d7da4b 100644 --- a/HEN_HOUSE/scripts/egsnrc_cshrc_additions +++ b/HEN_HOUSE/scripts/egsnrc_cshrc_additions @@ -53,7 +53,7 @@ endif # Set dynamic library path # -setenv LD_LIBRARY_PATH "${HEN_HOUSE}egs++/dso/$my_machine:$LD_LIBRARY_PATH" +setenv LD_LIBRARY_PATH "${HEN_HOUSE}egs++/dso/${my_machine}:$LD_LIBRARY_PATH" # Aliases # diff --git a/HEN_HOUSE/scripts/finalize_egs_foruser b/HEN_HOUSE/scripts/finalize_egs_foruser index 1612153bd..c74dcb3c2 100755 --- a/HEN_HOUSE/scripts/finalize_egs_foruser +++ b/HEN_HOUSE/scripts/finalize_egs_foruser @@ -66,7 +66,9 @@ help='?' timestamp='Aug 25 2015' # guess egs home location -if ! test "x$HEN_HOUSE" = x; then +if ! test "x$EGS_HOME" = x; then + test_egs_home=$EGS_HOME +elif ! test "x$HEN_HOUSE" = x; then test_egs_home=$(dirname $HEN_HOUSE)/egs_home else test_egs_home=$(cd $my_dir/../..; pwd)/egs_home @@ -124,12 +126,7 @@ while true; do echo "You must input a non empty string here!" >&2 else response=$test_egs_home - # directory already exists - if test -d "$response"; then - echo "The directory $response already exists" >&2 - else - break - fi + break fi # help @@ -149,12 +146,7 @@ _ACEOF # ensure this is an absolute path test_response=$( echo $response | sed 's,[\\/].*,,' ) if test "x$test_response" = x; then - # directory already exists - if test -d "$response"; then - echo "The directory $response already exists" >&2 - else - break - fi + break else echo "I'm expecting an absolute path here" >&2 fi @@ -241,12 +233,14 @@ echo "$OMEGA_HOME" >&3 echo >&3 echo >&2; +new_egs_home="no" if test ! -d "$EGS_HOME"; then printf $format "Creating $(basename $EGS_HOME) ... " >&2 printf $format "Creating $EGS_HOME ... " >&3 mkdir $EGS_HOME || { echo "failed" >&2; echo "failed" >&3; exit 1; } echo "OK" >&2; echo "OK" >&3 + new_egs_home="yes" fi cd "$EGS_HOME" || { echo "Failed to cd to $EGS_HOME" >&2; exit 1; } @@ -267,38 +261,40 @@ done # Copy all user codes to user area so that it is consistent with # the install GUI and also don't need to fix egs_gui, which does not # work if the user code is not on the user code area. -test_list=$( ls $HEN_HOUSE/user_codes ) -copy_list= -for uc in $test_list; do - if test -d $HEN_HOUSE/user_codes/$uc && test $uc != pegs4 && test $uc != bin; then - copy_list="$copy_list $uc" - fi -done -echo >&2; -echo "Copying user codes to EGS_HOME area ..." >&2 -echo "Copying user codes to EGS_HOME area" >&3 -for uc in $copy_list; do - printf $format " Copying $uc ..." >&2 - cp -r $HEN_HOUSE/user_codes/$uc . - echo "OK" >&2 -done +if test "x$new_egs_home" = xyes; then + test_list=$( ls $HEN_HOUSE/user_codes ) + copy_list= + for uc in $test_list; do + if test -d $HEN_HOUSE/user_codes/$uc && test $uc != pegs4 && test $uc != bin; then + copy_list="$copy_list $uc" + fi + done + echo >&2; + echo "Copying user codes to EGS_HOME area ..." >&2 + echo "Copying user codes to EGS_HOME area" >&3 + for uc in $copy_list; do + printf $format " Copying $uc ..." >&2 + cp -r $HEN_HOUSE/user_codes/$uc . + echo "OK" >&2 + done -# Copy BEAMnrc examples .module files to user area -test_list=$( ls $OMEGA_HOME/beamnrc/BEAMnrc_examples/ ) -copy_list= -for uc in $test_list; do - if test -f $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module; then - copy_list="$copy_list $uc" - fi -done -echo >&2; -echo "Copying BEAMnrc examples .module files ..." >&2 -echo "Copying BEAMnrc examples .module files ..." >&3 -for uc in $copy_list; do - printf $format " Copying $uc.module ..." >&2 - cp -r $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module ./beamnrc/spec_modules - echo "OK" >&2 -done + # Copy BEAMnrc examples .module files to user area + test_list=$( ls $OMEGA_HOME/beamnrc/BEAMnrc_examples/ ) + copy_list= + for uc in $test_list; do + if test -f $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module; then + copy_list="$copy_list $uc" + fi + done + echo >&2; + echo "Copying BEAMnrc examples .module files ..." >&2 + echo "Copying BEAMnrc examples .module files ..." >&3 + for uc in $copy_list; do + printf $format " Copying $uc.module ..." >&2 + cp -r $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module ./beamnrc/spec_modules + echo "OK" >&2 + done +fi echo "" >&2 @@ -317,7 +313,7 @@ if test "x$response" = x1; then test_list=$( ls $HEN_HOUSE/user_codes ) compile_list= for uc in $test_list; do - if test -d $HEN_HOUSE/user_codes/$uc; then + if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then compile_list="$compile_list $uc" fi done @@ -328,7 +324,7 @@ elif test "x$response" = x2; then junk_list=$( ls $HEN_HOUSE/user_codes ) junk_compile_list= for uc in $junk_list; do - if test -d $HEN_HOUSE/user_codes/$uc; then + if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then junk_compile_list=$( printf "$junk_compile_list\n$uc" ) fi done @@ -339,7 +335,7 @@ elif test "x$response" = x2; then fi compile_list= for uc in $test_list; do - if test -d $HEN_HOUSE/user_codes/$uc; then + if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then compile_list="$compile_list $uc" fi done @@ -375,11 +371,11 @@ done # move configuration log to log directory if test -f $my_dir/finalize_egs_$USER.log && test -d $HEN_HOUSE/log; then - mv $my_dir/finalize_egs_$USER.log $HEN_HOUSE/log/ + mv $my_dir/finalize_egs_$USER.log $HEN_HOUSE/log/configure-$my_machine-$USER.log echo >&2 printf $format "EGSnrc user configuration log saved in:" >&2 echo >&2 - echo "$my_dir/finalize_egs_$USER.log" >&2 + echo "$HEN_HOUSE/log/configure-$my_machine-$USER.log" >&2 fi cat >&2 <smaxir(irl)) USTEP=smaxir(irl); +TUSTEP=USTEP; +$SET-TUSTEP-EM-FIELD; +TVSTEP=TUSTEP; +VSTEP=TVSTEP; +USTEP=VSTEP; +IF(USTEP 0) [ "there are depth-dose plots on plotter" @@ -6669,7 +6675,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6689,7 +6695,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6713,7 +6719,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6759,7 +6765,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6778,7 +6784,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6802,7 +6808,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6860,7 +6866,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6879,7 +6885,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot kerma plot" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6902,7 +6908,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot dose/kerma graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6943,7 +6949,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6963,7 +6969,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot kerma histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; @@ -6989,7 +6995,7 @@ IF(IPLTPL.EQ.1) [ "plots for external plotter (0 if none)" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, IAXISTYPE); CURVENUM=CURVENUM+1; diff --git a/HEN_HOUSE/user_codes/dosxyznrc/srcxyznrc.mortran b/HEN_HOUSE/user_codes/dosxyznrc/srcxyznrc.mortran index 666498965..402bf988d 100644 --- a/HEN_HOUSE/user_codes/dosxyznrc/srcxyznrc.mortran +++ b/HEN_HOUSE/user_codes/dosxyznrc/srcxyznrc.mortran @@ -3982,7 +3982,7 @@ ELSEIF( isource = 20 ) [ "Phase Space Incident from multiple settings" ] ] "----------------------------------------------------------------" -ELSEIF( isource = 21) [ "Phase Space Incident from multiple settings" +ELSEIF( isource = 21) [ "BEAM Sim. source Incident from multiple settings" "and through an MLC" "----------------------------------------------------------------" LOOP [; @@ -4032,7 +4032,7 @@ LOOP [; nsrjct=nsrjct+1; goto :retry_sample_beam_vcu_source:; ] - ELSEIF(i_dbs=1 & iqin=0 & iphatsrc=1) [ + ELSEIF(i_dbs=1 & iqin=0 & iphatsrc>1) [ nsrjct=ndbsrjct+1; goto :retry_sample_beam_vcu_source:; ] diff --git a/HEN_HOUSE/user_codes/flurznrc/flurznrc.io b/HEN_HOUSE/user_codes/flurznrc/flurznrc.io index c52f34d89..c95bae886 100644 --- a/HEN_HOUSE/user_codes/flurznrc/flurznrc.io +++ b/HEN_HOUSE/user_codes/flurznrc/flurznrc.io @@ -1,4 +1,4 @@ - +# ############################################################################### # # EGSnrc flurznrc application unit numbers diff --git a/HEN_HOUSE/user_codes/flurznrc/flurznrc.mortran b/HEN_HOUSE/user_codes/flurznrc/flurznrc.mortran index 29aed958b..0e165ca70 100644 --- a/HEN_HOUSE/user_codes/flurznrc/flurznrc.mortran +++ b/HEN_HOUSE/user_codes/flurznrc/flurznrc.mortran @@ -4865,6 +4865,7 @@ $REAL XCOORD($EBIN), YCOORD($EBIN), UNCERT($EBIN); INTEGER NPTS, PLTYPE, AXISTYPE, CURVENUM, inte, CHECK; INTEGER IZR, IXR; INTEGER UNITNUM, IPLTSPEC; +CHARACTER*80 GRAPHTITLE; CHARACTER*60 SERIESTITLE, XTITLE, YTITLE,SUBTITLE; CHARACTER*4 CH_IZ, CH_IX, CH_IQ, CH_IP, CH_IRL; CHARACTER*1 a(3); @@ -5148,6 +5149,8 @@ DO IZ=1,NZ [ "determine the max and min fluence" "Plot of fluence zone results to file [-.spectra]" "this was already opened in +DO I=1,80[GRAPHTITLE(I:I)=TITLE(I);] + UNITNUM=IPLTSPEC; CURVENUM=0; DO IQ=1,4 [ "Q=4 is for electrons and positrons" @@ -5225,7 +5228,7 @@ DO IQ=1,4 [ "Q=4 is for electrons and positrons" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "end of point plot" @@ -5268,7 +5271,7 @@ DO IQ=1,4 [ "Q=4 is for electrons and positrons" "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "END OF HISTOGRAM PLOT" @@ -5355,7 +5358,7 @@ DO IQ=1,3[ "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "END OF POINT PLOT" @@ -5379,7 +5382,7 @@ DO IQ=1,3[ "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "END OF HISTOGRAM PLOT" @@ -5438,7 +5441,7 @@ DO IQ=1,3[ "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "end of point plot" @@ -5469,7 +5472,7 @@ DO IQ=1,3[ "plot histogram" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, PLTYPE, HISTXMIN, AXISTYPE); CURVENUM=CURVENUM+1; "DEFINE A NEW PLOT" ] "END OF HISTOGRAM" diff --git a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.io b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.io index 4d04bcba3..524a97485 100644 --- a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.io +++ b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.io @@ -1,4 +1,4 @@ - +# ############################################################################### # # EGSnrc sprrznrc application unit numbers diff --git a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.make b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.make index 1e512a9b2..8c22f7cb0 100644 --- a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.make +++ b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.make @@ -72,5 +72,6 @@ SOURCES = \ $(EGS_UTILS)xvgrplot.mortran \ $(MACHINE_MORTRAN) \ $(EGS_SOURCEDIR)egs_utilities.mortran \ + $(EGS_SOURCEDIR)egs_parallel.mortran \ $(EGS_SOURCEDIR)pegs4_routines.mortran\ $(EGS_SOURCEDIR)egsnrc.mortran diff --git a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.mortran b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.mortran index 0691332fc..5bfe875ca 100644 --- a/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.mortran +++ b/HEN_HOUSE/user_codes/sprrznrc/sprrznrc.mortran @@ -257,6 +257,8 @@ REPLACE {$VERSION} WITH { " analysis " = start-RNS (4) read starting random numbers from a file (E.G. for " output to a graphics package) +" = parallel (5) read in .egsdat files from parallel run and +" analyze " STORE DATA ARRAYS " = yes (0) store data arrays for re-use " = no (1) don't store them @@ -1577,7 +1579,7 @@ IDAT,IRESTART,IQIN,IVAL,ISPRREG,ISPR($MXREG); $LONG_INT NCASE,NCASEO,NCASET; $REAL AMASS,TMCPUO,TIMMAX,STATLM,EIN; $INTEGER IDAT,IRESTART,IQIN,IVAL,ISPR, -ISPRREG; +ISPRREG,DATCOUNT; } "AMASS(IZ,IX) MASS OF ZONE WITH COORDINATES (IZ,IX) "TMCPUO CPU TIME USED IN PREVIOUS SESSIONS @@ -1592,11 +1594,13 @@ ISPRREG; " = 1 => RESTARTED RUN " = 3 => DATA ANALYSIS ONLY " = 4 => READ STARTING RANDOM NUMBERS FROM A FILE +" = 5 => ANALYZE .egsdat FILES FROM PARALLEL RUN "IQIN CHARGE OF THE EXTERNAL BEAM "ISPR = 0 TO OUTPUT SPR's BY REGION " = 1 TO OUTPUT SPR's BY CYLINDER AND/OR SLAB "ISPRREG(J) = 1 IF THE USER IS OUTPUTTING SPR IN REGION J OR CYLINDER J OR " SLAB J-NR +"DATCOUNT = no. of files used for analysis of parallel run (IRESTART=5) ; REPLACE {;COMIN/USER/;} WITH {;COMIN/USER-VARIANCE-REDUCTION/;} @@ -1803,7 +1807,8 @@ REAL*4 COMIN/ BOUNDS,CHARS,ELECIN,EPCONT,GEOM,IODAT1,IODAT2,CH-Steps, PRINTC,MEDIA,MISC,PHOTIN,RUSROU,SCORE,SOURCE,SPECTR, - STACK,THRESH,UPHIOT,USEFUL,USER,RANDOM,EGS-VARIANCE-REDUCTION,RWPHSP/; + STACK,THRESH,UPHIOT,USEFUL,USER,RANDOM,EGS-VARIANCE-REDUCTION,RWPHSP, + EGS-IO/; $LONG_INT ITEMP,JCASE; $INTEGER I,J,NBATCH,IZ,IX,MEDNUM,LGLE,IBATCH,IBTCH,NOSCAT,INOCAV, NOSCT2,INOMED,IRL,IT,ICASE,IRIN,NRCFLG, @@ -1820,6 +1825,21 @@ $INTEGER egs_open_file, egs_open_datfile, rng_unit, data_unit; "character*256 junk_string; "$INTEGER lnblnk1; + +external combine_results; +$HAVE_C_COMPILER(#); + +#ifdef HAVE_C_COMPILER; + +$REAL part_spr, part2_spr, current_result, current_uncertainty; +$LONG_INT n_run,n_tot,n_last; +$INTEGER n_job; +$LOGICAL first_time; + +#endif; + +$LOGICAL is_finished; + " START OF EXECUTABLE CODE " ************************ @@ -1868,6 +1888,16 @@ ELSE IF( irestart = 4 ) [ "We well read RN's from a file" " OPEN(UNIT=2,STATUS='OLD'); "] +IF(IRESTART=5)["post-processing for parallel run" + + call egs_combine_runs(combine_results,'.egsdat'); + + NBATCH=0; "DON'T WANT IT TO RUN ANY HISTORIES" + NCASET=NCASEO; "To prevent a wrong normalization if some of the " + "parallel runs not available, IK, Jan 21 1999" +] "end of IRESTART = 5, PARALLEL POST-PROCESSING" + + MXNP=0; "RESET THE MAXIMUM STACK INDICATOR" IHSTRY=NCASEO; "RESET THE NUMBER OF HISTORIES COUNTER" @@ -2032,6 +2062,7 @@ ELSEIF(IRESTART = 1)[ ELSEIF(IRESTART = 3)[WRITE(6,204);WRITE(IOUT,204);GO TO :STATS-ANAL:;] ELSEIF(IRESTART = 4)[WRITE(6,205);WRITE(IOUT,205);] +ELSEIF(IRESTART = 5)[WRITE(6,206);WRITE(IOUT,206); GO TO :STATS-ANAL:;] "INITIALIZE IWATCH ROUTINE" IF(IWATCH.NE.0) CALL WATCH(-99,IWATCH); @@ -2055,6 +2086,41 @@ NETADJ=0; " IF( idat = 0 ) data_unit = egs_open_file(4,0,1,'.egsdat'); +"begin parallel processing implementation if there is a working C compiler +#ifdef HAVE_C_COMPILER; +; +/part_spr,part2_spr/ = 0; n_tot = ncaseo; +first_time = .true.; is_finished = .false.; +"Not sure what quantity to put in job control file, so just use" +"0 for now." + +:start_parallel_loop:; + +IF( n_parallel > 0 ) [ "Job is part of a parallel run " + + call egs_pjob_control(ncase,n_run,n_left,n_tot,part_spr,part2_spr, + current_result, current_uncertainty); + IF( n_run = 0 ) [ + write(6,'(//a,a//)') '****** No histories left in job control file', + ' => end simulation'; + goto :END-SIM:; + ] + jcase = n_run/$NBATCH; + IF( jcase < 1 ) [ jcase = 1; n_run = jcase*$NBATCH; ] + IF( first_time ) [ + first_time = .false.; n_last = n_run; + write(6,'(//a,i12,a//)') '****** Running ',n_run,' histories'; + ] + ELSE [ + write(6,'(//a,i12,a)') '***** Finished ',n_last,' histories'; + write(6,'(/a/,20x,1pe11.4,a,0pf5.2,a/,a,i12,a//)') + ' current result including previous runs and other parallel jobs: ', + current_result, ' +/- ',current_uncertainty,' %', + ' will run another ',n_run,' histories'; + ] +] +#endif; + "OUTPUT BATCHES. EXECUTION STOPS IF THERE IS NOT ENOUGH TIME TO DO ANOTHER "BATCH. DO IBATCH=1,$NBATCH[ @@ -2243,6 +2309,12 @@ TIMCPU=$CONVERSION_TO_SECONDS*(CPUT2-CPUT1)+TMCPUO; ] ] " END OF IBATCH LOOP I.E. END OF SIMULATIONS" +#ifdef HAVE_C_COMPILER; +; +IF( n_parallel > 0 ) [ goto :start_parallel_loop:; ] + +#endif; + :END-SIM:; "add unscored portions of _TMP arrays" @@ -2526,6 +2598,20 @@ write(iout,400) ' '; call egs_fdate(iout); write(iout,'(/"1")'); call egs_finish; +#ifdef HAVE_C_COMPILER; +; +IF( n_parallel > 0 & ~is_finished ) [ + call egs_pjob_finish(n_job); + IF( n_job = 0 ) [ + is_finished = .true.; + call egs_combine_runs(combine_results,'.egsdat'); + NCASET=NCASEO; IHSTRY=NCASET; + CALL SRCOTO(WEIGHT); + goto :STATS-ANAL:; + ] +] +#endif; + call SRCEND; $CALL_EXIT(0); @@ -2549,6 +2635,7 @@ $CALL_EXIT(0); ' ',20X,'NEW RN SEEDS=',2(1X,I12)/); 204 FORMAT(/' ********* DATA ANALYSIS ONLY *********'/); 205 FORMAT(/' ********* RANDOM NUMBERS READ FROM FILE *********'/); +206 FORMAT(/' ********* POST-PROCESSING PARALLEL RUNS **********'/); 210 FORMAT(/' ********* NOT ENOUGH TIME TO FINISH WITHIN', ' LIMIT OF',F8.2,' HOURS',I5,' BATCHES USED********'/ ' ',I12,' HISTORIES RUN, ',I12,' HISTORIES ANALYZED'//); @@ -3570,6 +3657,7 @@ ALLOWED_INPUTS(IVAL,0)='FIRST'; ALLOWED_INPUTS(IVAL,1)='RESTART'; ALLOWED_INPUTS(IVAL,3)='ANALYZE'; ALLOWED_INPUTS(IVAL,4)='START-RNS'; +ALLOWED_INPUTS(IVAL,5)='PARALLEL'; IVAL=IVAL+1; NUM_STORE=IVAL; @@ -3591,7 +3679,7 @@ IDAT=VALUE(NUM_STORE,1); OUTPUT IWATCH,ISTORE,IRESTART,IDAT; (/' DO NOT TRACK(0) OR TRACK(>0) EVERY INTERACTION:',T60,I12/ ' DO NOT STORE(0) OR STORE(1,2,3) INITIAL RANDOM #:',T60,I12/ - ' FIRST RUN(0),RESTARTED(1),ANALYZE(3),START RNS(4):', + ' FIRST RUN(0),RESTART(1),ANALYZE(3),START RNS(4),PARALLEL(5):', T60,I12/ ' STORE RAW DATA(0) OR NOT(1):',T60,I12); IF(IDAT.EQ.1)[INEXT=0;]ELSE[INEXT=1;] IF(IRESTART = 4) [ @@ -4057,7 +4145,7 @@ IF (ERROR_FLAG=1) [GOTO :FINISHED:;] NCASEO=0;NCASET=0;TMCPUO=0; "SET PREVIOUS RUN COUNTERS" SCSTP_TMP=0; -IF(IRESTART = 0)[ "FRESH START, SET EVERYTHING TO ZERO" +IF(IRESTART = 0 | IRESTART=5)[ "FRESH START, SET EVERYTHING TO ZERO" NNREAD=0; SCSTP=0.; SCSTP2=0.; SCSTP_LAST=0; PIISTP=0.; DO IX=1,NR[ DO IZ=1,NZ[ @@ -4436,6 +4524,7 @@ $REAL XCOORD(300), YCOORD(300), UNCERT(300); INTEGER NPTS, TYPE, AXISTYPE, UNITNUM, CURVENUM, int, CHECK; INTEGER IPLTUNX, SPRRZ_COUNT, BIN_CUT, ICOUNT; CHARACTER*60 SERIESTITLE, XTITLE, YTITLE, SUBTITLE; +CHARACTER*80 GRAPHTITLE; CHARACTER*4 CH_IZ, CH_IX; CHARACTER*1 a(3); $INTEGER egs_open_file; @@ -4469,6 +4558,8 @@ ELSE[ "For complete summary of the following variables see" "XVGRPLOT.MORTRAN" +DO I=1,80[GRAPHTITLE(I:I)=TITLE(I);] + IF(ISPRREG=1)["create the .plotdat file" SPRRZ_COUNT=0; ICOUNT=0; @@ -4503,7 +4594,7 @@ IF(ISPRREG=1)["create the .plotdat file" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, TYPE, HISTXMIN, AXISTYPE); SPRRZ_COUNT=SPRRZ_COUNT+1; "DEFINE A NEW PLOT" ICOUNT=ICOUNT+1; @@ -4527,7 +4618,7 @@ IF(ISPRREG=1)["create the .plotdat file" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, TYPE, HISTXMIN, AXISTYPE); SPRRZ_COUNT=SPRRZ_COUNT+1; "DEFINE A NEW PLOT" ICOUNT=ICOUNT+1; @@ -4562,7 +4653,7 @@ IF(ISPRREG=1)["create the .plotdat file" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, TYPE, HISTXMIN, AXISTYPE); SPRRZ_COUNT=SPRRZ_COUNT+1; "DEFINE A NEW PLOT" ICOUNT=ICOUNT+1; @@ -4588,7 +4679,7 @@ IF(ISPRREG=1)["create the .plotdat file" "plot XY-graph" CALL XVGRPLOT (XCOORD, YCOORD, UNCERT, NPTS, CURVENUM, SERIESTITLE, - XTITLE, YTITLE, TITLE, SUBTITLE, + XTITLE, YTITLE, GRAPHTITLE, SUBTITLE, UNITNUM, TYPE, HISTXMIN, AXISTYPE); SPRRZ_COUNT=SPRRZ_COUNT+1; "DEFINE A NEW PLOT" ICOUNT=ICOUNT+1; @@ -4725,6 +4816,120 @@ RETURN; 360 FORMAT(' NZ,NR=',I3,',',I3,F8.2,' -',F8.2,2X,2(F7.3,' (+/- ',F6.3,' )')); %I4 END; "end of subroutine osumry" + +"**************************************************************************** + +subroutine combine_results(file_name); + +"**************************************************************************** +implicit none; +character*(*) file_name; + +;COMIN/SCORE,RANDOM,IODAT2,GEOM,SOURCE/; + +real*8 TSCEDPN($MAXZREG,$MAXRADII,$MAXIT),TSCEDPN2($MAXZREG,$MAXRADII,$MAXIT), + TSCDOSE($MAXZREG,$MAXRADII,$MAXDOS),TSCDOSE2($MAXZREG,$MAXRADII,$MAXDOS), + TSCDOSE_COV($MAXZREG,$MAXRADII,2),TSCSPR_COV($MAXZREG,$MAXRADII,2), + TMPPIISTP,TSCSTP,TSCSTP2; +$REAL TMPTMCPU; +$LONG_INT TMPNCASE,TMPNNREAD; +$INTEGER TMPICROSS,TMPITRACKE,iorstrt; + +$INTEGER my_unit,egs_get_unit,iout,iz,ix,it,lnblnk1,irl; +$LOGICAL first_time; +data first_time/.true./, iout/1/; +save first_time,iout; + +IF( first_time ) [ + + OUTPUT ;(/1X,'Summing the following .egsdat files'); + OUTPUT ; (1X,'------------------------------------'/); + WRITE(IOUT,'(/1X,''Summing the following .egsdat files'')'); + WRITE(IOUT,'(1X,''------------------------------------''/)'); + + datcount=0; + /TMCPUO,NCASEO,PIISTP,NNREAD/ =0; + /ICROSS,ITRACKE/ =0; + DO iz=1,nz [ DO ix=1,nr [ + DO it=1,$MAXIT [ + /SCEDPN(IZ,IX,IT),SCEDPN2(IZ,IX,IT)/=0; + ] + DO it=1,$MAXDOS[ + /SCDOSE(IZ,IX,IT),SCDOSE2(IZ,IX,IT)/=0; + ] + DO it=1,2 [ /SCDOSE_COV(IZ,IX,IT),SCSPR_COV(IZ,IX,IT)/ = 0; ] + ] ] + + first_time = .false.; +] + +IORSTRT=egs_get_unit(4); "SET UNIT 4 FOR THE FILES TO BE READ" +WRITE(IOUT,'(A)') $cstring(file_name); +WRITE(6,'(A)') $cstring(file_name); +open(IORSTRT,file=file_name,status='old',err=:EOF_RS1:); + +READ(IORSTRT,*,END=:EOFC:) TSCSTP,TSCSTP2; +DO IZ=1,NZ[ + DO IX=1,NR[ + DO IT=1,$MAXIT[ + READ(iorstrt,*,END=:EOFC:)TSCEDPN(IZ,IX,IT),TSCEDPN2(IZ,IX,IT); + ] + DO IT=1,$MAXDOS[ + READ(iorstrt,*,END=:EOFC:)TSCDOSE(IZ,IX,IT),TSCDOSE2(IZ,IX,IT); + ] + READ(iorstrt,*,END=:EOFC:)TSCDOSE_COV(IZ,IX,1),TSCDOSE_COV(IZ,IX,2); + READ(iorstrt,*,END=:EOFC:)TSCSPR_COV(IZ,IX,1),TSCSPR_COV(IZ,IX,2); + ] +] +$RETRIEVE RNG STATE FROM UNIT iorstrt; +READ(iorstrt,*,END=:EOFC:) TMPNCASE,TMPTMCPU,TMPNNREAD,TMPPIISTP; +READ(iorstrt,*,END=:EOFC:)TMPICROSS,TMPITRACKE; + +"now add data" +"add separately in case we need to skip over a .egsdat file due to a" +"read error" + +DATCOUNT=DATCOUNT+1; + +SCSTP=SCSTP+TSCSTP;SCSTP2=SCSTP2+TSCSTP2; +DO IZ=1,NZ[ + DO IX=1,NR[ + DO IT=1,$MAXIT[ + SCEDPN(IZ,IX,IT)=SCEDPN(IZ,IX,IT)+TSCEDPN(IZ,IX,IT); + SCEDPN2(IZ,IX,IT)=SCEDPN2(IZ,IX,IT)+TSCEDPN2(IZ,IX,IT); + ] + DO IT=1,$MAXDOS[ + SCDOSE(IZ,IX,IT)=SCDOSE(IZ,IX,IT)+TSCDOSE(IZ,IX,IT); + SCDOSE2(IZ,IX,IT)=SCDOSE2(IZ,IX,IT)+TSCDOSE2(IZ,IX,IT); + ] + SCDOSE_COV(IZ,IX,1)=SCDOSE_COV(IZ,IX,1)+TSCDOSE_COV(IZ,IX,1); + SCDOSE_COV(IZ,IX,2)=SCDOSE_COV(IZ,IX,2)+TSCDOSE_COV(IZ,IX,2); + SCSPR_COV(IZ,IX,1)=SCSPR_COV(IZ,IX,1)+TSCSPR_COV(IZ,IX,1); + SCSPR_COV(IZ,IX,2)=SCSPR_COV(IZ,IX,2)+TSCSPR_COV(IZ,IX,2); + ] +] +TMCPUO=TMCPUO+TMPTMCPU; +NCASEO=NCASEO+TMPNCASE; +PIISTP=PIISTP+TMPPIISTP; +NNREAD=NNREAD+TMPNNREAD; +ICROSS=ICROSS+TMPICROSS; +ITRACKE=ITRACKE+TMPITRACKE; +write(6,*) ' ncase = ',TMPNCASE,' cpu = ',TMPTMCPU,' total cpu = ', + TMCPUO; +write(iout,*) ' ncase = ',TMPNCASE,' cpu = ',TMPTMCPU,' total cpu = ', + TMCPUO; + +CLOSE(UNIT=iorstrt); +return; + +:EOFC:; +WRITE(6,*) 'Error reading data from file',$cstring(file_name); +CLOSE(UNIT=iorstrt); +return; +:EOF_RS1:; +WRITE(6,*) 'Error opening file', $cstring(file_name); +return; end; + ; "end of sprrznrc.mortran (Rev 1.49)" ;