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 = np.asarray(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 time_norm(self, trace, trcopy): if self.onebit_norm: # one-bit normalization trace.data = np.sign(trace.data) else: # 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 normalization weight") # time-normalization trace.data /= tnorm_w return trace
def time_norm(self, trace, trcopy): if self.onebit_norm: # one-bit normalization trace.data = np.sign(trace.data) else: # 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 normalization weight") # time-normalization trace.data /= tnorm_w return trace