def filter_gwe(data:TimeSeries): from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, data.sample_rate) notches = [filter_design.notch(line, data.sample_rate) for line in (60, 120, 180)] zpk = filter_design.concatenate_zpks(bp, *notches) filt = data.filter(zpk, filtfilt=True) data = data.crop(*data.span.contract(1)) filt = filt.crop(*filt.span.contract(1)) return filt
def _filter_strain_data(data): """Apply general filtering techniques to clean strain data. Methods adapted from https://gwpy.github.io/docs/stable/examples/signal/gw150914.html Parameters ---------- data: gwpy.timeseries.TimeSeries Strain data to be filtered Returns ------- filtered_data: gwpy.timeseries.TimeSeries The filtered strain data. """ sample_rate = data.sample_rate # remove low and high freq bp = filter_design.bandpass(50, 250, sample_rate) # notches for harmonics of the 60 Hz AC mains power notches = [ filter_design.notch(line, sample_rate) for line in (60, 120, 180) ] # combine filters zpk = filter_design.concatenate_zpks(bp, *notches) # apply filters filtered_data = data.filter(zpk, filtfilt=True) # crop corrupted data from filtering filtered_data = filtered_data.crop(*filtered_data.span.contract(1)) return filtered_data
# We can design an arbitrarily complicated filter using # :mod:`gwpy.signal.filter_design` from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, 4096.) notches = [filter_design.notch(f, 4096.) for f in (60, 120, 180)] zpk = filter_design.concatenate_zpks(bp, *notches) # And then can download some data from LOSC to apply it using # `TimeSeries.filter`: from gwpy.timeseries import TimeSeries data = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478) filtered = data.filter(zpk, filtfilt=True) # We can plot the original signal, and the filtered version, cutting # off either end of the filtered data to remove filter-edge artefacts from gwpy.plotter import TimeSeriesPlot plot = TimeSeriesPlot(data, filtered[128:-128], sep=True) plot.show()
from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, hdata.sample_rate)
def test_bandpass(self): iir = filter_design.bandpass(100, 200, 1024) utils.assert_zpk_equal(iir, BANDPASS_IIR_100HZ_200HZ) fir = filter_design.bandpass(100, 200, 1024, type='fir') utils.assert_allclose(fir, BANDPASS_FIR_100HZ_200HZ)
def test_bandpass(self): iir = filter_design.bandpass(100, 200, 1024) utils.assert_zpk_equal(iir, BANDPASS_IIR_100HZ_200HZ) fir = filter_design.bandpass(100, 200, 1024, type='fir') utils.assert_allclose(fir, BANDPASS_FIR_100HZ_200HZ)
H1.set_strain_data_from_power_spectral_density( sampling_frequency=sampling_frequency, duration=duration, start_time=start_time) H1.inject_signal(waveform_generator=waveform_generator, parameters=injection_parameters) time_domain_data = H1.strain_data.time_domain_strain timeseries = gwpy.timeseries.TimeSeries(time_domain_data, t0=start_time, sample_rate=sampling_frequency) hdata = gwpy.timeseries.TimeSeries(time_domain_data, t0=start_time, sample_rate=sampling_frequency) from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, 2048) notches = [filter_design.notch(line, 2048) for line in (60, 120, 180)] zpk = filter_design.concatenate_zpks(bp, *notches) hfilt = hdata.filter(zpk, filtfilt=True) hdata = hdata.crop(*hdata.span.contract(1)) hfilt = hfilt.crop(*hfilt.span.contract(1)) from gwpy.plotter import TimeSeriesPlot plot = TimeSeriesPlot(hdata, hfilt, figsize=[12, 8], sep=True, sharex=True, color='gwpy:ligo-hanford') ax1, ax2 = plot.axes
def plot_time_domain_data(self, outdir='.', label=None, bandpass_frequencies=(50, 250), notches=None, start_end=None, t0=None): """ Plots the strain data in the time domain Parameters ========== outdir, label: str Used in setting the saved filename. bandpass: tuple, optional A tuple of the (low, high) frequencies to use when bandpassing the data, if None no bandpass is applied. notches: list, optional A list of frequencies specifying any lines to notch start_end: tuple A tuple of the (start, end) range of GPS times to plot t0: float If given, the reference time to subtract from the time series before plotting. """ import matplotlib.pyplot as plt from gwpy.timeseries import TimeSeries from gwpy.signal.filter_design import bandpass, concatenate_zpks, notch # We use the gwpy timeseries to perform bandpass and notching if notches is None: notches = list() timeseries = TimeSeries(data=self.strain_data.time_domain_strain, times=self.strain_data.time_array) zpks = [] if bandpass_frequencies is not None: zpks.append( bandpass(bandpass_frequencies[0], bandpass_frequencies[1], self.strain_data.sampling_frequency)) if notches is not None: for line in notches: zpks.append(notch(line, self.strain_data.sampling_frequency)) if len(zpks) > 0: zpk = concatenate_zpks(*zpks) strain = timeseries.filter(zpk, filtfilt=False) else: strain = timeseries fig, ax = plt.subplots() if t0: x = self.strain_data.time_array - t0 xlabel = 'GPS time [s] - {}'.format(t0) else: x = self.strain_data.time_array xlabel = 'GPS time [s]' ax.plot(x, strain) ax.set_xlabel(xlabel) ax.set_ylabel('Strain') if start_end is not None: ax.set_xlim(*start_end) fig.tight_layout() if label is None: fig.savefig('{}/{}_time_domain_data.png'.format(outdir, self.name)) else: fig.savefig('{}/{}_{}_time_domain_data.png'.format( outdir, self.name, label)) plt.close(fig)
# To create a band-pass filter for 100-1000 Hz for 4096 Hz-sampled data: from gwpy.signal.filter_design import bandpass bp = bandpass(100, 1000, 4096) # To view the filter, you can use the `~gwpy.plot.BodePlot`: from gwpy.plot import BodePlot plot = BodePlot(bp, sample_rate=4096) plot.show()
def main(start, end, chname): data = TimeSeries.read(dumped_gwf_fmt.format(start=start, end=end, chname=channel), channel, verbose=True, nproc=8) # Filtering from gwpy.signal import filter_design from gwpy.plot import BodePlot import numpy bp_high = filter_design.highpass( 0.3, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #,fstop() ) bp_mid = filter_design.bandpass( 0.05, 0.3, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #,fstop=(0.01,0.5) ) bp_low = filter_design.lowpass( 0.05, data.sample_rate, analog=True, ftype='butter', gpass=2, gstop=30 #, fstop=2 ) filters = [bp_high, bp_mid, bp_low] plot = BodePlot(*filters, analog=True, frequencies=numpy.logspace(-3, 1, 1e5), dB=False, unwrap=False, title='filter') axes = plot.get_axes() axes[0].set_yscale('log') axes[0].set_ylim(1e-4, 2e0) axes[-1].set_xlim(1e-2, 1e0) axes[-1].set_ylim(-180, 180) plot.savefig('Bodeplot_BandPass.png') plot.close() data_high = data.filter(bp_high, filtfilt=True) data_high = data_high.crop(*data_high.span.contract(1)) data_mid = data.filter(bp_mid, filtfilt=True) data_mid = data_mid.crop(*data_mid.span.contract(1)) data_low = data.filter(bp_low, filtfilt=True) data_low = data_low.crop(*data_low.span.contract(1)) # Plot TimeSeries title = channel[3:].replace('_', ' ') labels = [ 'No filt', 'High (300mHz-)', 'Mid (50mHz-300mHz)', 'Low (-50mHz)' ] if data.unit == ' ': yaxis_label = 'Count' else: yaxis_label = data.unit from gwpy.plot import Plot data_set = [data, data_high, data_mid, data_low] plot = Plot(*data_set, separate=True, sharex=True, sharey=True, color='gwpy:ligo-livingston', figsize=[10, 10]) axes = plot.get_axes() for i, ax in enumerate(axes): ax.legend([labels[i]], loc='upper left') plot.text(0.04, 0.5, yaxis_label, va='center', rotation='vertical', fontsize=16) #plot.text(0.5, 0.93, title, va='center',ha='center',rotation='horizontal',fontsize=16) axes[0].set_title(title, fontsize=16) axes[-1].set_xscale('Hours', epoch=start) plot.savefig(timeseriesplot_fname_fmt.format(channel=channel)) plot.close()
from gwpy.signal.filter_design import bandpass from gwpy.plot import BodePlot zpk = bandpass(40, 1000, 4096, analog=True) plot = BodePlot(zpk, analog=True, title='40-1000\,Hz bandpass filter') plot.show()
def main(channel,start,end): data = TimeSeries.read( dumped_gwf_fmt.format(start=start,end=end,chname=channel), channel, verbose=True ,nproc=8) # Filter zpk_bp_high = filter_design.highpass(0.3, data.sample_rate, ftype='butter',analog=False, gpass=2,gstop=40,fstop=0.03 ) zpk_bp_mid = filter_design.bandpass(0.03, 0.3, data.sample_rate, ftype='butter',analog=False, gpass=2, gstop=40,fstop=(0.003,3) ) zpk_bp_low = filter_design.lowpass(0.03, data.sample_rate, ftype='butter',analog=False, gpass=2, gstop=40, fstop=0.3 ) filters = [zpk_bp_high, zpk_bp_mid, zpk_bp_low] # Plot Bodeplot plot = BodePlot(*filters, frequencies=numpy.logspace(-4,1,1e5), dB=True,sample_rate=data.sample_rate, unwrap=False,analog=False, title='filter') axes = plot.get_axes() labels = ['High (300mHz-)','Mid (50mHz-300mHz)','Low (-50mHz)'] for i,ax in enumerate(axes): ax.legend(labels,loc='lower left') #axes[0].set_yscale('log') #axes[0].set_ylim(1e-3,2e0) axes[0].set_ylim(-40,2) axes[-1].set_xlim(5e-3,3e0) axes[-1].set_ylim(-200,200) plot.savefig('Bodeplot_BandPass.png') plot.close() # Filtering data_high = data.filter(zpk_bp_high, filtfilt=True,analog=False) data_mid = data.filter(zpk_bp_mid, filtfilt=True,analog=False) data_low = data.filter(zpk_bp_low, filtfilt=True,analog=False) # data_high = data_high.crop(*data_high.span.contract(1)) data_mid = data_mid.crop(*data_mid.span.contract(1)) data_low = data_low.crop(*data_low.span.contract(1)) # Plot TimeSeries from gwpy.plot import Plot data_set = [data,data_high, data_mid, data_low] plot = Plot(*data_set, separate=True, sharex=True, sharey=True, color='gwpy:ligo-livingston', figsize=[10,10]) # Add text, and save figure title = channel[3:].replace('_',' ') labels = ['No filt', 'High (300mHz-)', 'Mid (50mHz-300mHz)', 'Low (-50mHz)'] if data.unit == ' ': yaxis_label = 'Count' else: yaxis_label = data.unit axes = plot.get_axes() for i,ax in enumerate(axes): ax.legend([labels[i]],loc='upper left') plot.text(0.04, 0.5, yaxis_label, va='center', rotation='vertical',fontsize=18) axes[0].set_title(title,fontsize=16) axes[-1].set_xscale('Hours', epoch=start) plot.savefig(timeseriesplot_fname_fmt.format(channel=channel)) plot.close()
from gwpy.signal.filter_design import bandpass from gwpy.plot import BodePlot zpk = bandpass(40, 1000, 4096, analog=False) plot = BodePlot(zpk, analog=False, sample_rate=4096, title='40-1000 Hz bandpass filter') plot.show()
def whiten(data, ffttime, window, low_f, high_f, notch, rate): """ This function whitens the data and band-pass it in the range [low_f, high_f]. Parameters ---------- data: numpy array The signal to whiten as numpy array ffttime: int Portion of the strain to compute the psd window: str Type of function for the windowing low_f: int Lower bound of the band-pass filter high_f: int Upper bound of the band-pass filter notch: list Frequencies of the notch filters. Depends on the detector rate: int Resampling rate. Represents the sampling frequency Returns ------- whitened: numpy array The whitened and band-passed numpy array """ # Band-pass filter in [35, 250] bp = bandpass(float(low_f), float(high_f), data.sample_rate) #Notches for the 1st three harminics of the 60 Hz AC notches = [filter_design.notch(line, data.sample_rate) for line in notch] #Concatenate both filters zpk = filter_design.concatenate_zpks(bp, *notches) #Whiten and band-pass filter white = data.whiten(ffttime, int(ffttime / 2), window='hann') #whiten the data white_down = white.filter(zpk, filtfilt=True).resample( rate=rate, window='hann') #downsample to 2048Hz whitened = np.array(white_down) #Plot version with and without notches plot = Plot(figsize=(15, 6)) ax = plot.gca() ax.plot(white_down, label='Downsampled', alpha=0.7) ax.plot(white.filter(zpk, filtfilt=True), label='Not downsampled', alpha=0.7) ax.set_xscale('auto-gps') ax.set_ylabel('Frequency [Hz]') ax.set_title( 'LIGO-Livingston strain data whitened, band-passed in range [' + str(low_f) + '' + str(high_f) + '] $Hz$') plot.legend() plt.savefig('/home/melissa.lopez/Anomaly_Detection/Algorithm/dummy.png') plt.close() return whitened
from gwpy.plot import (rcParams, TimeSeriesPlot) rcParams.update({ 'figure.dpi': 600, 'figure.subplot.left': 0., 'figure.subplot.right': 1., 'figure.subplot.bottom': 0., 'figure.subplot.top': 1., }) # get data lho = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478) llo = TimeSeries.fetch_open_data('L1', 1126259446, 1126259478) # design filter to extract signal bp = filter_design.bandpass(50, 250, lho.sample_rate) notches = [ filter_design.notch(line, lho.sample_rate) for line in (60, 120, 180) ] zpk = filter_design.concatenate_zpks(bp, *notches) # filter data lhof = lho.filter(zpk, filtfilt=True).crop(1126259462, 1126259462.6) llof = llo.filter(zpk, filtfilt=True).crop(1126259462, 1126259462.6) # shift l1 data to account for time-delay and orientation llof.t0 += 0.0069 * llof.t0.unit llof *= -1 * llof.unit # plot plot = TimeSeriesPlot(figsize=[12, 4])