Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesMakela-NOAA committed Jan 22, 2018
2 parents f781d13 + 0c735a5 commit 2e24d53
Show file tree
Hide file tree
Showing 21 changed files with 318 additions and 80 deletions.
101 changes: 69 additions & 32 deletions py_gnome/gnome/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,44 +23,81 @@

# a few imports so that the basic stuff is there


def check_dependency_versions():
'''
"""
much simpler method :-)
Checks the versions of the following libraries:
gridded
oillibrary
unit_conversion
If the version is not at least as current as what's in the conda_requirements file,
If the version is not at least as current as what's defined here
a warning is displayed
'''
def get_version(package):
package = package.lower()
return next((p.version for p in pkg_resources.working_set if p.project_name.lower() == package), "No match")
libs = [('gridded', '>=', '0.0.9'),
('oil-library', '>=', '1.0.0'),
('unit-conversion', '>=', '2.5.5')]
# condafiledir = os.path.relpath(__file__).split(__file__.split('\\')[-3])[0]
# condafile = os.path.join(condafiledir, 'conda_requirements.txt')
# with open(condafile, 'r') as conda_reqs:
# for line in conda_reqs.readlines():
for req in libs:
criteria = None
req_name, cmp_str, reqd_ver = req
if '>' in cmp_str:
criteria = (lambda a, b: a >= b) if '=' in cmp_str else (lambda a, b: a > b)
elif '<' in cmp_str:
criteria = (lambda a, b: a <= b) if '=' in cmp_str else (lambda a, b: a < b)
else:
criteria = (lambda a, b: a == b)
inst_ver = get_version(req_name)
module_ver = importlib.import_module(req_name.replace('-','_')).__version__
if not criteria(inst_ver, reqd_ver):
if criteria(module_ver, reqd_ver):
w = 'Version {0} of {1} package is reported, but actual version in module is {2}'.format(inst_ver, req_name, module_ver)
warnings.warn(w)
else:
w = 'Version {0} of {1} package is installed in environment, {2}{3} required'.format(inst_ver, req_name, cmp_str, reqd_ver)
warnings.warn(w)
"""
libs = [('gridded', '0.0.9'),
('oil_library', '1.0.6'),
('unit_conversion', '2.5.5')]

for name, version in libs:
# import the lib:
try:
module = importlib.import_module(name)
except ImportError:
print ("ERROR: The {} package, version >= {} needs to be installed".
format(name, version))
sys.exit(1)
if module.__version__ < version:
w = ('Version {0} of {1} package is reported, but actual version in module is {2}'.
format(version, name, module.__version__))
warnings.warn(w)


# ## maybe too complex that required...
# def check_dependency_versions():
# '''
# Checks the versions of the following libraries:
# gridded
# oillibrary
# unit_conversion
# If the version is not at least as current as what's in the conda_requirements file,
# a warning is displayed
# '''
# def get_version(package):
# package = package.lower()
# return next((p.version for p in pkg_resources.working_set
# if p.project_name.lower() == package), "No match")

# libs = [('gridded', '>=', '0.0.9'),
# ('oil-library', '>=', '1.0.6'),
# ('unit-conversion', '>=', '2.5.5')]
# # condafiledir = os.path.relpath(__file__).split(__file__.split('\\')[-3])[0]
# # condafile = os.path.join(condafiledir, 'conda_requirements.txt')
# # with open(condafile, 'r') as conda_reqs:
# # for line in conda_reqs.readlines():
# for req in libs:
# criteria = None
# req_name, cmp_str, reqd_ver = req
# if '>' in cmp_str:
# criteria = (lambda a, b: a >= b) if '=' in cmp_str else (lambda a, b: a > b)
# elif '<' in cmp_str:
# criteria = (lambda a, b: a <= b) if '=' in cmp_str else (lambda a, b: a < b)
# else:
# criteria = (lambda a, b: a == b)
# inst_ver = get_version(req_name)

# try:
# module_ver = importlib.import_module(req_name.replace('-', '_')).__version__
# except ImportError:
# print "ERROR: The {} package, version {} {} needs to be installed".format(*req)
# sys.exit(1)

# if not criteria(inst_ver, reqd_ver):
# if criteria(module_ver, reqd_ver):
# w = 'Version {0} of {1} package is reported, but actual version in module is {2}'.format(inst_ver, req_name, module_ver)
# warnings.warn(w)
# else:
# w = 'Version {0} of {1} package is installed in environment, {2}{3} required'.format(inst_ver, req_name, cmp_str, reqd_ver)
# warnings.warn(w)


def initialize_log(config, logfile=None):
Expand Down
55 changes: 55 additions & 0 deletions py_gnome/gnome/environment/gridded_objects_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,21 @@ def new_from_dict(cls, dict_):
def get_cells(self):
return self.nodes[self.faces]

def get_lines(self):
'''
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 grid.
'''
open_cells = self.nodes[self.faces]
closed_cells = np.concatenate((open_cells, open_cells[:,None,0]), axis=1)
closed_cells = closed_cells.astype(np.float32, copy=False)
lengths = closed_cells.shape[1] * np.ones(closed_cells.shape[0], dtype=np.int32)

return (lengths, [closed_cells])

def get_nodes(self):
return self.nodes[:]

Expand All @@ -150,6 +165,13 @@ def get_centers(self):
self.build_face_coordinates()
return self.face_coordinates

def get_metadata(self):
json_ = {}
json_['nodes_shape'] = self.nodes.shape
json_['num_nodes'] = self.nodes.shape[0]
json_['num_cells'] = self.faces.shape[0]
return json_


class Grid_S(gridded.grids.Grid_S, serializable.Serializable):

Expand Down Expand Up @@ -219,6 +241,28 @@ def get_centers(self):
else:
return self.centers.reshape(-1,2)

def get_metadata(self):
json_ = {}
json_['nodes_shape'] = self.nodes.shape
json_['num_nodes'] = self.nodes.shape[0] * self.nodes.shape[1]
json_['num_cells'] = self._cell_trees['node'][2].shape[0]
return json_

def get_lines(self):
'''
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 grid.
'''
hor_lines = np.dstack((self.node_lon[:], self.node_lat[:])).astype(np.float32, copy=False)
ver_lines = hor_lines.transpose((1, 0, 2)).astype(np.float32, copy=True)
hor_lens = hor_lines.shape[1] * np.ones(hor_lines.shape[0], dtype=np.int32)
ver_lens = ver_lines.shape[1] * np.ones(ver_lines.shape[0], dtype=np.int32)
lens = np.concatenate((hor_lens, ver_lens))
return (lens, [hor_lines, ver_lines])


class Grid_R(gridded.grids.Grid_R, serializable.Serializable):

Expand All @@ -245,6 +289,17 @@ def get_nodes(self):
def get_centers(self):
return self.centers.reshape(-1,2)

def get_cells(self):
return np.concatenate(self.node_lon, self.node_lat)

def get_lines(self):

lon_lines = np.array([[(lon, self.node_lat[0]), (lon, self.node_lat[len(self.node_lat)/2]), (lon, self.node_lat[-1])] for lon in self.node_lon], dtype=np.float32)
lat_lines = np.array([[(self.node_lon[0], lat), (self.node_lon[len(self.node_lon)/2], lat), (self.node_lon[-1], lat)] for lat in self.node_lat], dtype=np.float32)
lon_lens = lon_lines.shape[1] * np.ones(lon_lines.shape[0], dtype=np.int32)
lat_lens = lat_lines.shape[1] * np.ones(lat_lines.shape[0], dtype=np.int32)
lens = np.concatenate((lon_lens, lat_lens))
return (lens, [lon_lines, lat_lines])

class PyGrid(gridded.grids.Grid):

Expand Down
3 changes: 2 additions & 1 deletion py_gnome/gnome/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -1097,7 +1097,8 @@ def __init__(self, filename, raster_size=4096 * 4096, **kwargs):
else:
map_bounds = BB.AsPoly()

elif spillable_area:
if spillable_area is None:
spillable_area = PolygonSet()
spillable_area.append(map_bounds)


Expand Down
1 change: 1 addition & 0 deletions py_gnome/gnome/movers/py_current_movers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class PyCurrentMover(movers.PyMover, serializable.Serializable):
test_for_eq=False),
serializable.Field('current', read=True,
save_reference=True),
serializable.Field('extrapolate', read=True, save=True)
])
_state.add(update=['uncertain_duration', 'uncertain_time_delay'],
save=['uncertain_duration', 'uncertain_time_delay'])
Expand Down
38 changes: 36 additions & 2 deletions py_gnome/gnome/movers/py_wind_movers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import copy

from colander import (SchemaNode,
Bool, Float, String, Sequence,
Bool, Float, String, Sequence, DateTime,
drop)

from gnome.basic_types import (oil_status,
Expand All @@ -13,6 +13,8 @@

from gnome.environment import GridWind
from gnome.persist import base_schema
from gnome.persist.validators import convertible_to_seconds
from gnome.persist.extend_colander import LocalDateTime


class PyWindMoverSchema(base_schema.ObjType):
Expand All @@ -23,6 +25,17 @@ class PyWindMoverSchema(base_schema.ObjType):
extrapolate = SchemaNode(Bool(), missing=drop)
time_offset = SchemaNode(Float(), missing=drop)
wind = GridWind._schema(missing=drop)
real_data_start = SchemaNode(DateTime(), missing=drop)
real_data_stop = SchemaNode(DateTime(), missing=drop)
on = SchemaNode(Bool(), missing=drop)
active_start = SchemaNode(LocalDateTime(), missing=drop,
validator=convertible_to_seconds)
active_stop = SchemaNode(LocalDateTime(), missing=drop,
validator=convertible_to_seconds)
real_data_start = SchemaNode(LocalDateTime(), missing=drop,
validator=convertible_to_seconds)
real_data_stop = SchemaNode(LocalDateTime(), missing=drop,
validator=convertible_to_seconds)


class PyWindMover(movers.PyMover, serializable.Serializable):
Expand All @@ -33,7 +46,8 @@ class PyWindMover(movers.PyMover, serializable.Serializable):
save=True, read=True, isdatafile=True,
test_for_eq=False),
serializable.Field('wind', save=True, read=True,
save_reference=True)])
save_reference=True),
serializable.Field('extrapolate', read=True, save=True)])
_state.add(update=['uncertain_duration', 'uncertain_time_delay'],
save=['uncertain_duration', 'uncertain_time_delay'])
_schema = PyWindMoverSchema
Expand Down Expand Up @@ -137,6 +151,26 @@ def from_netCDF(cls,
uncertain_cross=uncertain_cross,
default_num_method=default_num_method)

@property
def real_data_start(self):
return self.wind.time.min_time.replace(tzinfo=None)

@real_data_start.setter
def real_data_start(self, value):
self._r_d_s = value

@property
def real_data_stop(self):
return self.wind.time.max_time.replace(tzinfo=None)

@real_data_stop.setter
def real_data_stop(self, value):
self._r_d_e = value

@property
def is_data_on_cells(self):
return self.wind.grid.infer_location(self.current.u.data) != 'node'

def prepare_for_model_step(self, sc, time_step, model_time_datetime):
"""
Call base class method using super
Expand Down
18 changes: 14 additions & 4 deletions py_gnome/gnome/scripting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@
Scripting package for GNOME with assorted utilities that make it easier to
write scripts.
The ultimate goal is to be able to run py_gnome for the "common" use cases
with only functions available in this module
Helper functions are imported from various py_gnome modules
(spill, environment, movers etc).
"""
from .utilities import *

from gnome.environment.wind import constant_wind
from gnome.spill.spill import point_line_release_spill
from gnome.spill.spill import surface_point_line_spill, subsurface_plume_spill
from gnome.movers.wind_movers import constant_wind_mover
from gnome.movers.wind_movers import wind_mover_from_file

from gnome.spill.spill import (point_line_release_spill,
surface_point_line_spill,
subsurface_plume_spill,
grid_spill,
)
from gnome.movers.wind_movers import (constant_wind_mover,
wind_mover_from_file,
)

8 changes: 7 additions & 1 deletion py_gnome/gnome/scripting/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
assorted utilities that make it easier to write scripts to automate gnome
designed to be imported into the pacakge __init__.py
designed to be imported into the package __init__.py
remember to add anyting new you want imported to "__all__"
"""
import os
import shutil

__all__ = ["make_images_dir",
"remove_netcdf",
]


def make_images_dir(images_dir=None):
"""
Expand Down
24 changes: 6 additions & 18 deletions py_gnome/gnome/spill/__init__.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
from spill import (Spill, SpillSchema,
from spill import (Spill,
SpillSchema,
point_line_release_spill,
continuous_release_spill)
continuous_release_spill,
grid_spill)

from release import (Release,
ReleaseSchema,
PointLineReleaseSchema,
PointLineRelease,
PointLineReleaseSchema,
ContinuousRelease,
SpatialRelease,
GridRelease,
VerticalPlumeRelease,
InitElemsFromFile)
import elements

__all__ = [Spill,
SpillSchema,
point_line_release_spill,
continuous_release_spill,
Release,
ReleaseSchema,
PointLineReleaseSchema,
PointLineRelease,
ContinuousRelease,
SpatialRelease,
GridRelease,
VerticalPlumeRelease,
InitElemsFromFile,
elements,
]
4 changes: 4 additions & 0 deletions py_gnome/gnome/spill/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,9 @@ def GridRelease(release_time, bounds, resolution):
((min_lon, min_lat),
(max_lon, max_lat))
:type bounds: 2x2 numpy array or equivalent
:param resolution: resolution of grid -- it will be a resoluiton X resolution grid
:type resolution: integer
"""
lon = np.linspace(bounds[0][0], bounds[1][0], resolution)
lat = np.linspace(bounds[0][1], bounds[1][1], resolution)
Expand All @@ -928,6 +931,7 @@ def GridRelease(release_time, bounds, resolution):

return SpatialRelease(release_time, positions)


class ContinuousSpatialRelease(SpatialRelease):
"""
continuous release of elements from specified positions
Expand Down
Loading

0 comments on commit 2e24d53

Please sign in to comment.