Source code for pycif.plugins.datastreams.fields.netcdf_cams.read

import datetime
import calendar
import os
import pandas as pd
import numpy as np
import xarray as xr
from netCDF4 import Dataset

from .....utils.netcdf import readnc
from .....utils.check.errclass import CifError
from .....utils.hdf5 import _hdf5_lock


[docs] def read( self, name, varnames, dates, files, interpol_flx=False, comp_type=None, tracer=None, ddi=None, **kwargs ): """Get BCs from raw CAMS files and load them into a pyCIF variable. For each requested date, computes the time index within the monthly file from the file's number of time steps, reads the variable, and flips the latitude axis to increasing order (and the vertical axis if ``tracer.flip_level`` is set) as needed. Args: self: the BC Plugin name: the name of the component varnames: variable name to extract if different from ``name`` dates: list of ``[start, end]`` date pairs to extract files: list of file paths matching ``dates`` interpol_flx: unused, accepted for interface compatibility comp_type: unused, accepted for interface compatibility tracer: the fields Plugin; ``tracer.flip_level`` controls whether the vertical axis is flipped ddi: must not be ``None``; only used to validate the call, not otherwise referenced Returns: xarray.DataArray with dims ``(time, lev, lat, lon)``. Raises: CifError: if ``ddi`` is ``None``. """ if ddi is None: raise CifError("CAMS netCDF read function was called " "without specifying ddi") # Variable name to extract var2extract = name if varnames != "": var2extract = varnames # Reading fields for periods within the simulation window xout = [] opened_file = "" for dd, dd_file in zip(dates, files): with _hdf5_lock: # Avoid opening the file for all dates if dd_file != opened_file: ds = xr.open_dataset(dd_file) opened_file = dd_file ntimes = ds.dims["time"] freq = pd.DatetimeIndex([dd[0]]).days_in_month[0] * 24 / ntimes date_end = ds["time"].to_pandas().dt.to_pydatetime()[-1] date_index = \ ntimes - 1 - int((date_end - dd[0]) / datetime.timedelta(hours=freq)) # bottom of the atmosphere = at the beginning of the table lat = ds['latitude'] conc = ds[var2extract].values[date_index] if lat[1] < lat[0] and conc.ndim == 4: conc = conc[:, :, ::-1, :] elif lat[1] < lat[0] and conc.ndim == 3: conc = conc[:, ::-1, :] # Swap levels if required to if getattr(tracer, "flip_level", False): if conc.ndim == 4: conc = conc[:, ::-1] elif conc.ndim == 3: conc = conc[::-1] # Append to datastore xout.append(conc) xmod = xr.DataArray( np.array(xout), coords={"time": np.array(dates)[:, 0]}, dims=("time", "lev", "lat", "lon"), ) return xmod