Skip to content

Commit

Permalink
fix cyclic import
Browse files Browse the repository at this point in the history
  • Loading branch information
mathleur authored and jameshawkes committed Aug 1, 2023
1 parent ca87650 commit 6bdd3cd
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 47 deletions.
2 changes: 1 addition & 1 deletion examples/4D_flight_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setup_method(self):
ds = data.from_source("file", "./examples/data/temp_model_levels.grib")
array = ds.to_xarray()
array = array.isel(time=0).t
axis_options = {"longitude": {"Cyclic": [0, 360.0]}}
axis_options = {"longitude": {"cyclic": [0, 360.0]}}
self.xarraydatacube = XArrayDatacube(array)
for dim in array.dims:
array = array.sortby(dim)
Expand Down
2 changes: 1 addition & 1 deletion examples/country_slicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setup_method(self, method):
ds = data.from_source("file", "./examples/data/output8.grib")
array = ds.to_xarray()
array = array.isel(surface=0).isel(step=0).isel(number=0).isel(time=0).t2m
axis_options = {"longitude": {"Cyclic": [0, 360.0]}}
axis_options = {"longitude": {"cyclic": [0, 360.0]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=axis_options)
Expand Down
2 changes: 1 addition & 1 deletion examples/cyclic_route_around_earth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def setup_method(self, method):
ds = data.from_source("file", "./examples/data/output8.grib")
array = ds.to_xarray()
array = array.isel(surface=0).isel(step=0).isel(number=0).isel(time=0).t2m
axis_options = {"longitude": {"Cyclic": [0, 360.0]}}
axis_options = {"longitude": {"cyclic": [0, 360.0]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=axis_options)
Expand Down
2 changes: 1 addition & 1 deletion examples/slicing_all_ecmwf_countries.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setup_method(self, method):
ds = data.from_source("file", "./examples/data/output8.grib")
array = ds.to_xarray()
array = array.isel(surface=0).isel(step=0).isel(number=0).isel(time=0).t2m
axis_options = {"longitude": {"Cyclic": [0, 360.0]}}
axis_options = {"longitude": {"cyclic": [0, 360.0]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=axis_options)
Expand Down
2 changes: 1 addition & 1 deletion examples/wind_farms.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def setup_method(self):
array = ds.to_xarray()
array = array.isel(time=0).isel(surface=0).isel(number=0).u10
self.array = array
axis_options = {"longitude": {"Cyclic": [0, 360.0]}}
axis_options = {"longitude": {"cyclic": [0, 360.0]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=axis_options)
Expand Down
10 changes: 10 additions & 0 deletions polytope/datacube/datacube.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,13 @@ def create(datacube, axis_options: dict):

xadatacube = XArrayDatacube(datacube, axis_options=axis_options)
return xadatacube


def configure_datacube_axis(options, name, values, datacube):
if options == {}:
DatacubeAxis.create_standard(name, values, datacube)
if "mapper" in options.keys():
from .datacube_mappers import DatacubeMapper
DatacubeMapper.create_mapper(options, name, datacube)
if "cyclic" in options.keys():
DatacubeAxis.create_cyclic(options, name, values, datacube)
43 changes: 9 additions & 34 deletions polytope/datacube/datacube_axis.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import sys
from abc import ABC, abstractmethod, abstractproperty
from copy import deepcopy
from importlib import import_module
from typing import Any, List

import numpy as np
import pandas as pd

from .datacube_mappers import _type_to_datacube_mapper_lookup


class DatacubeAxis(ABC):
@abstractproperty
Expand Down Expand Up @@ -59,14 +56,14 @@ def to_cyclic_value(self, value: Any) -> Any:
def offset(self, value: Any) -> int:
pass

@staticmethod
def create_axis(options, name, values, datacube):
if options == {}:
DatacubeAxis.create_standard(name, values, datacube)
if "mapper" in options.keys():
DatacubeAxis.create_mapper(options, name, datacube)
if "Cyclic" in options.keys():
DatacubeAxis.create_cyclic(options, name, values, datacube)
# @staticmethod
# def create_axis(options, name, values, datacube):
# if options == {}:
# DatacubeAxis.create_standard(name, values, datacube)
# if "mapper" in options.keys():
# DatacubeAxis.create_mapper(options, name, datacube)
# if "Cyclic" in options.keys():
# DatacubeAxis.create_cyclic(options, name, values, datacube)

@staticmethod
def create_cyclic(options, name, values, datacube):
Expand All @@ -76,7 +73,7 @@ def create_cyclic(options, name, values, datacube):
cyclic_axis_type = deepcopy(getattr(sys.modules["polytope.datacube.datacube_axis"], axes_type_str)())
datacube._axes[name] = cyclic_axis_type
datacube._axes[name].name = name
datacube._axes[name].range = options["Cyclic"]
datacube._axes[name].range = options["cyclic"]
datacube.axis_counter += 1

@staticmethod
Expand All @@ -91,28 +88,6 @@ def check_axis_type(name, values):
if values.dtype.type not in _type_to_axis_lookup:
raise ValueError(f"Could not create a mapper for index type {values.dtype.type} for axis {name}")

@staticmethod
def create_mapper(options, name, datacube):
grid_mapping_options = options["mapper"]
grid_type = grid_mapping_options["type"]
grid_resolution = grid_mapping_options["resolution"]
grid_axes = grid_mapping_options["axes"]
map_type = _type_to_datacube_mapper_lookup[grid_type]
module = import_module("polytope.datacube.datacube_mappers")
constructor = getattr(module, map_type)
datacube.grid_mapper = constructor(name, grid_axes, grid_resolution)
# Once we have created mapper, create axis for the mapped axes
for i in range(len(grid_axes)):
axis_name = grid_axes[i]
new_axis_options = datacube.axis_options.get(axis_name, {})
if i == 0:
values = np.array(datacube.grid_mapper.first_axis_vals())
DatacubeAxis.create_axis(new_axis_options, axis_name, values, datacube)
if i == 1:
# the values[0] will be a value on the first axis
values = np.array(datacube.grid_mapper.second_axis_vals(values[0]))
DatacubeAxis.create_axis(new_axis_options, axis_name, values, datacube)


class IntDatacubeAxis(DatacubeAxis):
name = None
Expand Down
27 changes: 27 additions & 0 deletions polytope/datacube/datacube_mappers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import math
from abc import ABC, abstractmethod
from importlib import import_module

import numpy as np

from .datacube import configure_datacube_axis


class DatacubeMapper(ABC):
Expand All @@ -24,6 +29,28 @@ def map_second_axis(self, first_val, lower, upper):
def unmap(self):
pass

@staticmethod
def create_mapper(options, name, datacube):
grid_mapping_options = options["mapper"]
grid_type = grid_mapping_options["type"]
grid_resolution = grid_mapping_options["resolution"]
grid_axes = grid_mapping_options["axes"]
map_type = _type_to_datacube_mapper_lookup[grid_type]
module = import_module("polytope.datacube.datacube_mappers")
constructor = getattr(module, map_type)
datacube.grid_mapper = constructor(name, grid_axes, grid_resolution)
# Once we have created mapper, create axis for the mapped axes
for i in range(len(grid_axes)):
axis_name = grid_axes[i]
new_axis_options = datacube.axis_options.get(axis_name, {})
if i == 0:
values = np.array(datacube.grid_mapper.first_axis_vals())
configure_datacube_axis(new_axis_options, axis_name, values, datacube)
if i == 1:
# the values[0] will be a value on the first axis
values = np.array(datacube.grid_mapper.second_axis_vals(values[0]))
configure_datacube_axis(new_axis_options, axis_name, values, datacube)


class OctahedralGridMapper(DatacubeMapper):
def __init__(self, base_axis, mapped_axes, resolution):
Expand Down
9 changes: 4 additions & 5 deletions polytope/datacube/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import xarray as xr

from ..utility.combinatorics import unique, validate_axes
from .datacube import Datacube, DatacubePath, IndexTree
from .datacube_axis import DatacubeAxis
from .datacube import Datacube, DatacubePath, IndexTree, configure_datacube_axis


class XArrayDatacube(Datacube):
Expand All @@ -22,19 +21,19 @@ def __init__(self, dataarray: xr.DataArray, axis_options={}):
if name in dataarray.dims:
self.dataarray = self.dataarray.sortby(name)
options = axis_options.get(name, {})
DatacubeAxis.create_axis(options, name, values, self)
configure_datacube_axis(options, name, values, self)
treated_axes.append(name)
self.complete_axes.append(name)
else:
if self.dataarray[name].dims == ():
options = axis_options.get(name, {})
DatacubeAxis.create_axis(options, name, values, self)
configure_datacube_axis(options, name, values, self)
treated_axes.append(name)
for name in dataarray.dims:
if name not in treated_axes:
options = axis_options.get(name, {})
val = dataarray[name].values[0]
DatacubeAxis.create_axis(options, name, val, self)
configure_datacube_axis(options, name, val, self)

def get(self, requests: IndexTree):
for r in requests.leaves:
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cyclic_axis_over_negative_vals.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def setup_method(self, method):
"long": [-0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1.0, -1.1],
},
)
options = {"long": {"Cyclic": [-1.1, -0.1]}, "level": {"Cyclic": [1, 129]}}
options = {"long": {"cyclic": [-1.1, -0.1]}, "level": {"cyclic": [1, 129]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=options)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cyclic_axis_slicer_not_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def setup_method(self, method):
"long": [-0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1.0, -1.1],
},
)
options = {"long": {"Cyclic": [-1.1, -0.1]}, "level": {"Cyclic": [1, 129]}}
options = {"long": {"cyclic": [-1.1, -0.1]}, "level": {"cyclic": [1, 129]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=options)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_cyclic_axis_slicing.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def setup_method(self, method):
"long": [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0],
},
)
options = {"long": {"Cyclic": [0, 1.0]}, "level": {"Cyclic": [1, 129]}}
options = {"long": {"cyclic": [0, 1.0]}, "level": {"cyclic": [1, 129]}}
self.xarraydatacube = XArrayDatacube(array)
self.slicer = HullSlicer()
self.API = Polytope(datacube=array, engine=self.slicer, axis_options=options)
Expand Down

0 comments on commit 6bdd3cd

Please sign in to comment.