oxihuman_export/
hemoglobin_map_export.rs1#![allow(dead_code)]
4
5pub struct HemoglobinMap {
6 pub width: u32,
7 pub height: u32,
8 pub oxy: Vec<f32>,
9 pub deoxy: Vec<f32>,
10}
11
12pub fn new_hemoglobin_map(w: u32, h: u32) -> HemoglobinMap {
13 let n = (w * h) as usize;
14 HemoglobinMap {
15 width: w,
16 height: h,
17 oxy: vec![0.0; n],
18 deoxy: vec![0.0; n],
19 }
20}
21
22fn idx(m: &HemoglobinMap, x: u32, y: u32) -> usize {
23 (y * m.width + x) as usize
24}
25
26pub fn hemo_map_set(m: &mut HemoglobinMap, x: u32, y: u32, oxy: f32, deoxy: f32) {
27 let i = idx(m, x, y);
28 m.oxy[i] = oxy;
29 m.deoxy[i] = deoxy;
30}
31
32pub fn hemo_map_get(m: &HemoglobinMap, x: u32, y: u32) -> (f32, f32) {
33 let i = idx(m, x, y);
34 (m.oxy[i], m.deoxy[i])
35}
36
37pub fn hemo_map_oxygen_saturation(m: &HemoglobinMap, x: u32, y: u32) -> f32 {
38 let (oxy, deoxy) = hemo_map_get(m, x, y);
39 let total = oxy + deoxy;
40 if total < 1e-8 {
41 0.0
42 } else {
43 oxy / total
44 }
45}
46
47pub fn hemo_map_to_bytes(m: &HemoglobinMap) -> Vec<u8> {
48 m.oxy
49 .iter()
50 .zip(m.deoxy.iter())
51 .flat_map(|(&oxy, &deoxy)| {
52 let o = (oxy.clamp(0.0, 1.0) * 255.0) as u8;
53 let d = (deoxy.clamp(0.0, 1.0) * 255.0) as u8;
54 [o, d, 0u8, 255u8]
55 })
56 .collect()
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_new_hemoglobin_map() {
65 let m = new_hemoglobin_map(4, 4);
67 assert_eq!(m.oxy.len(), 16);
68 }
69
70 #[test]
71 fn test_set_get() {
72 let mut m = new_hemoglobin_map(2, 2);
74 hemo_map_set(&mut m, 0, 0, 0.9, 0.1);
75 let (oxy, deoxy) = hemo_map_get(&m, 0, 0);
76 assert!((oxy - 0.9).abs() < 1e-6);
77 assert!((deoxy - 0.1).abs() < 1e-6);
78 }
79
80 #[test]
81 fn test_oxygen_saturation_half() {
82 let mut m = new_hemoglobin_map(2, 2);
84 hemo_map_set(&mut m, 0, 0, 0.5, 0.5);
85 assert!((hemo_map_oxygen_saturation(&m, 0, 0) - 0.5).abs() < 1e-6);
86 }
87
88 #[test]
89 fn test_oxygen_saturation_zero() {
90 let m = new_hemoglobin_map(2, 2);
92 assert!((hemo_map_oxygen_saturation(&m, 0, 0)).abs() < 1e-6);
93 }
94
95 #[test]
96 fn test_to_bytes_length() {
97 let m = new_hemoglobin_map(3, 3);
99 let bytes = hemo_map_to_bytes(&m);
100 assert_eq!(bytes.len(), 3 * 3 * 4);
101 }
102}