autd3_core/gain/mod.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
mod drive;
mod emit_intensity;
mod error;
mod phase;
use std::collections::HashMap;
/// A bit vector type.
pub type BitVec = bit_vec::BitVec<u32>;
pub use drive::Drive;
pub use emit_intensity::EmitIntensity;
pub use error::GainError;
pub use phase::Phase;
use crate::{
datagram::{Segment, TransitionMode},
geometry::{Device, Geometry, Transducer},
};
/// A trait to calculate the phase and intensity for [`Gain`].
///
/// [`Gain`]: crate::gain::Gain
pub trait GainCalculator: Send + Sync {
/// Calculates the phase and intensity for the transducer.
fn calc(&self, tr: &Transducer) -> Drive;
}
impl GainCalculator for Box<dyn GainCalculator> {
fn calc(&self, tr: &Transducer) -> Drive {
self.as_ref().calc(tr)
}
}
/// A trait for generating a calculator for the gain operation.
pub trait GainCalculatorGenerator {
/// The type of the calculator that actually performs the calculation.
type Calculator: GainCalculator;
/// Generate a calculator for the given device.
fn generate(&mut self, device: &Device) -> Self::Calculator;
}
/// Trait for calculating the phase/amplitude of each transducer.
///
/// See also [`Gain`] derive macro.
///
/// [`Gain`]: autd3_derive::Gain
pub trait Gain: std::fmt::Debug + Sized {
/// The type of the calculator generator.
type G: GainCalculatorGenerator;
/// Initialize the gain and generate the calculator generator.
fn init(self) -> Result<Self::G, GainError>;
/// Initialize the gain and generate the calculator generator.
///
/// `filter` is a hash map that holds a bit vector representing the indices of the enabled transducers for each device index.
/// If `filter` is `None`, all transducers are enabled.
fn init_full(
self,
_: &Geometry,
_filter: Option<&HashMap<usize, BitVec>>,
_parallel: bool,
) -> Result<Self::G, GainError> {
self.init()
}
}
#[doc(hidden)]
pub struct GainOperationGenerator<G: GainCalculatorGenerator> {
pub generator: G,
pub segment: Segment,
pub transition: Option<TransitionMode>,
}
impl<G: GainCalculatorGenerator> GainOperationGenerator<G> {
pub fn new<T: Gain<G = G>>(
gain: T,
geometry: &Geometry,
segment: Segment,
transition: Option<TransitionMode>,
parallel: bool,
) -> Result<Self, GainError> {
Ok(Self {
generator: gain.init_full(geometry, None, parallel)?,
segment,
transition,
})
}
}