Sunteți pe pagina 1din 96

%E

/************************************************************************
*****
*
* $Id: dosxyznrc.mortran,v 1.50 2013/02/13 21:57:55 bwalters Exp $
*
* Started from Revision 1.47 of
* /usr/people/omega/dosxyznrc/RCS/dosxyznrc.mortran,v
* last edited 2003-02-14 11:00:50-05.
*

*************************************************************************
***/

" Copyright 1999 by the National Research Council
"
" of Canada, all rights reserved. This code is part
"
" of the BEAM code system for Monte carlo simulation
"
" of radiotherapy treatment units. It was developed
"
" at the National Research Council of Canada as part
"
" of the OMEGA collaborative project with the University
"
" of Wisconsin. The system is described in:
"
" BEAM: A Monte Carlo code to simulate radiotherapy
"
" treatment units
"
" D.W.O. Rogers, B.A. Faddegon, G.X. Ding, C.-M. Ma,
"
" J. Wei and T.R.Mackie
"
" Medical Physics 22 (1995) 503 -- 524.
"
" in the
"
" BEAM Users Manual "
" D.W.O. Rogers, C.-M. Ma, B. Walters, G.X. Ding,
"
" D. Sheikh-Bagheri and G. Zhang
"
" NRC Report PIRS-509A (rev D)
"
" and in the many other NRC reports cited in the Users Manual
"
"
"
" As well as the authors of the above paper and report
"
" Joanne Treurniet of NRC made significant contributions to the
"
" code system, in particular the GUIs and EGS_Windows
"
" Mark Holmes, Brian Geiser and Paul Reckwerdt of Wiscosin
"
" were important parts of the overall OMEGA project within which
"
" the BEAM code system was developed.
"
" The BEAM code system (excluding the EGS4 portions of it)
"
" is copyright and subject to the BEAM General License
"
" which is included in the distribution.
"
" The BEAM code system is provided as is without any warranty or
"
" guarantee of any kind, either expressed or implied,
"
" as to its accuracy or ability to perform particular
"
" calculations.
"
Copyright NRC 1999
"************************************************************************
*******
"
%C80 "80 column mortran input"
!INDENT M 4; "Indent 4 spaces for each nesting level in mortran listing
file"
!INDENT F 4; "Indent 4 spaces for each nesting level in fortran output
file"
%Q1 "Automatically close quotes at end of the line"

"The next line is 80 characters long, use it to set up the screen width
"23456789|123456789|123456789|123456789|123456789|123456789|123456789|123
456789|
;
"************************************************************************
*******
"
" ********************************************* ""toc:
" * * ""toc:
" * dosxyznrc.mortran ($Revision: 1.50 $) * ""toc:
" * (last edited $Date: 2013/02/13 21:57:55 $)* ""toc:
" * * ""toc:
" ********************************************* ""toc:
"
" A general purpose EGSnrc user code to do cartesian coordinate dose
" deposition studies. Every voxel (volume element) can have different
" materials and/or varying densities (for use with CT data).
"
" The geometry is a rectilinear volume with a right-handed coordinate
system:
" the X-Y plane on the page, X to the right, Y down and the
" Z-axis into the page. Voxel dimensions are completely variable in
" all three directions. For more detail on geometry see subroutine
HOWFAR

" Unit Assignments ""toc:
" ================
"
" Unit 1 Output summary and results
" Unit 2 .egsrns file for storing random numbers
" Unit 3 output .3ddose file containing dose arrays
" Unit 4 Raw data output file for restarts
" Unit 5 Input stream - file or terminal
" Unit 6 prompts for and echoes input
" Unit 8 echoes input cross-section data (usually assigned to a
null file)
" Unit 17 geometry output file for EGS_Windows
" Unit 13 phase space output file for EGS_Windows
" Unit 12 Input cross section file from PEGS4
" Unit 15 Output of EGSnrc input error messages
" Unit 16 Output for .pardose when IPARALLEL > 1
" Unit 44 Full phase-space data set, such as output from BEAM
" $CTUnitNumber (normally 45) CT data set input
"
" DESCRIPTION OF INPUT FILE (on unit 5) ""toc:
" =========================
"
" Record 1 TITLE Up to 80 characters
"
" Record 2 NMED Number of media in problem - defaults to 1
" If (NMED=0) then create dosxyznrc phantom from binary CT
data
"
"------------------------------------------------------------------------
----
"----------if NMED > 0 => non-CT data input-----------------------------
----
"------------------------------------------------------------------------
----
"
" Record 3(NMED times) Media names, left justified. Note that
" entire volume is initially set to medium 1
"
" Record 4 ECUTIN,PCUTIN,ESTEPM(i,i=1,NMED),SMAX
" ECUTIN,PCUTIN: Electron (total) and photon global cutoff
" energies in MeV. If ECUTIN > ECUT input in EGSnrc
" parameters (See below), then ECUTIN is used. The
" same is true if PCUTIN > PCUT input in EGSnrc
parameters.
" ECUT and PCUT default to AE and AP, respectively.
" ESTEPM(i,i=1,NMED): Dummy input (used to be estepe, max.
energy
" loss/electron step in each medium)
" SMAX: Dummy input (used to be max. step length)
"
" ESTEPE and SMAX are now handled in EGSnrc inputs (See
below),
" but the dummy inputs are retained for compatibility with
" EGS4/DOSXYZ input files.
"
" Record 5 IMAX,JMAX,KMAX,IPHANT (4i10)
" IMAX,JMAX,KMAX: Number of voxels in the X,Y,Z directions
" If < 0, it means that (-n) sets of equally spaced
" boundaries will be input for that direction.
" IPHANT: set to 1 to output a .egsphant file for
displaying
" non-CT isodose contours using dosxyz_show
"
" Record 6 et seq, repeated for x, y and z directions separately
" i.e. repeat the following replacing (i and x) by
" (j and y) and (k and z) respectively
" if IMAX > 0
" input, one per record, the IMAX+1 x boundaries
"
" if IMAX < 0
" input smallest x boundary, followed by abs(IMAX) pairs
" one pair/record:
" voxel width, # voxels with this width
"
" For example, starting at record 5:
" -1,-1,-1
" 0.0
" 1.0,16
" 0.0
" 1.0,16
" 0.0
" 1.0,16
" defines a 16x16x16 cm cube of 1cm**3 voxels with a total of 4097
regions
" Or:
" -1,-1,2
" 0.0
" 1.0,16
" 0.0
" 1.0,16
" 0.0
" 5.0
" 10.0
" defines a 16x16x10 cm cube with 1x1x5 cm voxels stacked 2 deep
"
" Record 7 et seq
" IL,IU, JL,JU, KL,KU, MEDIUM, DENSITY (7i10,f10.0)
" This record is repeated until a blank record is found.
" All regions default to medium 1 with its default density
" unless changed here.
" For all voxels with
" IL <= i <= IU
" JL <= j <= JU
" KL <= k <= KU
" the medium and density are defined.
" If DENSITY=0.0, the default value for that
" MEDIUM is used (faster than entering default density here).
" If IU and IL are non-zero, the rest default to all j,k
"
" Record 8 et seq
" IL,IU, JL,JU, KL,KU, ECUTL, PCUTL (6i10,2f10.0)
" This record is repeated until a blank record is found.
" As above but allowing a region by region local definition
" of ECUT and PCUT.
" All regions default to the global values defined in
" record 4 unless changed here.
" Note, this option disabled, but must enter blank record
" for compatibility. Note old code is in place.
"
" Record 9 et seq
" IL,IU, JL,JU, KL,KU,IZSCAN,MAX20
" This record is repeated until a blank record is found.
" As above except these are the regions for which the
" dose will be printed in .egslst - beware of a paper
explosion!
" The default is to print nothing unless asked for here.
" IZSCAN is non-zero to get a z-scan per page, otherwise
" output is an x-scan per page. If the input parameter
" MAX20 is equal to 1 on any of these input lines, a
" summary of the 20 highest doses is included in the output.
"
;
"------------------------------------------------------------------------
----
"---------------if NMED = 0 input for a CT phantom ---------------------
------
"------------------------------------------------------------------------
----

" Record 3 PhantFileName (A256) : The full name of the file
containing
" the CT phantom as output by
ctcreate
" (should be a .egsphant file).
"
" Record 4 ECUTIN,PCUTIN,SMAX (3F15.0)
" ECUTIN,PCUTIN: Electron (total) and photon global cutoff
" energies in MeV. If ECUTIN > ECUT input in
EGSnrc
" parameters (See below), then ECUTIN is used as
the
" global ECUT. The same is true if PCUTIN > PCUT
input
" in EGSnrc parameters. ECUT and PCUT default to
AE and
" AP, respectively.
" SMAX: Dummy input (used to be max. step length)
"
" SMAX is now handled in EGSnrc inputs (See below),
" but the dummy input is retained for compatibility with
" EGS4/DOSXYZ input files.
"
" Record 5 zeroairdose,doseprint,MAX20 (3I5)
"
" zeroairdose: = 1 to zero the dose in air (any
" material with density < 0.044 g/cm^3)
" in the .3ddose file
" = 0(default) to not zero the dose in air
" doseprint: = 1 for output of all doses to
" .egslst file
" = 0(default) to suppress this output
" MAX20: = 1 to print out summary of 20 highest
" doses
" = 0(default) no summary of these doses
;
"------------------------------------------------------------------------
----
"---------------From here on the two formats are identical.--------------
----
"------------------------------------------------------------------------
----
"
" Records 10--12 (6--8 if NMED=0) Refer to srcxyznrc.mortran
"
" Record 13 (9 if NMED=0)
" NCASE, IWATCH, TIMMAX, INSEED1, INSEED2,
" BEAM_SIZE,
ISMOOTH,IRESTART,IDAT,IREJECT,ESAVE_GLOBAL,NRCYCL,IPARALLEL,
" PARNUM,n_split,ihowfarless
"
" NCASE Number of histories
" IWATCH 0=>no tracking output, 1=>list every interaction
" 2=>list every electron step 4=>EGS_Windows output
" IWATCH is for debugging/watching what is happening
" It MUST be ZERO for production runs
" TIMMAX Not used currently but prints warning: default 1
hour
" INSEED1&2 Starting random number seeds (0 is ok)
" Note that, if using the RANLUX random no.
" generator, INSEED1 is the luxury level and should
" have a value >0 and <=4. Otherwise, a default
" luxury level of 1 will be used.
" BEAM_SIZE Beam size for a square field for the dose
calculation
" This parameter is only used by sources 2,3 and 4
" (default to 100 cm for a 100x100 cm square field)
" ISMOOTH =1 re-distribute particles when re-start a ph-sp
file
" and/or recycle an individual particle
" =0 re-use the ph-sp data once run out (no
redistribution)
" IRESTART = 0 first run for this data set (the default)
" = 1 restart of a previous run
" = 2 just create the input file and exit
" = 3 just read in the raw data and do the
statistical
" analysis
" = 4 recombine .pardose files from parallel runs
" IDAT = 0 output intermediate files for restarts
" = 1 do not output intermediate data files at all
" = 2 output the data file for restart at end only
" IREJECT = 0 (default) do not perform charged particle
range
" rejection.
" = 1 perform charged particle range rejection. If
" particle range to ECUTIN < distance to nearest
voxel
" boundary then terminate history if E
<ESAVE_GLOBAL.
" ESAVE_GLOBAL Energy (MeV) below which charged particle will be
" considered for range rejection.
" NRCYCL Number of times to recycle each particle in a
phase space
" source. Each particle in the phase space
" file is used a total of NRCYCL+1 times (provided
the
" particle has the correct charge and latch value)
before
" going on to the next particle.
" If NRCYCL is set <=0 then NRCYCL is automatically
" calculated to use the entire phase space file with
no
" restarts, unless the incident charge is +1
(positron) or
" the user filters incident particles based on their
LATCH
" values (enflag=3), in which case NRCYCL is set to
0.
" The calculated NRCYCL does not take into account
" particles that are rejected because they miss the
" geometry or because they are beyond the beam field
" being considered (defined by BEAM_SIZE)
" If NRCYCL is set > 0, then the user-input value is
used.
" If NCASE > no. of particles in the phase space
file,
" then use of NRCYCL is essential for accurate
statistics.
" If you are unsure of how many times to recycle,
use
" the automatically-calculated value of NRCYCL. If
this
" still results in many restarts (because of many
" particles missing the geometry or beyond beam
field),
" then re-run the simulation with NRCYCL set
manually to:
" NCASE/(NPHSP - NSMISS/NRCYCL_prev - NOUTSIDE - NRJCT -
NDBSRJCT)-1
" where NPHSP is the no. of particles of interest in
the
" the ph-sp file (ie total no. of particle, no. of
photons,
" no. of electrons), NSMISS is the no. of particles
that
" missed the geometry in the previous run,
NRCYCL_prev is
" the value of NRCYCL used in the previous run,
" NOUTSIDE is the no. of particles rejected because
they
" were beyond BEAM_SIZE in the previous run, NRJCT
" is the no. of particles rejected because they were
" multiple passers, and NDBSRJCT is the number of
photons
" rejected because they fall outside the directional
" bremsstrahlung splitting (DBS) field radius at the
SSD
" (see inputs for source 2,8 for more info on
rejecting
" fat photons when DBS is used in BEAM to generate
phase
" space files). All of the aforementioned values are
" available in the .egslst file. Always round your
" calculated value of NRCYCL up.
"
" Note: the following 2 inputs are only relevant if you are manually
" creating/submitting your parallel jobs or if you are using the
" unix pprocess script. In the case of the pprocess script,
these
" inputs get set automatically.
"
" IPARALLEL set >1 if you are distributing the job among
IPARALLEL
" machines. This will generate
" a binary .pardose file for each job which will
contain
" the doses in all voxels WITHOUT UNCERTAINTIES.
The
" stand-alone code, combinedose, will average the
.pardose
" files and calculate the uncertainty and output the
" result in .3ddose format. IPARALLEL defaults to
0.
" PARNUM Only needs to be set if IPARALLEL>1 and you are
using
" a single phase space source. The partition of the
phase
" space source that will be used for this one of the
" series of parallel input files (for the same total
" simulation) is given by:
" (PARNUM-1)*(nshist/IPARALLEL)<nnphsp<=
"
(PARNUM)*(nshist/IPARALLEL)
" where nshist is the total number of particles in
the
" phase space file and nnphsp is the number of the
" particle chosen for the simulation. Thus, PARNUM
" should cover the range 1<=PARNUM<=IPARALLEL. If
you
" are using a separate phase space source for each
" parallel job (ie the phase space source exists in
" IPARALLEL pieces) and, thus, do not wish to
partition
" the phase space sources, PARNUM can be left at its
" default value of 0.
"
" n_split If set > 1, then all photons will be split
" n_split times. This option increases the
efficiency of
" dose caluclations more than photon forcing.
" A rule of thumb for good efficiency is
" n_split >= No/(1-exp(-Lambda))
" where Lambda is the approx. number of photon MFP
" in the geometry of interest and No >= 5.
" Note that if you use the above, there will
" be on average approx. No primary interactions per
" incident photon => reduce the number of
" histories by this number.
"
" The n_split algorithm works as follows:
" * dpmfp_i = -log(1 - (eta+i)/n_split)
" where dpmfp_i is MFP to the next interaction for the i-th
sub-photon
" eta is a random number (the same for all n_split sub-photons)
" * Once at the interaction site, the i'th sub-photon produces
" electrons and/or scattered photons. Scattered photons are
" killed with probability 1/n_split, so that, if they survive,
" they have the weight of the original photon. Electrons have
the
" weight of 1/n_split of original weight.
" * In any radiative events (brems, annih, annih at rest),
photons
" are killed with probability 1/n_split => they have again the
" weight of the photon that initiated the history, if they
survive
"
" ihowfarless Set to 1 to use the 'HOWFARLESS' algorithm for
" transport in a homogeneous phantom. When
'HOWFARLESS'
" is used, subroutines HOWFAR and HOWNEAR only
consider
" the extreme outer boundaries of the phantom when
" calculating the distance along the particle
trajectory
" or nearest perpendicular distance to a region
boundary.
" This removes the restriction that charged particle
" steps must stop at all voxel boundaries and, thus,
" speeds up the calculation considerably. For the
purpose
" of dose deposition in the voxels, the total curved
" charged particle step is approximated using 2
straight-
" line steps joined at a hinge point. See the
DOSXYZnrc
" manual for more details about the approximation.
" Restrictions on charged particle step length then
become
" the EGSnrc input variables Smax (max. allowable
charged
" particle step length) and estepe (max. fractional
energy
" loss/step). Leaving Smax set to its default value
" of 5 cm should maximize efficiency of the
'HOWFARLESS'
" algorithm at most beam energies. Efficiency
improvement
" due to 'HOWFARLESS' depends on the incident beam
type,
" DOSXYZnrc voxel size and the boundary crossing
algorithm
" (BCA) used. For incident photon beams from
accelerators
" simulated with BEAMnrc (phase space or BEAMnrc
sim.
" sources), the efficiency improves by ~30%
" when the PRESTA-I BCA is used, and by factors of
" 2.5-3.5 when the more accurate (but slower) EXACT
" BCA is used. In monoenergetic electron beams,
" 'HOWFARLESS' improves efficiency by a factor of up
to
" ~4 with the PRESTA-I BCA and by a factor of up to
" ~15 with the EXACT BCA. Recommended for all
homogeneous
" phantom calculations, but it must NOT be used in
" nonhomogeneous phantoms.
"
"------------------------------------------------------------------------
----
"------------------------------------------------------------------------
----
" EGSnrc INPUTS
" *************
" (modified from the description in $HEN_HOUSE/get_inputs.mortran)
"
" All input associated with selection of EGSnrc transport parameter
" is not crucial for the execution as there are default values set.
" Therefore, if some of the input options in this section are
" missing/misspelled, this will be ignored and defualt parameter assumed
" As the transport parameter input routine uses get_inputs, a lot
" of error/warning messages may be produced on UNIT 15, though.
" If you don't have the intention of changing default settings,
" simply ignore the error messages.
"
" The delimeters are
"
" :start mc transport parameter:
" :stop mc transport parameter:
"
" Currently, the following options are available (case does not matter
and
" the internal variables are shown in [ ] brackets):
"
" Global ECUT= Global (in all regions) electron transport cut
" off energy (in MeV). If this imput is missing,
" or is < ECUTIN from the main DOSXYZnrc inputs
" (See above) then ECUTIN is used for global ECUT.
" ECUT defaults to AE(medium).
" [ ECUT ]
" Global PCUT= Global (in all regions) photon transport cut
" off energy (in MeV). If this imput is missing,
" or is < PCUTIN from the main DOSXYZnrc inputs
" (See above) then PCUTIN is used for global PCUT.
" PCUT defaults to AP(medium).
" [ PCUT ]
" Global SMAX= Global (in all regions) maximum step-size
" restriction for electron transport (in cm).
" No SMAX restriction is necessary if the electron
" step algorithm is PRESTA-II and the EXACT
boundary
" crossing algorithm is used. In this case, SMAX
" will default to 1e10. However, if either
" Electron-step algorithm= PRESTA-I
" or
" Boundary crossing algorithm= PRESTA-I (the
default),
" then a step-size restriction is necessary, and
" SMAX will default to 5 cm.
" [ SMAXIR ]
" ESTEPE= Maximum fractional energy loss per step.
" Note that this is a global option only, no
" region-by-region setting is possible. If
missing,
" the defualt is 0.25 (25%).
" [ ESTEPE ]
" XImax= Maximum first elastic scattering moment per
step.
" Default is 0.5, NEVER use value greater than 1
as
" this is beyond the range of MS data available.
" [ XIMAX ]
" Boundary crossing algorithm=
" There are two selections possible: EXACT and
" PRESTA-I. PRESTA-I means that boundaries will
" be crossed a la PRESTA. That is, with lateral
" correlations turned off at a distance given by
" `Skin depth for BCA' (see below) from the
boundary
" and MS forced at the boundary. EXACT means
" the algorithm will cross boundaries in a single
" scattering (SS) mode, the distance from a
boundary
" at which the transition to SS mode is made is
" determined by `Skin depth for BCA' (see below).
" Default is PRESTA-I for efficiency reasons. This
" is known not to be exactly correct, and when
charged
" particle equilibrium does not hold or when there
is
" a large difference in size between dose voxels
and
" voxels making up the rest of the phantom, can
result
" in an overestimate of dose by up to 2.5%. In
such
" cases, swich to EXACT BCA.
" [ bca_algorithm, exact_bca ]
" Skin depth for BCA=
" If Boundary crossing algorithm= PRESTA-I
(default)
" then this is the distance from the boundary (in
" elastic MFP) at which lateral correlations will
be
" switched off. The default in this case is to
" calculate a value based on the scattering power
at
" ECUT (same as PRESTA in EGS4). If
" Boundary crossing algorithm= EXACT then this is
" the distance from the boundary (in elastic
" MFP) at which the algorithm will go into single
" scattering mode and defaults to 3 mfp.
" Note that if you choose EXACT boundary crossing
and
" set Skin depth for BCA to a very large number
(e.g.
" 1e10), the entire calculation will be in SS
mode.
" If you choose PRESTA-I boundary crossing and
make
" Skin depth for BCA large, you will get default
EGS4
" behaviour (no PRESTA).
" [ skindepth_for_bca ]
"
" Note that the above defaults have been choosen as a
compromise
" between accuracy (EXACT BCA) and efficiency (PRESTA-I BCA)
" since the PRESTA-I BCA algorithm has proven to generally
" produce satisfactory results. Note that the new transport
" mechanics of EGSnrc are maintained away from boundaries and
" that one always has the option of verifying the accuracy
" by doing a long run with the EXACT BCA.
"
" Electron-step algorithm=
" PRESTA-II (the default), the name is
" used for historical reasons
" or PRESTA-I
" Determines the algorithm used to take into
account
" lateral and longitudinal correlations in a
" condensed history step.
" [ transport_algorithm ]
" Spin effects= Off, On, default is On
" Turns off/on spin effects for electron elastic
" scattering. Spin On is ABSOLUTELY necessary for
" good backscattering calculations. Will make a
" difference even in `well conditioned' situations
" (e.g. depth dose curves for RTP energy range
" electrons).
" [ spin_effects ]
" Brems angular sampling= Simple, KM, default is Simple
" If Simple, use only the leading term of the
Koch-Motz
" distribution to determine the emission angle of
" bremsstrahlung photons. If KM, complete
" modified Koch-Motz 2BS is used (modifications
" concern proper handling of kinematics at low
" energies, makes 2BS almost the same as 2BN at
low
" energies).
" [ IBRDST ]
" Brems cross sections= BH, NIST, NRC, default is BH
" If BH is selected, the Bethe-Heitler
bremsstrahlung
" cross sections (Coulomb corrected above 50 MeV)
" will be used. If NIST is selected, the NIST
brems
" cross section data base (which is the basis for
" the ICRU radiative stopping powers) will be
employed.
" Differences are negligible for E > ,say, 10 MeV,
" but signifficant in the keV energy range. If
NRC is
" selected, NIST data including corrections for
" electron-electron brems will be used (typically
only
" significant for low values of the atomic number
Z
" and for k/T < 0.005).
" Bound Compton scattering= On, Off or Norej (Default is On)
" If Off, Compton scattering will be treated with
" Klein-Nishina, with On Compton scattering is
" treated in the Impulse approximation.
" Make sure to turn on for low energy
applications,
" not necessary above, say, 1 MeV. Option Norej
" uses full bound Compton cross section data
" supplied in input below and does not reject
" interactions.
" [ IBCMP ]
" Compton cross sections= Bound Compton cross-section data. User-
" supplied bound Compton cross-sections in the
file
" $HEN_HOUSE/data/comp_xsections_compton.data,
where
" comp_xsections is the name supplied for this
input.
" This is only used if Bound Compton scattering=
Simple
" and is not available on a region-by-region basis
" (see below). The default file (ie in the
absence
" of any user-supplied data) is
compton_sigma.data.
" [ comp_xsections ]
" Radiative Compton corrections= On or Off (default). If on, then
" include radiative corrections for Compton
scattering.
" Equations are based on original Brown & Feynman
" equations (Phys. Rev. 85, p 231--1952).
Requires
" a change to the user codes Makefile to include
" $(EGS_SOURCEDIR)rad_compton1.mortran in the
" SOURCES (just before
$(EGS_SOURCEDIR)egsnrc.mortran).
" [ radc_flag ]
" Pair angular sampling= Off, Simple or KM
" If off, pairs are set in motion at an angle m/E
" relative to the photon direction (m is electron
rest
" energy, E the photon energy). Simple turns on
" the leading term of the angular distribution
" (this is sufficient for most applications),
" KM (comes from Koch and Motz) turns on using 2BS
" from the article by Koch and Motz.
" Default is Simple, make sure you always use
" Simple or KM
" [ IPRDST ]
" Pair cross sections= BH (default) or NRC. If set to BH, then use
" Bethe-Heitler pair production cross-sections.
If set
" to NRC, then use NRC pair production cross-
sections
" (in file $HEN_HOUSE/data/pair_nrc1.data). Only
" of interest at low energies, where the NRC
cross-
" sections take into account the assymmetry in the
" positron-electron energy distribution.
" [ pair_nrc ]
" Photoelectron angular sampling= Off or On
" If Off, photo-electrons get the direction of the
" `mother' photon, with On, Sauter's furmula is
" used (which is, striktly speaking, valid only
for
" K-shell photo-absorption).
" If the user has a better approach, replace the
macro
" $SELECT-PHOTOELECTRON-DIRECTION;
" The only application that
" I encountered until now where this option made a
" small difference was a big ion chamber (cavity
size
" comparable with electron range) with high-Z
walls
" in a low energy photon beam.
" Default is Off
" [ IPHTER ]
" Rayleigh scattering= Off, On, custom
" If On, turned on coherent (Rayleigh) scattering.
" Default is Off. Should be turned on for low
energy
" applications. Not set to On by default because
" On requires a special PEGS4 data set. If set to
" custom, then media for which custom form factors
" are to be specified are listed in the input:
" ff media names=
" and the corresponding files containing custom
data
" are listed in:
" ff file names=
" [ IRAYLR ]
" Atomic relaxations= Off, On
" Default is Off. The effect of using On is
twofold:
" - In photo-electric absorption events, the
element
" (if material is mixture) and the shell the
photon
" is interacting with are sampled from the
" appropriate cross seections
" - Shell vacancies created in photo-absorption
events
" are relaxed via emission of fluorescent X-
Rays,
" Auger and Koster-Cronig electrons.
" Make sure to turn this option on for low energy
" applications.
" [ IEDGFL ]
" Electron impact ionization= Off, On, Casnati, Kolbenstvedt,
Gryzinski
" (Default is Off)
" Determines which, if any, theory is used to
model
" electron impact ionization. If set to 'On'
then the
" theory of Kawrakow is used. Other settings use
the
" theory associated with the name given. See
future
" editions of the EGSnrc Manual (PIRS-701) for
more
" details. This is only of interest in keV X-Ray
" simulations. Otherwise, leave it Off.
" [ eii_flag ]
" Photon cross sections= epdl, xcom, customized (Default is Storm-
Israel
" cross-sections from PEGS4)
" The name of the cross-section data for photon
" interactions. This input line must be left out
" to access the default Storm-Israel cross-
sections
" from PEGS4. 'edpl' uses cross-sections from
the
" evaluated photon data library (EPDL) from
Lawrence
" Livermore. 'xcom' will use the XCOM cross-
sections
" from Burger and Hubbell. The user also has the
" option of using their own customized cross-
section
" data. See the BEAMnrc manual for more details.
" [ photon_xsections ]
" Photon cross-sections output= Off (default) or On. If On, then
" a file $EGS_HOME/user_code/inputfile.xsections
is
" output containing photon cross-section data
used.
" [ xsec_out ]
"
" Atomic relaxations, Rayleigh scattering,
" Photoelectron angular sampling and Bound Compton scattering
" can also be turned On/Off on a region-by-region
" basis. To do so, put e.g.
"
" Atomic relaxations= On in Regions or
" Atomic relaxations= Off in regions
"
" in your input file. Then use
"
" Bound Compton start region=
" Bound Compton stop region=
" or
" Rayleigh start region=
" Rayleigh stop region=
" or
" Relaxations start region=
" Relaxations stop region=
" or
" PE sampling start region=
" PE sampling stop region=
"
" each followed by a lost of of one or more
" start and stop regions separated by commas.
" Example:
" Atomic relaxations= On in Regions
" Relaxations start region= 1, 40
" Relaxations stop region= 10, 99
" will first turn off relaxations everywhere and
" then turn on in regions 1-10 and 40-99.
" Note that input is checked against min. and
max.
" region number and ignored if
" start region < 1 or stop_region > $MXREG or
" start region > stop region.
"
;
"************************************************************************
*******
"
" Origin of DOSXYZ
" ================
"
" DOSXYZ started out as a demonstration code that Dave Rogers wrote
" to show Ralph Nelson that special purpose coding of rectilinear
" voxels was faster than
" using his more general macros. It then got used to estimate the
" time required to do a full Monte Carlo treatment planning
" calculation and the results published 3 years later in a book
" chapter (Rogers and Bielajew, 1990). It then became the basis for
" a Monte Carlo timing benchmark (Bielajew and Rogers, Med. Phys.
" 19, (1992) 303).
" The OMEGA project took this code over and added a variety of
" different source routines with coding contributions from
" B.A. Faddegon, C.M. Ma, G.X. Ding, A.F. Bielajew and P. Reckwerdt.
" More recent mods have reduced the array space used by the code,
" and added beam characterization inputs (C.M. Ma), btree inputs,
" (Brian Geiser), correlated sampling hooks (Mark Holmes).
" Blake Walters and Mark Holmes added the CT reading ability
" Dave Rogers cleaned up code (added errors??) in 1997.
"
" DOSXYZnrc was created from DOSXYZ in January, 2001 by
" Blake Walters
"
" The code is copyright by the OMEGA collaboration of NRCC and
" University of Wisconsin. 1995 1996 1997 1998
"
"************************************************************************
*******
;

"Step 1 User overrides and declarations ""toc:
"=======================================

"There are macros defined in dosxyz_user_macros.mortran which user "
"may wish to adjust"

" Start of macro definitions ""toc:

"the following calculates BLCMIN on the fly if using PRESTA-I as the"
"BCA--can save a lot of time, overrides macro of the same name in
egsnrc.macros"
"This macro commented out since it was found to cause real differences"
"between dosxyznrc and dosxyz in e- depth-dose calculations. We now
default"
"to use PRESTA-I BCA with fixed BLCMIN"
"REPLACE {$SET-SKINDEPTH(#,#);} WITH {;"

"IF( exact_bca ) ["
" $CALCULATE-ELASTIC-SCATTERING-MFP(ssmfp,{P1},{P2});"
" skindepth = skindepth_for_bca*ssmfp;"
"]"
"ELSE ["
" p2 = {P1}*({P1}+rmt2); beta2 = p2/(p2 + rmsq);"
" xccl = xcc(medium); blccl = blcc(medium); chia2 =
xccl/(4*blccl*p2);"
" skindepth ="
" skindepth_for_bca*2*p2*beta2/xccl/(log(1+1./chia2)*(1+chia2)-
1);"
" IF( skindepth > 5 ) skindepth = 5;"
"]"
"};"

"The following macros used to be in machine.mortran"
REPLACE {$DECLARE_COMMON_TIMING_VARIABLES;} WITH {;
character timen*8, daten*11, dntime*24;
};
REPLACE {$DATEN_FORMAT} WITH {A};
REPLACE {$TIMEN_FORMAT} WITH {A};

"Macro to replace $SELECT-PHOTON-MFP in egsnrc.macros"
"This is a modified version of this macro found in cavrznrc.mortran"
REPLACE {$SELECT-PHOTON-MFP;} WITH {;

IF( n_split > 1 ) [ "we use photon splitting"

:START-MFP-LOOP:;

$RANDOMSET RNNO35;
rnno35 = rnno35/n_split;
d_eta = 1./n_split;
x_save = x(np); y_save = y(np); z_save = z(np);
u_save = u(np); v_save = v(np); w_save = w(np);
e_save = e(np); wt_save = wt(np)/n_split; ir_save = ir(np);
latch_save = latch(np);
np = np-1;

$RANDOMSET xxx; a_survive = xxx*n_split;
i_survive_s = 1 + a_survive;

dpmfp_old = 0;
eta_prime = 1 - rnno35 + d_eta;
IF(IWATCH ~=0 & IWATCH~=4)["output a message about splitting"
OUTPUT n_split,wt_save;
(' Splitting photon into ',I4,' photons with weight ',1PE10.3);
]
DO i_split = 1,n_split [
eta_prime = eta_prime - d_eta;
IF(eta_prime <= 0 ) goto :END-MFP-LOOP:;
dpmfp = -log(eta_prime) - dpmfp_old;
dpmfp_old = dpmfp_old + dpmfp;
np = np+1;
IF( np > $MXSTACK ) [
write(6,*) ' Stack overflow in $SELECT-PHOTON-MFP ';
stop;
]
x(np) = x_save; y(np) = y_save; z(np) = z_save;
u(np) = u_save; v(np) = v_save; w(np) = w_save;
wt(np) = wt_save; e(np) = e_save; iq(np) = 0; ir(np) = ir_save;
latch(np) = latch_save;
irl = ir(np); irold = irl; medium = med(irl);
LOOP [
IF( medium ~= 0 ) [
$SET INTERVAL GLE,GE;
$EVALUATE GMFPR0 USING GMFP(GLE);
$SET-RHOF;
GMFP=GMFPR0/RHOF;
$RAYLEIGH-CORRECTION;
TSTEP=GMFP*DPMFP;
]
ELSE [ TSTEP=VACDST; ]
irnew = irl; idisc = 0; ustep = tstep; tustep = ustep;
call howfar;
VSTEP=USTEP;
TVSTEP=VSTEP;
EDEP=PZERO;
IF (IWATCH>0) CALL WATCH($TRANAUSB,IWATCH);
x(np) = x(np) + u(np)*ustep;
y(np) = y(np) + v(np)*ustep;
z(np) = z(np) + w(np)*ustep;
IF( idisc > 0 ) [
IF (IWATCH>0) CALL WATCH($USERDAUS,IWATCH);
np = np-1;
IF( np = 0 ) [
ircode = 2; return;
]
goto :END-MFP-LOOP:;
]
IF( medium ~= 0 ) dpmfp = dpmfp - ustep/gmfp;
IF( irnew ~= irold ) [
ir(np) = irnew; irl = irnew; irold = irnew;
medium = med(irl);
]
IF (IWATCH>0) CALL WATCH($TRANAUSA,IWATCH);
] UNTIL (medium ~= 0 & dpmfp < $EPSGMFP);
x_save = x(np); y_save = y(np); z_save = z(np);
ir_save = ir(np);
IF(IRAYLR(IRL).EQ.1) [
$RANDOMSET RNNO37;
IF (RNNO37.LE.(1.0-COHFAC)) [
IF( i_split ~= i_survive_s ) [
np = np-1; goto :JUST-RAYLEIGH-EVENT:;
]
IF (IWATCH>0) CALL WATCH($RAYLAUSB,IWATCH);
$AUSCALL($RAYLAUSB);"for howfarless version"
wt(np) = wt(np)*n_split;
:RAYLEIGH-SAMPLING-LOOP: LOOP [
$RANDOMSET XXX;
$SET INTERVAL XXX,RCO; $EVALUATE X2 USING
RSCT(XXX);
Q2=X2*RMSQ/(20.60744*20.60744);
COSTHE=1.-Q2/(2.*E(NP)*E(NP));
IF (ABS(COSTHE).GT.1.0) GO TO :RAYLEIGH-SAMPLING-
LOOP:;
CSQTHE=COSTHE*COSTHE;
REJF=(1.0+CSQTHE)/2.0;
$RANDOMSET RNNORJ;
] UNTIL (RNNORJ <= REJF);
SINTHE=SQRT(1.0-CSQTHE); CALL UPHI(2,1);
IF (IWATCH>0) CALL WATCH($RAYLAUSA,IWATCH);
goto :JUST-RAYLEIGH-EVENT:;
]
]
$RANDOMSET RNNO36;
$EVALUATE GBR1 USING GBR1(GLE);
IF((RNNO36.LE.GBR1).AND.(E(NP).GT.RMT2) )[
IF (IWATCH>0) CALL WATCH($PAIRAUSB,IWATCH);
$AUSCALL($PAIRAUSB); "for howfarless option"
call pair;
IF (IWATCH>0) CALL WATCH($PAIRAUSA,IWATCH);
]
ELSE [
$EVALUATE GBR2 USING GBR2(GLE);
IF (RNNO36.LT.GBR2) [
IF (IWATCH>0) CALL WATCH($COMPAUSB,IWATCH);
$AUSCALL($COMPAUSB); "for howfarless option"
call compt;
IF (IWATCH>0) CALL WATCH($COMPAUSA,IWATCH);
]
ELSE [
IF (IWATCH>0) CALL WATCH($PHOTOAUSB,IWATCH);
$AUSCALL($PHOTOAUSB); "for howfarless option"
call photo;
IF (IWATCH>0) CALL WATCH($PHOTOAUSA,IWATCH);
]
]

"Kill scattered photons with probability 1/nsplit"
"surviving photon carries the weight of the original photon"
ip = NPold;
LOOP [
IF( iq(ip) = 0 ) [
IF( i_split ~= i_survive_s ) [
IF( ip < np ) [
IF(IWATCH~=0 & IWATCH~=4)[
OUTPUT ip,e(ip),iq(ip),ir(ip),x(ip),y(ip),
z(ip),u(ip),v(ip),w(ip),latch(ip),wt(ip);
(' Eliminating scattered photon',T36,':',
I5,F9.3,2I4,3F8.3,3F7.3,I10,1PE10.3);
]
e(ip) = e(np); iq(ip) = iq(np);
u(ip) = u(np); v(ip) = v(np); w(ip) = w(np);
wt(ip) = wt(np); latch(ip) = latch(np);
]
np = np-1;
]
ELSE [
wt(ip) = wt(ip)*n_split; ip = ip+1;
]
]
ELSE [ "this is a charged particle, skip to the next
particle"
ip = ip+1;
]
] UNTIL (ip > np);

:JUST-RAYLEIGH-EVENT:

]
:END-MFP-LOOP:;

IF( np <= 0 ) [ ircode = 2; return; ]
IF( iq(np) = 0 ) [
"split it again if energy > PCUT"
peig = e(np); eig = peig; irl = ir(np); medium = med(irl);
IF(EIG.LE.PCUT(IRL)) [GO TO :PCUT-DISCARD:;]
gle = log(eig);
goto :START-MFP-LOOP:;
]
return;
]
ELSE[
"just the regular $SELECT-PHOTON-MFP coding"
$RANDOMSET RNNO35;
IF(RNNO35 = 0.0)[RNNO35=1.E-30;]
DPMFP=-LOG(RNNO35);
]
}

" Range rejection macro:
" **********************
" DOSXYZnrc bypasses the EGSnrc built-in range rejection (implemented in
" the $RANGE-DISCARD macro in EGSnrc) because EGSnrc range rejection
" uses particle range to AE, while we want to use particle range to
" ECUTIN. In the macro below, DNEAR(NP) is the perpendicular distance
from
" the particle to the nearest region boundary, range is the particle
range to
" AE (calculated in EGSnrc) and RANGE_ECUTRR(MED(IRL)) is the range from
ECUTIN
" to AE in the medium in region IRL (calculated at the beginning of the
" simulation). Thus, range-RANGE_ECUTRR(MED(IRL)) is the particle range
to
" ECUTIN in region IRL, scaled for non-default density, and if
" DNEAR is >= this, we can discard the particle.
"
" No range rejection is done in vacuum, if IREJECT=0, or if the particle
energy
" exceeds ESAVE_GLOBAL.
"
REPLACE {$USER-RANGE-DISCARD;} WITH {
" ===================="
;
IF( IREJECT = 1 & MED(IR(NP)) ~= 0 & E(NP) < ESAVE_GLOBAL &
DNEAR(NP) >= range-
RANGE_ECUTRR(MED(IR(NP)))*(RHO(MED(IR(NP)))/RHOR(IR(NP)))
& (IR(NP)=irmax+1 | ~howfarless) )[

"Perform charged-particle range-rejection using ECUTIN"
"range-RANGE_ECUTRR(MED(IR(NP)))*(RHO(MED(IR(NP)))/RHOR(IR(NP))) is the
range"
"to ECUTIN in region IR(NP), scaled for possible non-default densities"

IF(LELEC = -1)[ IDISC=1;"electron" ] ELSE [IDISC=99;"positron"]
GOTO :USER-ELECTRON-DISCARD:;

]"end of perform range-rejection block"
}

"macro below overrides that in egsnrc.macros. It is identical with"
"the exception of the check on (irl=irmax+1|~howfarless)"
REPLACE {$RANGE-DISCARD;} WITH {
;IF( i_do_rr(irl) = 1 & e(np) < e_max_rr(irl) &
(irl=irmax+1|~howfarless))[
IF(tperp >= range) ["particle cannot escape local region"
idisc = 50 + 49*iq(np); "1 for electrons, 99 for positrons"
go to :USER-ELECTRON-DISCARD: ;
]
]
};

"macro below overrides that in egsnrc.macros. It is identical with"
"the exception of the return statement if IARG<0"
REPLACE {$AUSCALL(#);} WITH
{IARG={P1} ; IF (IAUSFL(IARG+1).NE.0) [CALL AUSGAB(IARG);]
IF(IARG<0) RETURN;} ;

"the following change the defaults for the EGSnrc input parameters"
"override the values in egsnrc.macros"

"Brems angular sampling= Simple"
REPLACE {$IBRDST-DEFAULT} WITH {0}
;

"Bound Compton scattering= Off"
REPLACE {$IBCMP-DEFAULT} WITH {0}
;

"Atomic relaxations= Off"
REPLACE {$IEDGFL-DEFAULT} WITH {0}
;

"Photoelectron angular sampling= Off"
REPLACE {$IPHTER-DEFAULT} WITH {0}
;

"Boundary crossing algorithm= PRESTA-I"
REPLACE {$BCA-ALGORITHM-DEFAULT} WITH {1}
;

"must agree with above"
REPLACE {$EXACT-BCA-DEFAULT} WITH {.false.}
;

"Macros to replace these large arrays to reduce static storage"

REPLACE {ECUT(#)} WITH {ECUT} ;
REPLACE {ecut(#)} WITH {ECUT} ;
REPLACE {ECUT/$MXREG} WITH {ECUT/1} ;
REPLACE {PCUT(#)} WITH {PCUT} ;
REPLACE {pcut(#)} WITH {PCUT} ;
REPLACE {PCUT/$MXREG} WITH {PCUT/1} ;
REPLACE {ESTEPR(#)} WITH {ESTEPR} ;
REPLACE {estepr(#)} WITH {ESTEPR} ;
REPLACE {ESTEPR/$MXREG} WITH {ESTEPR/1};
REPLACE {NOPLC(#)} WITH {NOPLC} ;
REPLACE {NOMSCT(#)} WITH {NOMSCT} ;
REPLACE {SMAXIR(#)} WITH {SMAXIR} ;
REPLACE {smaxir(#)} WITH {SMAXIR} ;
REPLACE {SMAXIR/$MXREG} WITH {SMAXIR/1};
REPLACE {ESAVE(#)} WITH {ESAVE} ;
REPLACE {IRAYLR(#)} WITH {IRAYLR} ;
REPLACE {iraylr(#)} WITH {IRAYLR} ;
REPLACE {IRAYLR/$MXREG} WITH {IRAYLR/1} ;
REPLACE {IEDGFL(#)} WITH {IEDGFL} ;
REPLACE {iedgfl(#)} WITH {IEDGFL} ;
REPLACE {IEDGFL/$MXREG} WITH {IEDGFL/1} ;
REPLACE {IPHTER(#)} WITH {IPHTER} ;
REPLACE {iphter(#)} WITH {IPHTER} ;
REPLACE {IPHTER/$MXREG} WITH {IPHTER /1} ;
REPLACE {IBCMP(#)} WITH {IBCMP} ;
REPLACE {ibcmp(#)} WITH {ibcmp} ;
REPLACE {ibcmp/$MXREG} WITH {ibcmp /1} ;
REPLACE {e_max_rr(#)} WITH {e_max_rr};
REPLACE {e_max_rr/$MXREG} WITH {e_max_rr /1};
REPLACE {i_do_rr(#)} WITH {i_do_rr};
REPLACE {i_do_rr/$MXREG} WITH {i_do_rr /1};

"The geometry common is only system dependent when PRESTA is invoked
REPLACE {;COMIN/GEOM/;} WITH {
; common/geom/
xbound($IMAX+1), "voxel x-boundaries "
ybound($JMAX+1), "voxel y-boundaries "
zbound($KMAX+1), "voxel z-boundaries "
xbound_min, "minimum x-boundary "
xbound_max, "maximum x-boundary "
ybound_min, "minimum y-boundary "
ybound_max, "maximum y-boundary "
zbound_min, "minimum z-boundary "
zbound_max, "maximum z-boundary "
medsur, "medium No for region outside the phantom "
dsurround(4), "medium thicknesses for region outside the
phantom "
IMAX, "number of cells in x-direction "
JMAX, "number of cells in y-direction "
KMAX, "number of cells in z-direction "
ijmax, "number of cells in x-y plane = IMAX*JMAX"
irmax, "number of regions = KMAX*ijmax + 1 "
howfarless; "set to .true. if DIST and DNEAR are only"
"to use outer boundaries of the phantom."
".false. otherwise."
"Type declarations"
real*4 xbound, ybound, zbound, xbound_min, xbound_max,
ybound_min,
ybound_max, zbound_min, zbound_max,dsurround;
integer medsur,IMAX, JMAX, KMAX, ijmax,irmax;
logical howfarless;
}

REPLACE {;COMIN/TIMEINFO/;} WITH {
; COMMON/TIMEINFO/
TIMEN, "stores current time"
DATEN, "stores current date"
DNTIME; "necessary for date and time routines"
$DECLARE_COMMON_TIMING_VARIABLES; "declared in machine.mortran"
}

REPLACE {$CTUnitNumber} WITH {45} "assign a unit number for the CT data"

REPLACE {$MXDATA} WITH {1} "To get over nrccaux(p).mortran
definition
REPLACE {$NBATCH} WITH {10} "Use 10 batches for restart features,
etc.
REPLACE {$MXDOS} WITH {7} "Max number of groups of regions to
analyse

"Some macros for facilitating access to boundaries and regions
"=============================================================

"Region number vs (i,j,k)
REPLACE {$IR(#,#,#)} WITH {(1 + {P1} + ({P2}-1)*IMAX + ({P3}-1)*ijmax)}

"Dose region number vs (i,j,k)
REPLACE {$IRD(#,#,#)} WITH {({P1} + ({P2}-1)*IMAX + ({P3}-1)*ijmax)}

"(i,j,k vs region number)
REPLACE {;$DECODEIR(#,#,#,#);} WITH {
"First parameter is input region, next 3 are decoded i,j,k"
;{P2}=mod({P1}-1,IMAX); IF({P2}=0) {P2}=IMAX;
{P4} = 1 + ({P1}-1-{P2})/ijmax;
{P3} = 1 + ( ({P1}-1-{P2}) - ({P4}-1)*ijmax)/IMAX;
}

"Generalized output to units 6 and 1
REPLACE {OUTPUT61#;#;} WITH {
{SETR A =@LG}
write(6,{COPY A}){P1};write(1,{COPY A}){P1};{COPY A}format{P2};
}
"Generalized output to unit 1
REPLACE {OUTPUT1#;#;} WITH { {SETR A =@LG}
write(1,{COPY A}){P1};{COPY A}format{P2};
}
"Generalized output to ioutgeom, used to be unit 17
REPLACE {OUTPUT17#;#;} WITH { {SETR A =@LG}
write(ioutgeom,{COPY A}){P1};{COPY A}format{P2};
}

"replaces CALL-HOWNEAR with a call to the HOWNEAR subroutine"
REPLACE {$CALL-HOWNEAR(#);} WITH {
CALL HOWNEAR({P1},X(NP),Y(NP),Z(NP),IR(NP));
}

REPLACE {;COMIN/SCORE/;} WITH {
;common/score/IWATCH,mxnp,
endep($MAXDOSE), endep2($MAXDOSE), temp2, planarefe,
planarefp,planarfe,planarfp,nestep,endep_tmp($MAXDOSE),
endep_last($MAXDOSE);
integer IWATCH, mxnp;
real endep_tmp;
REAL*8 endep, endep2, temp2,planarefe, planarefp, planarfe, planarfp;
$LONG_INT nestep;
$SHORT_INT endep_last;
}
"V> endep(I) I=1,IMAX*JMAX*KMAX + 1, +1 is for surrounding region
"V> note endep(I) is for geometric region I+1


REPLACE {;COMIN/PHSPFILE/;} WITH {;
COMMON/PHSPFILE/BEAM_SIZE,MODE_PHSP1,LATCH_OPT,

NCASE_PHSP,LATBIT,NBIT1,NBIT2,I_BIT_FILTER,NofREPEAT,ISMOOTH,
OUTCNT,NRCYCL,IPARALLEL,PARNUM,CYCLNUM;
real BEAM_SIZE;
INTEGER MODE_PHSP1,LATCH_OPT,NCASE_PHSP,LATBIT(20),NBIT1,NBIT2,
I_BIT_FILTER,NofREPEAT,ISMOOTH,OUTCNT,NRCYCL,IPARALLEL,PARNUM,CYCLNUM;
}
;

REPLACE {;COMIN/USER/;} WITH {
;COMIN/USER-PHOTON-SPLITTING,USER-RANGE-REJECTION/;
}

"V> COMMON/USER-PHOTON-SPLITTING/ Common used for photon splitting,
included
"V> ============================ in COMIN/USER/
"V>
"V>n_split = no. of times to split photons. Splitting is only in effect
"V> if n_split > 1

REPLACE{;COMIN/USER-PHOTON-SPLITTING/;} WITH {
;COMMON/USERPS/n_split;
$INTEGER n_split;
}

"V> COMMON/USER-RANGE-REJECTION/ Common used for range rejection,
included
"V> =========================== in COMIN/USER/
"V>
"V>IREJECT = 1 for range rejection, 0 otherwise
"V>ESAVE_GLOBAL = global upper energy for range rejection
"V>RANGE_ECUTRR(IMED) = range from ECUTIN to AE in medium IMED (not
"V> scaled for non-default density)

REPLACE{;COMIN/USER-RANGE-REJECTION/;} WITH {
;COMMON/USERRR/ESAVE_GLOBAL,RANGE_ECUTRR($MXMED),IREJECT;
$REAL ESAVE_GLOBAL,RANGE_ECUTRR;
$INTEGER IREJECT;
}

"Define variables used in the new version of $SELECT-PHOTON-MFP to"
"allow the n_split option"
APPEND
{;
$REAL d_eta,eta_prime,dpmfp_old,
x_save,y_save,z_save,u_save,v_save,w_save,
e_save,wt_save,a_survive;
$INTEGER ir_save,ip,i_split,latch_save,i_survive_s;
;} TO {$DEFINE-LOCAL-VARIABLES-PHOTON;}
;

APPEND {;COMIN/SCORE/;} TO {$COMIN-PHOTON;} "necessary for IWATCH"
"output for n_split option"

APPEND {;COMIN/GEOM/;} TO {$COMIN-ELECTR;} "necessary to use range
rejection"
"with howfarless on"

$HAVE_C_COMPILER(#);

#ifdef HAVE_C_COMPILER;
"append variables that allow us to keep track of min, max particle"
"in a phase space source chunk, SOURCE common block is defined in"
"srcxyznrc.macros"
APPEND {;COMMON/SOURCE_FORPARALLEL/nnphsp_max, nnphsp_min;
$INTEGER nnphsp_max, nnphsp_min; } TO
{;COMIN/SOURCE/;}

#endif;

" start of coding ""toc:

$IMPLICIT-NONE;

;COMIN/ BOUNDS,BREMPR,ELECIN,GEOM,MEDIA,MISC,PHSPFILE,SCORE,SOURCE,
STACK,THRESH,USEFUL,RANDOM,TIMEINFO,ET-Control,CH-Steps,USER,EPCONT,EGS-
IO,
RWPHSP/;

$LONG_INT NCASE,IHSTRY,tempdiv,jcase,compensated_NCASE;
"compensated_NCASE for source 20 only"
integer idosl($MXDOS),idosu($MXDOS),jdosl($MXDOS),jdosu($MXDOS),
kdosl($MXDOS),kdosu($MXDOS),IZSCAN($MXDOS),idgrp,n,j,i,
maxx,maxy,maxz,maxbd,ngroup,igroup,nn,nnn,in,IL,IU,JL,JU,KL,KU,
medtmp,k,irl,ieof,IOUT,lnblnk1,IXXIN,JXXIN;
integer IRSECT, "should be be part of common block--something with
presta"
ihist, "looping variable"
idose, "loops over dose regions for analysis"
nperpg, "number of sets of dose curves per page"
ipage, "page counter"
ios, "1 if there is an error on opening ct phantom file"
irin, "first region of source particle"
temppar, "holds IPARALLEL when calculating NRCYCL"
jj, "loop counter"
idd, "unit number for .3ddose file"
iorstrt, "unit number for the .egsdat file"
ioutgeom, "unit number for .egsgeom file"
ioutgph, "unit number for .egsgph file"
ioutphant, "unit no. for output .egsphant file"
egs_open_file,
egs_open_datfile,
ihowfarless, "set to 1 to calc. DIST, DNEAR against outer
boundaries"
"of phantom. Set to 0 for normal transport."
i_par_temp; "stores value of i_parallel"
$REAL xin,yin,zin, "x,y,z position of source particle"
uin,vin,win, "u,v,w of source particle"
weight,etotin,
etot, "total energy, used in stat analysis at end of run"
mindelX,mindelY,mindelZ; "min. width of X,Y,Z voxels, used to"
"set min. step length when howfarless
used"
real amass,tcpuold,ECUTIN,PCUTIN,ESTEPM($MXMED),width,
rhotmp,ECUTL,PCUTL,TIMMAX,SMAX,
timcpu, "keeps track of total CPU time"
ainflu, "total number of incident particles"
minrhor, "min density of CT phantom"
maxrhor; "max density of CT phantom"
character*256 PhantFileName, "name of file holding CT phantom data"
parname; "name of .pardose file"
REAL XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX,
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN,
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN; "used to output"
"rep of source plane"
"to .egsgeom file"
INTEGER IRESTART,ibatch,ncaseold;
character title(80);
REAL BATCHT, "T>used by timing
TIMEB, "T>used by timing routines
SECNDS; "T>used by $SET_ and
$INITIALIZE_ELAPSED_TOTAL_TIME;

"Correlated sampling no longer supported with history by history
statistics"
"$Corr_Vars; mah 09/05/95 To declare CRFLAG ";

"CT Phantom Variable Declaration."
Integer CTError; " Declare error flag variable."

Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
"variables for zeroing doses with >50% error and in air in the .3ddose
file"
INTEGER zerodose, "set to $DOSEZERO from dosxyz_user_macros.mortran"
zerocount, "keeps track of how many doses zeroed"
MAX20, "set to 1 to print summary of max 20 doses"
tempmax20, "used in conjunction with MAX20"
doseprint, "set to 1 for full dose output to .egslst"
"(CT data only)"
IDAT, "0 => store intermediate data"
"1 => do not store data"
"2 => store data but only at end of run"
zeroairdose, "set to 1 to zero air dose in .3ddose file (CT data
"only)"
IPHANT; "set to 1 to output a .egsphant file (non-CT data)"

"variables for recording total elapsed clock time"
INTEGER NETADJ; "keeps track of how many times elapsed time
adjusted"
REAL ETIMETOT; "T>stores total elapsed time"

"variables for calculating range from ECUTIN to AE for range rejection"
$INTEGER LELKE, lelktmp, lelec;
$REAL EKEI,ELKEI,fedep,elktmp,dedxmid,aux;

"variables related to calculating dose statistics"
REAL*8 temp;
$LONG_INT nhist_old; "stores previous value of nhist"

$INTEGER n_repeat,i_repeat;

"New parallel processing implementation. Only used if there is a
" working C compiler.

external combine_results;

#ifdef HAVE_C_COMPILER;
$REAL part_dose, part2_dose, current_result, current_uncertainty;
$LONG_INT n_run,n_tot,n_last,n_left,other_num_1,other_num_2;
$INTEGER n_job,p_per_phsp_chunk,n_run_chunk;
$LOGICAL first_time;
#endif;

$LOGICAL is_finished;

" start of executable code ""toc:

$DECLARE_TIMING_VARIABLES;
"Above declares cput0, cput1,cput2"
"cput0 is cpu time at start of execution"
"cput1 is cputime at start of simulations"
"cput2 is cputime when asked for so elapsed cpu is cput2-cput0 or -cput1"


call egs_init; "initialize EGSnrc system"

$INITIALIZE_ELAPSED_TOTAL_TIME;
$SET_ELAPSED_CPUTIME(cput0);
"above initialized in machine.mortran"

"define unit numbers for output files"
IOUT=1; "the unit number for the .egslst file
idd=3; "unit number for .3ddose file
iorstrt=4; "unit number for the .egsdat file
ioutgeom=17; "unit number for .egsgeom file
ioutgph=13; "unit number for .egsgph file
ioutphant=18; "for output .egsphant file

OUTPUT;(/' Begin execution with large arrays being zeroed'/
' This is only needed for Linux g77 compiler - comment'/
' this code near the top of dosxyznrc.mortran if you are'/
' not using a linux g77 compiler'/);

DO i = 1, $MXREG [MED(i) = 1;RHOR(i) =0.;]
"above duplicates a statement in egsnrc.mortran BLOCK DATA"
"It can be commented out for everything except g77 and fort77"
"compilers which cannot handle such huge arrays."
"The corresponding stmts in the BLOCKDATA are deleted via"
"the dosxyznrc.configuration file when the fort77 or g77 compilers"
"are being used."


zeroairdose = 0; "can only be set to 1 in CT inputs"
MAX20=0;
IPHANT=0;
doseprint=1; "assume we want to output doses to .egslst unless using CT"


CALL DATETIME(1);
OUTPUT61 TIMEN, DATEN; (' ',79('*')/
' NRCC/UW EGSnrc user-code DOSXYZnrc',
' ($Revision: 1.50 $ last edited $Date: 2013/02/13 21:57:55 $)'/
' ON '$MACHINE' ',T60,$TIMEN_FORMAT,1X,$DATEN_FORMAT / ' ',79('*')/
' **',T79,'**'/
' **',T38,'DOSXYZnrc',T79,'**'/
' **',T34,'Z pronounced zed',T79,'**'/ ' **',T79,'**'/
' **',T10,'Code developed at the National Research Council of
Canada',
' and',T79,'**'/
' **',T15,'University of Wisconsin as part of the OMEGA project',
T79,'**'/ ' **',T79,'**'/
' **',T15,
'This is $Revision: 1.50 $ last edited $Date: 2013/02/13 21:57:55 $',
T79,'**'/ ' **',T79,'**'/ 1X ,79('*'));
OUTPUT61
$MXMED,$MXSTACK,$IMAX,$JMAX,$KMAX,$MAXDOSE,$DOSEZERO;
(/' The following parameters may be adjusted in
dosxyz_user_macros.mortran'/
' $MXMED: Max number of media:',I3,/
' $MXSTACK: Max stack size:',I10/
' $IMAX,etc: Max dose scoring regions in x,y,z directions:', 3I5/
' $MAXDOSE: Max dose scoring regions consistent with above:',I7/
' $DOSEZERO(=',I1,') 1=> all doses with uncert > 50% are zeroed',
' in .3ddose file'/);
OUTPUT61 $INVDIM, $NENSRC;
(/' The following parameters may be adjusted in srcxyz.macros'/
' $INVDIM: number of elements in inverse CPD for input energy spectra
=', I5/
' $NENSRC: number of bins in input energy spectrum =', I5/);

OUTPUT61;(1x,79('=')/1x,79('-')//' Title: ',$);
INPUT title;(80a1);
OUTPUT61 Title;(' ',80a1/1x,79('-')/1x,79('=')//);

"Step 2 Pre-hatch call initialization ""toc:
"======================================

OUTPUT61 $MXMED;(' Number of media (min = 1, max =',I4,', 0 => CT data):
',$);
read(5,'(I10)') NMED;
IF(NMED > $MXMED ) [ NMED= 1; "DEFAULTS TO 1 MEDIUM" ]
OUTPUT61 NMED;(' ',t10,i7);

"------------------------------------------------------------------------
----"
IF(NMED = 0)[ "Input data from CT data file as processed by the code
ctcreate"
"------------------------------------------------------------------------
----"
OUTPUT61;
(' Input the full name of the file containing the CT phantom created
'/
' using ctcreate '/
' : ',$);
read(5,'(A256)') PhantFileName;
OUTPUT61 PhantFileName(:lnblnk1(PhantFileName));(A);


Open($CTUnitNumber,file=PhantFileName,status='old',access='sequential',
iostat=ios);
IF(ios~=0)[
OUTPUT61;(/' The CT phantom file does not exist.'/
' Try again. ');
STOP;
]

OUTPUT61;(/' CT Phantom summary: ');

"now start reading the info from the file"
"read number of media"
read($CTUnitNumber,'(i2)')NMED;
OUTPUT61 NMED;(/' NMED = ',i2);
"media names"
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
OUTPUT61;(/' media:');
DO n=1,NMED[
read($CTUnitNumber,'(24a1)') (media(j,n),j=1,24);
OUTPUT61 (media(j,n),j=1,24);(' ',24a1);
]
"estepe and SMAX"
read($CTUnitNumber,*) (ESTEPM(i),i=1,NMED);
OUTPUT61 (ESTEPM(i),i=1,NMED);
(/' Dummy values of (ESTEPM(i),i=1,NMED)'/
' : ',10f10.3);
"IMAX,JMAX,KMAX"
read($CTUnitNumber,'(3i5)') IMAX,JMAX,KMAX;
OUTPUT61 IMAX,JMAX,KMAX;
(/' IMAX, JMAX, KMAX : ',3i4);
IF (IMAX > $IMAX | JMAX > $JMAX | KMAX > $KMAX)[
OUTPUT61; (/' ***ERROR:'/
' X, Y or Z dimension(s) of CT phantom > maximum allowed in DOSXYZnrc
'/
' Change $IMAX, $JMAX, $KMAX in dosxyz_user_macros.mortran and
recompile.');
STOP;
]

" IJMAX and irmax needs to be set. "
ijmax = IMAX*JMAX;
irmax =1 + IMAX*JMAX*KMAX;

"boundaries"
read($CTUnitNumber,*) (xbound(i),i=1,IMAX+1);
read($CTUnitNumber,*) (ybound(j),j=1,JMAX+1);
read($CTUnitNumber,*) (zbound(k),k=1,KMAX+1);
"calculate min and max boundaries"
xbound_min = xbound(1); xbound_max = xbound(IMAX+1);
ybound_min = ybound(1); ybound_max = ybound(JMAX+1);
zbound_min = zbound(1); zbound_max = zbound(KMAX+1);
OUTPUT61 xbound_min,xbound_max,ybound_min,ybound_max,
zbound_min,zbound_max;
(/' x range : ',F12.5,' - ',F12.5,' cm'/
' y range : ',F12.5,' - ',F12.5,' cm'/
' z range : ',F12.5,' - ',F12.5,' cm');
"input the media numbers"
DO k=1,KMAX[
DO j=1,JMAX[
read($CTUnitNumber,:medformat:) (med($IR(i,j,k)),i=1,IMAX);
]
read($CTUnitNumber,*);
]
:medformat: FORMAT($IMAXi1);
"input the densities"
maxrhor=0.;
minrhor=999.;
DO k=1,KMAX[
DO j=1,JMAX[
read($CTUnitNumber,*) (rhor($IR(i,j,k)),i=1,IMAX);
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
DO i=1,IMAX[
IF(rhor($IR(i,j,k)) > maxrhor)[maxrhor=rhor($IR(i,j,k));]
IF(rhor($IR(i,j,k)) < minrhor)[minrhor=rhor($IR(i,j,k));]
]
]
read($CTUnitNumber,*);
]
OUTPUT61 minrhor,maxrhor;
(/' Densities range from ',F12.5,' - ',F12.5,' g/cc');

close($CTUnitNumber);

"now read in transport parameters"
OUTPUT61;(/' ECUTIN,PCUTIN,(SMAX--DUMMY INPUT): ',$);
read(5,'(3F15.0)') ECUTIN,PCUTIN,SMAX;

OUTPUT61 ECUTIN,PCUTIN,SMAX;(/t10,3f10.3);

"now some output parameters"
OUTPUT61;
(/' Input zeroairdose (1 to zero dose in air in .3ddose file;
0[default]'/
' to not zero this dose), doseprint (1 for full dose output in
.egslst;'/
' 0[default] otherwise), MAX20 (1 to print out summary of 20
highest'/
' doses; 0[default] to not print this summary)'/
' : ',$);
READ(5,'(3I5)')zeroairdose,doseprint,MAX20;
IF(zeroairdose ~=1) zeroairdose=0; "default value"
IF(MAX20 ~= 1) MAX20=0;
IF(doseprint ~= 1) doseprint=0;
OUTPUT61 zeroairdose,doseprint,MAX20;(3I5);

idgrp=1;
idosl(idgrp)=1; idosu(idgrp)=IMAX;
jdosl(idgrp)=1; jdosu(idgrp)=JMAX;
kdosl(idgrp)=1; kdosu(idgrp)=KMAX;
IZSCAN(idgrp)=1;
] "end of block reading in CT data


ELSE [ " Read in geometric data as defined by user as opposed to CT data"

DO n=1,NMED [
OUTPUT61 n;(' Medium',i3,': ',$);
INPUT (media(j,n),j=1,24);(24a1);
OUTPUT61 (media(j,n),j=1,24);(' ',t20,24a1);
]
med(1)=0;
DO n=2,$MXREG [med(n)=1;] "ie Everything the first medium"
"Can be changed below on a region by region
basis"

Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
OUTPUT61;(/' ECUTIN,PCUTIN,(ESTEPE,SMAX--DUMMY INPUTS): ',$);
read(5,'(2F15.0,30F10.0,F15.0)')
ECUTIN,PCUTIN,(ESTEPM(i),i=1,NMED),SMAX;

OUTPUT61 ECUTIN,PCUTIN,(ESTEPM(i),i=1,NMED),SMAX;(/t10,13f10.3);

"Step 3 Initialization for howfar ""toc:
"==================================

" Input x, y, z boundaries

"First define a macro which will be used for each axis in turn
REPLACE {$GET-#-BOUNDARIES;} WITH {
;mindel{P1}=1.e20;
IF(max{P1} > 0) [
mindel{P1}=1.e20;
IF(max{P1} > maxbd)[
OUTPUT61 maxbd;
(t15,'***ERROR:'/
t15,'number of regions > max allowed (',i5,')');
STOP;
]
"Pick up boundaries one at a time"
DO i=1,max{P1} [
OUTPUT61 i;(' Small boundary for region(',i3,') ',$);
read(5,'(F15.0)') {P1}bound(i);
IF( (i ~=1 ) & ( {P1}bound(i) <= {P1}bound(i-1) )) [
OUTPUT61;(' *** Boundary out of order ***');
]
OUTPUT61 {P1}bound(i);(' ',t10,f12.3);
IF(i>=2 & {P1}bound(i)-{P1}bound(i-1)<mindel{P1})[
mindel{P1}={P1}bound(i)-{P1}bound(i-1);
]
]
OUTPUT61 max{P1};(' Outer boundary for region(',i3,') ',$);
read(5,'(F15.0)') {P1}bound(max{P1} + 1);
OUTPUT61 {P1}bound(max{P1}+1);(' ',t10,f12.3);
IF({P1}bound(max{P1}+1)-{P1}bound(max{P1})<mindel{P1})
mindel{P1}={P1}bound(max{P1}+1)-{P1}bound(max{P1});
]
ELSE [
"max(P1) < 0, Input groups of regions"
"Assume maxbd set to $IMAX, $JMAX or $KMAX"
OUTPUT61;(' Initial boundary: ',$);
read(5,'(F15.0)') {P1}bound(1);
OUTPUT61 {P1}bound(1);(' ',f12.3);
ngroup = - max{P1}; "Number of groups in this direction"
max{P1} = 0;
DO igroup = 1,ngroup [
OUTPUT61;
(' Width in this group, number of regions in group:
',$);
read(5,'(F15.0,I10)') width,nn;
IF(nn<=0) [nn=1;];
IF(width<=0.0)[width=1.0;]
IF(width<mindel{P1})mindel{P1}=width;
OUTPUT61 width,nn;(' ',f12.3,i5);
nnn = min(nn,maxbd-max{P1}); "Ensure do not add too many
regions"
IF(nnn ~= 0) [
DO in = max{P1}+1,max{P1}+nnn [
{P1}bound(in+1) = {P1}bound(in)+width;
]
]
IF(nn ~= nnn)[
OUTPUT61 maxbd;
(t15,'***ERROR:'/
t15,'number of regions > max allowed (',i5,')');
STOP;
]
max{P1} = max{P1}+nnn;
]
"Must set IMAX etc after call to this macro"
OUTPUT61 ({P1}bound(i),i=1,max{P1}+1);('
Boundaries'/(6f12.3));
]
}

OUTPUT61 $IMAX,$JMAX,$KMAX;
(/' # regions in x (max=',I4,'),y (max=',I4,'),z (max=',I4,')
directions'/
' (if<0,implies # groups of reg), IPHANT (1 to output a
.egsphant'/
' file for dosxyz_show, 0[default] to not output this file)'/
' : ',$);
read(5,'(4I10)') maxx,maxy,maxz,IPHANT;

IF(maxx = 0) maxx=1; IF(maxx>$IMAX) maxx=$IMAX;
IF(maxy = 0) maxy=1; IF(maxy>$JMAX) maxy=$JMAX;
IF(maxz = 0) maxz=1; IF(maxz>$KMAX) maxz=$KMAX;
OUTPUT61 maxx,maxy,maxz,IPHANT;(' ',4i6);

IF(IPHANT=1)[
OUTPUT; (//' Will output a .egsphant file to display isodose
contours'/
' with dosxyz_show.'//);
]

maxbd=$IMAX;
OUTPUT61; ( / ' Input boundaries in the x-direction'/
' -----------------------------------');
$GET-X-BOUNDARIES; IMAX=maxx;
maxbd=$JMAX;
OUTPUT61; ( / ' Input boundaries in the y-direction'/
' -----------------------------------');
$GET-Y-BOUNDARIES; JMAX=maxy;
maxbd=$KMAX;
OUTPUT61; ( / ' Input boundaries in the z-direction'/
' -----------------------------------');
$GET-Z-BOUNDARIES; KMAX=maxz;

"Determine boundary limits - to be used by the source routine
xbound_min = xbound(1); xbound_max = xbound(IMAX+1);
ybound_min = ybound(1); ybound_max = ybound(JMAX+1);
zbound_min = zbound(1); zbound_max = zbound(KMAX+1);

ijmax = IMAX*JMAX; irmax =1 + IMAX*JMAX*KMAX;

OUTPUT61 irmax;(/' Total # regions including exterior =',i10);
IF(irmax > $MXREG) [
OUTPUT61;(/' *** That is too many regions ***'//);
stop ' *** Stopping because too many regions asked for ***';
]

" Get density or material for each region
" rhor = 0.0 means use default density for the material in region

OUTPUT61;
(/' Input groups of regions for which density and medium are not
defaults');
LOOP [
OUTPUT61;(' Lower,upper i, j, k, MEDIUM, DENSITY',$);
read(5,'(7I10,F15.0)') IL,IU,JL,JU,KL,KU,MEDTMP,RHOTMP;
IF( (IL = 0) & (IU = 0) )["Blank line, so quit"
OUTPUT61;(/' Found blank line => end of this input');
EXIT;
]
"Check IL etc are ok
IF((IL <= 0)|(IL > IMAX)) IL = 1; IF((IU < IL)|(IU > IMAX)) IU =
IMAX;
IF((JL <= 0)|(JL > JMAX)) JL = 1; IF((JU < JL)|(JU > JMAX)) JU =
JMAX;
IF((KL <= 0)|(KL > KMAX)) KL = 1; IF((KU < KL)|(KU > KMAX)) KU =
KMAX;
IF((medtmp < 0)|(medtmp > NMED)) medtmp = 1;

OUTPUT61 IL,IU,JL,JU,KL,KU,MEDTMP,RHOTMP;
(' ',3('(',i3,i4,')'), i4, f10.3);
DO i=Il,IU [
DO j=JL,JU [
DO k=KL,KU [
irl = $IR(i,j,k);
rhor(irl)=rhotmp;
med(irl)=medtmp;
]
]
]
]

OUTPUT61;
(//' Input groups of regions for which ECUT and PCUT are not
defaults');
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
OUTPUT61;(' NB This option is disabled, just input 8 zeros.');
LOOP [
OUTPUT61;(' Dummy values of lower,upper i, j, k, ECUT, PCUT',$);
read(5,'(6I10,2F15.0)') IL,IU,JL,JU,KL,KU,ECUTL,PCUTL;
IF( IL = 0 & IU = 0)[
OUTPUT61;(/' Found blank line => end of this input');
EXIT;"Blank line, so quit"
]
OUTPUT61 IL,IU,JL,JU,KL,KU,ECUTL,PCUTL;
(' ',3('(',i3,i4,')'),2(f10.3,1x));
]

"Step 4 Initialization for ausgab ""toc:
"=================================

"Initially just ask for ranges of regions over which the dose to be
output
OUTPUT61; (//' Enter 8 numbers on one line'/
' 3 pairs defining lower,upper x,y,z indicies of dose
regions'/
' for which results are to be output'/
' IZSCAN: non-zero for z-scan/page'/
' MAX20: if any one = 1, output summary of max 20
doses.'/
' end signaled by first pair both zero'/
' for no dose printed, MAX20 is still read from first
line'/);
idgrp=0;
tempmax20=0;
LOOP [
idgrp=idgrp+1;
read(5,'(8I10)')
idosl(idgrp),idosu(idgrp),jdosl(idgrp),jdosu(idgrp),
kdosl(idgrp),kdosu(idgrp),IZSCAN(idgrp),tempmax20;
IF((idosl(idgrp) = 0)&(idosu(idgrp) = 0))["Quit when get blank
line"
OUTPUT61;(' Found blank line => end of this input');
IF(idgrp = 1) ["was on first line of input"
IF(tempmax20 = 1 )[
MAX20 = 1;
OUTPUT61; (' MAX20 =1 so will print largest 20 doses
only');
]
ELSE [
OUTPUT61;(' No doses will be output to egslst file');
]
]"end of block for defaults if no input"
EXIT; "exit from loop - note can leave all blank=> no output"
]
"The first two are not zero, so set defaults for all others"
"to span whole range if not explicitly input"
IF(idosl(idgrp)<=0) idosl(idgrp)=1;
IF(idosu(idgrp)<=0 |idosu(idgrp)>=IMAX) idosu(idgrp)=IMAX;
IF(jdosl(idgrp)<=0)jdosl(idgrp)=1;
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
IF(jdosu(idgrp)<=0 |jdosu(idgrp)>=JMAX) jdosu(idgrp)=JMAX;
IF(kdosl(idgrp)<=0)kdosl(idgrp)=1;
IF(kdosu(idgrp)<=0 |kdosu(idgrp)>=KMAX) kdosu(idgrp)=KMAX;
IF(tempmax20=1) MAX20=1;
OUTPUT61 idosl(idgrp),idosu(idgrp),jdosl(idgrp),jdosu(idgrp),
kdosl(idgrp),kdosu(idgrp),IZSCAN(idgrp),tempmax20;
(t5,3(i6,i4),i6,i6);
]
idgrp=idgrp-1;

] "end of users input to directly specify phantom as opposed to CT input"

"Step 5 Determination of incident particle parameters ""toc:
"====================================================

dose_stat=0; "assume non phsp source or we can get nhist from phsp
source"

"Define source
call srcinput(ieof);

OUTPUT61;
(//'
NCASE,IWATCH,TIMMAX,INSEED1,INSEED2,BEAM_SIZE,ISMOOTH,IRESTART,IDAT,'/
' IREJECT,ESAVE_GLOBAL,NRCYCL,IPARALLEL,PARNUM,n_split,ihowfarless'/
' : ',$);
read(5,'(2I12,F15.0,2I10,F15.0,4I10,F15.0,5I10)')
NCASE,IWATCH,TIMMAX,IXXIN,JXXIN,BEAM_SIZE,ISMOOTH,IRESTART,IDAT,IREJECT,
ESAVE_GLOBAL,NRCYCL,IPARALLEL,PARNUM,n_split,ihowfarless;

IF(n_split<=1 & e_split>1)[
OUTPUT;
(//' ***Warning: Electron splitting on with no photon splitting.'/
' Electron splitting will not be done.'//);
]


IF(TIMMAX<=0.0)[TIMMAX = 0.99;"Default 1 hour"]

IF (IWATCH = 0 & NCASE < 100)[NCASE=100;]
IF (NCASE/$NBATCH = 0)[
NCASE=$NBATCH;
]
jcase = NCASE/$NBATCH; NCASE = jcase*$NBATCH;

"Make sure the IXXIN and JXXIN values will not be overridden by defaults"
" and warn user if they will in case they expect to start independent
runs"
IF((IXXIN <= 0) | (IXXIN > 31328)) [
OUTPUT; (' First RN seed outside allowed range and default value
set');
IXXIN=1802;
]
IF((JXXIN < = 0) | (JXXIN > 30081)) [
OUTPUT; (' Second RN seed outside allowed range and default value
set');
JXXIN=9373; "sets Marsaglia default"
]

IF( i_parallel > 0 ) JXXIN = JXXIN - 1 + i_parallel;

IF(BEAM_SIZE <= 0.0) BEAM_SIZE=100.;

IF(IRESTART < 0 | IRESTART > 4)IRESTART=0;"SET UP THE DEFAULT VALUE"

IF(IPARALLEL<0) IPARALLEL=0;
IF(PARNUM<0) PARNUM=0;

#ifdef HAVE_C_COMPILER;
;
IF(IPARALLEL>1 & n_parallel>0)[
OUTPUT IPARALLEL, n_parallel;
(/' You have set IPARALLEL in the input file to ',I4,/
' But you are also running a C compiled code with
n_parallel=',I4,/
' IPARALLEL will be reset to 1, and control of the parallel run
'/
' will be from the code.'/);
IPARALLEL=1;
]
#endif;

IF(IPARALLEL>1 & PARNUM>IPARALLEL & (isource = 2 | isource = 8 |
isource = 20))[
OUTPUT; (//' ****WARNING:'/
' PARNUM is > IPARALLEL '/
' It must be in the range 1<=PARNUM<=IPARALLEL if you'/
' want to partition a phase space source.'/
' PARNUM will be set to 0 for now, and the phase space'/
' source will not be partitioned.'//);
PARNUM=0;
]

"necessary for calling srcinit with a BEAM simulation source if pprocess"
"is being used"
IF(IPARALLEL>1 & PARNUM>0)i_parallel=PARNUM;

IF(NRCYCL <= 0 & (isource=2 | isource=8))[
"automatically calculate NRCYCL"
IF(iqin=1 | enflag=3)["cannot determine nrcycl apriori"
NRCYCL=0;
]
ELSE[
IF(iqin=0)[
tempdiv=nphist;
]
ELSEIF(iqin=-1)[
tempdiv=nshist-nphist;
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
]
ELSE["all particles"
tempdiv=nshist;
]
IF(IPARALLEL>1 & PARNUM>0)[
temppar=IPARALLEL;
]
ELSE[
temppar=1;
]
IF(NINT(dble(temppar*NCASE)/dble(tempdiv))<=1)[
"prevents undersampling of ph-sp data in case NCASE is only"
"slightly > tempdiv and also makes sure we do not recycle if"
"NCASE<tempdiv"
NRCYCL=0;
]
ELSEIF(MOD(temppar*NCASE,tempdiv)=0)[
"NCASE is an exact multiple of tempdiv"
NRCYCL=(temppar*NCASE)/tempdiv-1;
]
ELSE[
NRCYCL=(temppar*NCASE)/tempdiv;
]
]
]

IF(ihowfarless<=0 | ihowfarless>1)[
ihowfarless=0;
howfarless=.false.;
]
ELSE[
howfarless=.true.;
iausfl(6)=1;"call ausgab after particle transport"
iausfl(16)=1;"before pair production"
iausfl(18)=1;"before compton"
iausfl(20)=1;"before photoelectric"
iausfl(24)=1;"before rayleigh"
]

"set initial energy - used only for enflag=0 (mono-energetic source)"
" reset for other sources elsewhere"
IF(iqin = 0)[etotin = ein;] ELSE [etotin = ein + 0.511;]

OUTPUT61 NCASE,IWATCH,TIMMAX,IXXIN,JXXIN,BEAM_SIZE,ISMOOTH,IRESTART,IDAT,
IREJECT,ESAVE_GLOBAL,NRCYCL,IPARALLEL,PARNUM,n_split,ihowfarless;
(/i12,i4,f7.2,2i10,f7.2,i7,i5,i4,i4,F7.2,i4,i4,i4,i4,i4/);
IF(IRESTART=1)[
OUTPUT61;(/' Above RNG seeds will be replaced by those from previous
run.');
]

$INITIALIZE RNG USING IXXIN AND JXXIN;


"========================================================================
=="
" Moved here by Ernesto Mainegra-Hing Dec 2011
"
" Opening same pegs4 file with two different units gives an error in gcc
"
" 4.5.1 and 4.6.2. This occurs with a BEAM source when the pegs4 file is
"
" the same as for the dosxyz simulation.
"
"========================================================================
=="
"Step 6 Get EGSnrc transport parameters ""toc:
"========================================================================
=="

"set skin depth to 0 here. If skindepth is omitted or not input
properly"
"this will get reset to BLCMIN if BCA=PRESTA-I, or 3 if BCA=EXACT by "
"subroutine mscati. If value is input properly, then it will take on
that"
"value. If value is input properly, but out of range, then skindepth"
"will be set to 3, regardless of the BCA"
skindepth_for_bca=0;

call get_transport_parameter(-1);

"now check to see if ECUTIN>ECUT or PCUTIN>PCUT"
IF(ECUTIN>ECUT)[ "reset ecut in all regions to ecutin"
OUTPUT ECUT;
(/' ****WARNING****'/
' ECUTIN > ECUT input in EGSnrc parameters ( ',F10.4,' MeV).'/
' ECUT defaults to ECUTIN.'/);
ECUT=ECUTIN;
]
ELSE[
ECUTIN=ECUT;
]
IF(PCUTIN>PCUT)[ "reset ecut in all regions to ecutin"
OUTPUT PCUT;
(/' ****WARNING****'/
' PCUTIN > PCUT input in EGSnrc parameters ( ',F10.4,' MeV).'/
' PCUT defaults to PCUTIN.'/);
PCUT=PCUTIN;
]
ELSE[
ECUTIN=ECUT;
]

IF((~exact_bca | transport_algorithm=$PRESTA--I) & SMAXIR=1e10)[
"if we get to here with the default value of SMAX (1e10), then"
"assume that this is because the SMAX input does not exist, the user"
"did not input it properly or the value was out of range and we want to"
"set it to the PRESTA-I default of 5"
SMAXIR=5.;
]

"Just in case we need this, set it to the EGSnrc value"
smax = smaxir;

"Step 7 HATCH call ""toc:
"===================

OUTPUT; ( / / ' Call hatch'/ ' ----------'/);
call hatch;

call show_transport_parameter(6); "output egsnrc parameters to the
screen"
call show_transport_parameter(iout); " print the transport parameter
settings"
" settings on unit IOUT"
"========================================================================
=="
"End of block added by Ernesto Mainegra-Hing Dec 2011"
"========================================================================
=="

"call this here so that BEAM simulation source can get i_parallel if"
"pprocess is used"
call srcinit(weight);

IF(isource=20)[
compensated_NCASE = (dble(NCASE)/dble(survival_ratio)+0.5);
jcase = (NCASE+$NBATCH/2)/$NBATCH; NCASE = jcase*$NBATCH;
" the factors of 1/2 are added to round up"
IF(NRCYCL <= 0)[
IF(iqin=1 | enflag=3)["cannot determine nrcycl apriori"
NRCYCL=0;
]
ELSE[
IF(iqin=0)[
tempdiv=nphist;
]
ELSEIF(iqin=-1)[
tempdiv=nshist-nphist;
]
ELSE["all particles"
tempdiv=nshist;
]
IF(IPARALLEL>1 & PARNUM>0)[
temppar=IPARALLEL;
]
ELSE[
temppar=1;
]

IF(NINT(dble(temppar*compensated_NCASE)/dble(tempdiv))<=1)[
"prevents undersampling of ph-sp data in case NCASE is"
"only slightly > tempdiv and also makes sure we do not"
"recycle if NCASE<tempdiv"
NRCYCL=0;
]
ELSEIF(MOD(temppar*compensated_NCASE,tempdiv)=0)[
"NCASE is an exact multiple of tempdiv"

NRCYCL=dble(temppar*compensated_NCASE)/dble(tempdiv)-1;
]
ELSE[
NRCYCL=(temppar*compensated_NCASE)/dble(tempdiv);
]
]
]
]

IF( isource = 2 | isource = 8 | isource = 20)["phase space source"
IF(NRCYCL>0)[
OUTPUT NRCYCL;
(' Will recyle each phase space particle ',I4,' times before going
on '/
' to next particle.');
]
IF( ISMOOTH = 1) [
OUTPUT;(/' Will redistribute phase space particles if phase space
file'/
' restarted and/or individual particles recycled');
]
ELSE [OUTPUT;(' Restarted phase space files and recycled particles are
not'/
' redistributed');
]
]

IF(IRESTART = 0) [OUTPUT;(/' Starting a new calculation');]
ELSEIF(IRESTART = 1) [OUTPUT;(/' Restarting from a previous run');]
ELSEIF(IRESTART = 2) [OUTPUT;(/' Just create input file and exit');]
ELSEIF(IRESTART = 3) [OUTPUT;(/' Read in stored data and analyse');]
ELSEIF(IRESTART = 4) [OUTPUT;(/' Recombining parallel runs');]
ELSE [ IRESTART = 0; OUTPUT;(/' IRESTART set to 0, start new caln');]

IF(IDAT = 0) [OUTPUT;(/' Store intermediate files for each batch');]
ELSEIF (IDAT = 1) [OUTPUT;(/' Do not store intermediate files at all');]
ELSEIF (IDAT = 2) [OUTPUT;(/' Store data files at end of run only');]
ELSE [IDAT = 0; OUTPUT;(/' Store intermediate files for each batch');]

IF(IPARALLEL>1)[
OUTPUT;
(/' Will output binary .pardose files for later analysis with
combinedose.'/
' With this set, the egslst files do not contain dose listings
either.');
]

"Output the cube to the egsgeom file if IWATCH=4"
IF(IWATCH=4)[
"open the .egsgeom file, .egsgph is opened by WATCH routine"
ioutgeom=egs_open_file(ioutgeom,0,1,'.egsgeom');
OUTPUT17 1,'QUAD', xbound_min,ybound_min,zbound_min,
xbound_min,ybound_max,zbound_min,
xbound_max,ybound_max,zbound_min,
xbound_max,ybound_min,zbound_min; (' ',I1,A4,12(F7.2,','));
OUTPUT17 1,'QUAD', xbound_min,ybound_min,zbound_max,
xbound_min,ybound_max,zbound_max,
xbound_max,ybound_max,zbound_max,
xbound_max,ybound_min,zbound_max; (' ',I1,A4,12(F7.2,','));
OUTPUT17 1,'QUAD', xbound_min,ybound_min,zbound_min,
xbound_min,ybound_min,zbound_max,
xbound_min,ybound_max,zbound_max,
xbound_min,ybound_max,zbound_min; (' ',I1,A4,12(F7.2,','));
OUTPUT17 1,'QUAD', xbound_max,ybound_min,zbound_min,
xbound_max,ybound_min,zbound_max,
xbound_max,ybound_max,zbound_max,
xbound_max,ybound_max,zbound_min; (' ',I1,A4,12(F7.2,','));
OUTPUT17 1,'QUAD', xbound_min,ybound_min,zbound_min,
xbound_min,ybound_min,zbound_max,
xbound_max,ybound_min,zbound_max,
xbound_max,ybound_min,zbound_min; (' ',I1,A4,12(F7.2,','));
OUTPUT17 1,'QUAD', xbound_min,ybound_max,zbound_min,
xbound_min,ybound_max,zbound_max,
xbound_max,ybound_max,zbound_max,
xbound_max,ybound_max,zbound_min; (' ',I1,A4,12(F7.2,','));

IF(isource = 2 | isource = 8)["output representation of source plane"
XMIN_YMIN_ZMIN = r_11(1)*(-BEAM_SIZE/2) + r_12(1)*(-BEAM_SIZE/2)
+
r_13(1)*(dsource+0.1) + xiso;
YMIN_XMIN_ZMIN = r_21(1)*(-BEAM_SIZE/2) + r_22(1)*(-BEAM_SIZE/2)
+
r_23(1)*(dsource+0.1) + yiso;
ZMIN_XMIN_YMIN = r_31(1)*(-BEAM_SIZE/2) + r_32(1)*(-BEAM_SIZE/2)
+
r_33(1)*(dsource+0.1) + ziso;

XMIN_YMAX_ZMIN = r_11(1)*(-BEAM_SIZE/2) + r_12(1)*(BEAM_SIZE/2) +
r_13(1)*(dsource+0.1) + xiso;
YMAX_XMIN_ZMIN = r_21(1)*(-BEAM_SIZE/2) + r_22(1)*(BEAM_SIZE/2) +
r_23(1)*(dsource+0.1) + yiso;
ZMIN_XMIN_YMAX = r_31(1)*(-BEAM_SIZE/2) + r_32(1)*(BEAM_SIZE/2) +
r_33(1)*(dsource+0.1) + ziso;

XMAX_YMIN_ZMIN = r_11(1)*(BEAM_SIZE/2) + r_12(1)*(-BEAM_SIZE/2) +
r_13(1)*(dsource+0.1) + xiso;
YMIN_XMAX_ZMIN = r_21(1)*(BEAM_SIZE/2) + r_22(1)*(-BEAM_SIZE/2) +
r_23(1)*(dsource+0.1) + yiso;
ZMIN_XMAX_YMIN = r_31(1)*(BEAM_SIZE/2) + r_32(1)*(-BEAM_SIZE/2) +
r_33(1)*(dsource+0.1) + ziso;

XMAX_YMAX_ZMIN = r_11(1)*(BEAM_SIZE/2) + r_12(1)*(BEAM_SIZE/2) +
r_13(1)*(dsource+0.1) + xiso;
YMAX_XMAX_ZMIN = r_21(1)*(BEAM_SIZE/2) + r_22(1)*(BEAM_SIZE/2) +
r_23(1)*(dsource+0.1) + yiso;
ZMIN_XMAX_YMAX = r_31(1)*(BEAM_SIZE/2) + r_32(1)*(BEAM_SIZE/2) +
r_33(1)*(dsource+0.1) + ziso;

XMIN_YMIN_ZMAX = r_11(1)*(-BEAM_SIZE/2) + r_12(1)*(-BEAM_SIZE/2)
+
r_13(1)*(dsource-0.1) + xiso;
YMIN_XMIN_ZMAX = r_21(1)*(-BEAM_SIZE/2) + r_22(1)*(-BEAM_SIZE/2)
+
r_23(1)*(dsource-0.1) + yiso;
ZMAX_XMIN_YMIN = r_31(1)*(-BEAM_SIZE/2) + r_32(1)*(-BEAM_SIZE/2)
+
r_33(1)*(dsource-0.1) + ziso;

XMIN_YMAX_ZMAX = r_11(1)*(-BEAM_SIZE/2) + r_12(1)*(BEAM_SIZE/2) +
r_13(1)*(dsource-0.1) + xiso;
YMAX_XMIN_ZMAX = r_21(1)*(-BEAM_SIZE/2) + r_22(1)*(BEAM_SIZE/2) +
r_23(1)*(dsource-0.1) + yiso;
ZMAX_XMIN_YMAX = r_31(1)*(-BEAM_SIZE/2) + r_32(1)*(BEAM_SIZE/2) +
r_33(1)*(dsource-0.1) + ziso;

XMAX_YMIN_ZMAX = r_11(1)*(BEAM_SIZE/2) + r_12(1)*(-BEAM_SIZE/2) +
r_13(1)*(dsource-0.1) + xiso;
YMIN_XMAX_ZMAX = r_21(1)*(BEAM_SIZE/2) + r_22(1)*(-BEAM_SIZE/2) +
r_23(1)*(dsource-0.1) + yiso;
ZMAX_XMAX_YMIN = r_31(1)*(BEAM_SIZE/2) + r_32(1)*(-BEAM_SIZE/2) +
r_33(1)*(dsource-0.1) + ziso;

XMAX_YMAX_ZMAX = r_11(1)*(BEAM_SIZE/2) + r_12(1)*(BEAM_SIZE/2) +
r_13(1)*(dsource-0.1) + xiso;
YMAX_XMAX_ZMAX = r_21(1)*(BEAM_SIZE/2) + r_22(1)*(BEAM_SIZE/2) +
r_23(1)*(dsource-0.1) + yiso;
ZMAX_XMAX_YMAX = r_31(1)*(BEAM_SIZE/2) + r_32(1)*(BEAM_SIZE/2) +
r_33(1)*(dsource-0.1) + ziso;

OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX,
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN,
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX;
(' ',I1,A4,12(F7.2,','));

IF(isource=8)[ "output the other positions of the source plane"
DO I=2,numang[
XMIN_YMIN_ZMIN = r_11(I)*(-BEAM_SIZE/2) + r_12(I)*(-
BEAM_SIZE/2) +
r_13(I)*(dsource+0.1) + xiso;
YMIN_XMIN_ZMIN = r_21(I)*(-BEAM_SIZE/2) + r_22(I)*(-
BEAM_SIZE/2) +
r_23(I)*(dsource+0.1) + yiso;
ZMIN_XMIN_YMIN = r_31(I)*(-BEAM_SIZE/2) + r_32(I)*(-
BEAM_SIZE/2) +
r_33(I)*(dsource+0.1) + ziso;

XMIN_YMAX_ZMIN = r_11(I)*(-BEAM_SIZE/2) +
r_12(I)*(BEAM_SIZE/2) +
r_13(I)*(dsource+0.1) + xiso;
YMAX_XMIN_ZMIN = r_21(I)*(-BEAM_SIZE/2) +
r_22(I)*(BEAM_SIZE/2) +
r_23(I)*(dsource+0.1) + yiso;
ZMIN_XMIN_YMAX = r_31(I)*(-BEAM_SIZE/2) +
r_32(I)*(BEAM_SIZE/2) +
r_33(I)*(dsource+0.1) + ziso;

XMAX_YMIN_ZMIN = r_11(I)*(BEAM_SIZE/2) + r_12(I)*(-
BEAM_SIZE/2) +
r_13(I)*(dsource+0.1) + xiso;
YMIN_XMAX_ZMIN = r_21(I)*(BEAM_SIZE/2) + r_22(I)*(-
BEAM_SIZE/2) +
r_23(I)*(dsource+0.1) + yiso;
ZMIN_XMAX_YMIN = r_31(I)*(BEAM_SIZE/2) + r_32(I)*(-
BEAM_SIZE/2) +
r_33(I)*(dsource+0.1) + ziso;

XMAX_YMAX_ZMIN = r_11(I)*(BEAM_SIZE/2) +
r_12(I)*(BEAM_SIZE/2) +
r_13(I)*(dsource+0.1) + xiso;
YMAX_XMAX_ZMIN = r_21(I)*(BEAM_SIZE/2) +
r_22(I)*(BEAM_SIZE/2) +
r_23(I)*(dsource+0.1) + yiso;
ZMIN_XMAX_YMAX = r_31(I)*(BEAM_SIZE/2) +
r_32(I)*(BEAM_SIZE/2) +
r_33(I)*(dsource+0.1) + ziso;

XMIN_YMIN_ZMAX = r_11(I)*(-BEAM_SIZE/2) + r_12(I)*(-
BEAM_SIZE/2) +
r_13(I)*(dsource-0.1) + xiso;
YMIN_XMIN_ZMAX = r_21(I)*(-BEAM_SIZE/2) + r_22(I)*(-
BEAM_SIZE/2) +
r_23(I)*(dsource-0.1) + yiso;
ZMAX_XMIN_YMIN = r_31(I)*(-BEAM_SIZE/2) + r_32(I)*(-
BEAM_SIZE/2) +
r_33(I)*(dsource-0.1) + ziso;

XMIN_YMAX_ZMAX = r_11(I)*(-BEAM_SIZE/2) +
r_12(I)*(BEAM_SIZE/2) +
r_13(I)*(dsource-0.1) + xiso;
YMAX_XMIN_ZMAX = r_21(I)*(-BEAM_SIZE/2) +
r_22(I)*(BEAM_SIZE/2) +
r_23(I)*(dsource-0.1) + yiso;
ZMAX_XMIN_YMAX = r_31(I)*(-BEAM_SIZE/2) +
r_32(I)*(BEAM_SIZE/2) +
r_33(I)*(dsource-0.1) + ziso;

XMAX_YMIN_ZMAX = r_11(I)*(BEAM_SIZE/2) + r_12(I)*(-
BEAM_SIZE/2) +
r_13(I)*(dsource-0.1) + xiso;
YMIN_XMAX_ZMAX = r_21(I)*(BEAM_SIZE/2) + r_22(I)*(-
BEAM_SIZE/2) +
r_23(I)*(dsource-0.1) + yiso;
ZMAX_XMAX_YMIN = r_31(I)*(BEAM_SIZE/2) + r_32(I)*(-
BEAM_SIZE/2) +
r_33(I)*(dsource-0.1) + ziso;

XMAX_YMAX_ZMAX = r_11(I)*(BEAM_SIZE/2) +
r_12(I)*(BEAM_SIZE/2) +
r_13(I)*(dsource-0.1) + xiso;
YMAX_XMAX_ZMAX = r_21(I)*(BEAM_SIZE/2) +
r_22(I)*(BEAM_SIZE/2) +
r_23(I)*(dsource-0.1) + yiso;
ZMAX_XMAX_YMAX = r_31(I)*(BEAM_SIZE/2) +
r_32(I)*(BEAM_SIZE/2) +
r_33(I)*(dsource-0.1) + ziso;

OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX,
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMIN_ZMIN,YMIN_XMIN_ZMIN,ZMIN_XMIN_YMIN,
XMIN_YMIN_ZMAX,YMIN_XMIN_ZMAX,ZMAX_XMIN_YMIN,
XMAX_YMIN_ZMAX,YMIN_XMAX_ZMAX,ZMAX_XMAX_YMIN,
XMAX_YMIN_ZMIN,YMIN_XMAX_ZMIN,ZMIN_XMAX_YMIN;
(' ',I1,A4,12(F7.2,','));
OUTPUT17 3,'QUAD',
XMIN_YMAX_ZMIN,YMAX_XMIN_ZMIN,ZMIN_XMIN_YMAX,
XMIN_YMAX_ZMAX,YMAX_XMIN_ZMAX,ZMAX_XMIN_YMAX,
XMAX_YMAX_ZMAX,YMAX_XMAX_ZMAX,ZMAX_XMAX_YMAX,
XMAX_YMAX_ZMIN,YMAX_XMAX_ZMIN,ZMIN_XMAX_YMAX;
(' ',I1,A4,12(F7.2,','));
]
]
IF(isource=20 | isource=21)[ "supress output the other positions"
" of the source planes"
OUTPUT17;(/' Not displaying all 10000 source planes'/)
]
]
]

call srcout;

IF(howfarless) call modify_tmxs(MIN(mindelX,mindelY,mindelZ));

OUTPUT61;(/' Medium',t24,'AE',t34,'AP');
DO n=1,NMED[OUTPUT61 (media(j,n),j=1,15),ae(n),ap(n);(1x,15a1,2f10.3);]

"RESTART FEATURES"
"================"
DO irl=1,irmax[endep_last(irl)=0;] "always zero this array"

IHSTRY=0; "always zero this as well"

IF(IRESTART = 0)["START A NEW RUN"
nnread = 0;"initialize counter"
nsmiss=0; nmissm=0; ncaseold=0;
nsrjct=0; nsoutside=0; ndbsrjct=0;
planarefe=0.; planarefp=0.;
planarfe=0.; planarfp=0.;
NofREPEAT = 0; esrc=0.; nestep=0;
nhist=0; more_in_cont=0; "src10 and 11boolean"
frMU_indx=0; nsblocked=0;
"-- no particles in container to start so read from the phase space"

IF(IPARALLEL>1 & PARNUM>0)[
nnphsp=INT((PARNUM-1)*nshist/IPARALLEL)+1;
]
ELSE[
nnphsp=1;
]
IF(i_iaea_in=1)[
$IAEA_SET_PHSP_RECORD(i_unit_in,nnphsp);
]
"Zero the main scoring array
DO irl=1,irmax[
endep(irl)=0.0;
endep2(irl)=0.0;
endep_tmp(irl)=0.0;
]
tcpuold=0.;
]
ELSEIF(IRESTART = 1)["READ DATA FROM A PREVIOUS RUN"
OUTPUT; (/' *** About to read dose data from previous run ***');
i_par_temp=i_parallel;
IF(IPARALLEL>0 & n_parallel=0) i_parallel=0;
iorstrt=egs_open_datfile(iorstrt,0,1,'.egsdat');
i_parallel=i_par_temp;
DO irl=1,irmax[
READ(iorstrt,*)endep(irl),endep2(irl);
]
READ(iorstrt,*)
ncaseold,nnread,nsmiss,nmissm,nnphsp,NofREPEAT,tcpuold,esrc,

planarefe,planarefp,planarfe,planarfp,nestep,nsrjct,nsoutside,ndbsrjct,
nhist,nsblocked;
$RETRIEVE RNG STATE FROM UNIT iorstrt;
CLOSE(iorstrt);
OUTPUT61 ncaseold; (/' Histories finshed in previous run',i12);
IF(isource=2 | isource=8 | isource=9)[
OUTPUT61 nhist; (/' Equivalent no. of primary histories',i12);
]
OUTPUT61 tcpuold/3600.;(/' Total previou CPU time (hour) ',f10.3);
OUTPUT61;(/' Random number seeds for restart ',$);
$SHOW-RNG-STATE(6);
$SHOW-RNG-STATE(1);
OUTPUT;(/' ***Successfully read previous dose data file ***');
]
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
ELSEIF(IRESTART = 2)["Just create the input file and then quit" GO TO
:END:; ]

ELSEIF(IRESTART = 3)["Just do a data analysis"
NCASE=0;
OUTPUT; (/' *** About to read dose data from previous run ***');
i_par_temp=i_parallel;
IF(IPARALLEL>0 & n_parallel=0) i_parallel=0;
iorstrt=egs_open_datfile(iorstrt,0,1,'.egsdat');
i_parallel=i_par_temp;
DO irl=1,irmax[
READ(iorstrt,*)endep(irl),endep2(irl);
]
READ(iorstrt,*)
ncaseold,nnread,nsmiss,nmissm,nnphsp,NofREPEAT,tcpuold,esrc,

planarefe,planarefp,planarfe,planarfp,nestep,nsrjct,nsoutside,ndbsrjct,
nhist,nsblocked;
$RETRIEVE RNG STATE FROM UNIT iorstrt;
CLOSE(iorstrt);
OUTPUT61 ncaseold;(/' Histories finished in previous run',i12);
OUTPUT61 tcpuold/3600.;(/' Total CPU time (hour) by then ',f10.3);
timcpu=0;
NCASE=0;
OUTPUT;(/' ***Successfully read previous dose data file ***');
GO TO :STAT-ANALYSIS:;
]
ELSEIF(IRESTART=4)["just combine .pardose files"
call egs_combine_runs(combine_results,'.pardose');
ainflu=temp2; "need to define this because it is used to normalize
dose"
IF((isource = 0 | isource = 1 | isource = 3 | isource = 7) &
beamarea>0.) ainflu=ainflu/beamarea;
goto :ANALYZE-PARALLEL:;
]

" Range rejection initialization
""toc:
" ******************************

IF (IREJECT = 1) ["do range rejection "
OUTPUT61 ESAVE_GLOBAL;
(/' Will perform charged-particle range rejection against voxel
boundaries'/
' if particle energy is below ',F12.5,' MeV.');
IF (ESAVE_GLOBAL <= ECUTIN) [
OUTPUT61 ;(///' ****** NB ESAVE_GLOBAL <= ECUT so NO Range
Rejection',
' ***' //);
IREJECT=0;
]
ELSE[
"calculate range from ECUTIN to AE for use in range rejection
macro"
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
"must do this for each medium"
lelec=-1;
DO MEDIUM=1,NMED[
IF (ECUTIN = AE(MEDIUM))[
RANGE_ECUTRR(MEDIUM)=0.0;
]
ELSE[
EKE = ECUTIN- RM;
ELKE = LOG(EKE);
$SET INTERVAL ELKE, EKE;
EKEI = E_array(LELKE,MEDIUM);
ELKEI = (LELKE - eke0(MEDIUM))/eke1(MEDIUM);
$COMPUTE-
DRANGE(EKE,EKEI,LELKE,ELKE,ELKEI,RANGE_ECUTRR(MEDIUM));

RANGE_ECUTRR(MEDIUM)=RANGE_ECUTRR(MEDIUM)+range_ep(0,LELKE,MEDIUM);
"note that this is not yet scaled for non-default density"
"scaling will be done on the fly"
]
]
]
]
ELSE["no range rejection"
IREJECT=0; "set default"
OUTPUT61; (/' No range rejection.');
IF(ESAVE_GLOBAL > ECUTIN)[
OUTPUT61;
(T10,' Why is ESAVE_GLOBAL set when there is no range
rejection?',
/T15,'It is set to zero'/);
ESAVE_GLOBAL = 0.0;
]
]


IF(n_split > 1)[
iausfl(8) = 1; "After bremsstrahlung"
iausfl(14) = 1; "A positron has annihilated in-flight"
iausfl(15) = 1; "A positron has annihilated at rest"
OUTPUT61 n_split; (/' Photons will be split ',I4,' times'/);
]

OUTPUT61;(//'
***************************************************************');
IF(isource=20)[
OUTPUT61 NCASE;
(/ ' Histories to be simulated into the phantom for this run ',i12);
OUTPUT61 compensated_NCASE;
( / ' Predicted histories required ',i12);
]
ELSE[
OUTPUT61 NCASE; (/ ' Histories to be simulated for this run
',i12);
OUTPUT61 ncaseold+NCASE; (/ ' Histories to be analyzed after this
run',i12);
]
OUTPUT61;(/ '
***************************************************************');

"Step 8 shower call ""toc:
"====================

"open the .egsdat file if called for"
IF(IDAT=0 | IDAT=2)[
i_par_temp=i_parallel;
IF(IPARALLEL>0 & n_parallel=0) i_parallel=0;
"avoids adding double _w extensions if"
"parallel job controlled by script"
iorstrt=egs_open_file(iorstrt,0,1,'.egsdat');
i_parallel=i_par_temp;
]

IF(IWATCH ~= 0)[call watch(-99,IWATCH);] "Set up for watch routine if
needed

$SET_ELAPSED_TOTAL_TIME(TIMEB);
OUTPUT61 TIMEB;(' Elapsed wall clock time to this point=',f12.3,' s'/);
$INITIALIZE_ELAPSED_TOTAL_TIME; "reset to get elapsed time during run
only"
ETIMETOT=0; "initialize total elapsed time"
$SET_ELAPSED_CPUTIME(cput1);
OUTPUT61 cput1 - cput0;
(/' CPU time so far for this run =',f12.3,' s'/);

NETADJ=0; "initialize number of times elapsed time adjusted"

CYCLNUM=0; "initialize counter for number of times particles recycled"

nhist_last=0;

#ifdef HAVE_C_COMPILER;
;
n_tot = ncaseold; first_time = .true.; is_finished = .false.;
/part_dose,part2_dose/=0;
"I'm not sure what is a good quantity to put into the job control file
=>"
"just use 0 for now"

:start_parallel_loop:;

IF(isource = 20 | isource = 21)["reset more_in_cont and MU index for
every"
"chunk"
more_in_cont=0;
frMU_indx=0;
]
IF( n_parallel > 0 ) [ "Job is part of a parallel run "

call egs_pjob_control(ncase,n_run,n_left,n_tot,part_dose,part2_dose,
current_result, current_uncertainty);
IF( n_run = 0 ) [
write(6,'(//a,a//)') '****** No histories left in job control
file',
' => end simulation';
goto :STAT-ANALYSIS:;
]
jcase = n_run/$NBATCH;
IF( jcase < 1 ) [ jcase = 1; n_run = jcase*$NBATCH; ]
IF( first_time ) [
IF(isource=2|isource=8|isource=20)
p_per_phsp_chunk=nshist/(n_parallel*$N_CHUNKS);
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';
]
IF(isource=2|isource=8|isource=20)[
" figure out where to start in the phase space file"
" if ncase/(n_parallel*$N_CHUNKS) has a remainder, then the last
chunk"
" of the phase space file will be used twice. This should not cause"
" too much underestimate of uncertainty"
n_run_chunk=(ncase-n_left)*n_parallel*$N_CHUNKS/ncase;
other_num_1=n_run_chunk*ncase;
other_num_2=(ncase-n_left)*n_parallel*$N_CHUNKS;
IF(other_num_1<other_num_2)[
"ncase/(n_parallel*$N_CHUNKS) is not an integer"
"and so n_run, no of histories in each chunk, has been rounded
down"
n_run_chunk=n_run_chunk+1;
]
nnphsp_min=(n_run_chunk-1)*p_per_phsp_chunk+1;
IF(n_left=0)["this is the last run just use up the rest of the"
"phsp source"
nnphsp_max=nshist;
]
ELSE["calculate the max value of nnphsp"
nnphsp_max=nnphsp_min+p_per_phsp_chunk-1;
]
nnphsp=nnphsp_min;
IF(i_iaea_in=1)[
$IAEA_SET_PHSP_RECORD(i_unit_in,nnphsp);
]
CYCLNUM=0; "reset NRCYCL counter"
write(6,'(/a/,a,i12,a,i12/,a//)')
' This simulation uses a phase space source.',
' This run will use from particle',nnphsp_min,' to particle ',
nnphsp_max,
' in the source file.';
]
]
#endif;

DO ibatch = 1,$NBATCH["Break into $NBATCH batches"

IF(ibatch = 1)[
CALL DATETIME(1); "argument is a dummy"
OUTPUT61 TIMEN;
(/' BATCH #',2X,'TIME-ELAPSED',2X,'TOTAL CPUTIME',2X,'RATIO',2X,
'TIME OF DAY',2X,'RNG pointers'//
' ',4X,'1',10X,'0.0',12X,'0.0',6X,'0.00',4X,$TIMEN_FORMAT,'
',$);
$SHOW-RNG-STATE(6);$SHOW-RNG-STATE(1);OUTPUT61;(' ');
]
ELSE[
$SET_ELAPSED_TOTAL_TIME(TIMEB);
ETIMETOT=ETIMETOT+TIMEB;
$SET_ELAPSED_CPUTIME(CPUT2);
CALL DATETIME(1);
TIMCPU=CPUT2-CPUT1;
OUTPUT61 IBATCH,ETIMETOT,TIMCPU,ETIMETOT/TIMCPU,TIMEN;
(4X,I2,5X,F8.1,7X,F8.1,2X,F8.2,4X,$TIMEN_FORMAT,' ',$);
$SHOW-RNG-STATE(6);$SHOW-RNG-STATE(1);OUTPUT61;(' ');
"Check there is time left for another batch"
BATCHT=TIMCPU/FLOAT(IBATCH-1);"Time per batch so far"
IF(TIMCPU+1.1*BATCHT > TIMMAX*3600.)[
"Not enough time for another batch"
"Print message and exit simulation loop"
OUTPUT61;(' Not enough time for another batch within time
limit');
]

;$BEAMMODEL_DATA_OUTPUT;
"analysis data for beam characterization models"
]

DO ihist = 1,jcase[

nhist_old=nhist;

IHSTRY=IHSTRY+1;

call srchst(xin,yin,zin,uin,vin,win,irin,weight,latchi);

"srchst also returns in comin source esrc_sp, the sampled k.e."
" (enflag=1 cases) and einsrc, the total initial energy"
" for phase space inputs. Also, if this is a new phase"
" space file, it returns nhist, the total no. of primary"
" histories used that scored particles in the phsp file."

"IF(((isource=20)|(isource=21 ))& weight=0)["
"This check has been removed and the blocked particles are now
counted"
"as nsblocked in srcxyznrc.mortran (JL)"
"this happens if a particle "
"is blocked by shared library modules (only source 20
or 21)"
" IHSTRY=IHSTRY-1;""do not count this particle as one"
"that contributed"
"]"
"ELSE["
"increment esrc, the kinetic+Q energy incident on the phantom"
"----------------------------------------------------------------
-"
IF(enflag = 1)["Particle energy sampled from a spectrum"
"----------------------------------------------------------------
-"
"esrc_sp is the kinetic energy"
esrc = esrc + weight*esrc_sp;"we only count the kinetic E for
the "
"electrons and photons in the total incident E"
IF(iqin =1)[ esrc = esrc + weight*1.0220068;
"we include 2 0.511 MeV photons from e+ - e- annihilation"]
IF(iqin ~= 0)[ etotin = esrc_sp + 0.5110034;"particle total
E"]
ELSE[etotin = esrc_sp;]
]
"----------------------------------------------------------------
-"
ELSEIF(enflag = 2 | enflag = 3)["phase-space input or BEAM sim."
"----------------------------------------------------------------
-"
etotin = einsrc; "einsrc is the total energy of the
particle"
IF(iqin = -1) [esrc = esrc + weight*(etotin - 0.5110034);
"remove e- rest mass"]
ELSEIF(iqin = 0)[esrc = esrc + weight*etotin; ]
ELSEIF(iqin = 1)[esrc = esrc + weight*(etotin + 0.5110034);
"add 0.511 for the positron but was - till June 97"
]
]
"----------------------------------------------------------------
-"
ELSEIF(enflag = 4)[ ;$BEAMMODEL-SOURCE4-ENERGY; ]
"----------------------------------------------------------------
-"
ELSEIF(enflag > 5 )[ OUTPUT enflag;(' Wrong enflag:',I10); STOP;
]
"----------------------------------------------------------------
-"

IF(IWATCH > 0)[ WRITE(6,:INITIAL-SHOW-VALUE:)
1,etotin,iqin,irin,xin,yin,zin,uin,vin,win,latchi,weight;
:INITIAL-SHOW-VALUE: FORMAT(/' Initial shower values',
t36,':',i3,f9.3,2i4,3f8.3,3f7.3,i10,1pe10.3);
]

"Determine on-axis planar and energy fluence in 1cm^2 area"
IF(xin*xin+yin*yin<0.31831)[
IF(iqin ~= 0)[
planarfe=planarfe+weight;
planarefe=planarefe+(etotin-0.5110034)*weight;
]
ELSE["photons"
planarfp=planarfp+weight;
planarefp=planarefp+etotin*weight;
]
]

IF((isource~=2 & isource~=8 & isource~=9) | (dose_stat=1 &
NRCYCL=0) |
(dose_stat=1 & CYCLNUM=1) |
((isource=2 | isource=8) & dose_stat=0 & IPARALLEL>1 &
PARNUM>0 & ihist=1 & IBATCH=1 & nhist=nhist_old))
nhist=nhist+1;
"we have a non-phsp source, we cannot get number of"
"of primary histories from the phase space source AND we are not"
"recycling or we are at the first particle in the cycle, or this"
"particular partition of the phsp source (parallel run) does not"
"start with the first particle from a new primary history."

IF(nhist~=nhist_old)["we have incremented nhist"
nhist_last=nhist_last+1;
IF(nhist_last=32700)[ "we are near the limit of nhist_last"
"reset nhist_last to 1 and endep_last
to 0"
DO irl=1,irmax-1[
endep_last(irl)=0;
]
nhist_last=1;
]
]

IF( (iqin ~= 0 & e_split > 1 & n_split>1) &
(isource = 2 | isource = 8 | isource = 9 | isource = 10 |
isource = 20 | isource =21) ) [
n_repeat = e_split;
] ELSE [ n_repeat = 1; ]

DO i_repeat = 1,n_repeat [
"==========================================================="
call
shower(iqin,etotin,xin,yin,zin,uin,vin,win,irin,weight/n_repeat);
"==========================================================="
]

IF(IWATCH ~= 0) call watch(-1,IWATCH);
"]""end of source 20,21 else statement"
]"end of ihist loop"

$SET_ELAPSED_CPUTIME(cput2);"Final cpu for batch - only used for last"
"batch, but set here so write to file"
"not included"
timcpu=cput2-cput1;

"FINISHED BATCH, SAVE DATA TO A FILE if REQUESTED"
IF(IDAT = 0 | (IDAT = 2 & ibatch = $NBATCH) ) ["store data"
rewind(iorstrt); "overwrite previous data"
DO irl=1,irmax[
"add unscored portions of endep_tmp before writing"
endep(irl)=endep(irl)+endep_tmp(irl);
endep2(irl)=endep2(irl)+endep_tmp(irl)*endep_tmp(irl);
endep_tmp(irl)=0.;
WRITE(iorstrt,*)endep(irl),endep2(irl);
]
WRITE(iorstrt,*)
IHSTRY+ncaseold, nnread, nsmiss, nmissm, nnphsp,
NofREPEAT, tcpuold+timcpu, esrc, planarefe, planarefp,
planarfe,
planarfp, nestep, nsrjct,nsoutside,ndbsrjct,nhist,nsblocked;
$PUT RNG STATE ON UNIT iorstrt;
]
]"END OF IBATCH LOOP"

#ifdef HAVE_C_COMPILER;
;
IF( n_parallel > 0 ) [ goto :start_parallel_loop:; ]

#endif;

"close any files that we opened"
IF(IDAT=0 | IDAT=2) close(iorstrt);
IF(IWATCH=4) [
close(ioutgph);
close(ioutgeom);
]



:STAT-ANALYSIS:; "toc:
"=============="

IF (IRESTART ~= 3)[
OUTPUT61 timcpu,timcpu/3600.,dble(IHSTRY)/(timcpu/3600.);
(/' Total CPU time for run =',f8.1,' s =',f8.3,' hr =>',
F12.0,' hist/hr'/T3,' On '$MACHINE' ');
]
IF (IRESTART = 1) ["Case of restarting"
OUTPUT61 timcpu+tcpuold,(timcpu+tcpuold)/3600.,dble(IHSTRY+ncaseold)
/((timcpu+tcpuold)/3600.);
(/' CPU time for this+previous run =',f8.1,' s =',f8.3,' hr =>',
F12.0,' hist/hr'/T3,' On '$MACHINE' ');
]
ELSEIF (IRESTART = 3)["just data analysis"
OUTPUT61 timcpu+tcpuold,(timcpu+tcpuold)/3600.,float(ncaseold)
/((timcpu+tcpuold)/3600.);
(/' Total CPU time for old run =',f8.1,' s =',f8.3,' hr =>',
F12.0,' hist/hr'/T3,' On '$MACHINE' ');
]


IF(isource = 2 | isource = 8 )[ "Full phase-space source"
OUTPUT61 nnread,nhist,nsrjct,nsoutside,ndbsrjct,nsmiss,
float((NRCYCL+1)*(nnread-nsrjct-nsoutside-ndbsrjct)-
nsmiss)/float(nnread),
NRCYCL,IHSTRY+ncaseold,OUTCNT;
(/'
********************************************************************'/
/' # of particles read from ph-sp file (N_read)
=',i12/
' # of primary (non ph-sp) histories read from ph-sp file
=',i12/
' # of particles discarded due to charge/LATCH/W/multiple passer
=',i12/
' # of particles discarded because beyond BEAM_SIZE
=',i12/
' # of photons rejected because beyond DBS splitting radius
=',i12/
' # of particles that missed geometry
=',i12/
' N_used/N_read
=',f12.3/
' # of times each particle in ph-sp file recycled '/
' (last particle may be recycled less than this)
=',i12/
' # of ph-sp particles simulated (N_used)
=',i12/
' # of times ph-sp file restarted in this run
=',i12/
/'
********************************************************************');

]
ELSEIF(isource=9 | isource =10)["BEAM sim. of treatment head"
OUTPUT61 nnread,nhist,nsrjct,nsoutside,ndbsrjct,nsmiss,IHSTRY+ncaseold,
dble(IHSTRY+ncaseold)/float(nnread);
(/'
********************************************************************'//
' # of particles read from BEAM simulation (N_read)
=',i12/
' # of primary particles incident in BEAM simulation
=',i12/
' # of particles discarded due to charge/LATCH/W/multiple passer
=',i12/
' # of particles discarded because beyond BEAM_SIZE
=',i12/
' # of photons rejected because beyond DBS splitting radius
=',i12/
' # of particles that missed geometry
=',i12/
' # of particles simulated in DOSXYZnrc (N_used)
=',i12/
' N_used/N_read
=',f12.3/
/'
********************************************************************');

]
ELSEIF(isource=20)["VCU sim."
OUTPUT61 NCASE,survival_ratio,compensated_NCASE,nnread,nsrjct,nsoutside,
ndbsrjct, nsmiss, nsblocked,IHSTRY+ncaseold,
dble(IHSTRY+ncaseold)/(float(nnread)*(NRCYCL+1)),OUTCNT;
(/'
********************************************************************'//
' # of particles originally requested (NCASE)
=',i12/
' predicted survival ratio (based on shared library blockage)
=',f12.3/
' # calculated number to read from phsp (NCASE/survival_ratio)
=',i12/
' # of primary particles incident in the simulation (nnread)
=',i12/
' # of particles discarded due to charge/LATCH/W/multiple passer
=',i12/
' # of particles discarded because beyond BEAM_SIZE
=',i12/
' # of photons rejected because beyond DBS splitting radius
=',i12/
' # of particles that missed geometry
=',i12/
' # of particles that got blocked by shared library modules
=',i12/
' # of particles used in DOSXYZnrc (N_used)
=',i12/
' N_used/(nnread x N_recycle)
=',f12.3/
' # of times ph-sp file restarted in this run
=',i12/
/'
********************************************************************');
]
ELSEIF(isource=21)["BEAM simulation used as source, incident from any
angle"
"and through MLC"
OUTPUT61 nnread,nhist,nsrjct,nsoutside,ndbsrjct,nsmiss,nsblocked,
IHSTRY+ncaseold,dble(IHSTRY+ncaseold)/float(nnread);
(/'
********************************************************************'//
' # of particles read from BEAM simulation (N_read)
=',i12/
' # of primary particles incident in BEAM simulation
=',i12/
' # of particles discarded due to charge/LATCH/W/multiple passer
=',i12/
' # of particles discarded because beyond BEAM_SIZE
=',i12/
' # of photons rejected because beyond DBS splitting radius
=',i12/
' # of particles that missed geometry
=',i12/
' # of particles that got blocked by shared library modules
=',i12/
' # of particles simulated in DOSXYZnrc (N_used)
=',i12/
' N_used/N_read
=',f12.3/
/'
********************************************************************');

]
ELSEIF(isource = 1)["parallel beam from any direction"
OUTPUT61 nmissm;
(/'
********************************************************************'/
/' # of particles which missed the phantom with source 1
=',i12/
/'
********************************************************************');
]

ELSEIF(isource =4 )[ ;$BEAMMODEL-SOURCE4-SUMMARY; ]


"Step 9 Analyse and output results ""toc:
"=================================

etot=0.;

"Correlated sampling no longer supported with history by history
statistics"
"$Corr_Dump;mah 09/05/95 To store DOSEIS to file. ";

"sum energy deposition in phantom"
"Note that dose is still really just an energy deposition"
DO irl=1,irmax-1[etot=etot+endep(irl);]

IF (enflag = 0)[
"Known Bug - this doesn't handle positrons correctly yet"
OUTPUT61 etot/(dble(IHSTRY+ncaseold)*ein);
(/' Fraction of incident energy deposited in the phantom =',f12.4/);
]
ELSEIF((enflag=1)|(enflag=2)|(enflag=3)|(enflag=4))[ ;OUTPUT61 etot/esrc;
(/' Fraction of incident energy deposited in the phantom =',f12.4/);
IF ((enflag > 1))[ OUTPUT61 endep(irl)/esrc;
(/' Fraction of incident energy deposited in the region surrounding'/
' the phantom when incident particles go through it =',f12.4/);
]
]

"Calculate incident fluence
IF(isource = 0 | isource = 1 | isource = 3 | isource = 7)[
temp2=dble(IHSTRY+ncaseold-nsmiss-nmissm);
IF(beamarea = 0)[ ainflu=dble(IHSTRY+ncaseold-nsmiss-nmissm);]
ELSE[ ainflu=dble(IHSTRY+ncaseold-nsmiss-
nmissm)/beamarea;]
]
ELSEIF(isource = 2 | isource = 8 )[
ainflu=dble(IHSTRY+ncaseold+nsmiss+

(NRCYCL+1)*(nsrjct+nsoutside+ndbsrjct))/float(nshist)*NINCSRC;
"IHSTRY+ncaseold is the number of particles"
"actually simulated from the phase space source"
"We then add nsmiss+(NRCYCL+1)*(nsrjct+nsoutside+ndbsrjct), an
estimate of"
"the total number of particles rejected based on charge, LATCH, W,"
"being a multiple passer, being outside BEAM_SIZE, falling beyond the"
"directional bremsstrahlung splitting (DBS) radius, or missing the
geometry"
"The result is an estimate of the total number of particles read from
the"
"phase space source. This number is then divided by nshist, the
total"
"number of particles in the phase space source, to give the number"
"of times that the phase space source has been used (this could be
<1)"
"Finally, we multiply this by NINCSRC, the number of particles"
"incident from the original (non-phase space) source that were used
to"
"obtain the phase space source. The result is an estimate of the
number"
"of particles incident from the original (non-phase space) source for"
"this simulation."
temp2=ainflu;
]
ELSEIF(isource=4)[
ainflu=dble(IHSTRY+ncaseold-nsmiss);
temp2=ainflu;
]
ELSEIF(isource=6)[
ainflu=dble(IHSTRY+ncaseold);
temp2=ainflu;
]
ELSEIF(isource=9|isource=10|isource=21)[
"full BEAM simulation, here we can just read nhist"
"the no. of primary histories"
ainflu=dble(nhist);
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
temp2=ainflu;
]
ELSEIF(isource=20)["full VCU simulation"

"ainflu=dble(IHSTRY+ncaseold+nsmiss+nsblocked+"

"(NRCYCL+1)*(nsrjct+nsoutside+ndbsrjct))/float(nshist)*NINCSRC;"

ainflu = dble((NRCYCL+1)*(nnread))/dble(nshist)*NINCSRC;

temp2=ainflu;
]
OUTPUT61 nestep,dble(nestep)/ainflu,count_pII_steps/dble(nestep);
(/' Number of charged particle steps simulated, N_step =',I15/
' Number of charged particle steps/incident fluence
=',1PE15.5/
' No. of PRESTA-II steps/total no. of charged particle steps
=',0PF15.5/);

"Now calculate dose uncertainties"
IF(dose_stat=1)[
OUTPUT61;(//' ***WARNING***'/
' Could not read no. of primary (non-phsp) histories from ph-sp
file.'/
' Dose analyzed assuming each particle read from the ph-sp'/
' file is an independent history. May result in an
underestimate'/
' of the uncertainty.'//);
]
ELSEIF(OUTCNT>0)[
OUTPUT61;(//' ***WARNING***'/
' The ph-sp source was restarted at least once. This may lead'/
' to an underestimate of uncertainty, especially if restarted'/
' many times. If restarted many times, try re-running with'/
' NRCYCL recalculated as described at top of
dosxyznrc.mortran'//);
]
DO irl = 1,irmax-1 [
IF(IDAT=1)[
"add unscored portion of endep_tmp(irl) first"
endep(irl)=endep(irl)+endep_tmp(irl);
endep2(irl)=endep2(irl)+endep_tmp(irl)*endep_tmp(irl);
]
"divide by rhor so that we do not have to store rhor in the .pardose"
"file during parallel runs."
endep(irl)=endep(irl)/rhor(irl+1);
endep2(irl)=endep2(irl)/(rhor(irl+1)*rhor(irl+1));
]

#ifdef HAVE_C_COMPILER;

"store endep and endep2 before analysis for a parallel run"
IF(IPARALLEL>1 | n_parallel>0)[

"now determine the full file name with the proper _w addition"
"this file is written directly into the user code directory"
parname=$cstring(egs_home) // $cstring(user_code) // $file_sep //
$cstring(work_dir) // $cstring(output_file);
IF(n_parallel>0)[
"have to add _w[iparallel] if not controlled by script"
parname=$cstring(parname)//'_w';
call egs_itostring(parname,i_parallel,.false.);
]
parname=$cstring(parname)//'.pardose';
"name must be null terminated"
parname(lnblnk1(parname)+1:lnblnk1(parname)+1)=char(0);

call write_pardose(temp2,IMAX,JMAX,KMAX,endep,endep2,parname);
]

#endif;

:ANALYZE-PARALLEL:;

"Now analyze uncertainty and convert
"to dose per unit incident fluence gray-cm**2
DO i=1,IMAX [
DO j=1,JMAX [
DO k=1,KMAX [

"first, estimate uncertainty"
irl= $IRD(i,j,k);
temp=endep(irl)/temp2;
endep2(irl)=endep2(irl)/temp2;
endep2(irl)=(endep2(irl)-temp*temp)/(temp2-1);
IF(endep2(irl)>0) endep2(irl)=sqrt(endep2(irl));
IF(endep(irl)~=0)
endep2(irl)=endep2(irl)/(endep(irl)/temp2);

"amass used to store mass but now just stores volume"
amass=
(xbound(i+1)-xbound(i))*
(ybound(j+1)-ybound(j))*
(zbound(k+1)-zbound(k));
IF (amass~=0.0) [
endep(irl) = endep(irl)*1.602e-10/(amass*ainflu);
]
ELSE[
endep(irl) = 0.0;
OUTPUT61 i,j,k;
('AMASS is zero in I= ',I4,'J= ',I4,' K= ',I4);
OUTPUT61;('So the dose has been set to zero.');
];
IF(endep(irl)=0.) endep2(irl)=0.9999999;
]
]
]
" Output results
" ==============

REPLACE {$PRINT-HEADER;} WITH {;
IF((n_parallel>0 & is_finished)|IRESTART=4 )[
"fluence meaningless in final analysis"
OUTPUT1 title;
(//,'1',80a1 //
t10,
'DOSXYZnrc ($Revision: 1.50 $) Dose outputs (dose/F, Gy.cm**2)');
]
ELSE[
IF(((isource.EQ.0).OR.( isource.EQ.1).OR.( isource.EQ.3).OR.
(isource.EQ.7)).AND.
(beamarea ~= 0.))[
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,ainflu;
( '1',80a1 //
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Average planar fluence (number/beam area), F =',
1pe11.3,'(1/cm**2)'//
t10,
'DOSXYZnrc ($Revision: 1.50 $) Dose outputs (dose/F, Gy.cm**2)');
]
ELSEIF(isource.EQ.2.OR.isource.EQ.8)[
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,
IHSTRY+ncaseold;
( '1',80a1 /
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'No. of particles incident from phase space file =',1i13/);
IF(OLDSRC.EQ.1)[
OUTPUT1;
(t10,' DOSXYZnrc ($Revision: 1.50 $) Dose outputs '/
t10,'(Dose/incident particle from phase space file, Gy)');
]
ELSE[
OUTPUT1 ainflu;
(t5,'No. of particles incident from original source =',1f13.1//
t10,' DOSXYZnrc ($Revision: 1.50 $) Dose outputs '/
t10,'(Dose/incident particle from original source, Gy)');
]
]
ELSEIF(((isource.EQ.4).OR.(isource.EQ.5)).OR.
(((isource.EQ.0).OR.( isource.EQ.1).OR.( isource.EQ.3).OR.
(isource.EQ.7)).AND.(beamarea.EQ.0.)))[
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,ainflu;
( '1',80a1 /
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Total number of incident particles =',1pe11.3//
t10,'DOSXYZnrc ($Revision: 1.50 $)',
' Dose outputs (Dose/incident particle, Gy)');
]
ELSEIF(isource.EQ.6)[
OUTPUT1 title,ainflu;
( '1',80a1 /
t5,'Total number of incident particles =',1pe11.3//
t10,'DOSXYZnrc ($Revision: 1.50 $)',
' Dose outputs (Dose/incident particle, Gy)');
]
ELSEIF((isource.EQ.9).OR.(isource.EQ.21))[
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,
IHSTRY+ncaseold,nhist;
( '1',80a1 /
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,' No. of particles incident on DOSXYZ phantom
=',1i13//
t5,'No. of primary particles incident in BEAM simulation
=',1i13//
t10,' DOSXYZnrc ($Revision: 1.50 $) Dose outputs '/
t10,'(Dose/incident particle from original source, Gy)');
]
ELSEIF(isource.EQ.20)[
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,
IHSTRY+ncaseold,nhist;
( '1',80a1 /
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,' No. of particles incident on DOSXYZ phantom
=',1i13//
t5,'No. of primary particles incident in VCU/BEAM simulation
=',1i13//
t10,' DOSXYZnrc ($Revision: 1.50 $) Dose outputs '/
t10,'(Dose/incident particle from original source, Gy)');
]
ELSE["currently we do not have any other sources"
OUTPUT1 title,planarefe,planarefp,planarfe,planarfp,ainflu;
( '1',80a1 /
t5,'Elec/positron planar energy fluence scored in a 1cm**2 circle
'/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar energy fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Elec/positron planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'Photon planar fluence scored in a 1cm**2 circle '/
t5,'centered at z-axis on the phantom surface
=',1pe11.3,'(1/cm**2)'//
t5,'on the phantom surface =',1pe11.3,'(1/cm**2)'//
t10,'DOSXYZnrc ($Revision: 1.50 $) Dose outputs',
' Gy.cm**2 (or Gy/incident particle)');
]
]
}
;
IF(doseprint ~= 1)[
$PRINT-HEADER;
OUTPUT1;(/t5,'full dose output suppressed in this run');
]
ELSE[
DO idose=1,idgrp [
"Loop over groups of regions to analyse

IF(IZSCAN(idose) = 1) [
"Do output with one z scan per page
k = (kdosu(idose) - kdosl(idose));
k = k + k/5 + 7;
nperpg = 60/k; "Number of sets of depths per page";
IF(nperpg = 0)[
OUTPUT nperpg;(' Sets of depths per page = ',I2);
nperpg = 1;
OUTPUT nperpg;(' Set to = ',I2);
]
$PRINT-HEADER;
ipage=1; "Count how many zgroups printed on this page
DO i=idosl(idose),idosu(idose) [
DO j = jdosl(idose),jdosu(idose),4 [
JL=j;JU=min(j+3,jdosu(idose));
OUTPUT1 xbound(i),xbound(i+1),i;
(//t15,'for x=',f10.3,' to',f10.3,5x,'i=',i3);
OUTPUT1 (ybound(jj),jj=JL,JU+1);
(/' ybounds:',f7.3,f12.3,3f17.3);
OUTPUT1 (jj,jj=JL ,JU );(t10,'j=',t17,5(i4,13x));
OUTPUT1 zbound(kdosl(idose));(' zbounds (',f10.3,')');
DO k = kdosl(idose),kdosu(idose) [
OUTPUT1 zbound(k+1),k, (endep($IRD(i,jj,k)),
min(99.9d0, 100d0*endep2($IRD(i,jj,k))),jj=JL,JU);
(f8.3,i4,4(1pe11.3,'-',0pf4.1,'%') );
IF(mod(k,5) = 0)[OUTPUT1;(' ');]
]
IF( ( mod(ipage,nperpg) = 0) & ( ( JU ~= jdosu(idose) ) |
( i ~= idosu(idose) ))) [
$PRINT-HEADER;
ipage=1;
]
ELSE [ ipage = ipage+1; ]
]"end DO j"
]"end DO i"
]"end (IZSCAN(idose) ~= 0) block"

ELSEIF(IZSCAN(idose) = 0) [ "Output x scans each page
i = (idosu(idose) - idosl(idose));
i = i + i/5 + 7;
nperpg = 60/i; "Number of sets of bins per page
IF(nperpg = 0)[
OUTPUT nperpg;(' Sets of X scans per page = ',I2);
nperpg = 1;
OUTPUT nperpg;(' Set to = ',I2);
]
$PRINT-HEADER;
ipage=1;
DO k=kdosl(idose),kdosu(idose) [
DO j = jdosl(idose),jdosu(idose),4 [
JL=J;JU=min(j+3,jdosu(idose));
OUTPUT1 zbound(k),zbound(k+1),k;
(//t15,'for z=',f10.3,' to',f10.3,5x,'k=',i3);
OUTPUT1 (ybound(jj),jj=JL,JU+1);
(/' ybounds:',f7.3,f12.3,3f17.3);
OUTPUT1 (jj,jj=JL ,JU );(t10,'j=',t17,5(i4,13x));
OUTPUT1 xbound(idosl(idose));(' xbounds (',f10.3,')');
DO i = idosl(idose),idosu(idose) [
OUTPUT1 xbound(i+1),i, (endep($IRD(i,jj,k)),
min(99.9d0,
100d0*endep2($IRD(i,jj,k))),jj=JL,JU);
(f8.3,i4,4(1pe11.3,'-',0pf4.1,'%') );
IF(mod(i,5) = 0)[OUTPUT1;(' ');]
]
IF( ( mod(ipage,nperpg) = 0) & ( ( JU ~= jdosu(idose) ) |
( k ~= kdosu(idose) ))) [
$PRINT-HEADER;
ipage=1;
]
ELSE [ ipage = ipage+1; ]
]
]
]"end ELSE"
/*This was added HB: march 25 2008*/
ELSE ["Output y scans each page
j = (idosu(idose) - idosl(idose));
j = j + j/5 + 7;
nperpg = 60/j; "Number of sets of bins per page
IF(nperpg = 0)[
OUTPUT nperpg;(' Sets of Y scans per page = ',I2);
nperpg = 1;
OUTPUT nperpg;(' Set to = ',I2);
]
$PRINT-HEADER;
ipage=1;
DO k=kdosl(idose),kdosu(idose) [
DO i = idosl(idose),idosu(idose),4 [
JL=i;JU=min(i+3,idosu(idose));
OUTPUT1 zbound(k),zbound(k+1),k;
(//t15,'for z=',f10.3,' to',f10.3,5x,'k=',i3);
OUTPUT1 (xbound(jj),jj=JL,JU+1);
(/' xbounds:',f7.3,f12.3,3f17.3);
OUTPUT1 (jj,jj=JL ,JU );(t10,'i=',t17,5(i4,13x));
OUTPUT1 ybound(jdosl(idose));(' ybounds (',f10.3,')');
DO j = jdosl(idose),jdosu(idose) [
OUTPUT1 ybound(j+1),j, (endep($IRD(jj,j,k)),
min(99.9d0,
100d0*endep2($IRD(jj,j,k))),jj=JL,JU);
(f8.3,i4,4(1pe11.3,'-',0pf4.1,'%') );
IF(mod(j,5) = 0)[OUTPUT1;(' ');]
]
IF( ( mod(ipage,nperpg) = 0) & ( ( JU ~= idosu(idose) ) |
( k ~= kdosu(idose) ))) [
$PRINT-HEADER;
ipage=1;
]
ELSE [ ipage = ipage+1; ]
]
]


]"end ELSE"
/*End of addition*/
]

WRITE(1,'(''1'')'); "page throw under fortran control"
]

"if IPHANT is set to 1, write out a .egsphant file"
IF(IPHANT=1 & (n_parallel=0|(n_parallel>0 & is_finished)))[
call
write_phantom(ioutphant,nmed,media,estepm,IMAX,JMAX,KMAX,xbound,ybound,
zbound,rhor,med);
]

"zero doses in air in the .3ddose file if requested"
IF(zeroairdose = 1)[
DO i=1,IMAX[
DO j=1,JMAX[
DO k=1,KMAX[
IF(rhor($IR(i,j,k)) <= 0.044)[
endep($IRD(i,j,k))=0.0;
endep2($IRD(i,j,k))=0.9999999;
]
]
]
]
]

"Now zero doses with errors >50% in the .3ddose file if requested"
zerodose=$DOSEZERO;
zerocount=0;
IF(zerodose = 1)[
DO i=1,IMAX[
DO j=1,JMAX[
DO k=1,KMAX[
IF(endep2($IRD(i,j,k))>0.5 & endep($IRD(i,j,k)) > 0.0)[
endep($IRD(i,j,k))=0.0;
endep2($IRD(i,j,k))=0.9999999;
zerocount=zerocount+1;
]
]
]
]
]
IF(zerodose=1 & zerocount >0)[
OUTPUT61 zerocount;
(/' The dose values in ',I10,' voxels had error > 50% and have been'/
' zeroed in the .3ddose file.'/);
]

"subroutine call replaces a portion of code to write to .3ddose file"
"do not call if we are doing a parallel run"
IF((IPARALLEL <= 1 & n_parallel = 0) | (n_parallel > 0 & is_finished))[
call
write_dose(IMAX,JMAX,KMAX,xbound,ybound,zbound,endep,endep2,idd,MAX20);
]
ELSE [OUTPUT61;(//' No dose outputs since this is a parallel run '//);]


$SET_ELAPSED_CPUTIME(cput2);
timcpu=$CONVERSION_TO_SECONDS*(cput2-cput0);
OUTPUT61 timcpu,timcpu/3600.;
(/' Total CPU time for this run =',f8.1,' s =',f8.3,' hr');
IF(IRESTART=4)[
OUTPUT61;(/' CPU time is for combining .pardose files only.');
]
ELSEIF(n_parallel>0 & is_finished)[
OUTPUT61;(/' CPU time is for last run to finish only.');
]
CALL DATETIME(1);
OUTPUT61 DATEN, TIMEN; (/' END OF RUN ',A11,1X,A8/);

:END:;

call egs_finish; " Finish the simulation "

#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,'.pardose');
ainflu=temp2; "need to define this because it is used to
normalize dose"
IF((isource = 0 | isource = 1 | isource = 3 | isource = 7) &
beamarea>0.) ainflu=ainflu/beamarea;
goto :ANALYZE-PARALLEL:;
]
]
#endif;

IF(isource=9 | isource=21) call finish_beamsource;

IF((isource=20 | isource = 21) & MLCflag=1) [call finish_vcusource;]

$CALL_EXIT(0);

stop 'Normal completion in main routine';
end;
" end of main routine in dosxyznrc.mortran"
%E "dosxyznrc.mortran - start of subroutine ausgab"
"************************************************************************
*******
"
" ausgab
" ======
"
subroutine ausgab(iarg);
Copyright NRC 1999
"
"************************************************************************
*******
;
$IMPLICIT-NONE;
COMIN/EPCONT,SCORE,STACK,USER,RANDOM,SOURCE,GEOM,CH-Steps,MISC,MEDIA,
USEFUL/;
"SCORE has IWATCH, MXNP,NESTEP,DOSEIS"

$INTEGER iarg, "argument from EGSnrc (see SLAC-265, section A2.6, p260)"
ip; "looping variable"
$REAL XSI; "used to perform russian roulette on higher-order photons
when"
"n_split > 1"

"variables for howfarless option"
$INTEGER
irx,iry,irz,irold_loc,irnew_loc,outside,min_plane,iri,i,ii,jj,kk,
ibsearch,hwfl_rr,dirx,diry,dirz;
$REAL dist_loc, dist_tot, edep_loc, tv,t(2),xi,yi,zi,ui(2),vi(2),wi(2),
dist_tmp,x_tmp,y_tmp,z_tmp,edep_save,x_loc,y_loc,z_loc,
xpln,ypln,zpln,dnear_loc,t_tot,t_rnd,dist_max,uii,vii,wii,
distx,disty,distz,edep_frac;
LOGICAL ir_defined;
SAVE xi,yi,zi,ui,vi,wi,tv,iri,edep_save;
DATA edep_save/0.0/;

IF(IWATCH ~=0) call watch(iarg,IWATCH); "IWATCH passed in comin score

mxnp=max(mxnp,np); "Keep track of how deep stack gets
IF(np >= $MXSTACK) [ OUTPUT61 np, $MXSTACK;
(//' In ausgab, np=',i3,' >= maximum stack allowed which is',i3/
1X,79('*')//);
IF(mxnp > $MXSTACK) [OUTPUT61 np, $MXSTACK;
(//' In ausgab, np=',i3,' > maximum stack allowed which is',i3/
1X,79('*')//' Must stop - you must increase $MXSTACK in'/
' dosxyz_user_macros.mortran');
stop '*** Stack overflow ***'; "Must increase $MXSTACK"
]
]

IF( n_split > 1 ) [
IF( iarg = 7 | iarg = 13 | iarg = 14 ) ["perform russian roulette on
higher"
"order photons"
DO ip=NPold,NP [
IF( iq(ip) = 0 ) [
$RANDOMSET XSI;
IF( xsi*n_split > 1) [ wt(ip) = 0; e(ip) = 0; ]
ELSE [ wt(ip) = wt(ip)*n_split; ]
]
]
]
]

IF(howfarless & (iarg=15 | iarg=17 | iarg=19 | iarg=23) &
ir(np)<irmax+1)[
"photon about to create an electron or Rayleigh scatter"
"find current region"

IF(x(np)>xbound_max | x(np)<xbound_min |
y(np)>ybound_max | y(np)<ybound_min |
z(np)>zbound_max | z(np)<zbound_min )[
IF(enflag>1)[
ir(np)=irmax+1;
]
ELSE[
ir(np)=1;
]
]
ELSE[
irx=ibsearch(x(np),imax+1,xbound);
iry=ibsearch(y(np),jmax+1,ybound);
irz=ibsearch(z(np),kmax+1,zbound);
ir(np)=$IR(irx,iry,irz);
]
irold=ir(np);
]

IF(iarg >5) RETURN;

IF(howfarless & iarg>0 & edep_save>0.0)[ "howfarless version"
"Have energy to deposit along the path"
"Can enter here with iarg=1,2,3,4,5. If iarg=5, this is the end"
"of a normal step and we want to deposit energy. If iarg<5, then"
"this is the case where the particle is in the same region at the"
"beginning of the step as it was at the end of the step AND the"
"particle energy fell below ECUT,PCUT,AE or AP during the step."
"In this case, we want to deposit the energy from the step, which"
"is stored in edep_save and then fall through to the normal"
"energy deposition condition below where the remainder of the
particle"
"energy is deposited."

"estimate total curves step as two straight-line steps, t(1) and
t(2)"
"with a hinge point. Direction after hinge is ui(2),vi(2),wi(2)"


$DECODEIR(irold,irx,iry,irz);
IF( x(np) > xbound(irx) & x(np) < xbound(irx+1) &
y(np) > ybound(iry) & y(np) < ybound(iry+1) &
z(np) > zbound(irz) & z(np) < zbound(irz+1) ) [
"in case full step still leaves it within the voxel"
IF(nhist_last = endep_last(irold-1))[
"same shower that deposited energy last time in this region"
endep_tmp(irold-1) = endep_tmp(irold-1) + edep_save*wt(np);
]
ELSE["we have the next shower depositing energy into region
ir(np)"
" => put endep_tmp into the scoring arrays and set
endep_last"
endep(irold-1)=endep(irold-1)+endep_tmp(irold-1);
endep2(irold-1)=endep2(irold-1) +
endep_tmp(irold-1)*endep_tmp(irold-1);
endep_tmp(irold-1) = edep_save*wt(np);
endep_last(irold-1)=nhist_last;
]
irnew = irold;
]
ELSE ["step definitely takes it out of current voxel"

IF(~is_ch_step)["single scattering mode, set t1=tv"
t(1)=tv;
t(2)=0.;
]
ELSE["may have random hinge in step"
$RANDOMSET t_rnd;
IF(t_rnd<0.5)["base hinge on initial direction"
t(1)=1-((x(np)-xi)*ui(1)+(y(np)-yi)*vi(1)+(z(np)-zi)*wi(1))/tv;
IF(t(1)<1e-3)["do not bother with hinge, set t1=straight line"
"dist and reset initial u,v,w accordingly"
t(1)=SQRT((x(np)-xi)**2+(y(np)-yi)**2+(z(np)-zi)**2);
ui(1)=(x(np)-xi)/t(1);
vi(1)=(y(np)-yi)/t(1);
wi(1)=(z(np)-zi)/t(1);
t(2)=0.;
]
ELSE[
t(1)=(tv**2-(x(np)-xi)**2-(y(np)-yi)**2-(z(np)-
zi)**2)/(2*tv*t(1));
t(2)=tv-t(1);
ui(2)=((x(np)-xi)-t(1)*ui(1))/(tv-t(1));
vi(2)=((y(np)-yi)-t(1)*vi(1))/(tv-t(1));
wi(2)=((z(np)-zi)-t(1)*wi(1))/(tv-t(1));
]
]
ELSE["use final direction to calculate hinge"
ui(2)=u(np);
vi(2)=v(np);
wi(2)=w(np);
t(2)=1-((x(np)-xi)*ui(2)+(y(np)-yi)*vi(2)+(z(np)-zi)*wi(2))/tv;
IF(t(2)<1e-3)[
t(1)=SQRT((x(np)-xi)**2+(y(np)-yi)**2+(z(np)-zi)**2);
ui(1)=(x(np)-xi)/t(1);
vi(1)=(y(np)-yi)/t(1);
wi(1)=(z(np)-zi)/t(1);
t(2)=0.;
]
ELSE[
t(2)=(tv**2-(x(np)-xi)**2-(y(np)-yi)**2-(z(np)-
zi)**2)/(2*tv*t(2));
t(1)=tv-t(2);
ui(1)=((x(np)-xi)-t(2)*ui(2))/(tv-t(2));
vi(1)=((y(np)-yi)-t(2)*vi(2))/(tv-t(2));
wi(1)=((z(np)-zi)-t(2)*wi(2))/(tv-t(2));
]
]
]

t_tot=t(1)+t(2);
irold_loc=irold;
irnew_loc=irold_loc;
edep_frac=edep_save/t_tot;

outside=0;

DO i=1,2["steps t1 and t2"
IF(t(i)>0. & irold_loc>1)["do not take step if it is zero or"
"the particle is already outside the geom"
IF(i=2)[
xi=xi+ui(1)*t(1);
yi=yi+vi(1)*t(1);
zi=zi+wi(1)*t(1);
]
IF(ui(i)>0)[
uii=1./abs(ui(i));
dirx=1; distx=(xbound(irx+1)-xi)*uii;
]
ELSEIF(ui(i)<0)[
uii=1./abs(ui(i));
dirx=-1; distx=(xi-xbound(irx))*uii;
]
ELSE[
dirx=0; uii=0; distx=1e20;
]
IF(vi(i)>0)[
vii=1./abs(vi(i));
diry=1; disty=(ybound(iry+1)-yi)*vii;
]
ELSEIF(vi(i)<0)[
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
vii=1./abs(vi(i));
diry=-1; disty=(yi-ybound(iry))*vii;
]
ELSE[
diry=0; vii=0; disty=1e20;
]
IF(wi(i)>0)[
wii=1./abs(wi(i));
dirz=1; distz=(zbound(irz+1)-zi)*wii;
]
ELSEIF(wi(i)<0)[
wii=1./abs(wi(i));
dirz=-1; distz=(zi-zbound(irz))*wii;
]
ELSE[
dirz=0; wii=0; distz=1e20;
]
dist_tot=0.;
LOOP[
dist_max=t(i)-dist_tot;
IF(distx<disty & distx<distz & distx<dist_max)[
dist_loc=distx;
irx=irx+dirx;
IF(irx>0 & irx<=IMAX)[
disty=disty-distx;
distz=distz-distx;
irnew_loc=irold_loc+dirx;
distx=(xbound(irx+1)-xbound(irx))*uii;
]
ELSE[outside=1;]
]
ELSEIF(disty<distz & disty<dist_max)[
dist_loc=disty;
iry=iry+diry;
IF(iry>0 & iry<=JMAX)[
distx=distx-disty;
distz=distz-disty;
irnew_loc=irold_loc+diry*IMAX;
disty=(ybound(iry+1)-ybound(iry))*vii;
]
ELSE[outside=1;]
]
ELSEIF(distz<dist_max)[
dist_loc=distz;
irz=irz+dirz;
IF(irz>0 & irz<=KMAX)[
distx=distx-distz;
disty=disty-distz;
irnew_loc=irold_loc+dirz*ijmax;
distz=(zbound(irz+1)-zbound(irz))*wii;
]
ELSE[outside=1;]
]
ELSE[dist_loc=dist_max;]

edep_loc=dist_loc*edep_frac;"fraction of total energy in step"

IF(nhist_last = endep_last(irold_loc-1))[
"same shower that deposited energy last time in this region"
endep_tmp(irold_loc-1) = endep_tmp(irold_loc-1) +
edep_loc*wt(np);
]
ELSE["we have the next shower depositing energy into region
ir(np)"
" => put endep_tmp into the scoring arrays and set
endep_last"
endep(irold_loc-1)=endep(irold_loc-1)+endep_tmp(irold_loc-1);
endep2(irold_loc-1)=endep2(irold_loc-1) +
endep_tmp(irold_loc-1)*endep_tmp(irold_loc-1);
endep_tmp(irold_loc-1) = edep_loc*wt(np);
endep_last(irold_loc-1)=nhist_last;
]

IF(outside=1)["set it to outside region"
IF(enflag>1)[irnew_loc=irmax+1;]
ELSE[irnew_loc=1;]
]

irold_loc=irnew_loc;
dist_tot=dist_tot+dist_loc;
]UNTIL(dist_tot>=t(i)|outside=1);
]
]
irnew=irnew_loc;"define irnew at end of charged particle step"
IF(irnew~=irold)ir(np)=irnew;
]
]

IF(iarg = 0 & iq(np)~=0) nestep = nestep + 1;
"count total number of charged particle steps"

IF(howfarless)[
edep_save=0.0;
hwfl_rr=0;
]

IF(iarg=5)RETURN;

IF(ir(np)>1 & edep~=0.0)[

IF(iarg=0 & howfarless & ir(np)<irmax+1)[

$DECODEIR(ir(np),irx,iry,irz);

"calculate dnear to voxel boundary"
dnear_loc=min(xbound(irx+1)-x(np),x(np)-xbound(irx),
ybound(iry+1)-y(np),y(np)-ybound(iry),
zbound(irz+1)-z(np),z(np)-zbound(irz));
IF(IREJECT=1 & dnear_loc > e_range-RANGE_ECUTRR(MED(IR(NP)))*
RHO(MED(IR(NP)))/RHOR(IR(NP)))[
"charged particle range rejection"
"dump energy in current voxel"
edep=e(np)-prm;
hwfl_rr=1;
]
ELSEIF(dnear_loc < vstep)["step leaves voxel"
"save particle initial position, direction, energy deposited"
xi=x(np);yi=y(np);zi=z(np);
ui(1)=u(np);vi(1)=v(np);wi(1)=w(np);
edep_save=edep;
"also, save total curved path step length"
IF(~is_ch_step)[
"this is step to a boundary, no random hinge"
tv=vstep;
]
ELSE[
"condensed history step, set tv equal to total curved
pathlength"
tv=tvstep;
]
RETURN; "do energy deposition after step"
]
]

"if it gets here it is one of: a) normal transport without using"
"howfarless option b) howfarless option with iarg=1,2,3,4"
"(ECUT,PCUT discard) c) howfarless option with iarg=0 (step about"
"to occur) and particle range rejected d) howfarless option with"
"iarg=0 and particle step does not take it outside the current voxel"
"e) howfarless version with particle in region irmax+1 (dsurround)"

IF(nhist_last = endep_last(ir(np)-1))[
"same shower that deposited energy last time in this region"
endep_tmp(ir(np)-1) = endep_tmp(ir(np)-1) + edep*wt(np);
]
ELSE["we have the next shower depositing energy into region ir(np)"
" => put endep_tmp into the scoring arrays and set endep_last"
endep(ir(np)-1)=endep(ir(np)-1)+endep_tmp(ir(np)-1);
endep2(ir(np)-1)=endep2(ir(np)-1) +
endep_tmp(ir(np)-1)*endep_tmp(ir(np)-1);
endep_tmp(ir(np)-1) = edep*wt(np);
endep_last(ir(np)-1)=nhist_last;
]
" note endep region # = region number - 1, i.e., endep(1) for region
2,etc"

IF(howfarless & hwfl_rr=1)[
IF(iq(np)=-1)[
np=np-1;
]
ELSEIF(iq(np)=1)[
call annih_at_rest;
]
iarg=-1; "forces return from ELECTR or PHOTON"
]
]

return;end;
%E "dosxyznrc.mortran - start of subroutine howfar"
"************************************************************************
*******
"
" howfar
" ======
"
subroutine howfar;
Copyright NRC 1999

" howfar routine to use with a generalized cartesian coordinate system
"
" Routine is optimized for speed - please suggest improvements
"
" Geometrical information is passed in COMIN/GEOM,SOURCE/
"
" xbound($IMAX),ybound($JMAX),zbound($KMAX),IMAX,JMAX,KMAX,ijmax,irmax
" xbound etc are the x, y and z boundaries defining the voxels
" $IMAX etc are the maximum number of elements in each direction
" as defined in the users main program
" IMAX etc are the actual number of elements in each direction for
" this particular calculation
" ijmax = IMAX*JMAX a useful number
" irmax = 1 + ijmax*ikmax the total number of regions in the
" current problem
" region 1 is the exterior region and signifies particle left geometry
" region irmax+1 is the surrounding air region if it exists.
"
" Each voxel is defined by a triple of integers (i,j,k) (but called
" irx,iry and irz in this routine) such that:
"
" xbound(i) <= x < xbound(i+1) 1 < i < IMAX
" ybound(j) <= y < ybound(j+1) 1 < j < JMAX
" zbound(k) <= z < zbound(k+1) 1 < k < KMAX
"
" The x axis is to the right, y axis down the page and z into the page
"
" The region number is defined as:
" ir = 1 + i + (j-1)*IMAX + (k-1)*ijmax
"
" The routine sets dnear. Note that in problems where the typical
" step size is of the order of the region dimensions, then computing
" dnear can decrease efficiency. In this case the two lines containing
" dnear should be commented out
"
" The routine assumes $DECODEIR(irl,i,j,k) is expanded to calculate
" i,j,k given irl, the current region
"
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
" Equivalence statements are used to allow variable names to be used
" in the main macro for each direction
"
" Version 1 April 1986 D.W.O.Rogers, NRCC
" Added coding for the surrounding air region April 1996 C.-M. Ma, NRCC
"
"************************************************************************
*******
;
$IMPLICIT-NONE;

;COMIN/EPCONT,GEOM,STACK,SOURCE/;

INTEGER ione, "set to 1"
irl, "absolute region number"
i,j,k, "loop counters"
irx,iry,irz; "voxel x,y,z indices"

$REAL dnearl, "perpendicular distance to boundary"
dist, "distance to boundary along particle trajectory"
xsrcp,ysrcp,zsrcp;
"x,y,z positions where incident particle hits
geometry"

data ione/1/;

irl = ir(np);

"now, find dnear"
$CALL-HOWNEAR(dnearl);
dnear(np)=dnearl;

IF(irl=1)[idisc = 1;return;"have left geometry"]

ELSEIF(irl = irmax + 1)["begin in region surrounding the phantom"

"introduce this check to deal with reflection right on the boundary
"of the dsurround region. This was found to be a problem as soon
"as the use of multiple dsurrounds was introduced
" IF(z(np)>zbound_min & z(np)<zbound_max & x(np)>xbound_min &
" x(np)<xbound_max & y(np)>ybound_min & y(np)<ybound_max)[
" dist=0.;
" ustep=dist;
" IF(irold<irmax+1)[particle reflecting back into dsurround"
" irnew=irold;
" return;
" ]
" ELSE[put the particle in the right region within the phantom"
" OUTPUT61;
" (' ***Warning: irold=ir(np)=irmax+1 (ie the dsurround region) but'/
" ' particle is in the phantom. Putting particle in '/
" ' correct region now.');
" irx=0;
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
" LOOP[irx=irx+1;]UNTIL(xbound(irx)<=x(np) &
xbound(irx+1)>x(np));
" iry=0;
" LOOP[iry=iry+1;]UNTIL(ybound(iry)<=y(np) &
ybound(iry+1)>y(np));
" irz=0;
" LOOP[irz=irz+1;]UNTIL(zbound(irz)<=z(np) &
zbound(irz+1)>z(np));
" irnew=$IR(irx,iry,irz);
" return;
" ]
" ]
IF(u(np) > 0.0) [
"Going towards lower x-plane
dist = (xbound_min - x(np))/u(np); "Distance to boundary
IF(dist>0.)[
ysrcp = y(np) + dist*v(np); "possible contact point..."
zsrcp = z(np) + dist*w(np);
IF ( (ysrcp >= ybound_min) & (ysrcp <= ybound_max) &
(zsrcp >= zbound_min) & (zsrcp <= zbound_max)) [
"Hits the lower x-plane, search for the entrance region
number
DO j=1,JMAX [
IF( (ybound(j) <= ysrcp) & (ysrcp <= ybound(j+1)) ) [
DO k=1,KMAX [
IF( (zbound(k) <= zsrcp) & (zsrcp <= zbound(k+1)) )
[
IF(dist < ustep) [
ustep = dist;
irnew = IMAX*j + klowx + ijmax*k;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]"end of do"
]
]
stop ' * Stopped in howfar on lower x-plane. Cannot find
irnew! *';
]
]
]
ELSEIF(u(np) < 0.0) [ "Going towards upper x-plane
dist = (xbound_max - x(np))/u(np); "Distance to boundary
IF(dist>0.)[
ysrcp = y(np) + dist*v(np); "possible contact point..."
zsrcp = z(np) + dist*w(np);
IF ( (ysrcp >= ybound_min) & (ysrcp <= ybound_max) &
(zsrcp >= zbound_min) & (zsrcp <= zbound_max)) [
"Hits the upper x-plane, search for the entrance region
number
DO j=1,JMAX [
IF( (ybound(j) <= ysrcp) & (ysrcp <= ybound(j+1)) )[
DO k=1,KMAX [
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
IF((zbound(k)<= zsrcp)&(zsrcp<= zbound(k+1)))[
IF(dist < ustep) [
ustep = dist;
irnew = IMAX*j + khix + ijmax*k;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]
]
]
stop ' * Stopped in howfar on upper x-plane. Cannot find
irnew! *';
]
]
]
IF(v(np) > 0.0) [
"Going towards lower y-plane
dist = (ybound_min - y(np))/v(np); "Distance to boundary
IF(dist>0.)[
xsrcp = x(np) + dist*u(np); "possible contact point"
zsrcp = z(np) + dist*w(np);
IF ( (xsrcp >= xbound_min) & (xsrcp <= xbound_max) &
(zsrcp >= zbound_min) & (zsrcp <= zbound_max)) [
"Hits the lower y-plane, search for the entrance region
number
DO i=1,IMAX [
IF( (xbound(i) <= xsrcp) & (xsrcp <= xbound(i+1)) ) [
DO k=1,KMAX [
IF( (zbound(k) <= zsrcp) & (zsrcp <= zbound(k+1)))[
IF(dist < ustep) [
ustep = dist;
irnew = i + klowy + ijmax*k;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]
]
]
stop ' * Stopped in howfar on lower y-plane. Cannot find irnew!
*';
]
]
]
ELSEIF(v(np) < 0.0) [ "Going towards upper y-plane
dist = (ybound_max - y(np))/v(np); "Distance to boundary
IF(dist>0.)[
xsrcp = x(np) + dist*u(np); "possible contact point"
zsrcp = z(np) + dist*w(np);
IF ( (xsrcp >= xbound_min) & (xsrcp <= xbound_max) &
(zsrcp >= zbound_min) & (zsrcp <= zbound_max)) [
"Hits the upper y-plane, search for the entrance region
number
DO i=1,IMAX [
IF( (xbound(i) <= xsrcp) & (xsrcp <= xbound(i+1)) ) [
DO k=1,KMAX [
IF( (zbound(k) <= zsrcp) & (zsrcp <= zbound(k+1)) )
[
IF(dist < ustep) [
ustep = dist;
irnew = i + khiy + ijmax*k;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]
]
]
stop ' * Stopped in howfar on upper y-plane. Cannot find irnew!
*';
]
]
]
IF(w(np) > 0.0) [ "Going towards lower z-plane
dist = (zbound_min - z(np))/w(np); "Distance to boundary
IF(dist>0.)[
xsrcp = x(np) + dist*u(np); "possible contact point"
ysrcp = y(np) + dist*v(np);
IF ( (xsrcp >= xbound_min) & (xsrcp <= xbound_max) &
(ysrcp >= ybound_min) & (ysrcp <= ybound_max)) [
"Hits the lower z-plane, search for the entrance region
number
DO i=1,IMAX [
IF( (xbound(i) <= xsrcp) & (xsrcp <= xbound(i+1)) ) [
DO j=1,JMAX [
IF( (ybound(j) <= ysrcp) & (ysrcp <= ybound(j+1)) ) [
IF(dist < ustep) [
ustep = dist;
irnew = i + klowz + IMAX*j;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]
]
]
stop ' * Stopped in howfar on lower z-plane. Cannot find irnew!
*';
]
]
]
ELSEIF(w(np) < 0.0) [ "Going towards upper z-plane
dist = (zbound_max-z(np))/w(np); "Distance to boundary
IF(dist>0.)[
xsrcp = x(np) + dist*u(np); "possible contact point"
ysrcp = y(np) + dist*v(np);
IF ( (xsrcp >= xbound_min) & (xsrcp <= xbound_max) &
(ysrcp >= ybound_min) & (ysrcp <= ybound_max)) [
"Hits the upper z-plane, search for the entrance region
number
DO i=1,IMAX [
IF( (xbound(i) <= xsrcp) & (xsrcp <= xbound(i+1)) ) [
DO j=1,JMAX [
IF( (ybound(j) <= ysrcp) & (ysrcp <= ybound(j+1)) ) [
IF(dist < ustep) [
ustep = dist;
irnew = i + khiz + IMAX*j;
]
ELSE[irnew=ir(np);"still in the air region"]
return; "No other solution possible
]
]
]
]
stop ' * Stopped in howfar on upper z-plane. Cannot find irnew!
*';
]
]
]

"If gets here => still in air, discard it if far away from the
phantom"
IF(u(np)>0.)[xsrcp=(xbound_max+dsurround(1)-x(np))/u(np);]
ELSEIF(u(np)<0.)[xsrcp=(xbound_min-dsurround(1)-x(np))/u(np);]
ELSE[xsrcp=1.0E10;]
IF(v(np)>0.)[ysrcp=(ybound_max+dsurround(2)-y(np))/v(np);]
ELSEIF(v(np)<0.)[ysrcp=(ybound_min-dsurround(2)-y(np))/v(np);]
ELSE[ysrcp=1.0E10;]
IF(w(np)>0.)[zsrcp=(zbound_max+dsurround(3)-z(np))/w(np);]
ELSEIF(w(np)<0.)[zsrcp=(zbound_min-dsurround(4)-z(np))/w(np);]
ELSE[zsrcp=1.0E10;]
dist=min(xsrcp,ysrcp,zsrcp);
IF(dist< ustep)[
ustep=dist;
irnew=1;"the particle is going out of the air region"
]
ELSE[irnew=ir(np);"still in the surrounding air region"]

]"end of checking in the surrounding air"
ELSEIF(howfarless)["just check against outer bounds of phantom"

dist=1e20;

IF(w(np) > 0.0) [
"Going towards upper plane"
dist = min(dist,(zbound_max-z(np))/w(np));"Distance to boundary"
]
ELSEIF(w(np) < 0.0) [ "Going towards inner plane"
dist = min(dist,-( z(np) - zbound_min)/w(np));
]
IF(u(np) > 0.0) [
"Going towards max plane"
dist = min(dist,(xbound_max-x(np))/u(np));"Distance to boundary"
]
ELSEIF(u(np) < 0.0) [ "Going towards inner plane"
dist = min(dist,-( x(np) - xbound_min)/u(np));
]
IF(v(np) > 0.0) [
"Going towards max plane"
dist = min(dist,(ybound_max-y(np))/v(np));"Distance to boundary"
]
ELSEIF(v(np) < 0.0) [ "Going towards inner plane"
dist = min(dist,-( y(np) - ybound_min)/v(np));
]

IF(dist < ustep)[
ustep=dist;
IF(enflag > 1)[irnew=irmax+1;"entering dsurround territory"]
ELSE[irnew=1; "Leaving entire geometry" ]
]
ELSE[
irnew=irl; "irnew gets set properly in ausgab before step is
taken"
]
return;
]
ELSE["full HOWFAR"

$DECODEIR(irl,irx,iry,irz);

"code below used to be in a macro called $CHECK-IN-#-DIRECTION"
"macro was eliminated to get rid of equivalence statments in hopes"
"of speeding up execution time"

IF(w(np) > 0.0) [
"Going towards outer plane"
dist = (zbound(irz+1)-z(np))/w(np);"Distance to boundary"
IF(dist < ustep)[ustep=dist;
IF(irz ~= KMAX) [ irnew=irl+ijmax; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew=1; "Leaving entire geometry" ]
"Note this only assigns irnew correctly if no other
boundaries are "
"crossed first - but if they are, irnew will be set correctly
there"
]
]
ELSEIF(w(np) < 0.0) [ "Going towards inner plane"
dist = -( z(np) - zbound(irz))/w(np);
IF(dist < ustep) [
ustep = dist;
IF(irz ~= 1) [ irnew=irl-ijmax; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew = 1; "leaving geometry" ]
]
]
IF(u(np) > 0.0) [
"Going towards outer plane"
dist = (xbound(irx+1)-x(np))/u(np);"Distance to boundary"
IF(dist < ustep)[ustep=dist;
IF(irx ~= IMAX) [ irnew=irl+ione; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew=1; "Leaving entire geometry" ]
"Note this only assigns irnew correctly if no other
boundaries are "
"crossed first - but if they are, irnew will be set correctly
there"
]
]
ELSEIF(u(np) < 0.0) [ "Going towards inner plane"
dist = -( x(np) - xbound(irx))/u(np);
IF(dist < ustep) [
ustep = dist;
IF(irx ~= 1) [ irnew=irl-ione; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew = 1; "leaving geometry" ]
]
]
IF(v(np) > 0.0) [
"Going towards outer plane"
dist = (ybound(iry+1)-y(np))/v(np);"Distance to boundary"
IF(dist < ustep)[ustep=dist;
IF(iry ~= JMAX) [ irnew=irl+IMAX; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew=1; "Leaving entire geometry" ]
"Note this only assigns irnew correctly if no other
boundaries are "
"crossed first - but if they are, irnew will be set correctly
there"
]
]
ELSEIF(v(np) < 0.0) [ "Going towards inner plane"
dist = -( y(np) - ybound(iry))/v(np);
IF(dist < ustep) [
ustep = dist;
IF(iry ~= 1) [ irnew=irl-IMAX; ]
ELSEIF(enflag > 1)[irnew=irmax+1;"entering dsurround
territory"]
ELSE [ irnew = 1; "leaving geometry" ]
]
]
return;
]
end;
%E "dosxyznrc.mortran - start of subroutine hownear"
"************************************************************************
*******
"
" hownear
" =======
"
SUBROUTINE HOWNEAR (TPERP,X,Y,Z,IRL);
Copyright NRC 1999

" hownear routine to use with a generalized cartesian coordinate system
"

$IMPLICIT-NONE;

COMIN/GEOM/;

" subroutine parameters:
$REAL TPERP, "the perpendicular distance to the nearest region boundary"
X, "the X position of the particle"
Y, "Y position"
Z; "Z position"

$INTEGER IRL; "absolute region number of particle"

"internal variables"
$INTEGER IRX,IRY,IRZ; "indices of voxel that particle is in"

TPERP=1.e10;
IF(IRL=1)[TPERP=0;] "exiting geometry"
ELSEIF(IRL=irmax+1)["in dsurround region"
IF((X>=xbound_min & X<=xbound_max & Y>=ybound_min &
Y<=ybound_max) & (Z>=zbound_max | Z<=zbound_min))[
TPERP=MIN(TPERP,ABS(Z-zbound_min),ABS(Z-zbound_max));
]
ELSE[
IF(Y>=ybound_min & Y<=ybound_max &
(X<=xbound_min | X>=xbound_max))[
TPERP=MIN(TPERP,ABS(X-xbound_min),ABS(X-xbound_max));
]
ELSEIF(X>=xbound_min & X<=xbound_max &
(Y<=ybound_min | Y>=ybound_max))[
TPERP=MIN(TPERP,ABS(Y-ybound_min),ABS(Y-ybound_max));
]
ELSEIF((X>=xbound_max | X<=xbound_min) &
(Y>=ybound_max | Y<=ybound_min))[
TPERP=MIN(TPERP**2,(X-xbound_max)**2+(Y-ybound_max)**2,
(X-xbound_max)**2+(Y-ybound_min)**2,
(X-xbound_min)**2+(Y-ybound_max)**2,
(X-xbound_min)**2+(Y-ybound_min)**2);
TPERP=SQRT(TPERP);
]
ELSE[
TPERP=0.;
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
]
IF(Z<zbound_min)[
TPERP=SQRT(TPERP**2+(Z-zbound_min)**2);
]
ELSEIF(Z>zbound_max)[
TPERP=SQRT(TPERP**2+(Z-zbound_max)**2);
]
]
TPERP=MIN(TPERP,ABS(X-(xbound_min-dsurround(1))),
ABS(X-(xbound_max+dsurround(1))),
ABS(Y-(ybound_min-dsurround(2))),
ABS(Y-(ybound_max+dsurround(2))),
ABS(Z-(zbound_min-dsurround(4))),
ABS(Z-(zbound_max+dsurround(3))));
]
ELSEIF(howfarless)[
TPERP=MIN(TPERP,X-xbound_min,xbound_max-X,
Y-ybound_min,ybound_max-Y,
Z-zbound_min,zbound_max-Z);
]
ELSE["within phantom"
;$DECODEIR(IRL,IRX,IRY,IRZ);
TPERP=min(TPERP,(xbound(irx+1)-X),(X-xbound(irx)));
TPERP=min(TPERP,(ybound(iry+1)-Y),(Y-ybound(iry)));
TPERP=min(TPERP,(zbound(irz+1)-Z),(Z-zbound(irz)));
]
return;
end;
"************************************************************************
******
SUBROUTINE DATETIME(DUMMY);
Copyright NRC 1999

"calls the macros CALL DATE and CALL TIME to assign the current date and
time
"to DATEN and TIMEN, respectively. A subroutine is used to call the
macros so
"that machine-dependent date and time routines are all contained here.
"************************************************************************
******
$IMPLICIT-NONE;
;COMIN/TIMEINFO/; INTEGER DUMMY; "just a dummy variable"
"CALL DATE(DATEN); CALL TIME(TIMEN);"
"IK: use the EGSnrc egs_fdate function instead. "
call egs_get_fdate(DNTIME);
daten(1:7)=dntime(5:11);
daten(8:11)=dntime(21:24);
timen(1:8)=dntime(12:19);
RETURN; end;
%E "dosxyznrc.mortran - start of subroutine write_dose"
"************************************************************************
******

subroutine write_dose(iimax,jjmax,kkmax,xbnd,ybnd,zbnd,dd,ddun,unitnum,
writemax20);

Copyright NRC 1999

"Writes dose to file designated by unitnum. Currently the subroutine
only
"writes in the .3ddose format (unitnum=3) and replaces a portion of the
"main code. However, this subroutine will eventually output the dose in
"other formats as well.

"3 possible methods of specifying the array sizes for dd and ddun, the
"dose and dose uncertainty arrays in this subroutine, were explored. The
"first method passed $MAXDOSE as a parameter to the subroutine. The
second
"method, which ended up being the method used, calculated the required
size
"using iimax*jjmax*kkmax+1. The third method specified dd and ddun as
"dd(1) and ddun(1), which maps the start of these arrays onto their
"counterparts in the main program (dose and doseun, respectively) and
ensures
"that they are as large as dose and doseun. The following table
summarizes
"the size and resident in memory requirements (determined using top.new)
"for compiling and a simple test run using each of the three array size
"methods. The version of dosxyz used for these tests had IMAX=512,
JMAX=512,
"KMAX=10.
"
" method compile run
" ------ max. size max. res in mem. max. size max. res. in
mem.
" -------- -------------- --------- -------------
---
"
" before write_dose
" added 90M 55M 95M 22M
"
" pass $MAXDOSE 90M 62M 95M 22M
"iimax*jjmax*kkmax+1 90M 59M 95M 22M
" dd(1),ddun(1) 90M 54M 95M 22M
"
"The test run case used 20x20x10 voxels to define a 20x20x10cm volume.
"Incident beam was 10x0cm of 15MeV electrons.
"
"iimax*jjmax*kkmax+1 was favoured because it did not involve passing yet
"another parameter (ie $MAXDOSE) and it would allow the user to run in
"debug mode with error boundaries (which using DD(1),DDUN(1) would not).
"************************************************************************
******
;
"Information which MUST be available to use this routine to plot dose:
"1) number of voxels in the x,y,z directions (iimax,jjmax,kkmax)
"2) 1-D array of real numbers containing voxel boundaries (in cm)
" in x,y,z directions (xbnd,ybnd,zbnd). Data in these matrices is
" arranged so that xbnd(i+1) is the upper boundary of voxel i in the x
" direction, and xbnd(i) is the lower boundary of voxel i in the x
" direction.
"3) 1-D array of real numbers containing dose/unit fluence (Gy/cm^2) in
every
" voxel (dd). 3-D dose distribution must be collapsed into this 1-D
" array using the scheme:
" dose(i,j,k)=dd(i+(j-1)*iimax+(k-1)*iimax*jjmax)
" where dose(i,j,k) is the dose in voxel (i,j,k)
"4) 1-D array of real numbers containing the dose uncertainty expressed
" as a fraction of dose in every voxel (ddun).
" 3-D dose uncertainty distribution must be collapsed into the 1-D
array
" in the same manner as in 3)
"
;IMPLICIT NONE;
INTEGER iimax, "max number of x cells"
jjmax, "max number of y cells"
kkmax, "max number of z cells"
ijkmax, "iimax*jjmax*kkmax"
irtmp, "tmp variable to hold ir"
writemax20, "1 for summary of max 20 doses"
unitnum, "unit number in which to write data"
ii,jj,kk,mm,nn, "indices"
NUMFRAC, "number of voxels for av. rel.
uncertainty"
MAXI(20),MAXJ(20),MAXK(20),"indices for max 20 doses"
egs_open_file;
REAL xbnd($IMAX+1), "voxel x boundaries"
ybnd($JMAX+1), "voxel y boundaries"
zbnd($KMAX+1), "voxel z boundaries"
MAXDOS(20), "maximum 20 doses"
MAXDOSAVG, "average of max 20 doses"
ERRMAXDOSAVG, "average of error of max 20 doses"
ERR50AVG, "average % error of doses > 50% of max
dose"
ERR50FRAC, "average error of doses > 50% of max"
" dose as a fraction of max dose"
DOSEFRAC, "fraction for calculating av. rel.
uncertainty"
DOSEmin, "DOSEFRAC*MAXDOS(1)"
ARUFRAC; "average relative uncertainty on all
voxels"
"with dose > DOSEFRAC*Dmax"

REAL*8 dd($MAXDOSE), "linear array of doses"
ddun($MAXDOSE); "linear array of dose uncertainties"

REPLACE {$PLOTOUT#;} WITH {write(unitnum,*){P1};}
REPLACE {$IRDWD(#,#,#)} WITH {({P1}+({P2}-1)*iimax+({P3}-1)*iimax*jjmax)}

"open the .3ddose file for output"
unitnum=egs_open_file(unitnum,0,1,'.3ddose');

$PLOTOUT iimax,jjmax,kkmax;
$PLOTOUT (xbnd(ii),ii=1,iimax+1);
$PLOTOUT (ybnd(jj),jj=1,jjmax+1);
$PLOTOUT (zbnd(kk),kk=1,kkmax+1);
$PLOTOUT (((dd($IRDWD(ii,jj,kk)),ii=1,iimax),jj=1,jjmax),kk=1,kkmax);
$PLOTOUT (((ddun($IRDWD(ii,jj,kk)),ii=1,iimax),jj=1,jjmax),kk=1,kkmax);

close(unitnum);

ijkmax=iimax*jjmax*kkmax;

IF(writemax20=1)["print out maximum 20 doses"
DO mm=1,20 [ MAXDOS(mm)=0.0; ]
DO ii=1,iimax[
DO jj=1,jjmax[
DO kk=1,kkmax[
irtmp = $IRDWD(ii,jj,kk);
DO mm=1,min(20,ijkmax) [
IF(dd(irtmp)>=MAXDOS(mm))[
DO nn=min(20,ijkmax),mm+1,-1 [
MAXDOS(nn)=MAXDOS(nn-1);
MAXI(nn)=MAXI(nn-1);
MAXJ(nn)=MAXJ(nn-1);
MAXK(nn)=MAXK(nn-1);
]
MAXDOS(mm)=dd(irtmp);
MAXI(mm)=ii;
MAXJ(mm)=jj;
MAXK(mm)=kk;
EXIT;
]
]
]
]
]

MAXDOSAVG=0.;
ERRMAXDOSAVG=0.;
DO mm=1,min(20,ijkmax) [
MAXDOSAVG=MAXDOSAVG+MAXDOS(mm);
ERRMAXDOSAVG=ERRMAXDOSAVG+ddun($IRDWD(MAXI(mm),MAXJ(mm),MAXK(mm)));
]
MAXDOSAVG=MAXDOSAVG/float(min(20,ijkmax));
ERRMAXDOSAVG=ERRMAXDOSAVG/float(min(20,ijkmax));

"now find average error of doses > DOSEFRAC*dose_maximum of max dose"
"We calculate two ways, one taking straight average, the other"
"summing the fractional variance and then taking the square root"
"The later was added Dec 1999 after Iwan Kawrakow suggested that"
"this parameter was independent of how many batches are used"

ERR50AVG=0.;
ERR50FRAC=0.;
DOSEFRAC=0.5;
DOSEmin = DOSEFRAC*MAXDOS(1);
ARUFRAC=0.;
NUMFRAC=0;
DO ii=1,iimax[
DO jj=1,jjmax[
DO kk=1,kkmax[
irtmp = $IRDWD(ii,jj,kk);
IF(dd(irtmp) > DOSEmin )[
ERR50AVG =ERR50AVG +ddun(irtmp); "ave % uncertainty"
ERR50FRAC=ERR50FRAC+ddun(irtmp)*dd(irtmp); "ave abs.
uncertainty"
ARUFRAC =ARUFRAC +ddun(irtmp)**2;
"ave % uncertainty in quadrature"
NUMFRAC =NUMFRAC+1;
]
]
]
]

IF( (NUMFRAC ~= 0) & (MAXDOS(1) ~= 0.0)) [
ERR50AVG=ERR50AVG/NUMFRAC;
ERR50FRAC=ERR50FRAC/(NUMFRAC*MAXDOS(1));
ARUFRAC=SQRT(ARUFRAC/NUMFRAC);
]
ELSE[
OUTPUT DOSEFRAC;
(' Statistics really bad - analysis of average relatative
uncertainty'/
' on voxels with dose > ',F12.5,'*Dmax is meaningless');
]


OUTPUT61 min(20,ijkmax), MAXDOSAVG, min(20,ijkmax), ERRMAXDOSAVG*100.,
DOSEFRAC, ERR50AVG*100., DOSEFRAC,
ERR50FRAC*100, DOSEFRAC, ARUFRAC*100., NUMFRAC, DOSEFRAC,
min(20,ijkmax);
(/' average of ',I2,' highest doses = ',T62,E12.5,' Gy/particle'/
' average % error of ',I2,' highest doses = ',T60,F9.3,' %'/
' average % error of doses >',F7.3,' of max dose = ',T60,F9.3,' %'/
' (average error of doses >',F7.3,' of max dose)/(max dose)
=',T60,F9.3,' %'/
' quadrature average % error of doses >',F7.3,' of max dose
=',T60,F9.3,' %'/
' There are ',I11,' voxels with dose > ',F7.3,' of max dose ' //
' ',I2,' highest doses: '/
' '/
' dose (Gy/particle) (x,y,z) (cm)'/
' ----------------- ------------'/);

DO mm=1,min(20,ijkmax) [
OUTPUT61 MAXDOS(mm),ddun($IRDWD(MAXI(mm),MAXJ(mm),MAXK(mm)))*100,
(xbnd(MAXI(mm)+1)+xbnd(MAXI(mm)))/2.,
(ybnd(MAXJ(mm)+1)+ybnd(MAXJ(mm)))/2.,
(zbnd(MAXK(mm)+1)+zbnd(MAXK(mm)))/2.;
(' ',E12.5,' +/- ',F12.5,' % ( ',F12.5,',',F12.5,',',F12.5,' )');
]
]

RETURN;
end;

%E "dosxyznrc.mortran - start of subroutine write_phantom"
"************************************************************************
******
"
subroutine write_phantom(iunit,nmed,media,estepe,
iimax,jjmax,kkmax,xbnd,ybnd,zbnd,
rho,med);
"
"This subroutine writes out a .egsphant file so that dosxyz_show can be"
"used to view dose contours when not using CT data"
"It is a slightly modified form of write_phantom found in
ctcreate.mortran"
"************************************************************************
******
;IMPLICIT NONE;
Character*4 media(24,$MXMED); "Media names"
INTEGER iunit, "fort.iunit = .egsphant file"
nmed, "number of media"
iimax, "max number of x cells"
jjmax, "max number of y cells"
kkmax, "max number of z cells"
ii,jj,kk, "indices"
egs_open_file;
$SHORT_INT med($MXREG); "linear array of media numbers"
REAL xbnd($IMAX+1), "voxel x boundaries"
ybnd($JMAX+1), "voxel y boundaries"
zbnd($KMAX+1), "voxel z boundaries"
estepe($MXMED); "linear array of estepe values"
$REAL rho($MXREG);


REPLACE {$IRWP(#,#,#)} WITH {(1 + {P1} + ({P2}-1)*iimax + ({P3}-
1)*iimax*jjmax)}

iunit=egs_open_file(iunit,0,1,'.egsphant');

WRITE(iunit,'(i2)') nmed;
DO ii=1,nmed [
Write(iunit,'(24a1)') (media(jj,ii),jj=1,24);
]
WRITE(iunit,*) (estepe(ii),ii=1,nmed);
WRITE(iunit,'(3i5)') iimax,jjmax,kkmax;
WRITE(iunit,*) (xbnd(ii),ii=1,iimax+1);
WRITE(iunit,*) (ybnd(jj),jj=1,jjmax+1);
WRITE(iunit,*) (zbnd(kk),kk=1,kkmax+1);
DO kk=1,kkmax[
DO jj=1,jjmax[
Edited by Foxit Reader
Copyright(C) by Foxit Software Company,2005-2008
For Evaluation Only.
WRITE(iunit,1399) (med($IRWP(ii,jj,kk)),ii=1,iimax);
]
WRITE(iunit,*);
]
1399 FORMAT($IMAXi1);
DO kk=1,kkmax[
DO jj=1,jjmax[
WRITE(iunit,*) (rho($IRWP(ii,jj,kk)),ii=1,iimax);
]
WRITE(iunit,*);
]
close(iunit);
RETURN;
end;

"========================================================================
==="
subroutine combine_results(file_name);
"========================================================================
==="
" Subroutine called at the end of all parallel runs to recombine the
results"
" This used to have to be done separately by the user.
"
"
"
"========================================================================
==="
implicit none;
COMIN/SCORE/;
character*(*) file_name;
$INTEGER I,IMAX,JMAX,KMAX,lnblnk1;
REAL*4 TENDEP($MAXDOSE), TENDEP2($MAXDOSE);
REAL*8 TTEMP2;
$LOGICAL first_time;
data first_time/.true./;
save first_time;

IF(first_time)[
OUTPUT61 ;(/1X,'Summing the following .pardose files');
OUTPUT61 ; (1X,'------------------------------------'/);
]

OUTPUT61 $cstring(file_name);(A);

"file name must be null terminated before passing to C routine"
file_name=$cstring(file_name)//char(0);

call read_pardose(TTEMP2,IMAX,JMAX,KMAX,TENDEP,TENDEP2,file_name);

IF(first_time)[
first_time = .false.;
"zero arrays that we are going to be adding to"
TEMP2=0.;
DO I=1,IMAX*JMAX*KMAX[
endep(I)=0.0;
endep2(I)=0.0;
]
]

DO I=1,IMAX*JMAX*KMAX[
endep(i)=endep(i)+tendep(i);
endep2(i)=endep2(i)+ tendep2(i);
]
TEMP2=TEMP2+TTEMP2;
return;
end;
;

/*

C************************************************************************
**
C*
*
C* Function ibsearch(a, nsh, b)
*
C*
*
C* binary search for an element l of array b such that
*
C* b[l] =< a < b[l+1]
*
C*
*
C* Note: array must be increasingly monotone
*
C* Ernesto Mainegra-Hing
*
C************************************************************************
**
*/
integer function ibsearch(a, nsh, b);
real*4 b(*);
$REAL a;
integer min,max,help,nsh;
real*4 x;
min = 1;
max = nsh;
x = a;
WHILE( min < max-1 )[
help = (max+min) / 2;
IF ( b(help)<=x)[
min = help;
]
ELSE[
max = help;
]
]
ibsearch = min;
return;
end;

subroutine modify_tmxs(mindel);
implicit none;
;COMIN/BOUNDS,ELECIN,MEDIA,MISC,RANDOM,ET-Control/;
$REAL rm,eil,ei,p2,beta2,chi_a2,elke,eke,dedx0,estepx,si,sip1,tmxs_orig,
mindel;
$INTEGER medium,i,neke,leil,lelke;

rm = 0.5110034;
DO medium = 1,nmed [

neke = meke(medium);

eil = (1 - eke0(medium))/eke1(medium); leil = 1;
ei = Exp(eil); leil = 1; " As in $SET INTERVAL but avoids roundoff
p2 = ei*(ei+2*rm); beta2 = p2/(p2+rm*rm);
chi_a2 = Xcc(medium)/(4*p2*blcc(medium));
$EVALUATE dedx0 USING ededx(eil);
estepx =
2*p2*beta2*dedx0/ei/Xcc(medium)/(Log(1+1./chi_a2)*(1+chi_a2)-1);
estepx = estepx*ximax;
IF( estepx > estepe ) [ estepx = estepe; ]
si = estepx*ei/dedx0;
IF( si < mindel/2. ) si = mindel/2.;

DO i = 1,neke - 1 [

elke = (i + 1 - eke0(medium))/eke1(medium); lelke = i;
tmxs_orig=tmxs1(i,MEDIUM)*elke+tmxs0(i,MEDIUM);
eke = Exp(elke); lelke = i+1;
p2 = eke*(eke+2*rm); beta2 = p2/(p2+rm*rm);
chi_a2 = Xcc(medium)/(4*p2*blcc(medium));
$EVALUATE dedx0 USING ededx(elke);
estepx = 2*p2*beta2*dedx0/eke/
Xcc(medium)/(Log(1+1./chi_a2)*(1+chi_a2)-1);
estepx = estepx*ximax;
IF( estepx > estepe ) [ estepx = estepe; ]
sip1 = estepx*eke/dedx0;
IF( sip1 < mindel/2. ) sip1 = mindel/2.;
tmxs1(i,medium) = (sip1 - si)*eke1(medium);
tmxs0(i,medium) = sip1 - tmxs1(i,medium)*elke;
si = sip1;

]

tmxs0(neke,medium) = tmxs0(neke - 1,medium);
tmxs1(neke,medium) = tmxs1(neke - 1,medium);

]

return; end;

S-ar putea să vă placă și