Recipe format¶
A recipe is one YAML file. The schema is published at
/ai/schemas/preset.schema.json and
spectro preset validate checks a file against the running kernel: format,
metadata vocabulary, algorithm names, parameter names, variables, and the
kernel version range.
The file¶
name: be_halpha_ew # lowercase snake_case; the identifier users cite
version: 1.0.0 # semantic version of the recipe itself
description: >-
What is measured and how, in one paragraph.
requires: ">=0.7, <1.0" # spectro-kernel range the recipe was validated for
metadata:
kind: campaign # analysis | reduction | campaign | template
status: reviewed # draft | reviewed | reference
references: # mandatory for a campaign recipe
- "Vollmann & Eversberg 2006, AN 327, 862"
conventions: "continuum band 6500-6520 Å, 40 Å window around H-alpha"
author: "BeSS working group"
variables: # what depends on the instrument or the observer
tilt_deg: {type: float, required: true, description: "slit tilt (deg)"}
half_width: {type: int, default: 6}
steps: # the pipeline, in order
- name: Straighten the slit
algorithm: correct_tilt_affine
params: {tilt_deg: "${tilt_deg}"}
name, version, description and steps are required. A recipe with no
variables block is a plain preset and runs as is; every preset written
before v0.7.0 is still valid.
Variables¶
Each variable has a type, an optional default, a description, and
optionally a list of choices. A variable without a default is required.
The shorthand half_width: 6 declares an optional integer with that default.
| Type | Accepts | Example values |
|---|---|---|
int |
integers, or strings such as "12" from the command line |
6 |
float |
numbers | 0.4 |
bool |
booleans, or true/false, yes/no, on/off, 1/0 |
true |
str |
text | "alf Cyg" |
path |
a file or directory path, kept as text | /data/bias |
list |
a YAML list, a JSON list such as "[1, 2]", or "a, b" |
[5852.49, 6266.50] |
Values coming from --set name=value are strings and are converted to the
declared type; a value outside choices or of the wrong type is refused
with the variable's name and description in the message.
Substitution rules¶
The rules are deliberately small:
- a parameter whose value is exactly
${name}receives the variable's typed value (a number stays a number, a list stays a list); - a string that contains
${name}among other text is interpolated as text (label: "H-${line}"), useful for labels and file names; - lists and mappings are walked recursively;
- every
${name}must be declared invariables, and every declared variable must be used, otherwise validation fails.
Write the token in quotes, "${name}": YAML would otherwise read the braces
of {tilt_deg: ${tilt_deg}} as a nested mapping. The quotes change nothing
for the kernel, which still passes the typed value.
Profiles¶
A profile is any YAML mapping of variable name to value. It carries no science, only what is true of one instrument and one observer:
Ways to bind values, in increasing priority:
| From | How |
|---|---|
| the recipe | default of each variable |
| a profile file | spectro pipeline <recipe> --profile lhires_lyon.yaml |
| the command line | --set tilt_deg=1.1 (repeatable) |
| Python | PipelineBuilder().from_preset("be_halpha_ew", {"tilt_deg": 1.1}) |
| MCP | run_preset(session_id, "be_halpha_ew", variables={"tilt_deg": 1.1}) |
Keep your profiles next to your data, one per instrument setup, and reuse
them across every recipe: the same alpy600_toulouse.yaml serves the Be
star recipe tonight and the nova recipe next month.
requires¶
The kernel version range the recipe was validated for, with the plain
comparison operators (>=, >, <=, <, ==, !=, comma-separated). A
recipe whose range excludes the running kernel refuses to build. When a
brick used by a recipe changes its own major version (its numbers changed),
the recipe author re-validates and bumps the recipe.
Metadata vocabulary¶
| Key | Values | Meaning |
|---|---|---|
kind |
analysis, reduction, campaign, template |
what the recipe is for; a campaign recipe fixes a measurement convention for a community |
status |
draft, reviewed, reference |
how far the review went (see Share a recipe) |
references |
list of strings | the papers the conventions rest on; mandatory for campaign |
conventions |
text | the choices that are not fixed by the literature, stated plainly |
author, notes, expects, category |
text | free information shown on the recipe page |
Validation¶
spectro preset validate be_halpha_ew.yaml # the file alone
spectro preset validate be_halpha_ew.yaml --profile p.yaml # plus your values
spectro preset show be_halpha_ew # variables and steps
Validation is what the CI of a recipe collection runs on every contribution.
It reports, all at once: a name that is not snake_case, a missing or malformed
version, a missing description, an unknown kind or status, a campaign
recipe without references, a requires range the kernel does not satisfy,
an unknown algorithm, an unknown parameter name, a required parameter that is
neither set nor bound to a variable, an undeclared ${token}, an unused
variable, and a depends_on that matches no step.
Provenance¶
When a recipe runs, every brick records itself in the context history as before, and the run closes with one more record:
algorithm pipeline:be_halpha_ew
version 1.0.0
params {variables: {...}, n_steps: 4, kernel_version: 0.7.0, source: package:spectro-kernel-recipes}
It is written by Pipeline.execute for every named pipeline built from a
file or a config, and carried into every export that serialises the history.
Ad-hoc pipelines assembled in Python without a name leave the history exactly
as their steps wrote it.
Discovery¶
spectro presets lists every recipe the kernel can see, in this search order:
- the recipes bundled with the kernel;
- the directories listed in the
SPECTRO_PRESET_PATHenvironment variable (:-separated on macOS and Linux); - installed packages that register an entry point in the
spectro_kernel.presetsgroup (see Share a recipe).
A bundled name always wins over an external one with the same name. A recipe
can also be run from a path (spectro pipeline ./my_recipe.yaml). Nothing is
ever fetched from the network.