gnome.spill_container

spill_container.py

Implements a container for spills – keeps all the data from each spill in one set of arrays. The spills themselves provide some of the arrays themselves (adding more each time LEs are released).

Module Contents

Classes

FateDataView

need a docstring -- what is this for?

SpillContainerData

A really simple SpillContainer -- holds the data arrays,

SpillContainer

Container class for all spills -- it takes care of capturing the released

SpillContainerPairData

A really simple SpillContainerPair

SpillContainerPair

Container holds two SpillContainers, one contains the certain spills while

class gnome.spill_container.FateDataView

Bases: gnome.AddLogger

need a docstring – what is this for?

_dicts_ = ('surface_weather', 'subsurf_weather', 'skim', 'burn', 'disperse', 'non_weather', 'all')
reset()
_get_fate_mask(sc, fate)

get fate_status mask over SC - only include LEs with ‘mass’ > 0.0

_set_data(sc, array_types, fate_mask, fate_status)

Set the data arrays in the FateDataView

fate_mask is the data already masked for the desired ‘fate’ option

fate_status is the status the mask is for (‘surface_weather’, etc.)

get_data(sc, array_types, fate_status='surface_weather')

Get data that matches the given fate_status. Since this is weathering data, only include elements with ‘mass’ > 0

Options are: ‘all’, ‘surface_weather’, ‘subsurf_weather’, ‘skim’, ‘non_weather’, ‘burn’

update_sc(sc, fate_status='surface_weather')

update SC arrays with FateDataView arrays for specified fate - update all arrays just to make sure everything is in sync

After update, remove LEs with mass = 0. Since weatherers call this at the end of a weathering step, this ensures zero mass LEs are removed from the arrays.

Note

the ‘id’ of each LE corresponds with the index into SC array when it was added. if LEs are removed, then this will not be the case. Do not rely on this indexing. Instead, get the mask again - the assumption is that the fate_mask should be the same between getting the data and resync’ing the original arrays in the SC

_reset_fatedata(sc, ix)

reset all arrays that contain LE with ‘id’ = ix

class gnome.spill_container.SpillContainerData(data_arrays=None, uncertain=False)

Bases: object

A really simple SpillContainer – holds the data arrays, but doesn’t manage spills, etc.

Think of it as a read-only SpillContainer.

Designed primarily to hold data retrieved from cache

Initialize a SimpleSpillContainer.

Parameters:
  • uncertain=False – flag indicating whether this holds uncertainty elements or not

  • data_arrays=None

    A dict of all the data arrays you want to hold NOTE: no error checking! they should be

    correctly aligned, etc.

The common use-case for this is for loading from cache for re-rendering, etc.

Note: initialize current_time_stamp attribute to None. It is responsibility of caller to set current_time_stamp (for eg: Model)

property num_released

The number of elements currently in the SpillContainer

If SpillContainer is initialized, all data_arrays exist as ndarrays even if no elements are released. So this will always return a valid int >= 0.

property data_arrays

Returns a dict of the all the data arrays

__contains__(item)
__getitem__(data_name)

The basic way to access data for the LEs

Parameters:

data_name – the name of the array to be returned

example: a_spill_container[‘positions’] give you the

(x,y,z positions array of the elements)

Raises:

KeyError – raised if the data is not there

__setitem__(data_name, array)

sets the data item

careful! – this should probably only be used for testing! as all arrays need to be compatible

It will be checked to at least be size-consistent with the rest of the data, and type-consistent if the data array is being replaced

It will not allow user to add a new data_array - only existing data_arrays can be modified. All data_arrays are defined in prepare_for_model_run

__eq__(other)

Compare equality of two SpillContanerData objects

__ne__(other)

Return self!=value.

__len__()

The “length” of a spill container is the number of elements in it. The first dimension of any ndarray in our data_arrays will always be the number of elements that are contained in a SpillContainer.

keys()

a keys() function so it looks a bit more like a dict

class gnome.spill_container.SpillContainer(uncertain=False)

Bases: gnome.AddLogger, SpillContainerData

Container class for all spills – it takes care of capturing the released LEs from all the spills, putting them all in a single set of arrays.

Many of the “fields” associated with a collection of elements are optional, or used only by some movers, so only the ones required will be requested by each mover.

The data for the elements is stored in the _data_arrays dict. They can be accessed by indexing. For example:

positions = spill_container[‘positions’] : returns a (num_LEs, 3) array of world_point_types

Initialize a SimpleSpillContainer.

Parameters:
  • uncertain=False – flag indicating whether this holds uncertainty elements or not

  • data_arrays=None

    A dict of all the data arrays you want to hold NOTE: no error checking! they should be

    correctly aligned, etc.

The common use-case for this is for loading from cache for re-rendering, etc.

Note: initialize current_time_stamp attribute to None. It is responsibility of caller to set current_time_stamp (for eg: Model)

property total_mass

return total mass spilled in ‘kg’

property substances

Returns list of substances for weathering - not including None since that is non-weathering. Currently, only one weathering substance is supported

property array_types

user can modify ArrayType initial_value in middle of run. Changing the shape should throw an error. Change the dtype at your own risk. This returns a new dict so user cannot add/delete an ArrayType in middle of run. Use prepare_for_model_run() to do add an ArrayType.

__repr__
_reset_arrays()

reset _array_types dict so it contains default keys/values

_reset__substances_spills()

reset internal attributes to None and empty list []:

  1. _substances_spills: data structure to contain spills per substance

  2. _oil_comp_array_len: max number of psuedocomponents - relevant if more than one substance is used.

  3. _fate_data_list: list of FateDataView() objects. One object per substance if substance is not None

_reset__fate_data_view()
reset_fate_dataview()

reset data arrays for each fate_dataviewer. Each substance that is not None has a fate_dataviewer object.

_set_substancespills()

_substances could change when spills are added/deleted using _spills_changed callback to reset self._substance_spills to None

This checks to make sure that the substance s set correctly and that there is not more than one substance

All spills that are ‘on’ are included. A spill that is off isn’t really being modeled so ignore it.

Note

Should not be called in middle of run. prepare_for_model_run() will invoke this if self._substance_spills is None. This is another view of the data - it doesn’t contain any state that needs to be persisted.

_set_fate_data()

If the substance is not None, initialize the FateDataView object.

_spills_changed(*args)

call back called on spills add/delete/replace Callback simply resets the internal _substance_spills attribute to None since the old _substance_spills value could now be invalid.

_get_s_id(substance)

Look in the _substances_spills data structure of substance and return the corresponding s_id

_get_fatedataview()

return the FateDataView object

_array_name(at)

given an array type, return the name of the array. This can be string, in which case, it is the name of the array so return it. If its not a string, then return the at.name attribute.

_append_data_arrays(num_released)

initialize data arrays once spill has spawned particles Data arrays are set to their initial_values

Parameters:

num_released (int) – number of particles released

substancefatedata(substance, array_types, fate='surface_weather')

Only one substance now! todo: fix this so it works for type of fate requested return the data for specified substance data must contain array names specified in ‘array_types’

iterspillsbysubstance()

iterate through the substances spills datastructure and return the spills associated with each substance. This is used by release_elements DataStructure contains all spills. If some spills contain None for substance, these will be returned

itersubstancedata(array_types, fate_status='surface_weather')

There is only one substance allowed per SpillContainer, so this is returns the data cooresponding to the fate_status.

This is only here to preserve compatiblity

returns (substance, substance_data)

This is used by weatherers - if a substance is None, StopIteration is raised

Parameters:
  • array_types – iterable containing array that should be in the data. This could be a set of strings corresponding with array names or ArrayType objects which have a name attribute

  • select='select' – a string stating the type of data to be returned. Default if ‘surface’, so all elements with status_codes==oil_status.in_water and z == 0 in positions array

Returns:

(substance, substance_data) for each iteration substance: substance object substance_data: dict of numpy arrays associated with substance with elements in_water and on surface if select == ‘surface’ or subsurface if select == ‘subsurface’

update_from_fatedataview(fate_status='surface_weather')

let’s only update the arrays that were changed only update if a copy of ‘data’ exists.

get_substances(complete=True)

only one substance…

rewind()

In the rewind operation, we: - rewind all the spills - restore _array_types to contain only defaults

  • movers/weatherers could have been deleted and we don’t want to carry associated data_arrays

  • prepare_for_model_run() will be called before the next run and new arrays can be given

  • purge the data arrays - we gather data arrays for each contained spill - the stored arrays are cleared, then replaced with appropriate

    empty arrays

get_spill_mask(spill)
uncertain_copy()

Returns a copy of the spill_container suitable for uncertainty

It has all the same spills, with the same ids, and the uncertain flag set to True

prepare_for_model_run(array_types=None, time_step=300)

called when setting up the model prior to 1st time step This is considered 0th timestep by model

Make current_time optional since SpillContainer doesn’t require it especially for 0th step; however, the model needs to set it because it will write_output() after each step. The data_arrays along with the current_time_stamp must be set in order to write_output()

Parameters:
  • model_start_time – model_start_time to initialize current_time_stamp. This is the time_stamp associated with 0-th step so initial conditions for data arrays

  • array_types – a set of additional names and/or array_types to append to standard array_types attribute. Set can contain only strings or a tuple with (string, ArrayType). See Note below.

Note

set can contains strings or tuples. If set contains only strings, say: {‘mass’, ‘windages’}, then SpillContainer looks for corresponding ArrayType object defined in gnome.array_types for ‘mass’ and ‘windages’. If set contains a tuple, say: {(‘mass’, gnome.array_types.mass)}, then SpillContainer uses the ArrayType defined in the tuple.

Note

The SpillContainer iterates through each of the item in array_types and checks to see if there is an associated initializer in any Spill. If corresponding initializer is found, it gets the array_types from initializer and appends them to its own list. This was added for the case where ‘droplet_diameter’ array is defined/used by initializer (InitRiseVelFromDropletSizeFromDist) and we would like to see it in output, but no Mover/Weatherer needs it.

initialize_data_arrays()

initialize_data_arrays() is called without input data during rewind and prepare_for_model_run to define all data arrays. At this time the arrays are empty.

_get_fate_mask(fate)

get fate_status mask over SC - only include LEs with ‘mass’ > 0.0

release_elements(start_time, end_time, environment=None)
Parameters:
  • start_time – – beginning of the release

  • end_time – – end of the release.

This calls release_elements on all of the contained spills, and adds the elements to the data arrays

Returns:

total number of particles released

split_element(ix, num, l_frac=None)

split an element into specified number. For data, like mass, that gets divided, l_frac can be optionally provided. l_frac is a list containing fraction of component’s value given to each new element. len(l_frac) must be equal to num and sum(l_frac) == 1.0

Parameters:
  • ix (int) – id of element to be split - before splitting each element has a unique ‘id’ defined in ‘id’ data array

  • num (int) – split ix into ‘num’ number of elements

  • l_frac (list or tuple or numpy array) – list containing fractions that sum to 1.0 with len(l_frac) == num

model_step_is_done()

Called at the end of a time step Need to remove particles marked as to_be_removed…

__str__()

Return str(self).

class gnome.spill_container.SpillContainerPairData(sc, u_sc=None)

Bases: object

A really simple SpillContainerPair
  • holds SpillContainerPairData objects, but doen’t manage spills, etc.

Think of it as a read-only SpillContainerPair.

Designed primarily to hold data retrieved from cache

Initialize object with the spill_containers passed in

property uncertain
property LE_data
__repr__()

Return repr(self).

items()

returns a tuple of the enclosed spill containers

if uncertainty is off, just one is in the tuple if uncertainly is on – then it is a two-tuple:

(certain_container, uncertain_container)

To act on both:
for sc in spill_container_pair.items():

do_something_with(sc)

NOTE: cache code counts on the uncertain SpillContainer being last

LE(prop_name, uncertain=False)
__eq__(other)

Compare equality of two SpillContainerPairData objects

__ne__(other)

Return self!=value.

class gnome.spill_container.SpillContainerPair(uncertain=False)

Bases: SpillContainerPairData

Container holds two SpillContainers, one contains the certain spills while the other contains uncertainty spills if model uncertainty is on.

initialize object: init spill_container, _uncertain and u_spill_container if uncertain

Note: all operations like add, remove, replace and __iter__ are exposed to user for the spill_container.spills OrderedCollection

property uncertain
property num_released

elements released by (forecast, uncertain) spills

rewind()

rewind spills in spill_container

__repr__()

unambiguous repr

_add_spill_pair(pair_tuple)

add both certain and uncertain spills given as a pair

_add_item(item)

could be a spill pair or a forecast spill - add appropriately

add(spills)

Add spill to spill_container and make copy in u_spill_container if uncertainty is on

Note: Method can take either a list, tuple, or list of tuples

with following assumptions:

1. spills = Spill() # A spill object, if uncertainty is on, make a copy for uncertain_spill_container.

2. spills = [s0, s1, ..,] # List of forecast spills. if uncertain, make a copy of each and add to uncertain_spill_container

3. spills = (s0, uncertain_s0) # tuple of length two. Assume first one is forecast spill and second one is the uncertain copy. Used when restoring from save file

4. spills = [(s0, uncertain_s0), ..] # list of tuples of length two. Added for completeness.

append(spill)
remove(ident)

remove object from spill_container.spills and the corresponding uncertainty spill as well

__getitem__(ident)

only return the certain spill

__setitem__(ident, new_spill)
__delitem__(ident)
__iadd__(rop)
__iter__()

iterates over the spills defined in spill_container

__len__()

It refers to the total number of spills that have been added The uncertain and certain spill containers will contain the same number of spills return the length of spill_container.spills

__contains__(ident)

looks to see if ident which is the id of a spill belongs in the _spill_container.spills OrderedCollection

to_dict()
takes the instance of SpillContainerPair class and outputs a dict with:

‘spills’: call to_dict() on spills ordered collection stored in certain spill container

if uncertain, then also return:

‘uncertain_spills’: call to_dict() on spills ordered collection stored in uncertain spill container

The input param json_ is not used. It is there to keep the same interface for all to_dict() functions

update_from_dict(dict_)

takes a dict {‘spills’: [list of spill objects]}, checks them against the forecast spills contained in _spill_container.spills and updates if they are different

It also creates a copy of the different spill and replaces the corresponding spill in _u_spill_container

This is primarily intended for the webapp so the dict_ will only contain a list of forecast spills

spill_by_index(index, uncertain=False)

return either the forecast spill or the uncertain spill at specified index

index(spill)

Look for spill in forecast SpillContainer or uncertain SpillContainer and return the index of ordered collection where spill is found

clear()

clear all spills from container pairs