Accessing Arome Data#
using meteofrance_publicapi
Get your application ID#
See the readme for details.
The following example uses a dotfile to store the secret.
[1]:
import dotenv
import os
dotenv.load_dotenv()
application_id = os.getenv("APPLICATION_ID")
Optional : activate the logs inside the notebook#
[2]:
import logging
logging.basicConfig(level=logging.INFO)
Initialize the client#
[3]:
from meteofrance_publicapi import AromeForecast
client = AromeForecast(application_id=application_id,
cache_dir="./.cache")
INFO:numexpr.utils:NumExpr defaulting to 8 threads.
Fetch the capabilities#
It is best the first get the capabilities from the API to know what is available.
[4]:
client.get_capabilities()
client.all_coverageid_prefix
[4]:
['U_COMPONENT_OF_WIND__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'CONVECTIVE_AVAILABLE_POTENTIAL_ENERGY__GROUND_OR_WATER_SURFACE',
'HIGH_CLOUD_COVER__GROUND_OR_WATER_SURFACE',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'TOTAL_PRECIPITATION_RATE__GROUND_OR_WATER_SURFACE',
'U_COMPONENT_OF_WIND_GUST__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'TOTAL_WATER_PRECIPITATION__GROUND_OR_WATER_SURFACE',
'PRESSURE__GROUND_OR_WATER_SURFACE',
'LOW_CLOUD_COVER__GROUND_OR_WATER_SURFACE',
'V_COMPONENT_OF_WIND__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'V_COMPONENT_OF_WIND_GUST__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'GEOMETRIC_HEIGHT__GROUND_OR_WATER_SURFACE',
'RELATIVE_HUMIDITY__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'WIND_SPEED_GUST__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'BRIGHTNESS_TEMPERATURE__GROUND_OR_WATER_SURFACE',
'MEDIUM_CLOUD_COVER__GROUND_OR_WATER_SURFACE',
'TOTAL_SNOW_PRECIPITATION__GROUND_OR_WATER_SURFACE',
'WIND_SPEED__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND',
'TOTAL_PRECIPITATION__GROUND_OR_WATER_SURFACE']
As you can see from the coverage ID prefixes, quite a lot are available ! Lets use the temperature for this example.
[5]:
coverage_name = "TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND"
coverageids = client.all_coverageid_of_name(coverage_name)
coverageids
[5]:
['TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T00.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T03.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T06.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T09.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T12.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T15.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T18.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-01T21.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T00.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T03.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T06.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T09.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T12.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T15.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T18.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-02T21.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T00.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T03.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T06.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T09.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T12.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T15.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T18.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-03T21.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T00.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T03.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T06.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T09.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T12.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T15.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T18.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-04T21.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T00.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T03.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T06.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T09.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T12.00.00Z',
'TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T15.00.00Z']
The coverageids
corresponds to all the forecast computation available for this Temperature field. This example was run on 2024-05-04 at 18:00 UTC.
The computations available goes back in the past up to 2024-04-01 up to the latests run available, today at 12:00 UTC. Let’s use the latests.
[6]:
coverageid = coverageids[-1]
description = client.get_description(coverageid)
Here, description is a dict with a lot of information. For instance, you can get the limits of the domain with the following:
[7]:
description["wcs:CoverageDescriptions"]["wcs:CoverageDescription"]["gml:boundedBy"]
[7]:
{'gml:EnvelopeWithTimePeriod': {'@srsName': 'http://meteofrance.fr/def/crs/3DLongLatHeight',
'@axisLabels': 'long lat height time',
'@uomLabels': 'deg deg m ISO8601',
'@srsDimension': '3',
'gml:lowerCorner': '-12.0 37.5 2',
'gml:upperCorner': '16.0 55.4 2',
'gml:beginPosition': {'@frame': '#ISO-8601',
'#text': '2024-04-05T15:00:00Z'},
'gml:endPosition': {'@frame': '#ISO-8601', '#text': '2024-04-07T18:00:00Z'}}}
You can see that
longitude spans from -12° et 16°
latitude spans from 37.5° to 55.4°
height spans from 2m to 2m (hum, so there is no height ?)
time goes from 2024-04-05T15:00:00Z to 2024-04-07T10:00:00Z which means 3 days in the future !
This 4D (but really 3D) domain can only be accessed by 2D slices.
According to the few tests I did, I seems that only the 2D lat-long can be accessed, which mean one time at a time.
[8]:
temperature_filename = client.get_coverage(
coverageid=coverageid,
height=2,
time=3600, # the value for the time is a bit strange. It is the number of seconds since the start of the forecast.
lat=(37.5, 55.4),
long=(-12, 16)
)
temperature_filename
[8]:
WindowsPath('.cache/TEMPERATURE__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2024-04-05T15.00.00Z/2m_3600Z_37.5-55.4_-12-16.tiff')
[9]:
from meteofrance_publicapi.raster import plot_tiff_file
ax = plot_tiff_file(temperature_filename)
ax.set_title(ax.get_title() + "\n 1hour in the future")
[9]:
Text(0.5, 1.0, 'Temperature at 2m above ground \n computed at 2024-04-05T15.00 \n 1hour in the future')
c:\Users\antoi\.conda\envs\dev\Lib\site-packages\cartopy\mpl\style.py:76: UserWarning: facecolor will have no effect as it has been defined as "never".
warnings.warn('facecolor will have no effect as it has been '