import datetime
import glob
import os
import numpy as np
import xarray as xr
from netCDF4 import Dataset
from .....utils.classes.domains import Domain
from logging import info
from .....utils.check.errclass import CifError
from .....utils.hdf5 import _hdf5_lock
[docs]
def get_domain(ref_dir, ref_file, input_interval, target_dir, tracer=None):
"""Build the horizontal domain from an EDGAR v5 reference file.
Locates a reference NetCDF file (either an exact name match for
``ref_file`` in ``ref_dir``, or the first file whose name parses
against ``ref_file`` as a date format). If ``tracer.truncated`` is set,
builds a regional domain from the file's native ``lon``/``lat``
coordinates; otherwise builds a fixed, longitude-cyclic global
0.1°x0.1° domain. In both cases a single (surface) vertical level is
used.
Args:
ref_dir (str): directory where the original files are found.
ref_file (str): (template) name of the original files.
input_interval (list): unused, kept for interface compatibility.
target_dir (str): unused, kept for interface compatibility.
tracer: the tracer Plugin, giving access to ``truncated``.
Returns:
Domain: a single-level domain, regional (``truncated``) or fixed
global 0.1°x0.1°.
Raises:
CifError: if no reference file could be found in ``ref_dir``.
"""
# Looking for a reference file to read lon/lat in
list_file = glob.glob(f"{ref_dir}/*nc")
domain_file = None
# Either a file is specified in the Yaml
if ref_file in list_file:
domain_file = f"{ref_dir}/{ref_file}"
# Or loop over available file regarding file pattern
else:
for flx_file in list_file:
try:
date = datetime.datetime.strptime(
os.path.basename(flx_file), ref_file
)
domain_file = flx_file
break
except ValueError:
continue
if domain_file is None:
raise CifError(
"EDGARv5 domain could not be initialized as no file was found"
)
# Read lon/lat in
# WARNING: Force reading from -180 to 180 or choose truncated option
if tracer.truncated:
with _hdf5_lock:
with Dataset(domain_file, "r") as f:
lon = f.variables["lon"][:]
lat = f.variables["lat"][:]
zlon, zlat = np.meshgrid(lon, lat)
# Grid cell corners
dlat = np.unique(np.diff(lat))[0]
dlon = np.unique(np.diff(lon))[0]
latc = np.append(lat - dlat * 0.5, lat[-1] + dlat * 0.5)
lonc = np.append(lon - dlon * 0.5, lon[-1] + dlon * 0.5)
zlonc, zlatc = np.meshgrid(lonc, latc)
nlon = lon.size
nlat = lat.size
domain = Domain(nlon=nlon, nlat=nlat,
zlon=zlon, zlat=zlat,
zlonc=zlonc, zlatc=zlatc,
nlev=1, pressure_unit="Pa",
sigma_b_mid=np.array([1]), sigma_a_mid=np.array([0]))
else:
lonc = np.arange(-180, 180.1, 0.1)
latc = np.arange(-90, 90.1, 0.1)
lon = 0.5 * (lonc[1:] + lonc[:-1])
lat = 0.5 * (latc[1:] + latc[:-1])
zlon, zlat = np.meshgrid(lon, lat)
zlonc, zlatc = np.meshgrid(lonc, latc)
nlat, nlon = zlat.shape
domain = Domain(nlon=nlon, nlat=nlat,
zlon=zlon, zlat=zlat,
zlonc=zlonc, zlatc=zlatc,
nlev=1, pressure_unit="Pa",
sigma_b_mid=np.array([1]), sigma_a_mid=np.array([0]),
lon_cyclic=True)
return domain