:py:mod:`opendrift.readers.basereader` ====================================== .. py:module:: opendrift.readers.basereader Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 consts/index.rst continuous/index.rst fakeproj/index.rst structured/index.rst unstructured/index.rst variables/index.rst Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: opendrift.readers.basereader.StructuredReader opendrift.readers.basereader.UnstructuredReader opendrift.readers.basereader.ContinuousReader opendrift.readers.basereader.Variables opendrift.readers.basereader.Combine opendrift.readers.basereader.Filter opendrift.readers.basereader.ReaderBlock opendrift.readers.basereader.BaseReader Attributes ~~~~~~~~~~ .. autoapisummary:: opendrift.readers.basereader.logger opendrift.readers.basereader.standard_names opendrift.readers.basereader.vector_pairs_xy .. py:data:: logger .. py:class:: StructuredReader Bases: :py:obj:`opendrift.readers.basereader.variables.Variables` A structured reader. Data is gridded on a regular grid. Used by e.g.: :class:`opendrift.readers.reader_netCDF_CF_generic.Reader`. Attributes: projected: is `True` if :class:`.fakeproj.fakeproj` is used because of missing projection information. The data points are assumed to be approximately equidistant on the surface (i.e. in meters). clipped: pixels to to remove along boundary (e.g. in case of bad data). .. seealso:: :py:mod:`opendrift.readers` .. py:attribute:: clipped :value: 0 .. py:attribute:: x .. py:attribute:: y .. py:attribute:: interpolation :value: 'linearNDFast' .. py:attribute:: convolve .. py:attribute:: save_interpolator .. py:attribute:: interpolator_filename .. py:attribute:: __lonlat2xy_parallel__ .. py:attribute:: __disable_parallel__ :value: False .. py:method:: get_variables(variables, time=None, x=None, y=None, z=None) :abstractmethod: Obtain a _block_ of values of the requested variables at all positions (x, y, z) closest to given time. These will be stored in :class:`opendrift.readers.interpolation.structured.ReaderBlock` and accessed from there. Arguments: variables: list of variables. time: datetime or None, time at which data are requested. x, y: float or ndarrays; coordinates of requested points. z: float or ndarray; vertical position (in meters, positive up) Returns: Dictionary keywords: variables (string) values: 2D ndarray bounding x and y. .. py:method:: prepare(extent, start_time, end_time, max_speed) Prepare reader for given simulation coverage in time and space. .. py:method:: set_convolution_kernel(convolve) Set a convolution kernel or kernel size (of array of ones) used by `get_variables` on read variables. .. py:method:: __convolve_block__(env) Convolve arrays with a kernel, if reader.convolve is set .. py:method:: lon_range() .. py:method:: _get_variables_interpolated_(variables, profiles, profiles_depth, time, reader_x, reader_y, z) This method _must_ be implemented by every reader. Usually by subclassing one of the reader types (e.g. :class:`structured.StructuredReader`). Arguments are in _native projection_ of reader. .. seealso: * :meth:`get_variables_interpolated_xy`. * :meth:`get_variables_interpolated`. .. py:method:: __check_env_arrays__(env) For the StructuredReader the variables are checked before entered into the ReaderBlock interpolator. This methods makes the second check a no-op. .. seealso:: :meth:`.variables.Variables.__check_env_arrays__`. .. py:method:: xy2lonlat(x, y) Calculate x,y in own projection from given lon,lat (scalars/arrays). .. py:method:: lonlat2xy(lon, lat) Calculate lon,lat from given x,y (scalars/arrays) in own projection. .. py:method:: pixel_size() .. py:method:: get_ocean_depth_area_volume(lonmin, lonmax, latmin, latmax) Get depth, area and volume of ocean basin within given coordinates .. py:method:: _coverage_unit_() .. py:method:: _bbox_(x, y) Find bounding box on grid containing points (x, y) .. py:method:: _make_projected_grid_(lon, lat, eq_eps=0.1) Make the projected grid in cases where `lon` and `lat` are present as 2D variables, but not `x` and `y` and assert that it is approximately equidistant. Args: eq_eps: tolerance for equidistance checks. .. py:method:: __validate_projected_grid__(eq_eps=0.1) Validate that the projected grid is approximately equidistant. Args: eq_eps: tolerance for equidistance checks. Raises: AssertionError if not equidistant within `eq_eps`. .. py:method:: _slice_variable_(var, indxTime=None, indy=None, indx=None, indz=None, indrealization=None) Slice variable depending on number of dimensions available. Args: All arguments can be `slice` objects or index. Returns: `var` sliced using the slices or indexes necessary to use depending on number of dimensions available. Raises: Unsupported number of dimensions (outside 2..5) raises an exception. .. py:class:: UnstructuredReader Bases: :py:obj:`opendrift.readers.basereader.variables.Variables` An unstructured reader. Data is gridded irregularily. The initial type of grid that this class supports are `triangular prisms `_. Unstructured in xy-coordinates, x and y is constant in z. z might be non-cartesian (e.g. sigma-levels). .. seealso:: :py:mod:`opendrift.readers` :class:`.structured.StructuredReader` .. py:attribute:: PARALLEL_WORKERS .. py:attribute:: boundary .. py:attribute:: x .. py:attribute:: y .. py:attribute:: node_variables .. py:attribute:: nodes_idx .. py:attribute:: xc .. py:attribute:: yc .. py:attribute:: face_variables .. py:attribute:: faces_idx .. py:method:: get_variables(variables, time=None, x=None, y=None, z=None) :abstractmethod: Obtain and return values of the requested variables at all positions (x, y, z) closest to given time. Returns: Dictionary with arrays of length len(time) with values at exact positions x, y and z. .. py:method:: _get_variables_interpolated_(variables, profiles, profiles_depth, time, reader_x, reader_y, z) This method _must_ be implemented by every reader. Usually by subclassing one of the reader types (e.g. :class:`structured.StructuredReader`). Arguments are in _native projection_ of reader. .. seealso: * :meth:`get_variables_interpolated_xy`. * :meth:`get_variables_interpolated`. .. py:method:: _build_boundary_polygon_(x, y) Build a polygon of the boundary of the mesh. Arguments: :param x: Array of node x position, lenght N :param y: Array of node y position, length N Returns: A `shapely.prepareped.prep` `shapely.Polygon`. The boundary of the mesh, ideally including holes in the mesh. Algorithms: .. note:: Try this alogrithm: https://stackoverflow.com/a/14109211/377927 Boundary edges (line between two nodes) are only referenced by a single triangle. 1. Find a starting edge segment: [v_start, v_next] (v is vertex or node) 2. Find another _unvisited_ edge segment [v_i, v_j] that has either v_i = v_next or v_j = v_next and add the one not equal to v_next to the polygon. 3. Reset v_next to the newly added point. Mark edge as visited. 4. Continue untill we reach v_start. The polygon has a rotation, but this should not matter for our purpose of checking the bounds. Note: In order to find holes in the polygon all points must be scanned. Approximate using the convex hull: An alternative simple approximation is to use the convex hull of the points, but this will miss points along the boundary which form a wedge in the boundary (as well as holes in the mesh). Holes in the mesh will often be covered by the landmask anyway, so they will usually not be a problem. .. py:method:: covers_positions(x, y, z=0) Check which points are within boundary of mesh. .. py:method:: _build_rtree_(x, y) Builds an R-tree of x, y .. py:method:: _build_ckdtree_(x, y) .. py:method:: __nearest_ckdtree__(idx, x, y) Return index of nearest point in cKDTree .. py:method:: __nearest_rtree__(idx, x, y) :staticmethod: Take array of points and get nearest point in rtree index. .. py:method:: _nearest_node_(x, y) Return nearest node (id) for x and y .. py:method:: _nearest_face_(xc, yc) Return nearest element or face (id) for xc and yc .. py:class:: ContinuousReader Bases: :py:obj:`opendrift.readers.basereader.variables.Variables` A continuous (in space and time) reader, able to provide exact values at any desired point (within bounds). This reader type is suitable for constant readers, analytical readers, or readers that are static and continuous within the valid domain (e.g. the landmask reader). .. seealso:: :py:mod:`opendrift.readers` .. py:method:: get_variables(variables, time=None, x=None, y=None, z=None) :abstractmethod: Obtain and return values of the requested variables at all positions (x, y, z) closest to given time. Returns: Dictionary with arrays of length len(x) with values at exact positions x, y and z. .. py:method:: _get_variables_interpolated_(variables, profiles, profiles_depth, time, reader_x, reader_y, z) This method _must_ be implemented by every reader. Usually by subclassing one of the reader types (e.g. :class:`structured.StructuredReader`). Arguments are in _native projection_ of reader. .. seealso: * :meth:`get_variables_interpolated_xy`. * :meth:`get_variables_interpolated`. .. py:class:: Variables Bases: :py:obj:`ReaderDomain` Handles reading and interpolation of variables. .. py:attribute:: variables .. py:attribute:: derived_variables .. py:attribute:: name .. py:attribute:: buffer :value: 0 .. py:method:: activate_environment_mapping(mapping_name) .. py:method:: __calculate_derived_environment_variables__(env) .. py:method:: set_buffer_size(max_speed, time_coverage=None) Adjust buffer to minimise data block size needed to cover elements. The buffer size is calculated from the maximum anticpated speed. Seeding over a large area or over longer time can easily cause particles to be located outside the block. This is not critical, but causes interpolation to be one-sided in time for the relevant particles. Args: max_speed (m/s): the maximum speed anticipated for particles. time_coverage (timedelta): the time span to cover .. py:method:: __check_env_coordinates__(env) Make sure x and y are floats (and not e.g. int64) .. py:method:: __check_variable_array__(name, variable) :staticmethod: Ensure arrays are not masked arrays and that values are within valid ranges. .. py:method:: __check_env_arrays__(env) Ensure arrays are not masked arrays and that values are within valid ranges. .. seealso:: Disabled in `StructuredReader` because variables are valided before entered into interpolator: :meth:`.structured.StructuredReader.__check_env_arrays__` .. py:method:: _get_variables_interpolated_(variables, profiles, profiles_depth, time, reader_x, reader_y, z) :abstractmethod: This method _must_ be implemented by every reader. Usually by subclassing one of the reader types (e.g. :class:`structured.StructuredReader`). Arguments are in _native projection_ of reader. .. seealso: * :meth:`get_variables_interpolated_xy`. * :meth:`get_variables_interpolated`. .. py:method:: get_variables_interpolated_xy(variables, profiles=None, profiles_depth=None, time=None, x=None, y=None, z=None, rotate_to_proj=None) Get variables in native projection of reader. .. seealso:: * :meth:`get_variables_interpolated`. * :meth:`_get_variables_interpolated_`. .. py:method:: get_variables_interpolated(variables, profiles=None, profiles_depth=None, time=None, lon=None, lat=None, z=None, rotate_to_proj=None) `get_variables_interpolated` is the main interface to :class:`opendrift.basemodel.OpenDriftSimulation`, and is responsible for returning variables at the correct positions. Readers should implement :meth:`_get_variables_interpolated_`. Arguments: variables: string, or list of strings (standard_name) of requested variables. These must be provided by reader. profiles: List of variable names that should be returned for the range in `profiles_depth`. profiles_depth: Profiles variables will be retrieved from surface and down to this depth. The exact z-depth are given by the reader and returned as `z` variable in `env_profiles`. time: datetime or None, time at which data are requested. Can be None (default) if reader/variable has no time dimension (e.g. climatology or landmask). lon: longitude, 1d array. lat: latitude, 1d array, same length as lon. z: float or ndarray; vertical position (in meters, positive up) of requested points. either scalar or same length as lon, lat. default: 0 m (unless otherwise documented by reader) block: bool, see return below rotate_to_proj: N/A Returns: (env, env_profiles) Interpolated variables at x, y and z. `env` contains values at a fixed depth (`z`), while `env_profiles` contains depth-profiles in the range `profile_depth` for the variables listed in `profiles` for each element (in `x`, `y`). The exact depth is determined by the reader and specified in `env_profiles['z']`. Thus variables in `env_profiles` are not interpolated in z-direction. .. seealso:: :meth:`get_variables_interpolated_xy`. .. py:data:: standard_names .. py:data:: vector_pairs_xy :value: [['x_wind', 'y_wind', 'wind_speed', 'wind_to_direction', 'wind_from_direction'],... .. py:class:: Combine .. py:method:: __add__(other) .. py:method:: __mul__(other) .. py:method:: __truediv__(other) .. py:method:: __sub__(other) .. py:class:: Filter .. py:property:: variables :type: List[str] :abstractmethod: .. py:method:: filter_vars(vars) Only keep the specified variables. .. py:method:: exclude_vars(vars) Remove the specified variables. .. py:class:: ReaderBlock(data_dict, interpolation_horizontal='linearNDFast', interpolation_vertical='linear') Class to store and interpolate the output from a reader with data on a regular (structured) grid. .. py:method:: _initialize_interpolator(x, y, z=None) .. py:method:: interpolate(x, y, z=None, variables=None, profiles=[], profiles_depth=None) .. py:method:: _interpolate_horizontal_layers(data, nearest=False) Interpolate all layers of 3d (or 2d) array. .. py:method:: covers_positions(x, y, z=None) Check if given positions are covered by this reader block. .. py:class:: BaseReader Bases: :py:obj:`variables.Variables`, :py:obj:`opendrift.readers.operators.ops.Combine`, :py:obj:`opendrift.readers.operators.ops.Filter` An abstract reader. Implementors provide a method to read data and specify how it is interpolated. This class inherits :class:`.variables.Variables` which inherits :class:`.variables.ReaderDomain`. `ReaderDomain` is responsible for the extent and domain of the reader, including checking for out-of-bounds and projection conversion. `Variables` is responsible for returning interpolated data at the requests positions or profiles. Apart from coercing the returned data into the right type for :py:mod:`opendrift.models.basemodel`, it defines the abstract interface to :meth:`.variables.Variables._get_variables_interpolated_` which reader-implementations must provide (_usually_ through one of the main reader-types, see: :py:mod:`opendrift.readers`). .. seealso:: :py:mod:`opendrift.readers`. :py:mod:`.variables`. Common constructor for all readers .. py:attribute:: __metaclass__ .. py:attribute:: verticalbuffer :value: 1 .. py:attribute:: variable_aliases .. py:attribute:: xy2eastnorth_mapping .. py:method:: y_is_north() .. py:method:: prepare(extent, start_time, end_time, max_speed) Prepare reader for given simulation coverage in time and space. .. py:method:: index_of_closest_z(requested_z) Return (internal) index of z closest to requested z. Thickness of layers (of ocean model) are not assumed to be constant. .. py:method:: indices_min_max_z(z) Return min and max indices of internal vertical dimension, covering the requested vertical positions. Needed when block is requested (True). Arguments: z: ndarray of floats, in meters .. py:method:: performance() Report the time spent on various tasks .. py:method:: clip_boundary_pixels(numpix) Trim some (potentially bad) pixels along boundary .. py:method:: plot(variable=None, vmin=None, vmax=None, time=None, filename=None, title=None, buffer=1, lscale='auto') Plot geographical coverage of reader. .. py:method:: get_timeseries_at_position(lon, lat, variables=None, start_time=None, end_time=None, times=None) Get timeseries of variables from this reader at given position. .. py:method:: shift_start_time(start_time) Shift the time coverage of reader to match given start_time