Skip to content

Commit

Permalink
Merge pull request #110 from pysat/tst/64_projections
Browse files Browse the repository at this point in the history
TST/DEP: update tests for spacecraft projections, deprecate `calculate_ecef_velocity`
  • Loading branch information
jklenzing committed Mar 1, 2023
2 parents d6723e3 + 62ffc91 commit 739d0ec
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ This project adheres to [Semantic Versioning](https://semver.org/).
* Remove optional dependencies in readthedocs requirements
* Add tests for NEP 29 testing
* Add tests for Mac OS
* Deprecate `calculate_ecef_velocity` method
* Testing
* Include checks on sc coordinate transformation calculations

## [0.3.3] - 2022-09-06
* Documentation Updates
Expand Down
11 changes: 11 additions & 0 deletions pysatMissions/methods/spacecraft.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Default routines for projecting values onto vectors for pysat instruments."""

import numpy as np
import warnings


def add_ram_pointing_sc_attitude_vectors(inst):
Expand Down Expand Up @@ -92,6 +93,11 @@ def add_ram_pointing_sc_attitude_vectors(inst):
def calculate_ecef_velocity(inst):
"""Calculate spacecraft velocity in ECEF frame.
.. deprecated:: 0.4.0
This function is no longer needed with the deprecation of `missions_ephem`.
Better calculations are available through geospacepy and skyfield.
`calculate_ecef_velocity` will be removed in versions 0.5.0+
Presumes that the spacecraft velocity in ECEF is in
the input instrument object as position_ecef_*. Uses a symmetric
difference to calculate the velocity thus endpoints will be
Expand All @@ -111,6 +117,11 @@ def calculate_ecef_velocity(inst):
"""

warnings.warn(' '.join(("`calculate_ecef_velocity` has been deprecated and",
"will be removed in pysatMissions 0.5.0+.",
"Use `geospacepy` or `skyfield` instead.")),
DeprecationWarning, stacklevel=2)

def get_vel_from_pos(x):
vel = (x.values[2:] - x.values[0:-2]) / 2.
return vel
Expand Down
84 changes: 61 additions & 23 deletions pysatMissions/tests/test_methods_spacecraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import datetime as dt
import numpy as np
import warnings

import pysat
from pysatMissions.methods import spacecraft as mm_sc
Expand All @@ -11,24 +12,29 @@
def add_ecef(inst):
"""Add ECEF position to pysat_testing instrument."""

inst['position_ecef_x'] = [-6197.135721, -6197.066687, -6196.990263,
-6196.906991, -6196.816336, -6196.718347,
-6196.613474, -6196.501303, -6196.382257]
inst['position_ecef_y'] = [-2169.334337, -2174.014920, -2178.693373,
-2183.368212, -2188.040895, -2192.711426,
-2197.378290, -2202.042988, -2206.703992]
inst['position_ecef_z'] = [1716.528241, 1710.870004, 1705.209738,
1699.547245, 1693.882731, 1688.216005,
1682.547257, 1676.876312, 1671.203352]
# Maintain each as unit vector to simplify checks.
inst['position_ecef_x'] = [0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
inst['position_ecef_y'] = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0]
inst['position_ecef_z'] = [0.0, 1.0, 1.0, 0.0, 0.0, 0.0]
return


def add_ecef_vel(inst):
"""Add ECEF velocity to pysat_testing instrument."""

# Maintain each as unit vector to simplify checks.
inst['velocity_ecef_x'] = [1.0, 1.0, 0.0, 0.0, 0.0, 0.0]
inst['velocity_ecef_y'] = [0.0, 0.0, 1.0, 1.0, 0.0, 0.0]
inst['velocity_ecef_z'] = [0.0, 0.0, 0.0, 0.0, 1.0, 1.0]
return


def add_fake_data(inst):
"""Add an arbitrary vector to a pysat_testing instrument."""

inst['ax'] = np.ones(9)
inst['ay'] = np.zeros(9)
inst['az'] = np.zeros(9)
inst['ax'] = np.ones(6)
inst['ay'] = np.zeros(6)
inst['az'] = np.zeros(6)
return


Expand All @@ -39,7 +45,7 @@ def setup_method(self):
"""Create a clean testing setup before each method."""

self.testInst = pysat.Instrument(platform='pysat', name='testing',
num_samples=9, clean_level='clean',
num_samples=6, clean_level='clean',
use_header=True)
self.testInst.custom_attach(add_ecef)
self.reftime = dt.datetime(2009, 1, 1)
Expand Down Expand Up @@ -73,29 +79,61 @@ def test_calculate_ecef_velocity(self):
self.eval_targets(targets)
return

def test_calculate_ecef_velocity_deprecation(self):
"""Test `calculate_ecef_velocity` helper function."""

self.testInst.custom_attach(mm_sc.calculate_ecef_velocity)
warnings.simplefilter("always", DeprecationWarning)
with warnings.catch_warnings(record=True) as war:
self.testInst.load(date=self.reftime)
warn_msgs = ["`calculate_ecef_velocity` has been deprecated"]

pysat.utils.testing.eval_warnings(war, warn_msgs)
return

def test_add_ram_pointing_sc_attitude_vectors(self):
"""Test `add_ram_pointing_sc_attitude_vectors` helper function."""

# TODO(#64): check if calculations are correct
self.testInst.custom_attach(mm_sc.calculate_ecef_velocity)
self.testInst.custom_attach(add_ecef_vel)
self.testInst.custom_attach(mm_sc.add_ram_pointing_sc_attitude_vectors)
self.testInst.load(date=self.reftime)
targets = ['sc_xhat_ecef_x', 'sc_xhat_ecef_y', 'sc_xhat_ecef_z',
'sc_yhat_ecef_x', 'sc_yhat_ecef_y', 'sc_yhat_ecef_z',
'sc_zhat_ecef_x', 'sc_zhat_ecef_y', 'sc_zhat_ecef_z']
self.eval_targets(targets)

# Xhat vector should match velocity
assert np.all(self.testInst['sc_xhat_ecef_x']
== self.testInst['velocity_ecef_x'])
assert np.all(self.testInst['sc_xhat_ecef_y']
== self.testInst['velocity_ecef_y'])
assert np.all(self.testInst['sc_xhat_ecef_z']
== self.testInst['velocity_ecef_z'])

# Zhat vector should match - position
assert np.all(self.testInst['sc_zhat_ecef_x']
== -self.testInst['position_ecef_x'])
assert np.all(self.testInst['sc_zhat_ecef_y']
== -self.testInst['position_ecef_y'])
assert np.all(self.testInst['sc_zhat_ecef_z']
== -self.testInst['position_ecef_z'])

# Yhat vector should be orthogonal
assert np.all(self.testInst['sc_yhat_ecef_x']
== [0.0, 0.0, 1.0, 0.0, 0.0, -1.0])
assert np.all(self.testInst['sc_yhat_ecef_y']
== [0.0, -1.0, 0.0, 0.0, 1.0, 0.0])
assert np.all(self.testInst['sc_yhat_ecef_z']
== [1.0, 0.0, 0.0, -1.0, 0.0, 0.0])
return

def test_project_ecef_vector_onto_sc(self):
"""Test `project_ecef_vector_onto_sc` helper function."""

# TODO(#64): check if calculations are correct
self.testInst.custom_attach(mm_sc.calculate_ecef_velocity)
self.testInst.custom_attach(add_ecef_vel)
self.testInst.custom_attach(mm_sc.add_ram_pointing_sc_attitude_vectors)
self.testInst.custom_attach(add_fake_data)
self.testInst.custom_attach(mm_sc.project_ecef_vector_onto_sc,
args=['ax', 'ay', 'az', 'bx', 'by', 'bz'])
self.testInst.load(date=self.reftime)
targets = ['bx', 'by', 'bz']
self.eval_targets(targets)

assert np.all(self.testInst['bx'] == [1.0, 1.0, 0.0, 0.0, 0.0, 0.0])
assert np.all(self.testInst['by'] == [0.0, 0.0, 1.0, 0.0, 0.0, -1.0])
assert np.all(self.testInst['bz'] == [0.0, 0.0, 0.0, -1.0, -1.0, 0.0])
return

0 comments on commit 739d0ec

Please sign in to comment.