pub(crate) mod aberration;
pub(crate) mod apparent_position;
pub mod batch;
pub(crate) mod geometry;
pub(crate) mod observation_ephemeris;
pub mod request;
pub mod result;
pub use aberration::AberrationOrder;
pub use apparent_position::ApparentPosition;
pub use batch::FullOrbitResultExt;
pub use geometry::BodyGeometry;
pub use request::{
Combined, EphemerisMode, EphemerisOutputKind, EphemerisRequest, Geometry, ObserverRequest,
Position,
};
pub use result::{EphemerisEntry, EphemerisResult};
use hifitime::ut1::Ut1Provider;
use crate::{
cache::observer_fixed_cache::ObserverFixedCache,
ephemeris::observation_ephemeris::check_elliptical_orbit, propagator::PropagatorKind,
EquinoctialElements, JPLEphem, OrbitalElements, OutfitError,
};
#[derive(Debug, Clone, Default)]
pub struct EphemerisConfig {
pub propagator: PropagatorKind,
pub aberration: AberrationOrder,
}
impl OrbitalElements {
pub fn compute<O: EphemerisOutputKind>(
&self,
request: &EphemerisRequest<O>,
jpl: &JPLEphem,
ut1: &Ut1Provider,
) -> EphemerisResult<O::Output> {
let equi = match self.to_equinoctial_for_ephemeris() {
Ok(e) => e,
Err(err) => {
let total: usize = request
.observers
.iter()
.map(|r| r.mode.epochs().len())
.sum();
let mut result = EphemerisResult::with_capacity(total);
for obs_req in &request.observers {
for epoch in obs_req.mode.epochs() {
result.push(
epoch,
obs_req.observer.clone(),
Err(OutfitError::InvalidConversion(err.to_string())),
);
}
}
return result;
}
};
if let Err(err) = check_elliptical_orbit(&equi) {
let total: usize = request
.observers
.iter()
.map(|r| r.mode.epochs().len())
.sum();
let mut result = EphemerisResult::with_capacity(total);
for obs_req in &request.observers {
for epoch in obs_req.mode.epochs() {
result.push(
epoch,
obs_req.observer.clone(),
Err(OutfitError::InvalidConversion(err.to_string())),
);
}
}
return result;
}
let total: usize = request
.observers
.iter()
.map(|r| r.mode.epochs().len())
.sum();
let mut result = EphemerisResult::with_capacity(total);
for obs_req in &request.observers {
let fixed_cache = match ObserverFixedCache::try_from(&obs_req.observer) {
Ok(c) => c,
Err(err) => {
for epoch in obs_req.mode.epochs() {
result.push(
epoch,
obs_req.observer.clone(),
Err(OutfitError::InvalidConversion(err.to_string())),
);
}
continue;
}
};
for epoch in obs_req.mode.epochs() {
let obs_time_mjd = epoch.to_mjd_tt_days();
let value = O::compute_one(
&equi,
obs_time_mjd,
&obs_req.observer,
&fixed_cache,
jpl,
ut1,
&request.config,
);
result.push(epoch, obs_req.observer.clone(), value);
}
}
result
}
fn to_equinoctial_for_ephemeris(&self) -> Result<EquinoctialElements, OutfitError> {
self.to_equinoctial()?
.as_equinoctial()
.ok_or(OutfitError::InvalidConversion(
"Conversion to equinoctial elements failed".to_string(),
))
}
}