def test_init_with_shared_varset_prior(self): shared_varset = plot.VariableSet() golf1 = cube.DataCube(golf_path, varset=shared_varset) golf2 = cube.DataCube(golf_path, varset=shared_varset) assert type(golf1.varset) is plot.VariableSet assert type(golf2.varset) is plot.VariableSet assert golf1.varset is shared_varset assert golf1.varset is golf2.varset
def test_Planform_slicing(self): # make the planforms golfcube = cube.DataCube(golf_path) golfcubestrat = cube.DataCube(golf_path) golfcubestrat.stratigraphy_from('eta', dz=0.1) golfstrat = cube.StratigraphyCube.from_DataCube(golfcube, dz=0.1) plnfrm1 = plan.Planform(golfcube, idx=-1) plnfrm2 = plan.Planform(golfcubestrat, z=-2) plnfrm3 = plan.Planform(golfstrat, z=-6) # note should be deep enough for no nans assert np.all(plnfrm1['eta'] == golfcube['eta'][-1, :, :]) assert np.all( plnfrm2['time'] == golfcubestrat['time'][plnfrm2.idx, :, :]) assert np.all(plnfrm3['time'] == golfstrat['time'][plnfrm3.idx, :, :])
def test_Planform_idx(self): golfcube = cube.DataCube(golf_path) plnfrm = plan.Planform(golfcube, idx=40) assert plnfrm.name == 'data' assert plnfrm.idx == 40 assert plnfrm.cube == golfcube assert len(plnfrm.variables) > 0
def test_show_section_mocked_BaseSection_show(self): golf = cube.DataCube(golf_path) golf.register_section('displaysection', section.StrikeSection(distance_idx=10)) golf.sections['displaysection'].show = mock.MagicMock() mocked = golf.sections['displaysection'].show # no arguments is an error with pytest.raises(TypeError, match=r'.* missing 2 .*'): golf.show_section() # one argument is an error with pytest.raises(TypeError, match=r'.* missing 1 .*'): golf.show_section('displaysection') # three arguments is an error with pytest.raises(TypeError, match=r'.* takes 3 .*'): golf.show_section('one', 'two', 'three') # two arguments passes to BaseSection.show() golf.show_section('displaysection', 'eta') assert mocked.call_count == 1 # kwargs should be passed along to BaseSection.show golf.show_section('displaysection', 'eta', ax=100) assert mocked.call_count == 2 mocked.assert_called_with('eta', ax=100) # first arg must be a string with pytest.raises(TypeError, match=r'`name` was not .*'): golf.show_section(1, 'two')
def test_init_cube_from_path_rcm8(self): golf = cube.DataCube(golf_path) assert golf._data_path == golf_path assert golf.dataio.io_type == 'netcdf' assert golf._planform_set == {} assert golf._section_set == {} assert type(golf.varset) is plot.VariableSet
def test_nostratigraphy_default_attribute_derived_variable(self): golf = cube.DataCube(golf_path) golf.register_section('testsection', section.StrikeSection(distance_idx=10)) assert golf._knows_stratigraphy is False with pytest.raises(utils.NoStratigraphyError): golf.sections['testsection']['velocity'].strat.as_stratigraphy()
def test_planforms_slice_op(self): golf = cube.DataCube(golf_path) golf.stratigraphy_from('eta', dz=0.1) golf.register_planform('testplanform', plan.Planform(idx=10)) assert 'testplanform' in golf.planforms.keys() slc = golf.planforms['testplanform'] assert issubclass(type(slc), plan.BasePlanform)
def test_register_plan_legacy_method(self): """This tests the shorthand named version.""" golf = cube.DataCube(golf_path) golf.register_plan('testplanform', plan.Planform(idx=10)) assert golf.planforms is golf.planform_set assert len(golf.planforms.keys()) == 1 assert 'testplanform' in golf.planforms.keys()
def test_DataCube_two_dataset(self): eta_data = self.fixeddatacube['eta'][:, :, :] vel_data = self.fixeddatacube['velocity'][:, :, :] dict_cube = cube.DataCube({'eta': eta_data, 'velocity': vel_data}) assert np.all(dict_cube['eta'] == self.fixeddatacube['eta'][:, :, :]) assert np.all( dict_cube['velocity'] == self.fixeddatacube['velocity'][:, :, :])
def test_Planform_private_show(self): """Doesn't actually check the plots, just checks that the function runs. """ # make the planforms golfcube = cube.DataCube(golf_path) plnfrm = plan.Planform(golfcube, idx=-1) _field = plnfrm['eta'] _varinfo = golfcube.varset['eta'] # with axis fig, ax = plt.subplots() plnfrm._show(_field, _varinfo, ax=ax) plt.close() # without axis fig, ax = plt.subplots() plnfrm._show(_field, _varinfo) plt.close() # with colorbar_label fig, ax = plt.subplots(1, 2) plnfrm._show(_field, _varinfo, ax=ax[0], colorbar_label='test') plnfrm._show(_field, _varinfo, ax=ax[1], colorbar_label=True) plt.close() # with ticks fig, ax = plt.subplots() plnfrm._show(_field, _varinfo, ax=ax, ticks=True) plt.close() # with title fig, ax = plt.subplots() plnfrm._show(_field, _varinfo, ax=ax, title='some title') plt.close()
def test_sections_slice_op(self): golf = cube.DataCube(golf_path) golf.stratigraphy_from('eta', dz=0.1) golf.register_section('testsection', section.StrikeSection(distance_idx=10)) assert 'testsection' in golf.sections.keys() slc = golf.sections['testsection'] assert issubclass(type(slc), section.BaseSection)
def test_Planform_idx_z_t_mutual_exclusive(self): golfcube = cube.DataCube(golf_path) with pytest.raises(TypeError, match=r'Cannot .* `z` and `idx`.'): _ = plan.Planform(golfcube, z=5e6, idx=30) with pytest.raises(TypeError, match=r'Cannot .* `t` and `idx`.'): _ = plan.Planform(golfcube, t=3e6, idx=30) with pytest.raises(TypeError, match=r'Cannot .* `z` and `t`.'): _ = plan.Planform(golfcube, t=3e6, z=5e6)
def test_init_cube_from_path_hdf5(self): with pytest.warns(UserWarning, match=r'No associated metadata'): hdfcube = cube.DataCube(hdf_path) assert hdfcube._data_path == hdf_path assert hdfcube.dataio.io_type == 'hdf5' assert hdfcube._planform_set == {} assert hdfcube._section_set == {} assert type(hdfcube.varset) is plot.VariableSet
def test_Planform_z_t_thesame(self): golfcube = cube.DataCube(golf_path) plnfrm = plan.Planform(golfcube, t=3e6) plnfrm2 = plan.Planform(golfcube, z=3e6) assert plnfrm.name == 'data' assert plnfrm.idx == 6 assert plnfrm.idx == plnfrm2.idx assert plnfrm.cube == golfcube assert len(plnfrm.variables) > 0
def test_init_cube_from_path_rcm8(self): with pytest.warns(UserWarning) as record: rcm8cube = cube.DataCube(rcm8_path) assert rcm8cube._data_path == rcm8_path assert rcm8cube.dataio.io_type == 'netcdf' assert rcm8cube._planform_set == {} assert rcm8cube._section_set == {} assert type(rcm8cube.varset) is plot.VariableSet # check that two warnings were raised assert re.match(r'Coordinates for "time", .*', record[0].message.args[0]) assert re.match(r'No associated metadata .*', record[1].message.args[0])
def test_register_section(self): golf = cube.DataCube(golf_path) golf.stratigraphy_from('eta', dz=0.1) golf.register_section('testsection', section.StrikeSection(distance_idx=10)) assert golf.sections is golf.section_set assert len(golf.sections.keys()) == 1 assert 'testsection' in golf.sections.keys() with pytest.raises(TypeError, match=r'`SectionInstance` .*'): golf.register_section('fail1', 'astring') with pytest.raises(TypeError, match=r'`SectionInstance` .*'): golf.register_section('fail2', 22) with pytest.raises(TypeError, match=r'`name` .*'): golf.register_section(22, section.StrikeSection(distance_idx=10))
class TestCubesFromDictionary: fixeddatacube = cube.DataCube(golf_path) def test_DataCube_one_dataset(self): eta_data = self.fixeddatacube['eta'][:, :, :] dict_cube = cube.DataCube({'eta': eta_data}) assert isinstance(dict_cube['eta'], xr.core.dataarray.DataArray) assert dict_cube.shape == self.fixeddatacube.shape assert np.all(dict_cube['eta'] == self.fixeddatacube['eta'][:, :, :]) def test_DataCube_one_dataset_numpy(self): eta_data = np.array(self.fixeddatacube['eta'][:, :, :]) dict_cube = cube.DataCube({'eta': eta_data}) # the return is always dataarray! assert isinstance(dict_cube['eta'], xr.core.dataarray.DataArray) assert dict_cube.shape == self.fixeddatacube.shape def test_DataCube_one_dataset_partial(self): eta_data = self.fixeddatacube['eta'][:30, :, :] dict_cube = cube.DataCube({'eta': eta_data}) assert np.all(dict_cube['eta'] == self.fixeddatacube['eta'][:30, :, :]) def test_DataCube_two_dataset(self): eta_data = self.fixeddatacube['eta'][:, :, :] vel_data = self.fixeddatacube['velocity'][:, :, :] dict_cube = cube.DataCube({'eta': eta_data, 'velocity': vel_data}) assert np.all(dict_cube['eta'] == self.fixeddatacube['eta'][:, :, :]) assert np.all( dict_cube['velocity'] == self.fixeddatacube['velocity'][:, :, :]) @pytest.mark.xfail(NotImplementedError, reason='not implemented', strict=True) def test_StratigraphyCube_from_etas(self): eta_data = self.fixeddatacube['eta'][:, :, :] _ = cube.StratigraphyCube({'eta': eta_data}) @pytest.mark.xfail(NotImplementedError, reason='not implemented', strict=True) def test_StratigraphyCube_from_etas_numpy(self): eta_data = self.fixeddatacube['eta'][:, :, :] _ = cube.StratigraphyCube({'eta': np.array(eta_data)}) def test_no_metadata_integrated(self): eta_data = self.fixeddatacube['eta'][:30, :, :] dict_cube = cube.DataCube({'eta': eta_data}) with pytest.raises(AttributeError): dict_cube.meta
class TestComputeSurfaceDepositAge: golfcube = cube.DataCube(golf_path) def test_idx_minus_date(self): with pytest.raises(ValueError): # cannot be index 0 _ = plan.compute_surface_deposit_time(self.golfcube, surface_idx=0) sfc_date_1 = plan.compute_surface_deposit_age(self.golfcube, surface_idx=1) assert np.all(sfc_date_1 == 1) # 1 - 0 sfc_date_m1 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1) # check that the idx wrapping functionality works assert np.all(sfc_date_m1 >= 0)
def test_register_planform(self): golf = cube.DataCube(golf_path) golf.stratigraphy_from('eta', dz=0.1) golf.register_planform('testplanform', plan.Planform(idx=10)) assert golf.planforms is golf.planform_set assert len(golf.planforms.keys()) == 1 assert 'testplanform' in golf.planforms.keys() with pytest.raises(TypeError, match=r'`PlanformInstance` .*'): golf.register_planform('fail1', 'astring') with pytest.raises(TypeError, match=r'`PlanformInstance` .*'): golf.register_planform('fail2', 22) with pytest.raises(TypeError, match=r'`name` .*'): golf.register_planform(22, plan.Planform(idx=10)) returnedplanform = golf.register_planform('returnedplanform', plan.Planform(idx=10), return_planform=True) assert returnedplanform.name == 'returnedplanform'
class TestShorelineDistance: golf_path = _get_golf_path() golf = cube.DataCube(golf_path) sm = mask.ShorelineMask(golf['eta'][-1, :, :], elevation_threshold=0, elevation_offset=-0.5) def test_empty(self): _arr = np.zeros((10, 10)) with pytest.raises(ValueError): _, _ = plan.compute_shoreline_distance(_arr) def test_single_point(self): _arr = np.zeros((10, 10)) _arr[7, 5] = 1 mean00, stddev00 = plan.compute_shoreline_distance(_arr) mean05, stddev05 = plan.compute_shoreline_distance(_arr, origin=[5, 0]) assert mean00 == np.sqrt(49 + 25) assert mean05 == 7 assert stddev00 == 0 assert stddev05 == 0 def test_simple_case(self): mean, stddev = plan.compute_shoreline_distance( self.sm, origin=[self.golf.meta['CTR'].data, self.golf.meta['L0'].data]) assert mean > stddev assert stddev > 0 def test_simple_case_distances(self): m, s = plan.compute_shoreline_distance( self.sm, origin=[self.golf.meta['CTR'].data, self.golf.meta['L0'].data]) m2, s2, dists = plan.compute_shoreline_distance( self.sm, origin=[self.golf.meta['CTR'].data, self.golf.meta['L0'].data], return_distances=True) assert len(dists) > 0 assert np.mean(dists) == m assert m2 == m assert s2 == s
def test_Planform_public_show(self): golfcube = cube.DataCube(golf_path) plnfrm = plan.Planform(golfcube, idx=-1) plnfrm._show = mock.MagicMock() # test with ax fig, ax = plt.subplots() plnfrm.show('time', ax=ax) plt.close() assert plnfrm._show.call_count == 1 # check that all bogus args are passed to _show plnfrm.show('time', ax=100, title=101, ticks=102, colorbar_label=103) assert plnfrm._show.call_count == 2 # hacky method to pull out the keyword calls only kw_calls = plnfrm._show.mock_calls[1][2:][0] assert kw_calls['ax'] == 100 assert kw_calls['title'] == 101 assert kw_calls['ticks'] == 102 assert kw_calls['colorbar_label'] == 103
class TestFrozenStratigraphyCube: fixeddatacube = cube.DataCube(golf_path) fixedstratigraphycube = cube.StratigraphyCube.from_DataCube(fixeddatacube, dz=0.1) frozenstratigraphycube = fixedstratigraphycube.export_frozen_variable( 'time') def test_types(self): assert isinstance(self.frozenstratigraphycube, xr.core.dataarray.DataArray) def test_matches_underlying_data(self): assert not (self.frozenstratigraphycube is self.fixedstratigraphycube) frzn_log = self.frozenstratigraphycube.values[ ~np.isnan(self.frozenstratigraphycube.values)] fixd_log = self.fixedstratigraphycube['time'].values[ ~np.isnan(self.fixedstratigraphycube['time'].values)] assert frzn_log.shape == fixd_log.shape assert np.all(fixd_log == frzn_log)
class TestStratigraphyCube: # create a fixed cube for variable existing, type checks fixeddatacube = cube.DataCube(golf_path) fixedstratigraphycube = cube.StratigraphyCube.from_DataCube(fixeddatacube, dz=0.1) def test_no_tT_StratigraphyCube(self): with pytest.raises(AttributeError): _ = self.fixedstratigraphycube.t with pytest.raises(AttributeError): _ = self.fixedstratigraphycube.T def test_export_frozen_variable(self): frzn = self.fixedstratigraphycube.export_frozen_variable('time') assert frzn.ndim == 3 def test_StratigraphyCube_inherit_varset(self): # when creating from DataCube, varset should be inherited tempsc = cube.StratigraphyCube.from_DataCube(self.fixeddatacube, dz=1) assert tempsc.varset is self.fixeddatacube.varset
class TestComputeSurfaceDepositTime: golfcube = cube.DataCube(golf_path) def test_with_diff_indices(self): with pytest.raises(ValueError): # cannot be index 0 _ = plan.compute_surface_deposit_time(self.golfcube, surface_idx=0) sfc_date_1 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=1) assert np.all(sfc_date_1 == 0) sfc_date_m1 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1) assert np.any(sfc_date_m1 > 0) # test that cannot be above idx half_idx = self.golfcube.shape[0] // 2 sfc_date_half = plan.compute_surface_deposit_time(self.golfcube, surface_idx=half_idx) assert np.max(sfc_date_half) <= half_idx assert np.max(sfc_date_m1) <= self.golfcube.shape[0] def test_with_diff_stasis_tol(self): with pytest.raises(ValueError): # cannot be tol 0 _ = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1, stasis_tol=0) sfc_date_tol_000 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1, stasis_tol=1e-16) sfc_date_tol_001 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1, stasis_tol=0.01) sfc_date_tol_010 = plan.compute_surface_deposit_time(self.golfcube, surface_idx=-1, stasis_tol=0.1) # time of deposition should always be older when threshold is greater assert np.all(sfc_date_tol_001 <= sfc_date_tol_000) assert np.all(sfc_date_tol_010 <= sfc_date_tol_001)
class TestLandsatCube: with pytest.warns(UserWarning, match=r'No associated metadata'): landsatcube = cube.DataCube(hdf_path) def test_init_cube_from_path_hdf5(self): with pytest.warns(UserWarning, match=r'No associated metadata'): hdfcube = cube.DataCube(hdf_path) assert hdfcube._data_path == hdf_path assert hdfcube.dataio.io_type == 'hdf5' assert hdfcube._planform_set == {} assert hdfcube._section_set == {} assert type(hdfcube.varset) is plot.VariableSet def test_read_Blue_intomemory(self): assert self.landsatcube._dataio._in_memory_data == {} assert self.landsatcube.variables == ['Blue', 'Green', 'NIR', 'Red'] assert len(self.landsatcube.variables) == 4 self.landsatcube.read('Blue') assert len(self.landsatcube.dataio._in_memory_data) == 1 def test_read_all_intomemory(self): assert self.landsatcube.variables == ['Blue', 'Green', 'NIR', 'Red'] assert len(self.landsatcube.variables) == 4 self.landsatcube.read(True) assert len(self.landsatcube.dataio._in_memory_data) == 4 def test_read_invalid(self): with pytest.raises(TypeError): self.landsatcube.read(5) def test_get_coords(self): assert self.landsatcube.coords == ['time', 'x', 'y'] assert self.landsatcube._coords == ['time', 'x', 'y']
class TestComputeChannelDepth: simple_cm = np.array([[0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0]]) simple_depth = np.array( [[1.5, 0.5, 1.5, 0.2, 0.4, 1.5, 1.5, 1, 1, 1, 1, 1.5, 1.5, 9, 0]]) trace = np.column_stack((np.zeros(simple_cm.shape[1]), np.arange(simple_cm.shape[1]))).astype(int) golf_path = _get_golf_path() golf = cube.DataCube(golf_path) cm = mask.ChannelMask(golf['eta'][-1, :, :], golf['velocity'][-1, :, :], elevation_threshold=0, flow_threshold=0.3) sec = section.CircularSection(golf, radius_idx=40) def test_depths_simple_thalweg(self): """Get mean and std from simple.""" m, s = plan.compute_channel_depth(self.simple_cm, self.simple_depth, section=self.trace) assert m == (0.5 + 0.4 + 1 + 9) / 4 assert s == pytest.approx(3.6299965564) def test_depths_simple_mean(self): """Get mean and std from simple.""" m, s = plan.compute_channel_depth(self.simple_cm, self.simple_depth, section=self.trace, depth_type='mean') assert m == (0.5 + 0.3 + 1 + 9) / 4 assert s == pytest.approx(3.6462309307009066) def test_depths_simple_list_equal(self): """Get mean, std, list from simple, check that same.""" m1, s1 = plan.compute_channel_depth(self.simple_cm, self.simple_depth, section=self.trace) m2, s2, w = plan.compute_channel_depth(self.simple_cm, self.simple_depth, section=self.trace, return_depths=True) assert m1 == (0.5 + 0.4 + 1 + 9) / 4 assert m1 == m2 assert s1 == s2 assert len(w) == 4 def test_depths_example_thalweg(self): """Get mean and std from example. This test does not actually test the computation, just that something valid is returned, i.e., the function takes the input. """ m, s = plan.compute_channel_depth(self.cm, self.golf['depth'][-1, :, :], section=self.sec) assert m > 0 assert s > 0 def test_bad_masktype(self): with pytest.raises(TypeError): m, s = plan.compute_channel_depth(33, self.golf['depth'][-1, :, :], section=self.sec) with pytest.raises(TypeError): m, s = plan.compute_channel_depth(True, self.golf['depth'][-1, :, :], section=self.sec) def test_bad_depth_type_arg(self): with pytest.raises(ValueError): m, s = plan.compute_channel_depth(self.cm, self.golf['depth'][-1, :, :], depth_type='nonsense', section=self.sec) def test_no_section_make_default(self): with pytest.raises(NotImplementedError): m, s = plan.compute_channel_depth(self.cm, self.golf['depth'][-1, :, :])
class TestComputeChannelWidth: simple_cm = np.array([[0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0]]) trace = np.column_stack((np.zeros(simple_cm.shape[1]), np.arange(simple_cm.shape[1]))).astype(int) golf_path = _get_golf_path() golf = cube.DataCube(golf_path) cm = mask.ChannelMask(golf['eta'][-1, :, :], golf['velocity'][-1, :, :], elevation_threshold=0, flow_threshold=0.3) sec = section.CircularSection(golf, radius_idx=40) def test_widths_simple(self): """Get mean and std from simple.""" m, s = plan.compute_channel_width(self.simple_cm, section=self.trace) assert m == (1 + 2 + 4 + 1) / 4 assert s == pytest.approx(1.22474487) def test_widths_simple_list_equal(self): """Get mean, std, list from simple, check that same.""" m1, s1 = plan.compute_channel_width(self.simple_cm, section=self.trace) m2, s2, w = plan.compute_channel_width(self.simple_cm, section=self.trace, return_widths=True) assert m1 == (1 + 2 + 4 + 1) / 4 assert m1 == m2 assert s1 == s2 assert len(w) == 4 def test_widths_example(self): """Get mean and std from example. This test does not actually test the computation, just that something valid is returned, i.e., the function takes the input. """ m, s = plan.compute_channel_width(self.cm, section=self.sec) # check valid values returned assert m > 0 assert s > 0 def test_bad_masktype(self): with pytest.raises(TypeError): m, s = plan.compute_channel_width(33, section=self.sec) with pytest.raises(TypeError): m, s = plan.compute_channel_width(True, section=self.sec) def test_no_section_make_default(self): with pytest.raises(NotImplementedError): m, s = plan.compute_channel_width(self.cm) def test_get_channel_starts_and_ends(self): _cs, _ce = plan._get_channel_starts_and_ends(self.simple_cm, self.trace) assert _cs[0] == 1 assert _ce[0] == 2 def test_wraparound(self): alt_cm = np.array([[1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1]]) _cs, _ce = plan._get_channel_starts_and_ends(alt_cm, self.trace) assert _cs[0] == 1 assert _ce[0] == 2
class TestShorelineLength: rcm8_path = _get_rcm8_path() with pytest.warns(UserWarning): rcm8 = cube.DataCube(rcm8_path) sm = mask.ShorelineMask(rcm8['eta'][-1, :, :], elevation_threshold=0) sm0 = mask.ShorelineMask(rcm8['eta'][0, :, :], elevation_threshold=0) _trim_length = 4 sm.trim_mask(length=_trim_length) sm0.trim_mask(length=_trim_length) rcm8_expected = 331.61484154404747 def test_simple_case(self): simple_len = plan.compute_shoreline_length(simple_shore) exp_len = (7 * 1) + (2 * 1.41421356) assert simple_len == pytest.approx(exp_len, abs=0.1) def test_simple_case_opposite(self): simple_len = plan.compute_shoreline_length(simple_shore, origin=[10, 0]) exp_len = (7 * 1) + (2 * 1.41421356) assert simple_len == pytest.approx(exp_len, abs=0.1) def test_simple_case_return_line(self): simple_len, simple_line = plan.compute_shoreline_length( simple_shore, return_line=True) exp_len = (7 * 1) + (2 * 1.41421356) assert simple_len == pytest.approx(exp_len) assert np.all(simple_line == np.fliplr(simple_shore_array)) def test_rcm8_defaults(self): # test that it is the same with opposite side origin len_0 = plan.compute_shoreline_length(self.sm) assert len_0 == pytest.approx(self.rcm8_expected, abs=0.1) def test_rcm8_defaults_opposite(self): # test that it is the same with opposite side origin len_0, line_0 = plan.compute_shoreline_length(self.sm, return_line=True) _o = [self.rcm8.shape[2], 0] len_1, line_1 = plan.compute_shoreline_length(self.sm, origin=_o, return_line=True) if False: import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 2) ax[0].imshow(self.sm.mask.squeeze()) ax[1].imshow(self.sm.mask.squeeze()) ax[0].plot(0, 0, 'ro') ax[1].plot(_o[0], _o[1], 'bo') ax[0].plot(line_0[:, 0], line_0[:, 1], 'r-') ax[1].plot(line_1[:, 0], line_1[:, 1], 'b-') plt.show(block=False) fig, ax = plt.subplots() ax.plot( np.cumsum( np.sqrt((line_0[1:, 0] - line_0[:-1, 0])**2 + (line_0[1:, 1] - line_0[:-1, 1])**2))) ax.plot( np.cumsum( np.sqrt((line_1[1:, 0] - line_1[:-1, 0])**2 + (line_1[1:, 1] - line_1[:-1, 1])**2))) plt.show() breakpoint() assert len_1 == pytest.approx(self.rcm8_expected, abs=5.0)
class TestShorelineRoughness: rcm8_path = _get_rcm8_path() with pytest.warns(UserWarning): rcm8 = cube.DataCube(rcm8_path) lm = mask.LandMask(rcm8['eta'][-1, :, :], elevation_threshold=0) sm = mask.ShorelineMask(rcm8['eta'][-1, :, :], elevation_threshold=0) lm0 = mask.LandMask(rcm8['eta'][0, :, :], elevation_threshold=0) sm0 = mask.ShorelineMask(rcm8['eta'][0, :, :], elevation_threshold=0) _trim_length = 4 lm.trim_mask(length=_trim_length) sm.trim_mask(length=_trim_length) lm0.trim_mask(length=_trim_length) sm0.trim_mask(length=_trim_length) rcm8_expected = 4.476379600936939 def test_simple_case(self): simple_rgh = plan.compute_shoreline_roughness(simple_shore, simple_land) exp_area = 45 exp_len = (7 * 1) + (2 * 1.41421356) exp_rgh = exp_len / np.sqrt(exp_area) assert simple_rgh == pytest.approx(exp_rgh) def test_rcm8_defaults(self): # test it with default options rgh_0 = plan.compute_shoreline_roughness(self.sm, self.lm) assert rgh_0 == pytest.approx(self.rcm8_expected, abs=0.1) def test_rcm8_ignore_return_line(self): # test that it ignores return_line arg rgh_1 = plan.compute_shoreline_roughness(self.sm, self.lm, return_line=False) assert rgh_1 == pytest.approx(self.rcm8_expected, abs=0.1) def test_rcm8_defaults_opposite(self): # test that it is the same with opposite side origin rgh_2 = plan.compute_shoreline_roughness( self.sm, self.lm, origin=[0, self.rcm8.shape[1]]) assert rgh_2 == pytest.approx(self.rcm8_expected, abs=0.2) def test_rcm8_fail_no_shoreline(self): # check raises error with pytest.raises(ValueError, match=r'No pixels in shoreline mask.'): plan.compute_shoreline_roughness(np.zeros((10, 10)), self.lm) def test_rcm8_fail_no_land(self): # check raises error with pytest.raises(ValueError, match=r'No pixels in land mask.'): plan.compute_shoreline_roughness(self.sm, np.zeros((10, 10))) def test_compute_shoreline_roughness_asarray(self): # test it with default options _smarr = np.copy(self.sm.mask) _lmarr = np.copy(self.lm.mask) assert isinstance(_smarr, np.ndarray) assert isinstance(_lmarr, np.ndarray) rgh_3 = plan.compute_shoreline_roughness(_smarr, _lmarr) assert rgh_3 == pytest.approx(self.rcm8_expected, abs=0.1)
class TestMorphologicalPlanform: simple_land = simple_land golf_path = _get_golf_path() golfcube = cube.DataCube(golf_path) def test_defaults_array_int(self): mpm = plan.MorphologicalPlanform(self.simple_land.astype(int), 2) assert isinstance(mpm._mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm._all_images, np.ndarray) assert mpm._mean_image.shape == self.simple_land.shape assert len(mpm._all_images.shape) == 3 assert mpm._all_images.shape[0] == 3 def test_defaults_array_bool(self): mpm = plan.MorphologicalPlanform(self.simple_land.astype(bool), 2) assert isinstance(mpm._mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm._all_images, np.ndarray) assert mpm._mean_image.shape == self.simple_land.shape assert len(mpm._all_images.shape) == 3 assert mpm._all_images.shape[0] == 3 def test_defaults_array_float(self): mpm = plan.MorphologicalPlanform(self.simple_land.astype(float), 2.0) assert isinstance(mpm._mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm._all_images, np.ndarray) assert mpm._mean_image.shape == self.simple_land.shape assert len(mpm._all_images.shape) == 3 assert mpm._all_images.shape[0] == 3 def test_invalid_disk_arg(self): with pytest.raises(TypeError): plan.MorphologicalPlanform(self.simple_land.astype(int), 'bad') def test_defaults_static_from_elevation_data(self): mpm = plan.MorphologicalPlanform.from_elevation_data( self.golfcube['eta'][-1, :, :], elevation_threshold=0, max_disk=2) assert mpm.planform_type == 'morphological method' assert mpm._mean_image.shape == (100, 200) assert mpm._all_images.shape == (3, 100, 200) assert isinstance(mpm._mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm._all_images, np.ndarray) def test_static_from_mask(self): mpm = plan.MorphologicalPlanform.from_mask(self.simple_land, 2) assert isinstance(mpm._mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm._all_images, np.ndarray) assert mpm._mean_image.shape == self.simple_land.shape assert len(mpm._all_images.shape) == 3 assert mpm._all_images.shape[0] == 3 def test_static_from_mask_negative_disk(self): mpm = plan.MorphologicalPlanform.from_mask(self.simple_land, -2) assert isinstance(mpm.mean_image, xr.core.dataarray.DataArray) assert isinstance(mpm.all_images, np.ndarray) assert mpm.mean_image.shape == self.simple_land.shape assert len(mpm.all_images.shape) == 3 assert mpm.all_images.shape[0] == 2 assert np.all(mpm.composite_array == mpm.mean_image) def test_empty_error(self): with pytest.raises(ValueError): plan.MorphologicalPlanform() def test_bad_type(self): with pytest.raises(TypeError): plan.MorphologicalPlanform('invalid string')