Source code for pangaea.read
# -*- coding: utf-8 -*-
#
# read.py
# pangaea
#
# Author : Alan D Snow, 2017.
# License: BSD 3-Clause
"""pangea.read
This module provides helper functions to read in
land surface model datasets.
"""
import numpy as np
import pandas as pd
import xarray as xr
[docs]def open_mfdataset(path_to_lsm_files,
lat_var,
lon_var,
time_var,
lat_dim,
lon_dim,
time_dim,
lon_to_180=False,
coords_projected=False,
loader=None,
engine=None,
autoclose=True):
"""
Wrapper to open land surface model netcdf files
using :func:`xarray.open_mfdataset`.
.. warning:: The time dimension and variable will both be
renamed to 'time' to enable slicing.
Parameters
----------
path_to_lsm_files: :obj:`str`
Path to land surface model files with wildcard.
(Ex. '/path/to/files/*.nc')
lat_var: :obj:`str`
Latitude variable (Ex. lat).
lon_var: :obj:`str`
Longitude variable (Ex. lon).
time_var: :obj:`str`
Time variable (Ex. time).
lat_dim: :obj:`str`
Latitude dimension (Ex. lat).
lon_dim: :obj:`str`
Longitude dimension (Ex. lon).
time_dim: :obj:`str`
Time dimension (ex. time).
lon_to_180: bool, optional, default=False
It True, will convert longitude from [0 to 360]
to [-180 to 180].
coords_projected: bool, optional, default=False
It True, it will assume the coordinates are already
in the projected coordinate system.
loader: str, optional, default=None
If 'hrrr', it will load in the HRRR dataset.
engine: str, optional
See: :func:`xarray.open_mfdataset` documentation.
autoclose: :obj:`str`, optional, default=True
If True, will use autoclose option with
:func:`xarray.open_mfdataset`.
Returns
-------
:func:`xarray.Dataset`
Read with pangaea example::
import pangaea as pa
with pa.open_mfdataset('/path/to/ncfiles/*.nc',
lat_var='lat',
lon_var='lon',
time_var='time',
lat_dim='lat',
lon_dim='lon',
time_dim='time') as xds:
print(xds.lsm.projection)
"""
def define_coords(xds):
"""xarray loader to ensure coordinates are loaded correctly"""
# remove time dimension from lat, lon coordinates
if xds[lat_var].ndim == 3:
xds[lat_var] = xds[lat_var].squeeze(time_dim)
# make sure coords are defined as coords
if lat_var not in xds.coords \
or lon_var not in xds.coords \
or time_var not in xds.coords:
xds.set_coords([lat_var, lon_var, time_var],
inplace=True)
return xds
def extract_hrrr_date(xds):
"""xarray loader for HRRR"""
for var in xds.variables:
if 'initial_time' in xds[var].attrs.keys():
grid_time = pd.to_datetime(xds[var].attrs['initial_time'],
format="%m/%d/%Y (%H:%M)")
if 'forecast_time' in xds[var].attrs.keys():
time_units = 'h'
if 'forecast_time_units' in xds[var].attrs.keys():
time_units = \
str(xds[var].attrs['forecast_time_units'][0])
time_dt = int(xds[var].attrs['forecast_time'][0])
grid_time += np.timedelta64(time_dt, time_units)
return xds.assign(time=grid_time)
return xds
if loader == 'hrrr':
preprocess = extract_hrrr_date
engine = 'pynio' if engine is None else engine
else:
preprocess = define_coords
xds = xr.open_mfdataset(path_to_lsm_files,
autoclose=autoclose,
preprocess=preprocess,
concat_dim=time_dim,
engine=engine,
)
xds.lsm.y_var = lat_var
xds.lsm.x_var = lon_var
xds.lsm.y_dim = lat_dim
xds.lsm.x_dim = lon_dim
xds.lsm.lon_to_180 = lon_to_180
xds.lsm.coords_projected = coords_projected
# make sure time dimensions are same for slicing
xds.rename(
{
time_dim: 'time',
time_var: 'time',
},
inplace=True
)
xds.lsm.to_datetime()
return xds