polytope-python 1.0.35__tar.gz → 1.0.36__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {polytope_python-1.0.35/polytope_python.egg-info → polytope_python-1.0.36}/PKG-INFO +1 -1
  2. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/backends/fdb.py +13 -8
  3. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/engine/hullslicer.py +16 -5
  4. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/polytope.py +7 -0
  5. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/shapes.py +47 -8
  6. polytope_python-1.0.36/polytope_feature/version.py +1 -0
  7. {polytope_python-1.0.35 → polytope_python-1.0.36/polytope_python.egg-info}/PKG-INFO +1 -1
  8. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_python.egg-info/SOURCES.txt +1 -0
  9. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_point_shape.py +9 -3
  10. polytope_python-1.0.36/tests/test_point_union.py +148 -0
  11. polytope_python-1.0.35/polytope_feature/version.py +0 -1
  12. {polytope_python-1.0.35 → polytope_python-1.0.36}/LICENSE +0 -0
  13. {polytope_python-1.0.35 → polytope_python-1.0.36}/MANIFEST.in +0 -0
  14. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/__init__.py +0 -0
  15. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/__init__.py +0 -0
  16. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/backends/__init__.py +0 -0
  17. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/backends/datacube.py +0 -0
  18. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/backends/mock.py +0 -0
  19. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/backends/xarray.py +0 -0
  20. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/datacube_axis.py +0 -0
  21. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/index_tree_pb2.py +0 -0
  22. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/tensor_index_tree.py +0 -0
  23. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/__init__.py +0 -0
  24. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_cyclic/__init__.py +0 -0
  25. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_cyclic/datacube_cyclic.py +0 -0
  26. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/__init__.py +0 -0
  27. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/datacube_mappers.py +0 -0
  28. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/__init__.py +0 -0
  29. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/healpix.py +0 -0
  30. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/healpix_nested.py +0 -0
  31. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/local_regular.py +0 -0
  32. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/octahedral.py +0 -0
  33. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/reduced_gaussian.py +0 -0
  34. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/reduced_ll.py +0 -0
  35. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_mappers/mapper_types/regular.py +0 -0
  36. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_merger/__init__.py +0 -0
  37. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_merger/datacube_merger.py +0 -0
  38. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_reverse/__init__.py +0 -0
  39. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_reverse/datacube_reverse.py +0 -0
  40. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_transformations.py +0 -0
  41. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_type_change/__init__.py +0 -0
  42. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/transformations/datacube_type_change/datacube_type_change.py +0 -0
  43. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/datacube/tree_encoding.py +0 -0
  44. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/engine/__init__.py +0 -0
  45. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/engine/engine.py +0 -0
  46. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/options.py +0 -0
  47. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/__init__.py +0 -0
  48. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/combinatorics.py +0 -0
  49. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/exceptions.py +0 -0
  50. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/geometry.py +0 -0
  51. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/list_tools.py +0 -0
  52. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_feature/utility/profiling.py +0 -0
  53. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_python.egg-info/dependency_links.txt +0 -0
  54. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_python.egg-info/not-zip-safe +0 -0
  55. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_python.egg-info/requires.txt +0 -0
  56. {polytope_python-1.0.35 → polytope_python-1.0.36}/polytope_python.egg-info/top_level.txt +0 -0
  57. {polytope_python-1.0.35 → polytope_python-1.0.36}/pyproject.toml +0 -0
  58. {polytope_python-1.0.35 → polytope_python-1.0.36}/requirements.txt +0 -0
  59. {polytope_python-1.0.35 → polytope_python-1.0.36}/setup.cfg +0 -0
  60. {polytope_python-1.0.35 → polytope_python-1.0.36}/setup.py +0 -0
  61. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_axis_mappers.py +0 -0
  62. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_bad_request_error.py +0 -0
  63. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_combinatorics.py +0 -0
  64. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_axis_over_negative_vals.py +0 -0
  65. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_axis_slicer_not_0.py +0 -0
  66. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_axis_slicing.py +0 -0
  67. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_nearest.py +0 -0
  68. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_simple.py +0 -0
  69. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_cyclic_snapping.py +0 -0
  70. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_datacube_axes_init.py +0 -0
  71. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_datacube_mock.py +0 -0
  72. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_datacube_xarray.py +0 -0
  73. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_date_time_unmerged.py +0 -0
  74. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_ecmwf_oper_data_fdb.py +0 -0
  75. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_engine_slicer.py +0 -0
  76. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_fdb_datacube.py +0 -0
  77. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_fdb_unmap_tree.py +0 -0
  78. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_float_type.py +0 -0
  79. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_healpix_mapper.py +0 -0
  80. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_healpix_nested_grid.py +0 -0
  81. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_hull_slicer.py +0 -0
  82. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_hullslicer_engine.py +0 -0
  83. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_incomplete_tree_fdb.py +0 -0
  84. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_local_grid_cyclic.py +0 -0
  85. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_local_regular_grid.py +0 -0
  86. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_local_swiss_grid.py +0 -0
  87. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_mappers.py +0 -0
  88. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_merge_cyclic_octahedral.py +0 -0
  89. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_merge_octahedral_one_axis.py +0 -0
  90. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_merge_transformation.py +0 -0
  91. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_multiple_param_fdb.py +0 -0
  92. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_octahedral_grid.py +0 -0
  93. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_override_md5_hash_options.py +0 -0
  94. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_point_nearest.py +0 -0
  95. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_profiling_requesttree.py +0 -0
  96. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_reduced_ll_grid.py +0 -0
  97. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_regular_grid.py +0 -0
  98. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_regular_reduced_grid.py +0 -0
  99. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_request_tree.py +0 -0
  100. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_request_trees_after_slicing.py +0 -0
  101. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_reverse_transformation.py +0 -0
  102. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_shapes.py +0 -0
  103. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slice_date_range_fdb.py +0 -0
  104. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slice_date_range_fdb_v2.py +0 -0
  105. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slice_fdb_box.py +0 -0
  106. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicer_engine.py +0 -0
  107. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicer_era5.py +0 -0
  108. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicer_xarray.py +0 -0
  109. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicing_unsliceable_axis.py +0 -0
  110. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicing_xarray_3D.py +0 -0
  111. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_slicing_xarray_4D.py +0 -0
  112. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_snapping.py +0 -0
  113. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_snapping_real_data.py +0 -0
  114. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_tree_protobuf.py +0 -0
  115. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_tree_protobuf_encoding.py +0 -0
  116. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_tree_protobuf_encoding_fdb.py +0 -0
  117. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_type_change_transformation.py +0 -0
  118. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_union_gj.py +0 -0
  119. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_union_point_box.py +0 -0
  120. {polytope_python-1.0.35 → polytope_python-1.0.36}/tests/test_wave_spectra_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polytope-python
3
- Version: 1.0.35
3
+ Version: 1.0.36
4
4
  Summary: Polytope datacube feature extraction library
5
5
  Home-page: https://github.com/ecmwf/polytope
6
6
  Author: ECMWF
@@ -227,17 +227,22 @@ class FDBDatacube(Datacube):
227
227
  first_ax_name = requests.children[0].axis.name
228
228
  second_ax_name = requests.children[0].children[0].axis.name
229
229
 
230
- if first_ax_name not in self.nearest_search.keys() or second_ax_name not in self.nearest_search.keys():
230
+ axes_in_nearest_search = [
231
+ first_ax_name not in self.nearest_search.keys(),
232
+ second_ax_name not in self.nearest_search.keys(),
233
+ ]
234
+
235
+ if all(not item for item in axes_in_nearest_search):
231
236
  raise Exception("nearest point search axes are wrong")
232
237
 
233
238
  second_ax = requests.children[0].children[0].axis
239
+ nearest_pts = self.nearest_search.get(first_ax_name, None)
240
+ if nearest_pts is None:
241
+ nearest_pts = self.nearest_search[second_ax_name]
234
242
 
235
- nearest_pts = [
236
- [lat_val, second_ax._remap_val_to_axis_range(lon_val)]
237
- for (lat_val, lon_val) in zip(
238
- self.nearest_search[first_ax_name][0], self.nearest_search[second_ax_name][0]
239
- )
240
- ]
243
+ transformed_nearest_pts = []
244
+ for point in nearest_pts:
245
+ transformed_nearest_pts.append([point[0], second_ax._remap_val_to_axis_range(point[1])])
241
246
 
242
247
  found_latlon_pts = []
243
248
  for lat_child in requests.children:
@@ -246,7 +251,7 @@ class FDBDatacube(Datacube):
246
251
 
247
252
  # now find the nearest lat lon to the points requested
248
253
  nearest_latlons = []
249
- for pt in nearest_pts:
254
+ for pt in transformed_nearest_pts:
250
255
  nearest_latlon = nearest_pt(found_latlon_pts, pt)
251
256
  nearest_latlons.append(nearest_latlon)
252
257
 
@@ -8,7 +8,7 @@ import scipy.spatial
8
8
  from ..datacube.backends.datacube import Datacube
9
9
  from ..datacube.datacube_axis import UnsliceableDatacubeAxis
10
10
  from ..datacube.tensor_index_tree import TensorIndexTree
11
- from ..shapes import ConvexPolytope
11
+ from ..shapes import ConvexPolytope, Product
12
12
  from ..utility.combinatorics import group, tensor_product
13
13
  from ..utility.exceptions import UnsliceableShapeError
14
14
  from ..utility.geometry import lerp
@@ -76,8 +76,6 @@ class HullSlicer(Engine):
76
76
  upper = ax.from_float(upper + tol)
77
77
  flattened = node.flatten()
78
78
  method = polytope.method
79
- if method == "nearest":
80
- datacube.nearest_search[ax.name] = polytope.points
81
79
 
82
80
  # NOTE: caching
83
81
  # Create a coupled_axes list inside of datacube and add to it during axis formation, then here
@@ -214,7 +212,11 @@ class HullSlicer(Engine):
214
212
 
215
213
  # Convert the polytope points to float type to support triangulation and interpolation
216
214
  for p in polytopes:
217
- self._unique_continuous_points(p, datacube)
215
+ if isinstance(p, Product):
216
+ for poly in p.polytope():
217
+ self._unique_continuous_points(poly, datacube)
218
+ else:
219
+ self._unique_continuous_points(p, datacube)
218
220
 
219
221
  groups, input_axes = group(polytopes)
220
222
  datacube.validate(input_axes)
@@ -233,7 +235,16 @@ class HullSlicer(Engine):
233
235
  new_c.extend(combi)
234
236
  else:
235
237
  new_c.append(combi)
236
- r["unsliced_polytopes"] = set(new_c)
238
+ # NOTE TODO: here some of the polys in new_c can be a Product shape instead of a ConvexPolytope
239
+ # -> need to go through the polytopes in new_c and replace the Products with their sub-ConvexPolytopes
240
+ final_polys = []
241
+ for poly in new_c:
242
+ if isinstance(poly, Product):
243
+ final_polys.extend(poly.polytope())
244
+ else:
245
+ final_polys.append(poly)
246
+ # r["unsliced_polytopes"] = set(new_c)
247
+ r["unsliced_polytopes"] = set(final_polys)
237
248
  current_nodes = [r]
238
249
  for ax in datacube.axes.values():
239
250
  next_nodes = []
@@ -64,6 +64,13 @@ class Polytope:
64
64
  """Higher-level API which takes a request and uses it to slice the datacube"""
65
65
  logging.info("Starting request for %s ", self.context)
66
66
  self.datacube.check_branching_axes(request)
67
+ for polytope in request.polytopes():
68
+ method = polytope.method
69
+ if method == "nearest":
70
+ if self.datacube.nearest_search.get(polytope.axes()[0], None) is None:
71
+ self.datacube.nearest_search[polytope.axes()[0]] = polytope.values
72
+ else:
73
+ self.datacube.nearest_search[polytope.axes()[0]].append(polytope.values[0])
67
74
  request_tree = self.engine.extract(self.datacube, request.polytopes())
68
75
  logging.info("Created request tree for %s ", self.context)
69
76
  self.datacube.get(request_tree, self.context)
@@ -61,6 +61,42 @@ class ConvexPolytope(Shape):
61
61
  return [self]
62
62
 
63
63
 
64
+ class Product(Shape):
65
+ """Shape that takes two polytopes and 'multiplies' them together to obtain higher-dimensional shape"""
66
+
67
+ def __init__(self, *polytopes, method, value):
68
+ # TODO
69
+ all_axes = []
70
+ for poly in polytopes:
71
+ all_axes.extend(poly.axes())
72
+ self._axes = list(set(all_axes))
73
+ # Check there weren't any duplicates in the polytopes' axes
74
+ assert len(self._axes) == len(all_axes)
75
+
76
+ self._polytopes = []
77
+ for poly in polytopes:
78
+ self._polytopes.extend(poly.polytope())
79
+
80
+ self.is_in_union = False
81
+ self.method = method
82
+ self.values = value
83
+
84
+ self.is_orthogonal = False
85
+
86
+ polys_orthogonal = [poly.is_orthogonal for poly in polytopes]
87
+ if all(polys_orthogonal):
88
+ self.is_orthogonal = True
89
+
90
+ def add_to_union(self):
91
+ self.is_in_union = True
92
+
93
+ def axes(self):
94
+ return self._axes
95
+
96
+ def polytope(self):
97
+ return self._polytopes
98
+
99
+
64
100
  # This is the only shape which can slice on axes without a discretizer or interpolator
65
101
  class Select(Shape):
66
102
  """Matches several discrete values"""
@@ -89,19 +125,22 @@ class Point(Shape):
89
125
  self._axes = axes
90
126
  self.values = values
91
127
  self.method = method
92
- self.polytopes = []
93
- if method == "nearest":
94
- assert len(self.values) == 1
95
- for i in range(len(axes)):
96
- polytope_points = [v[i] for v in self.values]
97
- self.polytopes.extend(
98
- [ConvexPolytope([axes[i]], [[point]], self.method, is_orthogonal=True) for point in polytope_points]
99
- )
128
+ assert len(values) == 1
100
129
 
101
130
  def axes(self):
102
131
  return self._axes
103
132
 
104
133
  def polytope(self):
134
+ # TODO: change this to use the Product instead and return a Product here of the two 1D selects
135
+
136
+ polytopes = []
137
+ for point in self.values:
138
+ poly_to_mult = []
139
+ for i in range(len(self._axes)):
140
+ poly_to_mult.append(ConvexPolytope([self._axes[i]], [[point[i]]], self.method, is_orthogonal=True))
141
+ polytopes.append(Product(*poly_to_mult, method=self.method, value=[point]))
142
+ self.polytopes = polytopes
143
+
105
144
  return self.polytopes
106
145
 
107
146
  def __repr__(self):
@@ -0,0 +1 @@
1
+ __version__ = "1.0.36"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polytope-python
3
- Version: 1.0.35
3
+ Version: 1.0.36
4
4
  Summary: Polytope datacube feature extraction library
5
5
  Home-page: https://github.com/ecmwf/polytope
6
6
  Author: ECMWF
@@ -88,6 +88,7 @@ tests/test_octahedral_grid.py
88
88
  tests/test_override_md5_hash_options.py
89
89
  tests/test_point_nearest.py
90
90
  tests/test_point_shape.py
91
+ tests/test_point_union.py
91
92
  tests/test_profiling_requesttree.py
92
93
  tests/test_reduced_ll_grid.py
93
94
  tests/test_regular_grid.py
@@ -4,7 +4,7 @@ import xarray as xr
4
4
 
5
5
  from polytope_feature.engine.hullslicer import HullSlicer
6
6
  from polytope_feature.polytope import Polytope, Request
7
- from polytope_feature.shapes import Point, Select
7
+ from polytope_feature.shapes import Point, Select, Union
8
8
 
9
9
 
10
10
  class TestSlicing3DXarrayDatacube:
@@ -30,20 +30,26 @@ class TestSlicing3DXarrayDatacube:
30
30
  assert result.leaves[0].axis.name == "level"
31
31
 
32
32
  def test_multiple_points(self):
33
- request = Request(Point(["step", "level"], [[3, 10], [3, 12]]), Select("date", ["2000-01-01"]))
33
+ # request = Request(Point(["step", "level"], [[3, 10], [3, 12]]), Select("date", ["2000-01-01"]))
34
+ request = Request(
35
+ Union(["step", "level"], Point(["step", "level"], [[3, 10]]), Point(["step", "level"], [[3, 12]])),
36
+ Select("date", ["2000-01-01"]),
37
+ )
34
38
  result = self.API.retrieve(request)
35
39
  result.pprint()
36
- assert len(result.leaves) == 1
40
+ assert len(result.leaves) == 2
37
41
  assert result.leaves[0].axis.name == "level"
38
42
 
39
43
  def test_point_surrounding_step(self):
40
44
  request = Request(Point(["step", "level"], [[2, 10]], method="surrounding"), Select("date", ["2000-01-01"]))
41
45
  result = self.API.retrieve(request)
46
+ result.pprint()
42
47
  assert len(result.leaves) == 1
43
48
  assert np.shape(result.leaves[0].result[1]) == (1, 2, 3)
44
49
 
45
50
  def test_point_surrounding_exact_step(self):
46
51
  request = Request(Point(["step", "level"], [[3, 10]], method="surrounding"), Select("date", ["2000-01-01"]))
47
52
  result = self.API.retrieve(request)
53
+ result.pprint()
48
54
  assert len(result.leaves) == 1
49
55
  assert np.shape(result.leaves[0].result[1]) == (1, 3, 3)
@@ -0,0 +1,148 @@
1
+ import pandas as pd
2
+ import pytest
3
+
4
+ from polytope_feature.engine.hullslicer import HullSlicer
5
+ from polytope_feature.polytope import Polytope, Request
6
+ from polytope_feature.shapes import Point, Select, Span, Union
7
+
8
+
9
+ class TestSlicingFDBDatacube:
10
+ def setup_method(self, method):
11
+ # Create a dataarray with 3 labelled axes using different index types
12
+ self.options = {
13
+ "axis_config": [
14
+ {"axis_name": "number", "transformations": [{"name": "type_change", "type": "int"}]},
15
+ {"axis_name": "step", "transformations": [{"name": "type_change", "type": "int"}]},
16
+ {
17
+ "axis_name": "date",
18
+ "transformations": [{"name": "merge", "other_axis": "time", "linkers": ["T", "00"]}],
19
+ },
20
+ {
21
+ "axis_name": "values",
22
+ "transformations": [
23
+ {"name": "mapper", "type": "octahedral", "resolution": 1280, "axes": ["latitude", "longitude"]}
24
+ ],
25
+ },
26
+ {"axis_name": "latitude", "transformations": [{"name": "reverse", "is_reverse": True}]},
27
+ {"axis_name": "longitude", "transformations": [{"name": "cyclic", "range": [0, 360]}]},
28
+ ],
29
+ "pre_path": {"class": "od", "expver": "0001", "levtype": "sfc", "stream": "oper"},
30
+ "compressed_axes_config": [
31
+ "longitude",
32
+ "latitude",
33
+ "levtype",
34
+ "step",
35
+ "date",
36
+ "domain",
37
+ "expver",
38
+ "param",
39
+ "class",
40
+ "stream",
41
+ "type",
42
+ ],
43
+ }
44
+
45
+ # Testing different shapes
46
+ @pytest.mark.fdb
47
+ def test_fdb_datacube(self):
48
+ import pygribjump as gj
49
+
50
+ request = Request(
51
+ Select("step", [0]),
52
+ Select("levtype", ["sfc"]),
53
+ Span("date", pd.Timestamp("20230625T120000"), pd.Timestamp("20230626T120000")),
54
+ Select("domain", ["g"]),
55
+ Select("expver", ["0001"]),
56
+ Select("param", ["167"]),
57
+ Select("class", ["od"]),
58
+ Select("stream", ["oper"]),
59
+ Select("type", ["an"]),
60
+ Union(
61
+ ["latitude", "longitude"],
62
+ Point(["latitude", "longitude"], [[20, 20]], method="nearest"),
63
+ Point(["latitude", "longitude"], [[0, 0]], method="nearest"),
64
+ Point(["latitude", "longitude"], [[0, 20]], method="nearest"),
65
+ Point(["latitude", "longitude"], [[25, 30]], method="nearest"),
66
+ Point(["latitude", "longitude"], [[-30, 90]], method="nearest"),
67
+ Point(["latitude", "longitude"], [[-60, -30]], method="nearest"),
68
+ Point(["latitude", "longitude"], [[-15, -45]], method="nearest"),
69
+ Point(["latitude", "longitude"], [[20, 0]], method="nearest"),
70
+ ),
71
+ )
72
+
73
+ self.fdbdatacube = gj.GribJump()
74
+ self.slicer = HullSlicer()
75
+ self.API = Polytope(
76
+ datacube=self.fdbdatacube,
77
+ engine=self.slicer,
78
+ options=self.options,
79
+ )
80
+ result = self.API.retrieve(request)
81
+ result.pprint()
82
+ assert len(result.leaves) == 8
83
+
84
+ @pytest.mark.fdb
85
+ def test_fdb_datacube_surrounding(self):
86
+ import pygribjump as gj
87
+
88
+ request = Request(
89
+ Select("step", [0]),
90
+ Select("levtype", ["sfc"]),
91
+ Span("date", pd.Timestamp("20230625T120000"), pd.Timestamp("20230626T120000")),
92
+ Select("domain", ["g"]),
93
+ Select("expver", ["0001"]),
94
+ Select("param", ["167"]),
95
+ Select("class", ["od"]),
96
+ Select("stream", ["oper"]),
97
+ Select("type", ["an"]),
98
+ Union(
99
+ ["latitude", "longitude"],
100
+ Point(["latitude", "longitude"], [[25, 30]], method="surrounding"),
101
+ Point(["latitude", "longitude"], [[-15, -45]], method="surrounding"),
102
+ ),
103
+ )
104
+
105
+ self.fdbdatacube = gj.GribJump()
106
+ self.slicer = HullSlicer()
107
+ self.API = Polytope(
108
+ datacube=self.fdbdatacube,
109
+ engine=self.slicer,
110
+ options=self.options,
111
+ )
112
+ result = self.API.retrieve(request)
113
+ result.pprint()
114
+ assert len(result.leaves) == 4
115
+ tot_leaves = 0
116
+ for leaf in result.leaves:
117
+ tot_leaves += len(leaf.result)
118
+ assert tot_leaves == 9
119
+
120
+ # @pytest.mark.fdb
121
+ # def test_fdb_datacube_mix_methods(self):
122
+ # import pygribjump as gj
123
+
124
+ # request = Request(
125
+ # Select("step", [0]),
126
+ # Select("levtype", ["sfc"]),
127
+ # Span("date", pd.Timestamp("20230625T120000"), pd.Timestamp("20230626T120000")),
128
+ # Select("domain", ["g"]),
129
+ # Select("expver", ["0001"]),
130
+ # Select("param", ["167"]),
131
+ # Select("class", ["od"]),
132
+ # Select("stream", ["oper"]),
133
+ # Select("type", ["an"]),
134
+ # Union(["latitude", "longitude"],
135
+ # Point(["latitude", "longitude"], [[25, 30]], method="nearest"),
136
+ # Point(["latitude", "longitude"], [[-15, -45]], method="surrounding"))
137
+ # )
138
+
139
+ # self.fdbdatacube = gj.GribJump()
140
+ # self.slicer = HullSlicer()
141
+ # self.API = Polytope(
142
+ # datacube=self.fdbdatacube,
143
+ # engine=self.slicer,
144
+ # options=self.options,
145
+ # )
146
+ # result = self.API.retrieve(request)
147
+ # result.pprint()
148
+ # assert len(result.leaves) == 6
@@ -1 +0,0 @@
1
- __version__ = "1.0.35"