anemoi-utils 0.4.37__py3-none-any.whl → 0.4.38__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/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.4.37'
32
- __version_tuple__ = version_tuple = (0, 4, 37)
31
+ __version__ = version = '0.4.38'
32
+ __version_tuple__ = version_tuple = (0, 4, 38)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -20,6 +20,7 @@ import zipfile
20
20
  from collections.abc import Callable
21
21
  from tempfile import TemporaryDirectory
22
22
 
23
+ import numpy as np
23
24
  import tqdm
24
25
 
25
26
  LOG = logging.getLogger(__name__)
@@ -147,6 +148,41 @@ def load_supporting_arrays(zipf: zipfile.ZipFile, entries: dict) -> dict:
147
148
  return supporting_arrays
148
149
 
149
150
 
151
+ def _get_supporting_arrays_paths(directory: str, folder: str, supporting_arrays: dict | np.ndarray) -> dict:
152
+ """Get the paths of supporting arrays."""
153
+ if supporting_arrays is None:
154
+ return {}
155
+
156
+ if isinstance(supporting_arrays, dict):
157
+ return {
158
+ new_key: _get_supporting_arrays_paths(f"{directory}/{folder}", new_key, new_value)
159
+ for new_key, new_value in supporting_arrays.items()
160
+ }
161
+
162
+ return dict(
163
+ path=f"{directory}/{folder}.numpy",
164
+ shape=supporting_arrays.shape,
165
+ dtype=str(supporting_arrays.dtype),
166
+ )
167
+
168
+
169
+ def _write_array_to_bytes(array: dict | np.ndarray, name: str, entry: dict, zipf: zipfile.ZipFile) -> None:
170
+ """Write a supporting array to bytes in a zip file."""
171
+ if isinstance(array, dict):
172
+ for sub_name, sub_array in array.items():
173
+ _write_array_to_bytes(sub_array, sub_name, entry[sub_name], zipf)
174
+ return None
175
+
176
+ LOG.info(
177
+ "Saving supporting array `%s` to %s (shape=%s, dtype=%s)",
178
+ name,
179
+ entry["path"],
180
+ entry["shape"],
181
+ entry["dtype"],
182
+ )
183
+ zipf.writestr(entry["path"], array.tobytes())
184
+
185
+
150
186
  def save_metadata(
151
187
  path: str, metadata: dict, *, supporting_arrays: dict = None, name: str = DEFAULT_NAME, folder: str = DEFAULT_FOLDER
152
188
  ) -> None:
@@ -189,29 +225,14 @@ def save_metadata(
189
225
  LOG.info("Saving metadata to %s/%s/%s", directory, folder, name)
190
226
 
191
227
  metadata = metadata.copy()
192
- if supporting_arrays is not None:
193
- metadata["supporting_arrays_paths"] = {
194
- key: dict(path=f"{directory}/{folder}/{key}.numpy", shape=value.shape, dtype=str(value.dtype))
195
- for key, value in supporting_arrays.items()
196
- }
197
- else:
198
- metadata["supporting_arrays_paths"] = {}
228
+ metadata["supporting_arrays_paths"] = _get_supporting_arrays_paths(directory, folder, supporting_arrays)
199
229
 
200
230
  zipf.writestr(
201
231
  f"{directory}/{folder}/{name}",
202
232
  json.dumps(metadata),
203
233
  )
204
234
 
205
- for name, entry in metadata["supporting_arrays_paths"].items():
206
- value = supporting_arrays[name]
207
- LOG.info(
208
- "Saving supporting array `%s` to %s (shape=%s, dtype=%s)",
209
- name,
210
- entry["path"],
211
- entry["shape"],
212
- entry["dtype"],
213
- )
214
- zipf.writestr(entry["path"], value.tobytes())
235
+ _write_array_to_bytes(supporting_arrays, "", metadata["supporting_arrays_paths"], zipf)
215
236
 
216
237
 
217
238
  def _edit_metadata(path: str, name: str, callback: Callable, supporting_arrays: dict | None = None) -> None:
anemoi/utils/dates.py CHANGED
@@ -260,39 +260,21 @@ def frequency_to_string(frequency: datetime.timedelta) -> str:
260
260
  A string representation of the frequency.
261
261
  """
262
262
 
263
- frequency = frequency_to_timedelta(frequency)
263
+ total_seconds = int(frequency.total_seconds())
264
264
 
265
- total_seconds = frequency.total_seconds()
266
265
  if total_seconds < 0:
267
266
  return f"-{frequency_to_string(-frequency)}"
268
- assert int(total_seconds) == total_seconds, total_seconds
269
- total_seconds = int(total_seconds)
270
267
 
271
- seconds = total_seconds
268
+ if total_seconds % (24 * 3600) == 0:
269
+ return f"{total_seconds // (24 * 3600)}d"
272
270
 
273
- days = seconds // (24 * 3600)
274
- seconds %= 24 * 3600
275
- hours = seconds // 3600
276
- seconds %= 3600
277
- minutes = seconds // 60
278
- seconds %= 60
271
+ if total_seconds % 3600 == 0:
272
+ return f"{total_seconds // 3600}h"
279
273
 
280
- if days > 0 and hours == 0 and minutes == 0 and seconds == 0:
281
- return f"{days}d"
274
+ if total_seconds % 60 == 0:
275
+ return f"{total_seconds // 60}m"
282
276
 
283
- if days == 0 and hours > 0 and minutes == 0 and seconds == 0:
284
- return f"{hours}h"
285
-
286
- if days == 0 and hours == 0 and minutes > 0 and seconds == 0:
287
- return f"{minutes}m"
288
-
289
- if days == 0 and hours == 0 and minutes == 0 and seconds > 0:
290
- return f"{seconds}s"
291
-
292
- if days > 0:
293
- return f"{total_seconds}s"
294
-
295
- return str(frequency)
277
+ return f"{total_seconds}s"
296
278
 
297
279
 
298
280
  def frequency_to_seconds(frequency: int | str | datetime.timedelta) -> int:
anemoi/utils/testing.py CHANGED
@@ -114,7 +114,7 @@ class GetTestData:
114
114
 
115
115
  LOG.info(f"Downloading test data from {url} to {target}")
116
116
 
117
- download(url, target)
117
+ download(url, target, maximum_retries=5, retry_after=60, timeout=60)
118
118
 
119
119
  if gzipped:
120
120
  import gzip
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anemoi-utils
3
- Version: 0.4.37
3
+ Version: 0.4.38
4
4
  Summary: A package to hold various functions to support training of ML models on ECMWF data.
5
5
  Author-email: "European Centre for Medium-Range Weather Forecasts (ECMWF)" <software.support@ecmwf.int>
6
6
  License: Apache License
@@ -1,13 +1,13 @@
1
1
  anemoi/utils/__init__.py,sha256=G1BlBl5IGz1AKHYkEUNT5x69WOTV0ALEe8appAdYr38,806
2
2
  anemoi/utils/__main__.py,sha256=6LlE4MYrPvqqrykxXh7XMi50UZteUY59NeM8P9Zs2dU,910
3
3
  anemoi/utils/_environment.py,sha256=jN4y-fNEkIQaz87dJJNBQU-UttFsEcL_edjlnaA6lVc,1488
4
- anemoi/utils/_version.py,sha256=rrk9b9t6FcjvVt4Tp41VGDj03xKbwyFWENJYjCLYQ_U,706
4
+ anemoi/utils/_version.py,sha256=0idbjr4U1OcAqhKQqoELJq61WRFFz5A1vJU4qmnJRMk,706
5
5
  anemoi/utils/caching.py,sha256=wKkpsACniNCFK1nc5Tw18EAv9FJGYdhs5p8qsr8i_FI,6153
6
- anemoi/utils/checkpoints.py,sha256=DME5s-OG5bwJJscjlO17RWrQe_gbyxlGETeBBzGLO9E,10407
6
+ anemoi/utils/checkpoints.py,sha256=4tfwG7KwCp2Kr4dnMyKiFtZ2bl0Vo8czVq7V69NBIBk,11050
7
7
  anemoi/utils/cli.py,sha256=w_edLlUa_S-RoPU3HKSmjjh949QWTl4FXPfR_HKLYDI,7522
8
8
  anemoi/utils/compatibility.py,sha256=Yx4Yj3xL5q0PxYccM3N5qGeQxTtEPfaCz4EqjrS7CUc,2175
9
9
  anemoi/utils/config.py,sha256=gyWr_4ZDEf5wIFoV9gVf8pHeBFTL9WS81s4et8K-RHE,17934
10
- anemoi/utils/dates.py,sha256=35KyiyFW8SeWLIm7VeMKBJvNvl2nVu-edRWLX-04uT4,17307
10
+ anemoi/utils/dates.py,sha256=kD72mxNmKyDAkkyiLTZzlueWjAjSA48yK5fN4Wup4dE,16795
11
11
  anemoi/utils/devtools.py,sha256=W3OBu96MkXRIl7Qh1SE5Zd6aB1R0QlnmlrlpBYM0fVY,3527
12
12
  anemoi/utils/grib.py,sha256=eHz3BVoSB4O-3RARxXFcKRSWtYVbt6lqoLBcssHOp70,3543
13
13
  anemoi/utils/grids.py,sha256=l09Hkvq8pZoh5XE8Cy29584-b1GouQSh_WqZks8uuEs,5963
@@ -20,7 +20,7 @@ anemoi/utils/rules.py,sha256=YtJcwkyBJwPjHlM4ZM6icGJXLCRZmcuHCXc-SSR8wgw,6856
20
20
  anemoi/utils/s3.py,sha256=bBVlfg3R4sJYOfgrSkhX7MxSVUQEur4LjE86ug8vkNw,4052
21
21
  anemoi/utils/sanitise.py,sha256=XkQzibDbu-VFJkJC4WcB9ovkcTkVAynXtkn1Tlc2CC4,4019
22
22
  anemoi/utils/sanitize.py,sha256=43ZKDcfVpeXSsJ9TFEc9aZnD6oe2cUh151XnDspM98M,462
23
- anemoi/utils/testing.py,sha256=u6VyarS9li5X_kqZr6hrqvwEAVjtgY9ZYdIyIsv7kyQ,10789
23
+ anemoi/utils/testing.py,sha256=Zy-HVhqQ_rQ3kXzj9ff5QOSUe_M3OibS5bP9hBGYfRE,10836
24
24
  anemoi/utils/text.py,sha256=9M7VepzZLL-jGfFGXDqNxjwpNl7tiU8arkkOqhT9iSE,14361
25
25
  anemoi/utils/timer.py,sha256=_leKMYza2faM7JKlGE7LCNy13rbdPnwaCF7PSrI_NmI,3895
26
26
  anemoi/utils/commands/__init__.py,sha256=5u_6EwdqYczIAgJfCwRSyQAYFEqh2ZuHHT57g9g7sdI,808
@@ -40,9 +40,9 @@ anemoi/utils/remote/s3.py,sha256=4UMqC4qFRNpZ2YJWhN6L71hqn0E-3tNAhUtkLZ_R1Tw,178
40
40
  anemoi/utils/remote/ssh.py,sha256=xNtsawh8okytCKRehkRCVExbHZj-CRUQNormEHglfuw,8088
41
41
  anemoi/utils/schemas/__init__.py,sha256=nkinKlsPLPXEjfTYQT1mpKC4cvs-14w_zBkDRxakwxw,698
42
42
  anemoi/utils/schemas/errors.py,sha256=lgOXzVTYzAE0qWQf3OZ42vCWixv8lilSqLLhzARBmvI,1831
43
- anemoi_utils-0.4.37.dist-info/licenses/LICENSE,sha256=8HznKF1Vi2IvfLsKNE5A2iVyiri3pRjRPvPC9kxs6qk,11354
44
- anemoi_utils-0.4.37.dist-info/METADATA,sha256=kgnjqlC2q10qDTEI5BAkYI3SAfVVnQgrd7Zd1CFBTtg,15692
45
- anemoi_utils-0.4.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
- anemoi_utils-0.4.37.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
47
- anemoi_utils-0.4.37.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
48
- anemoi_utils-0.4.37.dist-info/RECORD,,
43
+ anemoi_utils-0.4.38.dist-info/licenses/LICENSE,sha256=8HznKF1Vi2IvfLsKNE5A2iVyiri3pRjRPvPC9kxs6qk,11354
44
+ anemoi_utils-0.4.38.dist-info/METADATA,sha256=Ct1xBFzI5S9jwsLg-fk7btPCo-iwzuwmssJvwbiMJE0,15692
45
+ anemoi_utils-0.4.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
+ anemoi_utils-0.4.38.dist-info/entry_points.txt,sha256=LENOkn88xzFQo-V59AKoA_F_cfYQTJYtrNTtf37YgHY,60
47
+ anemoi_utils-0.4.38.dist-info/top_level.txt,sha256=DYn8VPs-fNwr7fNH9XIBqeXIwiYYd2E2k5-dUFFqUz0,7
48
+ anemoi_utils-0.4.38.dist-info/RECORD,,