Skip to content

Commit

Permalink
Remove SpiceKernels class, changing methods to functions (#69)
Browse files Browse the repository at this point in the history
Remove SpiceKernels class, changing meths to funcs

See #68 for more details
  • Loading branch information
dahlend authored Jul 5, 2024
1 parent aec7ef4 commit 8b8a0db
Show file tree
Hide file tree
Showing 24 changed files with 403 additions and 394 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Removed `SpiceKernel` as a class, lowering all its methods to the submodule level,
see #68 for more discussion.
- Removed `Time` object which was a wrapper over astropy.Time, instead making a
custom implementation of time which is ~3-400x faster than previous.
- Improved orbital element conversion, leading to a 2-3x speedup in two body orbit
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/kona.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ calculated from the corners of the frame.
frame = fits.open("data/01772a127-w3-int-1b.fits.gz")[0]
# Here we compute a State of the observer, this could also be constructed
# using spice kernels using neospy.SpiceKernels.state
# using spice kernels using neospy.spice.state
sc_pos = neospy.Vector([frame.header['SUN2SCX'],
frame.header['SUN2SCY'],
frame.header['SUN2SCZ']],
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorials/propagation_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import matplotlib.pyplot as plt
import neospy

neospy.SpiceKernels.kernel_reload(["./data/20000042.bsp"])
neospy.spice.kernel_reload(["./data/20000042.bsp"])

jd_start = neospy.Time.from_ymd(1920, 1, 1).jd
jd_end = neospy.Time.from_ymd(2020, 1, 1).jd

state = neospy.SpiceKernels.state("42", jd_end)
state = neospy.spice.state("42", jd_end)

jds = np.logspace(np.log10(jd_end), np.log10(jd_end - 10), 1000)
jds = np.concatenate(
Expand All @@ -21,9 +21,9 @@
error_2body = []
n_body_no_asteroids = []
n_body_ast = []
state = neospy.SpiceKernels.state("42", jd_end)
state = neospy.spice.state("42", jd_end)
for jd in jds:
jpl_pos = neospy.SpiceKernels.state("42", jd).pos
jpl_pos = neospy.spice.state("42", jd).pos

line = state.pos + state.vel * (jd - state.jd)
error_line.append((jpl_pos - line).r * neospy.constants.AU_KM)
Expand Down
2 changes: 1 addition & 1 deletion src/examples/galactic_center.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
while states[0].jd < jd_end:
states = neospy.propagate_two_body(states, states[0].jd + 1)

earth = neospy.SpiceKernels.state("Earth", states[0].jd)
earth = neospy.spice.state("Earth", states[0].jd)

earth_to_obj = [(s.pos - earth.pos) for s in states]
dist_to_galactic_center.append(
Expand Down
2 changes: 1 addition & 1 deletion src/examples/on_sky.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
print(obs_info)

# Load the position of the observer in the solar system:
observer = neospy.SpiceKernels.mpc_code_to_ecliptic("Palomar Mountain", jd)
observer = neospy.spice.mpc_code_to_ecliptic("Palomar Mountain", jd)


# %% Propagation and Orbit calculations
Expand Down
2 changes: 1 addition & 1 deletion src/examples/plot_close_approach.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
rel_earth_state = cur_state.change_center(399)
pos.append([rel_earth_state.pos.x, rel_earth_state.pos.y])
# gets earths position and record the distances.
moon = neospy.SpiceKernels.state("Moon", cur_state.jd, center=399).pos
moon = neospy.spice.state("Moon", cur_state.jd, center=399).pos
dist_to_moon.append((moon - rel_earth_state.pos).r * neospy.constants.AU_KM)
dist_to_earth.append(rel_earth_state.pos.r * neospy.constants.AU_KM)
moon_pos.append([moon.x, moon.y])
Expand Down
7 changes: 3 additions & 4 deletions src/examples/plot_close_encounter.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
# Sample the time from start to end in 1 day steps
jds = np.arange(jd_start, jd_end)

eph = neospy.SpiceKernels()

# Propagate the object to all of the state
obj_pos = []
Expand All @@ -39,7 +38,7 @@
for jd in jds:
last_state = neospy.propagate_two_body([last_state], jd)[0]
obj_pos.append(last_state.pos)
earth_pos.append(eph.state("Earth", jd).pos)
earth_pos.append(neospy.spice.state("Earth", jd).pos)
earth_r.append(neospy.Vector(obj_pos[-1] - earth_pos[-1]).r)

# Find the time where the closest encounter with the earth
Expand All @@ -56,10 +55,10 @@
ax.plot(pos[0], pos[1], pos[2], alpha=0.5, color="black")
ax.scatter(pos_center.x, pos_center.y, pos_center.z, s=5, color="black")
for i, planet in enumerate(["Mercury", "Venus", "Earth", "Mars", "Jupiter"]):
states = [eph.state(planet, jd).pos for jd in jds]
states = [neospy.spice.state(planet, jd).pos for jd in jds]
pos = np.array(states).T
ax.plot(pos[0], pos[1], pos[2], color=f"C{i}", alpha=0.5)
pos = eph.state(planet, jd_center).pos
pos = neospy.spice.state(planet, jd_center).pos
ax.scatter(pos.x, pos.y, pos.z, color=f"C{i}", s=5)
ax.scatter(0, 0, 0, color="red")
ax.set_xticks([-zoom, 0, zoom])
Expand Down
6 changes: 2 additions & 4 deletions src/examples/plot_elevation.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,8 @@
# for each time step, calculate the elevation and sun elevation
jd_step = jd_start + subrange
approx_state = neospy.propagate_two_body(states, jd_step)
sun2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(site, jd_step).pos
earth2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(
site, jd_step, center="399"
).pos
sun2obs = neospy.spice.mpc_code_to_ecliptic(site, jd_step).pos
earth2obs = neospy.spice.mpc_code_to_ecliptic(site, jd_step, center="399").pos
sun_elevation.append(90 - earth2obs.angle_between(-sun2obs))

cur_elev = []
Expand Down
4 changes: 2 additions & 2 deletions src/examples/plot_light_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@


# Using ceres as a source for a state vector
state = neospy.SpiceKernels.state("ceres", 2460000.5)
state = neospy.spice.state("ceres", 2460000.5)

# Various input values
albedo = 0.1
Expand Down Expand Up @@ -39,7 +39,7 @@

for dt in dts:
# Find the observer and object positions some time in the future.
earth_pos = neospy.SpiceKernels.state("Earth", jd + dt).pos
earth_pos = neospy.spice.state("Earth", jd + dt).pos
final_pos = neospy.propagate_two_body([state], jd + dt, earth_pos)[0].pos

obj2obs = final_pos - earth_pos
Expand Down
4 changes: 2 additions & 2 deletions src/examples/plot_mpc_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@
# Plot the planets for 1 orbit each
for i, planet in enumerate(["Mercury", "Venus", "Earth", "Mars", "Jupiter"]):
jd = states[0].jd
plan = neospy.SpiceKernels().state(planet, jd)
plan = neospy.spice.state(planet, jd)
ax.scatter(plan.pos.x, plan.pos.y, color=f"C{i}", s=10)
jds = np.linspace(jd - plan.elements.orbital_period, jd, 100)
pos = np.array([neospy.SpiceKernels().state(planet, jd).pos for jd in jds]).T
pos = np.array([neospy.spice.state(planet, jd).pos for jd in jds]).T
ax.plot(pos[0], pos[1], pos[2], color="black", alpha=0.2)

for state in states:
Expand Down
8 changes: 4 additions & 4 deletions src/examples/plot_observability.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
# For each time, compute the geometry, then compute the mag as well as all of the
# various angle and distance values.
state = neospy.propagate_n_body([state], t)[0]
sun2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(site, t).pos
earth2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(site, t, center="399").pos
sun2obs = neospy.spice.mpc_code_to_ecliptic(site, t).pos
earth2obs = neospy.spice.mpc_code_to_ecliptic(site, t, center="399").pos

sun2obj = state.pos
obs2obj = -sun2obs + sun2obj
Expand Down Expand Up @@ -130,8 +130,8 @@
nights = []
for subrange in substeps:
approx_state = neospy.propagate_two_body([state], t + subrange)[0]
sun2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(site, t + subrange).pos
earth2obs = neospy.SpiceKernels.mpc_code_to_ecliptic(
sun2obs = neospy.spice.mpc_code_to_ecliptic(site, t + subrange).pos
earth2obs = neospy.spice.mpc_code_to_ecliptic(
site, t + subrange, center="399"
).pos

Expand Down
2 changes: 1 addition & 1 deletion src/examples/plot_phases.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# Move the entire population of asteroids to that time using 2-body
# mechanics, this can be directly substituted with propagate_n_body if you
# want more precision.
sun2earth = neospy.SpiceKernels.state("Earth", jd).pos
sun2earth = neospy.spice.state("Earth", jd).pos
states = neospy.propagate_two_body(neos, jd)

# Compute the expected V-mags for these objects at this time
Expand Down
2 changes: 1 addition & 1 deletion src/examples/plot_trojans.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
states = neospy.propagate_n_body(states, states[0].jd)

# Where is jupiter?
jupiter = neospy.SpiceKernels.state("Jupiter", states[0].jd)
jupiter = neospy.spice.state("Jupiter", states[0].jd)
# found it!

# Compute the positions, and relative longitudinal distance from jupiter
Expand Down
4 changes: 2 additions & 2 deletions src/examples/plot_uncertainty.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
mags = []
for jd in jds:
states = neospy.propagate_n_body(states, jd)
earth = neospy.SpiceKernels.state("earth", jd)
earth = neospy.spice.state("earth", jd)
m = [
neospy.flux.hg_apparent_mag(
sun2obj=x.pos, sun2obs=earth.pos, h_mag=obj.h_mag, g_param=g
Expand All @@ -65,7 +65,7 @@

# position at lowest mag
states = neospy.propagate_n_body(states, brightest_jd)
earth = neospy.SpiceKernels.state("earth", brightest_jd)
earth = neospy.spice.state("earth", brightest_jd)
vecs = [(s.pos - earth.pos).as_equatorial for s in states]
ras = np.array([v.ra for v in vecs])
decs = np.array([v.dec for v in vecs])
Expand Down
4 changes: 2 additions & 2 deletions src/neospy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
ztf,
fov,
shape,
spice,
)
from .spice import SpiceKernels
from .propagation import (
propagate_n_body,
propagate_two_body,
Expand Down Expand Up @@ -64,12 +64,12 @@
"population",
"Time",
"set_logging",
"SpiceKernels",
"flux",
"fov",
"wise",
"neos",
"mpc",
"spice",
"SimultaneousStates",
"propagate_n_body",
"propagate_two_body",
Expand Down
4 changes: 2 additions & 2 deletions src/neospy/fov.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
fov_spk_check as _fov_spk_check,
)
from .vector import State
from .spice import SpiceKernels
from . import spice


__all__ = [
Expand Down Expand Up @@ -49,5 +49,5 @@ def fov_spice_check(desigs: list[str], fovs) -> list[State]:
fov:
A list of field of views from which to subselect objects which are visible.
"""
obj_ids = [SpiceKernels.name_lookup(n)[1] for n in desigs]
obj_ids = [spice.name_lookup(n)[1] for n in desigs]
return _fov_spk_check(obj_ids, fovs)
4 changes: 2 additions & 2 deletions src/neospy/mpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ def _read_first_line(line):

@staticmethod
def _read_second_line(line, jd):
from .spice import SpiceKernels
from . import spice

if line[14] != "s":
raise ValueError("No second line of spacecraft observation found.")
Expand All @@ -929,7 +929,7 @@ def _read_second_line(line, jd):
y = float(line[46:57].replace(" ", "")) / constants.AU_KM
z = float(line[58:69].replace(" ", "")) / constants.AU_KM
earth2sc = Vector([x, y, z], Frames.Equatorial).as_ecliptic
sun2earth = SpiceKernels.state("Earth", jd).pos
sun2earth = spice.state("Earth", jd).pos
sun2sc = sun2earth + earth2sc
return list(sun2sc)

Expand Down
11 changes: 5 additions & 6 deletions src/neospy/propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
from scipy import optimize
import numpy as np

from .spice import SpiceKernels
from .vector import Vector, State
from . import _core
from . import _core, spice
from ._core import NonGravModel


Expand Down Expand Up @@ -133,10 +132,10 @@ def moid(state: State, other: Optional[State] = None):
state:
The state describing an object.
other:
The state of the object to calculate the MOID for, if this is not provided, then
Earth is fetched from :class:`~neospy.spice.SpiceKernels` and is used in
the calculation.
The state of the object to calculate the MOID for, if this is not provided,
then Earth is fetched from :mod:`~neospy.spice` and is used in the
calculation.
"""
if other is None:
other = SpiceKernels.state("Earth", state.jd)
other = spice.state("Earth", state.jd)
return _moid_single(state, other)
24 changes: 18 additions & 6 deletions src/neospy/rust/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,6 @@ impl PyTime {
PyTime(Time::<UTC>::from_year_month_day(year, month, day, frac_day).tdb())
}

/// Time in the UTC ISO time format.
#[getter]
pub fn iso(&self) -> PyResult<String> {
Ok(self.0.utc().to_iso()?)
}

/// Time in the current time.
#[staticmethod]
pub fn now() -> Self {
Expand Down Expand Up @@ -139,6 +133,24 @@ impl PyTime {
self.0.mjd()
}

/// Julian Date in UTC scaled time.
#[getter]
pub fn utc_jd(&self) -> f64 {
self.0.utc().jd
}

/// Modified Julian Date in UTC scaled time.
#[getter]
pub fn utc_mjd(&self) -> f64 {
self.0.utc().jd
}

/// Time in the UTC ISO time format.
#[getter]
pub fn iso(&self) -> PyResult<String> {
Ok(self.0.utc().to_iso()?)
}

#[staticmethod]
pub fn j2000() -> Self {
PyTime(Time::<TDB>::new(2451545.0))
Expand Down
Loading

0 comments on commit 8b8a0db

Please sign in to comment.