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

Feature/irregular grid mapper #112

Open
wants to merge 47 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
db21278
add first quadtree construction
mathleur Jan 2, 2024
f9ca22c
remove unnecessary code
mathleur Jan 2, 2024
7fd6cb2
add first quad tree construction in slicer
mathleur Jan 2, 2024
a6b7fe1
start query polygon function
mathleur Jan 3, 2024
96a2467
add polygon slicing
mathleur Jan 4, 2024
19ca294
write all methods for quadtree slicer
mathleur Jan 4, 2024
e2fa53b
quadtree slicer tests
mathleur Jan 5, 2024
33e6e97
clean up
mathleur Jan 5, 2024
5ffd68a
refactor
mathleur Jan 8, 2024
a941be2
finish quad tree extract function
mathleur Jan 8, 2024
badae88
first performance test for quadtree
mathleur Jan 8, 2024
2dda6df
clean up
mathleur Jan 8, 2024
85b9b21
fix MAX number of nodes in QuadTree
mathleur Jan 9, 2024
a69cad0
optimise quadtree slicer to not slice quadrants when the polygon is a…
mathleur Jan 10, 2024
47024c3
clean up
mathleur Jan 10, 2024
b152235
Merge branch 'develop' of github.com:ecmwf/polytope into feature/quad…
mathleur Jan 10, 2024
b860b0d
pull develop and fix tests
mathleur Jan 10, 2024
c2e9df5
add index in quad node
mathleur Jan 10, 2024
97cabac
add index in quadtree construction from point cloud
mathleur Jan 10, 2024
5fedb73
extract in quadtree slicer using point indices instead of lat/lon
mathleur Jan 10, 2024
811e5f9
reformat
mathleur Jan 10, 2024
b571028
start creating a higher-level extract function to allow for different…
mathleur Jan 15, 2024
7ce4957
add higher level extract inside the Polytope class
mathleur Jan 15, 2024
dcc7399
make new polytope class extract work with old tests
mathleur Jan 16, 2024
be4ebdb
add find_point_cloud to xarray datacube
mathleur Jan 16, 2024
d33fa74
quadtree slicer create lat/lon in index tree and stashes the point in…
mathleur Jan 17, 2024
e967f1a
merge mappings on separate files branch
mathleur Jan 17, 2024
c356e70
add irregular grid mapper support for xarray backend
mathleur Jan 17, 2024
a959b71
make first test with irregular grid for xarray backend work
mathleur Jan 19, 2024
d0dd2e0
make irregular grid work with fdb backend
mathleur Jan 22, 2024
8ba1cbf
fix polytope extract test with xarray backend and irregular mapper
mathleur Jan 23, 2024
a261ea5
fix polytope extract test with xarray backend and irregular mapper
mathleur Jan 23, 2024
8b76621
pull develop
mathleur Jan 25, 2024
be3e74b
fix edge case
mathleur Feb 22, 2024
e4334c9
fix edge cases tests
mathleur Feb 22, 2024
0acb8dc
merge with develop
mathleur Feb 23, 2024
10886c7
clean up
mathleur Feb 23, 2024
b0c20bd
fix flake8
mathleur Feb 23, 2024
4d49503
mark tests using gribjump
mathleur Feb 23, 2024
ccd4498
fix missing gribjump tests
mathleur Feb 23, 2024
04a8a74
fix missing gribjump tests
mathleur Feb 23, 2024
9fb93c9
remove unnecessary file
mathleur Mar 15, 2024
d201087
add ORCA grid example
mathleur Mar 20, 2024
bc9596a
merge develop
mathleur Mar 20, 2024
74702c7
Merge pull request #120 from ecmwf/feature/irregular_grid_merged_develop
mathleur Mar 20, 2024
12b0eba
black and isort
mathleur Mar 20, 2024
85e1741
timings for irregular grid
mathleur Mar 21, 2024
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
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ site
*.grib
*.gif
*.html
*.req
.mypy_cache
example_eo
example_mri
.mypy_cache
*.req
polytope_python.egg-info
10 changes: 8 additions & 2 deletions polytope/datacube/backends/datacube.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,17 @@ def remap_path(self, path: DatacubePath):
return path

@staticmethod
def create(datacube, axis_options: dict, datacube_options={}):
def create(datacube, axis_options: dict, datacube_options={}, point_cloud_options=None):
if isinstance(datacube, (xr.core.dataarray.DataArray, xr.core.dataset.Dataset)):
from .xarray import XArrayDatacube

xadatacube = XArrayDatacube(datacube, axis_options, datacube_options)
xadatacube = XArrayDatacube(
datacube, axis_options, datacube_options, point_cloud_options=point_cloud_options
)
return xadatacube
else:
return datacube

@abstractmethod
def find_point_cloud(self):
pass
10 changes: 9 additions & 1 deletion polytope/datacube/backends/fdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


class FDBDatacube(Datacube):
def __init__(self, config=None, axis_options=None, datacube_options=None):
def __init__(self, config=None, axis_options=None, datacube_options=None, point_cloud_options=None):
if config is None:
config = {}

Expand All @@ -17,6 +17,7 @@ def __init__(self, config=None, axis_options=None, datacube_options=None):
logging.info("Created an FDB datacube with options: " + str(axis_options))

self.unwanted_path = {}
self.has_point_cloud = point_cloud_options # NOTE: here, will be True/False

partial_request = config
# Find values in the level 3 FDB datacube
Expand All @@ -43,6 +44,11 @@ def __init__(self, config=None, axis_options=None, datacube_options=None):

logging.info("Polytope created axes for: " + str(self._axes.keys()))

def find_point_cloud(self):
# TODO: somehow, find the point cloud of irregular grid if it exists
if self.has_point_cloud:
return self.has_point_cloud

def get(self, requests: IndexTree):
fdb_requests = []
fdb_requests_decoding_info = []
Expand Down Expand Up @@ -161,13 +167,15 @@ def get_2nd_last_values(self, requests, leaf_path=None):

leaf_path_copy = deepcopy(leaf_path)
leaf_path_copy.pop("values")
leaf_path_copy.pop("result")
return (leaf_path_copy, range_lengths, current_start_idxs, fdb_node_ranges, lat_length)

def get_last_layer_before_leaf(self, requests, leaf_path, range_l, current_idx, fdb_range_n):
i = 0
for c in requests.children:
# now c are the leaves of the initial tree
key_value_path = {c.axis.name: c.value}
leaf_path["result"] = c.result
ax = c.axis
(key_value_path, leaf_path, self.unwanted_path) = ax.unmap_path_key(
key_value_path, leaf_path, self.unwanted_path
Expand Down
3 changes: 3 additions & 0 deletions polytope/datacube/backends/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,6 @@ def ax_vals(self, name):

def _find_indexes_between(self, axis, indexes, low, up):
pass

def find_point_cloud(self):
pass
25 changes: 15 additions & 10 deletions polytope/datacube/backends/xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
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, datacube_options=None):
def __init__(self, dataarray: xr.DataArray, axis_options=None, datacube_options=None, point_cloud_options=None):
super().__init__(axis_options, datacube_options)
self.dataarray = dataarray
self.has_point_cloud = point_cloud_options

for name, values in dataarray.coords.variables.items():
if name in dataarray.dims:
Expand All @@ -37,24 +38,28 @@ def __init__(self, dataarray: xr.DataArray, axis_options=None, datacube_options=
val = self._axes[name].type
self._check_and_add_axes(options, name, val)

def find_point_cloud(self):
# TODO: somehow, find the point cloud of irregular grid if it exists
if self.has_point_cloud:
return self.has_point_cloud

def get(self, requests: IndexTree):
for r in requests.leaves:
path = r.flatten()
if len(path.items()) == self.axis_counter:
path = r.flatten_with_result()
if len(path.items()) == self.axis_counter + 1:
# first, find the grid mapper transform
unmapped_path = {}
path_copy = deepcopy(path)
for key in path_copy:
axis = self._axes[key]
key_value_path = {key: path_copy[key]}
# (path, unmapped_path) = axis.unmap_to_datacube(path, unmapped_path)
(key_value_path, path, unmapped_path) = axis.unmap_path_key(key_value_path, path, unmapped_path)
if key != "result":
axis = self._axes[key]
key_value_path = {key: path_copy[key]}
(key_value_path, path, unmapped_path) = axis.unmap_path_key(key_value_path, path, unmapped_path)
path.update(key_value_path)
path.update(unmapped_path)

unmapped_path = {}
self.refit_path(path, unmapped_path, path)

subxarray = self.dataarray.sel(path, method="nearest")
subxarray = subxarray.sel(unmapped_path)
value = subxarray.item()
Expand Down Expand Up @@ -83,9 +88,9 @@ def refit_path(self, path_copy, unmapped_path, path):
for key in path.keys():
if key not in self.dataarray.dims:
path_copy.pop(key)
if key not in self.dataarray.coords.dtypes:
elif key not in self.dataarray.coords.dtypes:
unmapped_path.update({key: path[key]})
path_copy.pop(key)
path_copy.pop(key, None)
for key in self.dataarray.coords.dtypes:
key_dtype = self.dataarray.coords.dtypes[key]
if key_dtype.type is np.str_ and key in path.keys():
Expand Down
28 changes: 21 additions & 7 deletions polytope/datacube/index_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ def copy_children_from_other(self, other):
c.copy_children_from_other(o)
return

def pprint_2(self, level=0):
if self.axis.name == "root":
print("\n")
print("\t" * level + "\u21b3" + str(self))
for child in self.children:
child.pprint_2(level + 1)

def _collect_leaf_nodes_old(self, leaves):
if len(self.children) == 0:
leaves.append(self)
Expand Down Expand Up @@ -191,6 +184,13 @@ def pprint(self, level=0):
if len(self.children) == 0:
logging.debug("\t" * (level + 1) + "\u21b3" + str(self.result))

def pprint_2(self, level=0):
if self.axis.name == "root":
print("\n")
print("\t" * level + "\u21b3" + str(self))
for child in self.children:
child.pprint_2(level + 1)

def remove_branch(self):
if not self.is_root():
old_parent = self._parent
Expand All @@ -204,6 +204,20 @@ def flatten(self):
ancestors = self.get_ancestors()
for ancestor in ancestors:
path[ancestor.axis.name] = ancestor.value
# add the result to the path
# NOTE: this is useful for the quadtree engine when we stash the point idx in the result
# if len(ancestors) != 0:
# if ancestors[len(ancestors)-1].result is not None:
# path["result"] = ancestors[len(ancestors)-1].result
return path

def flatten_with_result(self):
path = DatacubePath()
ancestors = self.get_ancestors()
for ancestor in ancestors:
path[ancestor.axis.name] = ancestor.value
if len(ancestors) != 0:
path["result"] = ancestors[-1].result
return path

def flatten_with_ancestors(self):
Expand Down
Loading
Loading