Пример #1
0
def multitaper(st, number_of_tapers=None, time_bandwidth=4., sine=False):
    """
    Output multitaper for stream st
    RETURNS POWER SPECTRAL DENSITY, units = input units **2 per Hz

    # TO DO add statistics and optional_output options

    :param st: obspy stream or trace containing data to plot
    :param number_of_tapers: Number of tapers to use, Defaults to int(2*time_bandwidth) - 1.
     This is maximum senseful amount. More tapers will have no great influence on the final spectrum but increase the
     calculation time. Use fewer tapers for a faster calculation.
    :param time_bandwidth_div: Smoothing amount, should be between 1 and Nsamps/2.
    :param sine: if True, will use sine_psd instead of multitaper, sine method should be used for sharp cutoffs or
     deep valleys, or small sample sizes
    """
    from mtspec import mtspec, sine_psd

    st = Stream(st)  # turn into a stream object in case st is a trace

    amps = []
    freqs = []
    for st1 in st:
        if sine is False:
            nfft = int(nextpow2((st1.stats.endtime - st1.stats.starttime) * st1.stats.sampling_rate))
            amp, freq = mtspec(st1.data, 1./st1.stats.sampling_rate, time_bandwidth=time_bandwidth,
                               number_of_tapers=number_of_tapers, nfft=nfft)
        else:
            st1.taper(max_percentage=0.05, type='cosine')
            amp, freq = sine_psd(st1.data, 1./st1.stats.sampling_rate)
        amps.append(amp)
        freqs.append(freq)
    return freqs, amps
    def test_figure3(self):
        """
        Recreate Figure 2
        """
        data = load_mtdata('PASC.dat.gz')

        fig = plt.figure()
        ax1 = fig.add_subplot(3, 1, 1)
        ax1.plot(data, color='black')
        ax1.set_xlim(0, len(data))

        spec, freq = mtspec(data, 1.0, 1.5, number_of_tapers=1)

        ax2 = fig.add_subplot(3, 2, 3)
        ax2.set_yscale('log')
        ax2.set_xscale('log')
        ax2.plot(freq, spec, color='black')
        ax2.set_xlim(freq[0], freq[-1])

        spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5)

        ax3 = fig.add_subplot(3, 2, 4)
        ax3.set_yscale('log')
        ax3.set_xscale('log')
        ax3.plot(freq, spec, color='black')
        ax3.set_xlim(freq[0], freq[-1])

        spec, freq = sine_psd(data, 1.0)

        ax4 = fig.add_subplot(3, 2, 5)
        ax4.set_yscale('log')
        ax4.set_xscale('log')
        ax4.plot(freq, spec, color='black')
        ax4.set_xlim(freq[0], freq[-1])

        spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5, quadratic=True)

        ax5 = fig.add_subplot(3, 2, 6)
        ax5.set_yscale('log')
        ax5.set_xscale('log')
        ax5.plot(freq, spec, color='black')
        ax5.set_xlim(freq[0], freq[-1])

        outfile = os.path.join(self.outpath, 'fig3.pdf')
        fig.savefig(outfile)
        stat = os.stat(outfile)
        self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
    def test_figure3(self):
        """
        Recreate Figure 2
        """
        data = load_mtdata('PASC.dat.gz')

        fig = plt.figure()
        ax1 = fig.add_subplot(3, 1, 1)
        ax1.plot(data, color='black')
        ax1.set_xlim(0, len(data))

        spec, freq = mtspec(data, 1.0, 1.5, number_of_tapers=1)

        ax2 = fig.add_subplot(3, 2, 3)
        ax2.set_yscale('log')
        ax2.set_xscale('log')
        ax2.plot(freq, spec, color='black')
        ax2.set_xlim(freq[0], freq[-1])

        spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5)

        ax3 = fig.add_subplot(3, 2, 4)
        ax3.set_yscale('log')
        ax3.set_xscale('log')
        ax3.plot(freq, spec, color='black')
        ax3.set_xlim(freq[0], freq[-1])

        spec, freq = sine_psd(data, 1.0)

        ax4 = fig.add_subplot(3, 2, 5)
        ax4.set_yscale('log')
        ax4.set_xscale('log')
        ax4.plot(freq, spec, color='black')
        ax4.set_xlim(freq[0], freq[-1])

        spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5, quadratic=True)

        ax5 = fig.add_subplot(3, 2, 6)
        ax5.set_yscale('log')
        ax5.set_xscale('log')
        ax5.plot(freq, spec, color='black')
        ax5.set_xlim(freq[0], freq[-1])

        outfile = os.path.join(self.outpath, 'fig3.pdf')
        fig.savefig(outfile)
        stat = os.stat(outfile)
        self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
Пример #4
0
 def test_sinePSD(self):
     """
     Test for the sine_psd spectra. The result is compared to the output of
     test_recreatePaperFigures.py in the same directory. This is assumed to
     be correct because they are identical to the figures in the paper on
     the machine that created these.
     """
     data = load_mtdata('PASC.dat.gz')
     # Calculate the spectra.
     spec, freq = sine_psd(data, 1.0)
     # No NaNs are supposed to be in the output.
     self.assertEqual(np.isnan(spec).any(), False)
     self.assertEqual(np.isnan(freq).any(), False)
     # Load the good data.
     datafile = os.path.join(os.path.dirname(__file__), 'data',
                             'sine_psd.npz')
     spec2 = np.load(datafile)['spec']
     freq2 = np.arange(43201) * 1.15740741e-05
     # Compare.
     np.testing.assert_almost_equal(freq, freq2)
     np.testing.assert_almost_equal(spec / spec, spec2 / spec, 2)
Пример #5
0
 def test_sinePSD(self):
     """
     Test for the sine_psd spectra. The result is compared to the output of
     test_recreatePaperFigures.py in the same directory. This is assumed to
     be correct because they are identical to the figures in the paper on
     the machine that created these.
     """
     data = load_mtdata('PASC.dat.gz')
     # Calculate the spectra.
     spec, freq = sine_psd(data, 1.0)
     # No NaNs are supposed to be in the output.
     self.assertEqual(np.isnan(spec).any(), False)
     self.assertEqual(np.isnan(freq).any(), False)
     # Load the good data.
     datafile = os.path.join(os.path.dirname(__file__), 'data',
                             'sine_psd.npz')
     spec2 = np.load(datafile)['spec']
     freq2 = np.arange(43201) * 1.15740741e-05
     # Compare.
     np.testing.assert_almost_equal(freq, freq2)
     np.testing.assert_almost_equal(spec / spec, spec2 / spec, 2)
Пример #6
0
 def test_sinePSDStatistics(self):
     """
     Test for the sine_psd spectra with optional output. The result is
     compared to the output of test_recreatePaperFigures.py in the same
     directory. This is assumed to be correct because they are identical
     to the figures in the paper on the machine that created these.
     """
     data = load_mtdata('PASC.dat.gz')
     # Calculate the spectra.
     spec, freq, errors, tapers = sine_psd(data, 1.0, statistics=True)
     # No NaNs are supposed to be in the output.
     self.assertEqual(np.isnan(spec).any(), False)
     self.assertEqual(np.isnan(freq).any(), False)
     self.assertEqual(np.isnan(errors).any(), False)
     self.assertEqual(np.isnan(tapers).any(), False)
     #XXX: assert for errors and tapers is missing
     # Load the good data.
     datafile = os.path.join(os.path.dirname(__file__), 'data',
                             'sine_psd.npz')
     spec2 = np.load(datafile)['spec']
     freq2 = np.arange(43201) * 1.15740741e-05
     # Compare #XXX really bad precision for spec (linux 64bit)
     np.testing.assert_almost_equal(freq, freq2)
     np.testing.assert_almost_equal(spec / spec, spec2 / spec, 2)
Пример #7
0
 def test_sinePSDStatistics(self):
     """
     Test for the sine_psd spectra with optional output. The result is
     compared to the output of test_recreatePaperFigures.py in the same
     directory. This is assumed to be correct because they are identical
     to the figures in the paper on the machine that created these.
     """
     data = load_mtdata('PASC.dat.gz')
     # Calculate the spectra.
     spec, freq, errors, tapers = sine_psd(data, 1.0, statistics=True)
     # No NaNs are supposed to be in the output.
     self.assertEqual(np.isnan(spec).any(), False)
     self.assertEqual(np.isnan(freq).any(), False)
     self.assertEqual(np.isnan(errors).any(), False)
     self.assertEqual(np.isnan(tapers).any(), False)
     #XXX: assert for errors and tapers is missing
     # Load the good data.
     datafile = os.path.join(os.path.dirname(__file__), 'data',
                             'sine_psd.npz')
     spec2 = np.load(datafile)['spec']
     freq2 = np.arange(43201) * 1.15740741e-05
     # Compare #XXX really bad precision for spec (linux 64bit)
     np.testing.assert_almost_equal(freq, freq2)
     np.testing.assert_almost_equal(spec / spec, spec2 / spec, 2)
Пример #8
0
def calculateHVSR(stream, intervals, window_length, method, options,
                  master_method, cutoff_value, smoothing=None,
                  smoothing_count=1, smoothing_constant=40,
                  message_function=None):
    """
    Calculates the HVSR curve.
    """
    # Some arithmetics.
    length = len(intervals)
    good_length = window_length // 2 + 1
    # Create the matrix that will be used to store the single spectra.
    hvsr_matrix = np.empty((length, good_length))
    # The stream that will be used.
    # XXX: Add option to use the raw data stream.
    if method == 'multitaper':
        if options['nfft']:
            good_length = options['nfft']// 2 + 1
            # Create the matrix that will be used to store the single
            # spectra.
            hvsr_matrix = np.empty((length, good_length))
        # Loop over each interval
        for _i, interval in enumerate(intervals):
            if message_function:
                message_function('Calculating HVSR %i of %i...' % \
                                 (_i+1, length))
            # Figure out which traces are vertical and which are horizontal.
            v = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'vertical']
            h = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'horizontal']
            v = stream[v[0]].data[interval[0]: interval[0] + \
                               window_length]
            h1 = stream[h[0]].data[interval[0]: interval[0] + \
                                window_length]
            h2 = stream[h[1]].data[interval[0]: interval[0] + \
                                window_length]
            # Calculate the spectra.
            v_spec, v_freq = mtspec(v, stream[0].stats.delta,
                                    options['time_bandwidth'],
                                    nfft=options['nfft'],
                                    number_of_tapers=options['number_of_tapers'],
                                    quadratic=options['quadratic'],
                                    adaptive=options['adaptive'])
            h1_spec, h1_freq = mtspec(h1, stream[0].stats.delta,
                                      options['time_bandwidth'], nfft=options['nfft'],
                                      number_of_tapers=options['number_of_tapers'],
                                      quadratic=options['quadratic'],
                                      adaptive=options['adaptive'])
            h2_spec, h2_freq = mtspec(h2, stream[0].stats.delta,
                                      options['time_bandwidth'],
                                      nfft=options['nfft'],
                                      number_of_tapers=options['number_of_tapers'],
                                      quadratic=options['quadratic'],
                                      adaptive=options['adaptive'])
            # Apply smoothing.
            if smoothing:
                if 'konno-ohmachi' in smoothing.lower():
                    if _i == 0:
                        sm_matrix = calculate_smoothing_matrix(v_freq,
                                                           smoothing_constant)
                    for _j in xrange(smoothing_count):
                        v_spec = np.dot(v_spec, sm_matrix)
                        h1_spec = np.dot(h1_spec, sm_matrix)
                        h2_spec = np.dot(h2_spec, sm_matrix)
            hv_spec = np.sqrt(h1_spec * h2_spec) / v_spec
            if _i == 0:
                good_freq = v_freq
            hvsr_matrix[_i, :] = hv_spec
        # Cut the hvsr matrix.
        hvsr_matrix = hvsr_matrix[0:length, :]
    elif method == 'sine multitaper':
        for _i, interval in enumerate(intervals):
            if message_function:
                message_function('Calculating HVSR %i of %i...' % \
                                 (_i+1, length))
            # Figure out which traces are vertical and which are horizontal.
            v = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'vertical']
            h = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'horizontal']
            v = stream[v[0]].data[interval[0]: interval[0] + \
                               window_length]
            h1 = stream[h[0]].data[interval[0]: interval[0] + \
                                window_length]
            h2 = stream[h[1]].data[interval[0]: interval[0] + \
                                window_length]
            # Calculate the spectra.
            v_spec, v_freq = sine_psd(v, stream[0].stats.delta,
                              number_of_tapers=options['number_of_tapers'],
                              number_of_iterations=options['number_of_iterations'],
                              degree_of_smoothing=options['degree_of_smoothing'])
            h1_spec, h1_freq = sine_psd(h1, stream[0].stats.delta,
                              number_of_tapers=options['number_of_tapers'],
                              number_of_iterations=options['number_of_iterations'],
                              degree_of_smoothing=options['degree_of_smoothing'])
            h2_spec, h2_freq = sine_psd(h2, stream[0].stats.delta,
                              number_of_tapers=options['number_of_tapers'],
                              number_of_iterations=options['number_of_iterations'],
                              degree_of_smoothing=options['degree_of_smoothing'])
            # Apply smoothing.
            if smoothing:
                if 'konno-ohmachi' in smoothing.lower():
                    if _i == 0:
                        sm_matrix = calculate_smoothing_matrix(v_freq,
                                                           smoothing_constant)
                    for _j in xrange(smoothing_count):
                        v_spec = np.dot(v_spec, sm_matrix)
                        h1_spec = np.dot(h1_spec, sm_matrix)
                        h2_spec = np.dot(h2_spec, sm_matrix)
            hv_spec = np.sqrt(h1_spec * h2_spec) / v_spec
            if _i == 0:
                good_freq = v_freq
            # Store it into the matrix if it has the correct length.
            hvsr_matrix[_i,:] = hv_spec
        # Cut the hvsr matrix.
        hvsr_matrix = hvsr_matrix[0:length, :]
    # Use a single taper spectrum with different available tapers.
    elif method == 'single taper':
        for _i, interval in enumerate(intervals):
            if message_function:
                message_function('Calculating HVSR %i of %i...' % \
                                 (_i+1, length))
            v = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'vertical']
            h = [_j for _j, trace in enumerate(stream) if \
                 trace.stats.orientation == 'horizontal']
            v = stream[v[0]].data[interval[0]: interval[0] + \
                               window_length]
            h1 = stream[h[0]].data[interval[0]: interval[0] + \
                                window_length]
            h2 = stream[h[1]].data[interval[0]: interval[0] + \
                                window_length]
            # Calculate the spectra.
            v_spec, v_freq = single_taper_spectrum(v,
                                    stream[0].stats.delta, options['taper'])
            h1_spec, h1_freq = single_taper_spectrum(h1,
                                    stream[0].stats.delta, options['taper'])
            h2_spec, h2_freq = single_taper_spectrum(h2,
                                    stream[0].stats.delta, options['taper'])
            # Apply smoothing.
            if smoothing:
                if 'konno-ohmachi' in smoothing.lower():
                    if _i == 0:
                        sm_matrix = calculate_smoothing_matrix(v_freq,
                                                           smoothing_constant)
                    for _j in xrange(smoothing_count):
                        v_spec = np.dot(v_spec, sm_matrix)
                        h1_spec = np.dot(h1_spec, sm_matrix)
                        h2_spec = np.dot(h2_spec, sm_matrix)
            hv_spec = np.sqrt(h1_spec * h2_spec) / v_spec
            if _i == 0:
                good_freq = v_freq
            # Store it into the matrix if it has the correct length.
            hvsr_matrix[_i, :] = hv_spec
        # Cut the hvsr matrix.
        hvsr_matrix = hvsr_matrix[0:length, :]
    # Should never happen.
    else:
        msg = 'Something went wrong.'
        raise Exception(msg)
    # Copy once to be able to calculate standard deviations.
    original_matrix = deepcopy(hvsr_matrix)
    # Sort it for quantile operations.
    hvsr_matrix.sort(axis=0)
    # Only senseful for mean calculations. Omitted for the median.
    if cutoff_value != 0.0 and master_method != 'median':
        hvsr_matrix = hvsr_matrix[int(length * cutoff_value):
                              ceil(length * (1 - cutoff_value)), :]
    length = len(hvsr_matrix)
    # Mean.
    if master_method == 'mean':
        master_curve = hvsr_matrix.mean(axis=0)
    # Geometric average.
    elif master_method == 'geometric average':
        master_curve = hvsr_matrix.prod(axis=0) ** (1.0 / length)
    # Median.
    elif master_method == 'median':
        # Use another method because interpolation might be necessary.
        master_curve = np.empty(len(hvsr_matrix[0, :]))
        error = np.empty((len(master_curve), 2))
        for _i in xrange(len(master_curve)):
            cur_row = hvsr_matrix[:, _i]
            master_curve[_i] = quantile(cur_row, 50)
            error[_i, 0] = quantile(cur_row, 25)
            error[_i, 1] = quantile(cur_row, 75)
    # Calculate the standard deviation for the two mean methods.
    if master_method != 'median':
        error = np.empty((len(master_curve), 2))
        std = (hvsr_matrix[:][:] - master_curve) ** 2
        std = std.sum(axis=0)
        std /= float(length)
        std **= 0.5
        error[:, 0] = master_curve - std
        error[:, 1] = master_curve + std
    return original_matrix, good_freq, length, master_curve, error
Пример #9
0
plt.subplot(323)
plt.loglog(freq, spec, color='black')
plt.xlim(freq[0], freq[-1])
plt.text(x=0.5, y=0.85, s="Single Taper",
         transform=plt.gca().transAxes, ha="center")

spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5)

plt.subplot(324)
plt.loglog(freq, spec, color='black')
plt.xlim(freq[0], freq[-1])
plt.text(x=0.5, y=0.85, s="5 Tapers Multitaper",
         transform=plt.gca().transAxes, ha="center")

spec, freq = sine_psd(data, 1.0)

plt.subplot(325)
plt.loglog(freq, spec, color='black')
plt.xlim(freq[0], freq[-1])
plt.text(x=0.5, y=0.85, s="Sine Multitaper",
         transform=plt.gca().transAxes, ha="center")

spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=5,
                    quadratic=True)

plt.subplot(326)
plt.loglog(freq, spec, color='black')
plt.xlim(freq[0], freq[-1])
plt.text(x=0.5, y=0.85, s="Quadratic Multitaper",
         transform=plt.gca().transAxes, ha="center")