Skip to content

Commit

Permalink
Merge pull request #241 from ecmwf/develop
Browse files Browse the repository at this point in the history
new_version
  • Loading branch information
mathleur authored Nov 5, 2024
2 parents 9edfbca + 1ab18fe commit 9d68476
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 16 deletions.
8 changes: 5 additions & 3 deletions polytope_feature/datacube/backends/datacube.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,19 @@ def remap_path(self, path: DatacubePath):
return path

@staticmethod
def create(datacube, config={}, axis_options={}, compressed_axes_options=[], alternative_axes=[]):
def create(datacube, config={}, axis_options={}, compressed_axes_options=[], alternative_axes=[], context=None):
# TODO: get the configs as None for pre-determined value and change them to empty dictionary inside the function
if type(datacube).__name__ == "DataArray":
from .xarray import XArrayDatacube

xadatacube = XArrayDatacube(datacube, axis_options, compressed_axes_options)
xadatacube = XArrayDatacube(datacube, axis_options, compressed_axes_options, context)
return xadatacube
if type(datacube).__name__ == "GribJump":
from .fdb import FDBDatacube

fdbdatacube = FDBDatacube(datacube, config, axis_options, compressed_axes_options, alternative_axes)
fdbdatacube = FDBDatacube(
datacube, config, axis_options, compressed_axes_options, alternative_axes, context
)
return fdbdatacube

def check_branching_axes(self, request):
Expand Down
11 changes: 9 additions & 2 deletions polytope_feature/datacube/backends/fdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
from copy import deepcopy
from itertools import product

from ...utility.exceptions import BadRequestError
from ...utility.geometry import nearest_pt
from .datacube import Datacube, TensorIndexTree


class FDBDatacube(Datacube):
def __init__(self, gj, config=None, axis_options=None, compressed_axes_options=[], alternative_axes=[]):
def __init__(
self, gj, config=None, axis_options=None, compressed_axes_options=[], alternative_axes=[], context=None
):
if config is None:
config = {}
if context is None:
context = {}

super().__init__(axis_options, compressed_axes_options)

Expand All @@ -24,7 +29,9 @@ def __init__(self, gj, config=None, axis_options=None, compressed_axes_options=[

self.gj = gj
if len(alternative_axes) == 0:
self.fdb_coordinates = self.gj.axes(partial_request)
self.fdb_coordinates = self.gj.axes(partial_request, ctx=context)
if len(self.fdb_coordinates) == 0:
raise BadRequestError(partial_request)
else:
self.fdb_coordinates = {}
for axis_config in alternative_axes:
Expand Down
2 changes: 1 addition & 1 deletion polytope_feature/datacube/backends/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class XArrayDatacube(Datacube):
"""Xarray arrays are labelled, axes can be defined as strings or integers (e.g. "time" or 0)."""

def __init__(self, dataarray: xr.DataArray, axis_options=None, compressed_axes_options=[]):
def __init__(self, dataarray: xr.DataArray, axis_options=None, compressed_axes_options=[], context=None):
super().__init__(axis_options, compressed_axes_options)
if axis_options is None:
axis_options = {}
Expand Down
20 changes: 11 additions & 9 deletions polytope_feature/polytope.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def __repr__(self):


class Polytope:
def __init__(self, datacube, engine=None, options=None):
def __init__(self, datacube, engine=None, options=None, context=None):
from .datacube import Datacube
from .engine import Engine

Expand All @@ -48,22 +48,24 @@ def __init__(self, datacube, engine=None, options=None):

axis_options, compressed_axes_options, config, alternative_axes = PolytopeOptions.get_polytope_options(options)

self.datacube = Datacube.create(datacube, config, axis_options, compressed_axes_options, alternative_axes)
self.context = context

self.datacube = Datacube.create(
datacube, config, axis_options, compressed_axes_options, alternative_axes, self.context
)
self.engine = engine if engine is not None else Engine.default()
self.time = 0

def slice(self, polytopes: List[ConvexPolytope]):
"""Low-level API which takes a polytope geometry object and uses it to slice the datacube"""
return self.engine.extract(self.datacube, polytopes)

def retrieve(self, request: Request, method="standard", context=None):
def retrieve(self, request: Request, method="standard"):
"""Higher-level API which takes a request and uses it to slice the datacube"""
if context is None:
context = {}
logging.info("Starting request for %s ", context)
logging.info("Starting request for %s ", self.context)
self.datacube.check_branching_axes(request)
request_tree = self.engine.extract(self.datacube, request.polytopes())
logging.info("Created request tree for %s ", context)
self.datacube.get(request_tree, context)
logging.info("Retrieved data for %s ", context)
logging.info("Created request tree for %s ", self.context)
self.datacube.get(request_tree, self.context)
logging.info("Retrieved data for %s ", self.context)
return request_tree
6 changes: 6 additions & 0 deletions polytope_feature/utility/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ class PolytopeError(Exception):
pass


class BadRequestError(PolytopeError):
def __init__(self, pre_path):
self.pre_path = pre_path
self.message = f"No data for {pre_path} is available on the FDB."


class AxisOverdefinedError(PolytopeError, KeyError):
def __init__(self, axis):
self.axis = axis
Expand Down
2 changes: 1 addition & 1 deletion polytope_feature/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.0.10"
__version__ = "1.0.11"
65 changes: 65 additions & 0 deletions tests/test_bad_request_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import pytest

from polytope_feature.engine.hullslicer import HullSlicer
from polytope_feature.polytope import Polytope
from polytope_feature.utility.exceptions import BadRequestError

# import geopandas as gpd
# import matplotlib.pyplot as plt


class TestSlicingFDBDatacube:
def setup_method(self, method):
# Create a dataarray with 3 labelled axes using different index types
self.options = {
"axis_config": [
{"axis_name": "step", "transformations": [{"name": "type_change", "type": "int"}]},
{"axis_name": "number", "transformations": [{"name": "type_change", "type": "int"}]},
{
"axis_name": "date",
"transformations": [{"name": "merge", "other_axis": "time", "linkers": ["T", "00"]}],
},
{
"axis_name": "values",
"transformations": [
{"name": "mapper", "type": "octahedral", "resolution": 1280, "axes": ["latitude", "longitude"]}
],
},
{"axis_name": "latitude", "transformations": [{"name": "reverse", "is_reverse": True}]},
{"axis_name": "longitude", "transformations": [{"name": "cyclic", "range": [0, 360]}]},
],
"compressed_axes_config": [
"longitude",
"latitude",
"levtype",
"step",
"date",
"domain",
"expver",
"param",
"class",
"stream",
"type",
],
"pre_path": {
"class": "od",
"expver": "0001",
"levtype": "sfc",
"stream": "oper",
"date": "20230621T120000",
},
}

# Testing different shapes
@pytest.mark.fdb
def test_fdb_datacube(self):
import pygribjump as gj

with pytest.raises(BadRequestError):
self.fdbdatacube = gj.GribJump()
self.slicer = HullSlicer()
self.API = Polytope(
datacube=self.fdbdatacube,
engine=self.slicer,
options=self.options,
)

0 comments on commit 9d68476

Please sign in to comment.