Пример #1
0
    def test_simplify_mpeaks(self):
        # 1D: Four attributes.
        peaks = swprocess.Peaks(self.frq,
                                self.vel,
                                identifier=self._id,
                                azimuth=self.azi,
                                power=self.pwr,
                                ellipticity=self.ell,
                                noise=self.noi)
        for attr in [
                "frequency", "velocity", "azimuth", "power", "ellipticity",
                "noise"
        ]:
            simplified_attr = peaks.simplify_mpeaks(attr)
            self.assertArrayEqual(getattr(peaks, f"{attr}"), simplified_attr)

        # 2D: No attributes with nan.
        peaks = swprocess.Peaks(self.frq2n, self.vel2n, identifier=self._id2n)
        row, col = np.array([1, 0, 0]), np.array([0, 1, 2])
        for attr in ["frequency", "velocity"]:
            simplified_attr = peaks.simplify_mpeaks(attr)
            self.assertArrayEqual(
                getattr(peaks, f"_{attr}")[row, col], simplified_attr)

        # 2D: Four attributes with nan.
        peaks = swprocess.Peaks(self.frq2n,
                                self.vel2n,
                                identifier=self._id2n,
                                azimuth=self.azi2n,
                                power=self.pwr2n,
                                ellipticity=self.ell2n,
                                noise=self.noi2n)
        row, col = np.array([1, 0, 0]), np.array([0, 1, 2])
        for attr in [
                "frequency", "velocity", "azimuth", "power", "ellipticity",
                "noise"
        ]:
            simplified_attr = peaks.simplify_mpeaks(attr)
            self.assertArrayEqual(
                getattr(peaks, f"_{attr}")[row, col], simplified_attr)

        # 2D: Power attribute with nan.
        frequency = np.array([[1, 3, 5, 7, 9, np.nan],
                              [1, 3, np.nan, np.nan, 9, 2],
                              [np.nan, np.nan, np.nan, 7, 9, 2]])
        velocity = np.array([[1, 3, 5, 7, 9, np.nan],
                             [3, 9, np.nan, np.nan, 9, 2],
                             [np.nan, np.nan, np.nan, 7, 9, 2]])
        power = np.array([[2, 6, 1, 8, 2, np.nan],
                          [5, 1, np.nan, np.nan, 9, 1],
                          [np.nan, np.nan, np.nan, 1, 1, 9]])
        peaks = swprocess.Peaks(frequency,
                                velocity,
                                identifier=self._id2n,
                                power=power)
        row, col = np.array([1, 0, 0, 0, 1, 2]), np.array([0, 1, 2, 3, 4, 5])
        for attr in ["frequency", "velocity", "power"]:
            simplified_attr = peaks.simplify_mpeaks(attr)
            self.assertArrayEqual(
                getattr(peaks, f"_{attr}")[row, col], simplified_attr)
Пример #2
0
    def test_reject_limits_outside(self):
        fs = np.array([1, 5, 9, np.nan, 3, 5, 7, 4, 6, 2, 8])
        vs = np.array([1, 9, 4, np.nan, 5, 6, 8, 5, 2, 1, 4])

        # None
        peaks = swprocess.Peaks(fs, vs)
        limits = None, None
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            peaks.reject_limits_outside("frequency", limits)
        self.assertArrayEqual(fs[np.isfinite(fs)], peaks.frequency)
        self.assertArrayEqual(vs[np.isfinite(vs)], peaks.velocity)

        # Remove all above 4.5
        peaks = swprocess.Peaks(fs, vs)
        limits = None, 4.5
        peaks.reject_limits_outside("frequency", limits)
        self.assertArrayEqual(np.array([1., 3, 4, 2]), peaks.frequency)
        self.assertArrayEqual(np.array([1., 5, 5, 1]), peaks.velocity)

        # Remove all below 4.5
        peaks = swprocess.Peaks(fs, vs)
        limits = 4.5, None
        peaks.reject_limits_outside("frequency", limits)
        self.assertArrayEqual(np.array([5., 9, 5, 7, 6, 8]), peaks.frequency)
        self.assertArrayEqual(np.array([9., 4, 6, 8, 2, 4]), peaks.velocity)

        # Remove all below 1.5 and above 6.5
        peaks = swprocess.Peaks(fs, vs)
        limits = 1.5, 6.5
        peaks.reject_limits_outside("frequency", limits)
        self.assertArrayEqual(np.array([5., 3, 5, 4, 6, 2]), peaks.frequency)
        self.assertArrayEqual(np.array([9., 5, 6, 5, 2, 1]), peaks.velocity)
Пример #3
0
    def test_init(self):
        # 1D: No keyword arguments
        peaks = swprocess.Peaks(self.frq, self.vel, identifier=self._id)
        self.assertArrayEqual(np.array(self.frq), peaks.frequency)
        self.assertArrayEqual(np.array(self.vel), peaks.velocity)
        self.assertEqual(self._id, peaks.identifier)

        # 1D: Four keyword arguments
        peaks = swprocess.Peaks(self.frq,
                                self.vel,
                                identifier=self._id,
                                azimuth=self.azi,
                                ellipticity=self.ell,
                                noise=self.noi,
                                power=self.pwr)
        self.assertArrayEqual(np.array(self.frq), peaks.frequency)
        self.assertArrayEqual(np.array(self.vel), peaks.velocity)
        self.assertEqual(self._id, peaks.identifier)
        self.assertArrayEqual(np.array(self.azi), peaks.azimuth)
        self.assertArrayEqual(np.array(self.ell), peaks.ellipticity)
        self.assertArrayEqual(np.array(self.noi), peaks.noise)
        self.assertArrayEqual(np.array(self.pwr), peaks.power)

        # 2D: Four keyword arguments
        peaks = swprocess.Peaks(self.frq2,
                                self.vel2,
                                identifier=self._id2,
                                azimuth=self.azi2,
                                ellipticity=self.ell2,
                                noise=self.noi2,
                                power=self.pwr2)
        self.assertArrayEqual(np.array(self.frq2).flatten(), peaks.frequency)
        self.assertArrayEqual(np.array(self.vel2).flatten(), peaks.velocity)
        self.assertEqual(self._id2, peaks.identifier)
        self.assertArrayEqual(np.array(self.azi2).flatten(), peaks.azimuth)
        self.assertArrayEqual(np.array(self.ell2).flatten(), peaks.ellipticity)
        self.assertArrayEqual(np.array(self.noi2).flatten(), peaks.noise)
        self.assertArrayEqual(np.array(self.pwr2).flatten(), peaks.power)

        # 2D: Four keyword arguments with nans
        peaks = swprocess.Peaks(self.frq2n,
                                self.vel2n,
                                identifier=self._id2n,
                                azimuth=self.azi2n,
                                ellipticity=self.ell2n,
                                noise=self.noi2n,
                                power=self.pwr2n)
        self.assertArrayEqual(
            np.array(self.frq2n)[self.valid], peaks.frequency)
        self.assertArrayEqual(np.array(self.vel2n)[self.valid], peaks.velocity)
        self.assertEqual(self._id2n, peaks.identifier)
        self.assertArrayEqual(np.array(self.azi2n)[self.valid], peaks.azimuth)
        self.assertArrayEqual(
            np.array(self.ell2n)[self.valid], peaks.ellipticity)
        self.assertArrayEqual(np.array(self.noi2n)[self.valid], peaks.noise)
        self.assertArrayEqual(np.array(self.pwr2n)[self.valid], peaks.power)
Пример #4
0
    def test_append(self):
        # Simple append operation.
        p0 = swprocess.Peaks([1, 2, 3], [4, 5, 6], "p0")
        p1 = swprocess.Peaks([[7, np.nan, 9], [4, 5, 6]],
                             [[1, np.nan, 2], [7, 8, 9]], "p1")
        suite = swprocess.PeaksSuite(p0)
        suite.append(p1)

        for returned, expected in zip(suite, [p0, p1]):
            self.assertEqual(expected, returned)

        # Bad: replicated identifier
        self.assertRaises(KeyError, suite.append, p1)

        # Bad: append non-Peaks object
        self.assertRaises(TypeError, suite.append, "not a Peaks object")
Пример #5
0
    def test_configure_axes(self):
        peaks = swprocess.Peaks(self.frq, self.vel, self._id)
        defaults = {
            "frequency": {
                "label": "frq",
                "scale": "linear"
            },
            "velocity": {
                "label": "vel",
                "scale": "log"
            }
        }

        # Standard calls.
        ax = MagicMock()
        peaks._configure_axes(ax,
                              xtype="frequency",
                              ytype="velocity",
                              defaults=defaults)
        ax.set_xlabel.assert_called_with("frq")
        ax.set_xscale.assert_called_with("linear")
        ax.set_ylabel.assert_called_with("vel")
        ax.set_yscale.assert_called_with("log")

        # Non-standard calls to unknown attribute.
        ax = MagicMock()
        peaks._configure_axes(ax,
                              xtype="frequency",
                              ytype="azimuth",
                              defaults=defaults)
        ax.set_xlabel.assert_called_with("frq")
        ax.set_xscale.assert_called_with("linear")
        ax.set_ylabel.assert_not_called()
        ax.set_yscale.assert_not_called()
Пример #6
0
    def test_reject_box_inside(self):
        xs = np.array([1, 2, 4, np.nan, 5, 1, 2, 6, 4, 9, 4])
        ys = np.array([1, 5, 8, np.nan, 6, 4, 7, 7, 1, 3, 5])
        power = np.array([0, 1, 2, np.nan, 4, 5, 6, 7, 8, 9, 10])

        # Reject on frequency and velocity.
        peaks = swprocess.Peaks(xs, ys, power=power)
        peaks.reject_box_inside(xtype="frequency",
                                xlims=(4.5, 7.5),
                                ytype="velocity",
                                ylims=(3.5, 8.5))
        keep_ids = [0, 1, 2, 5, 6, 8, 9, 10]
        attrs = dict(frequency=xs, velocity=ys, power=power)
        for attr, value in attrs.items():
            self.assertArrayEqual(value[keep_ids], getattr(peaks, attr))

        # Reject on frequency and power.
        peaks = swprocess.Peaks(xs, ys, power=power)
        peaks.reject_box_inside(xtype="frequency",
                                xlims=(4.5, 7.5),
                                ytype="power",
                                ylims=(3.5, 8.5))
        keep_ids = [0, 1, 2, 5, 6, 8, 9, 10]
        attrs = dict(frequency=xs, velocity=ys, power=power)
        for attr, value in attrs.items():
            self.assertArrayEqual(value[keep_ids], getattr(peaks, attr))

        # Reject on wavelength and slowness.
        ws = np.array([1, 5, 8, np.nan, 6, 4, 7, 7, 1, 3, 5])
        ps = np.array([1, 5, 9, np.nan, 4, 5, 6, 7, 8, 1, 7])
        power = np.array([0, 1, 2, np.nan, 4, 5, 6, 7, 8, 9, 10])

        xs = 1 / (ws * ps)
        ys = 1 / ps

        peaks = swprocess.Peaks(xs, ys, power=power)
        peaks.reject_box_inside(xtype="wavelength",
                                xlims=(3.2, 8.5),
                                ytype="slowness",
                                ylims=(4.5, 7.5))

        keep_ids = [0, 2, 4, 8, 9]
        attrs = dict(frequency=xs, velocity=ys, power=power)
        for attr, value in attrs.items():
            self.assertArrayEqual(value[keep_ids], getattr(peaks, attr))
Пример #7
0
    def test_to_and_from_json(self):
        # Standard to_json and from_json.
        fname = "test_0.json"
        expected = swprocess.Peaks(self.frq,
                                   self.vel,
                                   self._id,
                                   azimuth=self.azi,
                                   power=self.pwr)
        expected.to_json(fname)
        returned = swprocess.Peaks.from_json(fname)
        self.assertEqual(expected, returned)
        os.remove(fname)

        # Create and append with to_json, read the original with from_json.
        fname = "test_1.json"
        expected = swprocess.Peaks(self.frq, self.vel, "org")
        expected.to_json(fname)

        append = swprocess.Peaks(self.frq2, self.vel2, "app")
        append.to_json(fname, append=True)

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            returned = swprocess.Peaks.from_json(fname)
        self.assertEqual(expected, returned)
        os.remove(fname)

        # Append using to_json but data already exists.
        fname = "test_2.json"
        peaks = swprocess.Peaks(self.frq, self.vel, "org")
        peaks.to_json(fname)
        self.assertRaises(KeyError, peaks.to_json, fname, append=True)
        os.remove(fname)

        # Write and overwrite using to_json, read overwrite with from_json.
        fname = "test_3.json"
        expected = swprocess.Peaks(self.frq, self.vel, "org")
        expected.to_json(fname)
        expected.identifier = "app"
        expected.to_json(fname, append=False)
        returned = swprocess.Peaks.from_json(fname)
        self.assertEqual(expected, returned)
        os.remove(fname)
Пример #8
0
    def test__plot(self):
        peaks = swprocess.Peaks(self.frq, self.vel, self._id)

        # Standard
        fig, ax = plt.subplots()
        peaks._plot(ax=ax, xtype="frequency", ytype="velocity")

        # Bad Attribute
        fig, ax = plt.subplots()
        self.assertRaises(AttributeError,
                          peaks._plot,
                          ax=ax,
                          xtype="magic",
                          ytype="size_of_unicorn")

        plt.show(block=False)
        plt.close("all")
Пример #9
0
    def test_properties(self):
        peaks = swprocess.Peaks(self.frq, self.vel, self._id, azimuth=self.azi)

        # Wavelength
        self.assertArrayEqual(
            np.array(self.vel) / np.array(self.frq), peaks.wavelength)

        # Extended Attrs
        expected = [
            "frequency", "velocity", "azimuth", "wavelength", "slowness",
            "wavenumber"
        ]
        returned = peaks.extended_attrs
        self.assertListEqual(expected, returned)

        # Wavenumber
        self.assertArrayAlmostEqual(2 * np.pi / peaks.wavelength,
                                    peaks.wavenumber)
Пример #10
0
    def test__eq__(self):
        peaks_a = swprocess.Peaks(self.frq,
                                  self.vel,
                                  self._id,
                                  azimuth=self.azi)
        peaks_b = "I am not even a Peaks object"
        peaks_c = swprocess.Peaks(self.frq, self.vel, "diff", azimuth=self.azi)
        peaks_d = swprocess.Peaks(self.frq[:-2],
                                  self.vel[:-2],
                                  self._id,
                                  azimuth=self.azi[:-2])
        peaks_e = swprocess.Peaks(np.zeros_like(self.frq),
                                  self.vel,
                                  self._id,
                                  azimuth=self.azi)
        peaks_f = swprocess.Peaks(np.zeros_like(self.frq), self.vel, self._id)
        peaks_g = swprocess.Peaks(self.frq,
                                  self.vel,
                                  self._id,
                                  azimuth=self.azi)
        del peaks_g.identifier
        peaks_h = swprocess.Peaks(self.frq, self.vel, self._id, noise=self.noi)
        peaks_i = swprocess.Peaks(self.frq,
                                  self.vel,
                                  self._id,
                                  azimuth=self.azi)

        self.assertTrue(peaks_a == peaks_a)
        self.assertFalse(peaks_a == peaks_b)
        self.assertFalse(peaks_a == peaks_c)
        self.assertFalse(peaks_a == peaks_d)
        self.assertFalse(peaks_a == peaks_e)
        self.assertFalse(peaks_a == peaks_f)
        self.assertFalse(peaks_a == peaks_g)
        self.assertFalse(peaks_a == peaks_h)
        self.assertTrue(peaks_a == peaks_i)
Пример #11
0
 def test_plot_statistics(self):
     # Mock ax
     ax = MagicMock(spec=plt.Axes)
     suite = swprocess.PeaksSuite(swprocess.Peaks([1, 2, 3], [0, 1, 2]))
     suite.plot_statistics(ax, [1, 2, 3], [0, 1, 2], [4, 5, 6])
     ax.errorbar.assert_called_once()
Пример #12
0
    def test_statistics(self):
        # 1D: no missing data.
        values = np.array([[1, 2, 3, 4, 5], [4, 5, 7, 8, 9], [4, 3, 6, 4, 2]])
        frq = [1, 2, 3, 4, 5]
        peaks = [swprocess.Peaks(frq, values[k], str(k)) for k in range(3)]
        suite = swprocess.PeaksSuite.from_peaks(peaks)
        rfrq, rmean, rstd, rcorr = suite.statistics(xtype="frequency",
                                                    ytype="velocity",
                                                    xx=frq,
                                                    ignore_corr=False)
        self.assertArrayEqual(np.array(frq), rfrq)
        self.assertArrayEqual(np.mean(values, axis=0), rmean)
        self.assertArrayEqual(np.std(values, axis=0, ddof=1), rstd)
        self.assertArrayEqual(np.corrcoef(values.T), rcorr)

        # 1D: fewer than three Peaks in PeaksSuite -> ValueError.
        peaks = [swprocess.Peaks(frq, values[k], str(k)) for k in range(2)]
        suite = swprocess.PeaksSuite.from_peaks(peaks)
        self.assertRaises(ValueError,
                          suite.statistics,
                          xtype="frequency",
                          ytype="velocity",
                          xx=frq)

        # 1D: drop_sample_if_fewer_count = 3.
        values = np.array([[np.nan] * 6, [np.nan, 1, 2, 3, 4, 5],
                           [0, 4, 5, 7, 8, 9], [0, 4, 3, 6, 4, 2]])
        frq = [0.2, 1, 2, 3, 4, 5]

        valid = np.array([[1, 2, 3, 4, 5], [4, 5, 7, 8, 9], [4, 3, 6, 4, 2]])
        valid_frq = frq[1:]
        peaks = [swprocess.Peaks(frq, values[k], str(k)) for k in range(4)]
        suite = swprocess.PeaksSuite.from_peaks(peaks)

        rfrq, rmean, rstd, rcorr = suite.statistics(xtype="frequency",
                                                    ytype="velocity",
                                                    xx=frq,
                                                    ignore_corr=False)
        self.assertArrayEqual(np.array(valid_frq), rfrq)
        self.assertArrayEqual(np.mean(valid, axis=0), rmean)
        self.assertArrayEqual(np.std(valid, axis=0, ddof=1), rstd)
        self.assertArrayEqual(np.corrcoef(valid.T), rcorr)

        # 2D: with missing data.
        f0 = [[1, 3, 5, 7, np.nan], [np.nan, 3, 5, 7, 9], [1, 3, 5, 7, 9]]
        v0 = [[4, 6, 7, 1, np.nan], [np.nan, 3, 2, 5, 4], [1, 3, 5, 1, 2]]
        p0 = [[4, 3, 5, 1, np.nan], [np.nan, 3, 7, 5, 4], [1, 6, 7, 1, 2]]
        # --> 4, 3, 2, 5, 4
        peaks0 = swprocess.Peaks(f0, v0, identifier="0", power=p0)

        f1 = [[1, 3, 5, 7, np.nan], [np.nan, 3, 5, 7, 9], [1, 3, 5, 7, 9]]
        v1 = [[8, 8, 7, 7, np.nan], [np.nan, 2, 1, 3, 8], [4, 1, 4, 1, 4]]
        p1 = [[4, 6, 7, 1, np.nan], [np.nan, 3, 7, 5, 4], [1, 3, 5, 1, 2]]
        # --> 8, 8, 7, 3, 8
        peaks1 = swprocess.Peaks(f1, v1, identifier="1", power=p1)

        f2 = [[1, 3, 5, 7, np.nan], [np.nan, 3, 5, 7, 9], [1, 3, 5, 7, 9]]
        v2 = [[2, 4, 1, 1, np.nan], [np.nan, 8, 1, 3, 2], [5, 2, 9, 4, 8]]
        p2 = [[4, 6, 7, 1, np.nan], [np.nan, 3, 7, 5, 4], [1, 3, 5, 1, 2]]
        # --> 2, 4, 1, 3, 2
        peaks2 = swprocess.Peaks(f2, v2, identifier="2", power=p2)

        suite = swprocess.PeaksSuite.from_peaks([peaks0, peaks1, peaks2])
        valid = np.array([[4, 3, 2, 5, 4], [8, 8, 7, 3, 8], [2, 4, 1, 3, 2]],
                         dtype=float)
        frq = [1, 3, 5, 7, 9]
        rfrq, rmean, rstd, rcorr = suite.statistics(xtype="frequency",
                                                    ytype="velocity",
                                                    xx=frq,
                                                    ignore_corr=False)
        self.assertArrayEqual(np.array(frq), rfrq)
        self.assertArrayEqual(np.mean(valid, axis=0), rmean)
        self.assertArrayEqual(np.std(valid, axis=0, ddof=1), rstd)
        self.assertArrayEqual(np.corrcoef(valid.T), rcorr)
Пример #13
0
    def test_init(self):
        p0 = swprocess.Peaks([1, np.nan, 3], [4, np.nan, 6], "p0")
        suite = swprocess.PeaksSuite(p0)

        self.assertEqual(suite[0], p0)
        self.assertEqual(suite.ids[0], p0.identifier)
Пример #14
0
    def test_interactive_trimming(self):
        # Create simple suite, composed of two Peaks.
        peaks_a = swprocess.Peaks(frequency=[0.5, 0.5],
                                  velocity=[0.5, 1.5],
                                  identifier="a")
        peaks_b = swprocess.Peaks(frequency=[1.5, 1.5],
                                  velocity=[0.5, 1.5],
                                  identifier="b")
        suite = swprocess.PeaksSuite(peaks_a)
        suite.append(peaks_b)

        # Create a response generator.
        def response_generator(responses):
            index = 0
            while index < len(responses):
                yield responses[index]
                index += 1

        # Use a closure to wrap generator.
        def wrap_generator(generator):
            def wrapper(*args, **kwargs):
                return next(generator)

            return wrapper

        # Define generator to replace _draw_box()
        xlims, ylims, axclicked = (1., 2.), (0., 1.), 0
        response_0 = (xlims, ylims, axclicked)
        xlims, ylims, axclicked = (1., 1.), (1., 1.), 0
        response_1 = (xlims, ylims, axclicked)
        pick_generator = response_generator([response_0, response_1])
        _draw_box_responses = wrap_generator(generator=pick_generator)

        with patch("swprocess.peakssuite.PeaksSuite._draw_box",
                   side_effect=_draw_box_responses):
            with patch('builtins.input', return_value="0"):
                suite.interactive_trimming(xtype="frequency", ytype="velocity")
        self.assertArrayEqual(np.array([0.5, 0.5]), peaks_a.frequency)
        self.assertArrayEqual(np.array([0.5, 1.5]), peaks_a.velocity)
        self.assertArrayEqual(np.array([1.5]), peaks_b.frequency)
        self.assertArrayEqual(np.array([1.5]), peaks_b.velocity)

        # Redefine generator for _draw_box()
        pick_generator = response_generator([response_0, response_1])
        _draw_box_responses = wrap_generator(generator=pick_generator)

        # Define generator to replace input()
        input_generator = response_generator(["5", "0"])
        _input_responses = wrap_generator(generator=input_generator)

        # Check with bad user entry at input().
        with patch("swprocess.peakssuite.PeaksSuite._draw_box",
                   side_effect=_draw_box_responses):
            with patch("builtins.input", side_effect=_input_responses):
                with warnings.catch_warnings():
                    warnings.simplefilter("ignore")
                    suite.interactive_trimming(xtype="frequency",
                                               ytype="velocity")

        # Redefine generator for _draw_box()
        pick_generator = response_generator([response_1])
        _draw_box_responses = wrap_generator(generator=pick_generator)
        mock = MagicMock()

        # Check with bad user entry at input().
        with patch("swprocess.peakssuite.PeaksSuite._draw_box",
                   side_effect=_draw_box_responses):
            with patch("builtins.input", return_value="0"):
                with patch(
                        "swprocess.peakssuite.PeaksSuite.plot_resolution_limits",
                        side_effect=mock):
                    suite.interactive_trimming(
                        xtype="frequency",
                        ytype="velocity",
                        resolution_limits=["wavelength", (1, 10)])
                    mock.assert_called()