Experiment Definition Files (--expdef)#

This page covers the contract that experiment definition template files must satisfy, independent of format, and then walks through how to create a new Plugin for a custom file format. See Experiment Templates for a user-facing introduction, and Plugin Development Guide for the general plugin development guide.

Template File Contract#

An experiment definition template is a single file passed to --expdef-template. SIERRA reads it once per batch and applies modifications from batch criteria and controllers.yaml to produce per-experiment, per-run input files. Two requirements apply regardless of format:

  1. Single file. The template must be a single file. Any configuration not reachable within it cannot be varied by SIERRA. If your simulator normally uses multiple config files, provide an expdef_flatten() hook in your engine plugin to collapse them at stage 1 startup--see New Engine Plugin (--engine).

    If your simulator normally expects multiple configuration files (a common pattern in ROS launch setups), you have two options:

    1. Flatten the configuration into a single file before passing it to SIERRA. The Engine plugin can provide an expdef_flatten() hook that SIERRA calls at the start of stage 1 to perform this transformation automatically. See Engine (--engine) for how to implement this hook.

    2. Factor out only the parameters SIERRA needs to vary into the template and load the remaining files from fixed paths within your project. This is the pragmatic approach for large legacy configurations where flattening is not practical.

  2. Unique node paths. Every element and attribute SIERRA needs to target must be uniquely identifiable by a path from the root of the file. For XML this is XPath; for JSON, JSONPath; for YAML, YAMLPath. If your file format has no companion query language you will need to write one.

Special Tokens#

SIERRA recognises the following tokens during stage 1 and substitutes them before writing per-run input files. They must appear in the locations described — SIERRA only looks for them in specific places.

__CONTROLLER__

A placeholder for the controller name in the template file. SIERRA replaces it with the controller name derived from --controller and controllers.yaml. Supported in XML, JSON, and YAML templates.

In XML templates, __CONTROLLER__ appears as an element tag name:

<__CONTROLLER__ library="...">
  ...
</__CONTROLLER__>

In JSON and YAML templates, it appears as a key whose value SIERRA overwrites with the resolved controller name:

{ "__CONTROLLER__" : "..." }
__CONTROLLER__: "..."

For how to target __CONTROLLER__ from controllers.yaml, see Special Tokens in controllers.yaml.

__UUID__

Available in ROS1 .launch templates when a ROS1 engine is selected. Expands to the robot's namespace prefix concatenated with its numeric ID (0-based); the enclosing tag is added once per robot rather than once overall. Used to set per-robot parameters that cannot be controlled through batch criteria. For usage in controllers.yaml, see Special Tokens in controllers.yaml.

sierra (namespace)

Reserved. Must not appear as an XML tag name or attribute value in ROS1 .launch templates. SIERRA uses this namespace internally.

Format-Specific Restrictions#

XML

Modifications use XPath expressions (Python xml.etree.ElementTree syntax) to locate elements and attributes. The full XPath subset supported is documented in the Python standard library.

JSON and YAML

SIERRA distinguishes between keys that map to scalar values and keys that map to nested objects. Batch criteria and controllers.yaml can only target scalar-valued keys. Attempting to modify a key that maps to a subtree raises an error, even though such a modification would be valid JSON or YAML. This restriction exists to keep modification semantics uniform across all supported formats.

ROS1 launch files

A dialect of XML. Subject to the XML restrictions above, plus the sierra namespace reservation and __UUID__ token described under Special Tokens.

Creating a New Expdef Plugin#

For the purposes of this tutorial, I will assume you are creating a new Plugin fizzbuzz for reading in and creating experiment definitions from an imaginary "fizzbuzz" file type. Before beginning, see Plugin Development Guide for a general overview of creating a new plugin.

To begin, create the following filesystem structure in $HOME/git/plugins/fizzbuzz.

  • plugin.py - This file is required, and is where most of the bits for the plugin will go. You don't have to call it this; if you want to use a different name, see Schemas for options.

  • cmdline.py This file is optional. If your new plugin doesn't need any additional cmdline arguments, you can skip it.

These files will be populated as you go through the rest of the tutorial.

  1. Create additional cmdline arguments for the new plugin by following Extending the SIERRA Cmdline For Your Plugin.

  2. Create the following filesystem structure in $HOME/git/plugins/fizzbuzz:

    Within this file, you must define the following classes, which must be named EXACTLY as specified, otherwise SIERRA will not detect them.

    import pathlib
    import implements
    from sierra.core.experiment import definition
    
    class ExpDef(definition.BaseExpDef):
    

    Within this file, you must define the following functions, which must be named EXACTLY as specified, otherwise SIERRA will not detect them.

    import pathlib
    import implements
    from sierra.core.experiment import definition
    
    def root_querypath() -> str:
        """Get unique string identifying the root element for the backend
        file type. This is needed when scaffolding batch experiments so
        SIERRA can do so in a format-agnostic way.
        """
        return "mystring"
    
  3. Put $HOME/git/plugins on your SIERRA_PLUGIN_PATH. Then your plugin can be selected as --expdef=plugins.fizzbuzz.