anemoi-datasets 0.5.27__py3-none-any.whl → 0.5.28__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.
- anemoi/datasets/_version.py +2 -2
- anemoi/datasets/commands/recipe/__init__.py +93 -0
- anemoi/datasets/commands/recipe/format.py +55 -0
- anemoi/datasets/commands/recipe/migrate.py +555 -0
- anemoi/datasets/create/__init__.py +42 -1
- anemoi/datasets/create/config.py +2 -0
- anemoi/datasets/create/input/__init__.py +43 -63
- anemoi/datasets/create/input/action.py +296 -236
- anemoi/datasets/create/input/context/__init__.py +71 -0
- anemoi/datasets/create/input/context/field.py +54 -0
- anemoi/datasets/create/input/data_sources.py +2 -1
- anemoi/datasets/create/input/misc.py +0 -71
- anemoi/datasets/create/input/repeated_dates.py +0 -114
- anemoi/datasets/create/input/result/__init__.py +17 -0
- anemoi/datasets/create/input/{result.py → result/field.py} +9 -89
- anemoi/datasets/create/sources/accumulations.py +74 -94
- anemoi/datasets/create/sources/accumulations2.py +16 -45
- anemoi/datasets/create/sources/anemoi_dataset.py +46 -42
- anemoi/datasets/create/sources/constants.py +39 -38
- anemoi/datasets/create/sources/empty.py +26 -22
- anemoi/datasets/create/sources/forcings.py +29 -28
- anemoi/datasets/create/sources/grib.py +92 -72
- anemoi/datasets/create/sources/grib_index.py +46 -42
- anemoi/datasets/create/sources/hindcasts.py +56 -55
- anemoi/datasets/create/sources/legacy.py +10 -62
- anemoi/datasets/create/sources/mars.py +107 -131
- anemoi/datasets/create/sources/netcdf.py +28 -24
- anemoi/datasets/create/sources/opendap.py +28 -24
- anemoi/datasets/create/sources/recentre.py +42 -41
- anemoi/datasets/create/sources/repeated_dates.py +44 -0
- anemoi/datasets/create/sources/source.py +26 -48
- anemoi/datasets/create/sources/tendencies.py +67 -94
- anemoi/datasets/create/sources/xarray_support/__init__.py +29 -24
- anemoi/datasets/create/sources/xarray_support/field.py +4 -4
- anemoi/datasets/create/sources/xarray_zarr.py +28 -24
- anemoi/datasets/create/sources/zenodo.py +43 -39
- anemoi/datasets/create/utils.py +0 -42
- anemoi/datasets/data/dataset.py +6 -0
- anemoi/datasets/data/grids.py +0 -152
- anemoi/datasets/data/rolling_average.py +141 -0
- anemoi/datasets/data/stores.py +7 -9
- anemoi/datasets/dates/__init__.py +2 -0
- anemoi/datasets/dumper.py +76 -0
- anemoi/datasets/grids.py +1 -178
- anemoi/datasets/schemas/recipe.json +131 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/METADATA +5 -2
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/RECORD +51 -51
- anemoi/datasets/create/filter.py +0 -47
- anemoi/datasets/create/input/concat.py +0 -161
- anemoi/datasets/create/input/context.py +0 -86
- anemoi/datasets/create/input/empty.py +0 -53
- anemoi/datasets/create/input/filter.py +0 -117
- anemoi/datasets/create/input/function.py +0 -232
- anemoi/datasets/create/input/join.py +0 -129
- anemoi/datasets/create/input/pipe.py +0 -66
- anemoi/datasets/create/input/step.py +0 -173
- anemoi/datasets/create/input/template.py +0 -161
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/WHEEL +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/entry_points.txt +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/licenses/LICENSE +0 -0
- {anemoi_datasets-0.5.27.dist-info → anemoi_datasets-0.5.28.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,8 @@ from earthkit.data.core.fieldlist import MultiFieldList
|
|
|
14
14
|
|
|
15
15
|
from anemoi.datasets.create.sources.mars import mars
|
|
16
16
|
|
|
17
|
-
from .
|
|
17
|
+
from . import source_registry
|
|
18
|
+
from .legacy import LegacySource
|
|
18
19
|
|
|
19
20
|
LOGGER = logging.getLogger(__name__)
|
|
20
21
|
|
|
@@ -37,57 +38,57 @@ def _to_list(x: list | tuple | Any) -> list[Any]:
|
|
|
37
38
|
return [x]
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
@
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
41
|
+
@source_registry.register("hindcasts")
|
|
42
|
+
class HindcastsSource(LegacySource):
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _execute(context: Any, dates: list[Any], **request: dict[str, Any]) -> MultiFieldList:
|
|
46
|
+
"""Generates hindcast requests based on the provided dates and request parameters.
|
|
47
|
+
|
|
48
|
+
Parameters
|
|
49
|
+
----------
|
|
50
|
+
context : Any
|
|
51
|
+
The context containing the dates provider and trace method.
|
|
52
|
+
dates : List[Any]
|
|
53
|
+
A list of dates for which to generate hindcast requests.
|
|
54
|
+
request : Dict[str, Any]
|
|
55
|
+
Additional request parameters.
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
MultiFieldList
|
|
60
|
+
A MultiFieldList containing the hindcast data.
|
|
61
|
+
"""
|
|
62
|
+
from anemoi.datasets.dates import HindcastsDates
|
|
63
|
+
|
|
64
|
+
provider = context.dates_provider
|
|
65
|
+
assert isinstance(provider, HindcastsDates)
|
|
66
|
+
|
|
67
|
+
context.trace("H️", f"hindcasts {len(dates)=}")
|
|
68
|
+
|
|
69
|
+
request["param"] = _to_list(request["param"])
|
|
70
|
+
request["step"] = _to_list(request.get("step", 0))
|
|
71
|
+
request["step"] = [int(_) for _ in request["step"]]
|
|
72
|
+
|
|
73
|
+
context.trace("H️", f"hindcast {request}")
|
|
74
|
+
|
|
75
|
+
requests = []
|
|
76
|
+
for d in dates:
|
|
77
|
+
r = request.copy()
|
|
78
|
+
hindcast = provider.mapping[d]
|
|
79
|
+
r["hdate"] = hindcast.hdate.strftime("%Y-%m-%d")
|
|
80
|
+
r["date"] = hindcast.refdate.strftime("%Y-%m-%d")
|
|
81
|
+
r["time"] = hindcast.refdate.strftime("%H")
|
|
82
|
+
r["step"] = hindcast.step
|
|
83
|
+
requests.append(r)
|
|
84
|
+
|
|
85
|
+
if len(requests) == 0:
|
|
86
|
+
return MultiFieldList([])
|
|
87
|
+
|
|
88
|
+
return mars(
|
|
89
|
+
context,
|
|
90
|
+
dates,
|
|
91
|
+
*requests,
|
|
92
|
+
date_key="hdate",
|
|
93
|
+
request_already_using_valid_datetime=True,
|
|
94
|
+
)
|
|
@@ -8,16 +8,13 @@
|
|
|
8
8
|
# nor does it submit to any jurisdiction.
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
import inspect
|
|
12
11
|
import logging
|
|
13
|
-
import
|
|
14
|
-
from collections.abc import Callable
|
|
12
|
+
from abc import abstractmethod
|
|
15
13
|
from typing import Any
|
|
16
14
|
|
|
17
|
-
from anemoi.datasets.create.input.
|
|
15
|
+
from anemoi.datasets.create.input.context import Context
|
|
18
16
|
|
|
19
17
|
from ..source import Source
|
|
20
|
-
from . import source_registry
|
|
21
18
|
|
|
22
19
|
LOG = logging.getLogger(__name__)
|
|
23
20
|
|
|
@@ -27,7 +24,7 @@ class LegacySource(Source):
|
|
|
27
24
|
|
|
28
25
|
Parameters
|
|
29
26
|
----------
|
|
30
|
-
context :
|
|
27
|
+
context : Context
|
|
31
28
|
The context in which the source is created.
|
|
32
29
|
*args : tuple
|
|
33
30
|
Positional arguments.
|
|
@@ -35,64 +32,15 @@ class LegacySource(Source):
|
|
|
35
32
|
Keyword arguments.
|
|
36
33
|
"""
|
|
37
34
|
|
|
38
|
-
def __init__(self, context:
|
|
35
|
+
def __init__(self, context: Context, *args: Any, **kwargs: Any) -> None:
|
|
39
36
|
super().__init__(context, *args, **kwargs)
|
|
40
37
|
self.args = args
|
|
41
38
|
self.kwargs = kwargs
|
|
42
39
|
|
|
40
|
+
@staticmethod
|
|
41
|
+
@abstractmethod
|
|
42
|
+
def _execute(context, *args, **kwargs):
|
|
43
|
+
pass
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Parameters
|
|
48
|
-
----------
|
|
49
|
-
name : str
|
|
50
|
-
The name of the legacy source.
|
|
51
|
-
"""
|
|
52
|
-
|
|
53
|
-
def __init__(self, name: str) -> None:
|
|
54
|
-
name, _ = os.path.splitext(os.path.basename(name))
|
|
55
|
-
self.name = name
|
|
56
|
-
|
|
57
|
-
def __call__(self, execute: Callable) -> Callable:
|
|
58
|
-
"""Call method to wrap the execute function.
|
|
59
|
-
|
|
60
|
-
Parameters
|
|
61
|
-
----------
|
|
62
|
-
execute : function
|
|
63
|
-
The execute function to be wrapped.
|
|
64
|
-
|
|
65
|
-
Returns
|
|
66
|
-
-------
|
|
67
|
-
function
|
|
68
|
-
The wrapped execute function.
|
|
69
|
-
"""
|
|
70
|
-
this = self
|
|
71
|
-
name = f"Legacy{self.name.title()}Source"
|
|
72
|
-
source = ".".join([execute.__module__, execute.__name__])
|
|
73
|
-
|
|
74
|
-
def execute_wrapper(self, dates) -> Any:
|
|
75
|
-
"""Wrapper method to call the execute function."""
|
|
76
|
-
|
|
77
|
-
args, kwargs = resolve(self.context, (self.args, self.kwargs))
|
|
78
|
-
|
|
79
|
-
try:
|
|
80
|
-
return execute(self.context, dates, *args, **kwargs)
|
|
81
|
-
except TypeError:
|
|
82
|
-
LOG.error(f"Error executing source {this.name} from {source}")
|
|
83
|
-
LOG.error(f"Function signature is: {inspect.signature(execute)}")
|
|
84
|
-
LOG.error(f"Arguments are: {args=}, {kwargs=}")
|
|
85
|
-
raise
|
|
86
|
-
|
|
87
|
-
klass = type(
|
|
88
|
-
name,
|
|
89
|
-
(LegacySource,),
|
|
90
|
-
{
|
|
91
|
-
"execute": execute_wrapper,
|
|
92
|
-
"_source": source,
|
|
93
|
-
},
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
source_registry.register(self.name)(klass)
|
|
97
|
-
|
|
98
|
-
return execute
|
|
45
|
+
def execute(self, dates: Any) -> Any:
|
|
46
|
+
return self._execute(self.context, dates, *self.args, **self.kwargs)
|
|
@@ -16,9 +16,9 @@ from anemoi.utils.humanize import did_you_mean
|
|
|
16
16
|
from earthkit.data import from_source
|
|
17
17
|
from earthkit.data.utils.availability import Availability
|
|
18
18
|
|
|
19
|
-
from anemoi.datasets.create.
|
|
19
|
+
from anemoi.datasets.create.sources import source_registry
|
|
20
20
|
|
|
21
|
-
from .legacy import
|
|
21
|
+
from .legacy import LegacySource
|
|
22
22
|
|
|
23
23
|
DEBUG = False
|
|
24
24
|
|
|
@@ -358,135 +358,111 @@ MARS_KEYS = [
|
|
|
358
358
|
]
|
|
359
359
|
|
|
360
360
|
|
|
361
|
-
@
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
requests = [kwargs]
|
|
398
|
-
|
|
399
|
-
for r in requests:
|
|
400
|
-
param = r.get("param", [])
|
|
401
|
-
if not isinstance(param, (list, tuple)):
|
|
402
|
-
param = [param]
|
|
403
|
-
# check for "Norway bug" where yaml transforms 'no' into False, etc.
|
|
404
|
-
for p in param:
|
|
405
|
-
if p is False:
|
|
406
|
-
raise ValueError(
|
|
407
|
-
"'param' cannot be 'False'. If you wrote 'param: no' or 'param: off' in yaml, you may want to use quotes?"
|
|
408
|
-
)
|
|
409
|
-
if p is None:
|
|
410
|
-
raise ValueError(
|
|
411
|
-
"'param' cannot be 'None'. If you wrote 'param: no' in yaml, you may want to use quotes?"
|
|
412
|
-
)
|
|
413
|
-
if p is True:
|
|
414
|
-
raise ValueError(
|
|
415
|
-
"'param' cannot be 'True'. If you wrote 'param: on' in yaml, you may want to use quotes?"
|
|
416
|
-
)
|
|
417
|
-
|
|
418
|
-
if len(dates) == 0: # When using `repeated_dates`
|
|
419
|
-
assert len(requests) == 1, requests
|
|
420
|
-
assert "date" in requests[0], requests[0]
|
|
421
|
-
if isinstance(requests[0]["date"], datetime.date):
|
|
422
|
-
requests[0]["date"] = requests[0]["date"].strftime("%Y%m%d")
|
|
423
|
-
else:
|
|
424
|
-
requests = factorise_requests(
|
|
425
|
-
dates,
|
|
426
|
-
*requests,
|
|
427
|
-
request_already_using_valid_datetime=request_already_using_valid_datetime,
|
|
428
|
-
date_key=date_key,
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
requests = list(requests)
|
|
432
|
-
|
|
433
|
-
ds = from_source("empty")
|
|
434
|
-
context.trace("✅", f"{[str(d) for d in dates]}")
|
|
435
|
-
context.trace("✅", f"Will run {len(requests)} requests")
|
|
436
|
-
for r in requests:
|
|
437
|
-
r = {k: v for k, v in r.items() if v != ("-",)}
|
|
438
|
-
context.trace("✅", f"mars {r}")
|
|
439
|
-
|
|
440
|
-
for r in requests:
|
|
441
|
-
r = {k: v for k, v in r.items() if v != ("-",)}
|
|
442
|
-
|
|
443
|
-
if context.use_grib_paramid and "param" in r:
|
|
444
|
-
r = use_grib_paramid(r)
|
|
445
|
-
|
|
446
|
-
for k, v in r.items():
|
|
447
|
-
if k not in MARS_KEYS:
|
|
448
|
-
raise ValueError(
|
|
449
|
-
f"⚠️ Unknown key {k}={v} in MARS request. Did you mean '{did_you_mean(k, MARS_KEYS)}' ?"
|
|
450
|
-
)
|
|
451
|
-
try:
|
|
452
|
-
if use_cdsapi_dataset:
|
|
453
|
-
ds = ds + from_source("cds", use_cdsapi_dataset, r)
|
|
454
|
-
else:
|
|
455
|
-
ds = ds + from_source("mars", **r)
|
|
456
|
-
except Exception as e:
|
|
457
|
-
if "File is empty:" not in str(e):
|
|
458
|
-
raise
|
|
459
|
-
return ds
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
execute = mars
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
if __name__ == "__main__":
|
|
466
|
-
import yaml
|
|
467
|
-
|
|
468
|
-
config = yaml.safe_load(
|
|
361
|
+
@source_registry.register("mars")
|
|
362
|
+
class MarsSource(LegacySource):
|
|
363
|
+
|
|
364
|
+
@staticmethod
|
|
365
|
+
def _execute(
|
|
366
|
+
context: Any,
|
|
367
|
+
dates: list[datetime.datetime],
|
|
368
|
+
*requests: dict[str, Any],
|
|
369
|
+
request_already_using_valid_datetime: bool = False,
|
|
370
|
+
date_key: str = "date",
|
|
371
|
+
use_cdsapi_dataset: str | None = None,
|
|
372
|
+
**kwargs: Any,
|
|
373
|
+
) -> Any:
|
|
374
|
+
"""Executes MARS requests based on the given context, dates, and other parameters.
|
|
375
|
+
|
|
376
|
+
Parameters
|
|
377
|
+
----------
|
|
378
|
+
context : Any
|
|
379
|
+
The context for the requests.
|
|
380
|
+
dates : List[datetime.datetime]
|
|
381
|
+
The list of dates to be used in the requests.
|
|
382
|
+
requests : Dict[str, Any]
|
|
383
|
+
The input requests to be executed.
|
|
384
|
+
request_already_using_valid_datetime : bool, optional
|
|
385
|
+
Flag indicating if the requests already use valid datetime.
|
|
386
|
+
date_key : str, optional
|
|
387
|
+
The key for the date in the requests.
|
|
388
|
+
use_cdsapi_dataset : Optional[str], optional
|
|
389
|
+
The dataset to be used with CDS API.
|
|
390
|
+
kwargs : Any
|
|
391
|
+
Additional keyword arguments for the requests.
|
|
392
|
+
|
|
393
|
+
Returns
|
|
394
|
+
-------
|
|
395
|
+
Any
|
|
396
|
+
The resulting dataset.
|
|
469
397
|
"""
|
|
470
|
-
- class: ea
|
|
471
|
-
expver: '0001'
|
|
472
|
-
grid: 20.0/20.0
|
|
473
|
-
levtype: sfc
|
|
474
|
-
param: [2t]
|
|
475
|
-
# param: [10u, 10v, 2d, 2t, lsm, msl, sdor, skt, slor, sp, tcw, z]
|
|
476
|
-
number: [0, 1]
|
|
477
|
-
|
|
478
|
-
# - class: ea
|
|
479
|
-
# expver: '0001'
|
|
480
|
-
# grid: 20.0/20.0
|
|
481
|
-
# levtype: pl
|
|
482
|
-
# param: [q]
|
|
483
|
-
# levelist: [1000, 850]
|
|
484
398
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
399
|
+
if not requests:
|
|
400
|
+
requests = [kwargs]
|
|
401
|
+
|
|
402
|
+
for r in requests:
|
|
403
|
+
param = r.get("param", [])
|
|
404
|
+
if not isinstance(param, (list, tuple)):
|
|
405
|
+
param = [param]
|
|
406
|
+
# check for "Norway bug" where yaml transforms 'no' into False, etc.
|
|
407
|
+
for p in param:
|
|
408
|
+
if p is False:
|
|
409
|
+
raise ValueError(
|
|
410
|
+
"'param' cannot be 'False'. If you wrote 'param: no' or 'param: off' in yaml, you may want to use quotes?"
|
|
411
|
+
)
|
|
412
|
+
if p is None:
|
|
413
|
+
raise ValueError(
|
|
414
|
+
"'param' cannot be 'None'. If you wrote 'param: no' in yaml, you may want to use quotes?"
|
|
415
|
+
)
|
|
416
|
+
if p is True:
|
|
417
|
+
raise ValueError(
|
|
418
|
+
"'param' cannot be 'True'. If you wrote 'param: on' in yaml, you may want to use quotes?"
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
if len(dates) == 0: # When using `repeated_dates`
|
|
422
|
+
assert len(requests) == 1, requests
|
|
423
|
+
assert "date" in requests[0], requests[0]
|
|
424
|
+
if isinstance(requests[0]["date"], datetime.date):
|
|
425
|
+
requests[0]["date"] = requests[0]["date"].strftime("%Y%m%d")
|
|
426
|
+
else:
|
|
427
|
+
requests = factorise_requests(
|
|
428
|
+
dates,
|
|
429
|
+
*requests,
|
|
430
|
+
request_already_using_valid_datetime=request_already_using_valid_datetime,
|
|
431
|
+
date_key=date_key,
|
|
432
|
+
)
|
|
489
433
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
434
|
+
requests = list(requests)
|
|
435
|
+
|
|
436
|
+
ds = from_source("empty")
|
|
437
|
+
context.trace("✅", f"{[str(d) for d in dates]}")
|
|
438
|
+
context.trace("✅", f"Will run {len(requests)} requests")
|
|
439
|
+
for r in requests:
|
|
440
|
+
r = {k: v for k, v in r.items() if v != ("-",)}
|
|
441
|
+
context.trace("✅", f"mars {r}")
|
|
442
|
+
|
|
443
|
+
for r in requests:
|
|
444
|
+
r = {k: v for k, v in r.items() if v != ("-",)}
|
|
445
|
+
|
|
446
|
+
if context.use_grib_paramid and "param" in r:
|
|
447
|
+
r = use_grib_paramid(r)
|
|
448
|
+
|
|
449
|
+
for k, v in r.items():
|
|
450
|
+
if k not in MARS_KEYS:
|
|
451
|
+
raise ValueError(
|
|
452
|
+
f"⚠️ Unknown key {k}={v} in MARS request. Did you mean '{did_you_mean(k, MARS_KEYS)}' ?"
|
|
453
|
+
)
|
|
454
|
+
try:
|
|
455
|
+
if use_cdsapi_dataset:
|
|
456
|
+
ds = ds + from_source("cds", use_cdsapi_dataset, r)
|
|
457
|
+
else:
|
|
458
|
+
ds = ds + from_source("mars", **r)
|
|
459
|
+
except Exception as e:
|
|
460
|
+
if "File is empty:" not in str(e):
|
|
461
|
+
raise
|
|
462
|
+
return ds
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
# TODO: make clearer the interface between sources that use mars.
|
|
466
|
+
# Currently some sources use mars as a function rather than through the registry,
|
|
467
|
+
# e.g. accumulations, accumulations2, hindcasts, recentre, tendencies
|
|
468
|
+
mars = MarsSource._execute
|
|
@@ -12,30 +12,34 @@ from typing import Any
|
|
|
12
12
|
|
|
13
13
|
import earthkit.data as ekd
|
|
14
14
|
|
|
15
|
-
from .
|
|
15
|
+
from . import source_registry
|
|
16
|
+
from .legacy import LegacySource
|
|
16
17
|
from .xarray import load_many
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
@
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
20
|
+
@source_registry.register("netcdf")
|
|
21
|
+
class NetCDFSource(LegacySource):
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def _execute(context: Any, dates: list[str], path: str, *args: Any, **kwargs: Any) -> ekd.FieldList:
|
|
25
|
+
"""Execute the loading of multiple NetCDF files.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
context : object
|
|
30
|
+
The context in which the function is executed.
|
|
31
|
+
dates : list
|
|
32
|
+
List of dates for which data is to be loaded.
|
|
33
|
+
path : str
|
|
34
|
+
Path to the directory containing the NetCDF files.
|
|
35
|
+
*args : tuple
|
|
36
|
+
Additional positional arguments.
|
|
37
|
+
**kwargs : dict
|
|
38
|
+
Additional keyword arguments.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
object
|
|
43
|
+
The loaded data.
|
|
44
|
+
"""
|
|
45
|
+
return load_many("📁", context, dates, path, *args, **kwargs)
|
|
@@ -12,30 +12,34 @@ from typing import Any
|
|
|
12
12
|
|
|
13
13
|
import earthkit.data as ekd
|
|
14
14
|
|
|
15
|
-
from .
|
|
15
|
+
from . import source_registry
|
|
16
|
+
from .legacy import LegacySource
|
|
16
17
|
from .xarray import load_many
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
@
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
20
|
+
@source_registry.register("opendap")
|
|
21
|
+
class OpenDAPSource(LegacySource):
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def _execute(context: dict[str, Any], dates: list[str], url: str, *args: Any, **kwargs: Any) -> ekd.FieldList:
|
|
25
|
+
"""Execute the data loading process from an OpenDAP source.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
context : dict
|
|
30
|
+
The context in which the function is executed.
|
|
31
|
+
dates : list
|
|
32
|
+
List of dates for which data is to be loaded.
|
|
33
|
+
url : str
|
|
34
|
+
The URL of the OpenDAP source.
|
|
35
|
+
*args : tuple
|
|
36
|
+
Additional positional arguments.
|
|
37
|
+
**kwargs : dict
|
|
38
|
+
Additional keyword arguments.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
xarray.Dataset
|
|
43
|
+
The loaded dataset.
|
|
44
|
+
"""
|
|
45
|
+
return load_many("🌐", context, dates, url, *args, **kwargs)
|