ERA5 data download and accessΒΆ

Functions to access downloaded ERA5 data:

# Functions to load ERA5 monthly data

import os
import iris
import iris.util
import iris.coord_systems
import numpy as np

# Don't really understand this, but it gets rid of the error messages.
iris.FUTURE.datum_support = True

# ERA5 data does not have explicit coodinate systems
# Specify one to add on load so the cubes work properly with iris.
cs_ERA5 = iris.coord_systems.RotatedGeogCS(90, 180, 0)


# And a function to add the coord system to a cube (in-place)
def add_coord_system(cbe):
    cbe.coord("latitude").coord_system = cs_ERA5
    cbe.coord("longitude").coord_system = cs_ERA5


def load(
    variable="total_precipitation", year=None, month=None, constraint=None, grid=None
):
    if variable == "land_mask":
        varC = load("sea_surface_temperature", year=2020, month=3, grid=grid)
        varC.data.data[np.where(varC.data.mask == True)] = 0
        varC.data.data[np.where(varC.data.mask == False)] = 1
        return varC
    if year is None or month is None:
        raise Exception("Year and month must be specified")
    fname = "%s/ERA5/monthly/reanalysis/%04d/%s.nc" % (
        os.getenv("SCRATCH"),
        year,
        variable,
    )
    if not os.path.isfile(fname):
        raise Exception("No data file %s" % fname)
    ftt = iris.Constraint(time=lambda cell: cell.point.month == month)
    varC = iris.load_cube(fname, ftt)
    # Get rid of unnecessary height dimensions
    if len(varC.data.shape) == 3:
        varC = varC.extract(iris.Constraint(expver=1))
    add_coord_system(varC)
    varC.long_name = variable
    if grid is not None:
        varC = varC.regrid(grid, iris.analysis.Nearest())
    if constraint is not None:
        varC = varC.extract(constraint)
    return varC


Script to download a year of ERA5 data:

#!/usr/bin/env python

# Retrieve ERA5 monthly averages.
#  Every month in one year

import os
import cdsapi
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--variable", help="Variable name", type=str, required=True)
parser.add_argument("--year", help="Year", type=int, required=True)
parser.add_argument(
    "--opdir",
    help="Directory for output files",
    default="%s/ERA5/monthly/reanalysis" % os.getenv("SCRATCH"),
)
args = parser.parse_args()
args.opdir += "/%04d" % args.year
if not os.path.isdir(args.opdir):
    os.makedirs(args.opdir, exist_ok=True)


ctrlB = {
    "format": "netcdf",
    "product_type": "monthly_averaged_reanalysis",
    "variable": args.variable,
    "year": ["%04d" % args.year],
    "month": ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"],
    "time": "00:00",
}

c = cdsapi.Client()
c.retrieve(
    "reanalysis-era5-single-levels-monthly-means",
    ctrlB,
    "%s/%s.nc" % (args.opdir, args.variable),
)

Script to download all the ERA5 data:

#!/usr/bin/env python

# Get monthly ERA5 data for several years, and store on SCRATCH.

import os
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--startyear", type=int, required=False, default=1940)
parser.add_argument("--endyear", type=int, required=False, default=2023)
args = parser.parse_args()

for year in range(args.startyear, args.endyear + 1):
    for var in [
        "2m_temperature",
        "sea_surface_temperature",
        "mean_sea_level_pressure",
        "total_precipitation",
    ]:
        opfile = "%s/ERA5/monthly/reanalysis/%04d/%s.nc" % (
            os.getenv("SCRATCH"),
            year,
            var,
        )
        if not os.path.isfile(opfile):
            print(
                ("./get_year_of_monthlies_from_ERA5.py --year=%d --variable=%s")
                % (
                    year,
                    var,
                )
            )