Ejemplo n.º 1
0
def test_adjoint_time_frequency_phase_misfit_source_plot(tmpdir):
    """
    Tests the plot for a time-frequency misfit adjoint source.
    """
    obs, syn = obspy.read(os.path.join(data_dir, "adj_src_test.mseed")).traces

    import matplotlib.pyplot as plt

    plt.figure(figsize=(15, 10))

    ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(obs.times(), obs.data, syn.data, 20.0, 100.0, plot=True)
    # High tolerance as fonts are for some reason shifted on some systems.
    # This should still be safe as a differnce in the actual tf difference
    # or the waveforms would induce changes all over the plot which would
    # make the rms error much larger.
    images_are_identical("tf_adjoint_source", str(tmpdir), tol=30)
Ejemplo n.º 2
0
    def test_adjoint_time_frequency_phase_misfit_source(self):
        """
        Tests the adjoint source calculation for the time frequency phase
        misfit after Fichtner et. al. (2008).
        """
        # Load the matlab output.
        ad_src_matlab = os.path.join(
            self.data_dir,
            "matlab_tf_phase_misfit_adjoint_source_reference_solution.mat")
        ad_src_matlab = loadmat(ad_src_matlab)["ad_src"].transpose()[0]

        # Generate some data.
        t, u = utils.get_dispersed_wavetrain()
        _, u0 = utils.get_dispersed_wavetrain(a=3.91,
                                              b=0.87,
                                              c=0.8,
                                              body_wave_factor=0.015,
                                              body_wave_freq_scale=1.0 / 2.2)

        adjoint_src = ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(
            t, u, u0, 2, 10, 0.0)
        ad_src = adjoint_src["adjoint_source"]
        # Assert the misfit.
        self.assertAlmostEqual(adjoint_src["misfit"], 0.271417, 5)

        # Some testing tolerance is needed mainly due to the phase being hard
        # to define for small amplitudes.
        tolerance = np.abs(ad_src).max() * 1.2E-3
        np.testing.assert_allclose(ad_src, ad_src_matlab, 1E-7, tolerance)
Ejemplo n.º 3
0
def test_adjoint_time_frequency_phase_misfit_source():
    """
    Tests the adjoint source calculation for the time frequency phase
    misfit after Fichtner et. al. (2008).

    XXX: Adjust the test.
    """
    # Load the matlab output.
    ad_src_matlab = os.path.join(
        data_dir,
        "matlab_tf_phase_misfit_adjoint_source_reference_solution.mat")
    ad_src_matlab = loadmat(ad_src_matlab)["ad_src"].transpose()[0]

    # Generate some data.
    t, u = utils.get_dispersed_wavetrain()
    _, u0 = utils.get_dispersed_wavetrain(
        a=3.91, b=0.87, c=0.8, body_wave_factor=0.015,
        body_wave_freq_scale=1.0 / 2.2)

    adjoint_src = ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(
        t, u, u0, 2, 10, 0.0)
    ad_src = adjoint_src["adjoint_source"]
    # Assert the misfit.
    np.testing.assert_almost_equal(adjoint_src["misfit"], 0.271417, 5)

    # Some testing tolerance is needed mainly due to the phase being hard
    # to define for small amplitudes.
    tolerance = np.abs(ad_src).max() * 1.2E-3
    np.testing.assert_allclose(ad_src, ad_src_matlab, 1E-7, tolerance)
Ejemplo n.º 4
0
def adjoint_src_for_window(
    data,
    synth,
    starttime,
    endtime,
    weight,
    process_parameters,
    output_window_manager,
    output_adjoint_source_manager,
    write_data=True,
):

    if write_data:
        output_window_manager.write_window(
            data.id, starttime, endtime, weight, "cosine", "TimeFrequencyPhaseMisfitFichtner2008"
        )

    #  Decimal percentage of cosine taper (ranging from 0 to 1). Set to the
    # fraction of the minimum period to the window length.
    taper_percentage = np.min([1.0, 1.0 / process_parameters["lowpass"] / (endtime - starttime)])

    #  data
    data_trimmed = data.copy()
    data_trimmed.trim(starttime, endtime)
    data_trimmed.taper(type="cosine", max_percentage=0.5 * taper_percentage)
    data_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True, fill_value=0.0)

    #  synthetics
    synth_trimmed = synth.copy()
    synth_trimmed.trim(starttime, endtime)
    synth_trimmed.taper(type="cosine", max_percentage=0.5 * taper_percentage)
    synth_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True, fill_value=0.0)

    #  make time axis
    t = np.linspace(0, synth.stats.npts * synth.stats.delta, synth.stats.npts)

    #  clear axes of misfit plot ------------------------------------------

    #  set data and synthetics, compute actual misfit ---------------------

    t = np.require(t, dtype="float64", requirements="C")
    data_d = np.require(data_trimmed.data, dtype="float64", requirements="C")
    synth_d = np.require(synth_trimmed.data, dtype="float64", requirements="C")

    #  compute misfit and adjoint source
    adsrc = adsrc_tf_phase_misfit(
        t,
        data_d,
        synth_d,
        1.0 / process_parameters["lowpass"],
        1.0 / process_parameters["highpass"],
        axis=None,
        colorbar_axis=None,
    )

    #  write adjoint source to file ---------------------------------------
    if write_data:
        output_adjoint_source_manager.write_adjoint_src(adsrc["adjoint_source"], data.id, starttime, endtime)
    return adsrc
Ejemplo n.º 5
0
def test_adjoint_time_frequency_phase_misfit_source_plot(tmpdir):
    """
    Tests the plot for a time-frequency misfit adjoint source.
    """
    obs, syn = obspy.read(os.path.join(data_dir, "adj_src_test.mseed")).traces

    import matplotlib.pyplot as plt
    plt.figure(figsize=(15, 10))

    ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(obs.times(),
                                                 obs.data,
                                                 syn.data,
                                                 20.0,
                                                 100.0,
                                                 plot=True)
    # High tolerance as fonts are for some reason shifted on some systems.
    # This should still be safe as a differnce in the actual tf difference
    # or the waveforms would induce changes all over the plot which would
    # make the rms error much larger.
    images_are_identical("tf_adjoint_source", str(tmpdir), tol=30)
Ejemplo n.º 6
0
def test_time_frequency_adjoint_source():
    """
    Test the time frequency misfit and adjoint source.
    """
    obs, syn = obspy.read(os.path.join(data_dir, "adj_src_test.mseed")).traces
    ret_val = ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(obs.times(), obs.data, syn.data, 20.0, 100.0)

    assert round(ret_val["misfit_value"], 4) == 0.7147
    assert not ret_val["details"]["messages"]

    adj_src_baseline = np.load(os.path.join(data_dir, "adjoint_source_baseline.npy"))

    np.testing.assert_allclose(
        actual=ret_val["adjoint_source"], desired=adj_src_baseline, atol=1e-5 * abs(adj_src_baseline).max(), rtol=1e-5
    )
Ejemplo n.º 7
0
def test_time_frequency_adjoint_source():
    """
    Test the time frequency misfit and adjoint source.
    """
    obs, syn = obspy.read(os.path.join(data_dir, "adj_src_test.mseed")).traces
    ret_val = ad_src_tf_phase_misfit.adsrc_tf_phase_misfit(
        obs.times(), obs.data, syn.data, 20.0, 100.0)

    assert round(ret_val["misfit_value"], 4) == 0.7147
    assert not ret_val["details"]["messages"]

    adj_src_baseline = np.load(
        os.path.join(data_dir, "adjoint_source_baseline.npy"))

    np.testing.assert_allclose(actual=ret_val["adjoint_source"],
                               desired=adj_src_baseline,
                               atol=1E-5 * abs(adj_src_baseline).max(),
                               rtol=1E-5)
Ejemplo n.º 8
0
    def _onWindowSelected(self, window_start, window_width, axis,
                          plot_only=False):
        """
        Function called upon window selection.

        :param plot_only: If True, do not write anything to disk, but only
            plot.
        """
        #  Initialisation -----------------------------------------------------

        # Minimum window length is 50 samples.
        delta = self.data["synthetics"][0].stats.delta
        if window_width < 50 * delta:
            plt.draw()
            return

        data = self.data["data"].select(component=axis.seismic_component)[0]
        synth = self.data["synthetics"].select(
            channel=axis.seismic_component)[0]

        if not data:
            plt.draw()
            return

        trace = data
        time_range = trace.stats.endtime - trace.stats.starttime
        plot_range = axis.get_xlim()[1] - axis.get_xlim()[0]
        starttime = trace.stats.starttime + (window_start / plot_range) * \
            time_range
        endtime = starttime + window_width / plot_range * time_range

        if plot_only is not True:
            self.window_manager.write_window(
                trace.id, starttime, endtime, self.weight, "cosine",
                "TimeFrequencyPhaseMisfitFichtner2008")
            self.plot_window(component=trace.id[-1], starttime=starttime,
                             endtime=endtime, window_weight=self.weight)

        #  window data and synthetics -----------------------------------------

        #  Decimal percentage of cosine taper (ranging from 0 to 1). Set to the
        # fraction of the minimum period to the window length.
        taper_percentage = np.min(
            [1.0, 1.0 / self. process_parameters["lowpass"] / window_width])

        #  data
        data_trimmed = data.copy()
        data_trimmed.trim(starttime, endtime)
        data_trimmed.taper(type='cosine',
                           max_percentage=0.5 * taper_percentage)
        data_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True,
                          fill_value=0.0)

        #  synthetics
        synth_trimmed = synth.copy()
        synth_trimmed.trim(starttime, endtime)
        synth_trimmed.taper(type='cosine',
                            max_percentage=0.5 * taper_percentage)
        synth_trimmed.trim(synth.stats.starttime, synth.stats.endtime,
                           pad=True, fill_value=0.0)

        #  make time axis
        t = np.linspace(0, synth.stats.npts * synth.stats.delta,
                        synth.stats.npts)

        #  clear axes of misfit plot ------------------------------------------

        self.misfit_axis.cla()
        self.colorbar_axis.cla()
        try:
            self.misfit_axis.twin_axis.cla()
            self.misfit_axis.twin_axis.set_xticks([])
            self.misfit_axis.twin_axis.set_yticks([])
        except:
            pass

        #  set data and synthetics, compute actual misfit ---------------------

        t = np.require(t, dtype="float64", requirements="C")
        data_d = np.require(data_trimmed.data, dtype="float64",
                            requirements="C")
        synth_d = np.require(synth_trimmed.data, dtype="float64",
                             requirements="C")

        #  compute misfit and adjoint source
        adsrc = adsrc_tf_phase_misfit(
            t, data_d, synth_d,
            1.0 / self.process_parameters["lowpass"],
            1.0 / self.process_parameters["highpass"],
            axis=self.misfit_axis,
            colorbar_axis=self.colorbar_axis)

        #  plot misfit distribution -------------------------------------------

        # Format all the axis.
        self.misfit_axis.yaxis.set_major_formatter(FormatStrFormatter("%.3f"))
        self.misfit_axis.twin_axis.yaxis.set_major_formatter(
            FormatStrFormatter("%.2g"))
        self.colorbar_axis.yaxis.set_major_formatter(
            FormatStrFormatter("%.1f"))

        plt.tight_layout()
        plt.draw()

        #  write adjoint source to file ---------------------------------------

        if plot_only is not True:
            self.adjoint_source_manager.write_adjoint_src(
                adsrc["adjoint_source"], trace.id, starttime, endtime)
Ejemplo n.º 9
0
    def _onWindowSelected(self, window_start, window_width, axis):
        """
        Function called upon window selection.
        """
        if window_width <= 0:
            return

        if axis is self.plot_axis_z:
            data = self.data["data"].select(component="Z")[0]
            synth = self.data["synthetics"].select(component="Z")[0]
        elif axis is self.plot_axis_n:
            data = self.data["data"].select(component="N")[0]
            synth = self.data["synthetics"].select(component="N")[0]
        elif axis is self.plot_axis_e:
            data = self.data["data"].select(component="E")[0]
            synth = self.data["synthetics"].select(component="E")[0]
        else:
            return

        if not data:
            return

        trace = data
        time_range = trace.stats.endtime - trace.stats.starttime
        plot_range = axis.get_xlim()[1] - axis.get_xlim()[0]
        starttime = trace.stats.starttime + (window_start / plot_range) * \
            time_range
        endtime = starttime + window_width / plot_range * time_range

        self.window_manager.write_window(trace.id, starttime, endtime, 1.0,
            "cosine", "TimeFrequencyPhaseMisfitFichtner2008")

        # Window the data.
        data_trimmed = data.copy()
        data_trimmed.trim(starttime, endtime)
        data_trimmed.taper()
        data_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True,
            fill_value=0.0)
        synth_trimmed = synth.copy()
        synth_trimmed.trim(starttime, endtime)
        synth_trimmed.taper()
        synth_trimmed.trim(synth.stats.starttime, synth.stats.endtime,
            pad=True, fill_value=0.0)

        t = np.linspace(0, synth.stats.npts * synth.stats.delta,
            synth.stats.npts)

        self.misfit_axis.cla()
        self.colorbar_axis.cla()
        try:
            self.misfit_axis.twin_axis.cla()
            self.misfit_axis.twin_axis.set_xticks([])
            self.misfit_axis.twin_axis.set_yticks([])
        except:
            pass

        t = np.require(t, dtype="float64", requirements="C")
        data_d = np.require(data_trimmed.data, dtype="float64",
            requirements="C")
        synth_d = np.require(synth_trimmed.data, dtype="float64",
            requirements="C")

        adsrc = adsrc_tf_phase_misfit(t, data_d, synth_d, 5.0, 50.0,
            0.00000001, axis=self.misfit_axis,
            colorbar_axis=self.colorbar_axis)
        plt.tight_layout()
        plt.draw()
Ejemplo n.º 10
0
    def _onWindowSelected(self, window_start, window_width, axis):
        """
        Function called upon window selection.
        """
        if window_width <= 0:
            return

        if axis is self.plot_axis_z:
            data = self.data["data"].select(component="Z")[0]
            synth = self.data["synthetics"].select(component="Z")[0]
        elif axis is self.plot_axis_n:
            data = self.data["data"].select(component="N")[0]
            synth = self.data["synthetics"].select(component="N")[0]
        elif axis is self.plot_axis_e:
            data = self.data["data"].select(component="E")[0]
            synth = self.data["synthetics"].select(component="E")[0]
        else:
            return

        if not data:
            return

        trace = data
        time_range = trace.stats.endtime - trace.stats.starttime
        plot_range = axis.get_xlim()[1] - axis.get_xlim()[0]
        starttime = trace.stats.starttime + (window_start / plot_range) * \
            time_range
        endtime = starttime + window_width / plot_range * time_range

        self.window_manager.write_window(
            trace.id, starttime, endtime, 1.0, "cosine",
            "TimeFrequencyPhaseMisfitFichtner2008")

        # Window the data.
        data_trimmed = data.copy()
        data_trimmed.trim(starttime, endtime)
        data_trimmed.taper()
        data_trimmed.trim(synth.stats.starttime,
                          synth.stats.endtime,
                          pad=True,
                          fill_value=0.0)
        synth_trimmed = synth.copy()
        synth_trimmed.trim(starttime, endtime)
        synth_trimmed.taper()
        synth_trimmed.trim(synth.stats.starttime,
                           synth.stats.endtime,
                           pad=True,
                           fill_value=0.0)

        t = np.linspace(0, synth.stats.npts * synth.stats.delta,
                        synth.stats.npts)

        self.misfit_axis.cla()
        self.colorbar_axis.cla()
        try:
            self.misfit_axis.twin_axis.cla()
            self.misfit_axis.twin_axis.set_xticks([])
            self.misfit_axis.twin_axis.set_yticks([])
        except:
            pass

        t = np.require(t, dtype="float64", requirements="C")
        data_d = np.require(data_trimmed.data,
                            dtype="float64",
                            requirements="C")
        synth_d = np.require(synth_trimmed.data,
                             dtype="float64",
                             requirements="C")

        adsrc = adsrc_tf_phase_misfit(t,
                                      data_d,
                                      synth_d,
                                      5.0,
                                      50.0,
                                      0.00000001,
                                      axis=self.misfit_axis,
                                      colorbar_axis=self.colorbar_axis)
        plt.tight_layout()
        plt.draw()