Skip to content

Commit

Permalink
ENH: Subset UGRID format #447
Browse files Browse the repository at this point in the history
- Does not include support for element connectivity
  • Loading branch information
bekozi committed Sep 15, 2017
1 parent f58d51d commit 841aafa
Show file tree
Hide file tree
Showing 60 changed files with 5,506 additions and 2,038 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ env:
global:
- NESII_CHANNEL="nesii"
matrix:
- CONDA_PYTHON="python=2.7", OCGIS_DEPS_ADDS="icclim esmpy"
- CONDA_PYTHON="python=2.7", OCGIS_DEPS_ADDS="icclim esmpy mock"
- CONDA_PYTHON="python=3.5", OCGIS_DEPS_ADDS=""
- CONDA_PYTHON="python=3.6", OCGIS_DEPS_ADDS=""

Expand Down
89 changes: 56 additions & 33 deletions doc/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,19 @@ Field
:members:
:special-members:

Grid
++++
Grids
+++++

.. autoclass:: ocgis.Grid
:show-inheritance:
:members:
:special-members:

.. autoclass:: ocgis.GridUnstruct
:show-inheritance:
:members:
:special-members:

GeometryVariable
++++++++++++++++

Expand All @@ -103,6 +108,24 @@ GeometryVariable
:members:
:special-members:

Geometry Coordinate Variables
+++++++++++++++++++++++++++++

.. autoclass:: ocgis.PolygonGC
:show-inheritance:
:members:
:special-members:

.. autoclass:: ocgis.LineGC
:show-inheritance:
:members:
:special-members:

.. autoclass:: ocgis.PointGC
:show-inheritance:
:members:
:special-members:

TemporalVariable
++++++++++++++++

Expand Down Expand Up @@ -180,69 +203,69 @@ SpatialSubsetOperation
Drivers
-------

DriverNetcdf
++++++++++++

.. autoclass:: ocgis.driver.nc.DriverNetcdf
:show-inheritance:

DriverNetcdfCF
++++++++++++++

.. autoclass:: ocgis.driver.nc.DriverNetcdfCF
:show-inheritance:

DriverVector
++++++++++++
.. autoclass:: ocgis.driver.nc_ugrid.DriverNetcdfUGRID
:show-inheritance:

.. autoclass:: ocgis.driver.vector.DriverVector
:show-inheritance:

DriverCSV
+++++++++

.. autoclass:: ocgis.driver.csv_.DriverCSV
:show-inheritance:

Grid Splitter
-------------

.. autoclass:: ocgis.spatial.grid_splitter.GridSplitter

Base Classes
------------

AbstractOcgisObject
+++++++++++++++++++

.. autoclass:: ocgis.base.AbstractOcgisObject
:show-inheritance:

AbstractInterfaceObject
+++++++++++++++++++++++

.. autoclass:: ocgis.base.AbstractInterfaceObject
:show-inheritance:
:members:

AbstractNamedObject
+++++++++++++++++++

.. autoclass:: ocgis.base.AbstractNamedObject
:show-inheritance:
:members:

AbstractContainer
+++++++++++++++++

.. autoclass:: ocgis.variable.base.AbstractContainer
:show-inheritance:
:members:

Attributes
++++++++++
.. autoclass:: ocgis.spatial.grid.AbstractGrid
:show-inheritance:
:members:

.. autoclass:: ocgis.variable.attributes.Attributes
:show-inheritance:
:members:

AbstractCRS
+++++++++++
Spatial Objects
+++++++++++++++

.. autoclass:: ocgis.spatial.base.AbstractSpatialContainer
:show-inheritance:
:members:

.. autoclass:: ocgis.spatial.base.AbstractXYZSpatialContainer
:show-inheritance:
:members:

.. autoclass:: ocgis.spatial.geomc.AbstractGeometryCoordinates
:show-inheritance:
:members:

Coordinate Systems
++++++++++++++++++

.. autoclass:: ocgis.variable.crs.AbstractCRS
:show-inheritance:
Expand All @@ -252,14 +275,14 @@ AbstractCRS
:show-inheritance:
:members:

AbstractDriver
++++++++++++++
Abstract Drivers
++++++++++++++++

.. autoclass:: ocgis.driver.base.AbstractDriver
:show-inheritance:

AbstractTabularDriver
+++++++++++++++++++++
.. autoclass:: ocgis.driver.nc.AbstractDriverNetcdfCF
:show-inheritance:

.. autoclass:: ocgis.driver.base.AbstractTabularDriver
:show-inheritance:
6 changes: 3 additions & 3 deletions doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ Building from Source
Testing the Installation
------------------------

It is recommended that a simple suite of tests are run to verify the new installation. Testing requires the Python ``nose`` library (https://nose.readthedocs.io/en/latest/):
It is recommended that a simple suite of tests are run to verify the new installation. Testing requires the Python ``nose`` library (https://nose.readthedocs.io/en/latest/) and ``mock`` (included by default with Python 3+):

.. code-block:: sh
[sudo] pip install nose
[sudo] pip install nose mock
# OR
conda install nose
conda install nose mock
Run tests:

Expand Down
5 changes: 4 additions & 1 deletion doc/operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ These are global parameters used by OpenClimateGIS. For those familiar with :mod
:attr:`env.USE_CFUNITS` = ``True``
If ``True``, use :mod:`cfunits` for any unit transformations. This will be automatically set to ``False`` if :mod:`cfunits` is not available for import.

:attr:`env.USE_MEMORY_OPTIMIZATIONS` = ``False``
If ``True``, some methods will attempt to minimize their memory usage at the expense of computational time.

:attr:`env.USE_SPATIAL_INDEX` = ``True``
If ``True``, use :mod:`rtree` to create spatial indices for spatial operations. This will be automatically set to ``False`` if :mod:`rtree` is not available for import.

Expand All @@ -577,7 +580,7 @@ These are global parameters used by OpenClimateGIS. For those familiar with :mod
Inspecting Data
===============

See :ref:`inspection` for guidance on inspecing datasets.
See :ref:`inspection` for guidance on inspecting datasets.

Spatial Collections
===================
Expand Down
20 changes: 20 additions & 0 deletions examples/esmf_rwg_indexing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import subprocess

from ocgis import env
from ocgis.test.base import create_gridxy_global
from ocgis.variable.crs import Spherical

SRC_PATH = '/home/benkoziol/htmp/rwg_test_src.nc'
DST_PATH = '/home/benkoziol/htmp/rwg_test_dst.nc'
WGT_PATH = '/home/benkoziol/htmp/rwg_test_weights.nc'
env.CLOBBER_UNITS_ON_BOUNDS = False

src_grid = create_gridxy_global(resolution=10.0, wrapped=False, crs=Spherical())
dst_grid = create_gridxy_global(resolution=20.0, wrapped=False, crs=Spherical())

src_grid.write(SRC_PATH)
dst_grid.write(DST_PATH)

cmd = ['ESMF_RegridWeightGen', '-s', SRC_PATH, '--src_type', 'GRIDSPEC', '-d', DST_PATH, '--dst_type', 'GRIDSPEC',
'-w', WGT_PATH, '--method', 'conserve', '--weight-only']
subprocess.check_call(cmd)
4 changes: 2 additions & 2 deletions examples/ipynb/NESII-IO-20161002.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2.0
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
Expand All @@ -1026,4 +1026,4 @@
},
"nbformat": 4,
"nbformat_minor": 0
}
}
2 changes: 1 addition & 1 deletion examples/subset_ugrid_first_principles.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
def get_subset(bbox, subset_filename, buffer_width, rhs_tol=10.):
rd = ocgis.RequestDataset(uri=IN_PATH)
rd.metadata['dimensions']['nlandmesh_face']['dist'] = True
vc = rd.get_variable_collection()
vc = rd.get_raw_field()

# ------------------------------------------------------------------------------------------------------------------
# Subset the face centers and accumulate the indices of face centers occurring inside the bounding box selection.
Expand Down
108 changes: 108 additions & 0 deletions examples/subset_ugrid_grid_splitter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import os
import tempfile

import ocgis
from ocgis import vm
from ocgis.constants import GridAbstraction
from ocgis.driver.nc_ugrid import DriverNetcdfUGRID
from ocgis.driver.request.core import RequestDataset
from ocgis.spatial.grid_splitter import GridSplitter
from ocgis.test.base import create_gridxy_global, create_exact_field

WD = tempfile.gettempdir()
IN_PATH = '/home/ubuntu/data/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc'
# IN_PATH = '/media/benkoziol/Extra Drive 1/data/ocgis/ugrid-cesm-subsetting/UGRID_1km-merge-10min_HYDRO1K-merge-nomask_c130402.nc'
# OUT_PATH = '/tmp/ugrid_subset.nc'

# OUTDIR = '/home/benkoziol/htmp/ugrid_splits'
OUTDIR = '/home/ubuntu/htmp/ugrid_splits'

BBOX = [10., 5., 12., 7.]
XVAR = 'landmesh_node_x'
YVAR = 'landmesh_node_y'
FACE_CENTER_X = 'landmesh_face_x'
FACE_CENTER_Y = 'landmesh_face_y'
FACE_NODE = 'landmesh_face_node'
DIM_FACE_COUNT = 'nlandmesh_face'
MESHVAR = 'landmesh'

# Do not set units on bounds variables by default.
ocgis.env.CLOBBER_UNITS_ON_BOUNDS = False


def assert_weight_file_is_rational(weight_filename):
wf = RequestDataset(weight_filename).get()
row = wf['row'].get_value()
S = wf['S']
# col = wf['col'].get_value()
for idx in xrange(1, row.size + 1):
print 'current row:', idx
row_idx = row == idx
curr_S = S[row_idx].get_value()
print 'current S sum:', curr_S.sum()
print '============================='


def create_grid_splitter():
resolution = 1. / 111.
# resolution = 1.
dst_grid = create_gridxy_global(resolution=resolution, wrapped=False, crs=ocgis.crs.Spherical())
field = create_exact_field(dst_grid, 'exact', ntime=3, fill_data_var=False, crs=ocgis.crs.Spherical())
field.write(os.path.join(OUTDIR, 'dst_field_1km.nc'))
src_grid = RequestDataset(uri=IN_PATH, driver=DriverNetcdfUGRID, grid_abstraction=GridAbstraction.POINT).get().grid
gs = GridSplitter(src_grid, dst_grid, (10, 10), src_grid_resolution=0.167, check_contains=False)
return gs


def main(write_subsets=False, merge_weight_files=False):
gs = create_grid_splitter()

index_path = os.path.join(OUTDIR, 'gs_index.nc')
if write_subsets:
src_template = os.path.join(OUTDIR, 'src_subset_{}.nc')
dst_template = os.path.join(OUTDIR, 'dst_subset_{}.nc')
wgt_template = os.path.join('esmf_weights_{}.nc')
gs.write_subsets(src_template, dst_template, wgt_template, index_path)

if merge_weight_files:
mwfn = os.path.join(OUTDIR, '01-merged_weights.nc')
gs.create_merged_weight_file(index_path, mwfn, OUTDIR, split_grids_directory=OUTDIR)

vm.barrier()


def test():
# for ii in range(1, 101):
# src_template = os.path.join(OUTDIR, 'src_subset_{}.nc'.format(ii))
# if os.path.exists(src_template):
# dst_template = os.path.join(OUTDIR, 'dst_subset_{}.nc'.format(ii))
# fsrc = RequestDataset(src_template, driver=DriverNetcdfUGRID, grid_abstraction='polygon').get()
# fdst = RequestDataset(dst_template).get()
#
# print 'src extent:', fsrc.grid.extent
# sbox = box(*fsrc.grid.extent)
# print 'dst extent:', fdst.grid.extent
# dbox = box(*fdst.grid.extent)
# print sbox.intersects(dbox)
# time.sleep(0.5)

# for ii in range(1, 101):
# template = os.path.join(OUTDIR, 'esmf_weights_{}.nc'.format(ii))
# if os.path.exists(template):
# field = RequestDataset(template).get()
# S = field['S'].get_value()
# print 'esmf weights:', template
# print 'min:', S.min()
# print 'max:', S.max()
# if (S.max() - 1.0) > 1e6:
# raise ValueError('S is too high')
# if (S.min()) < 0.0:
# raise ValueError('S is less then zero')

weight_filename = os.path.join(OUTDIR, '01-merged_weights.nc')
assert_weight_file_is_rational(weight_filename)


if __name__ == '__main__':
# main(write_subsets=False, merge_weight_files=True)
test()
Loading

0 comments on commit 841aafa

Please sign in to comment.