Skip to content

Commit

Permalink
Merge branch 'master' into locstream-support
Browse files Browse the repository at this point in the history
  • Loading branch information
vindelico authored Jul 10, 2023
2 parents e2276c3 + f0cd9d9 commit c49fcc3
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 99 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:
tox-env: py39
- python-version: "3.10"
tox-env: py310
- python-version: "3.11"
tox-env: py311
steps:
- uses: actions/checkout@v3
- name: Set up Python${{ matrix.python-version }}
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ default_language_version:

repos:
- repo: https://github.com/asottile/pyupgrade
rev: v3.7.0
rev: v3.9.0
hooks:
- id: pyupgrade
args: [ '--py38-plus' ]
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,6 @@ Before you submit a pull request, check that it meets these guidelines:
#. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.md.
#. The pull request should work for Python 3.8, 3.9, and 3.10. Check
#. The pull request should work for Python 3.8, 3.9, 3.10, and 3.11. Check
https://github.com/roocs/clisops/actions
and make sure that the tests pass for all supported Python versions.
25 changes: 13 additions & 12 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
Version History
===============

v.10.0 (unreleased)
-------------------
v0.10.0 (2023-06-28)
--------------------

New Features
^^^^^^^^^^^^
* Added support for Python 3.11 (#287).

Bug Fixes
^^^^^^^^^
* Fixed bug in `core.subset.shape_bbox_indexer` with the union of invalid geometries. Added regression test. (Issue #280)
* Added support in `core.subset.shape_bbox_indexer` for Point and MultiPoint geometries. (Issue #283)
* Fixed `core.subset.subset_bbox` and `core.subset.subset_shape` for datasets with 1D longitude and latitude (ex : Station data).
* Fixed bug in `core.subset.shape_bbox_indexer` with the union of invalid geometries. Added regression test. (#280)
* Added support in `core.subset.shape_bbox_indexer` for Point and MultiPoint geometries. (#283)
* Fixed `core.subset.subset_bbox` and `core.subset.subset_shape` for datasets with 1D longitude and latitude (ex: Station data). (#288)

Other Changes
^^^^^^^^^^^^^
* Shapely 2.0 is now faster than pygeos for ``create_mask``. Removed pygeos from extra dependencies and pinned shapely above 2.0. (#289)

v0.9.6 (2023-04-05)
-------------------
Expand Down Expand Up @@ -262,7 +270,6 @@ Other Changes
* Using file caching to gather ``xclim`` test data.
* Change made to ``core.subset.subset_bbox._check_desc_coords`` to cope with subsetting when only one latitude or longitude exists in the input dataset


v0.5.0 (2020-12-17)
-------------------

Expand Down Expand Up @@ -295,7 +302,6 @@ Breaking Changes

New Features
^^^^^^^^^^^^

* ``subset_level`` added.
* PR template.
* Config file now exists at ``clisops.etc.roocs.ini``. This can be overwritten by setting the environment variable
Expand All @@ -313,13 +319,11 @@ New Features

Bug Fixes
^^^^^^^^^

* Nudging time values to nearest available in dataset to fix a bug where subsetting failed when the exact date
did not exist in the dataset.

Other Changes
^^^^^^^^^^^^^

* ``cfunits`` dependency removed - not needed.
* requirements.txt and environment.yml synced.
* Documentation updated to include API.
Expand All @@ -341,15 +345,13 @@ Other Changes
^^^^^^^^^^^^^
* Update testdata and subset module (#34).


v0.2.1 (2020-07-08)
-------------------

Other Changes
^^^^^^^^^^^^^
* Fixed docs version (#25).


v0.2.0 (2020-06-19)
-------------------

Expand All @@ -365,7 +367,6 @@ Other Changes
* Now employing PEP8 + Black compatible autoformatting.
* Pre-commit is now used to launch code formatting inspections for local development.


v0.1.0 (2020-04-22)
-------------------

Expand Down
45 changes: 24 additions & 21 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
clisops - climate simulation operations
=======================================

.. image:: https://img.shields.io/pypi/v/clisops.svg
:target: https://pypi.python.org/pypi/clisops
:alt: PyPI

.. image:: https://img.shields.io/conda/vn/conda-forge/clisops.svg
:target: https://anaconda.org/conda-forge/clisops
:alt: Conda Forge

.. image:: https://github.com/roocs/clisops/workflows/build/badge.svg
:target: https://github.com/roocs/clisops/actions
:alt: Build Status

.. image:: https://coveralls.io/repos/github/roocs/clisops/badge.svg?branch=master
:target: https://coveralls.io/github/roocs/clisops?branch=master
:alt: Coverage

.. image:: https://readthedocs.org/projects/clisops/badge/?version=latest
:target: https://clisops.readthedocs.io/en/latest/?badge=latest
:alt: Documentation
|pypi| |conda| |build| |coveralls| |docs| |black|

The ``clisops`` package (pronounced "clie-sops") provides a python library for running
*data-reduction* operations on `Xarray <http://xarray.pydata.org/>`_ data sets or files
Expand Down Expand Up @@ -56,6 +38,27 @@ This package was created with ``Cookiecutter`` and the ``audreyr/cookiecutter-py
* Cookiecutter: https://github.com/audreyr/cookiecutter
* cookiecutter-pypackage: https://github.com/audreyr/cookiecutter-pypackage

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg

.. |pypi| image:: https://img.shields.io/pypi/v/clisops.svg
:target: https://pypi.python.org/pypi/clisops
:alt: PyPI

.. |conda| image:: https://img.shields.io/conda/vn/conda-forge/clisops.svg
:target: https://anaconda.org/conda-forge/clisops
:alt: Conda Forge

.. |build| image:: https://github.com/roocs/clisops/workflows/build/badge.svg
:target: https://github.com/roocs/clisops/actions
:alt: Build Status

.. |coveralls| image:: https://coveralls.io/repos/github/roocs/clisops/badge.svg?branch=master
:target: https://coveralls.io/github/roocs/clisops?branch=master
:alt: Coverage

.. |docs| image:: https://readthedocs.org/projects/clisops/badge/?version=latest
:target: https://clisops.readthedocs.io/en/latest/?badge=latest
:alt: Documentation

.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/python/black
:alt: Python Black
:alt: Black
2 changes: 1 addition & 1 deletion clisops/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

__author__ = "Elle Smith"
__email__ = "eleanor.smith@stfc.ac.uk"
__version__ = "0.9.6"
__version__ = "0.10.0"
41 changes: 8 additions & 33 deletions clisops/core/subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@

from clisops.utils.dataset_utils import adjust_date_to_calendar

try:
import pygeos # noqa
except ImportError:
pygeos = None


__all__ = [
"create_mask",
"create_weight_masks",
Expand Down Expand Up @@ -552,35 +546,16 @@ def create_mask(
if not is_integer_dtype(poly.index.dtype):
poly = poly.reset_index()

if pygeos is not None:
# Vectorized creation of Point geometries
pts = pygeos.points(lon1, lat1)[np.newaxis, ...]
# Preparation for optimized computation
pygeos.prepare(pts)

geoms = pygeos.from_shapely(poly.geometry.values)[:, np.newaxis, np.newaxis]
pygeos.prepare(geoms)
else:
geoms = poly.geometry.values

# Do for all geometries
# For the pygeos case, this is slightly slower than going directly 3D,
# but keeps memory usage at an acceptable level with large polygon collections.
geoms = poly.geometry.values
mask = np.full(lat1.shape, np.nan)
for val, geom in zip(poly.index[::-1], geoms[::-1]):
if pygeos is not None:
# Get "covers" and remove singleton first dim
intersection = pygeos.covers(geom, pts)[0, ...]
else:
# Slow way because of the "touches"
contained = vectorized.contains(
geom, lon1.flatten(), lat1.flatten()
).reshape(lat1.shape)
touched = vectorized.touches(geom, lon1.flatten(), lat1.flatten()).reshape(
lat1.shape
)
intersection = np.logical_or(contained, touched)

contained = vectorized.contains(geom, lon1.flatten(), lat1.flatten()).reshape(
lat1.shape
)
touched = vectorized.touches(geom, lon1.flatten(), lat1.flatten()).reshape(
lat1.shape
)
intersection = np.logical_or(contained, touched)
mask[intersection] = val

mask = xarray.DataArray(mask, dims=dims_out, coords=coords_out)
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
# the built documents.
#
# The short X.Y version.
version = "0.9.6"
version = "0.10.0"
# The full version, including alpha/beta/rc tags.
release = version

Expand Down
3 changes: 0 additions & 3 deletions docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ you through the process.
on packages (ESMF, ESMpy) unavailable on windows. It can still be installed on osx/linux through `conda` or
directly [from source](https://github.com/pangeo-data/xESMF/).

Another optional dependency is [pygeos](https://pygeos.readthedocs.io/en/latest/index.html). If installed,
the performance of `core.subset.create_mask` and `core.subset.subset_shape` are greatly improved.

From sources
------------

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.9.6
current_version = 0.10.0
commit = True
tag = True

Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"matplotlib",
]

extra_requirements = ["xesmf>=0.6.2", "pygeos>=0.9"]
extra_requirements = ["xesmf>=0.6.2"]

setup(
version=about["__version__"],
Expand All @@ -61,6 +61,7 @@
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Security",
"Topic :: Internet",
"Topic :: Scientific/Engineering",
Expand Down
25 changes: 2 additions & 23 deletions tests/core/test_subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,6 @@
except ImportError:
xesmf = None

try:
import pygeos
except ImportError:
pygeos = None


@pytest.fixture(params=[True, False])
def toggle_pygeos(request):
if request.param:
if pygeos is None:
pytest.skip("pygeos not installed")
else:
yield request.param
else:
# Do not use pygeos
mod = subset.pygeos
# Monkeypatch core.subset to imitate the absence of pygeos.
subset.pygeos = None
yield request.param
subset.pygeos = mod


class TestSubsetTime:
nc_poslons = get_file("cmip3/tas.sresb1.giss_model_e_r.run1.atm.da.nc")
Expand Down Expand Up @@ -849,7 +828,7 @@ def test_small_poly_buffer(self, tmp_netcdf_filename):
with xr.open_dataset(filename_or_obj=tmp_netcdf_filename) as f:
assert {"tas", "crs"}.issubset(set(f.data_vars))

def test_mask_multiregions(self, toggle_pygeos):
def test_mask_multiregions(self):
ds = xr.open_dataset(self.nc_file)
regions = gpd.read_file(self.multi_regions_geojson)
regions.set_index("id")
Expand Down Expand Up @@ -881,7 +860,7 @@ def test_subset_multiregions(self):
assert ds_sub.notnull().sum() == 58 + 250 + 22
assert ds_sub.tas.shape == (12, 14, 128)

def test_vectorize_touches_polygons(self, toggle_pygeos):
def test_vectorize_touches_polygons(self):
"""Check that points touching the polygon are included in subset."""
# Create simple polygon
poly = Polygon([[0, 0], [1, 0], [1, 1]])
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
min_version = 4.0
envlist =
py{38,39,310}
py{38,39,310,311}
black
docs
requires =
Expand Down

0 comments on commit c49fcc3

Please sign in to comment.