Source code for pygeobase.io_base

# Copyright (c) 2015, Vienna University of Technology, Department of Geodesy
# and Geoinformation. All rights reserved.

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the Vienna University of Technology, Department of
#     Geodesy and Geoinformation nor the names of its contributors may be
#     used to endorse or promote products derived from this software without
#     specific prior written permission.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL VIENNA UNIVERSITY OF TECHNOLOGY,
# DEPARTMENT OF GEODESY AND GEOINFORMATION BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import abc
import numpy as np


[docs]class StaticBase(object): pass
[docs]class TsBase(object): pass
[docs]class ImageBase(object): pass
[docs]class GriddedStaticBase(object): """ The GriddedStaticBase class uses another IO class together with a grid object to read/write a dataset under the given path. """ def __init__(self, path, grid, ioclass, mode='r', fn_format='{:04d}'): self.path = path self.grid = grid self.ioclass = ioclass self.mode = mode self.fn_format = fn_format self.previous_cell = None self.fid = None def __enter__(self): """ Context manager initialization. Returns ------- self : GriddedStaticBase object self """ return self def __exit__(self, exc_type, exc_value, traceback): """ Exit the runtime context related to this object. The file will be closed. The parameters describe the exception that caused the context to be exited. exc_type : exc_value : traceback : """ self.close() def _open(self, gpi): """ Open file. Parameters ---------- gpi : int Grid point index. """ cell = self.grid.gpi2cell(gpi) filename = os.path.join(self.path, self.fn_format.format(cell)) if self.previous_cell != cell: if self.fid is not None: self.close() self.previous_cell = cell self.fid = self.ioclass(filename, mode=self.mode)
[docs] def read(self, *args, **kwargs): """ Takes either 1 or 2 arguments and calls the correct function which is either reading the gpi directly or finding the nearest gpi from given lat,lon coordinates and then reading it """ if len(args) == 1: data = self.read_gp(args[0], **kwargs) if len(args) == 2: data = self._read_lonlat(args[0], args[1], **kwargs) return data
def _read_lonlat(self, lon, lat, **kwargs): """ Reading data for given longitude and latitude coordinate. Parameters ---------- lon : float Longitude coordinate. lat : float Latitude coordinate. Returns ------- data : dict of values data record. """ gp, _ = self.grid.find_nearest_gpi(lon, lat) return self.read_gp(gp, **kwargs)
[docs] def read_gp(self, gpi): """ Read data for given grid point. Parameters ---------- gpi : int Grid point index. Returns ------- data : numpy.ndarray Time series data. """ self._open(gpi) return self.fid.read(gpi)
[docs] def iter_gp(self): """ Yield all values for all grid points. Yields ------ data : pandas.DataFrame pandas.DateFrame with DateTimeIndex """ gpi_info = list(self.grid.grid_points()) gps = np.array(gpi_info, dtype=np.int)[:, 0] for gp in gps: yield self.read_gp(gp), gp
[docs] def write(self, data): """ Write data. Parameters ---------- data : numpy.ndarray Data records. A field 'gpi', indicating the grid point index has to be included. """ self.write_gp(data['gpi'], data)
[docs] def write_gp(self, gpi, data): """ Write data for given grid point. Parameters ---------- gpi : int Grid point index. data : numpy.ndarray Data """ self._open(gpi) self.fid.write(data)
[docs] def flush(self): """ Flush data. """ self.fid.flush()
[docs] def close(self): """ Close file. """ self.fid.close()
[docs]class GriddedTsBase(object): """ The GriddedTsBase class uses another IO class together with a grid object to read/write a time series dataset under the given path. Parameters ---------- path : string Path to dataset. grid : pytesmo.grid.grids.BasicGrid of CellGrid instance Grid on which the time series data is stored. ioclass : class IO class mode : str, optional File mode and can be read 'r', write 'w' or append 'a'. Default: 'r' cell_format : str, optional The string format of the cell files. Default: '{:04d}' """ __metaclass__ = abc.ABCMeta def __init__(self, path, grid, ioclass, mode='r', fn_format='{:04d}'): self.path = path self.grid = grid self.ioclass = ioclass self.mode = mode self.fn_format = fn_format self.previous_cell = None self.fid = None def __enter__(self): """ Context manager initialization. Returns ------- self : GriddedBaseTs object self """ return self def __exit__(self, exc_type, exc_value, traceback): """ Exit the runtime context related to this object. The file will be closed. The parameters describe the exception that caused the context to be exited. exc_type : exc_value : traceback : """ self.close() def _open(self, gpi): """ Open file. Parameters ---------- gpi : int Grid point index. """ cell = self.grid.gpi2cell(gpi) filename = os.path.join(self.path, self.fn_format.format(cell)) if self.previous_cell != cell: self.close() self.previous_cell = cell self.fid = self.ioclass(filename, mode=self.mode) def _read_lonlat(self, lon, lat, **kwargs): """ Reading time series for given longitude and latitude coordinate. Parameters ---------- lon : float Longitude coordinate. lat : float Latitude coordinate. Returns ------- data : pandas.DataFrame pandas.DateFrame with DateTimeIndex. """ gp, _ = self.grid.find_nearest_gpi(lon, lat) return self.read_gp(gp, **kwargs) def _write_lonlat(self, lon, lat, data, **kwargs): """ Write time series for given longitude and latitude coordinate. Parameters ---------- lon : float Longitude coordinate. lat : float Latitude coordinate. data : numpy.ndarray Data records. """ gp, _ = self.grid.find_nearest_gpi(lon, lat) return self.write_gp(gp, **kwargs)
[docs] def get_nearest_gp_info(self, lon, lat): """ get info for nearest grid point Parameters ---------- lon : float Longitude coordinate. lat : float Latitude coordinate. Returns ------- gpi : int Grid point index of nearest grid point. gp_lon : float Lontitude coordinate of nearest grid point. gp_lat : float Latitude coordinate of nearest grid point. gp_dist : float Geodetic distance to nearest grid point. """ gpi, gp_dist = self.grid.find_nearest_gpi(lon, lat) gp_lon, gp_lat = self.grid.gpi2lonlat(gpi) return gpi, gp_lon, gp_lat, gp_dist
[docs] def write_gp(self, gpi, data, **kwargs): """ Write data for given grid point. Parameters ---------- gpi : int Grid point index. data : numpy.ndarray Data records. """ self._open(gpi) if self.mode in ['r']: raise IOError("File is not open in write/append mode") lon, lat = self.grid.gpi2lonlat(gpi) self.fid.write_ts(gpi, data, lon=lon, lat=lat, **kwargs)
[docs] def write_ts(self, *args, **kwargs): """ Takes either 2 or 3 arguments (the last one always needs to be the data to be written) and calls the correct function which is either writing the gpi directly or finding the nearest gpi from given lon, lat coordinates and then reading it. """ if len(args) == 2: self.write_gp(args[0], args[1], **kwargs) if len(args) == 3: self._write_lonlat(args[0], args[1], args[2], **kwargs) if len(args) < 2 or len(args) > 3: raise ValueError("Wrong number of arguments")
[docs] def read_gp(self, gpi, **kwargs): """ Reads time series for a given grid point index. Parameters ---------- gpi : int grid point index Returns ------- data : pandas.DataFrame pandas.DateFrame with DateTimeIndex """ self._open(gpi) if self.mode in ['w', 'a']: raise IOError("File is not open in read mode") return self.fid.read_ts(gpi, **kwargs)
[docs] def read_ts(self, *args, **kwargs): """ Takes either 1 or 2 arguments and calls the correct function which is either reading the gpi directly or finding the nearest gpi from given lat,lon coordinates and then reading it """ if len(args) == 1: data = self.read_gp(args[0], **kwargs) if len(args) == 2: data = self._read_lonlat(args[0], args[1], **kwargs) if len(args) < 1 or len(args) > 2: raise ValueError("Wrong number of arguments") return data
[docs] def iter_ts(self): """ Yield time series for all grid points. Yields ------ data : pandas.DataFrame pandas.DateFrame with DateTimeIndex gpi : int Grid point index """ gps = self.grid.get_grid_points()[0] for gp in gps: yield self.read_gp(gp), gp
[docs] def flush(self): """ Flush data. """ if self.fid is not None: self.fid.flush()
[docs] def close(self): """ Close file. """ if self.fid is not None: self.fid.close() self.fid = None