def test_notch_design(self): """Test :func:`gwpy.signal.filter_design.notch` """ # test simple notch zpk = filter_design.notch(60, 16384) utils.assert_zpk_equal(zpk, NOTCH_60HZ) # test Quantities zpk2 = filter_design.notch(60 * ONE_HZ, 16384 * ONE_HZ) utils.assert_zpk_equal(zpk, zpk2) # test FIR notch doesn't work with pytest.raises(NotImplementedError): filter_design.notch(60, 16384, type='fir')
def test_notch_design(self): """Test :func:`gwpy.signal.filter_design.notch` """ # test simple notch zpk = filter_design.notch(60, 16384) utils.assert_zpk_equal(zpk, NOTCH_60HZ) # test Quantities zpk2 = filter_design.notch(60 * ONE_HZ, 16384 * ONE_HZ) utils.assert_zpk_equal(zpk, zpk2) # test FIR notch doesn't work with pytest.raises(NotImplementedError): filter_design.notch(60, 16384, type='fir')
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()
# To create a low-pass filter at 1000 Hz for 4096 Hz-sampled data: from gwpy.signal.filter_design import notch n = notch(100, 4096) # To view the filter, you can use the `~gwpy.plotter.BodePlot`: from gwpy.plotter import BodePlot plot = BodePlot(n, sample_rate=4096) plot.show()
# Next we can design a zero-pole-gain filter to remove the extranious noise. # First we import the `gwpy.signal.filter_design` module and create a # :meth:`~gwpy.signal.filter_design.bandpass` filter to remove both low and # high frequency content from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, hdata.sample_rate) # Now we want to combine the bandpass with a series of # :meth:`~gwpy.signal.filter_design.notch` filters, so we create those # for the first three harmonics of the 60 Hz AC mains power: notches = [ filter_design.notch(line, hdata.sample_rate) for line in (60, 120, 180) ] # and concatenate each of our filters together to create a single ZPK: zpk = filter_design.concatenate_zpks(bp, *notches) # Now, we can apply our combined filter to the data, using `filtfilt=True` # to filter both backwards and forwards to preserve the correct phase # at all frequencies hfilt = hdata.filter(zpk, filtfilt=True) # .. note:: # # The :mod:`~gwpy.signal.filter_design` methods return digital filters
#!/usr/bin/env python3 from gwpy.timeseries import TimeSeries hdata = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478, cache=True) from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, hdata.sample_rate) notches = [filter_design.notch(line, hdata.sample_rate) 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.plot import Plot plot = Plot(hdata, hfilt, figsize=[12, 6], separate=True, sharex=True, color='gwpy:ligo-hanford') ax1, ax2 = plot.axes ax1.set_title('LIGO-Hanford strain data around GW150914') ax1.text(1.0, 1.01, 'Unfiltered data', transform=ax1.transAxes, ha='right') ax1.set_ylabel('Amplitude [strain]', y=-0.2) ax2.set_ylabel('') ax2.text(1.0, 1.01, r'50-250\,Hz bandpass, notches at 60, 120, 180 Hz', transform=ax2.transAxes, ha='right') plot.show() plot = hfilt.plot(color='gwpy:ligo-hanford') ax = plot.gca() ax.set_title('LIGO-Hanford strain data around GW150914') ax.set_ylabel('Amplitude [strain]') ax.set_xlim(1126259462, 1126259462.6)
hdata = TimeSeries.fetch_open_data('H1', 1126259446, 1126259478) # Next we can design a zero-pole-gain filter to remove the extranious noise. # First we import the `gwpy.signal.filter_design` module and create a # :meth:`~gwpy.signal.filter_design.bandpass` filter to remove both low and # high frequency content from gwpy.signal import filter_design bp = filter_design.bandpass(50, 250, hdata.sample_rate) # Now we want to combine the bandpass with a series of # :meth:`~gwpy.signal.filter_design.notch` filters, so we create those # for the first three harmonics of the 60 Hz AC mains power: notches = [filter_design.notch(line, hdata.sample_rate) for line in (60, 120, 180)] # and concatenate each of our filters together to create a single ZPK: zpk = filter_design.concatenate_zpks(bp, *notches) # Now, we can apply our combined filter to the data, using `filtfilt=True` # to filter both backwards and forwards to preserve the correct phase # at all frequencies hfilt = hdata.filter(zpk, filtfilt=True) # .. note:: # # The :mod:`~gwpy.signal.filter_design` methods return digital filters
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 ax1.set_title('Strain Data') ax1.text(1.0, 1.0, 'Unfiltered data', transform=ax1.transAxes, ha='right')
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)
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