Skip to content

Writing Components

Peter Willendrup edited this page Jan 14, 2026 · 16 revisions

Component writing exercise:

For a step-by-step understanding of writing a component, please make use of the semi-transparent mirror exercise


Component walk-through: Slit()

The rest of this page takes you through one of the simplest McStas components, Slit.comp.

First, let us discuss the overall structure of a McStas component. The Slit() component realises an aperture or slit, in this case either a rectangular or circular opening in an absorbing material slab.

First we will have a look at the documentation header below. The various %-tags are parsed by mcdoc to define component online documentation like this http://mcstas.org/download/components/optics/Slit.html

The first part including the %I information tag signifies who wrote the component and where.

/*******************************************************************************
*
* McStas, neutron ray-tracing package
*         Copyright 1997-2002, All rights reserved
*         Risoe National Laboratory, Roskilde, Denmark
*         Institut Laue Langevin, Grenoble, France
*
* Component: Slit 
*
* %I
* Written by: Kim Lefmann and Henrik M. Roennow
* Date: June 16, 1997
* Version: $Revision: 4382 $
* Origin: Risoe
* Release: McStas 1.6
*

Next, some descriptive text is added, including the %D description tag.

* Rectangular/circular slit with optional insignificance cut
*
* %D
* A simple rectangular or circular slit. You may either
* specify the radius (circular shape), or the rectangular bounds.
* No transmission around the slit is allowed.
* If cutting option is used, low-weight neutron rays are ABSORBED
*
* Example: Slit(xmin=-0.01, xmax=0.01, ymin=-0.01, ymax=0.01)
*          Slit(radius=0.01, cut=1e-10)
*
The %P tag indicates component input parameters, defining e.g. physical properties and geometry of the component.
* %P
* INPUT PARAMETERS
*
* radius: Radius of slit in the z=0 plane, centered at Origo (m)
* xmin: Lower x bound (m)
* xmax: Upper x bound (m)
* ymin: Lower y bound (m)
* ymax: Upper y bound (m)
* xwidth: Width of slit. Overrides xmin,xmax. (m)
* yheight:Height of slit. Overrides ymin,ymax. (m)
*
* Optional parameters:
* cut:  Lower limit for allowed weight (1)
*
* %E
*******************************************************************************/
The optional %L tag can be used for attaching links to other information - and %E ends the commentary section.

Next follows some important lines of code that are mandatory for components:

DEFINE COMPONENT Slit
Defines the component type (here Slit) - and must match the filename under which the component is stored, i.e. Slit.comp
SETTING PARAMETERS (xmin=-0.01, xmax=0.01, ymin=-0.01, ymax=0.01, radius=0, 
  cut=0, xwidth=0, yheight=0)
Setting parameters include basic c-types, defaulting to being doubles but can also be cast as integers. Since McStas 3 SETTING PARAMETERS also allow the types ‘string somestring=“default”’’’ and ‘’’vector somelist={0,0,0,0}’’’ All setting parameters are prefixed in the generated c-code by the component instance name.
DECLARE %{
%}
Declare is used to define internal calculation variables and internal component functions. Bear in mind to put these as output parameters if they are to be "private" to the component. In McStas 3 DECLARE may ONLY contain declarations of the below, simple type since the section becomes a component struct:
DECLARE %{
  int i;
  double d;
  double* dd;
  char staticstring[128];
  // ..etc
%}
SHARE %{
%}
Share is used for code that should be shared for components of the same type - e.g. for function definitions, struct definitions etc.
INITIALIZE
%{
  if (xwidth > 0)  { xmax=xwidth/2;  xmin=-xmax; }
  if (yheight > 0) { ymax=yheight/2; ymin=-ymax; }
  if (xmin == 0 && xmax == 0 && ymin == 0 && ymax == 0 && radius == 0)
    { fprintf(stderr,"Slit: %s: Error: give geometry\n", NAME_CURRENT_COMP); exit(-1); }
%}
Initialize is used to calculate values for the declared variables, make checks of input variable consistency etc. This is where runtime-errors due to unmeaningful parameters should be placed.
TRACE
%{
    PROP_Z0;
    if (((radius == 0) && (x<xmin || x>xmax || y<ymin || y>ymax))
    || ((radius != 0) && (x*x + y*y > radius*radius)))
      ABSORB;
    else
      if (p < cut)
        ABSORB;
      else
        SCATTER;
%}
The Trace section is where the fun begins! :-) An incoming neutron (always with parameters x,y,z,vx,vy,vz,sx,sy,sz,t,p) is typically checked for intersection with the object - here after propagation by PROP_Z0. Other possibilities for intersection include e.g. the cylinder_intersect routine and similar, that calculate intersection times between the object and the neutron equation of motion (including gravitation if this is enabled).

After propagation something usually "happens" here, i.e. the neutron is scattered, changes direction, is absorbed or equivalent, and a new set of values for the neutron parameters are set accordingly.

SAVE %{
%}
Save is an optional section - typically used by monitors for calling the DETECTOR_OUT macros for storing histograms to disk.
FINALLY %{
%}
Finally is an optional section that allows to do e.g. memory cleanups at the end of execution.
MCDISPLAY
%{
  magnify("xy");
  if (radius == 0) {
    double xw, yh;
    xw = (xmax - xmin)/2.0;
    yh = (ymax - ymin)/2.0;
    multiline(3, xmin-xw, (double)ymax, 0.0,
              (double)xmin, (double)ymax, 0.0,
              (double)xmin, ymax+yh, 0.0);
    multiline(3, xmax+xw, (double)ymax, 0.0,
              (double)xmax, (double)ymax, 0.0,
              (double)xmax, ymax+yh, 0.0);
    multiline(3, xmin-xw, (double)ymin, 0.0,
              (double)xmin, (double)ymin, 0.0,
              (double)xmin, ymin-yh, 0.0);
    multiline(3, xmax+xw, (double)ymin, 0.0,
              (double)xmax, (double)ymin, 0.0,
              (double)xmax, ymin-yh, 0.0);
  } else {
    circle("xy",0,0,0,radius);
  }
%}
Mcdisplay is used to render the object on a graphics display, by means of simple linear outlines of the object.
END
The END keyword marks the end of the component code.

Additional information

  • See McStas manual section 4.7 for instructions on how-to write components
  • See McStas manual appendix B for description of built-in functions used when constructing components
  • Link to McStas manual http://mcstas.org/documentation/manual/

Clone this wiki locally