New Experiment Definition File Plugin (--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:
Single file. The template must be a single file. Any configuration not reachable within it cannot be varied by SIERRA.
If your simulator normally expects multiple configuration files (a common pattern in, e.g., ROS launch setups), you have two options:
Flatten the configuration into a single file. Each expdef plugin may implement a
flatten(keys)method (see New Experiment Definition File Plugin (--expdef)) that inlines external-file references identified bykeys. An Engine plugin invokes this at the start of stage 1, backend-agnostically, by resolving the expdef module from--expdefand callingflatten()on it. Not every backend implements flattening (e.g., the XML plugin does not). See New Engine Plugin (--engine) for how the engine drives this.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.
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
--controllerandcontrollers.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__fromcontrollers.yaml, see Special Tokens in controllers.yaml.__UUID__Available in ROS1
.launchtemplates 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 incontrollers.yaml, see Special Tokens in controllers.yaml.sierra(namespace)Reserved. Must not appear as an XML tag name or attribute value in ROS1
.launchtemplates. SIERRA uses this namespace internally.
Format-Specific Restrictions#
- XML
Modifications use XPath expressions (Python
xml.etree.ElementTreesyntax) 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.yamlcan 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
sierranamespace 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.pyThis 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.
Create additional cmdline arguments for the new plugin by following Extending the SIERRA Cmdline For Your Plugin.
Create the following filesystem structure in
$HOME/git/plugins/fizzbuzz:Within
plugin.pyyou must define a class named EXACTLYExpDefand a module-level function named EXACTLYroot_querypath(), otherwise SIERRA will not detect them.ExpDefderives fromBaseExpDefand implements the modification interface described in the required interface below.import pathlib import typing as tp from sierra.core.experiment import definition def root_querypath() -> str: """Return a unique string identifying the root element for this file type. Needed when scaffolding batch experiments so SIERRA can do so in a format-agnostic way (e.g. ``"."`` for XML, ``"$"`` for JSON). """ return "$" class ExpDef(definition.BaseExpDef): def __init__( self, input_fpath: pathlib.Path, write_config: tp.Optional[definition.WriterConfig] = None, ) -> None: ... # ... implement the required interface (see below) ...
Put
$HOME/git/pluginson yourSIERRA_PLUGIN_PATH. Then your plugin can be selected as--expdef=plugins.fizzbuzz.