Source code for pycif.plugins.datastreams.fluxes.GCP_1x1_N2O.get_domain

import datetime
import glob
import os
import numpy as np
import xarray as xr
from logging import debug
from .....utils.classes.setup import Setup
from .....utils.classes.domains import Domain
import copy
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 a GCP N2O 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), reads its ``LON``/``LAT`` variables (forcing latitude into increasing order), and computes cell corners assuming a regular grid spacing (a known limitation: this is not valid for irregular grids). Builds a single-level, longitude-cyclic domain. 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: unused, kept for interface compatibility. Returns: Domain: a single-level, longitude-cyclic domain. 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( "GCP domain could not be initialized as no file was found" ) debug(f'Domain file for GCP fluxes: {domain_file}') with _hdf5_lock: nc = xr.open_dataset(domain_file, decode_times=False) # Read lon/lat in domain_file lon = nc["LON"] lat = nc["LAT"] # must be increasing if lat[1] < lat[0]: lat2 = np.flip(lat) lat = copy.copy(lat2) nlon = lon.size nlat = lat.size lon_min = lon.min() lon_max = lon.max() lat_min = lat.min() lat_max = lat.max() # Compute corners #WARNING: only valid for regular grid in lat/lon -> to generalize dx = (lon[1] - lon[0]) / 2 dy = (lat[1] - lat[0]) / 2 lonc = np.linspace(lon_min - dx/2., lon_max + dx/2., nlon + 1) latc = np.linspace(lat_min - dy/2., lat_max + dy/2., nlat + 1) zlon, zlat = np.meshgrid(lon, lat) zlonc, zlatc = np.meshgrid(lonc, latc) # Read vertical information in domain_file # if relevant for emissions # XXXXXXXXX comment voir si une dimension verticale est presente? # else: dummy vertical punit = "Pa" nlevs = 1 sigma_a_mid = np.array([0]) sigma_b_mid = np.array([1]) # Put it to a domain Plugin domain = Domain(nlon=nlon, nlat=nlat, zlon=zlon, zlat=zlat, zlonc=zlonc, zlatc=zlatc, nlev=nlevs, pressure_unit="Pa", sigma_b_mid=sigma_b_mid, sigma_a_mid=sigma_a_mid, lon_cyclic=True) return domain