:py:mod:`gnome.spills.release` ============================== .. py:module:: gnome.spills.release .. autoapi-nested-parse:: release objects that define how elements are released. A Spill() objects is composed of a release object and an ElementType Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: gnome.spills.release.StartPositions gnome.spills.release.Release gnome.spills.release.PointLineRelease gnome.spills.release.PolygonRelease gnome.spills.release.NESDISRelease gnome.spills.release.ContinuousPolygonRelease gnome.spills.release.SubsurfaceRelease gnome.spills.release.VerticalPlumeRelease gnome.spills.release.InitElemsFromFile Functions ~~~~~~~~~ .. autoapisummary:: gnome.spills.release.GridRelease gnome.spills.release.release_from_splot_data Attributes ~~~~~~~~~~ .. autoapisummary:: gnome.spills.release.SPREADING_CUMULATIVE_TIME_SCALE .. py:data:: SPREADING_CUMULATIVE_TIME_SCALE .. py:class:: StartPositions(*args, **kw) Bases: :py:obj:`colander.SequenceSchema` Fundamental building block of schemas. The constructor accepts these positional arguments: - ``typ``: The 'type' for this node. It should be an instance of a class that implements the :class:`colander.interfaces.Type` interface. If ``typ`` is not passed, a call to the ``schema_type()`` method on this class is made to get a default type. (When subclassing, ``schema_type()`` should be overridden to provide a reasonable default type). - ``*children``: a sequence of subnodes. If the subnodes of this node are not known at construction time, they can later be added via the ``add`` method. The constructor accepts these keyword arguments: - ``name``: The name of this node. - ``typ``: The 'type' for this node can optionally be passed in as a keyword argument. See the documentation for the positional arg above. - ``default``: The default serialization value for this node when not set. If ``default`` is :attr:`colander.drop`, the node will be dropped from schema serialization. If not provided, the node will be serialized to :attr:`colander.null`. - ``missing``: The default deserialization value for this node. If it is not provided, the missing value of this node will be the special marker value :attr:`colander.required`, indicating that it is considered 'required'. When ``missing`` is :attr:`colander.required`, the ``required`` computed attribute will be ``True``. When ``missing`` is :attr:`colander.drop`, the node is dropped from the schema if it isn't set during deserialization. - ``missing_msg``: Optional error message to be used if the value is required and missing. - ``preparer``: Optional preparer for this node. It should be an object that implements the :class:`colander.interfaces.Preparer` interface. - ``validator``: Optional validator for this node. It should be an object that implements the :class:`colander.interfaces.Validator` interface. - ``after_bind``: A callback which is called after a clone of this node has 'bound' all of its values successfully. This callback is useful for performing arbitrary actions to the cloned node, or direct children of the cloned node (such as removing or adding children) at bind time. A 'binding' is the result of an execution of the ``bind`` method of the clone's prototype node, or one of the parents of the clone's prototype nodes. The deepest nodes in the node tree are bound first, so the ``after_bind`` methods of the deepest nodes are called before the shallowest. The ``after_bind`` callback should accept two values: ``node`` and ``kw``. ``node`` will be a clone of the bound node object, ``kw`` will be the set of keywords passed to the ``bind`` method. - ``title``: The title of this node. Defaults to a titleization of the ``name`` (underscores replaced with empty strings and the first letter of every resulting word capitalized). The title is used by higher-level systems (not by Colander itself). - ``description``: The description for this node. Defaults to ``''`` (the empty string). The description is used by higher-level systems (not by Colander itself). - ``widget``: The 'widget' for this node. Defaults to ``None``. The widget attribute is not interpreted by Colander itself, it is only meaningful to higher-level systems such as Deform. - ``insert_before``: if supplied, it names a sibling defined by a superclass for its parent node; the current node will be inserted before the named node. It is not useful unless a mapping schema is inherited from another mapping schema, and you need to control the ordering of the resulting nodes. Arbitrary keyword arguments remaining will be attached to the node object unmolested. .. py:attribute:: start_position .. py:class:: Release(release_time=None, num_elements=None, num_per_timestep=None, end_release_time=None, custom_positions=None, release_mass=0, retain_initial_positions=False, **kwargs) Bases: :py:obj:`gnome.gnomeobject.GnomeId` base class for Release classes. It contains interface for Release objects Required Arguments: :param release_time: time the LEs are released :type release_time: datetime.datetime or iso string. :param custom_positions: initial location(s) the elements are released :type custom_positions: iterable of (lon, lat, z) Optional arguments: .. note:: Either num_elements or num_per_timestep must be given. If both are None, then it defaults to num_elements=1000. If both are given a TypeError is raised because user can only specify one or the other, not both. :param num_elements: total number of elements to be released :type num_elements: integer default 1000 :param num_per_timestep: fixed number of LEs released at each timestep :type num_elements: integer :param end_release_time=None: optional -- for a time varying release, the end release time. If None, then release is instantaneous :type end_release_time: datetime.datetime :param release_mass=0: optional. This is the mass released in kilograms. :type release_mass: integer :param retain_initial_positions: Optional. If True, each LE will retain information about it's originally released position :type retain_initial_positions: boolean .. py:property:: centroid .. py:property:: release_mass .. py:property:: num_per_timestep .. py:property:: num_elements .. py:property:: release_duration duration over which particles are released in seconds .. py:property:: end_release_time .. py:attribute:: _schema .. py:method:: __repr__() Return repr(self). .. py:method:: rewind() .. py:method:: LE_timestep_ratio(ts) Returns the ratio .. py:method:: maximum_mass_error(ts) This function returns the maximum error in mass present in the model at any given time. In theory, this should be the mass of 1 LE .. py:method:: get_num_release_time_steps(ts) calculates how many time steps it takes to complete the release duration .. py:method:: generate_release_timeseries(num_ts, max_release, ts) Release timeseries describe release behavior as a function of time. _release_ts describes the number of LEs that should exist at time T PolygonRelease does not have a _pos_ts because it uses start_positions only All use TimeseriesData objects. .. py:method:: num_elements_after_time(current_time) Returns the number of elements expected to exist at current_time. Returns 0 if prepare_for_model_run has not been called. :param current_time: time of release :type current_time: datetime .. py:method:: prepare_for_model_run(ts) :param ts: timestep as integer seconds .. py:method:: initialize_LEs(to_rel, sc, start_time, end_time) set positions for new elements added by the SpillContainer .. note:: this releases all the elements at their initial positions at the end_time .. py:method:: initialize_LEs_post_substance(to_rel, sc, start_time, end_time, environment) .. py:class:: PointLineRelease(release_time=None, start_position=None, num_elements=None, num_per_timestep=None, end_release_time=None, end_position=None, release_mass=0, **kwargs) Bases: :py:obj:`Release` The primary spill source class -- a release of floating non-weathering particles, can be instantaneous or continuous, and be released at a single point, or over a line. Required Arguments: :param release_time: time the LEs are released (datetime object) :type release_time: datetime.datetime :param start_position: initial location the elements are released :type start_position: 3-tuple of floats (long, lat, z) Optional arguments: .. note:: Either num_elements or num_per_timestep must be given. If both are None, then it defaults to num_elements=1000. If both are given a TypeError is raised because user can only specify one or the other, not both. :param num_elements: total number of elements to be released :type num_elements: integer :param num_per_timestep: fixed number of LEs released at each timestep :type num_elements: integer :param end_release_time=None: optional -- for a time varying release, the end release time. If None, then release is instantaneous :type end_release_time: datetime.datetime :param end_position=None: optional. For moving source, the end position If None, then release from a point source :type end_position: 3-tuple of floats (long, lat, z) :param release_mass=0: optional. This is the mass released in kilograms. :type release_mass: integer .. py:property:: is_pointsource if end_position - start_position == 0, point source otherwise it is a line source :returns: True if point source, false otherwise .. py:property:: centroid .. py:property:: start_position .. py:property:: end_position .. py:attribute:: _schema .. py:method:: __repr__() Return repr(self). .. py:method:: generate_release_timeseries(num_ts, max_release, ts) Release timeseries describe release behavior as a function of time. _release_ts describes the number of LEs that should exist at time T _pos_ts describes the spill position at time T All use TimeseriesData objects. .. py:method:: rewind() .. py:method:: prepare_for_model_run(ts) :param ts: timestep as integer seconds .. py:method:: initialize_LEs(to_rel, sc, start_time, end_time) Initializes the mass and position for to_rel new LEs. :param data: spill container with data arrays :param to_rel: number of elements to initialize :param start_time: initial time of release :param end_time: final time of release .. py:method:: initialize_LEs_post_substance(to_rel, sc, start_time, end_time, environment) .. py:class:: PolygonRelease(filename=None, features=None, polygons=None, weights=None, thicknesses=None, **kwargs) Bases: :py:obj:`Release` A release of elements into a set of provided polygons. When X particles are determined to be released, they are into the polygons randomly. For each LE, pick a polygon, weighted by it's proportional area and place the LE randomly within it. By default the PolygonRelease uses simple area for polygon weighting. Other classes (NESDISRelease for example) may use other weighting functions. Required Arguments: :param release_time: time the LEs are released (datetime object) :type release_time: datetime.datetime :param polygons: polygons to use in this release :type polygons: list of shapely.Polygon or shapely.MultiPolygon. Optional arguments: :param filename: (optional) shapefile :type filename: string name of a zip file. Polygons loaded are concatenated after polygons from kwarg :param weights: (optional) LE placement probability weighting for each polygon. Must be the same length as the polygons kwarg, and must sum to 1. If None, weights are generated at runtime based on area proportion. :param num_elements: total number of elements to be released :type num_elements: integer default 1000 :param num_per_timestep: fixed number of LEs released at each timestep :type num_elements: integer :param end_release_time=None: optional -- for a time varying release, the end release time. If None, then release is instantaneous :type end_release_time: datetime.datetime :param release_mass=0: optional. This is the mass released in kilograms. :type release_mass: integer .. py:property:: filename .. py:property:: centroid .. py:property:: __geo_interface__ .. py:property:: features .. py:property:: polygons .. py:property:: thicknesses .. py:property:: weights .. py:property:: areas .. py:attribute:: _schema .. py:method:: gen_fc_from_kwargs(kwargs) .. py:method:: rewind() .. py:method:: get_polys_as_tris(polys, weights=None) .. py:method:: compute_distribution() .. py:method:: prepare_for_model_run(ts) :param ts: timestep as integer seconds .. py:method:: initialize_LEs(to_rel, data, start_time, end_time) set positions for new elements added by the SpillContainer .. note:: this releases all the elements at their initial positions at the end_time .. py:method:: get_polygons() Returns an array of lengths, and a list of line arrays. The first array sequentially indexes the second array. When the second array is split up using the first array and the resulting lines are drawn, you should end up with a picture of the polygons. .. py:method:: get_metadata() .. py:method:: new_from_dict(dict_) :classmethod: creates a new object from dictionary This is base implementation and can be over-ridden by classes using this mixin .. py:function:: GridRelease(release_time, bounds, resolution) Utility function that creates a release with a grid of elements. Only 2-d for now :param bounds: bounding box of region you want the elements in: ((min_lon, min_lat), (max_lon, max_lat)) :type bounds: 2x2 numpy array or equivalent :param resolution: resolution of grid -- it will be a resolution X resolution grid :type resolution: integer .. py:class:: NESDISRelease(filename=None, features=None, **kwargs) Bases: :py:obj:`PolygonRelease` A PolygonRelease subclass that has functions and data specifically for representing NESDIS shapefiles within GNOME :param filename: NESDIS shapefile :type filename: string filename :param feature: FeatureCollection representation of a NESDIS shapefile :type feature: geojson.FeatureCollection .. py:property:: record_areas .. py:property:: oil_types .. py:attribute:: _schema .. py:method:: load_nesdis(filename, release_time=None) :staticmethod: 1. load a nesdis shapefile 2. Translates the time in the property array 3. Add extra properties as necessary filename should be a zipfile returns a geojson.FeatureCollection .. py:method:: to_dict(json_=None) Returns a dictionary representation of this object. Uses the schema to determine which attributes are put into the dictionary. No extra processing is done to each attribute. They are presented as is. The ``json_`` parameter is ignored in this base class. 'save' is passed in when the schema is saving the object. This allows an override of this function to do any custom stuff necessary to prepare for saving. .. py:class:: ContinuousPolygonRelease(release_time=None, start_positions=None, num_elements=10000, end_release_time=None, LE_timeseries=None, **kwargs) Bases: :py:obj:`PolygonRelease` continuous release of elements from specified positions NOTE 3/23/2021: THIS IS NOT FUNCTIONAL :param num_elements: the total number of elements to release. note that this may be rounded to fit the number of release points :type integer: :param release_time: the start of the release time :type release_time: datetime.datetime :param release_time: the end of the release time :type release_time: datetime.datetime :param start_positions: locations the LEs are released :type start_positions: (num_positions, 3) tuple or numpy array of float64 -- (long, lat, z) num_elements and release_time passed to base class __init__ using super See base :class:`Release` documentation .. py:property:: release_duration duration over which particles are released in seconds .. py:method:: LE_timestep_ratio(ts) Returns the ratio .. py:method:: num_elements_to_release(current_time, time_step) Return number of particles released in current_time + time_step .. py:method:: num_elements_to_release(current_time, time_step) .. py:method:: set_newparticle_positions(num_new_particles, current_time, time_step, data_arrays) Set positions for new elements added by the SpillContainer .. py:class:: SubsurfaceRelease(distribution=None, distribution_type='droplet_size', release_time=None, start_position=None, num_elements=None, num_per_timestep=None, end_release_time=None, end_position=None, release_mass=0, **kwargs) Bases: :py:obj:`PointLineRelease` The primary spill source class -- a release of floating non-weathering particles, can be instantaneous or continuous, and be released at a single point, or over a line. released as PointLinearRelease with additional features .. py:attribute:: _schema .. py:method:: initialize_LEs_post_substance(to_rel, sc, start_time, end_time, environment) .. py:class:: VerticalPlumeRelease(release_time=None, start_position=None, plume_data=None, end_release_time=None, **kwargs) Bases: :py:obj:`Release` An Underwater Plume spill class -- a continuous release of particles, controlled by a contained spill generator object. - plume model generator will have an iteration method. This will provide flexible looping and list comprehension behavior. :param num_elements: total number of elements to be released :type num_elements: integer :param start_position: initial location the elements are released :type start_position: 3-tuple of floats (long, lat, z) :param release_time: time the LEs are released :type release_time: datetime.datetime :param start_positions: locations the LEs are released :type start_positions: (num_elements, 3) numpy array of float64 -- (long, lat, z) .. py:method:: _plume_elem_coords(current_time, time_step) Return a list of positions for all elements released within current_time + time_step .. py:method:: num_elements_to_release(current_time, time_step) Return number of particles released in current_time + time_step .. py:method:: set_newparticle_positions(num_new_particles, current_time, time_step, data_arrays) Set positions for new elements added by the SpillContainer .. py:class:: InitElemsFromFile(filename, release_time=None, index=None, time=None) Bases: :py:obj:`Release` release object that sets the initial state of particles from a previously output NetCDF file Take a NetCDF file, which is an output of PyGnome's outputter: NetCDFOutput, and use these dataarrays as initial condition for the release. The release sets not only 'positions' but also all other arrays it finds. Arrays found in NetCDF file but not in the SpillContainer are ignored. Optional arguments, index and time can be used to initialize the release from any other record in the NetCDF file. Default behavior is to use the last record in the NetCDF to initialize the release elements. :param str filename: NetCDF file from which to initialize released elements Optional arguments: :param int index=None: index of the record from which to initialize the release elements. Default is to use -1 if neither time nor index is specified :param datetime time: timestamp at which the data is desired. Looks in the netcdf data's 'time' array and finds the closest time to this and use this data. If both 'time' and 'index' are None, use data for index = -1 .. py:method:: _read_data_file(filename, index, time) .. py:method:: num_elements_to_release(current_time, time_step) all elements should be released in the first timestep unless start time is invalid. Start time is invalid if it is after the Spill's releasetime .. py:method:: _set_data_arrays(num_new_particles, current_time, time_step, data_arrays) Will set positions and all other data arrays if data for them was found in the NetCDF initialization file. .. py:function:: release_from_splot_data(release_time, filename) Initialize a release object from a text file containing splots. The file contains 3 columns with following data: [longitude, latitude, num_LEs_per_splot/5000] For each (longitude, latitude) release num_LEs_per_splot points