Source code for pycif.plugins.datastreams.fluxes.orchidee.read
import numpy as np
import xarray as xr
from logging import debug
import xarray as xr
from netCDF4 import Dataset
import pandas as pd
from .....utils.hdf5 import _hdf5_lock
[docs]
def read(
self,
name,
varnames,
dates,
files,
interpol_flx=False,
tracer=None,
model=None,
ddi=None,
**kwargs
):
"""Get fluxes from raw ORCHIDEE files and load them into a pyCIF variable.
For each requested date/file pair, determines the file's time values
(reading the ``time`` variable, or synthesizing it from
`tracer.timeresol` if absent), shifting to period start if the values
mark period midpoints. If `tracer.interpol_resolution` is not set,
selects the exact matching time index; otherwise, linearly interpolates
the variable between the two time steps surrounding the midpoint of the
requested interval.
Args:
name (str): name of the component
varnames (list[str]): original names of variables to read; use `name`
if `varnames` is empty
dates (list): list of the date intervals to extract
files (list): list of the files matching dates
interpol_flx (bool): Unused directly, kept for interface
consistency with other flux plugins.
tracer: The flux tracer plugin, providing ``timeresol`` and,
optionally, ``interpol_resolution``.
model: Unused directly, kept for interface consistency.
ddi: Unused directly, kept for interface consistency.
Return:
xr.DataArray: the actual data with dimension:
time, levels, latitudes, longitudes
"""
var2extract = varnames if varnames != "" else name
# Loop over dates/files and import data
data = []
out_dates = []
for dd, ff in zip(dates, files):
debug(
f"Reading the file {ff} for the date interval {dd}"
)
# Read the file to fetch dates
with _hdf5_lock:
with Dataset(ff, "r") as f:
isvar = "time" in f.variables
times = xr.open_dataset(ff)["time"].values
# Define dates if not a variable
if not isvar:
times = pd.date_range(ddi, periods=len(times),
freq=tracer.timeresol).values[:, np.newaxis]
# Shift dates if in variables as the middle of periods is specified
freq = np.unique(np.diff(times))
if isvar and not hasattr(tracer, "interpol_resolution"):
times -= freq / 2
# Fetch correct index
if not hasattr(tracer, "interpol_resolution"):
dref = np.datetime64(dd[0])
ind_time = np.where(times == dref)[0][0]
with _hdf5_lock:
data.append(xr.open_dataset(ff)[var2extract][ind_time].values)
else:
dtref = np.datetime64(dd[1]) - np.datetime64(dd[0])
dref = np.datetime64(dd[0]) + dtref / 2
ind_time = np.argmax(times > dref)
d0 = times[ind_time - 1]
d1 = times[ind_time]
with _hdf5_lock:
data0 = xr.open_dataset(ff)[var2extract][ind_time - 1].values
data1 = xr.open_dataset(ff)[var2extract][ind_time].values
data.append(
(dref - d0) / (d1 - d0) * data1
+ (d1 - dref) / (d1 - d0) * data0)
out_dates.append(dd[0])
# if only one level for emissions, create the axis
dataout = np.array(data)[:, np.newaxis]
dataout[np.isnan(dataout)] = 0
xmod = xr.DataArray(
dataout,
coords={"time": out_dates},
dims=("time", "lev", "lat", "lon"),
)
return xmod