Source code for pycif.plugins.datastreams.backgrounds.tm5_background.read

import xarray as xr
import numpy as np
from netCDF4 import Dataset
import datetime
import pandas as pd
from .....utils.datastores.empty import init_empty
from .....utils.hdf5 import _hdf5_lock


[docs] def read( self, name, varnames, dates, files, interpol_flx=False, tracer=None, model=None, **kwargs ): """Read TM5-4DVAR background concentrations into a pyCIF datastore. Iterates over the unique files referenced in ``files``; for each new file, decodes the station-ID variable (``tracer.id_varname``) into station/network/agl (above-ground-level) components, reads the time stamps (``tracer.time_varname``) and the simulated-concentration array (``self.varname``), meshes stations against time stamps, and packs the result into an empty pyCIF datastore. Note: Only the datastore built from the last (in iteration order) distinct file in ``files`` is returned: ``ds`` is reassigned on each new file rather than accumulated/concatenated across files. Args: self: the background datastream Plugin. name: name of the observed parameter/component. varnames: unused (kept for interface consistency with other datastream ``read`` functions). dates: list of ``[start, end]`` date pairs, aligned with ``files``. files: list of TM5-4DVAR annual background files, aligned with ``dates``. Consecutive duplicate entries are only read once. interpol_flx (bool): unused here (kept for interface consistency). tracer: the background tracer, used for ``id_varname``, ``time_varname`` and the ``numscale`` scaling factor. model: unused here (kept for interface consistency). Returns: pandas.DataFrame: pyCIF datastore (as built by ``init_empty``) for the last file processed, with ``date``, ``station``, ``network``, ``parameter`` and ``duration`` metadata columns, and ``obserror``/ ``spec`` main-data columns. """ trcr_bc = [] out_dates = [] ref_file = "" for dd, ff in zip(dates, files): if ff != ref_file: ref_file = ff with _hdf5_lock: with Dataset(ff) as bkg: # Station ids ids = [''.join([c.decode().lower() for c in name]) for name in bkg[tracer.id_varname][:]] ids = pd.Series(ids).str.split("_", expand=True) stations = ids[0].values network = ids[1].values agl = ids[2].values # Time steps ts = np.array([ datetime.datetime(*t) for t in bkg[tracer.time_varname][:] ]) # Simulations from TM5 data = bkg.variables[self.varname][:] mesh_stat, mesh_ts = np.meshgrid(stations, ts) mesh_network, mesh_ts = np.meshgrid(network, ts) mesh_agl, mesh_ts = np.meshgrid(agl, ts) ds = init_empty() ds[("metadata", "date")] = mesh_ts.flatten() ds[("metadata", "station")] = mesh_stat.flatten() ds[("metadata", "network")] = mesh_network.flatten() ds[("metadata", "parameter")] = name ds[("metadata", "duration")] = 1 ds[("maindata", "obserror")] = 0 ds[("maindata", "spec")] = \ data.flatten() * getattr(tracer, "numscale", 1) return ds