def test_two_triangles_without_edges(): grid = two_triangles_with_depths() grid.edges = None fname = '2_triangles_without_edges.nc' with chdir(test_files): grid.save_as_netcdf(fname) ug = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert ug.nodes.shape == (4, 2) assert ug.nodes.shape == grid.nodes.shape # FIXME: Not ideal to pull specific values out, but how else to test? assert np.array_equal(ug.nodes[0, :], (0.1, 0.1)) assert np.array_equal(ug.nodes[-1, :], (3.1, 2.1)) assert np.array_equal(ug.nodes, grid.nodes) assert ug.faces.shape == grid.faces.shape assert ug.edges is None depths = find_depths(ug) assert depths.data.shape == (4,) assert depths.data[0] == 1 assert depths.attributes['units'] == 'unknown'
def test_write_with_edge_data(): """Tests writing a netcdf file with data on the edges (fluxes, maybe?).""" grid = two_triangles() grid.mesh_name = 'mesh2' # Create a UVar object for fluxes: flux = UVar('flux', location='edge', data=[0.0, 0.0, 4.1, 0.0, 5.1, ]) flux.attributes['units'] = 'm^3/s' flux.attributes['long_name'] = 'volume flux between cells' flux.attributes['standard_name'] = 'ocean_volume_transport_across_line' grid.add_data(flux) # Add coordinates for edges. grid.build_edge_coordinates() fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) assert nc_has_variable(ds, 'mesh2') assert nc_has_variable(ds, 'flux') assert nc_var_has_attr_vals(ds, 'flux', { 'coordinates': 'mesh2_edge_lon mesh2_edge_lat', 'location': 'edge', 'units': 'm^3/s', 'mesh': 'mesh2'}) assert np.array_equal(ds.variables['mesh2_edge_lon'], grid.edge_coordinates[:, 0]) assert np.array_equal(ds.variables['mesh2_edge_lat'], grid.edge_coordinates[:, 1]) ds.close()
def test_with_just_nodes_and_depths(): expected = two_triangles() del expected.faces del expected.edges depth = UVar('depth', 'node', np.array([1.0, 2.0, 3.0, 4.0]), {'units': 'm', 'positive': 'down', 'standard_name': 'sea_floor_depth_below_geoid'}) expected.add_data(depth) fname = '2_triangles_depth.nc' with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert grid.faces is None assert grid.edges is None assert np.array_equal(expected.nodes, grid.nodes) assert np.array_equal(expected.data['depth'].data, grid.data['depth'].data) assert expected.data['depth'].attributes == grid.data['depth'].attributes
def test_write_with_depths(): """Tests writing a netcdf file with depth data.""" grid = two_triangles() grid.mesh_name = 'mesh1' # Create a UVar object for the depths: depths = UVar('depth', location='node', data=[1.0, 2.0, 3.0, 4.0]) depths.attributes['units'] = 'm' depths.attributes['standard_name'] = 'sea_floor_depth_below_geoid' depths.attributes['positive'] = 'down' grid.add_data(depths) fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) assert nc_has_variable(ds, 'mesh1') assert nc_has_variable(ds, 'depth') assert nc_var_has_attr_vals(ds, 'depth', { 'coordinates': 'mesh1_node_lon mesh1_node_lat', 'location': 'node', 'mesh': 'mesh1'}) ds.close()
def test_set_mesh_name(): grid = two_triangles() grid.mesh_name = 'mesh_2' fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) assert nc_has_variable(ds, 'mesh_2') assert nc_var_has_attr_vals(ds, 'mesh_2', { 'cf_role': 'mesh_topology', 'topology_dimension': 2, 'long_name': u'Topology data of 2D unstructured mesh'}) assert nc_var_has_attr_vals(ds, 'mesh_2', { 'cf_role': 'mesh_topology', 'topology_dimension': 2, 'long_name': u'Topology data of 2D unstructured mesh', 'node_coordinates': 'mesh_2_node_lon mesh_2_node_lat'}) assert nc_has_variable(ds, 'mesh_2_node_lon') assert nc_has_variable(ds, 'mesh_2_node_lat') assert nc_has_variable(ds, 'mesh_2_face_nodes') assert nc_has_variable(ds, 'mesh_2_edge_nodes') assert nc_has_dimension(ds, 'mesh_2_num_node') assert nc_has_dimension(ds, 'mesh_2_num_edge') assert nc_has_dimension(ds, 'mesh_2_num_face') assert nc_has_dimension(ds, 'mesh_2_num_vertices') assert not nc_var_has_attr(ds, 'mesh_2', 'face_edge_connectivity') ds.close()
def test_with_just_nodes_and_depths(): expected = two_triangles() del expected.faces del expected.edges depth = UVar( "depth", "node", np.array([1.0, 2.0, 3.0, 4.0]), {"units": "m", "positive": "down", "standard_name": "sea_floor_depth_below_geoid"}, ) expected.add_data(depth) fname = "2_triangles_depth.nc" with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert grid.faces is None assert grid.edges is None assert np.array_equal(expected.nodes, grid.nodes) assert np.array_equal(expected.data["depth"].data, grid.data["depth"].data) assert expected.data["depth"].attributes == grid.data["depth"].attributes
def test_nc_variable(): """ test that it works with a netcdf variable object """ import netCDF4 # make a variable with chdir(test_files): fname = 'junk.nc' ds = netCDF4.Dataset(fname, mode='w') ds.createDimension('dim', (10)) var = ds.createVariable('a_var', float, ('dim')) var[:] = np.arange(10) # give it some attributes var.attr_1 = 'some value' var.attr_2 = 'another value' # make a UVar from it uvar = UVar("a_var", 'node', data=var) assert uvar._data is var # preserved the netcdf variable print(uvar.attributes) assert uvar.attributes == {'attr_1': 'some value', 'attr_2': 'another value'} # access the data assert np.array_equal(uvar[3:5], [3.0, 4.0])
def test_two_triangles_without_edges(): grid = two_triangles_with_depths() grid.edges = None fname = '2_triangles_without_edges.nc' with chdir(test_files): grid.save_as_netcdf(fname) ug = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert ug.nodes.shape == (4, 2) assert ug.nodes.shape == grid.nodes.shape # FIXME: Not ideal to pull specific values out, but how else to test? assert np.array_equal(ug.nodes[0, :], (0.1, 0.1)) assert np.array_equal(ug.nodes[-1, :], (3.1, 2.1)) assert np.array_equal(ug.nodes, grid.nodes) assert ug.faces.shape == grid.faces.shape assert ug.edges is None depths = find_depths(ug) assert depths.data.shape == (4, ) assert depths.data[0] == 1 assert depths.attributes['units'] == 'unknown'
def test_read_longitude_no_standard_name(): with chdir(files): grid = UGrid.from_ncfile('no_stand_name_long.nc') assert grid.nodes.shape == (11, 2) # Not ideal to pull specific values out, but how else to test? assert np.array_equal(grid.nodes[0, :], (-62.242, 12.774999)) assert np.array_equal(grid.nodes[-1, :], (-34.911235, 29.29379))
def test_get_mesh_names(): """ Check that it can find the mesh variable names. """ with chdir(files): nc = netCDF4.Dataset('ElevenPoints_UGRIDv0.9.nc') names = read_netcdf.find_mesh_names(nc) assert names == [u'Mesh2']
def test_read_nodes(): """Do we get the right nodes array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.nodes.shape == (11, 2) # Not ideal to pull specific values out, but how else to test? assert np.array_equal(grid.nodes[0, :], (-62.242, 12.774999)) assert np.array_equal(grid.nodes[-1, :], (-34.911235, 29.29379))
def test_read_none_edges(): """Do we get the right edge array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') # no edges in the file assert grid._edges is None # but edges can be generated from the faces grid.build_edges() assert grid.edges is not None
def test_read_face_face(): """Do we get the right face_face_connectivity array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.face_face_connectivity.shape == (13, 3) # Not ideal to pull specific values out, but how else to test? assert np.array_equal(grid.face_face_connectivity[0, :], (11, 5, -1)) assert np.array_equal(grid.face_face_connectivity[-1, :], (-1, 5, 11))
def test_read_data(): expected_depth = [1, 1, 1, 102, 1, 1, 60, 1, 1, 97, 1] expected_depth_attributes = {'standard_name': 'sea_floor_depth_below_geoid', 'units': 'm', 'positive': 'down', } with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc', load_data=True) assert np.array_equal(grid.data['depth'].data, expected_depth) assert grid.data['depth'].attributes == expected_depth_attributes
def test_read_faces(): """Do we get the right faces array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.faces.shape == (13, 3) # Not ideal to pull specific values out, but how else to test? assert np.array_equal(grid.faces[0, :], (2, 3, 10)) assert np.array_equal(grid.faces[-1, :], (10, 5, 6))
def test_load_grid_from_nc(): """Test reading a fairly full example file.""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.mesh_name == 'Mesh2' assert grid.nodes.shape == (11, 2) assert grid.faces.shape == (13, 3) assert grid.face_face_connectivity.shape == (13, 3) assert grid.boundaries.shape == (9, 2) assert grid.edges is None
def test_read_from_nc_dataset(): """ Minimal test, but makes sure you can read from an already open netCDF4.Dataset. """ with chdir(files): with netCDF4.Dataset('ElevenPoints_UGRIDv0.9.nc') as nc: grid = UGrid.from_nc_dataset(nc) assert grid.mesh_name == 'Mesh2' assert grid.nodes.shape == (11, 2) assert grid.faces.shape == (13, 3)
def test_read_face_coordinates(): """Do we get the right face_coordinates array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.face_coordinates.shape == (13, 2) # Not ideal to pull specific values out, but how else to test? assert np.array_equal(grid.face_coordinates[0], (-37.1904106666667, 30.57093)) assert np.array_equal(grid.face_coordinates[-1], (-38.684412, 27.7132626666667))
def test_read_boundaries(): """Do we get the right boundaries array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.boundaries.shape == (9, 2) # Not ideal to pull specific values out, but how else to test? # Note: file is 1-indexed, so these values are adjusted. expected_boundaries = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 0], [5, 6], [6, 7], [7, 8], [8, 5]] assert np.array_equal(grid.boundaries, expected_boundaries)
def test_without_faces(): expected = two_triangles() del expected.faces assert expected.faces is None fname = "2_triangles.nc" with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname) os.remove(fname) assert grid.faces is None assert np.array_equal(expected.faces, grid.faces) assert np.array_equal(expected.edges, grid.edges)
def test_without_faces(): expected = two_triangles() del expected.faces assert expected.faces is None fname = '2_triangles.nc' with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname) os.remove(fname) assert grid.faces is None assert np.array_equal(expected.faces, grid.faces) assert np.array_equal(expected.edges, grid.edges)
def test_simple_write(): grid = two_triangles() fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) # TODO: Could be lots of tests here. assert nc_has_variable(ds, 'mesh') assert nc_var_has_attr_vals(ds, 'mesh', { 'cf_role': 'mesh_topology', 'topology_dimension': 2, 'long_name': u'Topology data of 2D unstructured mesh'}) ds.close()
def test_with_faces(): """ Test with faces, edges, but no `face_coordinates` or `edge_coordinates`. """ expected = two_triangles() fname = '2_triangles.nc' with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname) os.remove(fname) assert np.array_equal(expected.nodes, grid.nodes) assert np.array_equal(expected.faces, grid.faces) assert np.array_equal(expected.edges, grid.edges)
def test_with_faces(): """ Test with faces, edges, but no `face_coordinates` or `edge_coordinates`. """ expected = two_triangles() fname = "2_triangles.nc" with chdir(test_files): expected.save_as_netcdf(fname) grid = UGrid.from_ncfile(fname) os.remove(fname) assert np.array_equal(expected.nodes, grid.nodes) assert np.array_equal(expected.faces, grid.faces) assert np.array_equal(expected.edges, grid.edges)
def test_write_with_bound_data(): """ Tests writing a netcdf file with data on the boundaries suitable for boundary conditions, for example fluxes. """ grid = two_triangles() # Add the boundary definitions: grid.boundaries = [(0, 1), (0, 2), (1, 3), (2, 3)] # Create a UVar object for boundary conditions: bnds = UVar('bnd_cond', location='boundary', data=[0, 1, 0, 0]) bnds.attributes['long_name'] = 'model boundary conditions' bnds.attributes['flag_values'] = '0 1' bnds.attributes['flag_meanings'] = 'no_flow_boundary open_boundary' grid.add_data(bnds) fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) assert nc_has_variable(ds, 'mesh') assert nc_has_variable(ds, 'bnd_cond') assert nc_var_has_attr_vals(ds, 'mesh', { 'boundary_node_connectivity': 'mesh_boundary_nodes'}) assert nc_var_has_attr_vals(ds, 'bnd_cond', {'location': 'boundary', 'flag_values': '0 1', 'flag_meanings': 'no_flow_boundary open_boundary', 'mesh': 'mesh', }) # There should be no coordinates attribute or variable for the # boundaries as there is no boundaries_coordinates defined. assert not nc_has_variable(ds, 'mesh_boundary_lon') assert not nc_has_variable(ds, 'mesh_boundary_lat') assert not nc_var_has_attr(ds, 'bnd_cond', 'coordinates') ds.close()
def test_21_triangles(): grid = twenty_one_triangles_with_depths() fname = '21_triangles.nc' with chdir(test_files): grid.save_as_netcdf(fname) ug = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert ug.nodes.shape == grid.nodes.shape # FIXME: Not ideal to pull specific values out, but how else to test? assert np.array_equal(ug.nodes, grid.nodes) depths = find_depths(ug) assert depths.data.shape == (20, ) assert depths.data[0] == 1 assert depths.attributes['units'] == 'unknown'
def test_21_triangles(): grid = twenty_one_triangles_with_depths() fname = '21_triangles.nc' with chdir(test_files): grid.save_as_netcdf(fname) ug = UGrid.from_ncfile(fname, load_data=True) os.remove(fname) assert ug.nodes.shape == grid.nodes.shape # FIXME: Not ideal to pull specific values out, but how else to test? assert np.array_equal(ug.nodes, grid.nodes) depths = find_depths(ug) assert depths.data.shape == (20,) assert depths.data[0] == 1 assert depths.attributes['units'] == 'unknown'
def test_write_with_velocities(): """Tests writing a netcdf file with velocities on the faces.""" grid = two_triangles() grid.mesh_name = 'mesh2' # Create a UVar object for u velocity: u_vel = UVar('u', location='face', data=[1.0, 2.0]) u_vel.attributes['units'] = 'm/s' u_vel.attributes['standard_name'] = 'eastward_sea_water_velocity' grid.add_data(u_vel) # Create a UVar object for v velocity: v_vel = UVar('v', location='face', data=[3.2, 4.3]) v_vel.attributes['units'] = 'm/s' v_vel.attributes['standard_name'] = 'northward_sea_water_velocity' grid.add_data(v_vel) # Add coordinates for face data. grid.build_face_coordinates() fname = 'temp.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) os.remove(fname) assert nc_has_variable(ds, 'mesh2') assert nc_has_variable(ds, 'u') assert nc_has_variable(ds, 'v') assert nc_var_has_attr_vals(ds, 'u', {'coordinates': 'mesh2_face_lon mesh2_face_lat', 'location': 'face', 'mesh': 'mesh2', } ) ds.close()
def test_read_data_keys(): with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc', load_data=True) assert sorted(grid.data.keys()) == [u'boundary_count', u'boundary_types', u'depth']
def test_read_none_boundary_coordinates(): """Do we get the right boundary_coordinates array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.boundary_coordinates is None
def test_read_none_edges(): """Do we get the right edge array?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert grid.edges is None
def test_write_everything(): """An example with all features enabled, and a less trivial grid.""" grid = twenty_one_triangles() grid.build_edges() grid.build_face_face_connectivity() grid.build_edge_coordinates() grid.build_face_coordinates() grid.build_boundary_coordinates() # Depth on the nodes. depths = UVar('depth', location='node', data=np.linspace(1, 10, 20)) depths.attributes['units'] = 'm' depths.attributes['standard_name'] = 'sea_floor_depth_below_geoid' depths.attributes['positive'] = 'down' grid.add_data(depths) # Create a UVar object for u velocity: u_vel = UVar('u', location='face', data=np.sin(np.linspace(3, 12, 21))) u_vel.attributes['units'] = 'm/s' u_vel.attributes['standard_name'] = 'eastward_sea_water_velocity' grid.add_data(u_vel) # Create a UVar object for v velocity: v_vel = UVar('v', location='face', data=np.sin(np.linspace(12, 15, 21))) v_vel.attributes['units'] = 'm/s' v_vel.attributes['standard_name'] = 'northward_sea_water_velocity' grid.add_data(v_vel) # Fluxes on the edges: flux = UVar('flux', location='edge', data=np.linspace(1000, 2000, 41)) flux.attributes['units'] = 'm^3/s' flux.attributes['long_name'] = 'volume flux between cells' flux.attributes['standard_name'] = 'ocean_volume_transport_across_line' grid.add_data(flux) # Boundary conditions: bounds = np.zeros((19,), dtype=np.uint8) bounds[7] = 1 bnds = UVar('bnd_cond', location='boundary', data=bounds) bnds.attributes['long_name'] = 'model boundary conditions' bnds.attributes['flag_values'] = '0 1' bnds.attributes['flag_meanings'] = 'no_flow_boundary open_boundary' grid.add_data(bnds) fname = 'full_example.nc' with chdir(test_files): grid.save_as_netcdf(fname) ds = netCDF4.Dataset(fname) # Now the tests: assert nc_has_variable(ds, 'mesh') assert nc_has_variable(ds, 'depth') assert nc_var_has_attr_vals(ds, 'depth', { 'coordinates': 'mesh_node_lon mesh_node_lat', 'location': 'node'}) assert nc_has_variable(ds, 'u') assert nc_has_variable(ds, 'v') assert nc_var_has_attr_vals(ds, 'u', { 'coordinates': 'mesh_face_lon mesh_face_lat', 'location': 'face', 'mesh': 'mesh'}) assert nc_var_has_attr_vals(ds, 'v', { 'coordinates': 'mesh_face_lon mesh_face_lat', 'location': 'face', 'mesh': 'mesh'}) assert nc_has_variable(ds, 'flux') assert nc_var_has_attr_vals(ds, 'flux', { 'coordinates': 'mesh_edge_lon mesh_edge_lat', 'location': 'edge', 'units': 'm^3/s', 'mesh': 'mesh'}) assert nc_has_variable(ds, 'mesh') assert nc_has_variable(ds, 'bnd_cond') assert nc_var_has_attr_vals(ds, 'mesh', { 'boundary_node_connectivity': 'mesh_boundary_nodes'}) assert nc_var_has_attr_vals(ds, 'bnd_cond', { 'location': 'boundary', 'flag_values': '0 1', 'flag_meanings': 'no_flow_boundary open_boundary', 'mesh': 'mesh'}) ds.close() # And make sure pyugrid can reload it! with chdir(test_files): grid = UGrid.from_ncfile('full_example.nc', load_data=True) # And that some things are the same. # NOTE: more testing might be good here. # maybe some grid comparison functions? assert grid.mesh_name == 'mesh' assert len(grid.nodes) == 20 depth = grid.data['depth'] assert depth.attributes['units'] == 'm' u = grid.data['u'] assert u.attributes['units'] == 'm/s' os.remove(fname)
def test_mesh_not_there(): """Test raising Value error with incorrect mesh name.""" with pytest.raises(ValueError): with chdir(files): UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc', mesh_name='garbage')
def test_simple_read(): """Can it be read at all?""" with chdir(files): grid = UGrid.from_ncfile('ElevenPoints_UGRIDv0.9.nc') assert isinstance(grid, UGrid)