Pipeline configuration reference#
This page summarises the YAML keys understood by MoDaCor pipeline definitions.
Step fields#
Each entry under steps is keyed by a step_id and supports the following fields:
module(required): ProcessStep class name to instantiate.requires_steps(optional): list of step_ids that must run before this step.configuration(optional): dictionary of ProcessStep configuration values.short_title(optional): a brief, human-friendly purpose label used in graphs (Mermaid/DOT). This is appended as a second line in node labels, e.g.AU: MultiplyDatabundles+scaling to absolute units.
Step configuration validation#
Each configuration block is checked when Pipeline.from_yaml(...) loads the
pipeline. MoDaCor builds the accepted key list and top-level type policy from
the selected module class:
shared
ProcessStepkeys fromCONFIG_KEYSmodule-specific keys from
ProcessStepDescriber.arguments
For example, Divide.divisor_source is declared as a string source reference,
so this is valid:
steps:
normalize:
module: Divide
configuration:
with_processing_keys:
- sample
divisor_source: sample::entry/frame_exposure_time
and this fails during pipeline loading because divisor_source is not a string:
steps:
normalize:
module: Divide
configuration:
divisor_source: 3
The central validator catches unknown keys and top-level type mismatches. Module code still performs semantic checks for values that need runtime context, such as missing sources, non-empty required strings, mutually exclusive options, or nested dictionary contents.
NeXus detector frames#
MoDaCor has a generic NeXus transformation-chain resolver in the base modules.
It follows scalar depends_on links, resolves relative NeXus paths, and returns
a 4x4 affine transform matrix in SI length units. The resolver is deliberately
not a scattering-only feature: the same NeXus transformation-chain convention
can describe detectors, sample stages, and other instrument components.
Scattering detector coordinate modules can use this resolver through a
detector_frame configuration block. This keeps pipeline YAML lean because
PixelCoordinates3D can read the detector origin, fast/slow pixel directions,
pixel pitches, and detector normal from the configured NXdetector directly:
steps:
pixel_coordinates:
module: PixelCoordinates3D
configuration:
with_processing_keys: [static]
detector_frame:
type: nexus
source: calibration
detector_path: /entry1/instrument/detector
module_origin: first_pixel_center
XSGeometryFromPixelCoordinates accepts the same detector_frame block to
reuse the NeXus pixel pitches and detector normal for solid-angle calculation:
steps:
scattering_geometry:
module: XSGeometryFromPixelCoordinates
requires_steps: [pixel_coordinates]
configuration:
with_processing_keys: [static]
detector_frame:
type: nexus
source: calibration
detector_path: /entry1/instrument/detector
module_origin: first_pixel_center
sample_z_override:
value: 0.0
units: mm
wavelength_source: calibration::/entry1/calibration_sample/beam/incident_wavelength
wavelength_units_source: calibration::/entry1/calibration_sample/beam/incident_wavelength@units
For measurement files with a NeXus sample-stage transformation chain,
sample_z_override can also resolve the sample position from that chain:
sample_z_override:
type: nexus
source: sample
transform_path: /entry1/sample/transformations/sample_z
component: z
component defaults to z and is extracted from the resolved lab-frame
translation. The current scattering geometry calculation still models the
sample position as (0, 0, sample_z); this override makes chained NeXus
translations usable for the z coordinate without adding a separate
preprocessing copy step.
The source value is an IoSources reference. detector_path points to the
NXdetector; by default MoDaCor reads its detector_module child. Use
detector_module_name when the module has a different child name.
module_origin controls how an NXdetector_module/module_offset is interpreted:
corner: use the resolved module offset directly.first_pixel_center: treat the resolved module offset as the first pixel centre. MoDaCor converts it back to a corner origin becausePixelCoordinates3Dadds the half-pixel centre shift internally.
The older explicit configuration form remains supported. Use direct
det_coord_*_source, pixel_pitch_*_source, and basis_* values when data are
not NeXus encoded or when a pipeline intentionally overrides the file geometry.
Threshold masks#
ThresholdMask creates a uint32 mask from any BaseData entry in a selected
DataBundle, not only from signal. This is useful when a correction map
stored with the measurement should define invalid detector pixels. For example,
to mask pixels whose flatfield correction matrix falls outside an acceptable
range:
steps:
load_flatfield:
module: AppendProcessingData
configuration:
processing_key: sample
signal_location: sample::entry/instrument/detector/flatfield
rank_of_data: 2
databundle_output_key: flatfield
units_override: dimensionless
flatfield_mask:
module: ThresholdMask
requires_steps: [load_flatfield]
configuration:
with_processing_keys: [sample]
source_basedata_key: flatfield
target_mask_key: flatfield_mask
lower_bound: 0.8
upper_bound: 1.2
mask_mode: outside
Use mask_mode: outside to mask values below lower_bound or above
upper_bound. Use mask_mode: inside to mask values within the inclusive
range instead. The older threshold option is still accepted as an upper-bound
alias when upper_bound is not configured. The created mask keeps the same
array shape as the source_basedata_key; leading image or frame axes are not
collapsed before thresholding.
The same step can create geometry masks from Q or Psi BaseData entries. For
example, this masks pixels outside a radial Q range and outside an azimuthal Psi
range, combines those masks, and applies the combined mask to the sample
signal:
steps:
q_range_mask:
module: ThresholdMask
configuration:
with_processing_keys: [sample]
source_basedata_key: Q
target_mask_key: q_mask
lower_bound: 0.05
upper_bound: 3.0
mask_mode: outside
psi_range_mask:
module: ThresholdMask
configuration:
with_processing_keys: [sample]
source_basedata_key: Psi
target_mask_key: psi_mask
lower_bound: -0.7853981633974483
upper_bound: 0.7853981633974483
mask_mode: outside
combine_geometry_masks:
module: BitwiseOrMasks
requires_steps: [q_range_mask, psi_range_mask]
configuration:
with_processing_keys: [sample]
target_mask_key: mask
source_mask_keys: [q_mask, psi_mask]
apply_geometry_mask:
module: ApplyMask
requires_steps: [combine_geometry_masks]
configuration:
with_processing_keys: [sample]
mask_key: mask
basedata_to_mask: [signal]
Use mask_mode: inside for the inverse region of interest, for example to mask
only a beamstop band or a known bad azimuthal sector while leaving the rest of
the detector unmasked.
For dynamic detector data, keep the dimensionality semantics explicit:
Use
ThresholdMaskbefore normalization or frame averaging to create a frame-resolved raw-count mask.Use
ReduceMaskto collapse non-detector axes while preserving NeXus bitfield reason bits.reduction: anykeeps a pixel masked if it was masked in any reduced frame;reduction: allkeeps only bits present in every reduced frame.Use
BitwiseOrMasksto combine a reduced dynamic mask with a static instrument mask beforeIndexedAverager.
ReduceDimensionality is intentionally signal-oriented and performs numeric
mean/sum reductions. It is not a replacement for ReduceMask, because numeric
averaging does not preserve integer mask bitfields.
When ApplyMask is used to replace masked signal values, masked_value
defaults to nan. Explicit sentinel values remain available:
steps:
apply_mask:
module: ApplyMask
configuration:
with_processing_keys: [sample]
mask_key: mask
basedata_to_mask: [signal]
masked_value: nan
When a pipeline is loaded through a runtime service using the restricted
runtime policy, the module name must resolve through the service’s curated or
explicit ProcessStepRegistry. Filesystem discovery of unregistered module
files is disabled in that mode. If loading fails with filesystem discovery is disabled by runtime policy, export/register the step in the service registry or
run a trusted local service.