Skip to main content

celestial_pointing/commands/
fit.rs

1use super::{Command, CommandOutput, FitDisplay};
2use crate::error::{Error, Result};
3use crate::session::Session;
4use crate::solver;
5
6pub struct Fit;
7
8impl Command for Fit {
9    fn name(&self) -> &str {
10        "FIT"
11    }
12    fn description(&self) -> &str {
13        "Fit model to observations"
14    }
15
16    fn execute(&self, session: &mut Session, _args: &[&str]) -> Result<CommandOutput> {
17        if session.model.term_count() == 0 {
18            return raw_rms(session);
19        }
20        let result = session.fit()?;
21        Ok(CommandOutput::FitDisplay(FitDisplay {
22            term_names: result.term_names.clone(),
23            coefficients: result.coefficients.clone(),
24            sigma: result.sigma.clone(),
25            sky_rms: result.sky_rms,
26        }))
27    }
28}
29
30fn raw_rms(session: &Session) -> Result<CommandOutput> {
31    let active: Vec<&_> = session.observations.iter().filter(|o| !o.masked).collect();
32    if active.is_empty() {
33        return Err(Error::Fit("no observations loaded".into()));
34    }
35    let residuals = solver::build_residuals(&active);
36    let rms = solver::compute_sky_rms(&residuals, &active);
37    Ok(CommandOutput::Text(format!("Raw sky RMS = {:.2}\"", rms)))
38}