Skip to content

group

src

Selects, per transducer, which pattern’s emission is output. The transducers are split by assigning keys (an enum, for example) with TransducerGroups. Transducers with no key produce no output.

There are two composing APIs.

  • group_compute — receives each key together with its TransducerMask, computes, and composes the results.
  • group — composes precomputed buffers selected by key. Use it to reuse results or to compute groups in parallel.
#[derive(Clone, Copy, PartialEq, Eq)]
enum Side {
Left,
Right,
}
group_compute(
&geometry,
&groups,
|side, mask, buffer| match side {
Side::Left => gspat(
&NalgebraBackend,
&geometry,
&foci,
wavelength,
&GspatOption {
mask,
..Default::default()
},
buffer,
),
Side::Right => {
focus(&geometry, target, wavelength, buffer);
Ok(())
}
},
&mut dst,
)?;
Parameter Type Description
geometry &Geometry Geometry
groups &TransducerGroups<K> Key of each transducer
compute FnMut(K, TransducerMask, &mut [Vec<Emission>]) -> Result<(), E> Computes into the scratch buffer for a key and its mask
dst &mut [Vec<Emission>] Output buffer

compute is called once per key (in order of first appearance), and only the transducers of that key are written into dst. Transducers not assigned to any key produce no output (Emission::NULL).

#[derive(Clone, Copy, PartialEq, Eq)]
enum Side {
Left,
Right,
}
let groups = TransducerGroups::new(&geometry, |device, tr| {
Some(if device.position(tr).x < center.x {
Side::Left
} else {
Side::Right
})
});
group(
&geometry,
&groups,
|side| match side {
Side::Left => &left,
Side::Right => &right,
},
&mut dst,
);
Parameter Type Description
geometry &Geometry Geometry
groups &TransducerGroups<K> Key of each transducer
source FnMut(K) -> impl AsRef<[Vec<Emission>]> Returns the source buffer for a key
dst &mut [Vec<Emission>] Output buffer

TransducerGroups::new(&geometry, |device, tr| ...) returns a key (None = no group) from a device and transducer index, and keeps the key of each transducer. Keys are Copy + Eq types in Rust, value types (struct) in C#, and hashable values in Python. mask(key) returns a TransducerMask for Holo that enables only the transducers with key.

use anyhow::Result;
use autd3_rs::geometry::{Autd3, Geometry, TransducerGroups, offset};
use autd3_rs::units::{m, mm, s};
use autd3_rs_pattern::{focus, group_compute, wavelength};
use autd3_rs_pattern_holo::{AmplitudeTarget, GspatOption, NalgebraBackend, Pa, gspat};
#[derive(Clone, Copy, PartialEq, Eq)]
enum Side {
Left,
Right,
}
let geometry = Geometry::new(vec![Autd3::default()]);
let wavelength = wavelength(340.0 * m / s);
let center = geometry.center();
let groups = TransducerGroups::new(&geometry, |device, tr| {
Some(if device.position(tr).x < center.x {
Side::Left
} else {
Side::Right
})
});
let foci = [
AmplitudeTarget {
point: center + offset(-50.0 * mm, 0.0 * mm, 150.0 * mm),
amplitude: 5e3 * Pa,
},
AmplitudeTarget {
point: center + offset(-20.0 * mm, 0.0 * mm, 150.0 * mm),
amplitude: 5e3 * Pa,
},
];
let mut dst = geometry.pattern_buffer();
group_compute(
&geometry,
&groups,
|side, mask, buffer| match side {
Side::Left => gspat(
&NalgebraBackend,
&geometry,
&foci,
wavelength,
&GspatOption {
mask,
..Default::default()
},
buffer,
),
Side::Right => {
focus(
&geometry,
center + offset(40.0 * mm, 0.0 * mm, 150.0 * mm),
wavelength,
buffer,
);
Ok(())
}
},
&mut dst,
)?;