Here we list a number of preprogrammed macros and functions which may ease the task of
writing component and instrument definitions. By convention macros are in upper case
whereas functions are in lower case.
B.1.1Photon propagation
Propagation routines perform all necessary operations to transport x-rays from one point to an
other. Except when using the special ALLOW_BACKPROP; call prior to executing any
PROP_* propagation, the x-rays which have negative propagation lengths are removed
automatically.
ABSORB. This macro issues an order to the overall McXtrace simulator to
interrupt the simulation of the current x-ray history and to start a new one.
PROP_Z0. Propagates the x-ray to the \(z=0\) plane, by adjusting \((x,y,z)\), \(\phi \), and \(t\) accordingly
from knowledge of the x-ray wavevector \((kx,ky,kz)\). If the propagation length is negative, the
x-ray is absorbed, except if a ALLOW_BACKPROP; preceeds it.
For components that are centered along the \(z\)-axis, use the _intersect functions
to determine intersection time(s), and then a PROP_DL call.
PROP_X0, PROP_Y0. These macros are analogous to PROP_Z0 except they
propagate to the \(x=0\) and \(y=0\) planes respectively.
PROP_DL\((dl)\). Propagates the x-ray by the length \(dl\), adjusting \((x,y,z)\), \(\phi \), \(t\) accordingly, from
knowledge of the x-ray wavevector.
ALLOW_BACKPROP. Indicates that the next propagation routine will not
remove the x-ray, even if negative propagation lengths are found. Subsequent
propagations are not affected.
SCATTER. This macro is used to denote a scattering event inside a component.
It should be used to indicate that a component has interacted with the x-ray
(e.g. scattered or detected). This does not affect the x-ray state (see, however,
Beamstop), and it is mainly used by the MCDISPLAY section and the GROUP
modifier. See also the SCATTERED variable (below).
B.1.2Coordinate and component variable retrieval
MC_GETPAR\((comp, outpar)\). This may be used in e.g. the FINALLY section of an instrument
definition to reference the parameters of a component.
NAME_CURRENT_COMP gives the name of the current component as a
string.
POS_A_CURRENT_COMP gives the
absolute position of the current component. A component of the vector is referred
to as POS_A_CURRENT_COMP.\(i\) where \(i\) is \(x\), \(y\) or \(z\).
ROT_A_CURRENT_COMP and ROT_R_CURRENT_COMP give the
orientation of the current component as rotation matrices (absolute orientation and
the orientation relative to the previous component, respectively). A component of
a rotation matrix is referred to as ROT_A_CURRENT_COMP\([m][n]\), where \(m\) and \(n\) are
0, 1, or 2 standing for \(x,y\) and \(z\) coordinates respectively.
POS_A_COMP\((comp)\) gives the absolute position of the component with the name
comp. Note that comp is not given as a string. A component of the vector is referred
to as POS_A_COMP\((comp).i\) where \(i\) is \(x\), \(y\) or \(z\).
ROT_A_COMP\((comp)\) and ROT_R_COMP\((comp)\) give the orientation of the component
comp as rotation matrices (absolute orientation and the orientation relative to
its previous component, respectively). Note that comp is not given as a string. A
component of a rotation matrice is referred to as ROT_A_COMP\((comp)[m][n]\), where \(m\) and \(n\) are
0, 1, or 2.
INDEX_CURRENT_COMP is the number (index) of the current component
(starting from 1).
POS_A_COMP_INDEX\((index)\) is the absolute position of component \(index\). POS_A_COMP_INDEX (INDEX_CURRENT_COMP) is the same as POS_A_CURRENT_COMP. You may use POS_A_COMP_INDEX (INDEX_CURRENT_COMP+1) to make, for instance, your component access the position of the next component
(this is usefull for automatic targeting). A component of the vector is referred to
as POS_A_COMP_INDEX\((index).i\) where \(i\) is \(x\), \(y\) or \(z\).
POS_R_COMP_INDEX works the same as above, but with relative
coordinates.
STORE_XRAY\((index, x, y, z, kx, ky, kz, phi,t, Ex, Ey, Ez, p)\) stores the current x-ray state in the trace-history table, in local
coordinate system. \(index\) is usually INDEX_CURRENT_COMP. This is automatically
done when entering each component of an instrument.
RESTORE_XRAY\((index, x, y, z, kx, ky, kz, phi,t, Ex, Ey, Ez, p)\) restores the x-ray state to the one at the input
of the component \(index\). To ignore a component effect, use RESTORE_XRAY
(INDEX_CURRENT_COMP, \(x, y, z, kx, ky, kz, phi, Ex, Ey, Ez, p\)) at the end of its TRACE section, or in its EXTEND section. These x-ray states
are in the local component coordinate systems.
SCATTERED is a variable set to 0 when entering a component, which is
incremented each time a SCATTER event occurs. This may be used in the EXTEND
sections to determine whether the component interacted with the current x-ray.
extend_list(\(n\), &arr, &len, elemsize). Given an array arr with len elements each of
size elemsize, make sure that the array is big enough to hold at least \(n\) elements, by
extending arr and len if necessary. Typically used when reading a list of numbers
from a data file when the length of the file is not known in advance.
mcset_ncount\((n)\). Sets the number of x-ray histories to simulate to \(n\).
mcget_ncount(). Returns the number of x-ray histories to simulate (usually set
by option -n).
mcget_run_num(). Returns the number of x-ray histories that have been
simulated until now.
B.1.3Coordinate transformations
coords_set\((x,y,z)\) returns a Coord structure (like POS_A_CURRENT_COMP) with \(x\), \(y\)
and \(z\) members.
coords_get\((P,\) &\(x\), &\(y\), &\(z)\) copies the \(x\), \(y\) and \(z\) members of the Coord structure \(P\) into \(x,y,z\)
variables.
coords_add\((a,b)\), coords_sub\((a,b)\), coords_neg\((a)\) enable to operate on coordinates, and
return the resulting Coord structure.
rot_set_rotation(Rotation t, \(\phi _x, \phi _y, \phi _z\)) Get transformation matrix for rotation first \(\phi _x\)
around x axis, then \(\phi _y\) around y, and last \(\phi _z\) around z. \(t\) should be a ’Rotation’ ([3][3]
’double’ matrix).
rot_apply(Rotation t, Coords a) returns a Coord structure which is \(t.a\)
B.1.4Mathematical routines
NORM\((x,y,z)\). Normalizes the vector \((x,y,z)\) to have length 1.
scalar_prod\((a_x,a_y,a_z, b_x,b_y,b_z)\). Returns the scalar product of the two vectors \((a_x,a_y,a_z)\) and \((b_x,b_y,b_z)\).
vec_prod(&\(a_x\),&\(a_y\),&\(a_z\), \(b_x\),\(b_y\),\(b_z\), \(c_x\),\(c_y\),\(c_z\)). Sets \((a_x,a_y,a_z)\) equal to the vector product \((b_x,b_y,b_z) \times (c_x,c_y,c_z)\).
rotate(&\(x\),&\(y\),&\(z\),\(v_x\),\(v_y\),\(v_z\),\(\varphi \),\(a_x\),\(a_y\),\(a_z\)). Set \((x,y,z)\) to the result of rotating the vector \((v_x,v_y,v_z)\) the angle \(\varphi \) (in radians)
around the vector \((a_x,a_y,a_z)\).
normal_vec(\(n_x\), \(n_y\), \(n_z\), \(x\), \(y\), \(z\)). Computes a unit vector \((n_x, n_y, n_z)\) normal to the vector \((x,y,z)\).\(^*\)
solve_2nd_order(*\(t_0\),*\(t_1\), \(A\), \(B\), \(C\)). Solves the 2\(^{nd}\) order equation \(At^2 + Bt + C = 0\) and puts the solutions in
*\(t_0\) and *\(t_1\). The smallest positive solution into pointer *\(t_0\). If \(t_1\)=NULL it is ignored and
the second solution is discarded.
B.1.5Output from detectors
Details about using these functions are given in the McXtrace User Manual.
DETECTOR_OUT_0D\((...)\). Used to output the results from a single detector.
The name of the detector is output together with the simulated intensity and
estimated statistical error. The output is produced in a format that can be read
by McXtrace front-end programs.
DETECTOR_OUT_1D\((...)\). Used to output the results from
a one-dimensional detector. Integrated intensities error etc. is also reported as for
DETECTOR_OUT_0D.
DETECTOR_OUT_2D\((\dots ...)\). Used to output the results from
a two-dimentional detector. Integrated intensities error etc. is also reported as for
DETECTOR_OUT_0D.
mcinfo_simulation(FILE *f, mcformat, char *pre, char *name) is used to
append the simulation parameters into file \(f\) (see for instance Res_monitor).
Internal variable \(mcformat\) should be used as specified. Please contact the authors for further
information.
B.1.6Ray-geometry intersections
inside_rectangle(\(x\), \(y\), \(xw\), \(yh\)). Return 1 if \(-xw/2 \leq x \leq xw/2\) AND \(-yh/2 \leq y \leq yh/2\). Else return 0.
box_intersect(&\(l_1\), &\(l_2\), \(x\), \(y\), \(z\), \(k_x\), \(k_y\), \(k_z\), \(d_x\), \(d_y\), \(d_z\)). Calculates the (0, 1, or 2) intersections between
the x-ray path and a box of dimensions \(d_x\), \(d_y\), and \(d_z\), centered at the origin for a x-ray
with the parameters \((x,y,z,k_x,k_y,k_z)\). The intersection lengths are returned in the variables \(l_1\) and
\(l_2\), with \(l_1 < l_2\). In the case of less than two intersections, \(t_1\) (and possibly \(t_2\)) are set to zero.
The function returns true if the x-ray intersects the box, false otherwise.
cylinder_intersect(&\(l_1\), &\(l_2\), \(x\), \(y\), \(z\), \(k_x\), \(k_y\), \(k_z\), \(r\), \(h\)). Similar to box_intersect, but using a
cylinder of height \(h\) and radius \(r\), centered at the origin.
sphere_intersect(&\(l_1\), &\(l_2\), \(x\), \(y\), \(z\), \(k_x\), \(k_y\), \(k_z\), \(r\)). Similar to box_intersect, but using a sphere
of radius \(r\).
ellipsoid_intersect(&\(l_1\), &\(l_2\), \(x\), \(y\), \(z\), \(k_x\), \(k_y\), \(k_z\), \(a\),\(b\),\(c\),\(Q\), ). Similar to box_intersect, but using an
ellipsoid with half-axis \(a\),\(b\),\(c\) oriented by the rotation matrix \(Q\). If \(Q=I\), \(a\) is along the \(x\)-axis, \(b \)
along \(y\) and \(c\) along \(z\)
B.1.7Random numbers
By default McXtrace uses a 64-bit KISS (“Keep It Simple Stupid”) algorithm for generating
pseudo random numbers, which runs on both CPU and GPU/OpenACC. The classic
Mersenne Twister[MN98] algorithm remains available as a CPU-only, build-time alternative
(see the User Manual’s appendix on random numbers).
rand01(). Returns a random number distributed uniformly between 0 and 1.
randnorm(). Returns a random number from a normal distribution centered
around 0 and with \(\sigma =1\). The algorithm used to sample the normal distribution is
explained in Ref. [Pre+86, ch.7].
randpm1(). Returns a random number distributed uniformly between -1 and 1.
randtriangle(). Returns a random number from a triangular distribution between
-1 and 1.
randvec_target_circle(&\(v_x\), &\(v_y\), &\(v_z\), &\(d\Omega \), aim\(_x\), aim\(_y\), aim\(_z\), \(r_f\)). Generates a random vector
\((v_x, v_y, v_z)\), of the same length as (aim\(_x\), aim\(_y\), aim\(_z\)), which is targeted at a disk centered at
(aim\(_x\), aim\(_y\), aim\(_z\)) with radius \(r_f\) (in meters), and perpendicular to the aim vector..
All directions that intersect the circle are chosen with equal probability. The solid
angle of the circle as seen from the position of the x-ray is returned in \(d\Omega \). This routine
was previously called randvec_target_sphere (which still works).
randvec_target_rect_angular(&\(v_x\), &\(v_y\), &\(v_z\), &\(d\Omega \), aim\(_x\), aim\(_y\), aim\(_z\),\(h, w, Rot\)) does the same as
randvec_target_circle but targetting at a rectangle with angular dimensions \(h\) and \(w\)
(in radians, not in degrees as other angles). The rotation matrix \(Rot\) is the coordinate
system orientation in the absolute frame, usually ROT_A_CURRENT_COMP.
randvec_target_rect(&\(v_x\), &\(v_y\), &\(v_z\), &\(d\Omega \), aim\(_x\), aim\(_y\), aim\(_z\),\(height, width, Rot\)) is the same as
randvec_target_rect_angular but \(height\) and \(width\) dimensions are given in meters. This
function is useful to e.g. target at a guide entry window or analyzer blade.