Skip to content

Commit

Permalink
feat: add changes for uploading to pypi (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
tsutterley authored Jun 15, 2022
1 parent bbd837f commit 79effcf
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 36 deletions.
3 changes: 1 addition & 2 deletions .binder/environment.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: read-GRACE-harmonics
name: gravity_toolkit
channels:
- conda-forge
dependencies:
Expand All @@ -23,5 +23,4 @@ dependencies:
- tk
- pip
- pip:
- git+https://github.com/tsutterley/read-GRACE-geocenter.git
- git+https://github.com/tsutterley/geoid-toolkit.git
32 changes: 32 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This workflows will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
release:
types: [created]

jobs:
deploy:

runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
1 change: 1 addition & 0 deletions .github/workflows/python-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
- name: Create conda Test Environment
run: |
conda install flake8 pytest pytest-cov cython
pip install git+https://github.com/tsutterley/read-GRACE-geocenter.git
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@
.Rhistory
__pycache__
build/
run/
dist/
develop-eggs/
run/
wheels/
.eggs/
*.egg-info/
.installed.cfg
*.egg
.pytest_cache
pythonenv*/
# OS generated files #
######################
.DS_Store
Expand Down Expand Up @@ -77,6 +81,7 @@ Thumbs.db
*.sw*
*.hidden
None*.png
*.gfc
# Jupyter Checkpoints #
#######################
.ipynb_checkpoints
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ RUN pip3 install --no-cache-dir --no-binary=cartopy \
python-dateutil \
pyyaml \
scipy && \
pip3 install --no-cache-dir --no-deps git+https://github.com/tsutterley/read-GRACE-geocenter.git && \
pip3 install --no-cache-dir --no-deps git+https://github.com/tsutterley/geoid-toolkit.git

COPY . .
Expand Down
4 changes: 3 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ read-GRACE-harmonics
.. |License| image:: https://img.shields.io/github/license/tsutterley/read-grace-harmonics
:target: https://github.com/tsutterley/read-GRACE-harmonics/blob/main/LICENSE

.. |PyPI Version| image:: https://img.shields.io/pypi/v/gravity-toolkit.svg
:target: https://pypi.python.org/pypi/gravity-toolkit/

.. |Documentation Status| image:: https://readthedocs.org/projects/read-grace-harmonics/badge/?version=latest
:target: https://read-grace-harmonics.readthedocs.io/en/latest/?badge=latest

Expand Down Expand Up @@ -53,7 +56,6 @@ Dependencies
- `cartopy: Python package designed for geospatial data processing <https://scitools.org.uk/cartopy/docs/latest/>`_
- `netCDF4: Python interface to the netCDF C library <https://unidata.github.io/netcdf4-python/>`_
- `h5py: Python interface for Hierarchal Data Format 5 (HDF5) <https://www.h5py.org/>`_
- `read-GRACE-geocenter: Python reader for GRACE/GRACE-FO geocenter data <https://github.com/tsutterley/read-GRACE-geocenter/>`_
- `geoid-toolkit: Python utilities for calculating geoid heights from static gravity field coefficients <https://github.com/tsutterley/geoid-toolkit/>`_

References
Expand Down
1 change: 0 additions & 1 deletion doc/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ dependencies:
- texlive-core
- tk
- pip:
- git+https://github.com/tsutterley/read-GRACE-geocenter.git
- git+https://github.com/tsutterley/geoid-toolkit.git
- ..
10 changes: 9 additions & 1 deletion doc/source/getting_started/Examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ Examples
Jupyter Notebooks providing demonstrations of the functionality within ``read-GRACE-harmonics``:

- Creating Spatial Maps |github spatial| |nbviewer spatial|
Creates an animation of spatial maps on a global Equirectangular projection using data derived from the monthly GRACE/GRACE-FO Level-2 spherical harmonic product
Creates an animation of spatial maps using data derived from the monthly GRACE/GRACE-FO Level-2 spherical harmonic product
- Creating Spatial Error Maps |github error| |nbviewer error|
Creates spatial maps of estimated GRACE/GRACE-FO errors derived from the monthly Level-2 spherical harmonic product
- Creating Harmonic Plots |github harmonic| |nbviewer harmonic|
Creates an animation of triangle plots that visualize the GRACE/GRACE-FO Level-2 spherical harmonic product

Expand All @@ -17,6 +19,12 @@ Jupyter Notebooks providing demonstrations of the functionality within ``read-GR
.. |nbviewer spatial| image:: https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg
:target: https://nbviewer.jupyter.org/github/tsutterley/read-GRACE-harmonics/blob/main/notebooks/GRACE-Spatial-Maps.ipynb

.. |github error| image:: https://img.shields.io/badge/GitHub-view-6f42c1?style=flat&logo=Github
:target: https://github.com/tsutterley/read-GRACE-harmonics/blob/main/notebooks/GRACE-Spatial-Error.ipynb

.. |nbviewer error| image:: https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg
:target: https://nbviewer.jupyter.org/github/tsutterley/read-GRACE-harmonics/blob/main/notebooks/GRACE-Spatial-Error.ipynb

.. |github harmonic| image:: https://img.shields.io/badge/GitHub-view-6f42c1?style=flat&logo=Github
:target: https://github.com/tsutterley/read-GRACE-harmonics/blob/main/notebooks/GRACE-Harmonic-Plots.ipynb

Expand Down
14 changes: 10 additions & 4 deletions doc/source/getting_started/Install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
Installation
============

Presently ``read-GRACE-harmonics`` is only available for use as a `GitHub repository <https://github.com/tsutterley/read-GRACE-harmonics>`_.
``read-GRACE-harmonics`` is available for download from the `GitHub repository <https://github.com/tsutterley/read-GRACE-harmonics>`_,
and the `Python Package Index (pypi) <https://pypi.org/project/gravity-toolkit/>`_,
The contents of the repository can be download as a `zipped file <https://github.com/tsutterley/read-GRACE-harmonics/archive/main.zip>`_ or cloned.

To use this repository, please fork into your own account and then clone onto your system:
Expand All @@ -29,6 +30,11 @@ Alternatively can install the ``gravity_toolkit`` utilities directly from GitHub
python3 -m pip install --user git+https://github.com/tsutterley/read-GRACE-harmonics.git
Executable versions of this repository can also be tested using
`Binder <https://mybinder.org/v2/gh/tsutterley/read-GRACE-harmonics/main>`_ or
`Pangeo <https://aws-uswest2-binder.pangeo.io/v2/gh/tsutterley/read-GRACE-harmonics/main?urlpath=lab>`_.
| This repository can be also tested using `BinderHub <https://github.com/jupyterhub/binderhub>`_ platforms:
| |Binder| |Pangeo|
.. |Binder| image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/tsutterley/read-GRACE-harmonics/main

.. |Pangeo| image:: https://img.shields.io/static/v1.svg?logo=Jupyter&label=PangeoBinderAWS&message=us-west-2&color=orange
:target: https://aws-uswest2-binder.pangeo.io/v2/gh/tsutterley/read-GRACE-harmonics/main?urlpath=lab
6 changes: 6 additions & 0 deletions doc/source/getting_started/NASA-Earthdata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ The `Physical Oceanography Distributed Active Archive Center (PO.DAAC) <https://
provides data and related information pertaining to the physical processes and conditions of the global oceans,
including measurements of ocean winds, temperature, topography, salinity, circulation and currents, and sea ice.
PO.DAAC hosts

PO.DAAC is `migrating its data archive to the Earthdata Cloud <https://podaac.jpl.nasa.gov/cloud-datasets/migration>`_,
which is hosted in Amazon Web Services (AWS).
GRACE/GRACE-FO spherical harmonic data is currently scheduled to be "cloud enabled"
during Phase 4 and Phase 5 of the transition, slated for April and July 2022 respectively.

If any problems contact JPL PO.DAAC support at `[email protected] <mailto:[email protected]>`_
or the NASA EOSDIS support team `[email protected] <mailto:[email protected]>`_.

Expand Down
91 changes: 80 additions & 11 deletions gravity_toolkit/geocenter.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
u"""
geocenter.py
Written by Tyler Sutterley (04/2022)
Written by Tyler Sutterley (06/2022)
Data class for reading and processing geocenter data
PYTHON DEPENDENCIES:
Expand All @@ -15,6 +15,7 @@
https://github.com/yaml/pyyaml
UPDATE HISTORY:
Updated 06/2022: drop external reader dependency for UCI format
Updated 04/2022: updated docstrings to numpy documentation format
include utf-8 encoding in reads to be windows compliant
Updated 03/2022: add try/except for read_GRACE_geocenter
Expand All @@ -36,16 +37,11 @@
import gzip
import time
import uuid
import yaml
import logging
import netCDF4
import warnings
import numpy as np
import gravity_toolkit.time
try:
from read_GRACE_geocenter.read_GRACE_geocenter import read_GRACE_geocenter
except ModuleNotFoundError:
warnings.filterwarnings("always")
warnings.warn("read_GRACE_geocenter not available")

class geocenter(object):
"""
Expand Down Expand Up @@ -176,7 +172,8 @@ def from_gravis(self, geocenter_file, **kwargs):
"""
Reads monthly geocenter spherical harmonic data files from
`GFZ GravIS calculated using GRACE/GRACE-FO measurements
and Ocean Models of degree 1 <ftp://isdcftp.gfz-potsdam.de/grace/GravIS/GFZ/Level-2B/aux_data/GRAVIS-2B_GFZOP_GEOCENTER_0002.dat>`_
and Ocean Models of degree 1
<ftp://isdcftp.gfz-potsdam.de/grace/GravIS/GFZ/Level-2B/aux_data/GRAVIS-2B_GFZOP_GEOCENTER_0002.dat>`_
Parameters
Expand Down Expand Up @@ -431,12 +428,13 @@ def from_SLR(self, geocenter_file, **kwargs):

def from_UCI(self, geocenter_file, **kwargs):
"""
Reads geocenter file and extracts dates and spherical harmonic data
Reads monthly geocenter files computed using GRACE/GRACE-FO
measurements and ocean models [Swenson2008]_ [Sutterley2019]_
Parameters
----------
geocenter_file: str
degree 1 file
input datafile with geocenter coefficients
References
----------
Expand All @@ -452,7 +450,78 @@ def from_UCI(self, geocenter_file, **kwargs):
"""
#-- set filename
self.case_insensitive_filename(geocenter_file)
DEG1 = read_GRACE_geocenter(self.filename)
#-- read geocenter file and get contents
with open(os.path.expanduser(geocenter_file), mode='r', encoding='utf8') as f:
file_contents = f.read().splitlines()
#-- number of lines contained in the file
file_lines = len(file_contents)

#-- counts the number of lines in the header
HEADER = False
count = 0
#-- Reading over header text
while (HEADER is False) and (count < file_lines):
#-- file line at count
line = file_contents[count]
#--if End of YAML Header is found: set HEADER flag
HEADER = bool(re.search("\# End of YAML header",line))
#-- add 1 to counter
count += 1

#-- verify HEADER flag was set
if not HEADER:
raise IOError('Data not found in file:\n\t{0}'.format(geocenter_file))

#-- number of months within the file
n_mon = np.int64(file_lines - count)
#-- output time variables
DEG1 = {}
DEG1['time'] = np.zeros((n_mon))
DEG1['JD'] = np.zeros((n_mon))
DEG1['month'] = np.zeros((n_mon), dtype=np.int64)
#-- parse the YAML header (specifying yaml loader)
DEG1.update(yaml.load('\n'.join(file_contents[:count]),
Loader=yaml.BaseLoader))

#-- compile numerical expression operator
regex_pattern = '[-+]?(?:(?:\d*\.\d+)|(?:\d+\.?))(?:[Ee][+-]?\d+)?'
rx = re.compile(regex_pattern, re.VERBOSE)

#-- get names and columns of input variables
variables = copy.copy(DEG1['header']['variables'])
variables.pop('mid-epoch_time')
variables.pop('month')
columns = {}
#-- for each output data variable
for key in variables:
DEG1[key] = np.zeros((n_mon))
comment_text, = rx.findall(variables[key]['comment'])
columns[key] = int(comment_text) - 1

#-- for every other line:
for t, line in enumerate(file_contents[count:]):
#-- find numerical instances in line including integers, exponents,
#-- decimal points and negatives
line_contents = rx.findall(line)
#-- extacting mid-date time and GRACE/GRACE-FO "month"
DEG1['time'][t] = np.float64(line_contents[0])
DEG1['month'][t] = np.int64(line_contents[-1])
#-- calculate mid-date as Julian dates
#-- calendar year of date
year = np.floor(DEG1['time'][t])
#-- check if year is a leap year
days_per_year = np.sum(gravity_toolkit.time.calendar_days(year))
#-- calculation of day of the year
day_of_the_year = days_per_year*(DEG1['time'][t] % 1)
#-- calculate Julian day
DEG1['JD'][t] = np.float64(367.0*year - np.floor(7.0*(year)/4.0) -
np.floor(3.0*(np.floor((year - 8.0/7.0)/100.0) + 1.0)/4.0) +
np.floor(275.0/9.0) + day_of_the_year + 1721028.5)
#-- extract fully-normalized degree one spherical harmonics
for key,val in columns.items():
DEG1[key][t] = np.float64(line_contents[val])

#-- return the geocenter harmonics
return self.from_dict(DEG1)

def from_swenson(self, geocenter_file, **kwargs):
Expand Down
29 changes: 19 additions & 10 deletions gravity_toolkit/tools.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
u"""
tools.py
Written by Tyler Sutterley (04/2022)
Written by Tyler Sutterley (05/2022)
Jupyter notebook, user interface and plotting tools
PYTHON DEPENDENCIES:
Expand All @@ -27,6 +27,7 @@
utilities.py: download and management utilities for files
UPDATE HISTORY:
Updated 05/2022: adjusted mask oceans function to be able to output mask
Updated 04/2022: updated docstrings to numpy documentation format
Updated 12/2021: added custom colormap function for some common scales
Written 09/2021
Expand Down Expand Up @@ -1114,7 +1115,7 @@ def interp_grid(data, xin, yin, xout, yout, order=0):

# PURPOSE: parallels the matplotlib basemap maskoceans function but with
# updated Greenland coastlines (G250) and Rignot (2017) Antarctic grounded ice
def mask_oceans(datain, xin, yin, order=0, lakes=False,
def mask_oceans(xin, yin, data=None, order=0, lakes=False,
iceshelves=True, resolution='qd'):
"""
Mask a data grid over global ocean and water points
Expand All @@ -1123,12 +1124,12 @@ def mask_oceans(datain, xin, yin, order=0, lakes=False,
Parameters
----------
datain: float
input data grid to be interpolated
xin: float
input x-coordinate array (monotonically increasing)
yin: float
input y-coordinate array (monotonically increasing)
data: float or NoneType
input data grid to be masked
order: int, default 0
interpolation order
Expand All @@ -1147,6 +1148,8 @@ def mask_oceans(datain, xin, yin, order=0, lakes=False,
Returns
-------
mask: bool
mask grid
datain: float
masked data grid
"""
Expand All @@ -1170,9 +1173,15 @@ def mask_oceans(datain, xin, yin, order=0, lakes=False,
#-- find Greenland and Antarctic ice shelf values (4)
if iceshelves:
land_function |= (landsea.data == 4)
# interpolation to output grid
datain.mask |= interp_grid(land_function.astype(np.int32),
landsea.lon, landsea.lat, xin, yin, order).astype(bool)
# replace data with updated mask
datain.data[datain.mask] = datain.fill_value
return datain
#-- interpolate to output grid
mask = interp_grid(land_function.astype(np.int32),
landsea.lon, landsea.lat, xin, yin, order)
#-- mask input data or return the interpolated mask
if data is not None:
# update data mask with interpolated mask
data.mask |= mask.astype(bool)
# replace data with fill values where invalid
data.data[data.mask] = data.fill_value
return data
else:
return mask.astype(bool)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
boto3
cartopy --no-binary=cartopy
future
geoid-toolkit
h5py
lxml
matplotlib
Expand Down
Loading

0 comments on commit 79effcf

Please sign in to comment.