crseo/wavefrontsensor/segment_wise/phase_sensor/
phase_sensor.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
use std::ops::Mul;

use indicatif::ProgressBar;

use crate::{
    wavefrontsensor::{GeomShack, PistonSensor},
    FromBuilder, Propagation, SegmentWiseSensor, SourceBuilder,
};

use super::{
    data_processing::{Calibration, DataRef, Slopes, SlopesArray},
    PhaseSensorBuilder,
};

/// Wrapper to CEO geometric ShackHartmann
pub struct PhaseSensor {
    pub(super) geom_shack: GeomShack,
    pub(super) piston_sensor: PistonSensor,
}

impl FromBuilder for PhaseSensor {
    type ComponentBuilder = PhaseSensorBuilder;
}
impl Propagation for PhaseSensor {
    fn propagate(&mut self, src: &mut crate::Source) {
        self.geom_shack.propagate(src);
        self.piston_sensor.propagate(src);
    }

    fn time_propagate(&mut self, _secs: f64, _src: &mut crate::Source) {
        todo!()
    }
}

impl SegmentWiseSensor for PhaseSensor {
    fn pupil_sampling(&self) -> usize {
        self.geom_shack.pupil_sampling()
    }

    fn calibrate_segment(
        &mut self,
        _src: Option<SourceBuilder>,
        _sid: usize,
        _n_mode: usize,
        _pb: Option<ProgressBar>,
    ) -> SlopesArray {
        todo!()
    }

    fn zeroed_segment(&mut self, _sid: usize, _src: Option<SourceBuilder>) -> DataRef {
        todo!()
    }

    fn into_slopes(&self, _data_ref: &DataRef) -> Slopes {
        todo!()
    }
}

impl Mul<&PhaseSensor> for &Calibration {
    type Output = Option<Vec<f32>>;
    /// Multiplies the pseudo-inverse of the calibration matrix with the [PhaseSensor] measurements
    fn mul(self, wfs: &PhaseSensor) -> Self::Output {
        Some(
            self.iter()
                .take(self.len() / 2)
                .map(|c| (c * &wfs.piston_sensor).unwrap())
                .zip(
                    self.iter()
                        .skip(self.len() / 2)
                        .map(|c| (c * &wfs.geom_shack).unwrap()),
                )
                .flat_map(|(p, a)| p.into_iter().chain(a.into_iter()).collect::<Vec<f32>>())
                .collect(),
        )
    }
}