Skip to content

Commit

Permalink
updated domain table fetch (#140)
Browse files Browse the repository at this point in the history
* updated domain table fetch

* test updates

* Update whats_new.rst

* added deprecation warning
  • Loading branch information
larsbuntemeyer authored Jul 2, 2023
1 parent 155e498 commit 80d44ef
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 111 deletions.
36 changes: 20 additions & 16 deletions cordex/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
from .utils import get_tempfile


def _locate_domain_id(domain_id, tables):
"""Locate domain_id in domain table trying different indexes."""
indexes = ["short_name", "domain_id", "CORDEX_domain"]

for i in indexes:
if domain_id in tables.reset_index()[i].values:
return (
tables.reset_index().replace(np.nan, None).set_index(i).loc[domain_id]
)

return tables.replace(np.nan, None).loc[domain_id]


def domain_names(table_name=None):
"""Returns a list of short names of all availabe Cordex domains
Expand Down Expand Up @@ -112,11 +125,12 @@ def cordex_domain(
tables = domains.table
if isinstance(tables, list):
tables = pd.concat(tables)
config = tables.replace(np.nan, None).loc[domain_id]

config = _locate_domain_id(domain_id, tables)

return create_dataset(
**config,
domain_id=domain_id,
# domain_id=domain_id,
dummy=dummy,
add_vertices=False,
attrs=attrs,
Expand Down Expand Up @@ -214,11 +228,15 @@ def create_dataset(
attrs = cv["default_global_attrs"]
elif attrs is None:
attrs = {}

if name:
attrs[cv["domain_id"]] = name
# remove inconsistencies in keyword names
if domain_id:
attrs[cv["domain_id"]] = domain_id
if cv["domain_id"] in kwargs:
attrs[cv["domain_id"]] = kwargs[cv["domain_id"]]

if pollon is None or pollat is None:
rotated = False
try:
Expand Down Expand Up @@ -424,20 +442,6 @@ def _bounds(coord, include="left"):
return xr.merge([left, right])


def bounds_coordinates(ds, coords):
"""Adds coordinate bounds as coordinates to the dataset."""
if isinstance(coords, str):
coords = (coords,)
bounds = []
for coord in coords:
lr = _bounds(ds.coords[coord])
name = ds.coords[coord].name + "_b"
bounds.append(
xr.DataArray(np.append(lr.left, lr.right[-1]), dims=name, name=name)
)
return ds.assign_coords({b.name: b for b in bounds})


def bounds(coords):
if isinstance(coords, xr.DataArray):
coords = (coords,)
Expand Down
37 changes: 8 additions & 29 deletions cordex/preprocessing/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
"""


from warnings import warn

import numpy as np
import xarray as xr

Expand Down Expand Up @@ -447,6 +449,12 @@ def get_grid_mapping(ds):
Dataarray containing the grid mapping meta data.
"""
message = (
"get_grid_mapping is deprecated, please use cf_xarray "
'accessor ds.cf["grid_mapping"] instead.'
)
warn(message, DeprecationWarning, stacklevel=2)

return ds[get_grid_mapping_varname(ds)]


Expand Down Expand Up @@ -553,35 +561,6 @@ def member_id_to_dset_id(ds_dict):
return ds_split


# def dset_ids_to_coord(ds_dict):
# """Creates a DataArray from dataset ids"""
# dset_ids = list(ds_dict.keys())
# dim = xr.DataArray(
# dset_ids, dims="dset_id", name="dset_id", coords={"dset_id": dset_ids}
# )
# return dim


# def align_time_axis(ds_dict):
# from datetime import datetime as dt

# for ds in ds_dict.values():
# # ds = ds.copy()
# ds.coords["time"] = [dt(date.year, date.month, 15) for date in ds.time.values]
# return ds_dict


# def concat_along_dset_id(ds_dict, coords="minimal", compat="override", **kwargs):
# dset_coord = dset_ids_to_coord(ds_dict)
# ds_dict = align_time_axis(ds_dict)
# ds_list = []
# for ds in ds_dict.values():
# ds = replace_rlon_rlat(ds)
# ds = replace_lon_lat(ds)
# ds_list.append(ds)
# return xr.concat(ds_list, dim=dset_coord, coords=coords, compat=compat, **kwargs)


def sort_ds_dict_by_attr(ds_dict, attr):
"""Sorts the dataset dict by a certain attribute.
Expand Down
63 changes: 31 additions & 32 deletions cordex/tables/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
from warnings import warn

import pandas as pd

from ._resources import (
from ._resources import ( # fetch_cmip6_cmor_table,
cmor_tables_inpath,
ecmwf_tables,
fetch_cmip6_cmor_table,
fetch_cordex_cmor_table,
read_cordex_domain_tables,
read_domain_table,
)

# __cmor_table_version__ = cmor_table_version
__all__ = [
"cmor_tables_inpath",
"ecmwf_tables",
"fetch_cmpi6_cmor_table",
# "fetch_cmpi6_cmor_table",
"fetch_cordex_cmor_table",
"read_cordex_domain_tables",
"read_cordex_domain_table",
"cmor_tables_inpath",
]

Expand All @@ -31,13 +28,15 @@ def tables(self):

@property
def table(self):
return pd.concat(self.tables.values())
if isinstance(self.tables, dict):
return pd.concat(self.tables.values())
return self.tables

# def __getattr__(self, table):
# return self.tables[table]


domains = read_cls(read_cordex_domain_tables)
domains = read_cls(read_domain_table)

ecmwf = read_cls(ecmwf_tables)

Expand Down Expand Up @@ -69,26 +68,26 @@ def cordex_cmor_table(table, table_dir=None):
return fetch_cordex_cmor_table(table)


def cmip6_cmor_table(table):
"""fetch a cmip6 cmor table
If required, the table will be download from github.
The tables are experimental right now and only used
for development purposes.
Parameters
----------
table: str
Name of the cmip6 table.
Returns
-------
filename : str
Filepath to the cmip6 cmor table.
"""
warn(
"CMIP6 cmor table fetching is deprecated and will be removed in the future. Please use cordex_cmor_table instead.",
DeprecationWarning,
stacklevel=2,
)
return fetch_cmip6_cmor_table(table)
# def cmip6_cmor_table(table):
# """fetch a cmip6 cmor table
#
# If required, the table will be download from github.
# The tables are experimental right now and only used
# for development purposes.
#
# Parameters
# ----------
# table: str
# Name of the cmip6 table.
#
# Returns
# -------
# filename : str
# Filepath to the cmip6 cmor table.
# """
# warn(
# "CMIP6 cmor table fetching is deprecated and will be removed in the future. Please use cordex_cmor_table instead.",
# DeprecationWarning,
# stacklevel=2,
# )
# return fetch_cmip6_cmor_table(table)
25 changes: 10 additions & 15 deletions cordex/tables/_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@ def _construct_cache_dir(path):
# Use the default cache folder for the OS
path=cache_url, # pooch.os_cache("cordex"),
# The remote data is on Github
base_url=base_url + "domains/",
base_url="https://raw.githubusercontent.com/WCRP-CORDEX/domain-tables/main/",
registry={
"cordex.csv": None,
"cordex-high-res.csv": None,
"cordex-fps.csv": None,
"cordex-core.csv": None,
"cordex-regular.csv": None,
"rotated-latitude-longitude.csv": None,
},
)

Expand Down Expand Up @@ -70,10 +66,10 @@ def fetch_cordex_cmor_table(table):
)


def fetch_cmip6_cmor_table(table):
return retrieve_cmor_table(
table, url="https://github.com/PCMDI/cmip6-cmor-tables/raw/master/Tables"
)
# def fetch_cmip6_cmor_table(table):
# return retrieve_cmor_table(
# table, url="https://github.com/PCMDI/cmip6-cmor-tables/raw/master/Tables"
# )


def retrieve_cmor_table(table, url):
Expand Down Expand Up @@ -106,12 +102,11 @@ def read_region_table(name):
return read_remote_table(name, resource=REGION_RESOURCE, index_col="area")


def read_cordex_domain_tables():
def read_domain_table():
resource = DOMAIN_RESOURCE
return {
table.split(".")[0]: read_remote_table(table, resource, index_col="short_name")
for table in resource.registry.keys()
}
return read_remote_table(
"rotated-latitude-longitude.csv", resource, index_col="short_name"
)


def region_tables():
Expand Down
8 changes: 4 additions & 4 deletions docs/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ What's New
v0.6.0 (Unreleased)
-------------------

New Features
~~~~~~~~~~~~
Internal Changes
~~~~~~~~~~~~~~~~

- Support for upcoming CORDEX-CMIP6 vocabulary. This includes the new keyword `mip_era` in :py:meth:`cmor.cordex_domain` and
:py:meth:`cmor.create_dataset` (:pull:`129`).
- Support for upcoming CORDEX-CMIP6 vocabulary. This includes the new keyword `mip_era` in :py:meth:`cmor.cordex_domain` and :py:meth:`cmor.create_dataset` (:pull:`129`).
- Updated domain table fetching. There is now only one table that contains all domain definitions which is now located in the `WCRP CORDEX github table repository <https://github.com/WCRP-CORDEX/domain-tables/blob/main/rotated-latitude-longitude.csv>`_ (:pull:`140`). This table allows for selection by different naming conventions for the domain identifier, e.g., ``EUR-12`` is equivilant to ``EUR-11``, etc.

Breaking Changes
~~~~~~~~~~~~~~~~
Expand Down
29 changes: 14 additions & 15 deletions tests/test_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@

import cordex as cx


@pytest.mark.parametrize(
"table",
[
"CMIP6_Amon",
"CMIP6_day",
"CMIP6_E1hr",
"CMIP6_E3hr",
"CMIP6_coordinate",
"CMIP6_fx",
"CMIP6_grids",
],
)
def test_download_cmip6_cmor_tables(table):
cx.tables.cmip6_cmor_table(table)
# @pytest.mark.parametrize(
# "table",
# [
# "CMIP6_Amon",
# "CMIP6_day",
# "CMIP6_E1hr",
# "CMIP6_E3hr",
# "CMIP6_coordinate",
# "CMIP6_fx",
# "CMIP6_grids",
# ],
# )
# def test_download_cmip6_cmor_tables(table):
# cx.tables.cmip6_cmor_table(table)


@pytest.mark.parametrize("table", ["CORDEX_CV", "CORDEX_remo_example"])
Expand Down

0 comments on commit 80d44ef

Please sign in to comment.