import numpy as np
import glob
import datetime
import os
import pandas as pd
import xarray as xr
from .....utils.classes.setup import Setup
from .....utils.classes.domains import Domain
import copy
from logging import debug
import itertools
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 CAMS grid Domain from one of the tracer's input files.
Reads longitude/latitude from the first available input file,
computes cell corners assuming a regular grid, and builds the
vertical hybrid-sigma coordinates either as interface values
(``ap``/``bp``, read from the file, or from a CSV given by
``tracer.aibi_file`` when ``tracer.aibi_name`` is set) or as
mid-level values (``hyam``/``hybm``).
Args:
ref_dir: unused, accepted for interface compatibility.
ref_file: unused, accepted for interface compatibility.
input_interval: unused, accepted for interface compatibility.
target_dir: unused, accepted for interface compatibility.
tracer: the fields Plugin; ``tracer.input_files`` is used to find
a reference file, and ``tracer.aibi_name``/``tracer.aibi_file``
control how the vertical coordinate is resolved.
Returns:
Domain: the CAMS grid domain.
Raises:
CifError: if no reference file can be found among
``tracer.input_files``.
"""
domain_file = list(itertools.chain.from_iterable(
tracer.input_files.values()))[0]
if not os.path.isfile(domain_file):
raise CifError(f"Could not initialize the domain as no reference file is available. Expecting the following file: {ref_file}")
debug(f'Domain file for CAMS BCs: {domain_file}')
with _hdf5_lock:
nc = xr.open_dataset(domain_file, decode_times=False)
# Read lon/lat in domain_file
lon = nc["longitude"]
lat = nc["latitude"]
# must be increasing
if lat[1] < lat[0]:
lat = np.flip(lat)
nlon = lon.size
nlat = lat.size
zlon, zlat = np.meshgrid(lon, lat)
# Compute corners
dlat = np.unique(np.diff(lat))[0]
dlon = np.unique(np.diff(lon))[0]
latc = np.append(lat - dlat / 2, lat[-1] + dlat / 2)
lonc = np.append(lon - dlon / 2, lon[-1] + dlon / 2)
zlonc, zlatc = np.meshgrid(lonc, latc)
zlatc = np.minimum(np.maximum(zlatc, -90), 90)
# Read vertical information in domain_file
if getattr(tracer, 'aibi_name', False):
# if tracer.aibi_name:
if hasattr(tracer, "aibi_file"):
aibi_file = tracer.aibi_file
tab = pd.read_csv(aibi_file, sep=',', header=0, usecols=[0, 1, 2])
sigma_a = tab.values[::-1, 1]
sigma_b = tab.values[::-1, 2]
else:
sigma_a = nc["ap"].values
sigma_b = nc["bp"].values
nlevs = sigma_b.size - 1
domain = Domain(
nlon=nlon, nlat=nlat, zlon=zlon, zlat=zlat,
zlonc=zlonc, zlatc=zlatc,
pressure_unit="Pa", lon_cyclic=True, nlev=nlevs,
sigma_a=sigma_a, sigma_b=sigma_b
)
else:
sigma_a_mid = nc["hyam"].values
sigma_b_mid = nc["hybm"].values
nlevs = sigma_a_mid.size
domain = Domain(
nlon=nlon, nlat=nlat, zlon=zlon, zlat=zlat,
zlonc=zlonc, zlatc=zlatc,
pressure_unit="Pa", lon_cyclic=True, nlev=nlevs,
sigma_a_mid=sigma_a_mid, sigma_b_mid=sigma_b_mid
)
# Initializes domain
return domain