Accessing Arome Data#

using meteofrance_publicapi

%pip install 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 '
../_images/examples_arome_18_2.png