qsm_core/pipeline/observer.rs
1//! Progress and intermediate outputs reported by pipeline stages as they run.
2//!
3//! A stage that produces more than its return value (QSMART's vessel mask and per-stage local
4//! fields and χ, for example) hands each intermediate to an [`Observer`] as soon as it exists.
5//! The observer gets a borrowed slice, so a host that only wants the final result keeps no extra
6//! copies, and a host that wants to show or save an intermediate copies or writes just that one.
7//!
8//! Any `FnMut(usize, usize)` closure is an observer that takes progress and ignores outputs, and
9//! `&mut ()` is an observer that ignores both.
10
11/// A borrowed volume reported by a stage: real-valued data or a binary mask, in the stage's
12/// grid (same dimensions and voxel order as its inputs).
13#[derive(Clone, Copy, Debug)]
14pub enum VolumeRef<'a> {
15 /// Real-valued volume (a field or susceptibility map, in the units the stage documents).
16 Real(&'a [f64]),
17 /// Binary mask (1 = inside, 0 = outside).
18 Mask(&'a [u8]),
19}
20
21/// Receives a stage's progress and its intermediate outputs as they are produced.
22///
23/// Both methods default to doing nothing, so an implementation overrides only what it uses.
24pub trait Observer {
25 /// Step `done` of `total` has started.
26 fn progress(&mut self, _done: usize, _total: usize) {}
27
28 /// An intermediate output named `name` is ready. The stage documents its names; the slice is
29 /// only valid for the duration of the call.
30 fn output(&mut self, _name: &'static str, _volume: VolumeRef<'_>) {}
31}
32
33/// A progress callback is an observer that ignores intermediate outputs.
34impl<F: FnMut(usize, usize)> Observer for F {
35 fn progress(&mut self, done: usize, total: usize) {
36 self(done, total)
37 }
38}
39
40/// Ignores progress and outputs.
41impl Observer for () {}