Source code for pycif.plugins.datastreams.fluxes.lmdz_sflx.read

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