def time_norm(self, trace, trcopy): # normalization of the signal by the running mean # in the earthquake frequency band trcopy.filter(type="bandpass", freqmin=self.freqmin_earthquake, freqmax=self.freqmax_earthquake, corners=self.corners, zerophase=self.zerophase) # decimating trace psutils.resample(trcopy, self.period_resample) # Time-normalization weights from smoothed abs(data) # Note that trace's data can be a masked array halfwindow = int(round(self.window_time*trcopy.stats.sampling_rate/2)) mask = ~trcopy.data.mask if np.ma.isMA(trcopy.data) else None tnorm_w = psutils.moving_avg(np.abs(trcopy.data), halfwindow=halfwindow, mask=mask) if np.ma.isMA(trcopy.data): # turning time-normalization weights into a masked array s = "[warning: {}.{} trace's data is a masked array]" print s.format(trace.stats.network, trace.stats.station), tnorm_w = np.ma.masked_array(tnorm_w, trcopy.data.mask) if np.any((tnorm_w == 0.0) | np.isnan(tnorm_w)): # illegal normalizing value -> skipping trace raise pserrors.CannotPreprocess("Zero or NaN normalisation \ weight") # time-normalization trace.data /= tnorm_w return trace
def time_norm(self, trace, trcopy): # normalization of the signal by the running mean # in the earthquake frequency band trcopy.filter(type="bandpass", freqmin=self.freqmin_earthquake, freqmax=self.freqmax_earthquake, corners=self.corners, zerophase=self.zerophase) # decimating trace psutils.resample(trcopy, self.period_resample) # Time-normalization weights from smoothed abs(data) # Note that trace's data can be a masked array halfwindow = int( round(self.window_time * trcopy.stats.sampling_rate / 2)) mask = ~trcopy.data.mask if np.ma.isMA(trcopy.data) else None tnorm_w = psutils.moving_avg(np.abs(trcopy.data), halfwindow=halfwindow, mask=mask) if np.ma.isMA(trcopy.data): # turning time-normalization weights into a masked array s = "[warning: {}.{} trace's data is a masked array]" print s.format(trace.stats.network, trace.stats.station), tnorm_w = np.ma.masked_array(tnorm_w, trcopy.data.mask) if np.any((tnorm_w == 0.0) | np.isnan(tnorm_w)): # illegal normalizing value -> skipping trace raise pserrors.CannotPreprocess("Zero or NaN normalisation \ weight") # time-normalization trace.data /= tnorm_w return trace
def spectral_whitening(self, trace): """ Function that takes an input obspy trace object that has been time-normalised, band-pass filtered and had its repsonse removed, delimited, demeaned and detrended. """ # real FFT fft = rfft(trace.data) # frequency step deltaf = trace.stats.sampling_rate / trace.stats.npts # smoothing amplitude spectrum halfwindow = int(round(self.window_freq / deltaf / 2.0)) weight = psutils.moving_avg(abs(fft), halfwindow=halfwindow) # normalizing spectrum and back to time domain trace.data = irfft(fft / weight, n=len(trace.data)) # re bandpass to avoid low/high freq noise trace.filter(type="bandpass", freqmin=self.freqmin, freqmax=self.freqmax, corners=self.corners, zerophase=self.zerophase) return trace
def plot(self, smooth_window_freq=0.0): """ Plots list of spectra: rows = filtering steps, columns = stations Plotting freq x abs(Fourier coefs) """ # list of stations and filters in spectra (preserving order) filterslist = [] stationlist = [] for spect in self: assert isinstance(spect, SpectrumInfos) if spect.filters not in filterslist: filterslist.append(spect.filters) if spect.station not in stationlist: stationlist.append(spect.station) # rows = filtering steps, columns = stations: 1 station = 1 spectrum [+ 1 trace] nrow = len(filterslist) ncol = len(stationlist) # plot per pair (station, filters) plottraces = any([spect.savedtrace for spect in self]) plotperpair = 1 if not plottraces else 2 plt.figure() for ipair, (filters, station) in enumerate(it.product(filterslist, stationlist)): assert isinstance(filters, str) try: # looking for spectrum of station/filters spect = next( spect for spect in self if spect.station == station and spect.filters == filters) except StopIteration: continue # getting freq and amplitude arrays spectrum = spect.spectrum assert isinstance(spectrum, FreqAmplSpectrum) freq = spectrum.freq ampl = np.abs(spectrum.coef) # smoothing amplitude spectrum (except after spectral whitening) if not 'white' in filters.lower(): halfwindow = int( round(smooth_window_freq / (freq[1] - freq[0]) / 2.0)) ampl = psutils.moving_avg(ampl, halfwindow) # position of current station/filters in plot irow = ipair / ncol + 1 icol = ipair % ncol + 1 pos = (irow - 1) * ncol * plotperpair + (icol - 1) * plotperpair + 1 # plotting frequence-amplitude plt.subplot(nrow, ncol * plotperpair, pos) plt.plot(freq[100:], ampl[100:]) plt.xlim((0.0, 0.5)) if icol == 1: plt.ylabel(filters) if irow == 1: plt.title('{station} (ampl spectrum)'.format( station=spect.station.name)) if irow == nrow: plt.xlabel('Frequency (Hz)') # plotting trace if plottraces and spect.savedtrace: tr = spect.savedtrace t = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta) t /= 3600.0 plt.subplot(nrow, ncol * plotperpair, pos + 1) plt.plot(t, tr.data) if irow == 1: plt.title('{station} (last day)'.format( station=spect.station.name)) if irow == nrow: plt.xlabel('Time (h)') plt.show()
def plot(self, smooth_window_freq=0.0): """ Plots list of spectra: rows = filtering steps, columns = stations Plotting freq x abs(Fourier coefs) """ # list of stations and filters in spectra (preserving order) filterslist = [] stationlist = [] for spect in self: assert isinstance(spect, SpectrumInfos) if spect.filters not in filterslist: filterslist.append(spect.filters) if spect.station not in stationlist: stationlist.append(spect.station) # rows = filtering steps, columns = stations: 1 station = 1 spectrum [+ 1 trace] nrow = len(filterslist) ncol = len(stationlist) # plot per pair (station, filters) plottraces = any([spect.savedtrace for spect in self]) plotperpair = 1 if not plottraces else 2 plt.figure() for ipair, (filters, station) in enumerate(it.product(filterslist, stationlist)): assert isinstance(filters, str) try: # looking for spectrum of station/filters spect = next(spect for spect in self if spect.station == station and spect.filters == filters) except StopIteration: continue # getting freq and amplitude arrays spectrum = spect.spectrum assert isinstance(spectrum, FreqAmplSpectrum) freq = spectrum.freq ampl = np.abs(spectrum.coef) # smoothing amplitude spectrum (except after spectral whitening) if not 'white' in filters.lower(): halfwindow = int(round(smooth_window_freq / (freq[1] - freq[0]) / 2.0)) ampl = psutils.moving_avg(ampl, halfwindow) # position of current station/filters in plot irow = ipair / ncol + 1 icol = ipair % ncol + 1 pos = (irow - 1) * ncol * plotperpair + (icol - 1) * plotperpair + 1 # plotting frequence-amplitude plt.subplot(nrow, ncol * plotperpair, pos) plt.plot(freq[100:], ampl[100:]) plt.xlim((0.0, 0.5)) if icol == 1: plt.ylabel(filters) if irow == 1: plt.title('{station} (ampl spectrum)'.format(station=spect.station.name)) if irow == nrow: plt.xlabel('Frequency (Hz)') # plotting trace if plottraces and spect.savedtrace: tr = spect.savedtrace t = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta) t /= 3600.0 plt.subplot(nrow, ncol * plotperpair, pos + 1) plt.plot(t, tr.data) if irow == 1: plt.title('{station} (last day)'.format(station=spect.station.name)) if irow == nrow: plt.xlabel('Time (h)') plt.show()