Source code for maddg._residuals

# Copyright (c) 2024 Massachusetts Institute of Technology
# SPDX-License-Identifier: MIT

import numpy as np
import pandas as pd
from astropy.time import Time

import madlib


[docs] def calculate_residuals( sensors: madlib.SensorCollection, satellite: madlib.Satellite, sim_duration_days: float, t_start_mjd: float = Time.now().mjd, ) -> pd.DataFrame | None: """Calculates the residuals. Parameters ---------- sensors : madlib.SensorCollection Collection of Sensors satellite : madlib.Satellite The Satellite object observed in the simulation sim_duration_days : float Duration of the simulation (days) t_start_mjd : float, optional Time (MJD) at the start of the simulation, by default astropy.time.Time.now().mjd Returns ------- pd.DataFrame | None pandas DataFrame of results (or None, if nobs == 0) Raises ------ MadlibException Raised if nobs != nexpected... number of actual and expected observations were not the same, so residuals cannot be calculated. This is likely a random occurrence. """ ### SIMULATION TIMING t_end_mjd = t_start_mjd + sim_duration_days sensors.generate_obs_timing(t_start_mjd, t_end_mjd) ### GENERATE OBSERVATIONS obs = sensors.observe(satellite) actual_obs = obs.pos_observed predicted_obs = obs.pos_expected nobs = obs.count_valid_observations() ### CALCULATE AND RETURN RESIDUALS output = None if nobs > 0: obs_res = np.array([actual_obs[n] - predicted_obs[n] for n in range(nobs)]) ra_res = np.array([obs_res[n].ra for n in range(nobs)]) * 3600 dec_res = np.array([obs_res[n].dec for n in range(nobs)]) * 3600 t = np.array([x.mjd for x in actual_obs]) sensor_ids = np.array([x.sensor_id for x in predicted_obs]) output = { "MJD": t, "RA Arcsec": ra_res, "DEC Arcsec": dec_res, "SensorID": sensor_ids, } output = pd.DataFrame(output) return output