diff --git a/src/waveresponse/_core.py b/src/waveresponse/_core.py index d11839e..e33c62a 100644 --- a/src/waveresponse/_core.py +++ b/src/waveresponse/_core.py @@ -1818,12 +1818,6 @@ def reshape( vals_new = interp_fun(freq_new, dirs_new) - if freq_hz: - vals_new *= 2.0 * np.pi - - if degrees: - vals_new *= np.pi / 180.0 - new = self.copy() new._freq, new._dirs, new._vals = freq_new, dirs_new, vals_new return new @@ -2003,9 +1997,6 @@ def reshape( vals_new = interp_fun(freq_new, self._dirs) - if freq_hz: - vals_new *= 2.0 * np.pi - new = self.copy() new._freq, new._vals = freq_new, vals_new return new @@ -2149,6 +2140,9 @@ def dirm(self, degrees=None): during instantiation. """ + if degrees is None: + degrees = self._degrees + dp, sp = self.spectrum1d(axis=0, degrees=False) d = self._full_range_dir(dp) @@ -2297,6 +2291,9 @@ def dirm(self, degrees=None): during instantiation. """ + if degrees is None: + degrees = self._degrees + dirm = self._mean_direction(*self.spectrum1d(axis=0, degrees=False)) if degrees: diff --git a/tests/test_core.py b/tests/test_core.py index 361021b..c13dec8 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -4156,6 +4156,151 @@ def test_extreme_absmax(self): assert extreme_out == pytest.approx(extreme_expect) + def test_reshape(self): + a = 7 + b = 6 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in yp]) + spectrum = DirectionalSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + x = np.linspace(5.0, 15.0, 10) + grid_reshaped = spectrum.reshape(y, x, freq_hz=True, degrees=True) + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * x + vals_expect = ( + np.array([[a * x_i + b * y_i for x_i in x] for y_i in y]) + * (180.0 / np.pi) + / (2.0 * np.pi) + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape2(self): + a = 7 + b = 6 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in yp]) + spectrum = DirectionalSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + x = np.linspace(5.0, 15.0, 10) + y_ = (2.0 * np.pi) * y + x_ = (np.pi / 180.0) * x + grid_reshaped = spectrum.reshape(y_, x_, freq_hz=False, degrees=False) + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * x + vals_expect = ( + np.array([[a * x_i + b * y_i for x_i in x] for y_i in y]) + * (180.0 / np.pi) + / (2.0 * np.pi) + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape_complex_rectangular(self): + a_real = 7 + b_real = 6 + a_imag = 3 + b_imag = 9 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp_real = np.array([[a_real * x_i + b_real * y_i for x_i in xp] for y_i in yp]) + vp_imag = np.array([[a_imag * x_i + b_imag * y_i for x_i in xp] for y_i in yp]) + vp = vp_real + 1j * vp_imag + spectrum = DirectionalSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + x = np.linspace(5.0, 15.0, 10) + grid_reshaped = spectrum.reshape( + y, x, freq_hz=True, degrees=True, complex_convert="rectangular" + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * x + vals_real_expect = np.array( + [[a_real * x_i + b_real * y_i for x_i in x] for y_i in y] + ) + vals_imag_expect = np.array( + [[a_imag * x_i + b_imag * y_i for x_i in x] for y_i in y] + ) + vals_expect = ( + (vals_real_expect + 1j * vals_imag_expect) * (180.0 / np.pi) / (2.0 * np.pi) + ) + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape_complex_polar(self): + a_amp = 7 + b_amp = 6 + a_phase = 0.01 + b_phase = 0.03 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp_amp = np.array([[a_amp * x_i + b_amp * y_i for x_i in xp] for y_i in yp]) + vp_phase = np.array( + [[a_phase * x_i + b_phase * y_i for x_i in xp] for y_i in yp] + ) + vp = vp_amp * (np.cos(vp_phase) + 1j * np.sin(vp_phase)) + spectrum = DirectionalSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + x = np.linspace(5.0, 15.0, 10) + grid_reshaped = spectrum.reshape( + y, x, freq_hz=True, degrees=True, complex_convert="polar" + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * x + vals_amp_expect = ( + np.array([[a_amp * x_i + b_amp * y_i for x_i in x] for y_i in y]) + * (180.0 / np.pi) + / (2.0 * np.pi) + ) + x_, y_ = np.meshgrid(x, y, indexing="ij", sparse=True) + vals_phase_cos_expect = RGI((xp, yp), np.cos(vp_phase).T)((x_, y_)).T + vals_phase_sin_expect = RGI((xp, yp), np.sin(vp_phase).T)((x_, y_)).T + + vals_expect = ( + vals_amp_expect + * (vals_phase_cos_expect + 1j * vals_phase_sin_expect) + / np.abs(vals_phase_cos_expect + 1j * vals_phase_sin_expect) + ) + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + class Test_DirectionalBinSpectrum: def test__init___hz_deg(self): @@ -4956,6 +5101,134 @@ def test_extreme_absmax(self): assert extreme_out == pytest.approx(extreme_expect) + def test_reshape(self): + a = 7 + b = 6 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in yp]) + spectrum = DirectionalBinSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + grid_reshaped = spectrum.reshape(y, freq_hz=True) + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * xp + vals_expect = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in y]) / ( + 2.0 * np.pi + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape2(self): + a = 7 + b = 6 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in yp]) + spectrum = DirectionalBinSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + y_ = (2.0 * np.pi) * y + grid_reshaped = spectrum.reshape(y_, freq_hz=False) + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * xp + vals_expect = np.array([[a * x_i + b * y_i for x_i in xp] for y_i in y]) / ( + 2.0 * np.pi + ) + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape_complex_rectangular(self): + a_real = 7 + b_real = 6 + a_imag = 3 + b_imag = 9 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp_real = np.array([[a_real * x_i + b_real * y_i for x_i in xp] for y_i in yp]) + vp_imag = np.array([[a_imag * x_i + b_imag * y_i for x_i in xp] for y_i in yp]) + vp = vp_real + 1j * vp_imag + spectrum = DirectionalBinSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + grid_reshaped = spectrum.reshape(y, freq_hz=True, complex_convert="rectangular") + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * xp + vals_real_expect = np.array( + [[a_real * x_i + b_real * y_i for x_i in xp] for y_i in y] + ) + vals_imag_expect = np.array( + [[a_imag * x_i + b_imag * y_i for x_i in xp] for y_i in y] + ) + vals_expect = (vals_real_expect + 1j * vals_imag_expect) / (2.0 * np.pi) + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + + def test_reshape_complex_polar(self): + a_amp = 7 + b_amp = 6 + a_phase = 0.01 + b_phase = 0.03 + + yp = np.linspace(0.0, 2.0, 20) + xp = np.linspace(0.0, 359.0, 10) + vp_amp = np.array([[a_amp * x_i + b_amp * y_i for x_i in xp] for y_i in yp]) + vp_phase = np.array( + [[a_phase * x_i + b_phase * y_i for x_i in xp] for y_i in yp] + ) + vp = vp_amp * (np.cos(vp_phase) + 1j * np.sin(vp_phase)) + spectrum = DirectionalBinSpectrum(yp, xp, vp, freq_hz=True, degrees=True) + + y = np.linspace(0.5, 1.0, 20) + grid_reshaped = spectrum.reshape(y, freq_hz=True, complex_convert="polar") + + freq_out = grid_reshaped._freq + dirs_out = grid_reshaped._dirs + vals_out = grid_reshaped._vals + + freq_expect = (2.0 * np.pi) * y + dirs_expect = (np.pi / 180.0) * xp + vals_amp_expect = np.array( + [[a_amp * x_i + b_amp * y_i for x_i in xp] for y_i in y] + ) / (2.0 * np.pi) + x_, y_ = np.meshgrid(xp, y, indexing="ij", sparse=True) + vals_phase_cos_expect = RGI((xp, yp), np.cos(vp_phase).T)((x_, y_)).T + vals_phase_sin_expect = RGI((xp, yp), np.sin(vp_phase).T)((x_, y_)).T + + vals_expect = ( + vals_amp_expect + * (vals_phase_cos_expect + 1j * vals_phase_sin_expect) + / np.abs(vals_phase_cos_expect + 1j * vals_phase_sin_expect) + ) + + np.testing.assert_array_almost_equal(freq_out, freq_expect) + np.testing.assert_array_almost_equal(dirs_out, dirs_expect) + np.testing.assert_array_almost_equal(vals_out, vals_expect) + class Test_WaveSpectrum: def test__init__(self):