-
Notifications
You must be signed in to change notification settings - Fork 52
feat: python recipes #420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
b8raoult
wants to merge
88
commits into
main
Choose a base branch
from
feat/python-recipes
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
feat: python recipes #420
Changes from all commits
Commits
Show all changes
88 commits
Select commit
Hold shift + click to select a range
9cb8c52
feat: recipe generator
b8raoult 01774dd
update
b8raoult 33793a6
update
b8raoult 920d523
update
b8raoult ed5d190
update
b8raoult 2562baf
fix: better handling of xarray metadata
b8raoult f048a4b
update
b8raoult 8ad5eb0
update
b8raoult 5db7a97
Merge branch 'fix/better-handling-of-xarray-metadata' into feat/recip…
b8raoult b33f3ac
fix: support other keys that param in rename filter
b8raoult 71d8180
Merge branch 'fix/support-other-keys-than-param-in-rename-filter' int…
b8raoult 6d23027
typo
b8raoult 6933574
Merge branch 'fix/support-other-keys-than-param-in-rename-filter' int…
b8raoult 9179dae
add command line
b8raoult 79a391b
update
b8raoult 203e09b
update
b8raoult b4433bd
update
b8raoult 6f3fdb0
update
b8raoult 45365a1
upadte
b8raoult d7cc82c
update
b8raoult f381b00
update
b8raoult da93ad6
update
b8raoult 3082edf
refactor missing
b8raoult ef4a5c9
add references
b8raoult 93410d5
refactor
b8raoult 1df0ef7
refactor
b8raoult 18df4eb
refactor
b8raoult 3341d4c
update
b8raoult 58dc8a2
work on migrate
b8raoult 3e180f9
work on migrate
b8raoult 255c22d
merge
b8raoult 83936f7
merge
b8raoult 5209f26
update
b8raoult c7a0e5d
update
b8raoult b78a098
update
b8raoult d641ea7
update
b8raoult 3754eb2
update
b8raoult 39ebc13
update
b8raoult 5d32745
update
b8raoult 6c1f146
update
b8raoult 37de369
update
b8raoult 24f2c2a
update
b8raoult db4d895
add dumper
b8raoult 55f740d
update
b8raoult 014dbbc
update
b8raoult 8ad9396
bug fix in path
b8raoult 9756618
join recipe command
b8raoult a493a96
join recipe command
b8raoult 1cde9f8
use ampersand
b8raoult cdb1a9a
use ampersand
b8raoult e69eb10
add settings
b8raoult 92165b4
add settings
b8raoult a044e14
udpate
b8raoult cb9c576
use ruamel
b8raoult 99a5fb7
fix source as parameters
b8raoult ce027f4
update
b8raoult 3bf7c35
Merge branch 'feat/refactor-create' of github.com:ecmwf/anemoi-datase…
b8raoult 96dfe3d
Merge branch 'feat/recipe-generator' into feat/refactor-create
b8raoult f68a11e
Merge remote-tracking branch 'origin/main' into feat/refactor-create
b8raoult 3d5f0ef
tidy
b8raoult 70272f6
update
b8raoult 38ced18
update tests
b8raoult cb3847e
fix tests
b8raoult 00477c9
add missing package
b8raoult 839a077
Merge branch 'main' into feat/refactor-create
floriankrb 619c416
remove unsused file
b8raoult 21321cb
Update copyright year
mchantry 90e21ee
Fix copyright header
mchantry fa35755
bug fix in repeated dates
b8raoult 2fc4189
bug fix in repeated dates
b8raoult 9cb1b63
remove python generating code that will be in another PR
b8raoult 5746b04
remove python generating code that will be in another PR
b8raoult e916035
Merge remote-tracking branch 'origin/main' into feat/refactor-create
b8raoult e4712f0
remove python generating code that will be in another PR
b8raoult 976c6a4
feat: python recipes
b8raoult 6a3cab8
work on doc
b8raoult 0cc8026
update docs
b8raoult 066d1ce
update docs
b8raoult 423f8a3
update docs
b8raoult 8bfa5d3
update
b8raoult e4f3ddb
update
b8raoult 83694ef
update
b8raoult 66945f0
Update docs/datasets/building/code/using-python-3.py
b8raoult e26ce75
add docs
b8raoult ebdc9a6
Merge remote-tracking branch 'origin/main' into feat/python-recipes
b8raoult ec4e74c
update
b8raoult 3c0ae14
update with main
b8raoult 26dfbaa
update with main
b8raoult File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = ( | ||
| (a := r.grib(path="dir1/*.grib")) | ||
| & r.grib(path="dir2/*.grib") | ||
| & r.forcings(param=["cos_latitude", "sin_latitude"], template=a) | ||
| ) | ||
|
|
||
| r.dump() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = r.concat( | ||
| { | ||
| ("2023-01-01T00:00:00", "2023-06-30T18:00:00", "12h"): r.grib(path="gribs/*.grib"), | ||
| ("2023-07-01T00:00:00", "2023-12-31T18:00:00", "12h"): r.netcdf(path="ncdfs/*.nc"), | ||
| } | ||
| ) | ||
|
|
||
| r.dump() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,249 @@ | ||
| import datetime | ||
|
|
||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.description = """ | ||
| This is a complex example of a dataset recipe written in Python. | ||
| It uses data from two different ECMWF research experiments for atmospheric and wave data, | ||
| from ECMWF's MARS archive. For the atmospheric data, it combines data from two | ||
| 12-hourly data streams (oper and lwda) to create a dataset with a 6-hourly frequency. | ||
| """ | ||
|
|
||
| r.name = "aifs-rd-an-oper-ioku-mars-n320-2024-2024-6h-v1" | ||
| r.licence = "CC-BY-4.0" | ||
| r.attribution = "ECMWF" | ||
|
|
||
| start_date = datetime.datetime(2024, 5, 2, 0, 0) | ||
| end_date = datetime.datetime(2024, 9, 8, 18, 0) | ||
|
|
||
| r.dates = { | ||
| "start": start_date, | ||
| "end": end_date, | ||
| "frequency": "6h", | ||
| } | ||
|
|
||
| r.build = {"use_grib_paramid": True} | ||
| r.statistics = {"allow_nans": True} | ||
|
|
||
|
|
||
| grid = "n320" | ||
|
|
||
| ioku = { | ||
| "class": "rd", | ||
| "grid": grid, | ||
| "expver": "ioku", | ||
| } | ||
|
|
||
| ikdi = { | ||
| "class": "rd", | ||
| "grid": grid, | ||
| "expver": "ikdi", | ||
| } | ||
|
|
||
| accumulations_stream = { | ||
| "oper": "lwda", | ||
| "lwda": "oper", | ||
| } | ||
|
|
||
|
|
||
| def accumulations(stream): | ||
| return r.accumulations( | ||
| levtype="sfc", | ||
| param=["cp", "tp", "sf", "strd", "ssrd"], | ||
| stream=accumulations_stream[stream], | ||
| **ioku, | ||
| ) | ||
|
|
||
|
|
||
| def pressure_levels(stream): | ||
| return r.mars( | ||
| stream=stream, | ||
| level=[ | ||
| 1, | ||
| 10, | ||
| 30, | ||
| 50, | ||
| 70, | ||
| 100, | ||
| 150, | ||
| 200, | ||
| 250, | ||
| 300, | ||
| 400, | ||
| 500, | ||
| 600, | ||
| 700, | ||
| 850, | ||
| 925, | ||
| 1000, | ||
| ], | ||
| levtype="pl", | ||
| param=["t", "u", "v", "w", "z"], | ||
| **ioku, | ||
| ) | ||
|
|
||
|
|
||
| def pressure_levels_q(stream): | ||
| return r.mars( | ||
| levtype="pl", | ||
| param=["q"], | ||
| level=[50, 100, 150, 200, 250, 300, 400, 500, 600, 700, 850, 925, 1000], | ||
| stream=stream, | ||
| **ioku, | ||
| ) | ||
|
|
||
|
|
||
| def sfc_fields(stream): | ||
| return r.mars( | ||
| levtype="sfc", | ||
| param=[ | ||
| "10u", | ||
| "10v", | ||
| "2d", | ||
| "2t", | ||
| "lsm", | ||
| "msl", | ||
| "sdor", | ||
| "skt", | ||
| "slor", | ||
| "tcw", | ||
| "z", | ||
| # Land parameters below | ||
| "stl1", | ||
| "stl2", | ||
| "tcc", | ||
| "mcc", | ||
| "hcc", | ||
| "lcc", | ||
| "100u", | ||
| "100v", | ||
| ], | ||
| stream=stream, | ||
| **ioku, | ||
| ) | ||
|
|
||
|
|
||
| def surface_pressure(stream): | ||
| return ( | ||
| r.mars( | ||
| levtype="ml", | ||
| levelist=1, | ||
| param="lnsp", | ||
| stream=stream, | ||
| **ioku, | ||
| ) | ||
| | r.lnsp_to_sp() | ||
| ) | ||
|
|
||
|
|
||
| def apply_mask(): | ||
| return r.apply_mask( | ||
| path="/data/climate.v015/319_3/lsm.grib", | ||
| mask_value=0, | ||
| ) | ||
|
|
||
|
|
||
| def land_params(stream): | ||
| soil_params = r.mars( | ||
| levtype="sfc", | ||
| param=["swvl1", "swvl2", "sd"], | ||
| stream=stream, | ||
| **ioku, | ||
| ) | ||
|
|
||
| snow_cover = ( | ||
| r.mars( | ||
| levtype="sfc", | ||
| param=["sd", "rsn"], | ||
| stream=stream, | ||
| **ioku, | ||
| ) | ||
| | r.snow_cover() | ||
| ) | ||
|
|
||
| run_off = r.accumulations( | ||
| levtype="sfc", | ||
| param=["ro"], | ||
| stream=accumulations_stream[stream], | ||
| **ioku, | ||
| ) | ||
|
|
||
| return (soil_params & snow_cover & run_off) | apply_mask() | ||
|
|
||
|
|
||
| def constants(template): | ||
| return r.constants( | ||
| param=[ | ||
| "cos_latitude", | ||
| "cos_longitude", | ||
| "sin_latitude", | ||
| "sin_longitude", | ||
| "cos_julian_day", | ||
| "cos_local_time", | ||
| "sin_julian_day", | ||
| "sin_local_time", | ||
| "insolation", | ||
| ], | ||
| template=template, | ||
| ) | ||
|
|
||
|
|
||
| def wave_data(): | ||
| return ( | ||
| r.mars( | ||
| param=[ | ||
| "swh", | ||
| "cdww", | ||
| "mwp", | ||
| "mwd", | ||
| "wmb", | ||
| "h1012", | ||
| "h1214", | ||
| "h1417", | ||
| "h1721", | ||
| "h2125", | ||
| "h2530", | ||
| ], | ||
| stream="wave", | ||
| **ikdi, | ||
| ) | ||
| | r.cos_sin_mean_wave_direction() | ||
| ) | ||
|
|
||
|
|
||
| def atmos_data(stream): | ||
| return ( | ||
| (a := sfc_fields(stream)) | ||
| & surface_pressure(stream) | ||
| & pressure_levels(stream) | ||
| & pressure_levels_q(stream) | ||
| & accumulations(stream) | ||
| & land_params(stream) | ||
| & constants(template=a) | ||
| ) | ||
|
|
||
|
|
||
| def dates(hour): | ||
| s = start_date.replace(hour=hour) | ||
| e = end_date.replace(hour=hour + 12) | ||
| while s > start_date: | ||
| s -= datetime.timedelta(hours=24) | ||
| while e < end_date: | ||
| e += datetime.timedelta(hours=24) | ||
| return (s, e, "12h") | ||
|
|
||
|
|
||
| def input_data(): | ||
| return r.concat( | ||
| { | ||
| dates(0): atmos_data("oper"), | ||
| dates(6): atmos_data("lwda"), | ||
| } | ||
| ) | ||
|
|
||
|
|
||
| r.input = input_data() & wave_data() | ||
|
|
||
| r.dump() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe( | ||
| description="Example dataset recipe", | ||
| name="example-dataset", | ||
| licence="CC-BY-4.0", | ||
| attribution="my-organisation", | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.description = """ | ||
| Example dataset recipe using Python, with attributes set one by one | ||
| and a multi-line description. | ||
| """ | ||
|
|
||
| r.name = "example-dataset" | ||
| r.licence = "CC-BY-4.0" | ||
| r.attribution = "my-organisation" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| from datetime import datetime | ||
|
|
||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| # As a tuple (start, end, frequency) | ||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| # As a dictionary | ||
| r.dates = { | ||
| "start": "2023-01-01T00:00:00", | ||
| "end": "2023-12-31T18:00:00", | ||
| "frequency": "12h", | ||
| } | ||
|
|
||
| # You can also provide datetime objects | ||
| r.dates = { | ||
| "start": datetime(2023, 1, 1, 0, 0), | ||
| "end": datetime(2023, 12, 31, 18, 0), | ||
| "frequency": "12h", | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = r.grib(path="data/*.grib") | r.clip(minimum=0, maximum=100) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = r.grib(path="dir1/*.grib") & r.grib(path="dir2/*.grib") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = (r.grib(path="dir1/*.grib") & r.grib(path="dir2/*.grib")) | r.clip(minimum=0, maximum=100) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| r.input = (r.grib(path="dir1/*.grib") & r.grib(path="dir2/*.grib")) | r.clip(minimum=0, maximum=100) | ||
|
|
||
| r.dump() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| from anemoi.datasets.recipe import Recipe | ||
|
|
||
| r = Recipe() | ||
|
|
||
| r.dates = ("2023-01-01T00:00:00", "2023-12-31T18:00:00", "12h") | ||
|
|
||
| a = r.grib(path="dir1/*.grib") | ||
| b = r.grib(path="dir2/*.grib") | ||
| c = r.forcings(param=["cos_latitude", "sin_latitude"], template=a) | ||
|
|
||
| r.input = a & b & c | ||
|
|
||
| r.dump() |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell, the
constantssource is deprecated and says we should useforcingsinstead. I think this should be updated to be consistent with the other examples/rest of the docs.