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.
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).
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.
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_mul(Rotation t1, Rotation t2, Rotation t3) performs \(t3 = t1 . t2\).
rot_copy(Rotation dest, Rotation src) performs \(dest = src\) for Rotation arrays.
rot_transpose(Rotation src, Rotation dest) performs \(dest = src^t\).
rot_apply(Rotation t, Coords a) returns a Coord structure which is \(t.a\)
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.
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.
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\)
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 chapter 7.3).
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.