plt.style.use("ggplot") from mtspec import mtspec, wigner_ville_spectrum from mtspec.util import signal_bursts fig = plt.figure() data = signal_bursts() # Plot the data ax1 = fig.add_axes([0.2, 0.75, 0.79, 0.24]) ax1.plot(data, color="k") ax1.set_xlim(0, len(data)) # Plot multitaper spectrum ax2 = fig.add_axes([0.06, 0.02, 0.13, 0.69]) spec, freq = mtspec(data, 10, 3.5) ax2.plot(spec, freq, color="k") ax2.set_xlim(0, spec.max()) ax2.set_ylim(freq[0], freq[-1]) ax2.set_xticks([]) # Create the wigner ville spectrum wv = wigner_ville_spectrum(data, 10, 3.5, smoothing_filter="gauss") # Plot the WV ax3 = fig.add_axes([0.2, 0.02, 0.79, 0.69]) ax3.set_yticks([]) ax3.set_xticks([]) ax3.imshow(abs(wv), interpolation="nearest", aspect="auto", cmap="magma") plt.show()
def multitaperSN(st, stnoise, SNrat=1.5, time_bandwidth=4.): """ Return masked arrays of multitaper, masking where SNratio is greater than SNrat # 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. """ from mtspec import mtspec st = Stream(st) # turn into a stream object in case st is a trace stnoise = Stream(stnoise) amps = [] freqs = [] ampmask = [] for i, st1 in enumerate(st): #if st1.stats.sampling_rate != stnoise[i].stats.sampling_rate: # print 'Signal and noise sample rates are different. Abort!' # return dat = st1.data pdat = stnoise[i].data # Find max nfft of the two and use that for both so they line up maxnfft = int(np.max((nextpow2(len(dat)), nextpow2(len(pdat))))) amp, freq = mtspec(dat, 1./st1.stats.sampling_rate, time_bandwidth=time_bandwidth, nfft=maxnfft) pamp, _ = mtspec(pdat, 1./st1.stats.sampling_rate, time_bandwidth=time_bandwidth, nfft=maxnfft) idx = (amp/pamp < SNrat) # good values amps.append(amp) freqs.append(freq) ampmask.append(ma.array(amp, mask=idx)) return freqs, amps, ampmask
def snr_test(tr, noise_win_len, sig_win_len, freq_range, perc): wl_10deg = 7 * 60. # see download_data_iris.py tp = tr.stats.starttime + wl_10deg noise_tr = tr.copy().trim(starttime=tp - noise_win_len - 5, endtime=tp - 5) signal_tr = tr.copy().trim(starttime=tp - 1, endtime=tp + sig_win_len) noise_tr.detrend('demean').taper(0.05) signal_tr.detrend('demean').taper(0.05) n_fft = nextpow2(max(signal_tr.stats.npts, noise_tr.stats.npts)) sig_spec, sig_freq = mtspec.mtspec(signal_tr.data, signal_tr.stats.delta, 2, nfft=n_fft) sig_spec = np.sqrt(sig_spec) noise_spec, noise_freq = mtspec.mtspec(noise_tr.data, noise_tr.stats.delta, 2, nfft=n_fft) noise_spec = np.sqrt(noise_spec) * (float(signal_tr.stats.npts) / noise_tr.stats.npts) sn_ratio = sig_spec / noise_spec index = np.where((sig_freq >= freq_range[0]) & (sig_freq <= freq_range[1])) sn_ratio = sn_ratio[index] L1 = np.size(np.where(sn_ratio >= 2.5)) L2 = np.size(sn_ratio) snr_test = 1 if ((float(L1) / float(L2)) > perc) else 0 return snr_test
def test_eigenspectraOutput(self): """ Tests the eigenspectra output using a nonadaptive spectra. This also at least somewhat tests the weights. """ data = load_mtdata('PASC.dat.gz') # Calculate the spectra. spec, freq, eigspec, eigcoef, weights = \ mtspec(data, 1.0, 4.5, number_of_tapers=5, adaptive=False, optional_output=True) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(eigspec).any(), False) self.assertEqual(np.isnan(eigcoef).any(), False) self.assertEqual(np.isnan(weights).any(), False) # The weights should all be one for the nonadaptive spectrum. np.testing.assert_almost_equal(weights, np.ones((43201, 5), 'float64')) # Sum over the eigenspectra to get the nonadaptive spectrum. new_spec = eigspec.sum(axis=1) / float(eigspec.shape[1]) new_spec[1:] *= 2.0 # Compare the output and the newly calculated spectrum. Normalize with # the maximum values to avoid scaling issues. np.testing.assert_almost_equal(spec[:10] / spec.max(), new_spec[:10] / new_spec.max())
def stf_from_scardec(times,moment,dt,time_bandwidth,ntapers): ''' Get the fourier transform of the SCARDEC Source time function, to obtain the source spectrum (I think that's what this is). Input: times: Array with the time of the STF moment: Array with the moment of the STF dt: Float with the time sampling interval time_bandwidth: Float with the time-bandwidth product. Common values: 2, 3, 4 and numbers in between. ntapers: Integer with the number of tapers to use. Defaults to int(2*time_bandwidth) - 1. This is maximum senseful amount. Output: frequencies: Array with the frequency powerspectrum: Array with the power spectrum ''' from mtspec import mtspec # [ampspectrum,frequencies] = mtspec(moment,dt,time_bandwidth,nfft=nfft,number_of_tapers=ntapers) [powerspectrum,frequencies] = mtspec(moment,dt,time_bandwidth,number_of_tapers=ntapers) return frequencies,powerspectrum
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_fstatisticsAndReshapedSpectrum(self): """ Test for mtspec_pad with jackknife interval errors. 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('v22_174_series.dat.gz') # Calculate the spectra. spec, freq, jackknife, fstatistics, _ = mtspec(data, 4930., 3.5, nfft=312, number_of_tapers=5, statistics=True, rshape=0, fcrit=0.9) # 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(jackknife).any(), False) self.assertEqual(np.isnan(fstatistics).any(), False) # Load the good data. datafile = os.path.join(os.path.dirname(__file__), 'data', 'fstatistics.npz') record = np.load(datafile) spec2 = record['spec'] jackknife2 = record['jackknife'] fstatistics2 = record['fstatistics'] freq2 = np.arange(157) * 6.50127447e-07 # Compare. np.testing.assert_almost_equal(freq, freq2) np.testing.assert_almost_equal(spec / spec, spec2 / spec) np.testing.assert_almost_equal(jackknife / jackknife, jackknife2 / jackknife, 5) np.testing.assert_almost_equal(fstatistics / fstatistics, fstatistics2 / fstatistics, 5)
def test_figure1(self): """ Recreate Figure 1 """ data = load_mtdata('v22_174_series.dat.gz') spec, freq, jackknife, _, _ = mtspec(data, 4930., 3.5, number_of_tapers=5, nfft=312, statistics=True) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) ax1.plot(data, color='black') ax1.set_xlim(0, len(data)) ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') ax2.plot(freq, spec, color='black') try: ax2.fill_between(freq, jackknife[:, 0], jackknife[:, 1], color='grey') except: ax2.plot(freq, jackknife[:, 0], '--', color = 'red') ax2.plot(freq, jackknife[:, 1], '--', color = 'red') ax2.set_xlim(freq[0], freq[-1]) outfile = os.path.join(self.outpath, 'fig1.pdf') fig.savefig(outfile) stat = os.stat(outfile) self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
def plot_all_spectra(self): """ plot spectral estimation """ fig, ax = plt.subplots(1, 1, figsize=(8, 5)) ax.tick_params(labelsize=14) ax.set_yscale('log') for i, run in enumerate(self.all_indices.keys()): spec, freq, jackknife, _, _ = mtspec.mtspec( data=self.all_indices[run].values, delta=1., time_bandwidth=4, number_of_tapers=5, statistics=True) ax.plot(freq, spec, color=f'C{i}', label=run.upper()) ax.fill_between(freq, jackknife[:, 0], jackknife[:, 1], color=f'C{i}', alpha=0.1) ax.legend(fontsize=14, loc=1, frameon=False) ax.set_ylim((1E-6, 1E1)) ax.set_xlim((0, 0.1)) ax.set_xlabel('Period [yr]', fontsize=14) ax.set_xlabel(r'Frequency [yr$^{-1}$]', fontsize=14) ax.set_ylabel(f'{self.index} Power Spectral Density', fontsize=14) plt.tight_layout() plt.savefig(f'{path_results}/SST/{self.index}_all_spectra')
def test_figure1(self): """ Recreate Figure 1 """ data = load_mtdata('v22_174_series.dat.gz') spec, freq, jackknife, _, _ = mtspec(data, 4930., 3.5, number_of_tapers=5, nfft=312, statistics=True) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) ax1.plot(data, color='black') ax1.set_xlim(0, len(data)) ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') ax2.plot(freq, spec, color='black') try: ax2.fill_between(freq, jackknife[:, 0], jackknife[:, 1], color='grey') except: ax2.plot(freq, jackknife[:, 0], '--', color='red') ax2.plot(freq, jackknife[:, 1], '--', color='red') ax2.set_xlim(freq[0], freq[-1]) outfile = os.path.join(self.outpath, 'fig1.pdf') fig.savefig(outfile) stat = os.stat(outfile) self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
def test_figure2(self): """ Recreate Figure 2 """ data = load_mtdata('v22_174_series.dat.gz') spec, freq, jackknife, fstatistics, _ = mtspec(data, 4930., 3.5, number_of_tapers=5, nfft=312, statistics=True, rshape=0, fcrit=0.9) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) ax1.plot(freq, fstatistics, color='black') ax1.set_xlim(freq[0], freq[-1]) ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') ax2.plot(freq, spec, color='black') ax2.set_xlim(freq[0], freq[-1]) outfile = os.path.join(self.outpath, 'fig2.pdf') fig.savefig(outfile) stat = os.stat(outfile) self.assertTrue(abs(stat.st_mtime - time.time()) < 3)
def test_paddedMultitaperSpectrumWithErrors(self): """ Test for mtspec_pad with jackknife interval errors. 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('v22_174_series.dat.gz') # Calculate the spectra. spec, freq, jackknife, _, _ = mtspec(data, 4930., 3.5, nfft=312, number_of_tapers=5, statistics=True) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(jackknife).any(), False) # Load the good data. datafile = os.path.join(os.path.dirname(__file__), 'data', 'mtspec_pad_with_errors.npz') record = np.load(datafile) spec2 = record['spec'] jackknife2 = record['jackknife'] freq2 = np.arange(157) * 6.50127447e-07 # Compare. np.testing.assert_almost_equal(freq, freq2) np.testing.assert_almost_equal(spec / spec, spec2 / spec, 6) np.testing.assert_almost_equal(jackknife / jackknife, jackknife2 / jackknife, 6)
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 getSpectra(series, pi=4, delta=0.01): import mtspec spectra = [] for s in series.T: a, b = mtspec.mtspec(s, delta, pi) spectra.append(a) return spectra
def multiband(data, fs, avgref=True): """ Pipeline function for computing the power spectral density of ECoG using multitaper spectral estimation. Data --> CAR Filter --> Multitaper power spectral density Parameters ---------- data: ndarray, shape (T, N) Input signal with T samples over N variates fs: int Sampling frequency reref: True/False Re-reference data to the common average (default: True) Returns ------- freq: ndarray, shape (F,) Range of frequencies over which power spectrum is being measured. powerspec: ndarray, shape (F, N) Power spectral density across F frequencies for N variates. """ # Standard param checks errors.check_type(data, np.ndarray) errors.check_dims(data, 2) errors.check_type(fs, int) # Parameter set param = {} param['time_band'] = 5. param['n_taper'] = 9 T, N = data.shape # Build pipeline if avgref: data_hat = reref.common_avg_ref(data) else: data_hat = data.copy() for n1 in xrange(N): out = mtspec(data=data[:, n1], delta=1.0 / fs, time_bandwidth=param['time_band'], number_of_tapers=param['n_taper'], adaptive=True) if n1 == 0: freq = out[1] powerspec = np.zeros((freq.shape[0], N)) powerspec[:, n1] = out[0] return freq, powerspec
def calculate_spectrum(self, trace, selection_indices): """ Calculates the multitaper spectrum of the trace going from selection_indices[0] to selection_indices[1]. """ data = trace.data[selection_indices[0]:selection_indices[1]] spec, freq, jackknife_errors, _, _ = mtspec.mtspec(data, trace.stats.delta, 2, statistics=True) spec = np.sqrt(spec) jackknife_errors = np.sqrt(jackknife_errors) self.current_state["channel"] = trace.id self.ui.spectrum_figure.clear() self.ui.spectrum_figure.subplots_adjust(left=0.1, bottom=0.1) ax = self.ui.spectrum_figure.add_subplot(111) ax.loglog(freq, spec, color="black") ax.frequencies = freq ax.spectrum = spec ax.fill_between(freq, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75", alpha=0.5, edgecolor="0.5") # Keep it around to avoid it being garbage collected. ax.cursor = matplotlib.widgets.Cursor(ax, True, color="#4c7412", linestyle="-") ax.pick_text = ax.text( 0.05, 0.05, ("Left click to adjust plateau " "value\nRight click to adjust corner frequency\n" "Scroll to adjust quality factor"), horizontalalignment="left", verticalalignment="bottom", multialignment="left", transform=ax.transAxes, bbox=dict(facecolor='orange', alpha=0.5)) ax.pick_values = {} ax.set_ylim(spec.min() / 10.0, spec.max() * 100.0) ax.set_xlim(1.0, 100) self.ui.spectrum_figure.canvas.draw() # Now guess guess some values, and fit the curve. Setting it to 10 is # reasonable. self.current_state["corner_frequency"] = 10.0 # Set omega_0 to the mean value of all values lower than the corner # frequency. corn_freq_index = \ np.abs(freq - self.current_state["corner_frequency"]).argmin() self.current_state["omega_0"] = spec[:corn_freq_index].mean() self.current_state["quality_factor"] = 100.0 self._on_fit_spectrum()
def test_quadraticMultitaperIsDifferent(self): """ The quadratic and the normal multitaper spectra look quite similar. Check that they are different. """ data = load_mtdata('v22_174_series.dat.gz') # Calculate the spectra. spec, freq = mtspec(data, 1.0, 4.5, number_of_tapers=2) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(freq).any(), False) spec2, freq2 = mtspec(data, 1.0, 4.5, number_of_tapers=2, quadratic=True) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec2).any(), False) self.assertEqual(np.isnan(freq2).any(), False) # Test that these are not equal. self.assertRaises(AssertionError, np.testing.assert_almost_equal, spec, spec2)
def multi_tape_spectr(self, time_serie, sampling_period=1, band_width=4, numb_tapers=4): spectrum, frequence, _, _, _ = mtspec.mtspec( data=time_serie, delta=sampling_period, time_bandwidth=band_width, number_of_tapers=numb_tapers, statistics=True) return [frequence, spectrum]
def spectrum(self, data=None, filter_type=None, filter_cutoff=None): """ multitaper spectrum """ if data is None: data = np.array(self.ts) assert type(data) == np.ndarray if filter_type is not None: data = self.filter_timeseries(data, filter_type, filter_cutoff) spec, freq, jackknife, _, _ = mtspec.mtspec(data=data, delta=1., time_bandwidth=2, number_of_tapers=3, statistics=True) return (spec, freq, jackknife)
def calc_alpha(ev_count, dt, per_max): """Computes the slope of the event count auto-correlation spectrum. This spectral slope is a good estimator of time-clustering of a point-process: if it is close to 0, the point process shows less time clustering than if it is significantly higher [1]_. Parameters ---------- ev_count : 1D array Event count, number of events in regular time bins, dimension `N_bins`. dt : float Size of time bin. per_max : float Maximum period to take into account in the fit. Returns ------- sp : 1D array Multi-taper spectrum of the event count auto-correlation. per : 1D array Periods at which the amplitude spectrum is computed. alpha : float The log-log slope of the spectrum of event count auto-correlation, along period, not frequency. References ---------- .. [1] Lowen, S. B., & Teich, M. C. (2005). Fractal-Based Point Processes (Vol. 366). John Wiley and Sons, Inc. """ # >> Compute un-bias autocorrelation a_corr, _ = crosscorr(ev_count, ev_count, dt, norm=True, no_bias=True) # >> Compute its spectrum sp, fq = mtspec(a_corr, dt, time_bandwidth=3.5, number_of_tapers=5) sp = np.sqrt(sp) * len(sp) # convert PSD into amplitude # -> Get rid of 0 frequency sp = sp[fq > 0] fq = fq[fq > 0] per = 1/fq # >> Compute slope of spectrum log_per = np.log10(per[per < per_max]) log_sp = np.log10(sp[per < per_max]) p = np.polyfit(log_per, log_sp, 1) alpha = p[0] return sp, per, alpha
def mtspectrum(ts, d=1., tb=4, nt=4): import mtspec """ multi-taper spectrum input: ts .. time series d .. sampling period tb .. time bounds (bandwidth) nt .. number of tapers """ spec, freq, jackknife, _, _ = mtspec.mtspec( data=ts, delta=d, time_bandwidth=tb, number_of_tapers=nt, statistics=True) return freq, spec
def update(self): pb = pbar.ProgressBar() winlen_samples = np.int(self.win_len_/self.spacing_) half_winlen = np.int(winlen_samples / 2) print('each window have size: ' + str(half_winlen * 2)) ffts = [] ns = [] for n in pb(np.arange(0 + half_winlen, len(self.x_) - half_winlen)[::self.sub_fact_]): ns.append(n) #get a piece of the signal small_signal = self.y_[n-half_winlen:n+half_winlen] #perform detrending if self.detrend_method_ == 'linear': small_signal = mlab.detrend_linear(small_signal) elif self.detrend_method_ == 'mean': small_signal = small_signal - np.mean(small_signal) elif self.detrend_method_ == 'none': #simply go ahead pass #do padding if self.N_zeros_ > len(small_signal): small_signal = np.concatenate((small_signal, np.zeros(self.N_zeros_-len(small_signal)))) #get a spectral estimation using some method if self.method_ == 'mtspec': ps, f = mtspec.mtspec(small_signal, self.spacing_, self.pi_) #normalize the single spectrum if self.max_normalization_: ps = ps / np.max(ps) #append to the ffts ffts.append(ps[f<=self.highfreq_]) self.ffts_ = np.array(ffts) self.eval_pos_ = self.x_[ns] #the real max frequency? self.real_maxfreq_ = np.max(f[f<=self.highfreq_])
def mtspectrum(self, data=None, d=1., tb=4, nt=4): """ multi-taper spectrum input: ts .. time series d .. sampling period tb .. time bounds (bandwidth) nt .. number of tapers """ if data is None: data = np.array(self.ts) assert type(data) == np.ndarray spec, freq, jackknife, _, _ = mtspec.mtspec(data=data, delta=d, time_bandwidth=tb, number_of_tapers=nt, statistics=True) return freq, spec
def calculate_spectrum(self, trace, selection_indices): """ Calculates the multitaper spectrum of the trace going from selection_indices[0] to selection_indices[1]. """ data = trace.data[selection_indices[0]: selection_indices[1]] spec, freq, jackknife_errors, _, _ = mtspec.mtspec(data, trace.stats.delta, 2, statistics=True) spec = np.sqrt(spec) jackknife_errors = np.sqrt(jackknife_errors) self.current_state["channel"] = trace.id self.ui.spectrum_figure.clear() self.ui.spectrum_figure.subplots_adjust(left=0.1, bottom=0.1) ax = self.ui.spectrum_figure.add_subplot(111) ax.loglog(freq, spec, color="black") ax.frequencies = freq ax.spectrum = spec ax.fill_between(freq, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75", alpha=0.5, edgecolor="0.5") # Keep it around to avoid it being garbage collected. ax.cursor = matplotlib.widgets.Cursor(ax, True, color="#4c7412", linestyle="-") ax.pick_text = ax.text(0.05, 0.05, ("Left click to adjust plateau " "value\nRight click to adjust corner frequency\n" "Scroll to adjust quality factor"), horizontalalignment="left", verticalalignment="bottom", multialignment="left", transform=ax.transAxes, bbox=dict(facecolor='orange', alpha=0.5)) ax.pick_values = {} ax.set_ylim(spec.min() / 10.0, spec.max() * 100.0) ax.set_xlim(1.0, 100) self.ui.spectrum_figure.canvas.draw() # Now guess guess some values, and fit the curve. Setting it to 10 is # reasonable. self.current_state["corner_frequency"] = 10.0 # Set omega_0 to the mean value of all values lower than the corner # frequency. corn_freq_index = \ np.abs(freq - self.current_state["corner_frequency"]).argmin() self.current_state["omega_0"] = spec[:corn_freq_index].mean() self.current_state["quality_factor"] = 100.0 self._on_fit_spectrum()
def test_multitaperSpectrum(self): """ Test for mtspec. 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 = mtspec(data, 1.0, 4.5, number_of_tapers=5) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(spec).any(), False) # Load the good data. datafile = os.path.join(os.path.dirname(__file__), 'data', 'multitaper.npz') spec2 = np.load(datafile)['spec'] freq2 = np.arange(43201) * 1.15740741e-05 # Compare, normalize for subdigit comparision np.testing.assert_almost_equal(freq, freq2) np.testing.assert_almost_equal(spec / spec, spec2 / spec, 5)
def mtspec_wigner_ville(data,fs,filename): from mtspec import mtspec, wigner_ville_spectrum fig = plt.figure() t = np.arange(len(data)) / fs ax1 = fig.add_axes([0.2,0.75, 0.79, 0.23]) ax1.plot(t,data, color="0.3") #ax1.set_xlim(0, len(data)) ax2 = fig.add_axes([0.06,0.02,0.13,0.69]) spec, freq = mtspec(data, 10, 3.5) print "freq is ", freq ax2.plot(spec, freq, color="0.3") ax2.set_xlim(0, spec.max()) ax2.set_ylim(freq[0], freq[-1]) ax2.set_xticks([]) wv = wigner_ville_spectrum(data, 10, 3.5, smoothing_filter='gauss') ax3 = fig.add_axes([0.2, 0.02, 0.79, 0.69]) ax3.set_yticks([]) ax1.set_xticks([]) ax3.imshow(np.sqrt(abs(wv)), interpolation='lanczos', aspect='auto') plt.savefig(filename+'.pdf')
def test_multitaperSpectrumOptionalOutput(self): """ Test for mtspec. 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, eigspec, eigcoef, weights = \ mtspec(data, 1.0, 4.5, number_of_tapers=5, optional_output=True) # No NaNs are supposed to be in the output. self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(spec).any(), False) self.assertEqual(np.isnan(eigspec).any(), False) self.assertEqual(np.isnan(eigcoef).any(), False) self.assertEqual(np.isnan(weights).any(), False) #XXX: Verify if this is correct, if so savez the data #import matplotlib.pyplot as plt #plt.plot(np.abs(eigcoef[:,0])) #plt.show() #import ipdb; ipdb.set_trace() #np.savez('data/multitaper.npz', spec=spec.astype('float32'), # eigspec=eigspec.astype('float32'), # eigcoef=eigcoef.astype('float32'), # weights=weights.astype('float32')) # Load the good data. datafile = os.path.join(os.path.dirname(__file__), 'data', 'multitaper.npz') record = np.load(datafile) spec2 = record['spec'] #eigspec2 = record['eigspec'] #eigcoef2 = record['eigcoef'] #weights2 = record['weights'] freq2 = np.arange(43201) * 1.15740741e-05 # Compare, normalize for subdigit comparision np.testing.assert_almost_equal(freq, freq2) np.testing.assert_almost_equal(spec / spec, spec2 / spec, 5)
def MTspectrum_plot(self, data, win, dt, tbp, ntapers, linf, lsup): if (win % 2) == 0: nfft = win / 2 + 1 else: nfft = (win + 1) / 2 lim = len(data) - win S = np.zeros([int(nfft), int(lim)]) data2 = np.zeros(2 ** math.ceil(math.log2(win))) for n in range(lim): data1 = data[n:win + n] data1 = data1 - np.mean(data1) data2[0:win] = data1 spec, freq = mtspec(data2, delta=dt, time_bandwidth=tbp, number_of_tapers=ntapers) spec = spec[0:int(nfft)] S[:, n] = spec value1, freq1 = self.find_nearest(freq, linf) value2, freq2 = self.find_nearest(freq, lsup) S = S[value1:value2] return S
import matplotlib as mpl mpl.rcParams['font.size'] = 9.0 import matplotlib.pyplot as plt from mtspec import mtspec from mtspec.util import load_mtdata data = load_mtdata('v22_174_series.dat.gz') spec, freq, jackknife, fstatistics, _ = mtspec(data, 4930., 3.5, number_of_tapers=5, nfft=312, statistics=True, rshape=0, fcrit=0.9) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) ax1.plot(freq, fstatistics, color='black') ax1.set_xlim(freq[0], freq[-1]) ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') ax2.plot(freq, spec, color='black') ax2.set_xlim(freq[0], freq[-1])
import matplotlib.pyplot as plt plt.style.use("ggplot") import numpy as np from mtspec import mtspec from mtspec.util import _load_mtdata data = _load_mtdata("v22_174_series.dat.gz") spec, freq, jackknife, fstatistics, _ = mtspec( data=data, delta=4930., time_bandwidth=3.5, number_of_tapers=5, nfft=312, statistics=True, rshape=0, fcrit=0.9) # Convert to million years. freq *= 1E6 plt.subplot(211) plt.plot(freq, fstatistics, color="black") plt.xlim(freq[0], freq[-1]) plt.xlabel("Frequency [c Ma$^{-1}]$") plt.ylabel("F-statistics for periodic lines") # Plot the confidence intervals. for p in [90, 95, 99]: y = np.percentile(fstatistics, p) plt.hlines(y, freq[0], freq[-1], linestyles="--", color="0.2") plt.text(x=99, y=y + 0.2, s="%i %%" % p, ha="right") plt.subplot(212) plt.semilogy(freq, spec, color="black") plt.xlim(freq[0], freq[-1])
plt.style.use("ggplot") from mtspec import mtspec, wigner_ville_spectrum from mtspec.util import signal_bursts fig = plt.figure() data = signal_bursts() # Plot the data ax1 = fig.add_axes([0.2,0.75, 0.79, 0.24]) ax1.plot(data, color="k") ax1.set_xlim(0, len(data)) # Plot multitaper spectrum ax2 = fig.add_axes([0.06,0.02,0.13,0.69]) spec, freq = mtspec(data, 10, 3.5) ax2.plot(spec, freq, color="k") ax2.set_xlim(0, spec.max()) ax2.set_ylim(freq[0], freq[-1]) ax2.set_xticks([]) # Create the wigner ville spectrum wv = wigner_ville_spectrum(data, 10, 3.5, smoothing_filter='gauss') # Plot the WV ax3 = fig.add_axes([0.2, 0.02, 0.79, 0.69]) ax3.set_yticks([]) ax3.set_xticks([]) ax3.imshow(abs(wv), interpolation='nearest', aspect='auto', cmap="magma")
import matplotlib.pyplot as plt plt.style.use("ggplot") import numpy as np from mtspec import mtspec from mtspec.util import _load_mtdata data = _load_mtdata("v22_174_series.dat.gz") spec, freq, jackknife, fstatistics, _ = mtspec(data=data, delta=4930., time_bandwidth=3.5, number_of_tapers=5, nfft=312, statistics=True, rshape=0, fcrit=0.9) # Convert to million years. freq *= 1E6 plt.subplot(211) plt.plot(freq, fstatistics, color="black") plt.xlim(freq[0], freq[-1]) plt.xlabel("Frequency [c Ma$^{-1}]$") plt.ylabel("F-statistics for periodic lines") # Plot the confidence intervals. for p in [90, 95, 99]: y = np.percentile(fstatistics, p)
SeD = np.where(np.logical_and(M>=0, M<=(N/2))) d1 = decon[SeD] SeD2 = np.where(np.logical_and(M>N/2, M<=N+1)) d2 = decon[SeD2] ''' Relative source time function ''' stf = np.concatenate((d2, d1)) '''Cleaning the rSTF from high frequency noise ''' stf = lowpass(stf, 4, fr, corners=4, zerophase=True) stf /= stf.max() ''' Fourier Transform of the rSTF ''' Cspec, Cfreq = mtspec(stf, delta=dt, time_bandwidth=2, number_of_tapers=3) m = len(Cspec) Cspec = Cspec[range(m/2)] Cfreq = Cfreq[range(m/2)] ''' Creating figure ''' fig = plt.figure() ax1 = fig.add_subplot(211) ax1.loglog(Cfreq, Cspec, 'grey', linewidth=1.7, label='Spectral ratio') ax1.set_xlabel("Frequency [Hz]") ax1.set_ylabel("Amplitude") plt.grid(True, which="both", ls="-", color='grey') plt.legend() ax2 = fig.add_subplot(212)
b, a = butter(order, array(fcorner)/(fnyquist),'bandpass') data_filt=filtfilt(b,a,data) return data_filt #resample tor egular itnerval t=arange(0,tg.max(),dt) f=interp1d(tg,eta_unfilt) eta_unfilt=f(t) #filter eta=eta_unfilt#bandpass(eta_unfilt,fcorner,1./dt,2) #Get psd psd, f = mtspec(data=eta, delta=dt, time_bandwidth=Tw,number_of_tapers=Ntapers, nfft=len(eta), statistics=False) psd_u, f = mtspec(data=eta_unfilt, delta=dt, time_bandwidth=Tw,number_of_tapers=Ntapers, nfft=len(eta), statistics=False) period=1./f/60 plt.figure() plt.plot(period,psd/psd.max()) #plt.plot(period,psd) plt.plot(ref_psd[:,0],ref_psd[:,1]/ref_psd[:,1].max()) #plt.plot(ref_psd[:,0],ref_psd[:,1]) plt.xlim([12,100]) plt.xlabel('Period (min)') plt.legend(['Gaussian source','Reference PSD']) plt.ylabel('PSD') plt.grid() plt.show()
u'/Users/dmelgar/Tsunamis/tehuantepec_gauges/_output/gauge00004.txt') #resample to regular itnerval tsyn = arange(syn[0, 1], syn[-1, 1], dt) f = interp1d(syn[:, 1], syn[:, 5]) syn_interp = f(tsyn) * shoal syn = Stream(Trace()) syn[0].data = syn_interp syn[0].stats.delta = dt syn[0].stats.starttime = time_epi syn[0].trim(starttime=data[0].stats.starttime, pad=True, fill_value=0) #get spectra delta = dt / 3600. spec_data, freq_data, jackknife, _, _ = mtspec(data=data[0].data, delta=delta, time_bandwidth=3.5, number_of_tapers=5, nfft=data[0].stats.npts, statistics=True) spec_syn, freq_syn, jackknife, _, _ = mtspec(data=syn[0].data, delta=delta, time_bandwidth=3.5, number_of_tapers=5, nfft=syn[0].stats.npts, statistics=True) ax = plt.subplot(111) pos1 = ax.get_position() # get the original position pos2 = [pos1.x0 + 0.3, pos1.y0 + 0.3, pos1.width / 2.0, pos1.height / 2.0] ax.set_position(pos2) # set a new position
#### ####Now that I have the ROI, compute the power spectrum of the signal for ####each A-line using MTM and average #### import math dataWindow = region.astype('double') tempPoints, tempLines = dataWindow.shape halfPoints = int(tempPoints/2) if halfPoints%2: halfPoints += 1 spectrum = np.zeros( halfPoints ) for l in range(tempLines): tmpSpec, freq = mtspec(dataWindow[:,l],1./tmpRf.fs , 3.) #data, delta, time-bandwidth spectrum += tmpSpec spectrum /= tempLines spectrumRef = np.zeros( halfPoints ) dataWindowRef = region.astype('double') for l in range(tempLines): tmpSpec, freq = mtspec(dataWindowRef[:,l],1./tmpRf.fs , 3.) #data, delta, time-bandwidth spectrumRef += tmpSpec spectrumRef /= tempLines ### maxF = freq[-1] deltaF = freq[1] - freq[0]
#eta=eta[i] #Keep only stuff above AMR 3 #i=where(levels>=3)[0] #t=t[i]g #eta=eta[i] #resample to correct times f = interp1d(t, eta, kind='linear') eta_interp = f(tout) #Get spectrum delta = 60. Sobs, fobs = mtspec(data=eta_interp, delta=delta, time_bandwidth=3.5, number_of_tapers=5, nfft=len(eta_interp)) tr = Trace() tr.data = Sobs tr.stats.delta = delta st += tr st.write(fout, format='MSEED') lon_gauge = xyz[:, 0] lat_gauge = xyz[:, 1] #Loop and look for frequencies of itnerest
def getMTMSpectrum(self, pi = 2, pad_to=100000, norm=True, from_x=None, to_x=None, max_f=None, detrend=True, det_type='linear', stats = False, p_crit = 0.95 ): """ Get the MTM (Thompson multitaper method) spectrum for the series This is an interface to mtspec python module Keyword arguments: pi -- the bandwhidth passed to mtspec.mtspec method pad_to -- if needed pad the series with zeros norm -- normalize forcing the higher peak to 1.0 from/to_x -- compute the spectrum only for a sub-slice of the series max_f -- get rid of frequencies above this value (cycles/time) stats -- gives back a lot of additional stats and data from the mtspec routines p_crit -- critical p-value for the f-test used for reshaped spectra """ import mtspec if ((from_x!=None) and (to_x!=None)): assert(from_x < to_x) ser = self.getSlice(from_x, to_x) else: ser = self if len(ser.y_) < pad_to: zeros = np.zeros(len(ser.y_ - pad_to)) new_signal = np.concatenate([ser.y_ , zeros]) else: new_signal = ser.y_ if detrend: new_signal = signal.detrend(new_signal, type=det_type) ampl, freqs = mtspec.mtspec(new_signal, ser.x_step_, pi, nfft=pad_to) statistics = {} if stats: ampl_reshaped, freqs2, eigensp, eigencoeff, weights, jack, f, dof = mtspec.mtspec(new_signal, ser.x_step_, pi, statistics=True, fcrit=p_crit, optional_output=True, rshape=0, nfft=pad_to) nd = eigensp.shape[1] lev = scipy.stats.f.ppf(np.array([0.80,0.90,0.95,0.99]), 2, 2*(nd - 1)) statistics = { 'reshaped': ampl_reshaped, 'eigenspectra': eigensp, 'eigencoeff': eigencoeff, 'weights': weights, 'jack5_95': jack, 'f_values': f, 'dof': dof} if max_f != None: ids = np.argwhere(freqs <= max_f) ampl = ampl[ids] freqs = freqs[ids] if stats: # cut away also statistics for k in statistics.keys(): arr = statistics[k] statistics[k] = arr[ids] ampl = ampl.T[0] freqs = freqs.T[0] if stats: statistics['p_levels'] = lev if norm == True: ampl = ampl/np.max(ampl) if stats: return freqs, ampl, statistics else: return freqs, ampl
def calc_mtspec(tr): """Do mtspec on a trace""" nfft = len(tr.data)*2 spec_den,freq = mtspec(tr.data,tr.stats.delta,3.5,nfft=nfft) amp = np.sqrt(spec_den) return amp,freq
import matplotlib.pyplot as plt plt.style.use("ggplot") from mtspec import mtspec, sine_psd from mtspec.util import _load_mtdata data = _load_mtdata('PASC.dat.gz') plt.subplot(311) plt.plot(data, color='black') plt.xlim(0, len(data)) spec, freq = mtspec(data, 1.0, 1.5, number_of_tapers=1) 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)
import matplotlib.pyplot as plt plt.style.use("ggplot") import numpy as np from mtspec import mtspec from mtspec.util import _load_mtdata data = _load_mtdata('v22_174_series.dat.gz') # Calculate the spectral estimation. spec, freq, jackknife, _, _ = mtspec( data=data, delta=4930.0, time_bandwidth=3.5, number_of_tapers=5, nfft=312, statistics=True) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) # Plot in thousands of years. ax1.plot(np.arange(len(data)) * 4.930, data, color='black') ax1.set_xlim(0, 800) ax1.set_ylim(-1.0, 1.0) ax1.set_xlabel("Time [1000 years]") ax1.set_ylabel("Change in $\delta^{18}O$") ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') # Convert frequency to Ma. freq *= 1E6 ax2.plot(freq, spec, color='black') ax2.fill_between(freq, jackknife[:, 0], jackknife[:, 1], color="red", alpha=0.3)
def multitaper_spect(values, times, sampling_rate, figsize=(8,9), tmax=1e20, title=None, ylab='Amplitude', plot_picks_dir=None, plot_trace=True, pick_errors=None, max_freq=2000, fig=None, normalise_spectra=False, plot_uncertainties=False, **kwargs): ''' Function to plot the spectral power of a trace calculated using a multitaper spectrum. Arguments: --values: A array of the amplitude values --times: An array of times against which the values are plotted --sampling_rate: The sampling rate of the data in seconds --figsize: The figure size of the plot --tmax: The maximum time to plot for --title: A title for the plot --ylab: The y label for the plot --plot_picks_dir: The directory where wave arrival picks are saved --plot_trace: True to plot the trace as well as the PSD --pick_errors: Which wave arrival pick errors to plot. One of 'both', 'early', 'late', or None. --max_freq: The maximum frequency to plot for, in kHz --fig: A fig to plot on --normalise_spectra: True to plot each spectral line between 0 and 1. --plot_uncertainties: True to plot the uncertainties for the spectra. --**kwargs: The keyword arguments for the plotting Returns: --fig: The figure instance ''' units = 'nm$^2$/Hz' if plot_trace: fig, (ax1, ax2) = plt.subplots(2,1, figsize=figsize, gridspec_kw={'height_ratios':[1, 2]}) plt.sca(ax1) elif not fig: fig, ax2 = plt.subplots(1,1, figsize=figsize) else: ax2 = plt.gca() plot_kwargs = kwargs.copy() [plot_kwargs.pop(key) for key in list(plot_kwargs.keys()) if key in inspect.getargspec(format_fig)[0]] format_dict = kwargs.copy() [format_dict.pop(key) for key in list(format_dict.keys()) if key not in inspect.getargspec(format_fig)[0]] if plot_trace: format_kwargs = {key:val for key ,val in format_dict.items() if key not in ['show','save_dir']} fig = all_traces([values], times, fig=fig,tmax=tmax, title=title, ylab=ylab, show=False, **plot_kwargs,**format_kwargs) #Calculate and plot the multitaper spectrum nex_pow2 = np.ceil(np.log2([len(values)])[0]) spec, freq, jackknife, _, _ = mtspec( data=values, delta=1/sampling_rate, time_bandwidth=4, statistics=True)#, nfft=2**int(nex_pow2)) freq /= 1e3 if normalise_spectra: spec /= np.max(spec) units = 'a.u.' line = ax2.semilogy(freq, spec, **plot_kwargs) if plot_uncertainties: ax2.fill_between(freq, jackknife[:, 0], jackknife[:, 1], alpha=0.1, color=line[0].get_color()) if plot_picks_dir: plot_picks(ax1, plot_picks_dir, pick_errors) fig, ax = format_fig(fig, ax2, title=None, xlab='Frequency (kHz)', ylab='Power Spectral Density ({})'.format(units), xlim=(0, min(sampling_rate/2,max_freq)), **format_dict) return fig
network = base_N.split('_')[0] station = base_N.split('_')[1] full_channel_N = base_N.split('_')[2] full_channel_E = base_E.split('_')[2] #mtspec returns power spectra (square of spectra) stream = read(recordpath_N[0]) tr = stream[0] data = tr.data ########################################################################## ## m/s data = data spec_amp, freq = mtspec(data, delta=0.01, time_bandwidth=4, number_of_tapers=7, quadratic=True) #power spectra spec_array_N = np.array(spec_amp) freq_array_N = np.array(freq) stream = read(recordpath_E[0]) tr = stream[0] data = tr.data #m data = data spec_amp, freq = mtspec(data, delta=0.01, time_bandwidth=4,
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
import matplotlib as mpl mpl.rcParams['font.size'] = 9.0 import matplotlib.pyplot as plt from mtspec import mtspec from mtspec.util import load_mtdata data = load_mtdata('v22_174_series.dat.gz') spec, freq, jackknife, _, _ = mtspec(data, 4930., 3.5, number_of_tapers=5, nfft=312, statistics=True) fig = plt.figure() ax1 = fig.add_subplot(2, 1, 1) ax1.plot(data, color='black') ax1.set_xlim(0, len(data)) ax2 = fig.add_subplot(2, 1, 2) ax2.set_yscale('log') ax2.plot(freq, spec, color='black') ax2.plot(freq, jackknife[:, 0], '--', color = 'red') ax2.plot(freq, jackknife[:, 1], '--', color = 'red') ax2.set_xlim(freq[0], freq[-1])
def calculate_moment_magnitudes(cat, output_file): """ :param cat: obspy.core.event.Catalog object. """ Mws = [] Mls = [] Mws_std = [] for event in cat: if not event.origins: print "No origin for event %s" % event.resource_id continue if not event.magnitudes: print "No magnitude for event %s" % event.resource_id continue origin_time = event.origins[0].time local_magnitude = event.magnitudes[0].mag #if local_magnitude < 1.0: #continue moments = [] source_radii = [] corner_frequencies = [] for pick in event.picks: # Only p phase picks. if pick.phase_hint.lower() == "p": radiation_pattern = 0.52 velocity = V_P k = 0.32 elif pick.phase_hint.lower() == "s": radiation_pattern = 0.63 velocity = V_S k = 0.21 else: continue distance = (pick.time - origin_time) * velocity if distance <= 0.0: continue stream = get_corresponding_stream(pick.waveform_id, pick.time, PADDING) if stream is None or len(stream) != 3: continue omegas = [] corner_freqs = [] for trace in stream: # Get the index of the pick. pick_index = int(round((pick.time - trace.stats.starttime) / \ trace.stats.delta)) # Choose date window 0.5 seconds before and 1 second after pick. data_window = trace.data[pick_index - \ int(TIME_BEFORE_PICK * trace.stats.sampling_rate): \ pick_index + int(TIME_AFTER_PICK * trace.stats.sampling_rate)] # Calculate the spectrum. spec, freq = mtspec.mtspec(data_window, trace.stats.delta, 2) try: fit = fit_spectrum(spec, freq, pick.time - origin_time, spec.max(), 10.0) except: continue if fit is None: continue Omega_0, f_c, err, _ = fit Omega_0 = np.sqrt(Omega_0) omegas.append(Omega_0) corner_freqs.append(f_c) M_0 = 4.0 * np.pi * DENSITY * velocity ** 3 * distance * \ np.sqrt(omegas[0] ** 2 + omegas[1] ** 2 + omegas[2] ** 2) / \ radiation_pattern r = 3 * k * V_S / sum(corner_freqs) moments.append(M_0) source_radii.append(r) corner_frequencies.extend(corner_freqs) if not len(moments): print "No moments could be calculated for event %s" % \ event.resource_id.resource_id continue # Calculate the seismic moment via basic statistics. moments = np.array(moments) moment = moments.mean() moment_std = moments.std() corner_frequencies = np.array(corner_frequencies) corner_frequency = corner_frequencies.mean() corner_frequency_std = corner_frequencies.std() # Calculate the source radius. source_radii = np.array(source_radii) source_radius = source_radii.mean() source_radius_std = source_radii.std() # Calculate the stress drop of the event based on the average moment and # source radii. stress_drop = (7 * moment) / (16 * source_radius ** 3) stress_drop_std = np.sqrt((stress_drop ** 2) * \ (((moment_std ** 2) / (moment ** 2)) + \ (9 * source_radius * source_radius_std ** 2))) if source_radius > 0 and source_radius_std < source_radius: print "Source radius:", source_radius, " Std:", source_radius_std print "Stress drop:", stress_drop / 1E5, " Std:", stress_drop_std / 1E5 Mw = 2.0 / 3.0 * (np.log10(moment) - 9.1) Mw_std = 2.0 / 3.0 * moment_std / (moment * np.log(10)) Mws_std.append(Mw_std) Mws.append(Mw) Mls.append(local_magnitude) calc_diff = abs(Mw - local_magnitude) Mw = ("%.3f" % Mw).rjust(7) Ml = ("%.3f" % local_magnitude).rjust(7) diff = ("%.3e" % calc_diff).rjust(7) ret_string = colorama.Fore.GREEN + \ "For event %s: Ml=%s | Mw=%s | " % (event.resource_id.resource_id, Ml, Mw) if calc_diff >= 1.0: ret_string += colorama.Fore.RED ret_string += "Diff=%s" % diff ret_string += colorama.Fore.GREEN ret_string += " | Determined at %i stations" % len(moments) ret_string += colorama.Style.RESET_ALL print ret_string mag = Magnitude() mag.mag = Mw mag.mag_errors.uncertainty = Mw_std mag.magnitude_type = "Mw" mag.origin_id = event.origins[0].resource_id mag.method_id = "smi:com.github/krischer/moment_magnitude_calculator/automatic/1" mag.station_count = len(moments) mag.evaluation_mode = "automatic" mag.evaluation_status = "preliminary" mag.comments.append(Comment( \ "Seismic Moment=%e Nm; standard deviation=%e" % (moment, moment_std))) mag.comments.append(Comment("Custom fit to Boatwright spectrum")) if source_radius > 0 and source_radius_std < source_radius: mag.comments.append(Comment( \ "Source radius=%.2fm; standard deviation=%.2f" % (source_radius, source_radius_std))) event.magnitudes.append(mag) print "Writing output file..." cat.write(output_file, format="quakeml")
Pdeconv = deconvolved[-500:][::-1] Pdeconv /= Pdeconv.max() nfft = 2 * len(pasc) pasc = scipy.fftpack.fft(pasc, n=nfft) ado = scipy.fftpack.fft(ado, n=nfft) cc = pasc * ado.conj() cc = scipy.fftpack.ifft(cc).real Pcc = cc[-500:][::-1] Pcc /= Pcc.max() Dspec, Dfreq = mtspec(Pdeconv, delta=1.0, time_bandwidth=1.5, number_of_tapers=1) Cspec, Cfreq = mtspec(Pcc, delta=1.0, time_bandwidth=1.5, number_of_tapers=1) # Plotting plt.plot(np.arange(0, 500), Pdeconv + 3) plt.annotate("deconvolution", (200, 3.5)) plt.plot(np.arange(0, 500), Pcc) plt.annotate("cross-correlation", (200, -0.5)) plt.ylim(-1, 4.5) plt.yticks([], []) plt.xlabel("Time (s)") plt.ylabel("Amplitude")