Source code for smos.smos_l4.interface_l4

# -*- coding: utf-8 -*-

# The MIT License (MIT)
#
# Copyright (c) 2021, TU Wien
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import numpy as np
from netCDF4 import Dataset
from smos.grid import EASE25CellGrid
from smos.interface import SMOSImg, SMOSDs


[docs] class SMOS_L4_Img(SMOSImg): """ Child-class for reading one SMOS L4 CATDS - CESBIO RZSM netcdf image file. Parameters ---------- filename: str filename of the SMOS nc image file mode: str, optional (default: 'r') mode of opening the file, only 'r' is implemented at the moment parameters : str or list, optional (default: None) one or list of parameters to read. We add 'Quality_Flags' if 'read_flags' is not None. All parameters are described in docs/varnames.rst. If None is passed, all parameters are read. flatten: bool, optional (default: False) If set then the data is read into 1D arrays. This is used to e.g reshuffle the data. grid : pygeogrids.CellGrid, optional (default: EASE25CellGrid) Grid that the image data is organised on, by default the global EASE25 grid is used. read_flags : tuple, list, np.array or None, optional (default: np.linspace(0,1,6,endpoint=True)) Filter values to read based on the selected quality flags. Values for locations that are not assigned any of the here passed flags are replaced with NaN (by default only the missing-data, i.e. flag=-1, are filtered out). If None is passed, no flags are considered. oper : bool, optional (default: False) Boolean operator distinguishing between the SMOS L4 RZSM Scientific and Operational products. Distinction is made due to differences in quality flag variable naming, values and their significance (see docs/varnames.rst). float_fillval : float or None, optional (default: np.nan) Fill Value for masked pixels, this is only applied to float variables. Therefore e.g. mask variables are never filled but use the fill value as in the data. """ def __init__(self, filename, mode='r', parameters=None, flatten=False, grid=EASE25CellGrid(bbox=None), read_flags=np.linspace(0,1,6,endpoint=True), oper=False, float_fillval=np.nan): super().__init__(filename, mode=mode) if parameters is None: parameters = [] if type(parameters) != list: parameters = [parameters] self.read_flags = read_flags self.parameters = parameters self.flatten = flatten self.oper = oper self.grid = grid self.image_missing = False self.img = None # to be loaded self.glob_attrs = None self.float_fillval = float_fillval def _read_img(self) -> (dict, dict): # Read a netcdf image and metadata ds = Dataset(self.filename) self.glob_attrs = ds.__dict__ param_img = {} param_meta = {} if len(self.parameters) == 0: # all data vars, exclude coord vars self.parameters = [k for k in ds.variables.keys() if ds.variables[k].ndim != 1] parameters = list(self.parameters) if not self.oper: if (self.read_flags is not None) and ('QUAL' not in parameters): parameters.append('QUAL') else: if (self.read_flags is not None) and ('Quality' not in parameters): parameters.append('Quality') for parameter in parameters: metadata = {} param = ds.variables[parameter] data = param[:] # read long name, FillValue and unit for attr in param.ncattrs(): metadata[attr] = param.getncattr(attr) data.mask = ~np.isfinite(data) np.ma.set_fill_value(data, metadata['_FillValue']) metadata['image_missing'] = 0 param_img[parameter] = data param_meta[parameter] = metadata # filter with the flags (this excludes non-land points as well) if self.read_flags is not None: if not self.oper: flag_mask = ~np.isin(param_img['QUAL'], self.read_flags) else: flag_mask = ~np.isin(param_img['Quality'], self.read_flags) else: flag_mask = np.full(param_img[parameters[0]].shape, False) for param, data in param_img.items(): param_img[param].mask = (data.mask | flag_mask) if self.float_fillval is not None: if issubclass(data.dtype.type, np.floating): param_img[param] = data.filled(fill_value=self.float_fillval) param_img[param] = param_img[param].flatten()[self.grid.activegpis] if not self.oper: if ('QUAL' in param_img.keys()) and \ ('QUAL' not in self.parameters): param_img.pop('QUAL') param_meta.pop('QUAL') else: if ('Quality' in param_img.keys()) and \ ('Quality' not in self.parameters): param_img.pop('Quality') param_meta.pop('Quality') return param_img, param_meta
[docs] class SMOS_L4_Ds(SMOSDs): """ Class for reading SMOS L4 CATDS - CESBIO RZSM images in nc format. Images are orgnaised in subdirs for each year. Parameters ---------- data_path : str Path to the nc files parameters : str or list, optional (default: None) one or list of parameters to read. We add quality flags if 'read_flags' is not None. All parameters are described in docs/varnames.rst. If None is passed, all parameters are read. flatten: bool, optional (default: False) If set then the data is read into 1D arrays. This is used to e.g reshuffle the data. grid : pygeogrids.CellGrid, optional (default: EASE25CellGrid) Grid that the image data is organised on, by default the global EASE25 grid is used. read_flags : tuple, list, np.array or None, optional (default: np.linspace(0,1,6,endpoint=True)) Filter values to read based on the selected quality flags. Values for locations that are not assigned any of the here passed flags are replaced with NaN (by default only the missing-data, i.e. flag=-1, are filtered out). If None is passed, no flags are considered. oper : bool, optional (default: False) Boolean operator distinguishing between the SMOS L4 RZSM Scientific and Operational products. Distinction is made due to differences in quality flag variable naming, values and their significance (see docs/varnames.rst). float_fillval : float or None, optional (default: np.nan) Fill Value for masked pixels, this is only applied to float variables. Therefore e.g. mask variables are never filled but use the fill value as in the data. """ default_fname_template = "SM_*_MIR_CLF4RD*_{datetime}T000000_{datetime}T235959_*_*_*.DBL.nc" def __init__(self, data_path, parameters=None, flatten=False, grid=EASE25CellGrid(bbox=None), filename_templ=None, read_flags=np.linspace(0,1,6,endpoint=True), oper=False, float_fillval=np.nan): if filename_templ is None: filename_templ = self.default_fname_template super().__init__(data_path, ioclass=SMOS_L4_Img, parameters=parameters, flatten=flatten, grid=grid, filename_templ=filename_templ, read_flags=read_flags, float_fillval=float_fillval, additional_kws={'oper': oper} )