Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [Unreleased]

### Added

- Added a new numerical integrator based on Picard-Chebyshev integration. This
integrator has only been added to the rust backend at this point, until more
testing can be done and it be made available on the frontend.

### Changed

- Throughout the rust code, `Time` is being enforced as inputs for functions instead
of accepting `f64` in a large number of places.

### Fixed

- Fixed epoch times in PCK Type 2 frames that were not being converted correctly.


## [v2.1.5]

### Added
Expand Down
9 changes: 5 additions & 4 deletions src/kete/rust/covariance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use std::{collections::HashMap, fmt::Debug};

use crate::state::PyState;
use crate::time::PyTime;
use crate::{elements::PyCometElements, vector::VectorLike};
use kete_core::{errors::Error, io::FileIO};
use pyo3::prelude::*;
Expand Down Expand Up @@ -34,13 +35,13 @@ impl Covariance {
#[allow(clippy::too_many_arguments)]
pub fn new(
desig: String,
epoch: f64,
epoch: PyTime,
params: Vec<(String, f64)>,
cov_matrix: Vec<Vec<f64>>,
) -> Self {
Self {
desig,
epoch,
epoch: epoch.jd(),
params,
cov_matrix,
}
Expand Down Expand Up @@ -98,12 +99,12 @@ impl Covariance {
.ok_or(Error::ValueError("Covariance missing 'inclination'".into()))?;
let elem = PyCometElements::new(
desig,
epoch,
epoch.into(),
eccentricity,
inclination,
peri_dist,
peri_arg,
peri_time,
peri_time.into(),
lon_of_ascending,
);
elem.state()
Expand Down
22 changes: 11 additions & 11 deletions src/kete/rust/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use kete_core::frames::Ecliptic;
use kete_core::prelude;
use pyo3::{PyResult, pyclass, pymethods};

use crate::state::PyState;
use crate::{state::PyState, time::PyTime};

/// Cometary Elements class made accessible to python.
///
Expand Down Expand Up @@ -60,21 +60,21 @@ impl PyCometElements {
#[allow(clippy::too_many_arguments)]
pub fn new(
desig: String,
epoch: f64,
epoch: PyTime,
eccentricity: f64,
inclination: f64,
peri_dist: f64,
peri_arg: f64,
peri_time: f64,
peri_time: PyTime,
lon_of_ascending: f64,
) -> Self {
Self(elements::CometElements {
desig: prelude::Desig::Name(desig),
epoch,
epoch: epoch.into(),
eccentricity,
inclination: inclination.to_radians(),
lon_of_ascending: lon_of_ascending.to_radians(),
peri_time,
peri_time: peri_time.into(),
peri_arg: peri_arg.to_radians(),
peri_dist,
})
Expand All @@ -93,8 +93,8 @@ impl PyCometElements {

/// Epoch of the elements in JD.
#[getter]
pub fn epoch(&self) -> f64 {
self.0.epoch
pub fn epoch(&self) -> PyTime {
self.0.epoch.into()
}

/// Designation of the object.
Expand Down Expand Up @@ -128,8 +128,8 @@ impl PyCometElements {

/// Perihelion time of the orbit in JD.
#[getter]
pub fn peri_time(&self) -> f64 {
self.0.peri_time
pub fn peri_time(&self) -> PyTime {
self.0.peri_time.into()
}

/// Argument of Perihelion of the orbit in degrees.
Expand Down Expand Up @@ -196,11 +196,11 @@ impl PyCometElements {
format!(
"CometElements(desig={:?}, epoch={}, eccentricity={}, inclination={}, lon_of_ascending={}, peri_time={}, peri_arg={}, peri_dist={})",
self.desig(),
self.epoch(),
self.epoch().jd(),
self.eccentricity(),
self.inclination(),
self.lon_of_ascending(),
self.peri_time(),
self.peri_time().jd(),
self.peri_arg(),
self.peri_dist()
)
Expand Down
19 changes: 12 additions & 7 deletions src/kete/rust/fovs/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ pub fn fov_checks_py(
chunk.push(fov);
continue;
};
let jd_start = chunk.first().unwrap().observer().jd;
let jd_start = chunk.first().unwrap().observer().epoch;

// chunk is complete
if (fov.observer().jd - jd_start).abs() >= 2.0 * dt_limit {
if (fov.observer().epoch - jd_start).elapsed.abs() >= 2.0 * dt_limit {
fov_chunks.push(chunk);
chunk = vec![fov];
} else {
Expand All @@ -55,21 +55,24 @@ pub fn fov_checks_py(
if !chunk.is_empty() {
fov_chunks.push(chunk);
}
let mut jd = pop.jd;
let mut jd = pop.epoch.jd;
let mut big_jd = jd;
let mut states = pop.states;
let mut big_step_states = states.clone();
let mut visible = Vec::new();
for fovs in fov_chunks.into_iter() {
let jd_mean =
(fovs.last().unwrap().observer().jd + fovs.first().unwrap().observer().jd) / 2.0;
let jd_mean = (fovs.last().unwrap().observer().epoch.jd
+ fovs.first().unwrap().observer().epoch.jd)
/ 2.0;

// Take large steps which are 10x the smaller steps, this helps long term numerical stability
if (jd_mean - big_jd).abs() >= dt_limit * 50.0 {
big_jd = jd_mean;
big_step_states = big_step_states
.into_par_iter()
.filter_map(|state| propagate_n_body_spk(state, jd, include_asteroids, None).ok())
.filter_map(|state| {
propagate_n_body_spk(state, jd.into(), include_asteroids, None).ok()
})
.collect();
};
// Take small steps based off of the large steps.
Expand All @@ -80,7 +83,9 @@ pub fn fov_checks_py(
jd = jd_mean;
states = states
.into_par_iter()
.filter_map(|state| propagate_n_body_spk(state, jd, include_asteroids, None).ok())
.filter_map(|state| {
propagate_n_body_spk(state, jd.into(), include_asteroids, None).ok()
})
.collect();
};

Expand Down
4 changes: 2 additions & 2 deletions src/kete/rust/fovs/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl FOVListLike {
FOVListLike::Vec(v) => v,
FOVListLike::FOVList(list) => list.0,
};
fovs.sort_by(|a, b| a.jd().total_cmp(&b.jd()));
fovs.sort_by(|a, b| a.jd().jd.total_cmp(&b.jd().jd));
fovs.into_iter().map(|fov| fov.unwrap()).collect()
}
}
Expand All @@ -45,7 +45,7 @@ impl FOVList {

/// Sort the list of FOVs by their JD.
pub fn sort(&mut self) {
self.0.sort_by(|a, b| a.jd().total_cmp(&b.jd()))
self.0.sort_by(|a, b| a.jd().jd.total_cmp(&b.jd().jd))
}

fn __len__(&self) -> usize {
Expand Down
76 changes: 39 additions & 37 deletions src/kete/rust/fovs/definitions.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use kete_core::fov::{self};
use kete_core::fov::{FovLike, SkyPatch};
use kete_core::frames::Vector;
use kete_core::time::{TDB, Time};
use pyo3::{exceptions, prelude::*};

use crate::time::PyTime;
use crate::vector::VectorLike;
use crate::{state::PyState, vector::PyVector};

Expand Down Expand Up @@ -256,20 +258,20 @@ pub enum AllowedFOV {

impl AllowedFOV {
#[allow(missing_docs)]
pub fn jd(&self) -> f64 {
pub fn jd(&self) -> Time<TDB> {
match self {
AllowedFOV::NEOS(fov) => fov.0.observer().jd,
AllowedFOV::WISE(fov) => fov.0.observer().jd,
AllowedFOV::Rectangle(fov) => fov.0.observer().jd,
AllowedFOV::ZTF(fov) => fov.0.observer().jd,
AllowedFOV::ZTFField(fov) => fov.0.observer().jd,
AllowedFOV::NEOSVisit(fov) => fov.0.observer().jd,
AllowedFOV::Cone(fov) => fov.0.observer().jd,
AllowedFOV::OmniDirectional(fov) => fov.0.observer().jd,
AllowedFOV::PTF(fov) => fov.0.observer().jd,
AllowedFOV::PTFField(fov) => fov.0.observer().jd,
AllowedFOV::SPHEREx(fov) => fov.0.observer().jd,
AllowedFOV::SPHERExField(fov) => fov.0.observer().jd,
AllowedFOV::NEOS(fov) => fov.0.observer().epoch,
AllowedFOV::WISE(fov) => fov.0.observer().epoch,
AllowedFOV::Rectangle(fov) => fov.0.observer().epoch,
AllowedFOV::ZTF(fov) => fov.0.observer().epoch,
AllowedFOV::ZTFField(fov) => fov.0.observer().epoch,
AllowedFOV::NEOSVisit(fov) => fov.0.observer().epoch,
AllowedFOV::Cone(fov) => fov.0.observer().epoch,
AllowedFOV::OmniDirectional(fov) => fov.0.observer().epoch,
AllowedFOV::PTF(fov) => fov.0.observer().epoch,
AllowedFOV::PTFField(fov) => fov.0.observer().epoch,
AllowedFOV::SPHEREx(fov) => fov.0.observer().epoch,
AllowedFOV::SPHERExField(fov) => fov.0.observer().epoch,
}
}

Expand Down Expand Up @@ -396,8 +398,8 @@ impl PyWiseCmos {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Direction that the observer is looking.
Expand Down Expand Up @@ -494,8 +496,8 @@ impl PyGenericRectangle {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Direction that the observer is looking.
Expand Down Expand Up @@ -560,8 +562,8 @@ impl PyGenericCone {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Direction that the observer is looking.
Expand Down Expand Up @@ -602,8 +604,8 @@ impl PyOmniDirectional {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

fn __repr__(&self) -> String {
Expand Down Expand Up @@ -653,8 +655,8 @@ impl PyNeosCmos {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Direction that the observer is looking.
Expand Down Expand Up @@ -798,8 +800,8 @@ impl PyNeosVisit {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -946,8 +948,8 @@ impl PyZtfCcdQuad {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -1053,8 +1055,8 @@ impl PyZtfField {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -1184,8 +1186,8 @@ impl PyPtfCcd {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -1279,8 +1281,8 @@ impl PyPtfField {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -1376,8 +1378,8 @@ impl PySpherexCmos {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down Expand Up @@ -1454,8 +1456,8 @@ impl PySpherexField {

/// JD of the observer location.
#[getter]
pub fn jd(&self) -> f64 {
self.0.observer().jd
pub fn jd(&self) -> PyTime {
self.0.observer().epoch.into()
}

/// Metadata about where this FOV is in the Survey.
Expand Down
2 changes: 1 addition & 1 deletion src/kete/rust/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ pub fn calc_obliquity_py(time: f64) -> f64 {
/// Time in TDB scaled Julian Days.
#[pyfunction]
#[pyo3(name = "earth_precession_rotation")]
pub fn calc_earth_precession(time: f64) -> Vec<Vec<f64>> {
pub fn calc_earth_precession(time: PyTime) -> Vec<Vec<f64>> {
earth_precession_rotation(time.into())
.rotations_to_equatorial()
.unwrap()
Expand Down
Loading