anemoi-utils 0.4.12__py3-none-any.whl → 0.4.13__py3-none-any.whl

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.

Potentially problematic release.


This version of anemoi-utils might be problematic. Click here for more details.

anemoi/utils/grids.py CHANGED
@@ -8,9 +8,7 @@
8
8
  # nor does it submit to any jurisdiction.
9
9
 
10
10
 
11
- """Utilities for working with grids.
12
-
13
- """
11
+ """Utilities for working with grids."""
14
12
 
15
13
  import logging
16
14
  import os
@@ -27,14 +25,46 @@ LOG = logging.getLogger(__name__)
27
25
  GRIDS_URL_PATTERN = "https://get.ecmwf.int/repository/anemoi/grids/grid-{name}.npz"
28
26
 
29
27
 
30
- def xyz_to_latlon(x, y, z):
28
+ def xyz_to_latlon(x: np.ndarray, y: np.ndarray, z: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
29
+ """Convert Cartesian coordinates to latitude and longitude.
30
+
31
+ Parameters
32
+ ----------
33
+ x : np.ndarray
34
+ The x coordinates
35
+ y : np.ndarray
36
+ The y coordinates
37
+ z : np.ndarray
38
+ The z coordinates
39
+
40
+ Returns
41
+ -------
42
+ tuple[np.ndarray, np.ndarray]
43
+ The latitude and longitude
44
+ """
31
45
  return (
32
46
  np.rad2deg(np.arcsin(np.minimum(1.0, np.maximum(-1.0, z)))),
33
47
  np.rad2deg(np.arctan2(y, x)),
34
48
  )
35
49
 
36
50
 
37
- def latlon_to_xyz(lat, lon, radius=1.0):
51
+ def latlon_to_xyz(lat: np.ndarray, lon: np.ndarray, radius: float = 1.0) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
52
+ """Convert latitude and longitude to Cartesian coordinates.
53
+
54
+ Parameters
55
+ ----------
56
+ lat : np.ndarray
57
+ The latitudes
58
+ lon : np.ndarray
59
+ The longitudes
60
+ radius : float, optional
61
+ The radius of the sphere, by default 1.0
62
+
63
+ Returns
64
+ -------
65
+ tuple[np.ndarray, np.ndarray, np.ndarray]
66
+ The x, y, and z coordinates
67
+ """
38
68
  # https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#From_geodetic_to_ECEF_coordinates
39
69
  # We assume that the Earth is a sphere of radius 1 so N(phi) = 1
40
70
  # We assume h = 0
@@ -54,7 +84,30 @@ def latlon_to_xyz(lat, lon, radius=1.0):
54
84
  return x, y, z
55
85
 
56
86
 
57
- def nearest_grid_points(source_latitudes, source_longitudes, target_latitudes, target_longitudes):
87
+ def nearest_grid_points(
88
+ source_latitudes: np.ndarray,
89
+ source_longitudes: np.ndarray,
90
+ target_latitudes: np.ndarray,
91
+ target_longitudes: np.ndarray,
92
+ ) -> np.ndarray:
93
+ """Find the nearest grid points.
94
+
95
+ Parameters
96
+ ----------
97
+ source_latitudes : np.ndarray
98
+ The source latitudes
99
+ source_longitudes : np.ndarray
100
+ The source longitudes
101
+ target_latitudes : np.ndarray
102
+ The target latitudes
103
+ target_longitudes : np.ndarray
104
+ The target longitudes
105
+
106
+ Returns
107
+ -------
108
+ np.ndarray
109
+ The indices of the nearest grid points
110
+ """
58
111
  from scipy.spatial import cKDTree
59
112
 
60
113
  source_xyz = latlon_to_xyz(source_latitudes, source_longitudes)
@@ -68,7 +121,19 @@ def nearest_grid_points(source_latitudes, source_longitudes, target_latitudes, t
68
121
 
69
122
 
70
123
  @cached(collection="grids", encoding="npz")
71
- def _grids(name):
124
+ def _grids(name: str) -> bytes:
125
+ """Get grid data by name.
126
+
127
+ Parameters
128
+ ----------
129
+ name : str
130
+ The name of the grid
131
+
132
+ Returns
133
+ -------
134
+ bytes
135
+ The grid data
136
+ """
72
137
  from anemoi.utils.config import load_config
73
138
 
74
139
  user_path = load_config().get("utils", {}).get("grids_path")
@@ -88,7 +153,19 @@ def _grids(name):
88
153
  return response.content
89
154
 
90
155
 
91
- def grids(name):
156
+ def grids(name: str) -> dict:
157
+ """Load grid data by name.
158
+
159
+ Parameters
160
+ ----------
161
+ name : str
162
+ The name of the grid
163
+
164
+ Returns
165
+ -------
166
+ dict
167
+ The grid data
168
+ """
92
169
  if name.endswith(".npz"):
93
170
  return dict(np.load(name))
94
171
 
anemoi/utils/hindcasts.py CHANGED
@@ -9,29 +9,46 @@
9
9
 
10
10
 
11
11
  import datetime
12
+ from typing import Iterator
13
+ from typing import List
14
+ from typing import Tuple
12
15
 
13
16
 
14
17
  class HindcastDatesTimes:
15
- """The HindcastDatesTimes class is an iterator that generates datetime objects within a given range."""
18
+ """The HindcastDatesTimes class is an iterator that generates datetime objects within a given range.
16
19
 
17
- def __init__(self, reference_dates, years=20):
18
- """_summary_
20
+ Attributes
21
+ ----------
22
+ reference_dates : List[datetime.datetime]
23
+ List of reference dates.
24
+ years : int
25
+ Number of years to go back from each reference date.
26
+ """
27
+
28
+ def __init__(self, reference_dates: List[datetime.datetime], years: int = 20):
29
+ """Initialize the HindcastDatesTimes iterator.
19
30
 
20
31
  Parameters
21
32
  ----------
22
- reference_dates : _type_
23
- _description_
33
+ reference_dates : List[datetime.datetime]
34
+ List of reference dates.
24
35
  years : int, optional
25
- _description_, by default 20
36
+ Number of years to go back from each reference date, by default 20.
26
37
  """
27
-
28
38
  self.reference_dates = reference_dates
29
39
 
30
40
  assert isinstance(years, int), f"years must be an integer, got {years}"
31
41
  assert years > 0, f"years must be greater than 0, got {years}"
32
42
  self.years = years
33
43
 
34
- def __iter__(self):
44
+ def __iter__(self) -> Iterator[Tuple[datetime.datetime, datetime.datetime]]:
45
+ """Generate tuples of past dates and their corresponding reference dates.
46
+
47
+ Yields
48
+ ------
49
+ Iterator[Tuple[datetime.datetime, datetime.datetime]]
50
+ Tuples containing a past date and its corresponding reference date.
51
+ """
35
52
  for reference_date in self.reference_dates:
36
53
  year, month, day = reference_date.year, reference_date.month, reference_date.day
37
54
  if (month, day) == (2, 29):