autd3_core/gain/
mod.rs

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