from logging import debug
import numpy as np
import pandas as pd
import xarray as xr
[docs]
def read(
self,
name,
varnames,
dates,
files,
interpol_flx=False,
tracer=None,
model=None,
**kwargs,
):
"""Get fluxes from pre-computed fluxes and load them into a pycif
variables
Args:
self: the model Plugin
name: the name of the component
tracdir, tracfile: flux directory and file format
dates: list of dates to extract
interpol_flx (bool): if True, interpolates fluxes at time t from
values of surrounding available files
"""
debug("Reading LMDZ sflx files for {} dates".format(len(dates)))
# Reading fluxes for periods within the simulation window
trcr_flx = []
trcr_dates = []
for dd, file_flx in zip(dates, files):
debug("Decoding sflx file {} for date {}".format(file_flx, dd[0]))
nc = xr.open_dataset(file_flx, decode_times=False)
nlon = self.domain.nlon
nlat = self.domain.nlat
# Keeps only values for the corresponding date
# Assumes monthly resolution
times = xr.open_dataset(file_flx)["time"][:]
# Round dates
times = times.to_dataframe()["time"].dt.round("h").values
# Check if monthly resolution
freq = np.unique(np.diff(times))
times = pd.DatetimeIndex(times)
if len(freq) != 1 and np.all(pd.TimedeltaIndex(np.diff(times)).days >= 28):
times -= (times.day - 1) * pd.Timedelta("1D") + times.hour * pd.Timedelta(
"1h"
)
# Shift year if using a fixed file
year_ref = times.year.min()
if dd[0].year != year_ref:
times = times + pd.DateOffset(years=dd[0].year - year_ref)
ind_date = np.where(
np.abs(times - np.datetime64(dd[0])) < np.timedelta64(1, "s")
)[0][0]
# Vector to map
# Deals with polar boxes by sub-dividing them zonally
# Also loops zonally for consistency with other call to gridded values
flx = nc[varnames].values[ind_date, ...]
flx0 = flx[0]
flx1 = flx[-1]
flx = flx[1:-1].reshape((nlat - 2, nlon - 1))
flx = np.append(
flx,
flx1[np.newaxis, np.newaxis] * np.ones((1, nlon - 1)),
axis=0,
)
flx = np.append(
flx0[np.newaxis, np.newaxis] * np.ones((1, nlon - 1)),
flx,
axis=0,
)
flx = np.append(flx, flx[:, np.newaxis, 0], axis=1)
trcr_flx.append(flx)
trcr_dates.append(dd[0])
# # Interpolating fluxes temporally between file values
# if interpol_flx:
# weights = []
# weights_inds = []
# for flx_file, flx, dd in zip(files, trcr_flx, dates):
# inds = [
# k for k, flxx in enumerate(trcr_flx) if np.all(flx == flxx)
# ]
# w0 = dd - dates[inds[0]]
# w1 = dates[min(inds[-1] + 1, len(dates) - 1)] - dd
# dt = w1 + w0
# w0 = w0.total_seconds() / float(dt.total_seconds())
# w1 = w1.total_seconds() / float(dt.total_seconds())
# weights.append((w0, w1))
# weights_inds.append((inds[0], min(inds[-1] + 1, len(dates) - 1)))
#
# trcr_flx_interp = []
# for k, ((w0, w1), (i0, i1)) in enumerate(zip(weights, weights_inds)):
# trcr_flx_interp.append(trcr_flx[i0] * w1 + trcr_flx[i1] * w0)
# trcr_flx = trcr_flx_interp
xmod = xr.DataArray(
np.array(trcr_flx)[:, np.newaxis, ...],
coords={"time": trcr_dates},
dims=("time", "lev", "lat", "lon"),
)
return xmod