Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix argopy broken by last xarray, fsspec and erddapy releases #65

Merged
merged 46 commits into from
Nov 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
fd48d01
Update xarray.py
gmaze Oct 15, 2020
ce39e9c
Update pythontests.yml
gmaze Oct 16, 2020
f44da7d
Update erddap_data.py
gmaze Nov 6, 2020
b11d691
Update erddap_index.py
gmaze Nov 6, 2020
b01bf91
Misc flake8 fixes
gmaze Nov 11, 2020
f182a0c
Update pythontests.yml
gmaze Nov 11, 2020
71c5957
Merge branch 'master' into xarray-016
gmaze Nov 11, 2020
5cfca8a
test without 3.8 but with xr>0.15
gmaze Nov 11, 2020
e4fe4bd
Misc flake8 fixes
gmaze Nov 11, 2020
1c316fe
test only mac/3.7 with xr>0.15
gmaze Nov 11, 2020
ef50fa4
Update pythontests.yml
gmaze Nov 11, 2020
0523f58
Update binder-badge-permissions.yaml
gmaze Nov 11, 2020
3974177
Update pythontests.yml
gmaze Nov 11, 2020
3b5bd99
Update pythontests.yml
gmaze Nov 11, 2020
12c115a
Try tests with conda env
gmaze Nov 11, 2020
6f21de5
Update pythontests-lock.yml
gmaze Nov 11, 2020
79db902
Update pythontests-lock.yml
gmaze Nov 11, 2020
706499a
Update .gitignore
gmaze Nov 11, 2020
0b99494
Update pythontests-lock.yml
gmaze Nov 11, 2020
eec1aa2
Update pythontests-lock.yml
gmaze Nov 11, 2020
4eccfb8
Try with fixes depend versions
gmaze Nov 11, 2020
8ebc54d
Update pythontests-lock.yml
gmaze Nov 11, 2020
f443026
Update argovis_data.py
gmaze Nov 11, 2020
c6688c3
Update pythontests-lock.yml
gmaze Nov 11, 2020
f770944
Increase strategy matrix
gmaze Nov 11, 2020
1d15088
Update pythontests-lock.yml
gmaze Nov 11, 2020
07eaf0e
Add free env test
gmaze Nov 11, 2020
48fb256
lock fsspec to 0.8.3
gmaze Nov 11, 2020
d2360e7
Update pythontests-lock.yml
gmaze Nov 11, 2020
0dc9437
Update pythontests-lock.yml
gmaze Nov 11, 2020
2a8ef8f
Update pythontests-lock.yml
gmaze Nov 11, 2020
0d8dca0
Delete pythontests.yml
gmaze Nov 11, 2020
c50d1cf
Update pythontests.yml
gmaze Nov 11, 2020
ae099f4
Update pythontests.yml
gmaze Nov 11, 2020
c6bc985
Add ipywidgets to env
gmaze Nov 11, 2020
fd3a006
Update requirements.txt
gmaze Nov 11, 2020
1a4c5d0
Build the doc with specific conda env under ci
gmaze Nov 11, 2020
7b5f14c
Update doc.yml
gmaze Nov 11, 2020
4996af3
Update doc.yml
gmaze Nov 11, 2020
249d3db
Improve doc
gmaze Nov 11, 2020
5f635fd
Update requirements.txt
gmaze Nov 17, 2020
65f4d0d
Split GA for dev and free environmments
gmaze Nov 17, 2020
e324051
Update pythontests.yml
gmaze Nov 17, 2020
a0c741e
Update pythontests.yml
gmaze Nov 17, 2020
81d1dc1
Update binder files
gmaze Nov 17, 2020
ef6ba21
Update postBuild
gmaze Nov 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions .github/workflows/binder-badge-permissions.yaml

This file was deleted.

53 changes: 53 additions & 0 deletions .github/workflows/pythonFREEtests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
on:
pull_request:
types: [ready_for_review]

jobs:
free_env:
name: unit-test FREE env

runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8]
os: [ubuntu-latest, macos-latest]
experimental: [true]

steps:
- uses: actions/checkout@master

- name: Set up environment with py-${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: argopy-tests
environment-file: ci/requirements/py${{matrix.python-version}}-free.yml
auto-update-conda: false
python-version: ${{ matrix.python-version }}
auto-activate-base: false

- shell: bash -l {0}
run: |
conda info
conda list

- name: Lint with flake8
shell: bash -l {0}
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
shell: bash -l {0}
run: |
pytest -s --verbosity=3 --cov=./ --cov-config=.coveragerc --cov-report xml:cov.xml --cov-report term-missing

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./cov.xml
flags: unittests
name: codecov-github
fail_ci_if_error: true
53 changes: 21 additions & 32 deletions .github/workflows/pythontests.yml
Original file line number Diff line number Diff line change
@@ -1,64 +1,53 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: build

on: [push, pull_request]
on: [push]

jobs:
unit-testing:

runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
strategy:
max-parallel: 12
fail-fast: false
matrix:
python-version: [3.6, 3.7, 3.8]
os: [ubuntu-latest, macos-latest]
experimental: [false]

steps:
- uses: actions/checkout@master

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@master
- name: Set up environment with py-${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v2
with:
activate-environment: argopy-tests
environment-file: ci/requirements/py${{matrix.python-version}}-dev.yml
auto-update-conda: false
python-version: ${{ matrix.python-version }}
auto-activate-base: false

# - name: Set up Conda for py-${{ matrix.python-version }}
# uses: goanpeca/setup-miniconda@v1
# with:
# auto-update-conda: true
# python-version: ${{ matrix.python-version }}
# auto-activate-base: false

- name: Install dependencies with pip
- shell: bash -l {0}
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install distributed aiohttp ipywidgets

# - name: Install dependencies with conda
# shell: bash -l {0}
# run: |
# conda info
# conda install matplotlib seaborn cartopy
conda info
conda list

- name: Lint with flake8
shell: bash -l {0}
run: |
pip install flake8
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Test with pytest
shell: bash -l {0}
run: |
pip install pytest pytest-cov
pytest -s --verbosity=3 --cov=./ --cov-config=.coveragerc --cov-report xml:cov.xml --cov-report term-missing

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
file: ./cov.xml # optional
flags: unittests # optional
name: codecov-github # optional
fail_ci_if_error: true # optional (default = false)
token: ${{ secrets.CODECOV_TOKEN }}
file: ./cov.xml
flags: unittests
name: codecov-github
fail_ci_if_error: true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,5 @@ fabric.properties
#pytest quai20
.vscode/
.pytest_cache
knotebooks/
knotebooks/
argopy/tests/cov.xml
8 changes: 4 additions & 4 deletions argopy/data_fetchers/argovis_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from .proto import ArgoDataFetcherProto
from abc import abstractmethod
import warnings
import distributed

from argopy.stores import httpstore
from argopy.options import OPTIONS
Expand All @@ -30,6 +29,7 @@
api_server + "/selection/overview"
) # URL to check if the API is alive


class ArgovisDataFetcher(ArgoDataFetcherProto):
###
# Methods to be customised for a specific Argovis request
Expand Down Expand Up @@ -337,7 +337,7 @@ def dashboard(self, **kw):


class Fetch_box(ArgovisDataFetcher):

def init(self, box: list):
""" Create Argo data loader

Expand Down Expand Up @@ -388,8 +388,8 @@ def get_url_shape(self):

def get_url_rect(self):
""" Return the URL used to download data """
strCorner = lambda b, i: str([b[i[0]],b[i[1]]]).replace(" ", "")
strDate = lambda b, i: pd.to_datetime(b[i]).strftime("%Y-%m-%dT%H:%M:%SZ")
def strCorner(b, i): return str([b[i[0]], b[i[1]]]).replace(" ", "")
def strDate(b, i): return pd.to_datetime(b[i]).strftime("%Y-%m-%dT%H:%M:%SZ")
url = self.server + "/selection/box/profiles"
url += "?startDate={}".format(strDate(self.BOX, 6))
url += "&endDate={}".format(strDate(self.BOX, 7))
Expand Down
13 changes: 8 additions & 5 deletions argopy/data_fetchers/erddap_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
from argopy.stores import httpstore
from argopy.plotters import open_dashboard

# Dirty fix before https://github.com/ioos/erddapy/issues/140
if isconnected():

# Load erddapy according to available version (breaking changes in v0.8.0)
try:
from erddapy import ERDDAP
from erddapy.utilities import parse_dates, quote_string_constraints
else:
from unittest.mock import MagicMock
sys.modules['ERDDAP'] = MagicMock()
except:
# >= v0.8.0
from erddapy.erddapy import ERDDAP
from erddapy.erddapy import _quote_string_constraints as quote_string_constraints
from erddapy.erddapy import parse_dates


access_points = ['wmo', 'box']
Expand Down
11 changes: 9 additions & 2 deletions argopy/data_fetchers/erddap_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@
from argopy.utilities import load_dict, mapp_dict, isconnected, format_oneline
from argopy.stores import httpstore

# Dirty fix before https://github.com/ioos/erddapy/issues/140
if isconnected():

# Load erddapy according to available version (breaking changes in v0.8.0)
try:
from erddapy import ERDDAP
from erddapy.utilities import parse_dates, quote_string_constraints
except:
# >= v0.8.0
from erddapy.erddapy import ERDDAP
from erddapy.erddapy import _quote_string_constraints as quote_string_constraints
from erddapy.erddapy import parse_dates


access_points = ['wmo', 'box']
exit_formats = ['xarray', 'dataframe']
Expand Down
16 changes: 3 additions & 13 deletions argopy/data_fetchers/localftp_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,12 @@

"""
import os
from glob import glob
import numpy as np
import pandas as pd
import xarray as xr
from abc import ABC, abstractmethod
import warnings
import getpass

import multiprocessing as mp
import distributed

from .proto import ArgoDataFetcherProto
from argopy.errors import NetCDF4FileNotFoundError
from argopy.utilities import list_standard_variables, load_dict, mapp_dict, check_localftp, format_oneline
from argopy.utilities import load_dict, mapp_dict, check_localftp, format_oneline
from argopy.options import OPTIONS
from argopy.stores import filestore, indexstore, indexfilter_wmo, indexfilter_box
from argopy.stores import indexstore, indexfilter_wmo, indexfilter_box

access_points = ['wmo', 'box']
exit_formats = ['xarray', 'dataframe']
Expand Down Expand Up @@ -180,7 +170,7 @@ def init(self, box: list = [-180, 180, -90, 90, '1900-01-01', '2100-12-31']):
The box domain to load all Argo data for:
box = [lon_min, lon_max, lat_min, lat_max, pres_min, pres_max, datim_min, datim_max]
"""
if len(box) != 4 and len(box) !=6 :
if len(box) != 4 and len(box) != 6:
raise ValueError('Box must be 4 or 6 length')
self.BOX = box
self.fcls = indexfilter_box(self.BOX)
2 changes: 2 additions & 0 deletions argopy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
A bunch of custom errors used in argopy.
"""


class DataNotFound(ValueError):
""" Raise when a data selection returns nothing """
pass


class FtpPathError(ValueError):
""" Raise when the ftp path is not appropriate """
pass
Expand Down
2 changes: 1 addition & 1 deletion argopy/plotters.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def open_dashboard(wmo=None, cyc=None, width="100%", height=1000, url=None, type
url = "https://fleetmonitoring.euro-argo.eu"
else:
url = "https://fleetmonitoring.euro-argo.eu/float/{}".format(str(wmo))
elif type == 'coriolis': # Open Coriolis dashboard
elif type == 'coriolis': # Open Coriolis dashboard
if wmo is not None:
url = ("https://co-insitucharts.ifremer.fr/platform/{}/charts").format(str(wmo))

Expand Down
32 changes: 28 additions & 4 deletions argopy/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,34 @@ def filter_data_mode(self, keep_error: bool = True, errors: str = 'raise'):
#########
# Sub-functions
#########
def safe_where_eq(xds, key, value):
# xds.where(xds[key] == value, drop=True) is not safe to empty time variables, cf issue #64
try:
return xds.where(xds[key] == value, drop=True)
except ValueError as v:
if v.args[0] == ("zero-size array to reduction operation "
"minimum which has no identity"):
# A bug in xarray will cause a ValueError if trying to
# decode the times in a NetCDF file with length 0.
# See:
# https://github.com/pydata/xarray/issues/1329
# https://github.com/euroargodev/argopy/issues/64
# Here, we just need to return an empty array
TIME = xds['TIME']
xds = xds.drop_vars('TIME')
xds = xds.where(xds[key] == value, drop=True)
xds['TIME'] = xr.DataArray(np.arange(len(xds['N_POINTS'])), dims='N_POINTS',
attrs=TIME.attrs).astype(np.datetime64)
xds = xds.set_coords('TIME')
return xds

def ds_split_datamode(xds):
""" Create one dataset for each of the data_mode

Split full dataset into 3 datasets
"""
# Real-time:
argo_r = xds.where(xds['DATA_MODE'] == 'R', drop=True)
argo_r = safe_where_eq(xds, 'DATA_MODE', 'R')
for v in plist:
vname = v.upper() + '_ADJUSTED'
if vname in argo_r:
Expand All @@ -232,7 +253,7 @@ def ds_split_datamode(xds):
if vname in argo_r:
argo_r = argo_r.drop_vars(vname)
# Real-time adjusted:
argo_a = xds.where(xds['DATA_MODE'] == 'A', drop=True)
argo_a = safe_where_eq(xds, 'DATA_MODE', 'A')
for v in plist:
vname = v.upper()
if vname in argo_a:
Expand All @@ -241,7 +262,8 @@ def ds_split_datamode(xds):
if vname in argo_a:
argo_a = argo_a.drop_vars(vname)
# Delayed mode:
argo_d = xds.where(xds['DATA_MODE'] == 'D', drop=True)
argo_d = safe_where_eq(xds, 'DATA_MODE', 'D')

return argo_r, argo_a, argo_d

def fill_adjusted_nan(ds, vname):
Expand Down Expand Up @@ -295,7 +317,9 @@ def new_arrays(argo_r, argo_a, argo_d, vname):
return ds

# Define variables to filter:
possible_list = ['PRES', 'TEMP', 'PSAL',
possible_list = ['PRES',
'TEMP',
'PSAL',
'DOXY',
'CHLA',
'BBP532',
Expand Down
Loading