ruv_neural_core/
sensor.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum SensorType {
8 NvDiamond,
10 Opm,
12 Eeg,
14 SquidMeg,
16 AtomInterferometer,
18}
19
20impl SensorType {
21 pub fn typical_sensitivity_ft_sqrt_hz(&self) -> f64 {
23 match self {
24 SensorType::NvDiamond => 10.0,
25 SensorType::Opm => 7.0,
26 SensorType::Eeg => 1000.0,
27 SensorType::SquidMeg => 3.0,
28 SensorType::AtomInterferometer => 1.0,
29 }
30 }
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct SensorChannel {
36 pub id: usize,
38 pub sensor_type: SensorType,
40 pub position: [f64; 3],
42 pub orientation: [f64; 3],
44 pub sensitivity_ft_sqrt_hz: f64,
46 pub sample_rate_hz: f64,
48 pub label: String,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct SensorArray {
55 pub channels: Vec<SensorChannel>,
57 pub sensor_type: SensorType,
59 pub name: String,
61}
62
63impl SensorArray {
64 pub fn num_channels(&self) -> usize {
66 self.channels.len()
67 }
68
69 pub fn is_empty(&self) -> bool {
71 self.channels.is_empty()
72 }
73
74 pub fn get_channel(&self, index: usize) -> Option<&SensorChannel> {
76 self.channels.get(index)
77 }
78
79 pub fn bounding_box(&self) -> Option<([f64; 3], [f64; 3])> {
81 if self.channels.is_empty() {
82 return None;
83 }
84 let mut min = [f64::INFINITY; 3];
85 let mut max = [f64::NEG_INFINITY; 3];
86 for ch in &self.channels {
87 for i in 0..3 {
88 if ch.position[i] < min[i] {
89 min[i] = ch.position[i];
90 }
91 if ch.position[i] > max[i] {
92 max[i] = ch.position[i];
93 }
94 }
95 }
96 Some((min, max))
97 }
98}