use std::collections::HashMap;
use ahash::RandomState;
use photom::TrajId;
#[cfg(feature = "parallel")]
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use crate::{
constants::FullOrbitResult,
ephemeris::{EphemerisOutputKind, EphemerisRequest, EphemerisResult},
JPLEphem, OutfitError,
};
use hifitime::ut1::Ut1Provider;
pub trait FullOrbitResultExt {
fn compute_ephemerides<O: EphemerisOutputKind>(
&self,
request: &EphemerisRequest<O>,
jpl: &JPLEphem,
ut1: &Ut1Provider,
) -> HashMap<TrajId, Result<EphemerisResult<O::Output>, OutfitError>, RandomState>;
#[cfg(feature = "parallel")]
fn compute_ephemerides_parallel<O>(
&self,
request: &EphemerisRequest<O>,
jpl: &JPLEphem,
ut1: &Ut1Provider,
) -> HashMap<TrajId, Result<EphemerisResult<O::Output>, OutfitError>, RandomState>
where
O: EphemerisOutputKind + Send + Sync,
O::Output: Send;
}
impl FullOrbitResultExt for FullOrbitResult {
fn compute_ephemerides<O: EphemerisOutputKind>(
&self,
request: &EphemerisRequest<O>,
jpl: &JPLEphem,
ut1: &Ut1Provider,
) -> HashMap<TrajId, Result<EphemerisResult<O::Output>, OutfitError>, RandomState> {
let mut map = HashMap::with_capacity_and_hasher(self.len(), RandomState::new());
for (traj_id, orbit_result) in self {
let entry = match orbit_result {
Ok(fit) => Ok(fit.orbital_elements().compute(request, jpl, ut1)),
Err(e) => Err(OutfitError::InvalidConversion(e.to_string())),
};
map.insert(traj_id.clone(), entry);
}
map
}
#[cfg(feature = "parallel")]
fn compute_ephemerides_parallel<O>(
&self,
request: &EphemerisRequest<O>,
jpl: &JPLEphem,
ut1: &Ut1Provider,
) -> HashMap<TrajId, Result<EphemerisResult<O::Output>, OutfitError>, RandomState>
where
O: EphemerisOutputKind + Send + Sync,
O::Output: Send,
{
let new_map = || HashMap::with_hasher(RandomState::new());
self.par_iter()
.map(|(traj_id, orbit_result)| {
let entry = match orbit_result {
Ok(fit) => Ok(fit.orbital_elements().compute(request, jpl, ut1)),
Err(e) => Err(OutfitError::InvalidConversion(e.to_string())),
};
(traj_id.clone(), entry)
})
.fold(new_map, |mut map, (k, v)| {
map.insert(k, v);
map
})
.reduce(new_map, |mut a, b| {
a.extend(b);
a
})
}
}