From e8038a485c79289972853942f92b03ae5aad62d4 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 10:36:32 -0400 Subject: [PATCH 01/34] TST: add windows tests --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca6a3976..14cae109 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: python-version: ["3.8", "3.9", "3.10"] - os: [ubuntu-latest] + os: ["ubuntu-latest", "windows-latest"] numpy_ver: ["latest"] name: Python ${{ matrix.python-version }} on ${{ matrix.os }} with numpy ${{ matrix.numpy_ver }} @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: | pip install -r requirements.txt - pip install OMMBV + pip install OMMBV --no-binary==OMMBV - name: Set up pysat run: | From d63377f65b7761fa06925b944bacab24afd48604 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 10:42:50 -0400 Subject: [PATCH 02/34] BUG: manual apexpy install --- .github/workflows/main.yml | 1 + requirements.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 14cae109..1c01f253 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,6 +33,7 @@ jobs: run: | pip install -r requirements.txt pip install OMMBV --no-binary==OMMBV + pip install apexpy --no-binary==apexpy - name: Set up pysat run: | diff --git a/requirements.txt b/requirements.txt index e25989b9..d15054aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ aacgmv2 -apexpy geospacepy numpy pandas From 5d66a016dc97dff7143fcd2ae785c8834e542bb0 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 11:34:43 -0400 Subject: [PATCH 03/34] STY: generalize package_check --- pysatMissions/__init__.py | 3 +- pysatMissions/methods/spacecraft.py | 36 ++++++--------------- pysatMissions/tests/test_utils.py | 50 +++++++++++++++++++++++++++++ pysatMissions/utils/__init__.py | 3 ++ pysatMissions/utils/_core.py | 33 +++++++++++++++++++ 5 files changed, 97 insertions(+), 28 deletions(-) create mode 100644 pysatMissions/tests/test_utils.py create mode 100644 pysatMissions/utils/__init__.py create mode 100644 pysatMissions/utils/_core.py diff --git a/pysatMissions/__init__.py b/pysatMissions/__init__.py index e2de92fd..b3628611 100644 --- a/pysatMissions/__init__.py +++ b/pysatMissions/__init__.py @@ -18,10 +18,11 @@ try: from pysatMissions import instruments from pysatMissions import methods + from pysatMissions import utils except ImportError as errstr: logging.exception('problem importing pysatMissions: ' + str(errstr)) -__all__ = ['instruments', 'methods'] +__all__ = ['instruments', 'methods', 'utils'] # set version here = os.path.abspath(os.path.dirname(__file__)) diff --git a/pysatMissions/methods/spacecraft.py b/pysatMissions/methods/spacecraft.py index 41c29863..f51d79f8 100644 --- a/pysatMissions/methods/spacecraft.py +++ b/pysatMissions/methods/spacecraft.py @@ -1,40 +1,22 @@ """Default routines for projecting values onto vectors for pysat instruments.""" import numpy as np -import warnings + +import pysat +from pysatMissions.utils import package_check try: import OMMBV -except ImportError: +except ImportError as ierr: + pysat.logger.warning(" ".join(["OMMBV module could not be imported.", + "OMMBV interface won't work.", + "Failed with error:", str(ierr)])) # Warnings thrown elsewhere if users call relevant functions without # ommbv installed pass -def ommbv_check(func): - """Throw a warning if OMMBV is not installed. - - Some systems are having issues installing OMMBV. This allows OMMBV to be - optionally installed. - - """ - - def wrapper(): - """Wrap functions that use the decorator function.""" - - ommbv_warning = ' '.join(['OMMBV must be installed to use this', - 'function. See instructions at', - 'https://github.com/pysat/pysatMissions']) - try: - func() - except NameError: - # Triggered if OMMBV is not installed - warnings.warn(ommbv_warning, stacklevel=2) - - return wrapper - - -@ommbv_check +@package_check('OMMBV') def add_ram_pointing_sc_attitude_vectors(inst): """Add attitude vectors for spacecraft assuming ram pointing. @@ -175,7 +157,7 @@ def get_vel_from_pos(x): return -@ommbv_check +@package_check('OMMBV') def project_ecef_vector_onto_sc(inst, x_label, y_label, z_label, new_x_label, new_y_label, new_z_label, meta=None): diff --git a/pysatMissions/tests/test_utils.py b/pysatMissions/tests/test_utils.py new file mode 100644 index 00000000..9d080694 --- /dev/null +++ b/pysatMissions/tests/test_utils.py @@ -0,0 +1,50 @@ +"""Unit tests for pysatMissions utilitis.""" + +import warnings + +import pytest + +from pysatMissions.utils import package_check + + +class TestBasics(object): + """Basic test for package utilities.""" + + def setup(self): + """Create a clean testing setup before each method.""" + + warnings.simplefilter("always") + return + + def teardown(self): + """Clean up test environment after tests.""" + + return + + @pytest.mark.parametrize("package_name, num_warns", + [('os', 0), + ('nonsense', 1)]) + def test_package_check(self, package_name, num_warns): + """Test that package_check warns users if packages are not installed. + + Parameters + ---------- + package_name : str + Name of package to check for. + num_warns : int + Expected number of warnings to be generated. + """ + + @package_check(package_name) + def dummy_func(): + """Pass through so that wrapper can be checked.""" + pass + + with warnings.catch_warnings(record=True) as war: + dummy_func() + + assert len(war) == num_warns + if len(war) > 0: + assert package_name in str(war[0]) + + return diff --git a/pysatMissions/utils/__init__.py b/pysatMissions/utils/__init__.py new file mode 100644 index 00000000..1827258c --- /dev/null +++ b/pysatMissions/utils/__init__.py @@ -0,0 +1,3 @@ +"""Methods for pysatCDAAC instruments.""" + +from pysatMissions.utils._core import package_check # noqa F401 diff --git a/pysatMissions/utils/_core.py b/pysatMissions/utils/_core.py new file mode 100644 index 00000000..59464a42 --- /dev/null +++ b/pysatMissions/utils/_core.py @@ -0,0 +1,33 @@ +"""Utilities for pysatMissions.""" + +from importlib import import_module +import warnings + + +def package_check(package_name): + """Throw a warning if package is not installed. + + Some systems are having issues installing OMMBV and apexpy. + This allows these packages to be optionally installed. + + """ + + def decorator(func): + """Pass the function through to the wrapper.""" + + def wrapper(*args, **kwargs): + """Wrap functions that use the decorator function.""" + + message_warn = ' '.join(['{:} must be installed'.format(package_name), + 'to use {:}.'.format(func.__name__), + 'See instructions at', + 'https://github.com/pysat/pysatMissions']) + try: + import_module(package_name) + except ModuleNotFoundError: + # Triggered if package is not installed + warnings.warn(message_warn, stacklevel=2) + + return wrapper + + return decorator From ef5204b0fd9d0a366488d7667687e3ff63bd5f3b Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 11:58:33 -0400 Subject: [PATCH 04/34] STY: skip tests if apexpy not installed --- pysatMissions/methods/magcoord.py | 2 ++ pysatMissions/tests/test_methods_magcoord.py | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pysatMissions/methods/magcoord.py b/pysatMissions/methods/magcoord.py index 94b7f968..eccd14e4 100644 --- a/pysatMissions/methods/magcoord.py +++ b/pysatMissions/methods/magcoord.py @@ -3,6 +3,7 @@ import aacgmv2 import pysat +from pysatMissions.utils import package_check try: # Warn user if apexpy is not configured. Bypass needed to function on @@ -75,6 +76,7 @@ def add_aacgm_coordinates(inst, glat_label='glat', glong_label='glong', return +@package_check('apexpy') def add_quasi_dipole_coordinates(inst, glat_label='glat', glong_label='glong', alt_label='alt'): """Add quasi-dipole coordinates to instrument object using Apexpy package. diff --git a/pysatMissions/tests/test_methods_magcoord.py b/pysatMissions/tests/test_methods_magcoord.py index ca4ddd37..cbee79b4 100644 --- a/pysatMissions/tests/test_methods_magcoord.py +++ b/pysatMissions/tests/test_methods_magcoord.py @@ -3,6 +3,7 @@ import datetime as dt import numpy as np +import warnings import pytest @@ -49,10 +50,19 @@ def eval_targets(self, targets): ('add_quasi_dipole_coordinates', ['qd_lat', 'qd_long', 'mlt'])]) def test_add_coordinates(self, func, targets): - """Test adding thermal plasma data to test inst.""" + """Test adding coordinates to test inst.""" self.test_inst.custom_attach(getattr(mm_magcoord, func), kwargs=self.kwargs) - self.test_inst.load(date=self.reftime) - self.eval_targets(targets) + with warnings.catch_warnings(record=True) as war: + self.test_inst.load(date=self.reftime) + + # Convert all warnings into one large string + messages = str([str(ww) for ww in war]) + + if 'apexpy' in messages: + pytest.skip("Apexpy not installed") + else: + self.eval_targets(targets) + return From 258c05f97255cb70311d6d402da3d7d648f6f8d1 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:11:11 -0400 Subject: [PATCH 05/34] STY: streamline ephem preprocess --- pysatMissions/instruments/missions_ephem.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/pysatMissions/instruments/missions_ephem.py b/pysatMissions/instruments/missions_ephem.py index fbad6dfc..6b51a14e 100644 --- a/pysatMissions/instruments/missions_ephem.py +++ b/pysatMissions/instruments/missions_ephem.py @@ -33,13 +33,6 @@ import pandas as pds import pysat -try: - import OMMBV -except ImportError: - # Warnings thrown elsewhere if users call relevant functions without - # OMMBV installed - pass - from pysat.instruments.methods import testing as ps_meth from pysatMissions.instruments import _core as mcore from pysatMissions.methods import magcoord as mm_magcoord @@ -88,11 +81,10 @@ def preprocess(self): """ - mm_magcoord.add_quasi_dipole_coordinates(self) mm_magcoord.add_aacgm_coordinates(self) - if "OMMBV" in dir(): - mm_sc.calculate_ecef_velocity(self) - mm_sc.add_ram_pointing_sc_attitude_vectors(self) + mm_magcoord.add_quasi_dipole_coordinates(self) + mm_sc.calculate_ecef_velocity(self) + mm_sc.add_ram_pointing_sc_attitude_vectors(self) return From 59666e3d1c38398f16669aa8650a624a35fd75c3 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:27:09 -0400 Subject: [PATCH 06/34] ENH: allow unrelated errors to pass --- pysatMissions/utils/_core.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/pysatMissions/utils/_core.py b/pysatMissions/utils/_core.py index 59464a42..5d7d4a98 100644 --- a/pysatMissions/utils/_core.py +++ b/pysatMissions/utils/_core.py @@ -1,11 +1,10 @@ """Utilities for pysatMissions.""" -from importlib import import_module import warnings def package_check(package_name): - """Throw a warning if package is not installed. + """Throw a warning if optional package is not installed. Some systems are having issues installing OMMBV and apexpy. This allows these packages to be optionally installed. @@ -23,10 +22,14 @@ def wrapper(*args, **kwargs): 'See instructions at', 'https://github.com/pysat/pysatMissions']) try: - import_module(package_name) - except ModuleNotFoundError: - # Triggered if package is not installed - warnings.warn(message_warn, stacklevel=2) + func(*args, **kwargs) + except NameError as nerr: + # Triggered if call is made to package that is not installed + if package_name in str(nerr): + warnings.warn(message_warn, stacklevel=2) + else: + # Error is unrelated to optional package, raise original. + raise nerr return wrapper From 0755ab5624ee237bf675d46884f92dd5bc6be4b5 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:27:20 -0400 Subject: [PATCH 07/34] TST: test for unrelated errors --- pysatMissions/tests/test_utils.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/pysatMissions/tests/test_utils.py b/pysatMissions/tests/test_utils.py index 9d080694..2bf7a16d 100644 --- a/pysatMissions/tests/test_utils.py +++ b/pysatMissions/tests/test_utils.py @@ -1,5 +1,6 @@ """Unit tests for pysatMissions utilitis.""" +from importlib import import_module import warnings import pytest @@ -24,7 +25,7 @@ def teardown(self): @pytest.mark.parametrize("package_name, num_warns", [('os', 0), ('nonsense', 1)]) - def test_package_check(self, package_name, num_warns): + def test_package_check_warns(self, package_name, num_warns): """Test that package_check warns users if packages are not installed. Parameters @@ -37,8 +38,12 @@ def test_package_check(self, package_name, num_warns): @package_check(package_name) def dummy_func(): - """Pass through so that wrapper can be checked.""" - pass + """Try importing a package, simulate a NameError if not found.""" + try: + import_module(package_name) + except ModuleNotFoundError: + raise NameError('{:} not found'.format(package_name)) + return with warnings.catch_warnings(record=True) as war: dummy_func() @@ -48,3 +53,19 @@ def dummy_func(): assert package_name in str(war[0]) return + + def test_package_check_error(self): + """Test that package_check raises error for unrelated errors.""" + + @package_check('nonsense') + def dummy_func(): + """Simulate an unrelated NameError.""" + raise NameError('A sensible error has occurred') + return + + with pytest.raises(NameError) as nerr: + dummy_func() + + assert 'sensible' in str(nerr) + + return From dbc920f3ebea79ffb1c1b75a7c818d501dc362a0 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:29:02 -0400 Subject: [PATCH 08/34] DOC: update docstrings --- pysatMissions/utils/_core.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pysatMissions/utils/_core.py b/pysatMissions/utils/_core.py index 5d7d4a98..fe9024b0 100644 --- a/pysatMissions/utils/_core.py +++ b/pysatMissions/utils/_core.py @@ -9,6 +9,12 @@ def package_check(package_name): Some systems are having issues installing OMMBV and apexpy. This allows these packages to be optionally installed. + Parameters + ---------- + package_name : str + Name of the package to check in a given function. If not present, a + warning is raised and the original function is skipped. + """ def decorator(func): From 6a6569b110fbb67730e9e5f512483c5761352335 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:35:49 -0400 Subject: [PATCH 09/34] TST: no OMMBV --- .github/workflows/main.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1c01f253..d1134787 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,6 @@ jobs: - name: Install dependencies run: | pip install -r requirements.txt - pip install OMMBV --no-binary==OMMBV pip install apexpy --no-binary==apexpy - name: Set up pysat From a23d9542bb90b4fec19f7cd3f83bf964e2cdd49b Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:46:47 -0400 Subject: [PATCH 10/34] DOC: typo --- pysatMissions/instruments/missions_ephem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pysatMissions/instruments/missions_ephem.py b/pysatMissions/instruments/missions_ephem.py index 6b51a14e..dc6e1151 100644 --- a/pysatMissions/instruments/missions_ephem.py +++ b/pysatMissions/instruments/missions_ephem.py @@ -204,7 +204,7 @@ def load(fnames, tag=None, inst_id=None, obs_long=0., obs_lat=0., obs_alt=0., lp['glong'], lp['alt']) except NameError: - # Triggered if pyglow not installed + # Triggered if OMMBV not installed warnings.warn("OMMBV not installed. ECEF coords not generated.", stacklevel=2) lp['x'] = np.ones(np.size(lp['alt'])) * np.nan From c78d3a5d45f59ccd437149e3d7296a2cb48076f1 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:47:23 -0400 Subject: [PATCH 11/34] TST: use OMMBV --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d1134787..8112d0e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -33,6 +33,7 @@ jobs: run: | pip install -r requirements.txt pip install apexpy --no-binary==apexpy + pip install OMMBV --no-binary==OMMBV - name: Set up pysat run: | From 65f6e5d0756be8c5aa54a1392b4b143591572349 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:50:45 -0400 Subject: [PATCH 12/34] DOC: optional installs --- setup.cfg | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index eb2bff24..689748d5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -39,15 +39,18 @@ zip_safe = False packages = find: install_requires = aacgmv2 - apexpy geospacepy numpy - OMMBV pandas pysat pyEphem sgp4 +[options.extras_require] +all = + apexpy + OMMBV + [coverage:report] From 7698cab95de6e6b9fba92a714f814055199ea94e Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 12:53:14 -0400 Subject: [PATCH 13/34] TST: reinstall mingw in GA --- .github/workflows/main.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8112d0e1..8e2eadc3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,6 +24,12 @@ jobs: with: python-version: ${{ matrix.python-version }} + - name: Reinstall and set up MinGW-64 on Windows + if: ${{ matrix.os == 'windows-latest' }} + uses: egor-tensin/setup-mingw@v1 + with: + platform: x64 + - name: Install requirements for testing setup run: | python -m pip install --upgrade pip From 73481d50682ee069b6a4fa636dfe4d7a67040952 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 13:05:45 -0400 Subject: [PATCH 14/34] ENH: normalize vectors --- pysatMissions/methods/spacecraft.py | 49 +++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/pysatMissions/methods/spacecraft.py b/pysatMissions/methods/spacecraft.py index 41c29863..1a49b5ca 100644 --- a/pysatMissions/methods/spacecraft.py +++ b/pysatMissions/methods/spacecraft.py @@ -69,9 +69,8 @@ def add_ram_pointing_sc_attitude_vectors(inst): # Ram pointing is along velocity vector inst['sc_xhat_ecef_x'], inst['sc_xhat_ecef_y'], inst['sc_xhat_ecef_z'] = \ - OMMBV.vector.normalize(inst['velocity_ecef_x'], - inst['velocity_ecef_y'], - inst['velocity_ecef_z']) + normalize(inst['velocity_ecef_x'], inst['velocity_ecef_y'], + inst['velocity_ecef_z']) # Begin with z along Nadir (towards Earth) # if orbit isn't perfectly circular, then the s/c z vector won't @@ -79,9 +78,8 @@ def add_ram_pointing_sc_attitude_vectors(inst): # to the true z (in the orbital plane) that we can use it to get y, # and use x and y to get the real z inst['sc_zhat_ecef_x'], inst['sc_zhat_ecef_y'], inst['sc_zhat_ecef_z'] = \ - OMMBV.vector.normalize(-inst['position_ecef_x'], - -inst['position_ecef_y'], - -inst['position_ecef_z']) + normalize(-inst['position_ecef_x'], -inst['position_ecef_y'], + -inst['position_ecef_z']) # get y vector assuming right hand rule # Z x X = Y @@ -94,9 +92,8 @@ def add_ram_pointing_sc_attitude_vectors(inst): inst['sc_xhat_ecef_z']) # Normalize since Xhat and Zhat from above may not be orthogonal inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z'] = \ - OMMBV.vector.normalize(inst['sc_yhat_ecef_x'], - inst['sc_yhat_ecef_y'], - inst['sc_yhat_ecef_z']) + normalize(inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], + inst['sc_yhat_ecef_z']) # Strictly, need to recalculate Zhat so that it is consistent with RHS # just created @@ -210,6 +207,11 @@ def project_ecef_vector_onto_sc(inst, x_label, y_label, z_label, inst['sc_xhat_ecef_x'], inst['sc_xhat_ecef_y'], inst['sc_xhat_ecef_z'], inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z'], inst['sc_zhat_ecef_x'], inst['sc_zhat_ecef_y'], inst['sc_zhat_ecef_z']) + + # out_x = x * xx + y * xy + z * xz + # out_y = x * yx + y * yy + z * yz + # out_z = x * zx + y * zy + z * zz + inst[new_x_label] = x inst[new_y_label] = y inst[new_z_label] = z @@ -220,3 +222,32 @@ def project_ecef_vector_onto_sc(inst, x_label, y_label, z_label, inst.meta[new_z_label] = meta[2] return + + +def normalize(x, y, z): + """Normalize a time-series of vectors. + + Parameters + ---------- + x : pds.Series + The x-component + y : pds.Series + The y-component + z : pds.Series + The z-component + + Returns + ------- + xhat : pds.Series + The normalized x-component + yhat : pds.Series + The normalized y-component + zhat : pds.Series + The normalized z-component + + """ + + vector = np.hstack([x, y, z]) + xhat, yhat, zhat = vector / np.linalg.norm(vector, axis=0) + + return xhat, yhat, zhat From 1bd25b9cce515c2e705a3d4ce86a4e259d945b3f Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:02:23 -0400 Subject: [PATCH 15/34] BUG: size of nans --- pysatMissions/instruments/missions_ephem.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pysatMissions/instruments/missions_ephem.py b/pysatMissions/instruments/missions_ephem.py index dc6e1151..dec46564 100644 --- a/pysatMissions/instruments/missions_ephem.py +++ b/pysatMissions/instruments/missions_ephem.py @@ -207,9 +207,9 @@ def load(fnames, tag=None, inst_id=None, obs_long=0., obs_lat=0., obs_alt=0., # Triggered if OMMBV not installed warnings.warn("OMMBV not installed. ECEF coords not generated.", stacklevel=2) - lp['x'] = np.ones(np.size(lp['alt'])) * np.nan - lp['y'] = np.ones(np.size(lp['alt'])) * np.nan - lp['z'] = np.ones(np.size(lp['alt'])) * np.nan + lp['x'] = np.nan + lp['y'] = np.nan + lp['z'] = np.nan output_params.append(lp) output = pds.DataFrame(output_params, index=index) From 972ff53ac9d4a2521ebe2c6964b52aab08e548b0 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:21:31 -0400 Subject: [PATCH 16/34] BUG: streamline calculations --- pysatMissions/instruments/missions_ephem.py | 26 +++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pysatMissions/instruments/missions_ephem.py b/pysatMissions/instruments/missions_ephem.py index dec46564..6ac06072 100644 --- a/pysatMissions/instruments/missions_ephem.py +++ b/pysatMissions/instruments/missions_ephem.py @@ -198,21 +198,23 @@ def load(fnames, tag=None, inst_id=None, obs_long=0., obs_lat=0., obs_alt=0., # Elevation of satellite in m, converted to km lp['alt'] = sat.elevation / 1000.0 - # Get ECEF position of satellite - try: - lp['x'], lp['y'], lp['z'] = OMMBV.trans.geodetic_to_ecef(lp['glat'], - lp['glong'], - lp['alt']) - except NameError: - # Triggered if OMMBV not installed - warnings.warn("OMMBV not installed. ECEF coords not generated.", - stacklevel=2) - lp['x'] = np.nan - lp['y'] = np.nan - lp['z'] = np.nan output_params.append(lp) output = pds.DataFrame(output_params, index=index) + + # Get ECEF position of satellite + try: + output['x'], output['y'], output['z'] = \ + OMMBV.trans.geodetic_to_ecef(output['glat'], output['glong'], + output['alt']) + except NameError: + # Triggered if OMMBV not installed + warnings.warn("OMMBV not installed. ECEF coords not generated.", + stacklevel=2) + output['x'] = output['glat'] * np.nan + output['y'] = output['glat'] * np.nan + output['z'] = output['glat'] * np.nan + # Modify input object to include calculated parameters # Put data into DataFrame data = pds.DataFrame({'glong': output['glong'], From 2a2f70aa835aa2b997a8a1e44b41443b3e52da96 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:21:39 -0400 Subject: [PATCH 17/34] BUG: vstack --- pysatMissions/methods/spacecraft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pysatMissions/methods/spacecraft.py b/pysatMissions/methods/spacecraft.py index 8af4df68..9e8fe456 100644 --- a/pysatMissions/methods/spacecraft.py +++ b/pysatMissions/methods/spacecraft.py @@ -229,7 +229,7 @@ def normalize(x, y, z): """ - vector = np.hstack([x, y, z]) + vector = np.vstack([x, y, z]) xhat, yhat, zhat = vector / np.linalg.norm(vector, axis=0) return xhat, yhat, zhat From 56db6fefe4fd780b1947b9a42a0a9f89f3bb30ae Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:26:12 -0400 Subject: [PATCH 18/34] STY: cross product --- pysatMissions/methods/spacecraft.py | 50 +++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/pysatMissions/methods/spacecraft.py b/pysatMissions/methods/spacecraft.py index 9e8fe456..7b0d7c05 100644 --- a/pysatMissions/methods/spacecraft.py +++ b/pysatMissions/methods/spacecraft.py @@ -16,7 +16,6 @@ pass -@package_check('OMMBV') def add_ram_pointing_sc_attitude_vectors(inst): """Add attitude vectors for spacecraft assuming ram pointing. @@ -66,12 +65,9 @@ def add_ram_pointing_sc_attitude_vectors(inst): # get y vector assuming right hand rule # Z x X = Y inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z'] = \ - OMMBV.vector.cross_product(inst['sc_zhat_ecef_x'], - inst['sc_zhat_ecef_y'], - inst['sc_zhat_ecef_z'], - inst['sc_xhat_ecef_x'], - inst['sc_xhat_ecef_y'], - inst['sc_xhat_ecef_z']) + cross_product(inst['sc_zhat_ecef_x'], inst['sc_zhat_ecef_y'], + inst['sc_zhat_ecef_z'], inst['sc_xhat_ecef_x'], + inst['sc_xhat_ecef_y'], inst['sc_xhat_ecef_z']) # Normalize since Xhat and Zhat from above may not be orthogonal inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z'] = \ normalize(inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], @@ -81,12 +77,9 @@ def add_ram_pointing_sc_attitude_vectors(inst): # just created # Z = X x Y inst['sc_zhat_ecef_x'], inst['sc_zhat_ecef_y'], inst['sc_zhat_ecef_z'] = \ - OMMBV.vector.cross_product(inst['sc_xhat_ecef_x'], - inst['sc_xhat_ecef_y'], - inst['sc_xhat_ecef_z'], - inst['sc_yhat_ecef_x'], - inst['sc_yhat_ecef_y'], - inst['sc_yhat_ecef_z']) + cross_product(inst['sc_xhat_ecef_x'], inst['sc_xhat_ecef_y'], + inst['sc_xhat_ecef_z'], inst['sc_yhat_ecef_x'], + inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z']) # Adding metadata for v in ['x', 'y', 'z']: @@ -233,3 +226,34 @@ def normalize(x, y, z): xhat, yhat, zhat = vector / np.linalg.norm(vector, axis=0) return xhat, yhat, zhat + + +def cross_product(x1, y1, z1, x2, y2, z2): + """Cross product of two vectors, v1 x v2. + + Parameters + ---------- + x1 : float or array-like + X component of vector 1 + y1 : float or array-like + Y component of vector 1 + z1 : float or array-like + Z component of vector 1 + x2 : float or array-like + X component of vector 2 + y2 : float or array-like + Y component of vector 2 + z2 : float or array-like + Z component of vector 2 + + Returns + ------- + x, y, z + Unit vector x,y,z components + + """ + x = y1 * z2 - y2 * z1 + y = z1 * x2 - x1 * z2 + z = x1 * y2 - y1 * x2 + + return x, y, z From ccf0883c567de86cdba86f0eb759d4271937992c Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:26:18 -0400 Subject: [PATCH 19/34] DOC: comments --- pysatMissions/methods/magcoord.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pysatMissions/methods/magcoord.py b/pysatMissions/methods/magcoord.py index eccd14e4..f6d09091 100644 --- a/pysatMissions/methods/magcoord.py +++ b/pysatMissions/methods/magcoord.py @@ -14,6 +14,8 @@ pysat.logger.warning(" ".join(["apexpy module could not be imported.", "apexpy interface won't work.", "Failed with error:", str(ierr)])) + # Warnings thrown elsewhere if users call relevant functions without + # apexpy installed def add_aacgm_coordinates(inst, glat_label='glat', glong_label='glong', From 0586ed007789211a9d2cfa931b738158cb0df961 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:29:16 -0400 Subject: [PATCH 20/34] DOC: update changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4128afd..2337c933 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). -## [0.3.2] - 2022-08-01 +## [0.3.2] - 2022-XX-XX * Make OMMBV an optional install * Access logger directly from pysat * Use pysat deprecation tests +* Incorporate Windows tests into Github Actions * Bug Fix * Ensure default num_samples consistent for one day regardless of cadence * Maintenance * Update instrument test standards + * Added `utils.package_check`, a standard decorator to bypass functions using + packages that are optional installs if the package is not installed + * Use local vector functions rather than import from OMMBV ## [0.3.1] - 2022-05-18 * Include license in package manifest From 42cef7fe9ebbd07991130cf136f8d217329c113b Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:35:18 -0400 Subject: [PATCH 21/34] DOC: update docs --- README.md | 24 ++++++++++++++---------- docs/installation.rst | 16 ++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 85238f29..967d5d6e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ pysatMissions allows users to run build simulated satellites for Two-Line Elemen Main Features ------------- - Simulate satellite orbits from TLEs and add data from empirical models -- Import magnetic coordinates through apexpy and aacgmv2 +- Import magnetic coordinates through apexpy (optional) and aacgmv2 - Import geomagnetic basis vectors through OMMBV (optional) Documentation @@ -32,12 +32,12 @@ pysatMissions uses common Python modules, as well as modules developed by and for the Space Physics community. This module officially supports Python 3.8+. -| Common modules | Community modules | -| -------------- | ----------------- | -| numpy | aacgmv2 | -| pandas | apexpy | -| pyEphem | pysat>=3.0.2 | -| sgp4>=2.7 | | +| Common modules | Community modules | Optional modules | +| -------------- | ----------------- | ---------------- | +| numpy | aacgmv2 | apexpy | +| pandas | pysat>=3.0.2 | OMMBV | +| pyEphem | | | +| sgp4>=2.7 | | | One way to install is through pip. Just type @@ -85,6 +85,10 @@ pysat.utils.registry.register_by_module(pysatMissions.instruments) simInst = pysat.Instrument('missions', 'ephem') ``` -Note that some of the spacecraft vector calculations used require OMMBV, which -needs to be installed separately. This is an optional install as not all systems -support installation of OMMBV through pip. +# Optional modules + +Some of the spacecraft vector calculations used require OMMBV, which needs to be +installed separately. This is an optional install as not all systems support +installation of OMMBV through pip. + +Magnetic vector coordinates through apexpy as also set up as an optional install. diff --git a/docs/installation.rst b/docs/installation.rst index 887cf268..ca82afac 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -17,14 +17,14 @@ pysatMissions uses common Python modules, as well as modules developed by and for the Space Physics community. This module officially supports Python 3.7+ and pysat 3.0.0+. - ================ ================== - Common modules Community modules - ================ ================== - numpy aacgmv2 - pandas apexpy - pyEphem OMMBV>=1.0 - sgp4>=2.7 pysat>=3.0 - ================ ================== + ================ =================== ================== + Common modules Community modules Optional Modules + ================ =================== ================== + numpy aacgmv2 apexpy + pandas pysat>=3.0.2 OMMBV>=1.0 + pyEphem + sgp4>=2.7 + ================ =================== ================== Installation Options From 2b8b0a0bce3fd730be20ffac5e4f6dac8f8134b2 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:35:58 -0400 Subject: [PATCH 22/34] TST: restored test that no longer needs OMMBV --- pysatMissions/tests/test_methods_spacecraft.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pysatMissions/tests/test_methods_spacecraft.py b/pysatMissions/tests/test_methods_spacecraft.py index da1afa55..80f923e4 100644 --- a/pysatMissions/tests/test_methods_spacecraft.py +++ b/pysatMissions/tests/test_methods_spacecraft.py @@ -79,7 +79,6 @@ def test_calculate_ecef_velocity(self): self.eval_targets(targets) return - @pytest.mark.skipif(("OMMBV" not in dir()), reason="OMMBV is not installed") def test_add_ram_pointing_sc_attitude_vectors(self): """Test `add_ram_pointing_sc_attitude_vectors` helper function.""" From 385ddde0420431c6260bba910d1e1fdf9246c8b1 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 14:36:20 -0400 Subject: [PATCH 23/34] STY: remove extra windows step --- .github/workflows/main.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8e2eadc3..8112d0e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,12 +24,6 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Reinstall and set up MinGW-64 on Windows - if: ${{ matrix.os == 'windows-latest' }} - uses: egor-tensin/setup-mingw@v1 - with: - platform: x64 - - name: Install requirements for testing setup run: | python -m pip install --upgrade pip From 85387c3121ff7da7956ee0515ff302b662f5eec6 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 15:39:25 -0400 Subject: [PATCH 24/34] STY: update headers --- pysatMissions/tests/test_methods_spacecraft.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pysatMissions/tests/test_methods_spacecraft.py b/pysatMissions/tests/test_methods_spacecraft.py index 80f923e4..66a4862a 100644 --- a/pysatMissions/tests/test_methods_spacecraft.py +++ b/pysatMissions/tests/test_methods_spacecraft.py @@ -46,7 +46,8 @@ def setup(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=9, clean_level='clean', + use_header=True) self.testInst.custom_attach(add_eci) self.reftime = dt.datetime(2009, 1, 1) return From a9cf901cc232af53c9fac2271e5e4e557da14c5b Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 15:47:56 -0400 Subject: [PATCH 25/34] STY: remove more OMMBV vectors --- pysatMissions/methods/spacecraft.py | 38 ++++++++++------------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/pysatMissions/methods/spacecraft.py b/pysatMissions/methods/spacecraft.py index 7b0d7c05..8096dbfe 100644 --- a/pysatMissions/methods/spacecraft.py +++ b/pysatMissions/methods/spacecraft.py @@ -2,19 +2,6 @@ import numpy as np -import pysat -from pysatMissions.utils import package_check - -try: - import OMMBV -except ImportError as ierr: - pysat.logger.warning(" ".join(["OMMBV module could not be imported.", - "OMMBV interface won't work.", - "Failed with error:", str(ierr)])) - # Warnings thrown elsewhere if users call relevant functions without - # ommbv installed - pass - def add_ram_pointing_sc_attitude_vectors(inst): """Add attitude vectors for spacecraft assuming ram pointing. @@ -147,7 +134,6 @@ def get_vel_from_pos(x): return -@package_check('OMMBV') def project_ecef_vector_onto_sc(inst, x_label, y_label, z_label, new_x_label, new_y_label, new_z_label, meta=None): @@ -177,19 +163,21 @@ def project_ecef_vector_onto_sc(inst, x_label, y_label, z_label, # TODO(#65): add checks for existence of ecef labels in inst - x, y, z = OMMBV.vector.project_onto_basis( - inst[x_label], inst[y_label], inst[z_label], - inst['sc_xhat_ecef_x'], inst['sc_xhat_ecef_y'], inst['sc_xhat_ecef_z'], - inst['sc_yhat_ecef_x'], inst['sc_yhat_ecef_y'], inst['sc_yhat_ecef_z'], - inst['sc_zhat_ecef_x'], inst['sc_zhat_ecef_y'], inst['sc_zhat_ecef_z']) + xx = inst['sc_xhat_ecef_x'] + xy = inst['sc_xhat_ecef_y'] + xz = inst['sc_xhat_ecef_z'] + + yx = inst['sc_yhat_ecef_x'] + yy = inst['sc_yhat_ecef_y'] + yz = inst['sc_yhat_ecef_z'] - # out_x = x * xx + y * xy + z * xz - # out_y = x * yx + y * yy + z * yz - # out_z = x * zx + y * zy + z * zz + zx = inst['sc_zhat_ecef_x'] + zy = inst['sc_zhat_ecef_y'] + zz = inst['sc_zhat_ecef_z'] - inst[new_x_label] = x - inst[new_y_label] = y - inst[new_z_label] = z + inst[new_x_label] = inst[x_label] * xx + inst[y_label] * xy + inst[z_label] * xz + inst[new_y_label] = inst[x_label] * yx + inst[y_label] * yy + inst[z_label] * yz + inst[new_z_label] = inst[x_label] * zx + inst[y_label] * zy + inst[z_label] * zz if meta is not None: inst.meta[new_x_label] = meta[0] From fd8abb0b830fcc64aed5e8aef574973d2c7d3df3 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Fri, 5 Aug 2022 15:48:52 -0400 Subject: [PATCH 26/34] TST: enable vector tests --- pysatMissions/tests/test_methods_spacecraft.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pysatMissions/tests/test_methods_spacecraft.py b/pysatMissions/tests/test_methods_spacecraft.py index 66a4862a..060d2d50 100644 --- a/pysatMissions/tests/test_methods_spacecraft.py +++ b/pysatMissions/tests/test_methods_spacecraft.py @@ -4,16 +4,9 @@ import datetime as dt import numpy as np -import pytest - import pysat from pysatMissions.methods import spacecraft as mm_sc -try: - import OMMBV # noqa: F401 -except ImportError: - pass - def add_eci(inst): """Add ECI position to pysat_testing instrument.""" @@ -93,7 +86,6 @@ def test_add_ram_pointing_sc_attitude_vectors(self): self.eval_targets(targets) return - @pytest.mark.skipif(("OMMBV" not in dir()), reason="OMMBV is not installed") def test_project_ecef_vector_onto_sc(self): """Test `project_ecef_vector_onto_sc` helper function.""" From a568c651c1d6bab47c7ea2b53240d2a74f062a07 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 11:27:21 -0400 Subject: [PATCH 27/34] STY: optional aacgm --- .github/workflows/main.yml | 1 + pysatMissions/methods/magcoord.py | 13 ++++++++++++- requirements.txt | 1 - 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8112d0e1..dca3a84c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,6 +32,7 @@ jobs: - name: Install dependencies run: | pip install -r requirements.txt + pip install aacgmv2 --no-binary==aacgmv2 pip install apexpy --no-binary==apexpy pip install OMMBV --no-binary==OMMBV diff --git a/pysatMissions/methods/magcoord.py b/pysatMissions/methods/magcoord.py index f6d09091..4b1661e4 100644 --- a/pysatMissions/methods/magcoord.py +++ b/pysatMissions/methods/magcoord.py @@ -1,10 +1,20 @@ """Routines for projecting aacgmv2 and apexpy model values onto pysat instruments. """ -import aacgmv2 import pysat from pysatMissions.utils import package_check +try: + # Warn user if apexpy is not configured. Bypass needed to function on + # readthedocs. Use of apexpy functions elsewhere in code will produce + # errors. + import aacgmv2 +except ImportError as ierr: + pysat.logger.warning(" ".join(["aacgmv2 module could not be imported.", + "aacgmv2 interface won't work.", + "Failed with error:", str(ierr)])) + # Warnings thrown elsewhere if users call relevant functions without + # apexpy installed try: # Warn user if apexpy is not configured. Bypass needed to function on # readthedocs. Use of apexpy functions elsewhere in code will produce @@ -18,6 +28,7 @@ # apexpy installed +@package_check('aacgmv2') def add_aacgm_coordinates(inst, glat_label='glat', glong_label='glong', alt_label='alt'): """Add AACGM coordinates to instrument object using AACGMV2 package. diff --git a/requirements.txt b/requirements.txt index d15054aa..57c5800a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -aacgmv2 geospacepy numpy pandas From 7568677c982fec4cbe8d5be376480c7c7bf9324c Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 11:43:08 -0400 Subject: [PATCH 28/34] DOC: improve documentation --- README.md | 35 ++++++++++++++++++------------- docs/introduction.rst | 1 - pysatMissions/__init__.py | 1 - pysatMissions/methods/magcoord.py | 15 +++++-------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 967d5d6e..75ceb2d9 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,7 @@ pysatMissions allows users to run build simulated satellites for Two-Line Elemen Main Features ------------- - Simulate satellite orbits from TLEs and add data from empirical models -- Import magnetic coordinates through apexpy (optional) and aacgmv2 -- Import geomagnetic basis vectors through OMMBV (optional) +- Import magnetic coordinates through apexpy and aacgmv2 (optional install) Documentation --------------------- @@ -34,9 +33,9 @@ Python 3.8+. | Common modules | Community modules | Optional modules | | -------------- | ----------------- | ---------------- | -| numpy | aacgmv2 | apexpy | -| pandas | pysat>=3.0.2 | OMMBV | -| pyEphem | | | +| numpy | pysat>=3.0.2 | aacgmv2 | +| pandas | | apexpy | +| pyEphem | | OMMBV | | sgp4>=2.7 | | | @@ -63,17 +62,19 @@ python setup.py install Note: pre-1.0.0 version ----------------------- -pysatMissions is currently in an initial development phase and requires pysat 3.0.2. +pysatMissions is currently in an initial development phase and requires pysat +3.0.2. # Using with pysat -The instrument modules are portable and designed to be run like any pysat instrument. +The instrument modules are portable and designed to be run like any pysat +instrument. ``` import pysat -from pysatMissions.instruments import missions_ephem +from pysatMissions.instruments import missions_sgp4 -simInst = pysat.Instrument(inst_module=missions_ephem) +sim_inst = pysat.Instrument(inst_module=missions_sgp4) ``` Another way to use the instruments in an external repository is to register the instruments. This only needs to be done the first time you load an instrument. Afterward, pysat will identify them using the `platform` and `name` keywords. @@ -82,13 +83,19 @@ import pysat import pysatMissions pysat.utils.registry.register_by_module(pysatMissions.instruments) -simInst = pysat.Instrument('missions', 'ephem') +sim_inst = pysat.Instrument('missions', 'sgp4') ``` # Optional modules -Some of the spacecraft vector calculations used require OMMBV, which needs to be -installed separately. This is an optional install as not all systems support -installation of OMMBV through pip. +Magnetic vector coordinates through apexpy and aacgmv2 are set up as optional +installs. Both packages require fortran to install properly, and may require +additional configuration. -Magnetic vector coordinates through apexpy as also set up as an optional install. +The instrument `missions_ephem` has been deprecated since pyEphem is no longer +maintained. This will be removed in v0.4.0. Note that OMMBV is required for +this instrument to function correctly, but is not required for the core +pysatMissions package. This has also been made optional to improve installation. +Please use the `missions_sgp4` instrument for future needs. + +The orbital trajectories can be calculated without any of the optional modules. diff --git a/docs/introduction.rst b/docs/introduction.rst index d2e55a4b..3e1385ef 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -10,7 +10,6 @@ Main Features ------------- - Simulate satellite orbits from TLEs and add data from empirical models - Import magnetic coordinates through apexpy and aacgmv2 -- Import geomagnetic basis vectors through OMMBV This document covers installation, a tutorial on pysatMissions including demonstration code, and an API reference. diff --git a/pysatMissions/__init__.py b/pysatMissions/__init__.py index b3628611..de88d0f6 100644 --- a/pysatMissions/__init__.py +++ b/pysatMissions/__init__.py @@ -8,7 +8,6 @@ ------------- - Simulate satellite orbits from TLEs and add data from empirical models - Import magnetic coordinates through apexpy and aacgmv2 -- Import geomagnetic basis vectors through OMMBV """ diff --git a/pysatMissions/methods/magcoord.py b/pysatMissions/methods/magcoord.py index 4b1661e4..3bc63b59 100644 --- a/pysatMissions/methods/magcoord.py +++ b/pysatMissions/methods/magcoord.py @@ -4,28 +4,23 @@ import pysat from pysatMissions.utils import package_check +# Warn user if aacgmv2 is not configured. Use of aacgmv2 functions elsewhere in +# code will produce additional warnings errors. try: - # Warn user if apexpy is not configured. Bypass needed to function on - # readthedocs. Use of apexpy functions elsewhere in code will produce - # errors. import aacgmv2 except ImportError as ierr: pysat.logger.warning(" ".join(["aacgmv2 module could not be imported.", "aacgmv2 interface won't work.", "Failed with error:", str(ierr)])) - # Warnings thrown elsewhere if users call relevant functions without - # apexpy installed + +# Warn user if apexpy is not configured. Use of apexpy functions elsewhere in +# code will produce additional warnings errors. try: - # Warn user if apexpy is not configured. Bypass needed to function on - # readthedocs. Use of apexpy functions elsewhere in code will produce - # errors. import apexpy except ImportError as ierr: pysat.logger.warning(" ".join(["apexpy module could not be imported.", "apexpy interface won't work.", "Failed with error:", str(ierr)])) - # Warnings thrown elsewhere if users call relevant functions without - # apexpy installed @package_check('aacgmv2') From e49435b86fb991374c851994e540c6b00614e0b9 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 11:43:26 -0400 Subject: [PATCH 29/34] DOC: update setup cfg --- setup.cfg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 689748d5..ffc41448 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,6 +25,7 @@ classifiers = Programming Language :: Python :: 3.10 Operating System :: MacOS :: MacOS X Operating System :: POSIX :: Linux + Operating System :: Microsoft :: Windows license_file = LICENSE long_description = file: README.md long_description_content_type = text/markdown @@ -38,7 +39,6 @@ include_package_data = True zip_safe = False packages = find: install_requires = - aacgmv2 geospacepy numpy pandas @@ -48,6 +48,7 @@ install_requires = [options.extras_require] all = + aacgmv2 apexpy OMMBV From 248807eb3091163a04403b05064e12645171f996 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 14:13:15 -0400 Subject: [PATCH 30/34] STY: update func name --- pysatMissions/tests/test_methods_spacecraft.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pysatMissions/tests/test_methods_spacecraft.py b/pysatMissions/tests/test_methods_spacecraft.py index 060d2d50..4cc7f01a 100644 --- a/pysatMissions/tests/test_methods_spacecraft.py +++ b/pysatMissions/tests/test_methods_spacecraft.py @@ -8,8 +8,8 @@ from pysatMissions.methods import spacecraft as mm_sc -def add_eci(inst): - """Add ECI position to pysat_testing instrument.""" +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, @@ -41,7 +41,7 @@ def setup(self): self.testInst = pysat.Instrument(platform='pysat', name='testing', num_samples=9, clean_level='clean', use_header=True) - self.testInst.custom_attach(add_eci) + self.testInst.custom_attach(add_ecef) self.reftime = dt.datetime(2009, 1, 1) return From bbf68208db000b240f6e3f2d8f4201a742499666 Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 14:20:22 -0400 Subject: [PATCH 31/34] STY: add skip for aacgm --- pysatMissions/tests/test_methods_magcoord.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pysatMissions/tests/test_methods_magcoord.py b/pysatMissions/tests/test_methods_magcoord.py index cbee79b4..08d7e0fc 100644 --- a/pysatMissions/tests/test_methods_magcoord.py +++ b/pysatMissions/tests/test_methods_magcoord.py @@ -60,7 +60,9 @@ def test_add_coordinates(self, func, targets): # Convert all warnings into one large string messages = str([str(ww) for ww in war]) - if 'apexpy' in messages: + if 'aacgmv2' in messages: + pytest.skip("aacgmv2 not installed") + elif 'apexpy' in messages: pytest.skip("Apexpy not installed") else: self.eval_targets(targets) From 997baa87934833a404c974dfe5dc45b6b5352b9e Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Mon, 8 Aug 2022 14:24:31 -0400 Subject: [PATCH 32/34] DOC: improve readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 75ceb2d9..1ef0d720 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,8 @@ sim_inst = pysat.Instrument('missions', 'sgp4') Magnetic vector coordinates through apexpy and aacgmv2 are set up as optional installs. Both packages require fortran to install properly, and may require -additional configuration. +additional configuration. Both can be installed from pip, but may require the +`--no-binary` option depending on your system. The instrument `missions_ephem` has been deprecated since pyEphem is no longer maintained. This will be removed in v0.4.0. Note that OMMBV is required for From b55cc597c2e1d7e4047dc2414b204ba63d3b47bc Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Thu, 18 Aug 2022 15:48:01 -0400 Subject: [PATCH 33/34] DOC: update docs --- docs/installation.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/installation.rst b/docs/installation.rst index ca82afac..02e60e65 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -20,9 +20,9 @@ Python 3.7+ and pysat 3.0.0+. ================ =================== ================== Common modules Community modules Optional Modules ================ =================== ================== - numpy aacgmv2 apexpy - pandas pysat>=3.0.2 OMMBV>=1.0 - pyEphem + numpy pysat>=3.0.2 aacgmv2 + pandas apexpy + pyEphem OMMBV>=1.0 sgp4>=2.7 ================ =================== ================== From fc439974e489faa748d9b3625b5db7322bbb00fa Mon Sep 17 00:00:00 2001 From: Jeff Klenzing Date: Thu, 18 Aug 2022 15:48:12 -0400 Subject: [PATCH 34/34] STY: more options --- setup.cfg | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index ffc41448..b5c92ce8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,10 +47,9 @@ install_requires = sgp4 [options.extras_require] -all = - aacgmv2 - apexpy - OMMBV +aacgmv2 = aacgmv2 +apexpy = apexpy +OMMBV = OMMBV [coverage:report]