Skip to content

Commit fdb3185

Browse files
committed
Merge branch 'main' into hotfix/pipaudit
2 parents 9abd6e1 + c66efa3 commit fdb3185

File tree

14 files changed

+599
-72
lines changed

14 files changed

+599
-72
lines changed

.github/workflows/ci-cd-mkdocs.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
name: Build doc
2020
runs-on: ubuntu-latest
2121
steps:
22-
- uses: actions/checkout@v4
22+
- uses: actions/checkout@v5
2323
- name: Install Python
24-
uses: actions/setup-python@v5
24+
uses: actions/setup-python@v6
2525
with:
2626
python-version: '3.11'
2727
- name: Install package with optional dependency 'doc'
@@ -32,7 +32,7 @@
3232
working-directory: ./docs
3333
run: mkdocs build
3434
- name: Upload Pages artifact
35-
uses: actions/upload-pages-artifact@v3
35+
uses: actions/upload-pages-artifact@v4
3636
with:
3737
path: "docs/site/"
3838
publish:

.github/workflows/ci-cd.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
runs-on: ubuntu-latest
2020
steps:
2121
- name: Checkout
22-
uses: actions/checkout@v4
22+
uses: actions/checkout@v5
2323
- name: Set up Python version
24-
uses: actions/setup-python@v5
24+
uses: actions/setup-python@v6
2525
with:
2626
python-version: |
2727
3.9
@@ -52,9 +52,9 @@
5252
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
5353
steps:
5454
- name: Checkout
55-
uses: actions/checkout@v4
55+
uses: actions/checkout@v5
5656
- name: Set up Python version
57-
uses: actions/setup-python@v5
57+
uses: actions/setup-python@v6
5858
with:
5959
python-version: '3.13'
6060
- name: Build package

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [0.2.1] - August, 2024
7+
## [0.2.2] - August, 2025
8+
9+
### Features
10+
11+
* Support for Météo-France ensemble model `PE-AROME` (#38)
12+
13+
## [0.2.1] - August, 2025
814

915
### Features
1016

1117
* Support for Python3.12 and Python 3.13
1218

13-
## [0.2.0] - January, 2024
19+
## [0.2.0] - January, 2025
1420

1521
### Features
1622

README.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,14 @@ Create an account on [the Météo-France API portal](https://portail-api.meteofr
5050

5151
Meteole allows you to retrieve forecasts for a wide range of weather indicators. Here's how to get started:
5252

53-
| Characteristics | AROME | ARPEGE | AROME INSTANTANE | PIAF |
54-
|------------------|----------------------|-----------------------------| -------------------------------| -------------------------------|
55-
| Resolution | 1.3 km | 10 km | 1.3 km | 1.3 km |
56-
| Update Frequency | Every 3 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
57-
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
53+
| Characteristics | AROME | AROME-PE | ARPEGE | AROME INSTANTANE | PIAF |
54+
|------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------|
55+
| Resolution | 1.3 km | 2.8 km | 10 km | 1.3 km | 1.3 km |
56+
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
57+
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
58+
| Numbers of scenarios | 1 | 25 | 1 | 1 | 1 |
59+
60+
The AromePE model is an ensemble model. Instead of making a single forecast of the most likely weather, a set (or ensemble) of forecasts is produced. This set of forecasts aims to give an indication of the range of possible future states of the atmosphere ([from Wikipedia](https://en.wikipedia.org/wiki/Ensemble_forecasting)). It provides 25 scenarios of the possible weather parameters instead of one for the standard determinist models.
5861

5962
*note : the date of the run cannot be more than 4 days in the past. Consequently, change the date of the run in the example below.*
6063

@@ -88,7 +91,8 @@ df_arome = arome_client.get_coverage(
8891
lat = (41.33356, 51.0889), # Optional: latitude
8992
coverage_id=None, # Optional: an alternative to indicator/run/interval
9093
temp_dir=None, # Optional: Directory to store the temporary file
91-
)
94+
ensemble_numbers=range(3), # Optional: Only for ensemble models (AromePE), the number of scenarios
95+
)
9296
```
9397
Note: The coverage_id can be used instead of indicator, run, and interval.
9498

docs/pages/how_to.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
Ensure that you have correctly installed **Meteole** before, check the [Installation](installation.md) page :wrench:
23

34
## Get a token, an API key or an application ID
@@ -46,14 +47,17 @@ client.get_vignette()
4647
4748
## Get data
4849

49-
Meteole allows you to retrieve forecasts for a wide range of weather indicators. Here's how to get started with AROME, AROME INSTANTANE, ARPEGE or PIAF:
50+
Meteole allows you to retrieve forecasts for a wide range of weather indicators. Here's how to get started with AROME, AROME-PE, AROME INSTANTANE, ARPEGE or PIAF:
5051

51-
| Characteristics | AROME | ARPEGE | AROME INSTANTANE | PIAF |
52-
|------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------|
53-
| Resolution | 1.3 km | 10 km | 1.3 km | 1.3 km |
54-
| Update Frequency | Every 3 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
55-
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
52+
| Characteristics | AROME | AROME-PE | ARPEGE | AROME INSTANTANE | PIAF |
53+
|------------------|----------------------------|----------------------------|-----------------------------|--------------------------------| -------------------------------|
54+
| Resolution | 1.3 km | 2.8 km | 10 km | 1.3 km | 1.3 km |
55+
| Update Frequency | Every 3 hours | Every 6 hours | Every 6 hours | Every 1 hour | Every 10 minutes |
56+
| Forecast Range | Every hour, up to 51 hours | Every hour, up to 51 hours | Every hour, up to 114 hours | Every 15 minutes, up to 360 minutes | Every 5 minutes, up to 195 minutes |
57+
| Numbers of scenarios | 1 | 25 | 1 | 1 | 1 |
5658

59+
The AromePE model is an ensemble model. Instead of making a single forecast of the most likely weather, a set (or ensemble) of forecasts is produced. This set of forecasts aims to give an indication of the range of possible future states of the atmosphere ([from Wikipedia](https://en.wikipedia.org/wiki/Ensemble_forecasting)). It provides 25 scenarios of the possible weather parameters instead of one for the standard determinist models.
60+
5761
*note : the date of the run cannot be more than 4 days in the past. Consequently, change the date of the run in the example below.*
5862

5963
```python
@@ -88,4 +92,6 @@ df_arome = arome_client.get_coverage(
8892
)
8993
```
9094

91-
The `get_combined_coverage` method allows you to retrieve weather data for multiple indicators at the same time, streamlining the process of gathering forecasts for different parameters (e.g., temperature, wind speed, etc.). For detailed guidance on using this feature, refer to this [tutorial](https://github.com/MAIF/meteole/tree/docs/update_readme/tutorial/tutorial/Fetch_forecast_for_multiple_indicators.ipynb).
95+
The `get_combined_coverage` method allows you to retrieve weather data for multiple indicators at the same time, streamlining the process of gathering forecasts for different parameters (e.g., temperature, wind speed, etc.). For detailed guidance on using this feature, refer to this [tutorial](https://github.com/MAIF/meteole/tree/docs/update_readme/tutorial/tutorial/Fetch_forecast_for_multiple_indicators.ipynb).
96+
97+
The use of ensemble models is slightly different as they retrieve several forecast scenarios for each run. See this [tutorial](https://github.com/MAIF/meteole/tree/docs/update_readme/tutorial/tutorial/Fetch_forecasts_ensemble.ipynb) for a guided example.

src/meteole/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from importlib.metadata import version
22

33
from meteole._arome import AromeForecast
4+
from meteole._arome_ensemble import AromePEForecast
45
from meteole._arome_instantane import AromePIForecast
56
from meteole._arpege import ArpegeForecast
67
from meteole._piaf import PiafForecast
78
from meteole._vigilance import Vigilance
89

9-
__all__ = ["AromeForecast", "AromePIForecast", "ArpegeForecast", "PiafForecast", "Vigilance"]
10+
__all__ = ["AromeForecast", "AromePIForecast", "ArpegeForecast", "PiafForecast", "Vigilance", "AromePEForecast"]
1011

1112
__version__ = version("meteole")

src/meteole/_arome.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class AromeForecast(WeatherForecast):
6161
INDICATORS: list[str] = AROME_INSTANT_INDICATORS + AROME_OTHER_INDICATORS
6262
INSTANT_INDICATORS: list[str] = AROME_INSTANT_INDICATORS
6363
BASE_ENTRY_POINT: str = "wcs/MF-NWP-HIGHRES-AROME"
64+
MODEL_TYPE: str = "DETER"
65+
ENSEMBLE_NUMBERS: int = 1
6466
DEFAULT_TERRITORY: str = "FRANCE"
6567
DEFAULT_PRECISION: float = 0.01
6668
CLIENT_CLASS: type[BaseClient] = MeteoFranceClient

src/meteole/_arome_ensemble.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from __future__ import annotations
2+
3+
import logging
4+
from typing import final
5+
6+
from meteole.clients import BaseClient, MeteoFranceClient
7+
from meteole.forecast import WeatherForecast
8+
9+
logger = logging.getLogger(__name__)
10+
11+
AVAILABLE_AROME_TERRITORY: list[str] = [
12+
"FRANCE",
13+
"NCALED",
14+
"INDIEN",
15+
"POLYN",
16+
"GUYANE",
17+
"ANTIL",
18+
]
19+
20+
AROME_INSTANT_INDICATORS: list[str] = [
21+
"BRIGHTNESS_TEMPERATURE__GROUND_OR_WATER_SURFACE",
22+
"BRIGHTNESS_TEMPERATURE_CHANNEL62__GROUND_OR_WATER_SURFACE",
23+
"INHIBITION_CONVECTIVE__GROUND_OR_WATER_SURFACE",
24+
"TOTAL_WATER_VAPOUR__GROUND_OR_WATER_SURFACE",
25+
"RELATIVE_DIVERGENCE__ISOBARIC_SURFACE",
26+
"RELATIVE_HUMIDITY__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
27+
"RELATIVE_HUMIDITY__ISOBARIC_SURFACE",
28+
"LOW_CLOUD_COVER__GROUND_OR_WATER_SURFACE",
29+
"PRECIPITATION_TYPE_MOST_SEVERE__GROUND_OR_WATER_SURFACE",
30+
"PRECIPITATION_TYPE__GROUND_OR_WATER_SURFACE",
31+
"PRESSURE__MEAN_SEA_LEVEL",
32+
"REFLECTIVITY_MAXIMUM__GROUND_OR_WATER_SURFACE",
33+
"REFLECTIVITY_DBZ__ISOBARIC_SURFACE",
34+
"MAXIMUM_TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
35+
"MINIMUM_TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
36+
"PSEUDO_ADIABATIC_POTENTIAL_TEMPERATURE__ISOBARIC_SURFACE",
37+
"TEMPERATURE__GROUND_OR_WATER_SURFACE",
38+
"TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
39+
"TEMPERATURE__ISOBARIC_SURFACE",
40+
"U_COMPONENT_OF_WIND_GUST__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
41+
"U_COMPONENT_OF_WIND__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
42+
"MINIMUM_VISIBILITY_PRECIPITATING_HYDROMETEORS__GROUND_OR_WATER_SURFACE",
43+
"MINIMUM_VISIBILITY_NON_PRECIPITATING_HYDROMETEORS__GROUND_OR_WATER_SURFACE",
44+
"VERTICAL_VELOCITY_PRESSURE__ISOBARIC_SURFACE",
45+
"V_COMPONENT_OF_WIND_GUST__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
46+
"V_COMPONENT_OF_WIND__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND",
47+
"GEOPOTENTIAL__ISOBARIC_SURFACE",
48+
]
49+
50+
AROME_OTHER_INDICATORS: list[str] = [
51+
"TOTAL_WATER_PRECIPITATION__GROUND_OR_WATER_SURFACE",
52+
"TOTAL_GRAUPEL_PRECIPITATION__GROUND_OR_WATER_SURFACE",
53+
"LIGHTNING_DENSITY_CUMULATED__GROUND_OR_WATER_SURFACE",
54+
"TOTAL_SNOW_PRECIPITATION__GROUND_OR_WATER_SURFACE",
55+
"TOTAL_PRECIPITATION__GROUND_OR_WATER_SURFACE",
56+
]
57+
58+
59+
@final
60+
class AromePEForecast(WeatherForecast):
61+
"""Access the PE-AROME ensemble forecast data from Meteo-France API."""
62+
63+
MODEL_NAME: str = "pearome"
64+
BASE_ENTRY_POINT: str = "wcs/MF-NWP-HIGHRES-PEARO"
65+
MODEL_TYPE: str = "ENSEMBLE"
66+
ENSEMBLE_NUMBERS: int = 25
67+
DEFAULT_TERRITORY: str = "FRANCE"
68+
CLIENT_CLASS: type[BaseClient] = MeteoFranceClient
69+
INDICATORS: list[str] = AROME_INSTANT_INDICATORS + AROME_OTHER_INDICATORS
70+
INSTANT_INDICATORS: list[str] = AROME_INSTANT_INDICATORS
71+
72+
def __init__(self, client=None, **kwargs):
73+
super().__init__(client, precision=0.025, **kwargs)
74+
75+
def _validate_parameters(self) -> None:
76+
"""Check the territory and the precision parameters.
77+
78+
Raise:
79+
ValueError: At least, one parameter is not good.
80+
"""
81+
if self.precision != 0.025:
82+
raise ValueError("Parameter `precision` must be 0.025")
83+
84+
if self.territory not in AVAILABLE_AROME_TERRITORY:
85+
raise ValueError(f"Parameter `territory` must be in {AVAILABLE_AROME_TERRITORY}")

src/meteole/_arome_instantane.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class AromePIForecast(WeatherForecast):
7171
INDICATORS: list[str] = AROMEPI_INSTANT_INDICATORS + AROMEPI_OTHER_INDICATORS
7272
INSTANT_INDICATORS: list[str] = AROMEPI_INSTANT_INDICATORS
7373
BASE_ENTRY_POINT: str = "wcs/MF-NWP-HIGHRES-AROMEPI"
74+
MODEL_TYPE: str = "DETER"
75+
ENSEMBLE_NUMBERS: int = 1
7476
DEFAULT_TERRITORY: str = "FRANCE"
7577
DEFAULT_PRECISION: float = 0.01
7678
CLIENT_CLASS: type[BaseClient] = MeteoFranceClient

src/meteole/_arpege.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ class ArpegeForecast(WeatherForecast):
7979
INDICATORS: list[str] = ARPEGE_INSTANT_INDICATORS + ARPEGE_OTHER_INDICATORS
8080
INSTANT_INDICATORS: list[str] = ARPEGE_INSTANT_INDICATORS
8181
BASE_ENTRY_POINT: str = "wcs/MF-NWP-GLOBAL-ARPEGE"
82+
MODEL_TYPE: str = "DETER"
83+
ENSEMBLE_NUMBERS: int = 1
8284
DEFAULT_TERRITORY: str = "EUROPE"
8385
RELATION_TERRITORY_TO_PREC_ARPEGE: dict[str, float] = {"EUROPE": 0.1, "GLOBE": 0.25, "ATOURX": 0.1, "EURAT": 0.05}
8486
CLIENT_CLASS: type[BaseClient] = MeteoFranceClient

0 commit comments

Comments
 (0)