Skip to content
Commits on Source (6)
[bumpversion]
current_version = 1.9.0
current_version = 1.9.3.gamma0
commit = True
tag = True
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)((?P<pre>[a-z]+)(?P<num>\d+))?(\.(?P<release>dev)(?P<dev>\d+))?
serialize =
{major}.{minor}.{patch}{pre}{num}.{release}{dev}
{major}.{minor}.{patch}{pre}{num}
{major}.{minor}.{patch}.{release}{dev}
{major}.{minor}.{patch}
[bumpversion:file:pyresample/version.py]
[bumpversion:part:release]
optional_value = gamma
values =
dev
gamma
[bumpversion:part:dev]
values =
0
1
2
3
4
optional_value = 4
[bumpversion:part:pre]
optional_value = final
values =
a
b
rc
final
<!-- Please make the PR against the `develop` branch. -->
<!-- Please make the PR against the `master` branch. -->
- [ ] Closes #xxxx <!-- remove if there is no corresponding issue, which should only be the case for minor changes -->
- [ ] Tests added <!-- for all bug fixes or enhancements -->
- [ ] Tests passed <!-- for all non-documentation changes -->
- [ ] Passes ``git diff origin/develop **/*py | flake8 --diff`` <!-- remove if you did not edit any Python files -->
- [ ] Passes ``git diff origin/master **/*py | flake8 --diff`` <!-- remove if you did not edit any Python files -->
- [ ] Fully documented <!-- remove if this change should not be visible to users, e.g., if it is an internal clean-up, or if this is part of a larger project that will be documented later -->
linters:
flake8:
fixer: true
max-line-length: 120
fixers:
enable: true
language: python
python:
- '2.7'
- '3.6'
env:
global:
# Set defaults to avoid repeating in most cases
- PYTHON_VERSION=$TRAVIS_PYTHON_VERSION
- PYTHON_VERSION=$PYTHON_VERSION
- NUMPY_VERSION=stable
- MAIN_CMD='python setup.py'
- CONDA_DEPENDENCIES='xarray dask toolz Cython pykdtree sphinx cartopy pillow matplotlib basemap pyyaml pyproj coveralls configobj coverage'
- CONDA_DEPENDENCIES='xarray dask toolz Cython pykdtree sphinx cartopy pillow matplotlib
basemap pyyaml pyproj coveralls configobj coverage codecov'
- SETUP_XVFB=False
- EVENT_TYPE='push pull_request'
- SETUP_CMD='test'
- CONDA_CHANNELS='conda-forge'
matrix:
include:
- env: PYTHON_VERSION=2.7
os: linux
- env: PYTHON_VERSION=2.7
os: osx
language: generic
- env: PYTHON_VERSION=3.6
os: linux
- env: PYTHON_VERSION=3.6
os: osx
language: generic
install:
- git clone --depth 1 git://github.com/astropy/ci-helpers.git
- source ci-helpers/travis/setup_conda.sh
script:
- coverage run --source=pyresample setup.py test && cd docs && mkdir doctest && sphinx-build -E -n -b doctest ./source ./doctest && cd ..
after_success: coveralls
- coverage run --source=pyresample setup.py test && cd docs && mkdir doctest && sphinx-build
-E -n -b doctest ./source ./doctest && cd ..
after_success:
- if [[ $PYTHON_VERSION == 3.6 ]]; then coveralls; codecov; fi
deploy:
- provider: pypi
user: dhoese
password:
secure: efysRf+1NddbJF6lnDYMHRm+qKXROWOTzcP7A+GJ/BGlkpZHQjf5gmE50C+9yHYigRLdVFX/x0aymiNMD1TFiZgA6a05ko+oFqGdEWV1ix/H1c4goTcIwdR0QVxd6MDmZiyyvmfOBWlKBGKv8ojtXbF+y1fxv+ly1AEeVvn1mqY=
distributions: sdist
skip_existing: true
on:
tags: true
repo: pytroll/pyresample
notifications:
slack: pytroll:96mNSYSI1dBjGyzVXkBT6qFt
###############################################################################
## Version 1.9.3 (2018/06/08)
### Issues Closed
* [Issue 113](https://github.com/pytroll/pyresample/issues/113) - Not all the close neighbours are found until search radius is increased ([PR 112](https://github.com/pytroll/pyresample/pull/112))
* [Issue 111](https://github.com/pytroll/pyresample/issues/111) - Bilinear interpolation leaves holes in fields with constant value ([PR 112](https://github.com/pytroll/pyresample/pull/112))
In this release 3 issues were closed.
### Pull Requests Merged
#### Bugs fixed
* [PR 125](https://github.com/pytroll/pyresample/pull/125) - Fix area slices not working for non-geos projections
* [PR 119](https://github.com/pytroll/pyresample/pull/119) - Add hashing to StackedAreaDefinitions
In this release 1 pull requests were closed.
## Version 1.9.2 (2018/05/13)
### Pull Requests Merged
#### Bugs fixed
* [PR 117](https://github.com/pytroll/pyresample/pull/117) - Fix get_area_slices ([218](https://github.com/pytroll/satpy/issues/218))
#### Features added
* [PR 116](https://github.com/pytroll/pyresample/pull/116) - Simplify get_sample_from_neighbour_info method
In this release 2 pull requests were closed.
## Version 1.9.1 (2018/05/03)
### Pull Requests Merged
#### Features added
* [PR 115](https://github.com/pytroll/pyresample/pull/115) - Geos area reduction
In this release 1 pull request was closed.
###############################################################################
......@@ -2,5 +2,4 @@ include docs/Makefile
recursive-include docs/source *
include test/test_files/*
include LICENSE.txt
include MANIFEST.in
include pyresample/ewa/*.h
[![Build Status](https://travis-ci.org/pytroll/pyresample.svg?branch=master)](https://travis-ci.org/pytroll/pyresample)
[![Build status](https://ci.appveyor.com/api/projects/status/a34o4utf8dqjsob1/branch/master?svg=true)](https://ci.appveyor.com/project/pytroll/pyresample/branch/master)
[![codebeat badge](https://codebeat.co/badges/2b9f14bc-758c-4fe1-967d-85b11e934983)](https://codebeat.co/projects/github-com-pytroll-pyresample-master)
Python package for geospatial resampling
----------------------------------------
......@@ -18,4 +18,3 @@ on Python 3.4+.
[Documentation](https://pyresample.readthedocs.org/en/latest/)
Look at [pytroll.org](http://pytroll.org/) for more information.
# Releasing Pyresample
prerequisites: `pip install bumpversion setuptools twine`
NB! You do not need `mercurial`. `bumpversion` is supposed to function without it. If it still doesn't work it might be that your PATH variable is screwed up. Check that all elements of your PATH are readable!
1. checkout master
2. pull from repo
3. run the unittests
4. run `loghub` and update the `CHANGELOG.md` file:
```
loghub pytroll/pyresample -u <username> -st v0.8.0 -plg bug "Bugs fixed" -plg enhancement "Features added" -plg documentation "Documentation changes"
```
Don't forget to commit!
5. run `bumpversion` with either `patch`, `minor`, `major`, `pre`, or `num` to
reach the desired version number
See [semver.org](http://semver.org/) for the definition of those values.
If the current "dev" version is not the desired version run:
```
bumpversion <level>
```
Where `level` is `num`, `pre`, `patch`, `minor`, or `major` to get to the correct
version. Check version.py to verify proper version. Then run:
```
bumpversion --tag release
```
To remove the `devN` portion of the version number and tag the release.
6. push changes to github `git push --follow-tags`
7. Verify travis tests passed and deploy sdist and wheel to PyPI
8. Update version to "dev" version of next release:
```
bumpversion patch
```
Which will set the version to "X.Y.Zdev0"
See [this issue](https://github.com/peritus/bumpversion/issues/77) for more information.
9. Push changes to github `git push` (there shouldn't be any new tags).
......@@ -3,8 +3,6 @@ environment:
PYTHON: "C:\\conda"
MINICONDA_VERSION: "latest"
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci-helpers\\appveyor\\windows_sdk.cmd"
# Don't build pykdtree with openmp because it isn't supported in appveyor's compilers
USE_OMP: "0"
CONDA_DEPENDENCIES: "xarray dask toolz Cython pykdtree sphinx cartopy pillow matplotlib pyyaml pyproj coveralls configobj coverage"
CONDA_CHANNELS: "conda-forge"
......
pyresample (1.9.3-1) unstable; urgency=medium
* New upstream release
* debian/patches
- refresh all patches
-- Antonio Valentino <antonio.valentino@tiscali.it> Tue, 12 Jun 2018 05:56:36 +0000
pyresample (1.9.0-1) unstable; urgency=medium
[ Bas Couwenberg ]
......
......@@ -7,7 +7,7 @@ Copyright: 2014-2018, PyTroll Developers
2010-2016, Esben S. Nielsen <esn@dmi.dk>
2010-2016, Thomas Lavergne <t.lavergne@met.no>
2010, 2014-2016, Adam Dybbroe
2010, 2013-2015, Martin Raspaud <martin.raspaud@smhi.se
2010, 2013-2015, Martin Raspaud <martin.raspaud@smhi.se>
License: LGPL-3+
Files: pyresample/bilinear/__init__.py
......
......@@ -21,10 +21,10 @@ index 3c6ef3c..5346cb4 100644
YSIZE: 480
AREA_EXTENT: (-20037508.342789244, -10018754.171394622, 20037508.342789244, 10018754.171394622)
diff --git a/pyresample/test/test_geometry.py b/pyresample/test/test_geometry.py
index eb1e13c..1a32806 100644
index d90ae97..449eb2c 100644
--- a/pyresample/test/test_geometry.py
+++ b/pyresample/test/test_geometry.py
@@ -411,7 +411,7 @@ class Test(unittest.TestCase):
@@ -401,7 +401,7 @@ class Test(unittest.TestCase):
swath_def = geometry.SwathDefinition(lons, lats)
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -33,7 +33,7 @@ index eb1e13c..1a32806 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -436,7 +436,7 @@ class Test(unittest.TestCase):
@@ -426,7 +426,7 @@ class Test(unittest.TestCase):
data = np.array([1, 2, 3, 4])
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -42,7 +42,7 @@ index eb1e13c..1a32806 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -471,7 +471,7 @@ class Test(unittest.TestCase):
@@ -461,7 +461,7 @@ class Test(unittest.TestCase):
data = np.dstack((data1, data2, data3))
filter_area = geometry.AreaDefinition('test', 'test', 'test',
{'proj': 'eqc', 'lon_0': 0.0,
......@@ -51,7 +51,7 @@ index eb1e13c..1a32806 100644
8, 8,
(-20037508.34, -10018754.17, 20037508.34, 10018754.17))
filter = np.array([[1, 1, 1, 1, 0, 0, 0, 0],
@@ -540,7 +540,7 @@ class Test(unittest.TestCase):
@@ -530,7 +530,7 @@ class Test(unittest.TestCase):
def test_latlong_area(self):
area_def = geometry.AreaDefinition('', '', '',
......
......@@ -301,7 +301,7 @@ Function for resampling using bilinear interpolation for irregular source grids.
... reduce_data=True, segments=None,
... epsilon=0)
The **target_area** needs to be an area definition with **proj4_string**
The **target_area** needs to be an area definition with **proj_str**
attribute.
..
......
......@@ -20,6 +20,7 @@ import os
CHUNK_SIZE = int(os.getenv('PYTROLL_CHUNK_SIZE', 4096))
from pyresample.version import __version__ # noqa
# Backwards compatibility
from pyresample import geometry # noqa
from pyresample import grid # noqa
......
......@@ -60,6 +60,7 @@ def _globe_from_proj4(proj4_terms):
# copy of class in cartopy (before it was released)
class _PROJ4Projection(ccrs.Projection):
def __init__(self, proj4_terms, globe=None, bounds=None):
terms = proj4_str_to_dict(proj4_terms)
globe = _globe_from_proj4(terms) if globe is None else globe
......
......@@ -135,8 +135,10 @@ def get_sample_from_bil_info(data, t__, s__, input_idxs, idx_arr,
# Reduce data
new_data = data[input_idxs]
data_min = np.nanmin(new_data)
data_max = np.nanmax(new_data)
# Add a small "machine epsilon" so that tiny variations are not discarded
epsilon = 1e-6
data_min = np.nanmin(new_data) - epsilon
data_max = np.nanmax(new_data) + epsilon
new_data = new_data[idx_arr]
......@@ -233,7 +235,7 @@ def get_bil_info(source_geo_def, target_area_def, radius=50e3, neighbours=32,
idx_ref = np.where(index_mask, 0, idx_ref)
# Get output projection as pyproj object
proj = Proj(target_area_def.proj4_string)
proj = Proj(target_area_def.proj_str)
# Get output x/y coordinates
out_x, out_y = _get_output_xy(target_area_def, proj)
......@@ -248,7 +250,7 @@ def get_bil_info(source_geo_def, target_area_def, radius=50e3, neighbours=32,
# Calculate vertical and horizontal fractional distances t and s
t__, s__ = _get_ts(pt_1, pt_2, pt_3, pt_4, out_x, out_y)
# Remove mask and put np.nan at the masked locations instead
# Mask NaN values
if masked:
mask = np.isnan(t__) | np.isnan(s__)
t__ = np.ma.masked_where(mask, t__)
......@@ -412,8 +414,11 @@ def _mask_coordinates(lons, lats):
def _get_corner(stride, valid, in_x, in_y, idx_ref):
"""Get closest set of coordinates from the *valid* locations"""
# Find the closest valid pixels, if any
idxs = np.argmax(valid, axis=1)
# Check which of these were actually valid
invalid = np.invert(np.max(valid, axis=1))
# Replace invalid points with np.nan
x__ = in_x[stride, idxs]
x__[invalid] = np.nan
......
This diff is collapsed.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014, 2015, 2017 Martin Raspaud
# Author(s):
# Martin Raspaud <martin.raspaud@smhi.se>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""The Boundary classes.
"""
import logging
import logging.handlers
import numpy as np
from pyresample.spherical import SphPolygon
logger = logging.getLogger(__name__)
class Boundary(object):
"""Boundary objects.
"""
def __init__(self, lons=None, lats=None, frequency=1):
self._contour_poly = None
if lons is not None:
self.lons = lons[::frequency]
if lats is not None:
self.lats = lats[::frequency]
def contour(self):
return self.lons, self.lats
@property
def contour_poly(self):
"""Get the Spherical polygon corresponding to the Boundary
"""
if self._contour_poly is None:
self._contour_poly = SphPolygon(
np.deg2rad(np.vstack(self.contour()).T))
return self._contour_poly
def draw(self, mapper, options, **more_options):
"""Draw the current boundary on the *mapper*
"""
self.contour_poly.draw(mapper, options, **more_options)
class AreaBoundary(Boundary):
"""Area boundary objects.
"""
def __init__(self, *sides):
Boundary.__init__(self)
self.sides_lons, self.sides_lats = zip(*sides)
self.sides_lons = list(self.sides_lons)
self.sides_lats = list(self.sides_lats)
def decimate(self, ratio):
"""Remove some points in the boundaries, but never the corners.
"""
for i in range(len(self.sides_lons)):
length = len(self.sides_lons[i])
start = int((length % ratio) / 2)
points = np.concatenate(([0], np.arange(start, length, ratio),
[length - 1]))
if points[1] == 0:
points = points[1:]
if points[-2] == (length - 1):
points = points[:-1]
self.sides_lons[i] = self.sides_lons[i][points]
self.sides_lats[i] = self.sides_lats[i][points]
def contour(self):
"""Get the (lons, lats) tuple of the boundary object.
"""
lons = np.concatenate([lns[:-1] for lns in self.sides_lons])
lats = np.concatenate([lts[:-1] for lts in self.sides_lats])
return lons, lats
class AreaDefBoundary(AreaBoundary):
"""Boundaries for area definitions (pyresample).
"""
def __init__(self, area, frequency=1):
lons, lats = area.get_bbox_lonlats()
AreaBoundary.__init__(self,
*zip(lons, lats))
if frequency != 1:
self.decimate(frequency)
class SimpleBoundary(object):
"""Container for geometry boundary.
Labelling starts in upper left corner and proceeds clockwise"""
def __init__(self, side1, side2, side3, side4):
self.side1 = side1
self.side2 = side2
self.side3 = side3
self.side4 = side4
......@@ -272,20 +272,20 @@ def _get_valid_index(lons_side1, lons_side2, lons_side3, lons_side4,
# Buffer min and max lon and lat of interest with radius of interest
lat_min = min(lats_side1.min(), lats_side2.min(), lats_side3.min(),
lats_side4.min())
lat_min_buffered = lat_min - float(radius_of_influence) / R
lat_min_buffered = lat_min - np.degrees(float(radius_of_influence) / R)
lat_max = max(lats_side1.max(), lats_side2.max(), lats_side3.max(),
lats_side4.max())
lat_max_buffered = lat_max + float(radius_of_influence) / R
lat_max_buffered = lat_max + np.degrees(float(radius_of_influence) / R)
max_angle_s2 = max(abs(lats_side2.max()), abs(lats_side2.min()))
max_angle_s4 = max(abs(lats_side4.max()), abs(lats_side4.min()))
lon_min_buffered = (lons_side4.min() -
float(radius_of_influence) /
(np.sin(np.radians(max_angle_s4)) * R))
np.degrees(float(radius_of_influence) /
(np.sin(np.radians(max_angle_s4)) * R)))
lon_max_buffered = (lons_side2.max() +
float(radius_of_influence) /
(np.sin(np.radians(max_angle_s2)) * R))
np.degrees(float(radius_of_influence) /
(np.sin(np.radians(max_angle_s2)) * R)))
# From the winding number theorem follows:
# angle_sum possiblilities:
......
......@@ -115,7 +115,7 @@ def ll2cr(swath_def, area_def, fill=np.nan, copy=True):
lats = lats.astype(np.float64)
# Break the input area up in to the expected parameters for ll2cr
p = area_def.proj4_string
p = area_def.proj_str
cw = area_def.pixel_size_x
# cell height must be negative for this to work as expected
ch = -abs(area_def.pixel_size_y)
......