Module gdess.data_source.observations.load
Expand source code
from gdess.operations.time import ensure_dataset_datetime64
from gdess.operations.datasetdict import DatasetDict
from gdess.operations.convert import co2_molfrac_to_ppm
import numpy as np
import xarray as xr
import os, logging
_logger = logging.getLogger(__name__)
def dataset_from_filelist(file_list: list,
vars_to_keep: list = None,
decode_times: bool = False):
"""Load ObsPack NetCDF files specified in a list and create one Dataset from them.
Parameters
----------
file_list
vars_to_keep: list
decode_times: parameter passed to Xarray.open_dataset()
Returns
-------
An xr.Dataset
"""
if vars_to_keep is None:
# These are the default variables to keep if not overridden by a passed parameter.
vars_to_keep = ['value', 'nvalue', 'value_std_dev',
'time', 'start_time', 'datetime', 'time_decimal',
'latitude', 'longitude', 'altitude', 'pressure',
'qcflag', 'dataset_platform', 'dataset_project',
'obspack_num', 'obspack_id']
ds_list = []
for i, f in enumerate(file_list):
thisds = xr.open_dataset(f, decode_times=decode_times)
# If the following variables are not present, continue loading and just make them blank DataArrays
# Otherwise, we will raise an error
possible_missing_vars = ['pressure', 'qcflag', 'value_std_dev', 'nvalue']
for pmv in possible_missing_vars:
if not (pmv in thisds.keys()):
blankarray = xr.DataArray(data=[np.nan], dims='obs', name=pmv).squeeze()
thisds = thisds.assign({pmv: blankarray})
# Only the specified variables are retained.
to_drop = []
for vname in thisds.keys():
if not (vname in vars_to_keep):
to_drop.append(vname)
newds = thisds.drop_vars(to_drop)
# Dataset attributes 'platform' and 'project' are copied to every data point along the 'obs' dimension.
n_obs = len(thisds['obs'])
newds = newds.assign(dataset_platform=xr.DataArray([thisds.attrs['dataset_platform']] * n_obs, dims='obs'))
newds = newds.assign(dataset_project=xr.DataArray([thisds.attrs['dataset_project']] * n_obs, dims='obs'))
ds_list.append(newds)
# if i > 100:
# break
ds = xr.concat(ds_list, dim='obs')
return ds
def load_data_with_regex(datadir: str,
compiled_regex_pattern=None,
) -> DatasetDict:
"""Load into memory the data from regex-defined files of Globalview+.
Parameters
----------
datadir
directory containing the Globalview+ NetCDF files.
compiled_regex_pattern
Returns
-------
dict
Names, latitudes, longitudes, and altitudes of each station
"""
# --- Go through files and extract all files found via the regex pattern search ---
# file_dict = {s.group(1): f for f in os.listdir(datadir) if (s := compiled_regex_pattern.search(f))}
file_dict = dict()
for f in os.listdir(datadir):
if s := compiled_regex_pattern.search(f):
if s.group(1) not in file_dict.keys():
file_dict[s.group(1)] = [f]
else:
file_dict[s.group(1)].append(f)
_logger.debug('%s', '\n'.join([item for sublist in
[[os.path.basename(ele) for ele in x]
for x in file_dict.values()]
for item in sublist]
)
)
ds_obs_dict = {}
site_dict = {}
for i, (sitecode, file_list) in enumerate(file_dict.items()):
ds_obs_dict[sitecode] = dataset_from_filelist([os.path.join(datadir, f) for f in file_list])
site_dict[sitecode] = {'name': ds_obs_dict[sitecode].site_name}
lats = ds_obs_dict[sitecode]['latitude'].values
lons = ds_obs_dict[sitecode]['longitude'].values
# Get the latitude and longitude of each station
# different_station_lats = np.unique(lats)
# different_station_lons = np.unique(lons)
# print(f"there are {len(different_station_lons)} different latitudes for the station: {different_station_lons}")
# Get the average lat,lon
meanlon = lons.mean()
if meanlon < 0:
meanlon = meanlon + 360
SiteLatLon = {'lat': lats.mean(), 'lon': meanlon}
_logger.info("%s. %s - %s", str(i).rjust(2), sitecode.ljust(12), SiteLatLon)
site_dict[sitecode]['lat'] = lats.mean()
site_dict[sitecode]['lon'] = meanlon
# Wrangle -- Do the things to the Obs dataset.
_logger.debug("Converting datetime format and units..")
# Do the things to the Obs dataset.
for k, v in ds_obs_dict.items():
ds_obs_dict[k] = (v
.set_coords(['time', 'time_decimal', 'latitude', 'longitude', 'altitude'])
.sortby(['time'])
.swap_dims({"obs": "time"})
.pipe(ensure_dataset_datetime64)
.rename({'value': 'co2'})
.pipe(co2_molfrac_to_ppm, co2_var_name='co2')
.set_index(obs=['time', 'longitude', 'latitude', 'altitude'])
)
#### Concatenate all sites into one large dataset, for mapping or other combined analysis purposes
ds_all = xr.concat(ds_obs_dict.values(), dim=('obs'))
return DatasetDict(ds_obs_dict)
Functions
def dataset_from_filelist(file_list: list, vars_to_keep: list = None, decode_times: bool = False)-
Load ObsPack NetCDF files specified in a list and create one Dataset from them.
Parameters
file_listvars_to_keep:listdecode_times:parameter passed to Xarray.open_dataset()
Returns
An xr.Dataset
Expand source code
def dataset_from_filelist(file_list: list, vars_to_keep: list = None, decode_times: bool = False): """Load ObsPack NetCDF files specified in a list and create one Dataset from them. Parameters ---------- file_list vars_to_keep: list decode_times: parameter passed to Xarray.open_dataset() Returns ------- An xr.Dataset """ if vars_to_keep is None: # These are the default variables to keep if not overridden by a passed parameter. vars_to_keep = ['value', 'nvalue', 'value_std_dev', 'time', 'start_time', 'datetime', 'time_decimal', 'latitude', 'longitude', 'altitude', 'pressure', 'qcflag', 'dataset_platform', 'dataset_project', 'obspack_num', 'obspack_id'] ds_list = [] for i, f in enumerate(file_list): thisds = xr.open_dataset(f, decode_times=decode_times) # If the following variables are not present, continue loading and just make them blank DataArrays # Otherwise, we will raise an error possible_missing_vars = ['pressure', 'qcflag', 'value_std_dev', 'nvalue'] for pmv in possible_missing_vars: if not (pmv in thisds.keys()): blankarray = xr.DataArray(data=[np.nan], dims='obs', name=pmv).squeeze() thisds = thisds.assign({pmv: blankarray}) # Only the specified variables are retained. to_drop = [] for vname in thisds.keys(): if not (vname in vars_to_keep): to_drop.append(vname) newds = thisds.drop_vars(to_drop) # Dataset attributes 'platform' and 'project' are copied to every data point along the 'obs' dimension. n_obs = len(thisds['obs']) newds = newds.assign(dataset_platform=xr.DataArray([thisds.attrs['dataset_platform']] * n_obs, dims='obs')) newds = newds.assign(dataset_project=xr.DataArray([thisds.attrs['dataset_project']] * n_obs, dims='obs')) ds_list.append(newds) # if i > 100: # break ds = xr.concat(ds_list, dim='obs') return ds def load_data_with_regex(datadir: str, compiled_regex_pattern=None) -> DatasetDict-
Load into memory the data from regex-defined files of Globalview+.
Parameters
datadir- directory containing the Globalview+ NetCDF files.
compiled_regex_pattern
Returns
dict- Names, latitudes, longitudes, and altitudes of each station
Expand source code
def load_data_with_regex(datadir: str, compiled_regex_pattern=None, ) -> DatasetDict: """Load into memory the data from regex-defined files of Globalview+. Parameters ---------- datadir directory containing the Globalview+ NetCDF files. compiled_regex_pattern Returns ------- dict Names, latitudes, longitudes, and altitudes of each station """ # --- Go through files and extract all files found via the regex pattern search --- # file_dict = {s.group(1): f for f in os.listdir(datadir) if (s := compiled_regex_pattern.search(f))} file_dict = dict() for f in os.listdir(datadir): if s := compiled_regex_pattern.search(f): if s.group(1) not in file_dict.keys(): file_dict[s.group(1)] = [f] else: file_dict[s.group(1)].append(f) _logger.debug('%s', '\n'.join([item for sublist in [[os.path.basename(ele) for ele in x] for x in file_dict.values()] for item in sublist] ) ) ds_obs_dict = {} site_dict = {} for i, (sitecode, file_list) in enumerate(file_dict.items()): ds_obs_dict[sitecode] = dataset_from_filelist([os.path.join(datadir, f) for f in file_list]) site_dict[sitecode] = {'name': ds_obs_dict[sitecode].site_name} lats = ds_obs_dict[sitecode]['latitude'].values lons = ds_obs_dict[sitecode]['longitude'].values # Get the latitude and longitude of each station # different_station_lats = np.unique(lats) # different_station_lons = np.unique(lons) # print(f"there are {len(different_station_lons)} different latitudes for the station: {different_station_lons}") # Get the average lat,lon meanlon = lons.mean() if meanlon < 0: meanlon = meanlon + 360 SiteLatLon = {'lat': lats.mean(), 'lon': meanlon} _logger.info("%s. %s - %s", str(i).rjust(2), sitecode.ljust(12), SiteLatLon) site_dict[sitecode]['lat'] = lats.mean() site_dict[sitecode]['lon'] = meanlon # Wrangle -- Do the things to the Obs dataset. _logger.debug("Converting datetime format and units..") # Do the things to the Obs dataset. for k, v in ds_obs_dict.items(): ds_obs_dict[k] = (v .set_coords(['time', 'time_decimal', 'latitude', 'longitude', 'altitude']) .sortby(['time']) .swap_dims({"obs": "time"}) .pipe(ensure_dataset_datetime64) .rename({'value': 'co2'}) .pipe(co2_molfrac_to_ppm, co2_var_name='co2') .set_index(obs=['time', 'longitude', 'latitude', 'altitude']) ) #### Concatenate all sites into one large dataset, for mapping or other combined analysis purposes ds_all = xr.concat(ds_obs_dict.values(), dim=('obs')) return DatasetDict(ds_obs_dict)