YAML Configuration

Settings that are not specific to one computer (see The .env File for those) live in YAML files. YAML is a plain-text format for nested settings, written as name: value with indentation for nesting:

wavelengths: [500.0, 600.0, 700.0]
limits:
  velocity: {min: 1.0, max: 10.0}

A module has up to two YAML files, for two different kinds of setting:

File

Where

Holds

Changes when

module configuration, config.yaml

inside the module’s package, next to its __init__.py; installed with it

facts about the module itself: unit conversions, hardware limits, which devices an experiment uses

the module’s code changes

run configuration, config/*.yaml

in the module’s top folder; experiments only

the settings of one measurement: which wavelengths, how many points, how long to wait

someone starts a different measurement

Neither file holds addresses, ports or passwords. Those go in .env.

The module configuration: config.yaml

Every module created with plesty init (see Tools for publishing a module) has one. Because it sits inside the package, it is installed with the module and every copy of the module reads the same values.

A motion controller’s config.yaml, for example, holds how many motor counts make one degree, and the speed limits the device must never exceed:

# plesty/k10cr1/config.yaml
scaling:
  position: 136533.3333      # counts per degree
limits:
  velocity: {min: 1.0, max: 10.0}

Read it with module_config, giving the module’s name and, optionally, the path to the part you want:

from plesty.lib.utils.config import module_config

module_config("plesty.k10cr1")                          # the whole file, as a dict
module_config("plesty.k10cr1", "scaling", "position")   # 136533.3333

Inside the module’s own code, __package__ is the module’s name, so you do not have to write it out:

LIMITS = module_config(__package__, "limits")

A module created with plesty init also has a load_config() function in its __init__.py that returns the whole file.

If the file is missing, module_config raises FileNotFoundError: the module was installed without it, which is a broken installation. If a part is missing, it raises KeyError naming the full path, such as scaling → position, so the error says which value the file forgot.

The run configuration: config/*.yaml

An experiment measures differently from run to run: other wavelengths, more points, a longer exposure. Those settings go in a YAML file in the module’s config/ folder. config/default.yaml is used when no other file is named; keep other sets beside it:

config/
├── default.yaml      # used when no other file is named
└── quick.yaml        # e.g. fewer points, for a test

With the experiment command line from Give it a command line, choose the file with -c:

python power_scan.py                      # config/default.yaml
python power_scan.py -c config/quick.yaml

The experiment receives the file’s contents as a dictionary and passes them to its plan. The plan is saved with the run, so every run keeps the exact settings it was started with, even if the file changes later. Run(...).config reads them back.

To read a YAML file in your own code, use load_yaml:

from plesty.lib.utils.config import load_yaml

settings = load_yaml("config/default.yaml")              # FileNotFoundError if missing
settings = load_yaml("config/local.yaml", default={})    # {} if missing

Without default, a missing file is an error, so a mistyped path is not silently treated as empty settings.