McStas / McXtrace COMPONENT grammar

This is one of two companion cheat sheets: this file covers .comp component files; the companion INSTRUMENT grammar covers .instr instrument files. Each is written to stand alone — a little material (the reserved-keyword table, the particle-terminology note, the shared-grammar note) is intentionally duplicated in both. Keywords are case-insensitive but conventionally written in UPPERCASE; identifiers are case-sensitive C identifiers. Sources are listed at the end of the document (§13).

On "McStas" vs "McXtrace" vs "particle": the instrument/component grammar itself — every keyword and syntax rule in this document — is identical between the two codes; it's one shared parser. What differs is the physics carried by the traced entity: McStas traces neutrons, McXtrace traces X-ray photons. This cheat sheet uses the neutral term "particle" throughout for the thing being traced through a component, and only calls out "neutron" or "photon" specifically where the two codes' behaviour (not grammar) actually differs — chiefly, the fields making up the particle's state, which every component's TRACE code reads and writes:

McStas (neutron) McXtrace (photon)
Position x, y, z [m] x, y, z [m]
Direction/momentum velocity vx, vy, vz [m/s] wavevector kx, ky, kz [Å⁻¹]
Extra kinematic field phase phi [rad]
Polarization spin sx, sy, sz polarization vector Ex, Ey, Ez
Time t [s] t [s]
Weight p p

A component's TRACE C code operates directly on these fields (by whichever names apply to the code you're writing for). USERVARS fields (§7 below) are appended to the same per-particle struct — the grammar for declaring them is identical in both codes.


Notation used for grammar skeletons in this document: [ ... ] marks an element (or whole clause) as optional; ( a | b | c ) marks a required choice among alternatives. Both are meta-notation and never appear literally in a .instr/.comp file. Everything else — including bare { } and, especially, %{ ... %} — is literal syntax: %{ %} is the actual embedded-C-code delimiter, and bare { } shows up as-is in real code (e.g. a vector default like axis={0,1,0}). The two never mean "optional" in this document.

Contents

Contents

1. Component file skeleton

DEFINE COMPONENT name [INHERIT parent]

SETTING PARAMETERS (s1, s2 = default, ...)
[OUTPUT PARAMETERS (o1, o2, ...)]      // legacy; parses but effect 

[DEPENDENCY "..."]
[NOACC] // marks that component TRACE code can not be offloaded to GPU via OpenACC

SHARE
%{ // C shared once across all instances of this component %}

DECLARE
%{ // becomes the per-instance member fields of this component's generated C struct, see §5 %}

USERVARS
%{ // per-particle fields, same mechanism as instrument-level USERVARS %}

INITIALIZE
%{ // run once per instance, at start %}

TRACE
%{ // the actual particle/component interaction %}

[SAVE %{ ... %}]
[FINALLY %{ ... %}]
[MCDISPLAY %{ ... %}]                  // alias: DISPLAY

END

Section order above is what the grammar enforces; every section except DEFINE COMPONENT name and TRACE/END is optional. A component definition may also carry one or more METADATA blocks (§8) and, in the TRACE section of an instrument that uses this component, be positioned/duplicated/grouped — see the companion instrument-grammar file for that side of things.

2. DEFINE COMPONENT header

DEFINE COMPONENT Slit
DEFINE COMPONENT Place INHERIT Arm          // whole-component inheritance, see §9
DEFINE COMPONENT MyComp NOACC               // GPU-incompatible component class, see §6

This marks the beginning of the definition and names the component. INHERIT parent (§9) and NOACC (§6) are both optional modifiers on this header line.

3. SETTING PARAMETERS

SETTING PARAMETERS (radius, height, pack = 1, string filename = "out.dat",
                     vector axis = {0,1,0}, symbol my_func)

4. Component-level DEPENDENCY

DEPENDENCY "-lLIB1 -lLIB2 .."

Works exactly like the instrument-level line (INSTRUMENT grammar, §3) — appends compiler/linker flags needed by this component's C code (external library calls, etc.). Must precede SHARE/DECLARE. Flags from every component actually used in an instrument are concatenated with the instrument's own DEPENDENCY line into one CFLAGS=... string.

5. SHARE vs DECLARE

SHARE
%{
  // emitted ONCE total, no matter how many instances exist
%}

DECLARE
%{
  // becomes the per-instance member fields of this component's generated C struct
%}
DECLARE %{
  double* myvar; // "type varname;" ONLY — no initializers, no multi-declarations
%}

6. NOACC — marking a component class GPU-incompatible

DEFINE COMPONENT MyComp NOACC

7. USERVARS, INITIALIZE, TRACE, SAVE, FINALLY, MCDISPLAY

USERVARS
%{
  double myvar;   // "type varname;" ONLY — no initializers, no multi-declarations
%}

INITIALIZE
%{
  // C code run once per instance, at simulation start; may modify SETTING parameters
%}

TRACE
%{
  // the actual computation of the interaction between the particle and the component
%}

SAVE
%{
  // C code executed whenever a (partial) data save is triggered
%}

FINALLY
%{
  // C code executed once, at simulation end
%}

MCDISPLAY               // alias: DISPLAY
%{
  // C code to draw the component geometry for mcdisplay
%}

8. METADATA at component-definition level

DEFINE COMPONENT File
SETTING PARAMETERS (string filename, string metadatakey = "", int keep = 0)
METADATA "text/plain" default_note
%{
  Default per-definition metadata text.
%}
...
END

9. INHERIT — component heritage

Whole-component inheritance (copies every section from the parent, minus its doc header; override/extend any section by re-declaring it):

DEFINE COMPONENT Place INHERIT Arm
END

(real, minimal example from mcstas-comps/optics/Place.comp)

DEFINE COMPONENT child_name INHERIT parent_name
  SETTING PARAMETERS (newpar1, newpar2)
  INITIALISE
    INHERIT parent_name
    EXTEND
    %{ // C code appended to parent_name's INITIALIZE %}
  SAVE
  %{ // C code that fully REPLACES parent_name's SAVE %}
END

Per-section INHERIT parent_name (optionally followed by EXTEND %{ ... %}) is written inside that section's own block, right after the section keyword — not as a top-level clause. A bare INHERIT parent for a section replaces it wholesale with the parent's code; INHERIT parent EXTEND %{ ... %} instead appends the given code after the parent's.

You can also pull in individual sections from any component without inheriting the whole definition (the top-level DEFINE COMPONENT line doesn't itself use INHERIT):

DEFINE COMPONENT name(...)
SETTING PARAMETERS (...)
DECLARE
  INHERIT parent1
INITIALISE
  INHERIT parent2
  EXTEND %{ // appended to parent2's INITIALIZE %}
TRACE
  INHERIT parent3
END

Mixing sections from different sources this way needs care around variable naming collisions. EXTEND used this way (attached to an INHERITed section, inside a component definition) is a different mechanism from the instrument-level EXTEND modifier on a COMPONENT instance (INSTRUMENT grammar, §9) — same keyword, but one extends an inherited section of a component definition, the other extends one instance's TRACE from the instrument file.

10. END (component level)

END

Mandatory; closes the component definition.


11. Reserved keyword reference

All tokens below are reserved and case-insensitive; do not reuse them as C identifiers. "Scope": I = valid in instrument definitions (INSTRUMENT grammar), C = valid in component definitions (this file).

Keyword Scope Meaning
ABSOLUTE I Global coordinate frame for AT/ROTATED.
AT I Component position.
COMPONENT I Declares a component instance.
COPY I Duplicate a preceding instance.
CPU I Force one instance to run on CPU only.
DECLARE I, C C global declarations (§5).
DEFINE I, C Starts an INSTRUMENT or COMPONENT definition (§2).
DEFINITION C No longer supported — raises a compile error if used (§3).
DEPENDENCY I, C Compiler/linker flags (§4).
DISPLAY C Alias for MCDISPLAY (§7).
END I, C Ends the definition (§10).
EXTEND I, C Appends C code after a TRACE, or after an INHERITed section (§9).
FINALLY I, C C code run at simulation end (§7).
GROUP I Exclusive ("XOR") component group.
%include I, C Import a file — component/instrument, or (inside %{ %}) a C library.
INHERIT C Derive a component (whole or per-section) from a parent (§9).
INITIALIZE / INITIALISE I, C C code run once at start-up (§7).
ITERATE I JUMP loop-count clause.
JUMP I Conditional/iterative non-sequential propagation.
MCDISPLAY C C code to draw component geometry (§7, alias DISPLAY).
METADATA I, C Attach a named, typed text block (§8).
MYSELF I Self-reference for COPY/JUMP.
NEXT / NEXT(n) I Forward instance reference, for JUMP.
NOACC C Marks a component class GPU-incompatible (§6).
OUTPUT C Alias for PRIVATE PARAMETERS; parses but no longer has any effect (§3, §5).
PARAMETERS C Qualifier after SETTING/OUTPUT/PRIVATE (and the rejected DEFINITION) (§3).
PREVIOUS / PREVIOUS(n) I, C Backward instance reference.
PRIVATE C Alias for OUTPUT PARAMETERS; parses but no longer has any effect (§3, §5).
RELATIVE I Relative coordinate frame for AT/ROTATED.
REMOVABLE I Skip this component when the file is %include'd.
ROTATED I Component orientation.
SAVE I, C C code run on (partial) data save (§7).
SEARCH I Extra component/instrument search directory — TRACE-section only.
SETTING C Component parameters compiled as ordinary C variables (§3).
SHARE C C code emitted once, shared across all instances (§5).
SHELL I, C Run a shell command at parse time.
SPLIT I Boost downstream statistics by event repetition.
TRACE I, C The particle-propagation / component-interaction section (§7).
USERVARS I, C Per-particle custom fields (§7).
WHEN I Conditional component activation, or JUMP condition.

Obsolete / rejected keywords

STATE PARAMETERS, POLARISATION PARAMETERS, and DEFINITION PARAMETERS (§3) are all still recognised by the grammar but immediately raise a compile error if used — leftovers from older grammar versions (the first two long-standing, DEFINITION PARAMETERS more recently). Remove them if you see them in an old .instr/.comp file. Separately, OUTPUT PARAMETERS/PRIVATE PARAMETERS (§3, §5) are not rejected — they still parse without error — but no longer have any effect; they're inert rather than erroring. All four are usually a sign the file, or the documentation it was written against, predates the current McStas/McXtrace.


12. Source-material for this reference

See also: INSTRUMENT grammar