Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions src/DataWrangling/ERA5/ERA5_single_levels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ end
##### ERA5 single-level variable name mappings
#####

# Variable name mappings from NumericalEarth names to ERA5/CDS API variable names
# Variable name mappings from NumericalEarth names to ERA5/CDS API variable names.
# Invariant fields (surface geopotential, land-sea mask) are requested like instantaneous
# variables: the CDS returns the same field for every date.
ERA5_dataset_variable_names = Dict(
:temperature => "2m_temperature",
:dewpoint_temperature => "2m_dewpoint_temperature",
Expand Down Expand Up @@ -66,6 +68,12 @@ ERA5_dataset_variable_names = Dict(
:total_column_water_vapor => "total_column_water_vapour",
:vertically_integrated_eastward_water_vapor_flux => "vertical_integral_of_eastward_water_vapour_flux",
:vertically_integrated_northward_water_vapor_flux => "vertical_integral_of_northward_water_vapour_flux",
:boundary_layer_height => "boundary_layer_height",
:convective_available_potential_energy => "convective_available_potential_energy",
:convective_precipitation => "convective_precipitation",
:land_sea_mask => "land_sea_mask",
:sea_ice_concentration => "sea_ice_cover",
:forecast_albedo => "forecast_albedo",
)

# NetCDF short variable names (what's actually in the downloaded files)
Expand Down Expand Up @@ -101,6 +109,12 @@ ERA5_netcdf_variable_names = Dict(
:total_column_water_vapor => "tcwv",
:vertically_integrated_eastward_water_vapor_flux => "viwve",
:vertically_integrated_northward_water_vapor_flux => "viwvn",
:boundary_layer_height => "blh",
:convective_available_potential_energy => "cape",
:convective_precipitation => "cp",
:land_sea_mask => "lsm",
:sea_ice_concentration => "siconc", # shortName: ci
:forecast_albedo => "fal",
)

# Variables available for download
Expand All @@ -116,10 +130,10 @@ DataWrangling.dataset_variable_name(md::ERA5Metadata) = ERA5_netcdf_variable_nam
# - `topography` divides the (surface) geopotential by g to give ERA5's model
# surface elevation in meters (`geopotential` is left in m² s⁻²);
# - downwelling SW/LW are hourly-accumulated energy (J/m²) → mean flux (W/m²);
# - total precipitation is an hourly-accumulated depth (m) → mass flux (kg/m²/s).
# - total and convective precipitation are hourly-accumulated depths (m) → mass flux (kg/m²/s).
function DataWrangling.conversion_units(md::ERA5Metadata)
md.name == :topography && return InverseGravity()
md.name == :total_precipitation && return MetersPerHour()
md.name == :topography && return InverseGravity()
md.name in (:total_precipitation, :convective_precipitation) && return MetersPerHour()
md.name in (:downwelling_shortwave_radiation, :downwelling_longwave_radiation) &&
return JoulesPerSquareMeterPerHour()
return nothing
Expand All @@ -130,6 +144,7 @@ DataWrangling.default_inpainting(md::ERA5Metadata) = nothing
# ERA5 accumulations and mean rates cover the hour *ending* at the stamp, so their windows run
# backwards from it. Every other single-level variable is instantaneous.
const ERA5_window_averaged_variables = (:total_precipitation,
:convective_precipitation,
:evaporation,
:mean_evaporation_rate,
:downwelling_shortwave_radiation,
Expand Down
14 changes: 13 additions & 1 deletion test/test_cds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ start_date = DateTime(2005, 2, 16, 12)
@test ERA5_dataset_variable_names[:temperature] == "2m_temperature"
@test ERA5_dataset_variable_names[:eastward_velocity] == "10m_u_component_of_wind"
@test ERA5_dataset_variable_names[:northward_velocity] == "10m_v_component_of_wind"

# CDS request names and netcdf short names from the reanalysis-era5-single-levels catalog
for (name, request_name, short_name) in ((:boundary_layer_height, "boundary_layer_height", "blh"),
(:convective_available_potential_energy, "convective_available_potential_energy", "cape"),
(:convective_precipitation, "convective_precipitation", "cp"),
(:land_sea_mask, "land_sea_mask", "lsm"),
(:sea_ice_concentration, "sea_ice_cover", "siconc"),
(:forecast_albedo, "forecast_albedo", "fal"))
@test ERA5_dataset_variable_names[name] == request_name
@test ERA5_netcdf_variable_names[name] == short_name
end
end

@testset "ERA5 metadata properties" begin
Expand Down Expand Up @@ -134,11 +145,12 @@ start_date = DateTime(2005, 2, 16, 12)
era5m(name) = Metadatum(name; dataset=ds, date=start_date)

# Surface geopotential ÷ g → meters; accumulated SW/LW (J/m²) ÷ 3600 → W/m²;
# accumulated precip depth (m) × 1000/3600 → kg/m²/s. Others are unconverted.
# accumulated total and convective precip depth (m) × 1000/3600 → kg/m²/s. Others are unconverted.
@test conversion_units(era5m(:topography)) isa InverseGravity
@test conversion_units(era5m(:downwelling_shortwave_radiation)) isa Jm²ph
@test conversion_units(era5m(:downwelling_longwave_radiation)) isa Jm²ph
@test conversion_units(era5m(:total_precipitation)) isa MetersPerHour
@test conversion_units(era5m(:convective_precipitation)) isa MetersPerHour
@test conversion_units(era5m(:temperature)) === nothing

@test convert_units(3600, Jm²ph()) ≈ 1 # 3600 J/m²/hr → 1 W/m²
Expand Down
6 changes: 4 additions & 2 deletions test/test_metadata.jl
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ end
@testset "ERA5 accumulation windows" begin
# ERA5 accumulations and mean rates cover the hour ending at the stamp, so their windows
# run backwards from it and their nodes sit half an hour before it.
for name in (:total_precipitation, :evaporation, :mean_evaporation_rate,
for name in (:total_precipitation, :convective_precipitation, :evaporation, :mean_evaporation_rate,
:downwelling_shortwave_radiation, :downwelling_longwave_radiation,
:mean_surface_momentum_flux_x, :mean_surface_momentum_flux_y,
:mean_surface_sensible_heat_flux, :mean_surface_latent_heat_flux)
Expand All @@ -306,7 +306,9 @@ end
@test window_center(metadatum) == DateTime(2020, 4, 1, 12, 30)
end

for name in (:temperature, :surface_pressure, :eastward_velocity, :significant_wave_height)
for name in (:temperature, :surface_pressure, :eastward_velocity, :significant_wave_height,
:boundary_layer_height, :convective_available_potential_energy, :land_sea_mask,
:sea_ice_concentration, :forecast_albedo)
metadatum = Metadatum(name; dataset = ERA5HourlySingleLevel(), date = DateTime(2020, 4, 1, 13))
@test window_center(metadatum) == DateTime(2020, 4, 1, 13)
end
Expand Down
Loading