celestial_pointing/commands/
fit.rs1use 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}