Skip to content

Commit

Permalink
Merge branch 'develop' into clean_warning_update
Browse files Browse the repository at this point in the history
  • Loading branch information
jklenzing authored Dec 20, 2023
2 parents c162e4c + a77c2c9 commit d75bcb9
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 252 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
* Added manual test for pysatModels RC pip install
* Updated tests to new pysat and pytest standards
* Updated model Instruments to include the new `_clean_warn` attribute
* Removed backwards-support for pysat pre-3.0.4 functions
* Documentation
* Added badges and instructions for PyPi and Zenodo

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
pysatModels handles model-centric data loading through pysat and contains a
variety of tools to perform model-data analysis, including model validation.

Come join us on Slack! An invitation to the pysat workspace is available
Come join us on Slack! An invitation to the pysat workspace is available
in the 'About' section of the
[pysat GitHub Repository.](https://github.com/pysat/pysat)

Expand All @@ -31,7 +31,7 @@ the Space Physics community. This module officially supports Python 3.6+.
| ------------------ | ------------------ |
| numpy | pyForecastTools |
| pandas >= 1.4.0 | pysat >= 3.0.4 |
| requests | pysatNASA >= 0.0.5 |
| requests | pysatNASA |
| scipy | |
| xarray | |

Expand Down
6 changes: 3 additions & 3 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ the Space Physics community. This module officially supports Python 3.6+.
Common modules Community modules
============== =================
numpy pysat
pandas pyForecastTools
requests
pandas pysatNASA
requests pyForecastTools
scipy
xarray
============== =================
Expand Down Expand Up @@ -85,7 +85,7 @@ is set up, you may choose to register the the :py:mod:`pysatModel` model

.. code:: python
import pysat
import pysatModels as pymod
Expand Down
21 changes: 4 additions & 17 deletions pysatModels/models/sami2py_sami2.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

import datetime as dt
import functools
from packaging import version as pack_version
import warnings
import xarray as xr

Expand Down Expand Up @@ -147,26 +146,14 @@ def load(fnames, tag='', inst_id='', **kwargs):
file_info['day']):
epochs.append(dt.datetime(year, month, day))

vstr = '3.0.2' # TODO(#112) Remove support for backwards compatibility
loaded_data = []
loaded_meta = []
for epoch, fname in zip(epochs, fnames):
# Load data
# TODO(#112) Remove backwards compatibility
if pack_version.Version(pysat.__version__) < pack_version.Version(vstr):
data, meta = pysat.utils.load_netcdf4([fname], pandas_format=False,
epoch_name='ut')
data = data.rename({"ut": "time"})

# Create datetimes from 'ut' variable
data['time'] = [epoch
+ dt.timedelta(seconds=int(val * 3600.0))
for val in data['time'].values]
else:
data, meta = pysat.utils.load_netcdf4([fname], pandas_format=False,
epoch_name='ut',
epoch_origin=epoch,
epoch_unit='h')
data, meta = pysat.utils.io.load_netcdf([fname], pandas_format=False,
epoch_name='ut',
epoch_origin=epoch,
epoch_unit='h')

# Store data/meta for each loop
loaded_data.append(data)
Expand Down
10 changes: 3 additions & 7 deletions pysatModels/models/ucar_tiegcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,9 @@ def load(fnames, tag='', inst_id='', **kwargs):
"""

# TODO(#114): eventually remove support for multiple pysat versions
if hasattr(pysat.utils, 'io'):
data, meta = pysat.utils.io.load_netcdf(fnames, pandas_format=False,
epoch_name='time',
decode_times=True)
else:
data, meta = pysat.utils.load_netcdf4(fnames, pandas_format=False)
data, meta = pysat.utils.io.load_netcdf(fnames, pandas_format=False,
epoch_name='time',
decode_times=True)

# Move misc parameters from xarray to the Instrument object via Meta.
# Doing this after `meta` created ensures all metadata is still kept
Expand Down
8 changes: 4 additions & 4 deletions pysatModels/tests/test_methods_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
class TestMethodsGeneralLogging(object):
"""Unit tests for log messages raised by general methods."""

def setup(self):
def setup_method(self):
"""Set up the unit test environment."""
self.ch = logging.StreamHandler()
self.ch.setLevel(logging.INFO)
self.model = pysat.Instrument("pysat", "testmodel")

return

def teardown(self):
def teardown_method(self):
"""Clean up the unit test environment."""

del self.ch, self.model
Expand Down Expand Up @@ -50,7 +50,7 @@ def test_general_clean(self, caplog):
class TestMethodsGeneralDownload(object):
"""Unit tests for general methods handling downloads."""

def setup(self):
def setup_method(self):
"""Set up the unit test environment."""
# TODO(#100): remove if-statement when it is always triggered
tkwargs = {}
Expand All @@ -65,7 +65,7 @@ def setup(self):

return

def teardown(self):
def teardown_method(self):
"""Clean up the unit test environment."""

if os.path.isfile(self.out_file):
Expand Down
146 changes: 9 additions & 137 deletions pysatModels/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,159 +8,31 @@

import datetime as dt
import os
from packaging import version as pack_version
import pytest
import shutil
import sys
import tempfile

# Import the test classes from pysat
import pysat
from pysat.tests.instrument_test_class import InstTestClass
from pysat.tests.classes import cls_instrument_library as clslib

import pysatModels

# Retrieve the lists of Model instruments and testing methods
instruments = pysat.utils.generate_instrument_list(inst_loc=pysatModels.models)
method_list = [func for func in dir(InstTestClass)
if callable(getattr(InstTestClass, func))]

# Search tests for iteration via pytestmark, update instrument list
for method in method_list:
if hasattr(getattr(InstTestClass, method), 'pytestmark'):
# Get list of names of pytestmarks
mark_name = [mod_mark.name for mod_mark
in getattr(InstTestClass, method).pytestmark]

# Add instruments from your library
if 'all_inst' in mark_name:
mark = pytest.mark.parametrize("inst_name", instruments['names'])
getattr(InstTestClass, method).pytestmark.append(mark)
elif 'download' in mark_name:
mark = pytest.mark.parametrize("inst_dict",
instruments['download'])
getattr(InstTestClass, method).pytestmark.append(mark)
elif 'no_download' in mark_name:
mark = pytest.mark.parametrize("inst_dict",
instruments['no_download'])
getattr(InstTestClass, method).pytestmark.append(mark)


class TestModels(InstTestClass):
instruments = clslib.InstLibTests.initialize_test_package(
clslib.InstLibTests, inst_loc=pysatModels.models)


class TestModels(clslib.InstLibTests):
"""Main class for instrument tests.
Note
----
Uses class level setup and teardown so that all tests use the same
temporary directory. We do not want to geneate a new tempdir for each test,
as the load tests need to be the same as the download tests.
All standard tests, setup, and teardown inherited from the core pysat
instrument test class.
"""

def setup_class(self):
"""Initialize the testing setup once before all tests are run."""
# Make sure to use a temporary directory so that the user setup is not
# altered
# TODO(#100): remove if-statement when it is always triggered
tkwargs = {}
if sys.version_info.major >= 3 and sys.version_info.minor >= 10:
tkwargs = {"ignore_cleanup_errors": True}
self.tempdir = tempfile.TemporaryDirectory(**tkwargs)
self.saved_path = pysat.params['data_dirs']
pysat.params.data['data_dirs'] = [self.tempdir.name]

# Assign the location of the model Instrument sub-modules
self.inst_loc = pysatModels.models
return

def teardown_class(self):
"""Clean up downloaded files and parameters from tests."""

pysat.params.data['data_dirs'] = self.saved_path

# TODO(#100): Remove try/except when Python 3.10 is the lowest version
try:
self.tempdir.cleanup()
except Exception:
pass

del self.inst_loc, self.saved_path, self.tempdir
return


class TestSAMIPysatVersion(object):
"""Test SAMI load code for pysat version differences across v3.0.2."""

def setup_class(self):
"""Initialize the testing setup once before all tests are run."""
# Make sure to use a temporary directory so that the user setup is not
# altered

# TODO(#100): remove if-statement when it is always triggered
tkwargs = {}
if sys.version_info.major >= 3 and sys.version_info.minor >= 10:
tkwargs = {"ignore_cleanup_errors": True}
self.tempdir = tempfile.TemporaryDirectory(**tkwargs)
self.saved_path = pysat.params['data_dirs']
self.saved_ver = pysat.__version__
pysat.params.data['data_dirs'] = [self.tempdir.name]

# Assign the location of the model Instrument sub-modules
self.inst_loc = pysatModels.models
return

def teardown_class(self):
"""Clean up downloaded files and parameters from tests."""

pysat.params.data['data_dirs'] = self.saved_path
pysat.__version__ = self.saved_ver

# Remove the temporary directory
# TODO(#100): Remove try/except when Python 3.10 is the lowest version
try:
self.tempdir.cleanup()
except Exception:
pass

del self.inst_loc, self.saved_path, self.tempdir, self.saved_ver
return

def test_load_failure(self):
"""Test for SAMI load failure when faking a different pysat version."""

if (pack_version.Version(pysat.__version__)
>= pack_version.Version('3.0.2')):
# Define target error variable label
label = 'ut'

# Replace reported version with one before 3.0.2
vlabel = '3.0.1'

# Expected error
error = ValueError
else:
# Define target error variable label
label = 'epoch_origin'

# Expected error
error = TypeError

# Replace reported version with one including 3.0.2
vlabel = '3.0.2'

# Update reported pysat version
pysat.__version__ = vlabel

with pytest.raises(error) as verr:
inst = pysat.Instrument(inst_module=self.inst_loc.sami2py_sami2,
tag='test')
inst.download(self.inst_loc.sami2py_sami2._test_dates['']['test'],
self.inst_loc.sami2py_sami2._test_dates['']['test'])
inst.load(date=self.inst_loc.sami2py_sami2._test_dates['']['test'])

assert str(verr).find(label) >= 0

return


class TestSAMILoadMultipleDays(object):
"""Test SAMI load code for multiple days."""
Expand Down
8 changes: 4 additions & 4 deletions pysatModels/tests/test_utils_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def eval_xarray_output(inst, xdata):
class TestUtilsConvertLoadModelXarray(object):
"""Unit tests for `utils.convert.load_model_xarray`."""

def setup(self):
def setup_method(self):
"""Create a clean testing setup before each method."""
self.ftime = pysat.instruments.pysat_testing_xarray._test_dates['']['']
self.filename = "%Y-%m-%d.nofile"
Expand All @@ -76,7 +76,7 @@ def setup(self):
self.xout = None
self.temp_file = 'None'

def teardown(self):
def teardown_method(self):
"""Clean up test environment after each method."""
if os.path.isfile(self.temp_file):
os.remove(self.temp_file)
Expand Down Expand Up @@ -130,11 +130,11 @@ def test_load_inst(self, mkey, mval):
class TestUtilsConvertPysatXarray(object):
"""Unit tests for utils.convert.convert_pysat_to_xarray."""

def setup(self):
def setup_method(self):
"""Create a clean testing setup before each method."""
self.ref_time = pysat.instruments.pysat_testing._test_dates['']['']

def teardown(self):
def teardown_method(self):
"""Clean up test environment after each method."""
del self.ref_time

Expand Down
Loading

0 comments on commit d75bcb9

Please sign in to comment.