Spec Syntax Reference¶
Specs define how Bruker Paravision parameter files are mapped into structured outputs. They are pure mapping recipes: no conditional selection, no runtime state, no project-specific logic.
Specs are selected by rules and evaluated by the remapper engine.
Purpose¶
Specs are used to:
- define fields shown by
brkraw info - generate structured metadata dictionaries
- populate sidecar JSON files (for example BIDS-style metadata)
- provide normalized values for layout and naming
Specs do not:
- decide when they apply (rules do that)
- modify values conditionally per project (context maps do that)
- control output filenames directly
Info specs (inspection-focused)¶
Info specs shape what brkraw info shows. When paired with a rule, they can
make the output modality-aware.
Example info spec (assume bids_bold_info is installed):
__meta__:
name: "bids_bold_info"
version: "1.0.0"
category: "info_spec"
transforms_source: "<spec-name>_transforms.py"
Method:
sources:
- file: method
key: Method
transform: to_bids_modality
Protocol:
sources:
- file: acqp
key: ACQ_Protocol
transform: to_bids_protocol
Specification:
- Field
Methodis specified by readingMethodfrom themethodfile, processing it withto_bids_modality, and mapping the result toMethod. - Field
Protocolis specified by readingACQ_Protocolfrom theacqpfile, processing it withto_bids_protocol, and mapping the result toProtocol.
Example input parameters:
method:Method = Bruker:EPI
acqp:ACQ_Protocol = 3_fMRI_protocol
Example output (after mapping + transforms):
Method: bold
Protocol: func
Metadata specs (sidecar-focused)¶
Metadata specs control JSON sidecars for conversion. Keep them small and structured, then let layout handle filenames.
Example metadata spec (assume bids_bold_metadata is installed):
__meta__:
name: "bids_bold_metadata"
version: "1.0.0"
category: "metadata_spec"
transforms_source: "<spec-name>_transforms.py"
RepetitionTime:
sources:
- file: method
key: PVM_RepetitionTime
transform: ms_to_s
PhaseEncodingDirection:
sources:
- file: method
key: PVM_EPI_PhaseEncDir
transform: to_bids_phase_dir
Specification:
- Field
RepetitionTimeis specified by readingPVM_RepetitionTimefrom themethodfile, processing it withms_to_s, and mapping the result toRepetitionTime. - Field
PhaseEncodingDirectionis specified by readingPVM_EPI_PhaseEncDirfrom themethodfile, processing it withto_bids_phase_dir, and mapping the result toPhaseEncodingDirection.
Resulting sidecar fragment:
{
"RepetitionTime": 2.0,
"PhaseEncodingDirection": "j-"
}
Note:
- When this metadata spec is selected, its output keys become sidecar JSON keys (after transforms are applied).
Spec file structure¶
A spec is a YAML mapping with two kinds of top-level entries:
__meta__: required metadata describing the spec- output keys: mapping definitions
Example:
__meta__:
name: "<spec-name>"
version: "1.0.0"
description: "Metadata mapping for a specific acquisition family"
category: "info_spec"
transforms_source: "<spec-name>_transforms.py"
Subject.ID:
sources:
- file: subject
key: SUBJECT_id
Specification:
- Field
Subject.IDis specified by readingSUBJECT_idfrom thesubjectfile and mapping the value to a dotted output key (Subject.ID), which produces a nested structure.
meta block¶
Every spec must define __meta__.
Required fields¶
__meta__:
name: "<spec-name>"
version: "1.0.0"
description: "Metadata mapping for a specific scan family"
category: "info_spec"
Specification:
-
__meta__specifies the identity and compatibility of the spec (for example, rules can select byname/version, and selection can validatecategory). -
name- lowercase snake_case
- up to four tokens
- pattern:
^[a-z][a-z0-9]*(?:_[a-z0-9]+){0,3}$
version- free-form string
- compared lexically unless pinned by rules
description- human-readable summary
category- required when selected by rules
- must be one of:
info_specmetadata_spec
Optional meta fields¶
__meta__:
transforms_source: "transforms.py"
include: "base.yaml"
include_mode: "override"
authors:
- name: "Jane Doe"
email: "jane@example.com"
doi: "10.1234/example"
citation: "Doe et al., NeuroImage 2024"
Specification:
- If
includeis specified, referenced spec(s) are merged first, then the current spec applies its overrides (unlessinclude_mode: strict). - If
transforms_sourceis specified,transform:function names can be resolved when the spec is loaded from YAML.
Supported optional fields:
transforms_source- string or list of strings
- relative to the spec file unless absolute
- later files override earlier ones
include- string or list of spec paths
- merged before the current spec
include_modeoverride(default): current spec winsstrict: conflict raises an error
authors,developersdoicitation
Output keys¶
Each non-__meta__ top-level key defines one output field.
Keys may be dotted to create nested structures:
Study.ID:
sources:
- file: subject
key: SUBJECT_id
Produces:
{"Study": {"ID": "1"}}
Specification:
- Dotted output keys (e.g.,
Study.ID) specify nested keys in the resulting mapping.
Sources¶
The simplest mapping uses sources.
FieldName:
sources:
- file: method
key: PVM_SPackArrNSlices
Specification:
- Field
FieldNameis specified by readingPVM_SPackArrNSlicesfrom themethodfile and mapping the value toFieldName.
Each source entry supports:
file: one of:methodacqpvisu_parsrecosubject
key: parameter name inside that filereco_id: optional, forvisu_parsorreco
If multiple sources are listed, the first available value wins.
Inputs (derived fields)¶
Use inputs when a field depends on multiple values.
out.joined:
inputs:
a:
sources:
- file: method
key: PVM_SPackArrNSlices
b:
const: 3
transform: join_fields
Specification:
- Field
out.joinedis specified by:- input
a: readPVM_SPackArrNSlicesfrom themethodfile - input
b: constant3 - transform: call
join_fields(a=..., b=3)and map the result toout.joined
- input
Rules:
- exactly one of
sources,inputs,const, orrefis required inputsmay reference:sourcesconstref(previously resolved output)$scan_id,$reco_id
You can also define constant or reference rules directly at the top level:
FieldName:
const: 1
FieldCopy:
ref: "FieldName"
Specification:
- Field
FieldNameis specified as the constant value1. - Field
FieldCopyis specified as a reference to the previously-resolved outputFieldName.
Transforms¶
Transforms are Python functions referenced by name.
FieldName:
sources:
- file: acqp
key: ACQ_XXX
transform: normalize_method
Specification:
- Field
FieldNameis specified by readingACQ_XXXfrom theacqpfile, processing it withnormalize_method, and mapping the result toFieldName.
Behavior:
- a single transform receives the resolved value
- a list applies transforms sequentially
- with
inputs, the first transform receives keyword arguments - an empty transform list is invalid
Transforms must be available in the transform registry:
- for file-based specs, this registry is loaded from
__meta__.transforms_source - for programmatic use, pass
transforms={...}intomap_parameters(...)
Transforms Require transforms_source
If you use transform: anywhere in a spec file, you must ensure BrkRaw can
load those functions.
- When loading from YAML with load_spec(...), set __meta__.transforms_source
so load_spec(...) returns a non-empty transforms registry.
- When building specs programmatically, pass transforms={...} to map_parameters(...).
If you reference transforms but provide no registry, mapping will fail at
runtime (missing transform function).
Inline inputs inside sources (advanced)¶
sources: items may include an inline inputs: block (optionally with a transform:).
This is useful when you want a computed fallback in a sources chain.
FieldName:
sources:
- inputs:
a:
sources:
- file: method
key: PVM_SPackArrNSlices
b:
const: 3
transform: join_fields
- file: method
key: PVM_SPackArrNSlices
Specification:
- Field
FieldNameis specified by asourceschain:- first source: computed value via
join_fields(...) - fallback source: raw
method:PVM_SPackArrNSlicesvalue
- first source: computed value via
Defaults and requirements¶
Input entries (inside inputs:) may define:
default: 1
Specification:
-
If an input has no value,
defaultspecifies the fallback value. -
default: fallback if no input value is found
Input entries (inside inputs:) may also define:
required: true
Specification:
-
If an input has no value and
required: true, mapping raises an error. -
required: missing input raises an error (instead of returningNone)
Output rules do not have a required flag; use sources ordering or an inline
inputs source entry for fallbacks.
Study-level behavior¶
When a Study-like object is used as the source:
- only
file: subjectis allowed - at least one subject source must be present
What specs intentionally do not handle¶
Specs do not define:
- conditional overrides per project
- subject or session remapping
- scan selection logic
- output layout rules
Those belong to:
- rules (selection)
- context maps (runtime remapping)
- layout configuration (naming)
Relationship to context maps¶
Specs produce canonical outputs.
Context maps:
- are supplied at runtime
- operate after spec evaluation
- may override or extend spec outputs
- may introduce selectors for conversion
See Context map syntax for mapping rules and schema.
Validation¶
To validate a spec file (including transform sources), prefer loading it through the spec loader:
from brkraw.specs.remapper import load_spec, map_parameters
spec, transforms = load_spec("spec.yaml", validate=True)
result = map_parameters(scan, spec, transforms=transforms)
Note:
load_spec(...)returns both the spec mapping and the transform registry needed to evaluatetransform:references.
Validation checks:
- schema compliance
- transform source paths (when validating a spec file)
- source correctness