PIV Processing
Configure multi-pass cross-correlation for instantaneous or ensemble analysis.
Overview
| Instantaneous | Ensemble | |
|---|---|---|
| Output | Velocity field per frame pair | Single mean velocity field |
| Correlation | Per frame pair | Averaged across all pairs |
| Use case | Time-resolved data, turbulence statistics | Mean flow, low seeding, max resolution |
| Pass types | Standard only | Standard + Single mode |
| Peak finder | Configurable (gauss3-6) | Configurable (default gauss6) |
| Live preview | Yes (per-frame) | No (accumulated) |
| Resume | No | Yes (resume_from_pass) |
Window Configuration
Both modes use multi-pass refinement. Each pass refines results from the previous one. Configure passes in the GUI pass table or directly in YAML.
| Parameter | Format | Description |
|---|---|---|
| window_size | [Height, Width] | Interrogation window in pixels per pass. Must be powers of 2. Rectangular windows supported. |
| overlap | integer (%) | Overlap percentage per pass. 50% doubles grid density. |
| runs | list of pass numbers | Which passes to save (1-based). Last pass always saved. |
| type (ensemble) | 'std' | 'single' | Standard or single-pixel mode per pass. |
Window size convention: [Height, Width] (row-major). Height = vertical (Y), Width = horizontal (X). Use rectangular windows for directional flows (e.g., [32, 64] for predominantly horizontal flow).
# Typical 3-pass configuration
instantaneous_piv:
window_size:
- [128, 128] # Pass 1: large windows
- [64, 64] # Pass 2: refinement
- [32, 32] # Pass 3: final
overlap:
- 50
- 50
- 50
runs:
- 3 # Save pass 3 onlySingle Mode and Sum Window
Ensemble only. Appears when any pass uses type single.
Single mode uses asymmetric window weighting: Frame A gets a small central window (the configured window_size), Frame B gets the full sum_window. This concentrates the measurement on a small region while computing correlations at the larger FFT size.
| Parameter | Description | Constraint |
|---|---|---|
| sum_window | FFT correlation window size [H, W] | Must be >= window_size |
| sum_fitting_window | Central extraction for fitting (optional) | Reduces memory and speeds fitting |
ensemble_piv:
window_size:
- [128, 128] # Pass 1: std
- [64, 64] # Pass 2: std
- [16, 16] # Pass 3: single
type:
- std
- std
- single
sum_window:
- 64
- 64 # [Height, Width] for single passesCamera Selection
Select which cameras to process via numbered chips in the GUI. At least one must be selected. In YAML, set paths.camera_numbers.
Peak Finding
Both modes. Instantaneous defaults to gauss3. Ensemble defaults to gauss6.
| Algorithm | DOF | Description |
|---|---|---|
| gauss3 | 3 | Parabolic (1D Gaussian). Fastest. |
| gauss4 | 4 | Circular Gaussian with amplitude. |
| gauss5 | 5 | Elliptical Gaussian. Good for anisotropic flows. |
| gauss6 | 6 | Rotated elliptical Gaussian. Maximum accuracy. |
instantaneous_piv:
peak_finder: gauss3 # Options: gauss3, gauss4, gauss5, gauss6Predictor & Peak Settings
Control how the predictor field is refined between multi-pass iterations and configure multi-peak detection.
| Setting | Default | Mode | Description |
|---|---|---|---|
| predictor_smoothing | true / false | Inst / Ens | Gaussian-smooth the predictor between passes. Recommended for instantaneous (reduces single-pair noise). For ensemble, smoothing can destroy real gradients — leave disabled unless data is very noisy. |
| predictor_interpolation | cubic | Ensemble | Interpolation for upscaling the predictor field between passes. Options: linear or cubic. |
| image_warp_interpolation | cubic | Both | Interpolation kernel for image warping during predictor deformation. cubic = bicubic (4×4 stencil), lanczos = Lanczos-3 (6×6 stencil, slightly sharper). |
| secondary_peak | false | Instantaneous | Extract the second-highest correlation peak per window. Useful for reverse flow or multiple particle populations. |
| num_peaks | 1 | Instantaneous | Number of correlation peaks to detect per window. Usually 1; increase for multi-peak analysis. |
| save_mode | minimal | Instantaneous | Output fields per vector file. 'minimal' saves ux, uy, b_mask only (fastest). 'full' saves all 11 fields including peak height, sigma, stresses. |
| save_compression | false | Instantaneous | Enable ZLIB compression on .mat output files. Slower writes but smaller file size. |
instantaneous_piv:
predictor_smoothing: true
secondary_peak: false
num_peaks: 1
save_mode: minimal
save_compression: false
image_warp_interpolation: cubic
ensemble_piv:
predictor_smoothing: false
predictor_interpolation: cubic
image_warp_interpolation: cubicBoundary Conditions
Ensemble only. Overrides edge-replicated predictor padding near walls with prescribed velocity values.
In wall-bounded flows, the predictor field near boundaries can be corrupted by edge replication. Boundary conditions let you prescribe known velocities (e.g., no-slip: ux=0, uy=0) at specific wall positions.
| Field | Type | Description |
|---|---|---|
| y_position | int (px) | Row position of the wall in the image |
| ux | float (px/frame) | Prescribed horizontal displacement at the wall |
| uy | float (px/frame) | Prescribed vertical displacement at the wall |
| edge | 'bottom' | 'top' | Which image edge the wall is near |
ensemble_piv:
predictor_boundary_conditions:
- y_position: 10
ux: 0
uy: 0
edge: bottom
- y_position: 950
ux: 0
uy: 0
edge: topCorrelation & Fitting
Ensemble only. Advanced controls for peak fitting and memory management.
| Setting | Default | Description |
|---|---|---|
| fit_offset | true | Include a constant offset in the Gaussian sub-pixel fit. Accounts for correlation plane background level. |
| mask_center_pixel | true | Mask the autocorrelation center pixel before peak fitting. Prevents the zero-lag spike from biasing displacement estimates. |
| persist_images | false | Keep all filtered images in worker RAM across passes. Faster on HPC with lots of memory, but significantly increases RAM usage. |
| sum_fitting_window_enabled | false | Extract a central sub-region from the summed correlation plane before peak fitting. Reduces memory and speeds up fitting. |
| sum_fitting_window | [16, 16] | Size [H, W] of the central extraction window. Only active when sum_fitting_window_enabled is true. |
ensemble_piv:
fit_offset: true
mask_center_pixel: true
persist_images: false
sum_fitting_window_enabled: false
sum_fitting_window:
- 16
- 16Ensemble Options
Ensemble only. Available in the collapsible Ensemble Options panel.
| Setting | Default | Description |
|---|---|---|
| fit_method | kspace | 'kspace' (Fourier-space, 5-param, default, 50-100x faster) or 'gaussian' (Levenberg-Marquardt, 16-param). K-space recommended for all use cases. |
| background_subtraction_method | correlation | 'correlation': R = <AB> - <A><B> (single-pass, memory efficient). 'image': R = <(A-μA)(B-μB)> (two-pass, more stable for k-space) |
| gradient_correction | false | Reynolds stress gradient correction near walls |
| kspace_soft_weighting | true | Anisotropic soft spectral weighting in k-space fitting. Improves Reynolds stress accuracy, especially at small window sizes. |
| kspace_k_max_cap | 0.35 | Maximum wavenumber cap for k-space fitting (0.0-0.5). Controls the spectral bandwidth used for displacement estimation. |
| store_planes | false | Save AA, BB, AB correlation planes to disk (large files) |
| save_diagnostics | false | Save debug images and peak fitting data to filters/ directory |
| resume_from_pass | 0 | Resume from pass N (1-based). 0 = fresh start. Requires existing ensemble_result.mat. |
Performance Settings
Configure parallel processing resources. Applies to both modes.
| Setting | Default | Description |
|---|---|---|
| backend | cpu | Processing backend |
| omp_threads | 4 | OpenMP threads per worker for C extensions |
| dask_workers_per_node | 2 | Number of parallel Dask workers |
| dask_memory_limit | 8GB | RAM allocation per worker |
| dask_max_in_flight_per_worker | 3 | Max concurrent tasks queued per worker. Higher values (4-6) improve I/O pipelining on HPC with fast storage. |
| open_dashboard | false | Auto-open the Dask performance dashboard in your browser when processing starts |
| cluster_type | local | 'local' or 'slurm' |
| filter_worker_count | 1 | Workers for preprocessing. Set 1 for temporal filters, 2+ for spatial-only. |
| auto_compute_params | false | Auto-compute omp_threads, dask_workers, and dask_memory from system resources |
| n_nodes | 1 | Number of compute nodes (SLURM cluster only) |
| slurm_walltime | 01:00:00 | Job walltime for SLURM submissions |
| slurm_partition | (none) | SLURM partition name |
| post_processing_workers | auto | Max parallel workers for calibration, statistics, merge, and transform. auto = min(cpu_count, 16) |
processing:
backend: cpu
omp_threads: 4
dask_workers_per_node: 2
dask_memory_limit: 8GB
dask_max_in_flight_per_worker: 3
open_dashboard: false
cluster_type: local
filter_worker_count: 1Outlier Detection
Identify and mark spurious vectors for replacement. Multiple methods can be chained. Instantaneous and ensemble use separate config sections.
| Method | Parameters | Description |
|---|---|---|
| peak_mag | threshold: 0.4 | Reject vectors with correlation peak below threshold |
| median_2d | epsilon: 0.2, threshold: 2.0 | Normalised median test against 8 neighbours |
outlier_detection:
enabled: true
methods:
- type: peak_mag
threshold: 0.4
- type: median_2d
epsilon: 0.2
threshold: 2ensemble_outlier_detection:
enabled: true
methods:
- type: median_2d
epsilon: 0.2
threshold: 2Infilling
Replace outlier vectors (NaN) with interpolated values. Applied in two phases: mid-pass (between passes, always enabled) and final-pass (on output, optional).
| Method | Parameters | Description |
|---|---|---|
| local_median | ksize: 3 | Median of neighbours. Fast, small gaps. |
| biharmonic | (none) | PDE-based smooth interpolation. High quality. |
| knn | n_neighbors: 32, weights: 'distance' | Distance-weighted regression. Sparse data. |
infilling: # or ensemble_infilling:
mid_pass:
method: biharmonic # no parameters needed
final_pass:
enabled: true
method: biharmonic # no parameters neededNaN Reason Codes
Every interrogation window is assigned a nan_reason code indicating why it was marked invalid, or 0 if it passed all checks. This field is saved in the output .mat file and is shared by both Gaussian and k-space fitters.
| Code | Stage | Description |
|---|---|---|
| -1 | Pre-fitting | Masked vector (outside ROI / polygon mask) |
| 0 | Success | Fit succeeded and passed all validation checks |
| 1 | Fitting | Solver did not converge (LM for Gaussian, TRF for k-space) |
| 2 | Post-fit validation | AB peak height invalid (Gaussian) or SNR too low (k-space) |
| 3 | Post-fit validation | Displacement exceeds 3/4 window rule (peak too far from centre) |
| 5 | Post-fit validation | Negative sigma / variance values (unphysical fit) |
| 6 | Displacement check | Displacement exceeds 3/4 window rule (checked in accumulator) |
| 10 | Outlier detection | Velocity outlier: fit succeeded but flagged by median-based displacement outlier detection |
| 11 | Outlier detection | Stress outlier: fit succeeded but flagged by stress field median test or Cauchy-Schwarz realizability violation (ensemble only) |
Validation pipeline order
- Fitter attempts fit (codes 1, 2)
- Post-fit parameter validation (codes 3, 5)
- Displacement magnitude check in accumulator (code 6)
- Velocity outlier detection via median test (code 10)
- Stress outlier detection + realizability check, ensemble final pass only (code 11)
- Vectors with code 0 after all checks are valid
Codes 3 and 6 both enforce the 3/4 displacement rule but at different stages: code 3 is checked inside the fitter, code 6 in the accumulator after the fitter returns. Vectors flagged with codes 10 or 11 are infilled from neighbours if infilling is enabled.
Running PIV
Start processing from the Run PIV card. Select which source/base path pairs to process via checkboxes.
Workflow
- Check the datasets to include. Same PIV settings apply to all selected paths.
- Click Run PIV. If output already exists, a confirmation dialog asks to clear and recompute.
- Monitor progress via the progress bar (instantaneous) or console logs (both modes).
- Cancel gracefully if needed. Partial results may be saved.
Instantaneous feedback
Progress bar, live vector field preview (variable selector, colormap), console logs.
Ensemble feedback
Status indicator + console logs only. No preview until all pairs are accumulated.
# Enable one mode at a time
processing:
instantaneous: true
ensemble: falseComplete YAML Reference
| YAML Path | Inst. | Ens. | Description |
|---|---|---|---|
| processing.instantaneous | Y | - | Enable instantaneous mode |
| processing.ensemble | - | Y | Enable ensemble mode |
| *_piv.window_size | Y | Y | List of [H, W] per pass |
| *_piv.overlap | Y | Y | Overlap % per pass |
| *_piv.runs | Y | Y | Passes to save (1-based) |
| *_piv.peak_finder | Y | Y | gauss3 (inst default) / gauss4 / gauss5 / gauss6 (ens default) |
| *_piv.predictor_smoothing | Y | Y | Smooth predictor between passes (inst: true, ens: false) |
| instantaneous_piv.secondary_peak | Y | - | Detect secondary correlation peak (default false) |
| instantaneous_piv.num_peaks | Y | - | Number of peaks to detect (default 1) |
| ensemble_piv.type | - | Y | Per-pass: std or single |
| ensemble_piv.sum_window | - | Y | [H, W] for single mode |
| ensemble_piv.fit_method | - | Y | gaussian or kspace |
| ensemble_piv.kspace_soft_weighting | - | Y | Soft spectral weighting for k-space (default true) |
| ensemble_piv.kspace_k_max_cap | - | Y | Max wavenumber cap (default 0.35) |
| ensemble_piv.background_subtraction_method | - | Y | correlation or image |
| ensemble_piv.gradient_correction | - | Y | Reynolds stress gradient correction |
| ensemble_piv.fit_offset | - | Y | Include offset in Gaussian fit (default true) |
| ensemble_piv.mask_center_pixel | - | Y | Mask autocorrelation center pixel (default true) |
| ensemble_piv.persist_images | - | Y | Keep filtered images in worker RAM (default false) |
| ensemble_piv.predictor_interpolation | - | Y | Predictor upscaling: linear or cubic |
| ensemble_piv.image_warp_interpolation | - | Y | Image warp kernel: cubic or lanczos |
| instantaneous_piv.image_warp_interpolation | Y | - | Image warp kernel: cubic or lanczos (default cubic) |
| instantaneous_piv.save_mode | Y | - | minimal (3 fields) or full (11 fields) |
| instantaneous_piv.save_compression | Y | - | ZLIB compression on .mat files (default false) |
| ensemble_piv.predictor_boundary_conditions | - | Y | Wall boundary conditions array |
| ensemble_piv.sum_fitting_window_enabled | - | Y | Extract central sub-region for fitting |
| ensemble_piv.sum_fitting_window | - | Y | [H, W] extraction size (default [16,16]) |
| ensemble_piv.store_planes | - | Y | Save correlation planes |
| ensemble_piv.save_diagnostics | - | Y | Save debug data |
| ensemble_piv.resume_from_pass | - | Y | 0 = fresh, N = resume from pass N |
| outlier_detection.* | Y | - | enabled, methods: [{type, threshold, epsilon}] |
| ensemble_outlier_detection.* | - | Y | Same structure as outlier_detection |
| infilling.* | Y | - | mid_pass + final_pass config |
| ensemble_infilling.* | - | Y | Same structure as infilling |
| processing.omp_threads | Y | Y | OpenMP threads (default 4) |
| processing.dask_workers_per_node | Y | Y | Dask workers (default 2) |
| processing.dask_memory_limit | Y | Y | Per-worker RAM (default 8GB) |
| processing.dask_max_in_flight_per_worker | Y | Y | Max tasks per worker (default 3) |
| processing.open_dashboard | Y | Y | Auto-open Dask dashboard (default false) |
| processing.cluster_type | Y | Y | local or slurm |
| processing.auto_compute_params | Y | Y | Auto-compute worker/thread settings (default false) |
| processing.post_processing_workers | Y | Y | Parallel post-processing workers (default auto) |
processing:
instantaneous: true
ensemble: false
backend: cpu
omp_threads: 4
dask_workers_per_node: 2
dask_memory_limit: 8GB
dask_max_in_flight_per_worker: 3
open_dashboard: false
cluster_type: local
filter_worker_count: 1
auto_compute_params: false
post_processing_workers: null
instantaneous_piv:
window_size:
- [128, 128]
- [64, 64]
- [32, 32]
overlap:
- 50
- 50
- 50
runs:
- 3
peak_finder: gauss3
predictor_smoothing: true
secondary_peak: false
num_peaks: 1
image_warp_interpolation: cubic
save_mode: minimal
save_compression: false
ensemble_piv:
window_size:
- [128, 128]
- [64, 64]
- [16, 16]
overlap:
- 50
- 50
- 50
type:
- std
- std
- single
runs:
- 3
sum_window:
- 64
- 64
fit_method: kspace
background_subtraction_method: correlation
gradient_correction: false
kspace_soft_weighting: true
kspace_k_max_cap: 0.35
fit_offset: true
mask_center_pixel: true
persist_images: false
predictor_smoothing: false
predictor_interpolation: cubic
image_warp_interpolation: cubic
predictor_boundary_conditions: []
sum_fitting_window_enabled: false
sum_fitting_window:
- 16
- 16
store_planes: false
save_diagnostics: false
resume_from_pass: 0
outlier_detection:
enabled: true
methods:
- type: peak_mag
threshold: 0.4
- type: median_2d
epsilon: 0.2
threshold: 2
ensemble_outlier_detection:
enabled: true
methods:
- type: median_2d
epsilon: 0.2
threshold: 2
infilling:
mid_pass:
method: biharmonic
parameters: {}
final_pass:
enabled: true
method: biharmonic
parameters: {}
ensemble_infilling:
mid_pass:
method: biharmonic
parameters: {}
final_pass:
enabled: true
method: biharmonic
parameters: {}Command Line Usage
# Run instantaneous PIV
pivtools-cli instantaneous
# Run ensemble PIV
pivtools-cli ensemble
# Process specific paths only (0-indexed)
pivtools-cli instantaneous -p 0,2
# Override active paths
pivtools-cli ensemble --active-paths 0,1| Command | Description |
|---|---|
| pivtools-cli init | Create default config.yaml |
| pivtools-cli instantaneous | Run instantaneous PIV |
| pivtools-cli ensemble | Run ensemble PIV |
| pivtools-cli apply-calibration | Apply calibration to vectors |
| pivtools-cli statistics | Compute statistics |
| pivtools-cli transform | Apply geometric transforms |
| pivtools-cli merge | Merge multi-camera fields |
| pivtools-cli video | Create visualisation videos |
All commands read settings from config.yaml in the current directory. Use -p 0,1 to override paths.active_paths. Use --help for command-specific options.