Skip to main content

nanonis_rs/client/lockin/
types.rs

1// ==================== Lock-In Amplifier Types ====================
2
3/// Demodulator RT signal output mode.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum RTSignalMode {
6    /// X/Y (Cartesian) output
7    #[default]
8    XY = 0,
9    /// R/phi (Polar) output
10    RPhi = 1,
11}
12
13impl From<RTSignalMode> for u32 {
14    fn from(mode: RTSignalMode) -> Self {
15        mode as u32
16    }
17}
18
19impl TryFrom<u32> for RTSignalMode {
20    type Error = crate::error::NanonisError;
21
22    fn try_from(value: u32) -> Result<Self, Self::Error> {
23        match value {
24            0 => Ok(RTSignalMode::XY),
25            1 => Ok(RTSignalMode::RPhi),
26            _ => Err(crate::error::NanonisError::Protocol(format!(
27                "Invalid RTSignalMode value: {}",
28                value
29            ))),
30        }
31    }
32}
33
34/// Lock-in modulator configuration.
35#[derive(Debug, Clone)]
36pub struct ModulatorConfig {
37    /// Modulator number (1-8)
38    pub number: i32,
39    /// Whether modulator is on
40    pub enabled: bool,
41    /// Signal index being modulated
42    pub signal_index: i32,
43    /// Phase register index (1-8)
44    pub phase_register: i32,
45    /// Harmonic number (1 = base frequency)
46    pub harmonic: i32,
47    /// Phase offset in degrees
48    pub phase_deg: f32,
49    /// Modulation amplitude
50    pub amplitude: f32,
51    /// Frequency in Hz
52    pub frequency_hz: f64,
53}
54
55impl Default for ModulatorConfig {
56    fn default() -> Self {
57        Self {
58            number: 1,
59            enabled: false,
60            signal_index: 0,
61            phase_register: 1,
62            harmonic: 1,
63            phase_deg: 0.0,
64            amplitude: 0.0,
65            frequency_hz: 1000.0,
66        }
67    }
68}
69
70/// Lock-in demodulator configuration.
71#[derive(Debug, Clone)]
72pub struct DemodulatorConfig {
73    /// Demodulator number (1-8)
74    pub number: i32,
75    /// Signal index being demodulated
76    pub signal_index: i32,
77    /// Harmonic number (1 = base frequency)
78    pub harmonic: i32,
79    /// High-pass filter order (0 = off, 1-8)
80    pub hp_filter_order: i32,
81    /// High-pass filter cutoff frequency in Hz
82    pub hp_filter_cutoff_hz: f32,
83    /// Low-pass filter order (0 = off, 1-8)
84    pub lp_filter_order: i32,
85    /// Low-pass filter cutoff frequency in Hz
86    pub lp_filter_cutoff_hz: f32,
87    /// Phase register index (1-8)
88    pub phase_register: i32,
89    /// Reference phase in degrees
90    pub phase_deg: f32,
91    /// Sync filter enabled
92    pub sync_filter: bool,
93    /// RT signal mode (X/Y or R/phi)
94    pub rt_signal_mode: RTSignalMode,
95}
96
97impl Default for DemodulatorConfig {
98    fn default() -> Self {
99        Self {
100            number: 1,
101            signal_index: 0,
102            harmonic: 1,
103            hp_filter_order: 0,
104            hp_filter_cutoff_hz: 10.0,
105            lp_filter_order: 4,
106            lp_filter_cutoff_hz: 100.0,
107            phase_register: 1,
108            phase_deg: 0.0,
109            sync_filter: false,
110            rt_signal_mode: RTSignalMode::XY,
111        }
112    }
113}
114
115/// High-pass or low-pass filter configuration.
116#[derive(Debug, Clone, Copy)]
117pub struct FilterConfig {
118    /// Filter order (0 = off, 1-8 active)
119    pub order: i32,
120    /// Cutoff frequency in Hz
121    pub cutoff_hz: f32,
122}
123
124impl Default for FilterConfig {
125    fn default() -> Self {
126        Self {
127            order: 0,
128            cutoff_hz: 100.0,
129        }
130    }
131}