scriptengine-tasks-ecearth 0.8.0__tar.gz → 0.9.0__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 (63) hide show
  1. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/PKG-INFO +3 -3
  2. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/cubes.py +41 -0
  3. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/oifs_global_mean_year_mean_timeseries.py +2 -25
  4. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/pyproject.toml +3 -3
  5. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/PKG-INFO +3 -3
  6. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/requires.txt +1 -1
  7. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_oifs_all_mean_map.py +18 -0
  8. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_oifs_global_mean_year_mean_timeseries.py +21 -0
  9. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_oifs_year_mean_temporalmap.py +16 -0
  10. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/LICENSE +0 -0
  11. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/README.md +0 -0
  12. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/__init__.py +0 -0
  13. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/dates.py +0 -0
  14. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/exceptions.py +0 -0
  15. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/files.py +0 -0
  16. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/map_type_handling.py +0 -0
  17. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/nemo.py +0 -0
  18. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/helpers/presentation_objects.py +0 -0
  19. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/diskusage_rte_scalar.py +0 -0
  20. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/gitlab.py +0 -0
  21. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/linear_combination.py +0 -0
  22. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/map.py +0 -0
  23. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/markdown.py +0 -0
  24. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/nemo_all_mean_map.py +0 -0
  25. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/nemo_time_mean_temporalmap.py +0 -0
  26. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/nemo_timeseries.py +0 -0
  27. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/oifs_all_mean_map.py +0 -0
  28. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/oifs_year_mean_temporalmap.py +0 -0
  29. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/redmine.py +0 -0
  30. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/scalar.py +0 -0
  31. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/si3_hemis_point_month_mean_all_mean_map.py +0 -0
  32. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/si3_hemis_point_month_mean_temporalmap.py +0 -0
  33. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/si3_hemis_sum_month_mean_timeseries.py +0 -0
  34. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/simulatedyears_rte_scalar.py +0 -0
  35. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/temporalmap.py +0 -0
  36. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/monitoring/timeseries.py +0 -0
  37. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/SOURCES.txt +0 -0
  38. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/dependency_links.txt +0 -0
  39. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/entry_points.txt +0 -0
  40. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/scriptengine_tasks_ecearth.egg-info/top_level.txt +0 -0
  41. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/setup.cfg +0 -0
  42. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/setup.py +0 -0
  43. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_cubes.py +0 -0
  44. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_dates.py +0 -0
  45. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_diskusage_rte_scalar.py +0 -0
  46. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_file_handling.py +0 -0
  47. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_gitlab.py +0 -0
  48. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_linear_combination.py +0 -0
  49. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_map.py +0 -0
  50. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_map_type_handling.py +0 -0
  51. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_markdown.py +0 -0
  52. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_nemo_all_mean_map.py +0 -0
  53. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_nemo_time_mean_temporalmap.py +0 -0
  54. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_nemo_timeseries.py +0 -0
  55. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_presentation_objects.py +0 -0
  56. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_redmine.py +0 -0
  57. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_scalar.py +0 -0
  58. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_si3_hemis_point_month_mean_all_mean_map.py +0 -0
  59. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_si3_hemis_point_month_mean_temporalmap.py +0 -0
  60. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_si3_hemis_sum_month_mean_timeseries.py +0 -0
  61. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_simulatedyears_rte_scalar.py +0 -0
  62. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_temporalmap.py +0 -0
  63. {scriptengine_tasks_ecearth-0.8.0 → scriptengine_tasks_ecearth-0.9.0}/tests/test_timeseries.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptengine-tasks-ecearth
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: ScriptEngine tasks for use with the EC-Earth climate model
5
5
  Author-email: Valentina Schueller <valentina.schueller@gmail.com>, Uwe Fladrich <uwe.fladrich@protonmail.com>
6
6
  Project-URL: Homepage, https://github.com/uwefladrich/scriptengine-tasks-ecearth
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/uwefladrich/scriptengine-tasks-ecea
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
11
+ Requires-Python: >=3.11
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: scriptengine>=0.8.1
@@ -16,7 +16,7 @@ Requires-Dist: pyYAML>=5.1
16
16
  Requires-Dist: matplotlib>=3.1
17
17
  Requires-Dist: numpy>=1.18
18
18
  Requires-Dist: imageio>=2.18
19
- Requires-Dist: scitools-iris>=3.5
19
+ Requires-Dist: scitools-iris>=3.12.2
20
20
  Requires-Dist: cartopy>=0.20
21
21
  Requires-Dist: python-redmine
22
22
  Requires-Dist: python-gitlab
@@ -3,6 +3,7 @@
3
3
  import warnings
4
4
 
5
5
  import iris
6
+ import iris.analysis.cartography
6
7
  import iris.cube
7
8
  import numpy as np
8
9
  from iris.util import equalise_attributes
@@ -157,3 +158,43 @@ def mask_other_hemisphere(cube, hemisphere):
157
158
  else:
158
159
  raise ValueError("Invalid hemisphere, must be 'north' or 'south'")
159
160
  return cube
161
+
162
+
163
+ def compute_area_weights(cube):
164
+ if is_grid_regular(cube):
165
+ return compute_regular_grid_weights(cube)
166
+ return compute_reduced_grid_weights(cube)
167
+
168
+
169
+ def is_grid_regular(cube) -> bool:
170
+ if not cube.coords("latitude", dim_coords=True):
171
+ return False
172
+ return True
173
+
174
+
175
+ def compute_reduced_grid_weights(cube):
176
+ """compute area weights for the reduced gaussian grid"""
177
+ nh_latitudes = np.ma.masked_less(cube.coord("latitude").points, 0)
178
+ unique_lats, gridpoints_per_lat = np.unique(nh_latitudes, return_counts=True)
179
+ unique_lats, gridpoints_per_lat = unique_lats[0:-1], gridpoints_per_lat[0:-1]
180
+ areas = []
181
+ last_angle = 0
182
+ earth_radius = 6371
183
+ for latitude, amount in zip(unique_lats, gridpoints_per_lat):
184
+ delta = latitude - last_angle
185
+ current_angle = last_angle + 2 * delta
186
+ sin_diff = np.sin(np.deg2rad(current_angle)) - np.sin(np.deg2rad(last_angle))
187
+ ring_area = 2 * np.pi * earth_radius**2 * sin_diff
188
+ grid_area = ring_area / amount
189
+ areas.extend([grid_area] * amount)
190
+ last_angle = current_angle
191
+ areas = np.append(areas[::-1], areas)
192
+ area_weights = np.broadcast_to(areas, cube.data.shape)
193
+ return area_weights
194
+
195
+
196
+ def compute_regular_grid_weights(cube):
197
+ """compute area weights for a regular lat/lon grid"""
198
+ cube.coord("latitude").guess_bounds()
199
+ cube.coord("longitude").guess_bounds()
200
+ return iris.analysis.cartography.area_weights(cube)
@@ -37,36 +37,13 @@ class OifsGlobalMeanYearMeanTimeseries(Timeseries):
37
37
 
38
38
  time_mean_cube = self.compute_time_mean(oifs_cube)
39
39
 
40
- area_weights = self.compute_area_weights(time_mean_cube)
40
+ area_weights = helpers.cubes.compute_area_weights(time_mean_cube)
41
41
  timeseries_cube = self.compute_spatial_mean(time_mean_cube, area_weights)
42
42
 
43
43
  self.set_cell_methods(timeseries_cube)
44
44
  timeseries_cube = self.adjust_metadata(timeseries_cube, varname)
45
45
  self.save(timeseries_cube, dst)
46
46
 
47
- def compute_area_weights(self, cube):
48
- """compute area weights for the reduced gaussian grid"""
49
- self.log_debug("Computing area weights.")
50
- nh_latitudes = np.ma.masked_less(cube.coord("latitude").points, 0)
51
- unique_lats, gridpoints_per_lat = np.unique(nh_latitudes, return_counts=True)
52
- unique_lats, gridpoints_per_lat = unique_lats[0:-1], gridpoints_per_lat[0:-1]
53
- areas = []
54
- last_angle = 0
55
- earth_radius = 6371
56
- for latitude, amount in zip(unique_lats, gridpoints_per_lat):
57
- delta = latitude - last_angle
58
- current_angle = last_angle + 2 * delta
59
- sin_diff = np.sin(np.deg2rad(current_angle)) - np.sin(
60
- np.deg2rad(last_angle)
61
- )
62
- ring_area = 2 * np.pi * earth_radius**2 * sin_diff
63
- grid_area = ring_area / amount
64
- areas.extend([grid_area] * amount)
65
- last_angle = current_angle
66
- areas = np.append(areas[::-1], areas)
67
- area_weights = np.broadcast_to(areas, cube.data.shape)
68
- return area_weights
69
-
70
47
  def set_cell_methods(self, timeseries_cube):
71
48
  """add the correct cell methods"""
72
49
  timeseries_cube.cell_methods = ()
@@ -100,7 +77,7 @@ class OifsGlobalMeanYearMeanTimeseries(Timeseries):
100
77
  ).bounds[:, [0, 1]]
101
78
  time_mean_cube.coord("longitude").bounds = time_mean_cube.coord(
102
79
  "longitude"
103
- ).bounds[:, [0, 2]]
80
+ ).bounds[:, [0, 1]]
104
81
  with warnings.catch_warnings():
105
82
  # Suppress warning about insufficient metadata.
106
83
  warnings.filterwarnings(
@@ -7,7 +7,7 @@
7
7
 
8
8
  [project]
9
9
  name = "scriptengine-tasks-ecearth"
10
- version = "0.8.0"
10
+ version = "0.9.0"
11
11
  authors = [
12
12
  { name = "Valentina Schueller", email = "valentina.schueller@gmail.com" },
13
13
  { name = "Uwe Fladrich", email = "uwe.fladrich@protonmail.com" },
@@ -19,14 +19,14 @@
19
19
  "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
20
20
  "Operating System :: OS Independent",
21
21
  ]
22
- requires-python = ">=3.8"
22
+ requires-python = ">=3.11"
23
23
  dependencies = [
24
24
  "scriptengine>=0.8.1",
25
25
  "pyYAML>=5.1",
26
26
  "matplotlib>=3.1",
27
27
  "numpy>=1.18",
28
28
  "imageio>=2.18",
29
- "scitools-iris>=3.5",
29
+ "scitools-iris>=3.12.2", # https://github.com/SciTools/iris/issues/6417
30
30
  "cartopy>=0.20",
31
31
  "python-redmine",
32
32
  "python-gitlab",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptengine-tasks-ecearth
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: ScriptEngine tasks for use with the EC-Earth climate model
5
5
  Author-email: Valentina Schueller <valentina.schueller@gmail.com>, Uwe Fladrich <uwe.fladrich@protonmail.com>
6
6
  Project-URL: Homepage, https://github.com/uwefladrich/scriptengine-tasks-ecearth
@@ -8,7 +8,7 @@ Project-URL: Bug Tracker, https://github.com/uwefladrich/scriptengine-tasks-ecea
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
10
10
  Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.8
11
+ Requires-Python: >=3.11
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: scriptengine>=0.8.1
@@ -16,7 +16,7 @@ Requires-Dist: pyYAML>=5.1
16
16
  Requires-Dist: matplotlib>=3.1
17
17
  Requires-Dist: numpy>=1.18
18
18
  Requires-Dist: imageio>=2.18
19
- Requires-Dist: scitools-iris>=3.5
19
+ Requires-Dist: scitools-iris>=3.12.2
20
20
  Requires-Dist: cartopy>=0.20
21
21
  Requires-Dist: python-redmine
22
22
  Requires-Dist: python-gitlab
@@ -3,7 +3,7 @@ pyYAML>=5.1
3
3
  matplotlib>=3.1
4
4
  numpy>=1.18
5
5
  imageio>=2.18
6
- scitools-iris>=3.5
6
+ scitools-iris>=3.12.2
7
7
  cartopy>=0.20
8
8
  python-redmine
9
9
  python-gitlab
@@ -25,6 +25,24 @@ def test_oifs_all_mean_map_working(tmp_path):
25
25
  assert len(cube.coord("time").points) == 1
26
26
 
27
27
 
28
+ def test_oifs_all_mean_map_regular_grid(tmp_path):
29
+ init = {
30
+ "src": ["./tests/testdata/regular_grid_tas.nc"],
31
+ "dst": str(tmp_path / "test.nc"),
32
+ "varname": "tas",
33
+ }
34
+ atmo_map = OifsAllMeanMap(init)
35
+ atmo_map.run(init)
36
+ cube = iris.load_cube(init["dst"])
37
+ assert cube.name() == "air_temperature"
38
+ assert cube.attributes["title"] is not None
39
+ assert cube.attributes["comment"] is not None
40
+ assert cube.attributes["diagnostic_type"] == "map"
41
+ assert cube.attributes["map_type"] == "global atmosphere"
42
+ assert cube.coord("time").climatological
43
+ assert len(cube.coord("time").points) == 1
44
+
45
+
28
46
  def test_oifs_all_mean_map_wrong_code(tmp_path):
29
47
  init = {
30
48
  "src": ["./tests/testdata/TES1_atm_1m_1990_2t.nc"],
@@ -28,6 +28,27 @@ def test_oifs_global_mean_year_mean_timeseries_working(tmp_path):
28
28
  )
29
29
 
30
30
 
31
+ def test_oifs_timeseries_compare_grids(tmp_path):
32
+ init = {
33
+ "src": ["./tests/testdata/regular_grid_tas.nc"],
34
+ "dst": str(tmp_path / "test_reg.nc"),
35
+ "varname": "tas",
36
+ }
37
+ atmo_ts = OifsGlobalMeanYearMeanTimeseries(init)
38
+ atmo_ts.run(init)
39
+ cube_reg = iris.load_cube(init["dst"])
40
+
41
+ init = {
42
+ "src": ["./tests/testdata/reduced_grid_tas.nc"],
43
+ "dst": str(tmp_path / "test_red.nc"),
44
+ "varname": "tas",
45
+ }
46
+ atmo_ts = OifsGlobalMeanYearMeanTimeseries(init)
47
+ atmo_ts.run(init)
48
+ cube_red = iris.load_cube(init["dst"])
49
+ assert abs(cube_red.data - cube_reg.data) < 1e-3
50
+
51
+
31
52
  def test_oifs_global_mean_year_mean_timeseries_wrong_varname(tmp_path):
32
53
  init = {
33
54
  "src": ["./tests/testdata/TES1_atm_1m_1990_2t.nc"],
@@ -23,6 +23,22 @@ def test_oifs_year_mean_temporalmap_working(tmp_path):
23
23
  assert cube.attributes["map_type"] == "global atmosphere"
24
24
 
25
25
 
26
+ def test_oifs_year_mean_temporalmap_regular_grid(tmp_path):
27
+ init = {
28
+ "src": ["./tests/testdata/regular_grid_tas.nc"],
29
+ "dst": str(tmp_path / "test.nc"),
30
+ "varname": "tas",
31
+ }
32
+ atmos_time_map = OifsYearMeanTemporalmap(init)
33
+ atmos_time_map.run(init)
34
+ cube = iris.load_cube(init["dst"])
35
+ assert cube.name() == "air_temperature"
36
+ assert cube.attributes["title"] is not None
37
+ assert cube.attributes["comment"] is not None
38
+ assert cube.attributes["diagnostic_type"] == "temporal map"
39
+ assert cube.attributes["map_type"] == "global atmosphere"
40
+
41
+
26
42
  def test_oifs_year_mean_temporalmap_wrong_varname(tmp_path):
27
43
  init = {
28
44
  "src": ["./tests/testdata/TES1_atm_1m_1990_2t.nc"],