gnome.model

module with the core Model class, and various supporting classes

This is the main class that contains objects used to model trajectory and weathering processes. It runs the loop through time, etc. The code comes with a full-featured version – you may want a simpler one if you aren’t doing a full-on oil spill model. The model contains:

  • map

  • collection of environment objects

  • collection of movers

  • collection of weatherers

  • spills

  • its own attributes

In pseudo code, the model loop is defined below. In the first step, it sets up the model run and in subsequent steps the model moves and weathers elements.

for each_timestep():
    if initial_timestep:
        setup_model_run()
    setup_time_step()
    move_the_elements()
    beach_refloat_the_elements()
    weather_the_elements()
    write_output()
    step_is_done()
    step_num += 1

Module Contents

Classes

Model

PyGnome Model Class

class gnome.model.Model(name='Model', time_step=timedelta(minutes=15), start_time=round_time(datetime.now(), 3600), duration=timedelta(days=1), weathering_substeps=1, map=None, uncertain=False, cache_enabled=False, mode=None, make_default_refs=True, location=[], environment=[], outputters=[], movers=[], weatherers=[], spills=[], uncertain_spills=[], weathering_activated=False, **kwargs)

Bases: gnome.gnomeobject.GnomeId

PyGnome Model Class

Initializes a model. All arguments have a default.

Parameters:
  • time_step=timedelta(minutes=15) – model time step in seconds or as a timedelta object. NOTE: if you pass in a number, it WILL be interpreted as seconds

  • start_time=datetime.now() – start time of model, datetime object. Rounded to the nearest hour.

  • duration=timedelta(days=1) – How long to run the model, a timedelta object.

  • weathering_substeps=1 – How many weathering substeps to run inside a single model time step.

  • map=gnome.map.GnomeMap() – The land-water map.

  • uncertain=False – Flag for setting uncertainty.

  • cache_enabled=False – Flag for setting whether the model should cache results to disk.

  • mode='Gnome' – The runtime ‘mode’ that the model should use. This is a value that the Web Client uses to decide which UI views it should present.

property uncertain

Uncertainty attribute of the model. If flag is toggled, rewind model

property uncertain_spills
property cache_enabled

If True, then generated data is cached

property has_weathering_uncertainty
property has_weathering
property start_time

Start time of the simulation

property time_step

time step over which the dynamics is computed

property current_time_step

Current timestep of the simulation

property duration

total duration of the model run

property map

land water map used for simulation

property num_time_steps

Read only attribute computed number of timesteps based on py:attribute:duration and py:attribute:time_step

_schema
_oc_list = ['movers', 'weatherers', 'environment', 'outputters']
modes
next
classmethod load_savefile(filename)

Load a model instance from a save file

Parameters:

filename – the filename of the save file – usually a zip file, but can also be a directry with the full contents of a zip file

Returns:

a model instance all set up from the savefile.

_register_callbacks()

Register callbacks with the OrderedCollections

add_weathering(which='standard')

Add the weatherers

Parameters:

which='standard'

which weatheres to add. Default is ‘standard’, which will add all the standard weathering algorithms if you don’t want them all, you can specify a list: [‘evaporation’, ‘dispersion’].

Options are:
  • ’evaporation’

  • ’dispersion’

  • ’emulsification’

  • ’dissolution’: Dissolution,

  • ’half_life_weatherer’

see: gnome.weatherers.__init__.py for the full list

reset(**kwargs)

Resets model to defaults – Caution – clears all movers, spills, etc. Takes same keyword arguments as __init__()

rewind()

Rewinds the model to the beginning (start_time)

update_from_dict(dict_, refs=None)

functions in common_object.

_reset_num_time_steps()

reset number of time steps if duration, or time_step change

contains_object(obj_id)
find_by_class(obj, collection, ret_all=False)

Look for an object that isinstance() of obj in specified colleciton. By default, it will return the first object of this type. To get all obects of this type, set ret_all to True

find_by_attr(attr, value, collection, allitems=False)

find first object in collection where the ‘attr’ attribute matches ‘value’. This is primarily used to find ‘wind’, ‘water’, ‘waves’ objects in environment collection. Use the ‘_ref_as’ attribute to search.

# fixme: why don’t we look for wind, water or waves directly?

Ignore AttributeError since all objects in collection may not contain the attribute over which we are searching.

Parameters:
  • attr (str) – attribute whose value must match

  • value (str) – desired value of the attribute

  • collection (OrderedCollection) – the ordered collection in which to search

_order_weatherers()

use weatherer_sort to sort the weatherers

_attach_default_refs(ref_dict)

Model invokes the default reference attachment system. Please note the structure of this function as an example of how to extend the system to contained child objects.

setup_model_run()

Runs the setup procedure preceding a model run. When complete, the model should be ready to run to completion without additional prep Currently this function consists of the following operations:

  1. Set up special objects.

    Some weatherers currently require other weatherers to exist. This step satisfies those requirements

  2. Remake collections in case ordering constraints apply (weatherers)

  3. Compile array_types and run setup procedure on spills

    array_types defines what data arrays are required by the various components of the model

  4. Attach default references

  5. Call prepare_for_model_run on all relevant objects

  6. Conduct miscellaneous prep items. See section in code for details.

post_model_run()

A place where the model goes through all collections and calls post_model_run if the object has it.

setup_time_step()

sets up everything for the current time_step:

move_elements()
Moves elements:
  • loops through all the movers. and moves the elements

  • sets new_position array for each spill

  • calls the beaching code to beach the elements that need beaching.

  • sets the new position

_update_fate_status(sc)

WeatheringData used to perform this operation in weather_elements; however, WeatheringData is one of the objects in weatherers collection so just let model do this for now. Eventually, we want to get rid of ‘fate_status’ array and only manipulate ‘status_codes’. Until then, update fate_status in move_elements

weather_elements()

Weathers elements:

  • loops through all the weatherers, passing in the spill_container and the time range

  • a weatherer modifies the data arrays in the spill container, so a particular time range should not be run multiple times. It is expected that we are processing a sequence of contiguous time ranges.

  • Note: If there are multiple sequential weathering processes, some inaccuracy could occur. A proposed solution is to ‘super-sample’ the model time step so that it will be replaced with many smaller time steps. We’ll have to see if this pans out in practice.

_split_into_substeps()
Returns:

sequence of (datetime, timestep) (Note: we divide evenly on second boundaries.

Thus, there will likely be a remainder that needs to be included. We include this remainder, which results in 1 more sub-step than we requested.)

step_is_done()

Loop through movers and weatherers and call model_step_is_done

Remove elements that marked for removal

Output data

write_output(valid, messages=None)
step()

Steps the model forward in time.

NOTE: in theory, it could also go backward with a negative time step, for hindcasting, but that has not been tested.

output_step(isvalid)
release_elements(start_time, end_time)

release elements into the model

Parameters:
  • start_time – – beginning of the release

  • end_time – – end of the release.

compile_env()

Produces a dictionary of objects that describe the model environmental conditions

Currently, only works with the ‘water’ object because the other environmental phenomena are not compatible yet

__iter__()

Rewinds the model and returns itself so it can be iterated over.

__next__()

(This method satisfies Python’s iterator and generator protocols)

Returns:

the step number

full_run(rewind=True)

Do a full run of the model.

Parameters:

rewind=True – whether to rewind the model first – if set to false, model will be run from the current step to the end

Returns:

list of outputter info dicts

_add_to_environ_collec(obj_added)

if an environment object exists in obj_added, but not in the Model’s environment collection, then add it automatically. todo: maybe we don’t want to do this - revisit this requirement JAH 9/22/2021: We sort of need this now because a lot of script behavior expects it. A lamentable state of affairs indeed.

CHB: maybe this could be more standardized though

– pity to have hard coded what all the possible environment types are.

perhaps all objects could have a “need_env_objects” attribute?

_callback_add_mover(obj_added)

Callback after mover has been added

_callback_add_outputter(obj_added)

Callback after outputter has been added

_callback_add_weatherer_env(obj_added)

Callback after weatherer/environment object has been added. ‘waves’ environment object contains ‘wind’ and ‘water’ so add those to environment collection and the ‘water’ attribute. todo: simplify this

_callback_add_spill(obj_added)
__eq__(other)
__eq__(other)

Since this class is designed as a mixin with one objective being to save _state of the object, then recreate a new object with the same _state.

Defines a base implementation of __eq__ so an object before persistence can be compared with a new object created after it is persisted. It can be overridden by the class with which it is mixed.

It looks at attributes defined in self._state and checks that the values match

It uses allclose() check for floats and numpy arrays, to avoid floating point tolerances: set to: RTOL=1e-05, ATOL=1e-08

Parameters:

other – another GnomeObject used for comparison in obj1 == other

NOTE: super is not used.

__ne__(other)

Return self!=value.

spills_update_from_dict(value)

invoke SpillContainerPair().update_from_dict

save(saveloc='.', refs=None, overwrite=True)

save the model state in saveloc. If self.zipsave is True, then a zip archive is created and model files are saved to the archive.

Parameters:
  • saveloc="."

    a directory or filename. If a directory, then either the model is saved into that dir, or a zip archive is created in that dir (with a .gnome extension).

    The file(s) are clobbered when save() is called.

  • refs=None – dict of references mapping ‘id’ to a string used for the reference. The value could be a unique integer or it could be a filename. It is up to the creator of the reference list to decide how to reference a nested object.

  • overwrite=True

Returns:

references

This overrides the base class save(). Model contains collections and model must invoke save for each object in the collection. It must also save the data in the SpillContainer’s if it is a mid-run save.

_save_spill_data(saveloc, nc_filename)

save the data arrays for current timestep to NetCDF If saveloc is zipfile, then move NetCDF to zipfile

classmethod load(saveloc='.', filename=None, refs=None)

Load an instance of this class from an archive or folder

Parameters:
  • saveloc – Can be an open zipfile.ZipFile archive, a folder, or a filename. If it is an open zipfile or folder, it must contain a .json file that describes an instance of this object type. If filename is not specified, it will load the first instance of this object discovered. If a filename, it must be a zip archive or a json file describing an object of this type.

  • filename – If saveloc is an open zipfile or folder, this indicates the name of the file to be loaded. If saveloc is a filename, is parameter is ignored.

  • refs – A dictionary of id -> object instances that will be used to complete references, if available.

_load_spill_data(saveloc, filename, nc_file)

load NetCDF file and add spill data back in - designed for savefiles

merge(model)

merge ‘model’ into self

check_inputs()

check the user inputs before running the model raise an exception if user can’t run the model

todo: check if all spills start after model ends

fixme: This should probably be broken out into its

own module, class, something – with each test independent.

validate()

invoke validate for all gnome objects contained in model todo: should also check wind, water, waves are defined if weatherers are defined

_validate_env_coll(refs, raise_exc=False)

validate refs + log warnings or raise error if required refs not found. If refs is None, model must query its weatherers/movers/environment collections to figure out what objects it needs to have in environment.

set_make_default_refs(value)

make default refs for all items in (‘weatherers’, ‘movers’, ‘environment’) collections

list_spill_properties()

Convenience method to list properties of a spill that can be retrieved using get_spill_property

Returns:

list of spill simulation attributes

get_spill_property(prop_name, ucert=False)

Convenience method to allow user to look up properties of a spill.

Parameters:
  • prop_name (str) – name of property: use model.list_properties() to see all the options.

  • ucert (bool) – whether to get it from the uncertainty spill

Returns:

np.array

get_spill_data(target_properties, conditions, ucert=0)

Convenience method to allow user to write an expression to filter raw spill data

Example case:

get_spill_data('position && mass',
               'position > 50 && spill_num == 1 || status_codes == 1'
               )

WARNING: EXPENSIVE! USE AT YOUR OWN RISK ON LARGE num_elements!

Example spill element properties are below. This list may not contain all properties tracked by the model.

‘positions’, ‘next_positions’, ‘last_water_positions’, ‘status_codes’, ‘spill_num’, ‘id’, ‘mass’, ‘age’

add_env(env, quash=False)